LCOV - code coverage report
Current view: top level - libreoffice/sw/source/filter/html - htmlnum.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 418 0.0 %
Date: 2012-12-27 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/style/NumberingType.hpp>
      21             : #include <hintids.hxx>
      22             : #include <svtools/htmltokn.h>
      23             : #include <svtools/htmlkywd.hxx>
      24             : #include <svtools/htmlout.hxx>
      25             : #include <svl/urihelper.hxx>
      26             : #include <editeng/brshitem.hxx>
      27             : #include <editeng/lrspitem.hxx>
      28             : #include <vcl/svapp.hxx>
      29             : #include <vcl/wrkwin.hxx>
      30             : #include <numrule.hxx>
      31             : #include <doc.hxx>
      32             : #include <docary.hxx>
      33             : #include <poolfmt.hxx>
      34             : #include <ndtxt.hxx>
      35             : #include <paratr.hxx>
      36             : 
      37             : #include "htmlnum.hxx"
      38             : #include "swcss1.hxx"
      39             : #include "swhtml.hxx"
      40             : #include "wrthtml.hxx"
      41             : 
      42             : #include <SwNodeNum.hxx>
      43             : #include <rtl/strbuf.hxx>
      44             : 
      45             : using namespace ::com::sun::star;
      46             : 
      47             : // TODO: Unicode: Are these characters the correct ones?
      48             : #define HTML_BULLETCHAR_DISC    (0xe008)
      49             : #define HTML_BULLETCHAR_CIRCLE  (0xe009)
      50             : #define HTML_BULLETCHAR_SQUARE  (0xe00b)
      51             : 
      52             : 
      53             : // <UL TYPE=...>
      54             : static HTMLOptionEnum aHTMLULTypeTable[] =
      55             : {
      56             :     { OOO_STRING_SVTOOLS_HTML_ULTYPE_disc,  HTML_BULLETCHAR_DISC        },
      57             :     { OOO_STRING_SVTOOLS_HTML_ULTYPE_circle,    HTML_BULLETCHAR_CIRCLE      },
      58             :     { OOO_STRING_SVTOOLS_HTML_ULTYPE_square,    HTML_BULLETCHAR_SQUARE      },
      59             :     { 0,                    0                           }
      60             : };
      61             : 
      62             : 
      63           0 : void SwHTMLNumRuleInfo::Set( const SwTxtNode& rTxtNd )
      64             : {
      65           0 :     const SwNumRule* pTxtNdNumRule( rTxtNd.GetNumRule() );
      66           0 :     if ( pTxtNdNumRule &&
      67           0 :          pTxtNdNumRule != rTxtNd.GetDoc()->GetOutlineNumRule() )
      68             :     {
      69           0 :         pNumRule = const_cast<SwNumRule*>(pTxtNdNumRule);
      70           0 :         nDeep = static_cast< sal_uInt16 >(pNumRule ? rTxtNd.GetActualListLevel() + 1 : 0);
      71           0 :         bNumbered = rTxtNd.IsCountedInList();
      72             :         // #i57919# - correction of refactoring done by cws swnumtree:
      73             :         // <bRestart> has to be set to <true>, if numbering is restarted at this
      74             :         // text node and the start value equals <USHRT_MAX>.
      75             :         // Start value <USHRT_MAX> indicates, that at this text node the numbering
      76             :         // is restarted with the value given at the corresponding level.
      77           0 :         bRestart = rTxtNd.IsListRestart() && !rTxtNd.HasAttrListRestartValue();
      78             :     }
      79             :     else
      80             :     {
      81           0 :         pNumRule = 0;
      82           0 :         nDeep = 0;
      83           0 :         bNumbered = bRestart = sal_False;
      84             :     }
      85           0 : }
      86             : 
      87             : 
      88           0 : void SwHTMLParser::NewNumBulList( int nToken )
      89             : {
      90           0 :     SwHTMLNumRuleInfo& rInfo = GetNumInfo();
      91             : 
      92             :     // Erstmal einen neuen Absatz aufmachen
      93           0 :     sal_Bool bSpace = (rInfo.GetDepth() + nDefListDeep) == 0;
      94           0 :     if( pPam->GetPoint()->nContent.GetIndex() )
      95           0 :         AppendTxtNode( bSpace ? AM_SPACE : AM_NOSPACE, sal_False );
      96           0 :     else if( bSpace )
      97           0 :         AddParSpace();
      98             : 
      99             :     // Die Numerierung-Ebene erhoehen
     100           0 :     rInfo.IncDepth();
     101           0 :     sal_uInt8 nLevel = (sal_uInt8)( (rInfo.GetDepth() <= MAXLEVEL ? rInfo.GetDepth()
     102           0 :                                                         : MAXLEVEL) - 1 );
     103             : 
     104             :     // ggf. ein Regelwerk anlegen
     105           0 :     if( !rInfo.GetNumRule() )
     106             :     {
     107           0 :         sal_uInt16 nPos = pDoc->MakeNumRule( pDoc->GetUniqueNumRuleName() );
     108           0 :         rInfo.SetNumRule( pDoc->GetNumRuleTbl()[nPos] );
     109             :     }
     110             : 
     111             :     // das Format anpassen, falls es fuer den Level noch nicht
     112             :     // geschehen ist!
     113           0 :     sal_Bool bNewNumFmt = rInfo.GetNumRule()->GetNumFmt( nLevel ) == 0;
     114           0 :     sal_Bool bChangeNumFmt = sal_False;
     115             : 
     116             :     // das default Numerierungsformat erstellen
     117           0 :     SwNumFmt aNumFmt( rInfo.GetNumRule()->Get(nLevel) );
     118           0 :     rInfo.SetNodeStartValue( nLevel );
     119           0 :     if( bNewNumFmt )
     120             :     {
     121           0 :         sal_uInt16 nChrFmtPoolId = 0;
     122           0 :         if( HTML_ORDERLIST_ON == nToken )
     123             :         {
     124           0 :             aNumFmt.SetNumberingType(SVX_NUM_ARABIC);
     125           0 :             nChrFmtPoolId = RES_POOLCHR_NUM_LEVEL;
     126             :         }
     127             :         else
     128             :         {
     129             :             // Wir setzen hier eine Zeichenvorlage, weil die UI das auch
     130             :             // so macht. Dadurch wurd immer auch eine 9pt-Schrift
     131             :             // eingestellt, was in Netscape nicht der Fall ist. Bisher hat
     132             :             // das noch niemanden gestoert.
     133             :             // #i63395# - Only apply user defined default bullet font
     134           0 :             if ( numfunc::IsDefBulletFontUserDefined() )
     135             :             {
     136           0 :                 aNumFmt.SetBulletFont( &numfunc::GetDefBulletFont() );
     137             :             }
     138           0 :             aNumFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
     139           0 :             aNumFmt.SetBulletChar( cBulletChar );       // das Bulletzeichen !!
     140           0 :             nChrFmtPoolId = RES_POOLCHR_BUL_LEVEL;
     141             :         }
     142             : 
     143           0 :         sal_uInt16 nAbsLSpace = HTML_NUMBUL_MARGINLEFT;
     144             : 
     145           0 :         short nFirstLineIndent  = HTML_NUMBUL_INDENT;
     146           0 :         if( nLevel > 0 )
     147             :         {
     148           0 :             const SwNumFmt& rPrevNumFmt = rInfo.GetNumRule()->Get( nLevel-1 );
     149           0 :             nAbsLSpace = nAbsLSpace + rPrevNumFmt.GetAbsLSpace();
     150           0 :             nFirstLineIndent = rPrevNumFmt.GetFirstLineOffset();
     151             :         }
     152           0 :         aNumFmt.SetAbsLSpace( nAbsLSpace );
     153           0 :         aNumFmt.SetFirstLineOffset( nFirstLineIndent );
     154           0 :         aNumFmt.SetCharFmt( pCSS1Parser->GetCharFmtFromPool(nChrFmtPoolId) );
     155             : 
     156           0 :         bChangeNumFmt = sal_True;
     157             :     }
     158           0 :     else if( 1 != aNumFmt.GetStart() )
     159             :     {
     160             :         // Wenn die Ebene schon mal benutzt wurde, muss der Start-Wert
     161             :         // ggf. hart am Absatz gesetzt werden.
     162           0 :         rInfo.SetNodeStartValue( nLevel, 1 );
     163             :     }
     164             : 
     165             :     // und es ggf. durch die Optionen veraendern
     166           0 :     String aId, aStyle, aClass, aBulletSrc, aLang, aDir;
     167           0 :     sal_Int16 eVertOri = text::VertOrientation::NONE;
     168           0 :     sal_uInt16 nWidth=USHRT_MAX, nHeight=USHRT_MAX;
     169           0 :     const HTMLOptions& rHTMLOptions = GetOptions();
     170           0 :     for (size_t i = rHTMLOptions.size(); i; )
     171             :     {
     172           0 :         const HTMLOption& rOption = rHTMLOptions[--i];
     173           0 :         switch( rOption.GetToken() )
     174             :         {
     175             :         case HTML_O_ID:
     176           0 :             aId = rOption.GetString();
     177           0 :             break;
     178             :         case HTML_O_TYPE:
     179           0 :             if( bNewNumFmt && rOption.GetString().Len() )
     180             :             {
     181           0 :                 switch( nToken )
     182             :                 {
     183             :                 case HTML_ORDERLIST_ON:
     184           0 :                     bChangeNumFmt = sal_True;
     185           0 :                     switch( rOption.GetString().GetChar(0) )
     186             :                     {
     187           0 :                     case 'A':   aNumFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER); break;
     188           0 :                     case 'a':   aNumFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER); break;
     189           0 :                     case 'I':   aNumFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER);        break;
     190           0 :                     case 'i':   aNumFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER);        break;
     191           0 :                     default:    bChangeNumFmt = sal_False;
     192             :                     }
     193           0 :                     break;
     194             : 
     195             :                 case HTML_UNORDERLIST_ON:
     196             :                     aNumFmt.SetBulletChar( (sal_Unicode)rOption.GetEnum(
     197           0 :                                     aHTMLULTypeTable,aNumFmt.GetBulletChar() ) );
     198           0 :                     bChangeNumFmt = sal_True;
     199           0 :                     break;
     200             :                 }
     201             :             }
     202           0 :             break;
     203             :         case HTML_O_START:
     204             :             {
     205           0 :                 sal_uInt16 nStart = (sal_uInt16)rOption.GetNumber();
     206           0 :                 if( bNewNumFmt )
     207             :                 {
     208           0 :                     aNumFmt.SetStart( nStart );
     209           0 :                     bChangeNumFmt = sal_True;
     210             :                 }
     211             :                 else
     212             :                 {
     213           0 :                     rInfo.SetNodeStartValue( nLevel, nStart );
     214             :                 }
     215             :             }
     216           0 :             break;
     217             :         case HTML_O_STYLE:
     218           0 :             aStyle = rOption.GetString();
     219           0 :             break;
     220             :         case HTML_O_CLASS:
     221           0 :             aClass = rOption.GetString();
     222           0 :             break;
     223             :         case HTML_O_LANG:
     224           0 :             aLang = rOption.GetString();
     225           0 :             break;
     226             :         case HTML_O_DIR:
     227           0 :             aDir = rOption.GetString();
     228           0 :             break;
     229             :         case HTML_O_SRC:
     230           0 :             if( bNewNumFmt )
     231             :             {
     232           0 :                 aBulletSrc = rOption.GetString();
     233           0 :                 if( !InternalImgToPrivateURL(aBulletSrc) )
     234           0 :                     aBulletSrc = URIHelper::SmartRel2Abs( INetURLObject( sBaseURL ), aBulletSrc, Link(), false );
     235             :             }
     236           0 :             break;
     237             :         case HTML_O_WIDTH:
     238           0 :             nWidth = (sal_uInt16)rOption.GetNumber();
     239           0 :             break;
     240             :         case HTML_O_HEIGHT:
     241           0 :             nHeight = (sal_uInt16)rOption.GetNumber();
     242           0 :             break;
     243             :         case HTML_O_ALIGN:
     244             :             eVertOri =
     245             :                 (sal_Int16)rOption.GetEnum( aHTMLImgVAlignTable,
     246           0 :                                                 static_cast< sal_uInt16 >(eVertOri) );
     247           0 :             break;
     248             :         }
     249             :     }
     250             : 
     251           0 :     if( aBulletSrc.Len() )
     252             :     {
     253             :         // Eine Bullet-Liste mit Grafiken
     254           0 :         aNumFmt.SetNumberingType(SVX_NUM_BITMAP);
     255             : 
     256             :         // Die Grafik als Brush anlegen
     257           0 :         SvxBrushItem aBrushItem( RES_BACKGROUND );
     258           0 :         aBrushItem.SetGraphicLink( aBulletSrc );
     259           0 :         aBrushItem.SetGraphicPos( GPOS_AREA );
     260             : 
     261             :         // Die Groesse nur beachten, wenn Breite und Hoehe vorhanden sind
     262           0 :         Size aTwipSz( nWidth, nHeight), *pTwipSz=0;
     263           0 :         if( nWidth!=USHRT_MAX && nHeight!=USHRT_MAX )
     264             :         {
     265             :             aTwipSz =
     266             :                 Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
     267           0 :                                                     MapMode(MAP_TWIP) );
     268           0 :             pTwipSz = &aTwipSz;
     269             :         }
     270             : 
     271             :         // Die Ausrichtung auch nur beachten, wenn eine Ausrichtung
     272             :         // angegeben wurde
     273             :         aNumFmt.SetGraphicBrush( &aBrushItem, pTwipSz,
     274           0 :                             text::VertOrientation::NONE!=eVertOri ? &eVertOri : 0);
     275             : 
     276             :         // Und noch die Grafik merken, um sie in den Absaetzen nicht
     277             :         // einzufuegen
     278           0 :         aBulletGrfs[nLevel] = aBulletSrc;
     279           0 :         bChangeNumFmt = sal_True;
     280             :     }
     281             :     else
     282           0 :         aBulletGrfs[nLevel].Erase();
     283             : 
     284             :     // den aktuellen Absatz erst einmal nicht numerieren
     285             :     {
     286           0 :         sal_uInt8 nLvl = nLevel;
     287           0 :         SetNodeNum( nLvl, false );
     288             :     }
     289             : 
     290             :     // einen neuen Kontext anlegen
     291           0 :     _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
     292             : 
     293             :     // Styles parsen
     294           0 :     if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
     295             :     {
     296           0 :         SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
     297           0 :         SvxCSS1PropertyInfo aPropInfo;
     298             : 
     299           0 :         if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
     300             :         {
     301           0 :             if( bNewNumFmt )
     302             :             {
     303           0 :                 if( aPropInfo.bLeftMargin )
     304             :                 {
     305             :                     // Der Der Default-Einzug wurde schon eingefuegt.
     306             :                     sal_uInt16 nAbsLSpace =
     307           0 :                         aNumFmt.GetAbsLSpace() - HTML_NUMBUL_MARGINLEFT;
     308           0 :                     if( aPropInfo.nLeftMargin < 0 &&
     309             :                         nAbsLSpace < -aPropInfo.nLeftMargin )
     310           0 :                         nAbsLSpace = 0U;
     311           0 :                     else if( aPropInfo.nLeftMargin > USHRT_MAX ||
     312             :                              (long)nAbsLSpace +
     313             :                                             aPropInfo.nLeftMargin > USHRT_MAX )
     314           0 :                         nAbsLSpace = USHRT_MAX;
     315             :                     else
     316           0 :                         nAbsLSpace = nAbsLSpace + (sal_uInt16)aPropInfo.nLeftMargin;
     317             : 
     318           0 :                     aNumFmt.SetAbsLSpace( nAbsLSpace );
     319           0 :                     bChangeNumFmt = sal_True;
     320             :                 }
     321           0 :                 if( aPropInfo.bTextIndent )
     322             :                 {
     323             :                     short nTextIndent =
     324           0 :                         ((const SvxLRSpaceItem &)aItemSet.Get( RES_LR_SPACE ))
     325           0 :                                                         .GetTxtFirstLineOfst();
     326           0 :                     aNumFmt.SetFirstLineOffset( nTextIndent );
     327           0 :                     bChangeNumFmt = sal_True;
     328             :                 }
     329             :             }
     330           0 :             aPropInfo.bLeftMargin = aPropInfo.bTextIndent = sal_False;
     331           0 :             if( !aPropInfo.bRightMargin )
     332           0 :                 aItemSet.ClearItem( RES_LR_SPACE );
     333             : 
     334             :             // #i89812# - Perform change to list style before calling <DoPositioning(..)>,
     335             :             // because <DoPositioning(..)> may open a new context and thus may
     336             :             // clear the <SwHTMLNumRuleInfo> instance hold by local variable <rInfo>.
     337           0 :             if( bChangeNumFmt )
     338             :             {
     339           0 :                 rInfo.GetNumRule()->Set( nLevel, aNumFmt );
     340           0 :                 pDoc->ChgNumRuleFmts( *rInfo.GetNumRule() );
     341           0 :                 bChangeNumFmt = sal_False;
     342             :             }
     343             : 
     344           0 :             DoPositioning( aItemSet, aPropInfo, pCntxt );
     345             : 
     346           0 :             InsertAttrs( aItemSet, aPropInfo, pCntxt );
     347           0 :         }
     348             :     }
     349             : 
     350           0 :     if( bChangeNumFmt )
     351             :     {
     352           0 :         rInfo.GetNumRule()->Set( nLevel, aNumFmt );
     353           0 :         pDoc->ChgNumRuleFmts( *rInfo.GetNumRule() );
     354             :     }
     355             : 
     356           0 :     PushContext( pCntxt );
     357             : 
     358             :     // die Attribute der neuen Vorlage setzen
     359           0 :     SetTxtCollAttrs( pCntxt );
     360           0 : }
     361             : 
     362           0 : void SwHTMLParser::EndNumBulList( int nToken )
     363             : {
     364           0 :     SwHTMLNumRuleInfo& rInfo = GetNumInfo();
     365             : 
     366             :     // Ein neuer Absatz muss aufgemacht werden, wenn
     367             :     // - der aktuelle nicht leer ist, also Text oder absatzgebundene Objekte
     368             :     //   enthaelt.
     369             :     // - der aktuelle Absatz numeriert ist.
     370           0 :     sal_Bool bAppend = pPam->GetPoint()->nContent.GetIndex() > 0;
     371           0 :     if( !bAppend )
     372             :     {
     373           0 :         SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
     374             : 
     375           0 :         bAppend = (pTxtNode && ! pTxtNode->IsOutline() && pTxtNode->IsCountedInList()) ||
     376             : 
     377           0 :             HasCurrentParaFlys();
     378             :     }
     379             : 
     380           0 :     sal_Bool bSpace = (rInfo.GetDepth() + nDefListDeep) == 1;
     381           0 :     if( bAppend )
     382           0 :         AppendTxtNode( bSpace ? AM_SPACE : AM_NOSPACE, sal_False );
     383           0 :     else if( bSpace )
     384           0 :         AddParSpace();
     385             : 
     386             :     // den aktuellen Kontext vom Stack holen
     387           0 :     _HTMLAttrContext *pCntxt = nToken!=0 ? PopContext( static_cast< sal_uInt16 >(nToken & ~1) ) : 0;
     388             : 
     389             :     // Keine Liste aufgrund eines Tokens beenden, wenn der Kontext
     390             :     // nie angelgt wurde oder nicht beendet werden darf.
     391           0 :     if( rInfo.GetDepth()>0 && (!nToken || pCntxt) )
     392             :     {
     393           0 :         rInfo.DecDepth();
     394           0 :         if( !rInfo.GetDepth() )     // wars der letze Level ?
     395             :         {
     396             :             // Die noch nicht angepassten Formate werden jetzt noch
     397             :             // angepasst, damit es sich besser Editieren laesst.
     398           0 :             const SwNumFmt *pRefNumFmt = 0;
     399           0 :             sal_Bool bChanged = sal_False;
     400           0 :             for( sal_uInt16 i=0; i<MAXLEVEL; i++ )
     401             :             {
     402           0 :                 const SwNumFmt *pNumFmt = rInfo.GetNumRule()->GetNumFmt(i);
     403           0 :                 if( pNumFmt )
     404             :                 {
     405           0 :                     pRefNumFmt = pNumFmt;
     406             :                 }
     407           0 :                 else if( pRefNumFmt )
     408             :                 {
     409           0 :                     SwNumFmt aNumFmt( rInfo.GetNumRule()->Get(i) );
     410           0 :                     aNumFmt.SetNumberingType(pRefNumFmt->GetNumberingType() != SVX_NUM_BITMAP
     411           0 :                                         ? pRefNumFmt->GetNumberingType() : style::NumberingType::CHAR_SPECIAL);
     412           0 :                     if( SVX_NUM_CHAR_SPECIAL == aNumFmt.GetNumberingType() )
     413             :                     {
     414             :                         // #i63395# - Only apply user defined default bullet font
     415           0 :                         if ( numfunc::IsDefBulletFontUserDefined() )
     416             :                         {
     417           0 :                             aNumFmt.SetBulletFont( &numfunc::GetDefBulletFont() );
     418             :                         }
     419           0 :                         aNumFmt.SetBulletChar( cBulletChar );
     420             :                     }
     421           0 :                     aNumFmt.SetAbsLSpace( (i+1) * HTML_NUMBUL_MARGINLEFT );
     422           0 :                     aNumFmt.SetFirstLineOffset( HTML_NUMBUL_INDENT );
     423           0 :                     aNumFmt.SetCharFmt( pRefNumFmt->GetCharFmt() );
     424           0 :                     rInfo.GetNumRule()->Set( i, aNumFmt );
     425           0 :                     bChanged = sal_True;
     426             :                 }
     427             :             }
     428           0 :             if( bChanged )
     429           0 :                 pDoc->ChgNumRuleFmts( *rInfo.GetNumRule() );
     430             : 
     431             :             // Beim letzen Append wurde das NumRule-Item und das
     432             :             // NodeNum-Objekt mit kopiert. Beides muessen wir noch
     433             :             // loeschen. Das ResetAttr loescht das NodeNum-Objekt mit!
     434           0 :             pPam->GetNode()->GetTxtNode()->ResetAttr( RES_PARATR_NUMRULE );
     435             : 
     436           0 :             rInfo.Clear();
     437             :         }
     438             :         else
     439             :         {
     440             :             // the next paragraph not numbered first
     441           0 :             SetNodeNum( rInfo.GetLevel(), false );
     442             :         }
     443             :     }
     444             : 
     445             :     // und noch Attribute beenden
     446           0 :     sal_Bool bSetAttrs = sal_False;
     447           0 :     if( pCntxt )
     448             :     {
     449           0 :         EndContext( pCntxt );
     450           0 :         delete pCntxt;
     451           0 :         bSetAttrs = sal_True;
     452             :     }
     453             : 
     454           0 :     if( nToken )
     455           0 :         SetTxtCollAttrs();
     456             : 
     457           0 :     if( bSetAttrs )
     458           0 :         SetAttr();  // Absatz-Atts wegen JavaScript moeglichst schnell setzen
     459             : 
     460           0 : }
     461             : 
     462             : 
     463           0 : void SwHTMLParser::NewNumBulListItem( int nToken )
     464             : {
     465           0 :     sal_uInt8 nLevel = GetNumInfo().GetLevel();
     466           0 :     String aId, aStyle, aClass, aLang, aDir;
     467             :     sal_uInt16 nStart = HTML_LISTHEADER_ON != nToken
     468           0 :                         ? GetNumInfo().GetNodeStartValue( nLevel )
     469           0 :                         : USHRT_MAX;
     470           0 :     if( USHRT_MAX != nStart )
     471           0 :         GetNumInfo().SetNodeStartValue( nLevel );
     472             : 
     473           0 :     const HTMLOptions& rHTMLOptions = GetOptions();
     474           0 :     for (size_t i = rHTMLOptions.size(); i; )
     475             :     {
     476           0 :         const HTMLOption& rOption = rHTMLOptions[--i];
     477           0 :         switch( rOption.GetToken() )
     478             :         {
     479             :             case HTML_O_VALUE:
     480           0 :                 nStart = (sal_uInt16)rOption.GetNumber();
     481           0 :                 break;
     482             :             case HTML_O_ID:
     483           0 :                 aId = rOption.GetString();
     484           0 :                 break;
     485             :             case HTML_O_STYLE:
     486           0 :                 aStyle = rOption.GetString();
     487           0 :                 break;
     488             :             case HTML_O_CLASS:
     489           0 :                 aClass = rOption.GetString();
     490           0 :                 break;
     491             :             case HTML_O_LANG:
     492           0 :                 aLang = rOption.GetString();
     493           0 :                 break;
     494             :             case HTML_O_DIR:
     495           0 :                 aDir = rOption.GetString();
     496           0 :                 break;
     497             :         }
     498             :     }
     499             : 
     500             :     // einen neuen Absatz aufmachen
     501           0 :     if( pPam->GetPoint()->nContent.GetIndex() )
     502           0 :         AppendTxtNode( AM_NOSPACE, sal_False );
     503           0 :     bNoParSpace = sal_False;    // In <LI> wird kein Abstand eingefuegt!
     504             : 
     505           0 :     const bool bCountedInList( HTML_LISTHEADER_ON==nToken ? false : true );
     506             : 
     507           0 :     _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
     508             : 
     509           0 :     String aNumRuleName;
     510           0 :     if( GetNumInfo().GetNumRule() )
     511             :     {
     512           0 :         aNumRuleName = GetNumInfo().GetNumRule()->GetName();
     513             :     }
     514             :     else
     515             :     {
     516           0 :         aNumRuleName = pDoc->GetUniqueNumRuleName();
     517             :         SwNumRule aNumRule( aNumRuleName,
     518           0 :                             SvxNumberFormat::LABEL_WIDTH_AND_POSITION );
     519           0 :         SwNumFmt aNumFmt( aNumRule.Get( 0 ) );
     520             :         // #i63395# - Only apply user defined default bullet font
     521           0 :         if ( numfunc::IsDefBulletFontUserDefined() )
     522             :         {
     523           0 :             aNumFmt.SetBulletFont( &numfunc::GetDefBulletFont() );
     524             :         }
     525           0 :         aNumFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
     526           0 :         aNumFmt.SetBulletChar( cBulletChar );   // das Bulletzeichen !!
     527           0 :         aNumFmt.SetCharFmt( pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_BUL_LEVEL) );
     528           0 :         aNumFmt.SetLSpace( (sal_uInt16)(-HTML_NUMBUL_INDENT) );
     529           0 :         aNumFmt.SetFirstLineOffset( HTML_NUMBUL_INDENT );
     530           0 :         aNumRule.Set( 0, aNumFmt );
     531             : 
     532           0 :         pDoc->MakeNumRule( aNumRuleName, &aNumRule );
     533             : 
     534             :         OSL_ENSURE( !nOpenParaToken,
     535             :                 "Jetzt geht ein offenes Absatz-Element verloren" );
     536             :         // Wir tun so, als ob wir in einem Absatz sind. Dann wird
     537             :         // beim naechsten Absatz wenigstens die Numerierung
     538             :         // weggeschmissen, die nach dem naechsten AppendTxtNode uebernommen
     539             :         // wird.
     540           0 :         nOpenParaToken = static_cast< sal_uInt16 >(nToken);
     541             :     }
     542             : 
     543           0 :     SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
     544           0 :     ((SwCntntNode *)pTxtNode)->SetAttr( SwNumRuleItem(aNumRuleName) );
     545           0 :     pTxtNode->SetAttrListLevel(nLevel);
     546             :     // #i57656# - <IsCounted()> state of text node has to be adjusted accordingly.
     547           0 :     if ( nLevel < MAXLEVEL )
     548             :     {
     549           0 :         pTxtNode->SetCountedInList( bCountedInList );
     550             :     }
     551             :     // #i57919#
     552             :     // correction of refactoring done by cws swnumtree
     553             :     // - <nStart> contains the start value, if the numbering has to be restarted
     554             :     //   at this text node. Value <USHRT_MAX> indicates, that numbering isn't
     555             :     //   restarted at this text node
     556           0 :     if ( nStart != USHRT_MAX )
     557             :     {
     558           0 :         pTxtNode->SetListRestart( true );
     559           0 :         pTxtNode->SetAttrListRestartValue( nStart );
     560             :     }
     561             : 
     562           0 :     if( GetNumInfo().GetNumRule() )
     563           0 :         GetNumInfo().GetNumRule()->SetInvalidRule( sal_True );
     564             : 
     565             :     // Styles parsen
     566           0 :     if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
     567             :     {
     568           0 :         SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
     569           0 :         SvxCSS1PropertyInfo aPropInfo;
     570             : 
     571           0 :         if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
     572             :         {
     573           0 :             DoPositioning( aItemSet, aPropInfo, pCntxt );
     574           0 :             InsertAttrs( aItemSet, aPropInfo, pCntxt );
     575           0 :         }
     576             :     }
     577             : 
     578           0 :     PushContext( pCntxt );
     579             : 
     580             :     // die neue Vorlage setzen
     581           0 :     SetTxtCollAttrs( pCntxt );
     582             : 
     583             :     // Laufbalkenanzeige aktualisieren
     584           0 :     ShowStatline();
     585           0 : }
     586             : 
     587           0 : void SwHTMLParser::EndNumBulListItem( int nToken, sal_Bool bSetColl,
     588             :                                       sal_Bool /*bLastPara*/ )
     589             : {
     590             :     // einen neuen Absatz aufmachen
     591           0 :     if( !nToken && pPam->GetPoint()->nContent.GetIndex() )
     592           0 :         AppendTxtNode( AM_NOSPACE );
     593             : 
     594             :     // Kontext zu dem Token suchen und vom Stack holen
     595           0 :     _HTMLAttrContext *pCntxt = 0;
     596           0 :     sal_uInt16 nPos = aContexts.size();
     597           0 :     nToken &= ~1;
     598           0 :     while( !pCntxt && nPos>nContextStMin )
     599             :     {
     600           0 :         sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
     601           0 :         switch( nCntxtToken )
     602             :         {
     603             :         case HTML_LI_ON:
     604             :         case HTML_LISTHEADER_ON:
     605           0 :             if( !nToken || nToken == nCntxtToken  )
     606             :             {
     607           0 :                 pCntxt = aContexts[nPos];
     608           0 :                 aContexts.erase( aContexts.begin() + nPos );
     609             :             }
     610           0 :             break;
     611             :         case HTML_ORDERLIST_ON:
     612             :         case HTML_UNORDERLIST_ON:
     613             :         case HTML_MENULIST_ON:
     614             :         case HTML_DIRLIST_ON:
     615             :             // keine LI/LH ausserhalb der aktuellen Liste betrachten
     616           0 :             nPos = nContextStMin;
     617           0 :             break;
     618             :         }
     619             :     }
     620             : 
     621             :     // und noch Attribute beenden
     622           0 :     if( pCntxt )
     623             :     {
     624           0 :         EndContext( pCntxt );
     625           0 :         SetAttr();  // Absatz-Atts wegen JavaScript moeglichst schnell setzen
     626           0 :         delete pCntxt;
     627             :     }
     628             : 
     629             :     // und die bisherige Vorlage setzen
     630           0 :     if( bSetColl )
     631           0 :         SetTxtCollAttrs();
     632           0 : }
     633             : 
     634             : 
     635           0 : void SwHTMLParser::SetNodeNum( sal_uInt8 nLevel, bool bCountedInList )
     636             : {
     637           0 :     SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
     638             :     OSL_ENSURE( pTxtNode, "Kein Text-Node an PaM-Position" );
     639             : 
     640             :     OSL_ENSURE( GetNumInfo().GetNumRule(), "Kein Numerierungs-Regel" );
     641           0 :     const String& rName = GetNumInfo().GetNumRule()->GetName();
     642           0 :     ((SwCntntNode *)pTxtNode)->SetAttr( SwNumRuleItem(rName) );
     643             : 
     644           0 :     pTxtNode->SetAttrListLevel( nLevel );
     645           0 :     pTxtNode->SetCountedInList( bCountedInList );
     646             : 
     647             :     // NumRule invalidieren, weil sie durch ein EndAction bereits
     648             :     // auf valid geschaltet worden sein kann.
     649           0 :     GetNumInfo().GetNumRule()->SetInvalidRule( sal_False );
     650           0 : }
     651             : 
     652             : 
     653             : 
     654           0 : void SwHTMLWriter::FillNextNumInfo()
     655             : {
     656           0 :     pNextNumRuleInfo = 0;
     657             : 
     658           0 :     sal_uLong nPos = pCurPam->GetPoint()->nNode.GetIndex() + 1;
     659             : 
     660           0 :     bool bTable = false;
     661           0 :     do
     662             :     {
     663           0 :         const SwNode* pNd = pDoc->GetNodes()[nPos];
     664           0 :         if( pNd->IsTxtNode() )
     665             :         {
     666             :             // Der naechste wird als naechstes ausgegeben.
     667           0 :             pNextNumRuleInfo = new SwHTMLNumRuleInfo( *pNd->GetTxtNode() );
     668             : 
     669             :             // Vor einer Tabelle behalten wir erst einmal die alte Ebene bei,
     670             :             // wenn die gleiche Numerierung hinter der Tabelle
     671             :             // fortgesetzt wird und dort nicht von vorne numeriert
     672             :             // wird. Die Tabelle wird ann beim Import so weit eingeruckt,
     673             :             // wie es der Num-Ebene entspricht.
     674           0 :             if( bTable &&
     675           0 :                 pNextNumRuleInfo->GetNumRule()==GetNumInfo().GetNumRule() &&
     676           0 :                 !pNextNumRuleInfo->IsRestart() )
     677             :             {
     678           0 :                 pNextNumRuleInfo->SetDepth( GetNumInfo().GetDepth() );
     679             :             }
     680             :         }
     681           0 :         else if( pNd->IsTableNode() )
     682             :         {
     683             :             // Eine Tabelle wird uebersprungen, also den Node
     684             :             // hinter der Tabelle betrachten.
     685           0 :             nPos = pNd->EndOfSectionIndex() + 1;
     686           0 :             bTable = true;
     687             :         }
     688             :         else
     689             :         {
     690             :             // In allen anderen Faellen ist die Numerierung erstmal
     691             :             // zu Ende.
     692           0 :             pNextNumRuleInfo = new SwHTMLNumRuleInfo;
     693             :         }
     694             :     }
     695           0 :     while( !pNextNumRuleInfo );
     696           0 : }
     697             : 
     698           0 : void SwHTMLWriter::ClearNextNumInfo()
     699             : {
     700           0 :     delete pNextNumRuleInfo;
     701           0 :     pNextNumRuleInfo = 0;
     702           0 : }
     703             : 
     704           0 : Writer& OutHTML_NumBulListStart( SwHTMLWriter& rWrt,
     705             :                                  const SwHTMLNumRuleInfo& rInfo )
     706             : {
     707           0 :     SwHTMLNumRuleInfo& rPrevInfo = rWrt.GetNumInfo();
     708           0 :     sal_Bool bSameRule = rPrevInfo.GetNumRule() == rInfo.GetNumRule();
     709           0 :     if( bSameRule && rPrevInfo.GetDepth() >= rInfo.GetDepth() &&
     710           0 :         !rInfo.IsRestart() )
     711             :     {
     712           0 :         return rWrt;
     713             :     }
     714             : 
     715           0 :     sal_Bool bStartValue = sal_False;
     716           0 :     if( !bSameRule && rInfo.GetDepth() )
     717             :     {
     718           0 :         String aName( rInfo.GetNumRule()->GetName() );
     719           0 :         if( 0 != rWrt.aNumRuleNames.count( aName ) )
     720             :         {
     721             :             // The rule has been applied before
     722             :             sal_Int16 eType = rInfo.GetNumRule()
     723           0 :                 ->Get( rInfo.GetDepth()-1 ).GetNumberingType();
     724           0 :             if( SVX_NUM_CHAR_SPECIAL != eType && SVX_NUM_BITMAP != eType )
     725             :             {
     726             :                 // If its a numbering rule, the current number should be
     727             :                 // exported as start value, but only if there are no nodes
     728             :                 // within the numbering that have a lower level
     729           0 :                 bStartValue = sal_True;
     730           0 :                 if( rInfo.GetDepth() > 1 )
     731             :                 {
     732             :                     sal_uLong nPos =
     733           0 :                         rWrt.pCurPam->GetPoint()->nNode.GetIndex() + 1;
     734           0 :                     do
     735             :                     {
     736           0 :                         const SwNode* pNd = rWrt.pDoc->GetNodes()[nPos];
     737           0 :                         if( pNd->IsTxtNode() )
     738             :                         {
     739           0 :                             const SwTxtNode *pTxtNd = pNd->GetTxtNode();
     740           0 :                             if( !pTxtNd->GetNumRule() )
     741             :                             {
     742             :                                 // node isn't numbered => check completed
     743           0 :                                 break;
     744             :                             }
     745             : 
     746             :                             OSL_ENSURE(! pTxtNd->IsOutline(),
     747             :                                    "outline not expected");
     748             : 
     749           0 :                             if( pTxtNd->GetActualListLevel() + 1 <
     750           0 :                                 rInfo.GetDepth() )
     751             :                             {
     752             :                                 // node is numbered, but level is lower
     753             :                                 // => check completed
     754           0 :                                 bStartValue = sal_False;
     755           0 :                                 break;
     756             :                             }
     757           0 :                             nPos++;
     758             :                         }
     759           0 :                         else if( pNd->IsTableNode() )
     760             :                         {
     761             :                             // skip table
     762           0 :                             nPos = pNd->EndOfSectionIndex() + 1;
     763             :                         }
     764             :                         else
     765             :                         {
     766             :                             // end node or sections start node -> check
     767             :                             // completed
     768           0 :                             break;
     769             :                         }
     770             :                     }
     771             :                     while( sal_True );
     772             :                 }
     773             :             }
     774             :         }
     775             :         else
     776             :         {
     777           0 :             rWrt.aNumRuleNames.insert( aName );
     778           0 :         }
     779             :     }
     780             : 
     781             : 
     782             :     OSL_ENSURE( rWrt.nLastParaToken == 0,
     783             :                 "<PRE> wurde nicht vor <OL> beendet." );
     784             :     sal_uInt16 nPrevDepth =
     785           0 :         (bSameRule && !rInfo.IsRestart()) ? rPrevInfo.GetDepth() : 0;
     786             : 
     787           0 :     for( sal_uInt16 i=nPrevDepth; i<rInfo.GetDepth(); i++ )
     788             :     {
     789           0 :         rWrt.OutNewLine(); // <OL>/<UL> in eine neue Zeile
     790             : 
     791           0 :         rWrt.aBulletGrfs[i].Erase();
     792           0 :         rtl::OStringBuffer sOut;
     793           0 :         sOut.append('<');
     794           0 :         const SwNumFmt& rNumFmt = rInfo.GetNumRule()->Get( i );
     795           0 :         sal_Int16 eType = rNumFmt.GetNumberingType();
     796           0 :         if( SVX_NUM_CHAR_SPECIAL == eType )
     797             :         {
     798             :             // Aufzaehlungs-Liste: <OL>
     799           0 :             sOut.append(OOO_STRING_SVTOOLS_HTML_unorderlist);
     800             : 
     801             :             // den Typ ueber das Bullet-Zeichen bestimmen
     802           0 :             const sal_Char *pStr = 0;
     803           0 :             switch( rNumFmt.GetBulletChar() )
     804             :             {
     805             :             case HTML_BULLETCHAR_DISC:
     806           0 :                 pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_disc;
     807           0 :                 break;
     808             :             case HTML_BULLETCHAR_CIRCLE:
     809           0 :                 pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_circle;
     810           0 :                 break;
     811             :             case HTML_BULLETCHAR_SQUARE:
     812           0 :                 pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_square;
     813           0 :                 break;
     814             :             }
     815             : 
     816           0 :             if( pStr )
     817             :             {
     818           0 :                 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_type).
     819           0 :                     append('=').append(pStr);
     820             :             }
     821             :         }
     822           0 :         else if( SVX_NUM_BITMAP == eType )
     823             :         {
     824             :             // Aufzaehlungs-Liste: <OL>
     825           0 :             sOut.append(OOO_STRING_SVTOOLS_HTML_unorderlist);
     826           0 :             rWrt.Strm() << sOut.makeStringAndClear().getStr();
     827             : 
     828             :             OutHTML_BulletImage( rWrt,
     829             :                                     0,
     830             :                                     rNumFmt.GetBrush(),
     831           0 :                                     rWrt.aBulletGrfs[i],
     832           0 :                                     rNumFmt.GetGraphicSize(),
     833           0 :                                     rNumFmt.GetGraphicOrientation() );
     834             :         }
     835             :         else
     836             :         {
     837             :             // Numerierungs-Liste: <UL>
     838           0 :             sOut.append(OOO_STRING_SVTOOLS_HTML_orderlist);
     839             : 
     840             :             // den Typ ueber das Format bestimmen
     841           0 :             sal_Char cType = 0;
     842           0 :             switch( eType )
     843             :             {
     844           0 :             case SVX_NUM_CHARS_UPPER_LETTER:    cType = 'A'; break;
     845           0 :             case SVX_NUM_CHARS_LOWER_LETTER:    cType = 'a'; break;
     846           0 :             case SVX_NUM_ROMAN_UPPER:           cType = 'I'; break;
     847           0 :             case SVX_NUM_ROMAN_LOWER:           cType = 'i'; break;
     848             :             }
     849           0 :             if( cType )
     850             :             {
     851           0 :                 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_type).
     852           0 :                     append('=').append(cType);
     853             :             }
     854             : 
     855           0 :             sal_uInt16 nStartVal = rNumFmt.GetStart();
     856           0 :             if( bStartValue && 1 == nStartVal && i == rInfo.GetDepth()-1 )
     857             :             {
     858             :                 // #i51089 - TUNING#
     859           0 :                 if ( rWrt.pCurPam->GetNode()->GetTxtNode()->GetNum() )
     860             :                 {
     861             :                     nStartVal = static_cast< sal_uInt16 >( rWrt.pCurPam->GetNode()
     862           0 :                                 ->GetTxtNode()->GetNumberVector()[i] );
     863             :                 }
     864             :                 else
     865             :                 {
     866             :                     OSL_FAIL( "<OutHTML_NumBulListStart(..) - text node has no number." );
     867             :                 }
     868             :             }
     869           0 :             if( nStartVal != 1 )
     870             :             {
     871           0 :                 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_start).
     872           0 :                     append('=').append(static_cast<sal_Int32>(nStartVal));
     873             :             }
     874             :         }
     875             : 
     876           0 :         if (sOut.getLength())
     877           0 :             rWrt.Strm() << sOut.makeStringAndClear().getStr();
     878             : 
     879           0 :         if( rWrt.bCfgOutStyles )
     880           0 :             OutCSS1_NumBulListStyleOpt( rWrt, *rInfo.GetNumRule(), (sal_uInt8)i );
     881             : 
     882           0 :         rWrt.Strm() << '>';
     883             : 
     884           0 :         rWrt.IncIndentLevel(); // Inhalt von <OL> einruecken
     885           0 :     }
     886             : 
     887           0 :     return rWrt;
     888             : }
     889             : 
     890           0 : Writer& OutHTML_NumBulListEnd( SwHTMLWriter& rWrt,
     891             :                                const SwHTMLNumRuleInfo& rNextInfo )
     892             : {
     893           0 :     SwHTMLNumRuleInfo& rInfo = rWrt.GetNumInfo();
     894           0 :     sal_Bool bSameRule = rNextInfo.GetNumRule() == rInfo.GetNumRule();
     895           0 :     if( bSameRule && rNextInfo.GetDepth() >= rInfo.GetDepth() &&
     896           0 :         !rNextInfo.IsRestart() )
     897             :     {
     898           0 :         return rWrt;
     899             :     }
     900             : 
     901             :     OSL_ENSURE( rWrt.nLastParaToken == 0,
     902             :                 "<PRE> wurde nicht vor </OL> beendet." );
     903             :     sal_uInt16 nNextDepth =
     904           0 :         (bSameRule && !rNextInfo.IsRestart()) ? rNextInfo.GetDepth() : 0;
     905             : 
     906             :     // MIB 23.7.97: Die Schleife muss doch rueckwaerts durchlaufen
     907             :     // werden, weil die Reihenfolge von </OL>/</UL> stimmen muss
     908           0 :     for( sal_uInt16 i=rInfo.GetDepth(); i>nNextDepth; i-- )
     909             :     {
     910           0 :         rWrt.DecIndentLevel(); // Inhalt von <OL> einruecken
     911           0 :         if( rWrt.bLFPossible )
     912           0 :             rWrt.OutNewLine(); // </OL>/</UL> in eine neue Zeile
     913             : 
     914             :         // es wird also eine Liste angefangen oder beendet:
     915           0 :         sal_Int16 eType = rInfo.GetNumRule()->Get( i-1 ).GetNumberingType();
     916             :         const sal_Char *pStr;
     917           0 :         if( SVX_NUM_CHAR_SPECIAL == eType || SVX_NUM_BITMAP == eType)
     918           0 :             pStr = OOO_STRING_SVTOOLS_HTML_unorderlist;
     919             :         else
     920           0 :             pStr = OOO_STRING_SVTOOLS_HTML_orderlist;
     921           0 :         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, sal_False );
     922           0 :         rWrt.bLFPossible = sal_True;
     923             :     }
     924             : 
     925           0 :     return rWrt;
     926             : }
     927             : 
     928             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10