LCOV - code coverage report
Current view: top level - sw/source/filter/html - htmlsect.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 118 401 29.4 %
Date: 2015-06-13 12:38:46 Functions: 7 10 70.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 <rtl/uri.hxx>
      21             : 
      22             : #include <svl/urihelper.hxx>
      23             : #include <vcl/svapp.hxx>
      24             : #include <vcl/wrkwin.hxx>
      25             : #include <editeng/adjustitem.hxx>
      26             : #include <editeng/ulspitem.hxx>
      27             : #include <editeng/formatbreakitem.hxx>
      28             : #include <svtools/htmltokn.h>
      29             : #include <svtools/htmlkywd.hxx>
      30             : #include <sfx2/linkmgr.hxx>
      31             : 
      32             : #include "hintids.hxx"
      33             : #include <fmtornt.hxx>
      34             : #include <fmthdft.hxx>
      35             : #include <fmtcntnt.hxx>
      36             : #include <fmtfsize.hxx>
      37             : #include <fmtclds.hxx>
      38             : #include <fmtanchr.hxx>
      39             : #include <fmtpdsc.hxx>
      40             : #include <fmtsrnd.hxx>
      41             : #include <fmtflcnt.hxx>
      42             : #include "frmatr.hxx"
      43             : #include "doc.hxx"
      44             : #include "pam.hxx"
      45             : #include "ndtxt.hxx"
      46             : #include "shellio.hxx"
      47             : #include "section.hxx"
      48             : #include "poolfmt.hxx"
      49             : #include "pagedesc.hxx"
      50             : #include "swtable.hxx"
      51             : #include "viewsh.hxx"
      52             : #include "swcss1.hxx"
      53             : #include "swhtml.hxx"
      54             : 
      55             : #define CONTEXT_FLAGS_MULTICOL (HTML_CNTXT_STRIP_PARA |  \
      56             :                                 HTML_CNTXT_KEEP_NUMRULE | \
      57             :                                 HTML_CNTXT_KEEP_ATTRS)
      58             : #define CONTEXT_FLAGS_HDRFTR (CONTEXT_FLAGS_MULTICOL)
      59             : #define CONTEXT_FLAGS_FTN (CONTEXT_FLAGS_MULTICOL)
      60             : 
      61             : using namespace ::com::sun::star;
      62             : 
      63          16 : void SwHTMLParser::NewDivision( int nToken )
      64             : {
      65          32 :     OUString aId, aHRef;
      66          32 :     OUString aStyle, aLang, aDir;
      67          32 :     OUString aClass;
      68             :     SvxAdjust eAdjust = HTML_CENTER_ON==nToken ? SVX_ADJUST_CENTER
      69          16 :                                                : SVX_ADJUST_END;
      70             : 
      71          16 :     bool bHeader=false, bFooter=false;
      72          16 :     const HTMLOptions& rHTMLOptions = GetOptions();
      73          54 :     for (size_t i = rHTMLOptions.size(); i; )
      74             :     {
      75          22 :         const HTMLOption& rOption = rHTMLOptions[--i];
      76          22 :         switch( rOption.GetToken() )
      77             :         {
      78             :         case HTML_O_ID:
      79          10 :             aId = rOption.GetString();
      80          10 :             break;
      81             :         case HTML_O_ALIGN:
      82           0 :             if( HTML_DIVISION_ON==nToken )
      83             :                 eAdjust = (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable,
      84           0 :                                                        static_cast< sal_uInt16 >(eAdjust) );
      85           0 :             break;
      86             :         case HTML_O_STYLE:
      87           6 :             aStyle = rOption.GetString();
      88           6 :             break;
      89             :         case HTML_O_CLASS:
      90           6 :             aClass = rOption.GetString();
      91           6 :             break;
      92             :         case HTML_O_LANG:
      93           0 :             aLang = rOption.GetString();
      94           0 :             break;
      95             :         case HTML_O_DIR:
      96           0 :             aDir = rOption.GetString();
      97           0 :             break;
      98             :         case HTML_O_HREF:
      99           0 :             aHRef =  rOption.GetString();
     100           0 :             break;
     101             :         case HTML_O_TITLE:
     102             :             {
     103           0 :                 const OUString& rType = rOption.GetString();
     104           0 :                 if( rType.equalsIgnoreAsciiCase("header") )
     105           0 :                     bHeader = true;
     106           0 :                 else if( rType.equalsIgnoreAsciiCase("footer") )
     107           0 :                     bFooter = true;
     108             :             }
     109             :         }
     110             :     }
     111             : 
     112          16 :     bool bAppended = false;
     113          16 :     if( pPam->GetPoint()->nContent.GetIndex() )
     114             :     {
     115           0 :         AppendTextNode( bHeader||bFooter||!aId.isEmpty()|| !aHRef.isEmpty() ? AM_NORMAL
     116           0 :                                                                 : AM_NOSPACE );
     117           0 :         bAppended = true;
     118             :     }
     119             : 
     120          16 :     _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
     121             : 
     122          16 :     bool bStyleParsed = false, bPositioned = false;
     123          16 :     SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
     124          32 :     SvxCSS1PropertyInfo aPropInfo;
     125          16 :     if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
     126             :     {
     127             :         bStyleParsed = ParseStyleOptions( aStyle, aId, aClass,
     128          14 :                                           aItemSet, aPropInfo, &aLang, &aDir );
     129          14 :         if( bStyleParsed )
     130             :         {
     131          10 :             if ( aPropInfo.nColumnCount >= 2 )
     132             :             {
     133           0 :                 delete pCntxt;
     134           0 :                 NewMultiCol( aPropInfo.nColumnCount );
     135          16 :                 return;
     136             :             }
     137          12 :             bPositioned = HTML_DIVISION_ON == nToken && !aClass.isEmpty() &&
     138             :                           CreateContainer( aClass, aItemSet, aPropInfo,
     139          12 :                                            pCntxt );
     140          10 :             if( !bPositioned )
     141          10 :                 bPositioned = DoPositioning( aItemSet, aPropInfo, pCntxt );
     142             :         }
     143             :     }
     144             : 
     145          16 :     if( !bPositioned && (bHeader || bFooter) && IsNewDoc() )
     146             :     {
     147           0 :         SwPageDesc *pPageDesc = pCSS1Parser->GetMasterPageDesc();
     148           0 :         SwFrameFormat& rPageFormat = pPageDesc->GetMaster();
     149             : 
     150             :         SwFrameFormat *pHdFtFormat;
     151           0 :         bool bNew = false;
     152           0 :         sal_uInt16 nFlags = CONTEXT_FLAGS_HDRFTR;
     153           0 :         if( bHeader )
     154             :         {
     155           0 :             pHdFtFormat = const_cast<SwFrameFormat*>(rPageFormat.GetHeader().GetHeaderFormat());
     156           0 :             if( !pHdFtFormat )
     157             :             {
     158             :                 // noch keine Header, dann erzeuge einen.
     159           0 :                 rPageFormat.SetFormatAttr( SwFormatHeader( true ));
     160           0 :                 pHdFtFormat = const_cast<SwFrameFormat*>(rPageFormat.GetHeader().GetHeaderFormat());
     161           0 :                 bNew = true;
     162             :             }
     163           0 :             nFlags |= HTML_CNTXT_HEADER_DIST;
     164             :         }
     165             :         else
     166             :         {
     167           0 :             pHdFtFormat = const_cast<SwFrameFormat*>(rPageFormat.GetFooter().GetFooterFormat());
     168           0 :             if( !pHdFtFormat )
     169             :             {
     170             :                 // noch keine Footer, dann erzeuge einen.
     171           0 :                 rPageFormat.SetFormatAttr( SwFormatFooter( true ));
     172           0 :                 pHdFtFormat = const_cast<SwFrameFormat*>(rPageFormat.GetFooter().GetFooterFormat());
     173           0 :                 bNew = true;
     174             :             }
     175           0 :             nFlags |= HTML_CNTXT_FOOTER_DIST;
     176             :         }
     177             : 
     178           0 :         const SwFormatContent& rFlyContent = pHdFtFormat->GetContent();
     179           0 :         const SwNodeIndex& rContentStIdx = *rFlyContent.GetContentIdx();
     180             :         SwContentNode *pCNd;
     181             : 
     182           0 :         if( bNew )
     183             :         {
     184           0 :             pCNd = pDoc->GetNodes()[rContentStIdx.GetIndex()+1]
     185           0 :                        ->GetContentNode();
     186             :         }
     187             :         else
     188             :         {
     189             :             // Einen neuen Node zu Beginn der Section anlegen
     190           0 :             SwNodeIndex aSttIdx( rContentStIdx, 1 );
     191           0 :             pCNd = pDoc->GetNodes().MakeTextNode( aSttIdx,
     192           0 :                             pCSS1Parser->GetTextCollFromPool(RES_POOLCOLL_TEXT));
     193             : 
     194             :             // Den bisherigen Inhalt der Section loeschen
     195           0 :             SwPaM aDelPam( aSttIdx );
     196           0 :             aDelPam.SetMark();
     197             : 
     198             :             const SwStartNode *pStNd =
     199           0 :                 static_cast<const SwStartNode *>( &rContentStIdx.GetNode() );
     200           0 :             aDelPam.GetPoint()->nNode = pStNd->EndOfSectionIndex() - 1;
     201             : 
     202           0 :             pDoc->getIDocumentContentOperations().DelFullPara( aDelPam );
     203             : 
     204             :             // Die Seitenvorlage aktualisieren
     205           0 :             for( size_t i=0; i < pDoc->GetPageDescCnt(); i++ )
     206             :             {
     207           0 :                 if( RES_POOLPAGE_HTML == pDoc->GetPageDesc(i).GetPoolFormatId() )
     208             :                 {
     209           0 :                     pDoc->ChgPageDesc( i, *pPageDesc );
     210           0 :                     break;
     211             :                 }
     212           0 :             }
     213             :         }
     214             : 
     215           0 :         SwPosition aNewPos( SwNodeIndex( rContentStIdx, 1 ), SwIndex( pCNd, 0 ) );
     216           0 :         SaveDocContext( pCntxt, nFlags, &aNewPos );
     217             :     }
     218          54 :     else if( !bPositioned && aId.getLength() > 9 &&
     219          30 :              (aId[0] == 's' || aId[0] == 'S' ) &&
     220           0 :              (aId[1] == 'd' || aId[1] == 'D' ) )
     221             :     {
     222           0 :         bool bEndNote = false, bFootNote = false;
     223           0 :         if( aId.startsWithIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdendnote ) )
     224           0 :             bEndNote = true;
     225           0 :         else if( aId.startsWithIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdfootnote ) )
     226           0 :             bFootNote = true;
     227           0 :         if( bFootNote || bEndNote )
     228             :         {
     229           0 :             SwNodeIndex *pStartNdIdx = GetFootEndNoteSection( aId );
     230           0 :             if( pStartNdIdx )
     231             :             {
     232             :                 SwContentNode *pCNd =
     233           0 :                     pDoc->GetNodes()[pStartNdIdx->GetIndex()+1]->GetContentNode();
     234           0 :                 SwNodeIndex aTmpSwNodeIndex = SwNodeIndex(*pCNd);
     235           0 :                 SwPosition aNewPos( aTmpSwNodeIndex, SwIndex( pCNd, 0 ) );
     236           0 :                 SaveDocContext( pCntxt, CONTEXT_FLAGS_FTN, &aNewPos );
     237           0 :                 aId.clear();
     238           0 :                 aPropInfo.aId.clear();
     239             :             }
     240             :         }
     241             :     }
     242             : 
     243             :     // Bereiche fuegen wir in Rahmen nur dann ein, wenn der Bereich gelinkt ist.
     244          16 :     if( (!aId.isEmpty() && !bPositioned) || !aHRef.isEmpty()  )
     245             :     {
     246             :         // Bereich einfuegen (muss vor dem Setzten von Attributen erfolgen,
     247             :         // weil die Section vor der PaM-Position eingefuegt.
     248             : 
     249             :         // wenn wir im ersten Node einer Section stehen, wir die neue
     250             :         // Section nicht in der aktuellen, sondern vor der aktuellen
     251             :         // Section eingefuegt. Deshalb muessen wir dann einen Node
     252             :         // einfuegen. UND IN LOESCHEN!!!
     253           9 :         if( !bAppended )
     254             :         {
     255           9 :             SwNodeIndex aPrvNdIdx( pPam->GetPoint()->nNode, -1 );
     256           9 :             if (aPrvNdIdx.GetNode().IsSectionNode())
     257             :             {
     258           4 :                 AppendTextNode();
     259           4 :                 bAppended = true;
     260           9 :             }
     261             :         }
     262           9 :         _HTMLAttrs *pPostIts = bAppended ? 0 : new _HTMLAttrs;
     263           9 :         SetAttr( true, true, pPostIts );
     264             : 
     265             :         // Namen der Section eindeutig machen
     266           9 :         const OUString aName( pDoc->GetUniqueSectionName( !aId.isEmpty() ? &aId : 0 ) );
     267             : 
     268           9 :         if( !aHRef.isEmpty() )
     269             :         {
     270           0 :             sal_Unicode cDelim = 255U;
     271           0 :             sal_Int32 nPos = aHRef.lastIndexOf( cDelim );
     272           0 :             sal_Int32 nPos2 = -1;
     273           0 :             if( nPos != -1 )
     274             :             {
     275           0 :                 nPos2 = aHRef.lastIndexOf( cDelim, nPos );
     276           0 :                 if( nPos2 != -1 )
     277             :                 {
     278           0 :                     sal_Int32 nTmp = nPos;
     279           0 :                     nPos = nPos2;
     280           0 :                     nPos2 = nTmp;
     281             :                 }
     282             :             }
     283           0 :             OUString aURL;
     284           0 :             if( nPos == -1 )
     285             :             {
     286           0 :                 aURL = URIHelper::SmartRel2Abs(INetURLObject( sBaseURL ), aHRef, Link<OUString *, bool>(), false);
     287             :             }
     288             :             else
     289             :             {
     290           0 :                 aURL = URIHelper::SmartRel2Abs(INetURLObject( sBaseURL ), aHRef.copy( 0, nPos ), Link<OUString *, bool>(), false );
     291           0 :                 aURL += OUString(sfx2::cTokenSeparator);
     292           0 :                 if( nPos2 == -1 )
     293             :                 {
     294           0 :                     aURL += aHRef.copy( nPos+1 );
     295             :                 }
     296             :                 else
     297             :                 {
     298           0 :                     aURL += aHRef.copy( nPos+1, nPos2 - (nPos+1) );
     299           0 :                     aURL += OUString(sfx2::cTokenSeparator);
     300           0 :                     aURL += rtl::Uri::decode( aHRef.copy( nPos2+1 ),
     301             :                                               rtl_UriDecodeWithCharset,
     302           0 :                                               RTL_TEXTENCODING_ISO_8859_1 );
     303             :                 }
     304             :             }
     305           0 :             aHRef = aURL;
     306             :         }
     307             : 
     308           9 :         SwSectionData aSection( (!aHRef.isEmpty()) ? FILE_LINK_SECTION
     309          18 :                                         : CONTENT_SECTION, aName );
     310           9 :         if( !aHRef.isEmpty() )
     311             :         {
     312           0 :             aSection.SetLinkFileName( aHRef );
     313           0 :             aSection.SetProtectFlag(true);
     314             :         }
     315             : 
     316           9 :         SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
     317          18 :                                 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
     318           9 :         if( !IsNewDoc() )
     319           0 :             Reader::ResetFrameFormatAttrs(aFrmItemSet );
     320             : 
     321             :         const SfxPoolItem *pItem;
     322           9 :         if( SfxItemState::SET == aItemSet.GetItemState( RES_BACKGROUND, false,
     323           9 :                                                    &pItem ) )
     324             :         {
     325           0 :             aFrmItemSet.Put( *pItem );
     326           0 :             aItemSet.ClearItem( RES_BACKGROUND );
     327             :         }
     328           9 :         if( SfxItemState::SET == aItemSet.GetItemState( RES_FRAMEDIR, false,
     329           9 :                                                    &pItem ) )
     330             :         {
     331           0 :             aFrmItemSet.Put( *pItem );
     332           0 :             aItemSet.ClearItem( RES_FRAMEDIR );
     333             :         }
     334             : 
     335           9 :         pDoc->InsertSwSection( *pPam, aSection, 0, &aFrmItemSet, false );
     336             : 
     337             :         // ggfs. einen Bereich anspringen
     338           9 :         if( JUMPTO_REGION == eJumpTo && aName == sJmpMark )
     339             :         {
     340           0 :             bChkJumpMark = true;
     341           0 :             eJumpTo = JUMPTO_NONE;
     342             :         }
     343             : 
     344             :         SwTextNode* pOldTextNd =
     345           9 :             (bAppended) ? 0 : pPam->GetPoint()->nNode.GetNode().GetTextNode();
     346             : 
     347           9 :         pPam->Move( fnMoveBackward );
     348             : 
     349             :         // PageDesc- und SwFormatBreak Attribute vom aktuellen Node in den
     350             :         // (ersten) Node des Bereich verschieben.
     351           9 :         if( pOldTextNd )
     352           5 :             MovePageDescAttrs( pOldTextNd, pPam->GetPoint()->nNode.GetIndex(),
     353           5 :                                true  );
     354             : 
     355           9 :         if( pPostIts )
     356             :         {
     357             :             // noch vorhandene PostIts in den ersten Absatz
     358             :             // der Tabelle setzen
     359           5 :             InsertAttrs( *pPostIts );
     360           5 :             delete pPostIts;
     361           5 :             pPostIts = 0;
     362             :         }
     363             : 
     364           9 :         pCntxt->SetSpansSection( true );
     365             : 
     366             :         // keine text::Bookmarks mit dem gleichen Namen wie Bereiche einfuegen
     367           9 :         if( !aPropInfo.aId.isEmpty() && aPropInfo.aId==aName )
     368          18 :             aPropInfo.aId.clear();
     369             :     }
     370             :     else
     371             :     {
     372           7 :         pCntxt->SetAppendMode( AM_NOSPACE );
     373             :     }
     374             : 
     375          16 :     if( SVX_ADJUST_END != eAdjust )
     376             :     {
     377           0 :         InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eAdjust, RES_PARATR_ADJUST), pCntxt );
     378             :     }
     379             : 
     380             :     // Style parsen
     381          16 :     if( bStyleParsed )
     382          10 :         InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
     383             : 
     384          48 :     PushContext( pCntxt );
     385             : }
     386             : 
     387          15 : void SwHTMLParser::EndDivision( int /*nToken*/ )
     388             : {
     389             :     // Stack-Eintrag zu dem Token suchen (weil wir noch den Div-Stack
     390             :     // haben unterscheiden wir erst einmal nicht zwischen DIV und CENTER
     391          15 :     _HTMLAttrContext *pCntxt = 0;
     392          15 :     auto nPos = aContexts.size();
     393          45 :     while( !pCntxt && nPos>nContextStMin )
     394             :     {
     395          15 :         switch( aContexts[--nPos]->GetToken() )
     396             :         {
     397             :         case HTML_CENTER_ON:
     398             :         case HTML_DIVISION_ON:
     399          15 :             pCntxt = aContexts[nPos];
     400          15 :             aContexts.erase( aContexts.begin() + nPos );
     401          15 :             break;
     402             :         }
     403             :     }
     404             : 
     405          15 :     if( pCntxt )
     406             :     {
     407             :         // Attribute beenden
     408          15 :         EndContext( pCntxt );
     409          15 :         SetAttr();  // Absatz-Atts wegen JavaScript moeglichst schnell setzen
     410             : 
     411          15 :         delete pCntxt;
     412             :     }
     413          15 : }
     414             : 
     415           0 : void SwHTMLParser::FixHeaderFooterDistance( bool bHeader,
     416             :                                             const SwPosition *pOldPos )
     417             : {
     418           0 :     SwPageDesc *pPageDesc = pCSS1Parser->GetMasterPageDesc();
     419           0 :     SwFrameFormat& rPageFormat = pPageDesc->GetMaster();
     420             : 
     421             :     SwFrameFormat *pHdFtFormat =
     422           0 :         bHeader ? const_cast<SwFrameFormat*>(rPageFormat.GetHeader().GetHeaderFormat())
     423           0 :                 : const_cast<SwFrameFormat*>(rPageFormat.GetFooter().GetFooterFormat());
     424             :     OSL_ENSURE( pHdFtFormat, "Doch keine Kopf- oder Fusszeile" );
     425             : 
     426           0 :     const SwFormatContent& rFlyContent = pHdFtFormat->GetContent();
     427           0 :     const SwNodeIndex& rContentStIdx = *rFlyContent.GetContentIdx();
     428             : 
     429             :     sal_uLong nPrvNxtIdx;
     430           0 :     if( bHeader )
     431             :     {
     432           0 :         nPrvNxtIdx = rContentStIdx.GetNode().EndOfSectionIndex()-1;
     433             :     }
     434             :     else
     435             :     {
     436           0 :         nPrvNxtIdx = pOldPos->nNode.GetIndex() - 1;
     437             :     }
     438             : 
     439           0 :     sal_uInt16 nSpace = 0;
     440           0 :     SwTextNode *pTextNode = pDoc->GetNodes()[nPrvNxtIdx]->GetTextNode();
     441           0 :     if( pTextNode )
     442             :     {
     443             :         const SvxULSpaceItem& rULSpace =
     444             :             static_cast<const SvxULSpaceItem&>(pTextNode
     445           0 :                 ->SwContentNode::GetAttr( RES_UL_SPACE ));
     446             : 
     447             :         // Der untere Absatz-Abstand wird zum Abstand zur
     448             :         // Kopf- oder Fusszeile
     449           0 :         nSpace = rULSpace.GetLower();
     450             : 
     451             :         // und anschliessend auf einen vernuenftigen Wert
     452             :         // gesetzt
     453             :         const SvxULSpaceItem& rCollULSpace =
     454           0 :             pTextNode->GetAnyFormatColl().GetULSpace();
     455           0 :         if( rCollULSpace.GetUpper() == rULSpace.GetUpper() )
     456           0 :             pTextNode->ResetAttr( RES_UL_SPACE );
     457             :         else
     458             :             pTextNode->SetAttr(
     459           0 :                 SvxULSpaceItem( rULSpace.GetUpper(),
     460           0 :                                 rCollULSpace.GetLower(), RES_UL_SPACE ) );
     461             :     }
     462             : 
     463           0 :     if( bHeader )
     464             :     {
     465           0 :         nPrvNxtIdx = pOldPos->nNode.GetIndex();
     466             :     }
     467             :     else
     468             :     {
     469           0 :         nPrvNxtIdx = rContentStIdx.GetIndex() + 1;
     470             :     }
     471             : 
     472           0 :     pTextNode = pDoc->GetNodes()[nPrvNxtIdx]
     473           0 :                     ->GetTextNode();
     474           0 :     if( pTextNode )
     475             :     {
     476             :         const SvxULSpaceItem& rULSpace =
     477             :             static_cast<const SvxULSpaceItem&>(pTextNode
     478           0 :                 ->SwContentNode::GetAttr( RES_UL_SPACE ));
     479             : 
     480             :         // Der obere Absatz-Abstand wird zum Abstand zur
     481             :         // Kopf- oder Fusszeile, wenn er groesser ist als
     482             :         // der untere vom Absatz davor
     483           0 :         if( rULSpace.GetUpper() > nSpace )
     484           0 :             nSpace = rULSpace.GetUpper();
     485             : 
     486             :         // und anschliessend auf einen vernuenftigen Wert gesetzt
     487             :         const SvxULSpaceItem& rCollULSpace =
     488           0 :             pTextNode->GetAnyFormatColl().GetULSpace();
     489           0 :         if( rCollULSpace.GetLower() == rULSpace.GetLower() )
     490           0 :             pTextNode->ResetAttr( RES_UL_SPACE );
     491             :         else
     492             :             pTextNode->SetAttr(
     493           0 :                 SvxULSpaceItem( rCollULSpace.GetUpper(),
     494           0 :                                 rULSpace.GetLower(), RES_UL_SPACE ) );
     495             :     }
     496             : 
     497           0 :     SvxULSpaceItem aULSpace( RES_UL_SPACE );
     498           0 :     if( bHeader )
     499           0 :         aULSpace.SetLower( nSpace );
     500             :     else
     501           0 :         aULSpace.SetUpper( nSpace );
     502             : 
     503           0 :     pHdFtFormat->SetFormatAttr( aULSpace );
     504           0 : }
     505             : 
     506           9 : bool SwHTMLParser::EndSection( bool bLFStripped )
     507             : {
     508          18 :     SwEndNode *pEndNd = pDoc->GetNodes()[pPam->GetPoint()->nNode.GetIndex()+1]
     509          18 :                             ->GetEndNode();
     510           9 :     if( pEndNd && pEndNd->StartOfSectionNode()->IsSectionNode() )
     511             :     {
     512             :         // den Bereich beenden
     513           9 :         if( !bLFStripped )
     514           9 :             StripTrailingPara();
     515           9 :         pPam->Move( fnMoveForward );
     516           9 :         return true;
     517             :     }
     518             : 
     519             :     OSL_ENSURE( false, "Falsche PaM Position Beenden eines Bereichs" );
     520             : 
     521           0 :     return false;
     522             : }
     523             : 
     524           0 : bool SwHTMLParser::EndSections( bool bLFStripped )
     525             : {
     526           0 :     bool bSectionClosed = false;
     527           0 :     auto nPos = aContexts.size();
     528           0 :     while( nPos>nContextStMin )
     529             :     {
     530           0 :         _HTMLAttrContext *pCntxt = aContexts[--nPos];
     531           0 :         if( pCntxt->GetSpansSection() && EndSection( bLFStripped ) )
     532             :         {
     533           0 :             bSectionClosed = true;
     534           0 :             pCntxt->SetSpansSection( false );
     535           0 :             bLFStripped = false;
     536             :         }
     537             :     }
     538             : 
     539           0 :     return bSectionClosed;
     540             : }
     541             : 
     542           0 : void SwHTMLParser::NewMultiCol( sal_uInt16 columnsFromCss )
     543             : {
     544           0 :     OUString aId;
     545           0 :     OUString aStyle, aClass, aLang, aDir;
     546           0 :     long nWidth = 100;
     547           0 :     sal_uInt16 nCols = columnsFromCss, nGutter = 10;
     548           0 :     bool bPrcWidth = true;
     549             : 
     550           0 :     const HTMLOptions& rHTMLOptions = GetOptions();
     551           0 :     for (size_t i = rHTMLOptions.size(); i; )
     552             :     {
     553           0 :         const HTMLOption& rOption = rHTMLOptions[--i];
     554           0 :         switch( rOption.GetToken() )
     555             :         {
     556             :         case HTML_O_ID:
     557           0 :             aId = rOption.GetString();
     558           0 :             break;
     559             :         case HTML_O_STYLE:
     560           0 :             aStyle = rOption.GetString();
     561           0 :             break;
     562             :         case HTML_O_CLASS:
     563           0 :             aClass = rOption.GetString();
     564           0 :             break;
     565             :         case HTML_O_LANG:
     566           0 :             aLang = rOption.GetString();
     567           0 :             break;
     568             :         case HTML_O_DIR:
     569           0 :             aDir = rOption.GetString();
     570           0 :             break;
     571             :         case HTML_O_COLS:
     572           0 :             nCols = (sal_uInt16)rOption.GetNumber();
     573           0 :             break;
     574             :         case HTML_O_WIDTH:
     575           0 :             nWidth = rOption.GetNumber();
     576           0 :             bPrcWidth = (rOption.GetString().indexOf('%') != -1);
     577           0 :             if( bPrcWidth && nWidth>100 )
     578           0 :                 nWidth = 100;
     579           0 :             break;
     580             :         case HTML_O_GUTTER:
     581           0 :             nGutter = (sal_uInt16)rOption.GetNumber();
     582           0 :             break;
     583             : 
     584             :         }
     585             :     }
     586             : 
     587           0 :     _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_MULTICOL_ON );
     588             : 
     589             :     //.is the multicol elememt contained in a container? That may be the
     590             :     // case for 5.0 documents.
     591           0 :     bool bInCntnr = false;
     592           0 :     auto i = aContexts.size();
     593           0 :     while( !bInCntnr && i > nContextStMin )
     594           0 :         bInCntnr = 0 != aContexts[--i]->GetFrmItemSet();
     595             : 
     596             :     // Parse style sheets, but don't position anything by now.
     597           0 :     bool bStyleParsed = false;
     598           0 :     SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
     599           0 :     SvxCSS1PropertyInfo aPropInfo;
     600           0 :     if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
     601             :         bStyleParsed = ParseStyleOptions( aStyle, aId, aClass,
     602           0 :                                           aItemSet, aPropInfo, &aLang, &aDir );
     603             : 
     604             :     // Calculate width.
     605           0 :     sal_uInt8 nPrcWidth = bPrcWidth ? (sal_uInt8)nWidth : 0;
     606           0 :     SwTwips nTwipWidth = 0;
     607           0 :     if( !bPrcWidth && nWidth && Application::GetDefaultDevice() )
     608             :     {
     609             :         nTwipWidth = Application::GetDefaultDevice()
     610             :                              ->PixelToLogic( Size(nWidth, 0),
     611           0 :                                              MapMode(MAP_TWIP) ).Width();
     612             :     }
     613             : 
     614           0 :     if( !nPrcWidth && nTwipWidth < MINFLY )
     615           0 :         nTwipWidth = MINFLY;
     616             : 
     617             :     // Do positioning.
     618           0 :     bool bPositioned = false;
     619           0 :     if( bInCntnr || SwCSS1Parser::MayBePositioned( aPropInfo, true ) )
     620             :     {
     621           0 :         SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
     622           0 :                                 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
     623           0 :         if( !IsNewDoc() )
     624           0 :             Reader::ResetFrameFormatAttrs(aFrmItemSet );
     625             : 
     626             :         SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE, aItemSet, aPropInfo,
     627           0 :                                 aFrmItemSet );
     628             : 
     629             :         // The width is either the WIDTH attribute's value or contained
     630             :         // in some style option.
     631           0 :         SetVarSize( aItemSet, aPropInfo, aFrmItemSet, nTwipWidth, nPrcWidth );
     632             : 
     633           0 :         SetSpace( Size(0,0), aItemSet, aPropInfo, aFrmItemSet );
     634             : 
     635             :         // Set some other frame attributes. If the background is set, its
     636             :         // it will be cleared here. That for, it won't be set at the section,
     637             :         // too.
     638             :         SetFrameFormatAttrs( aItemSet, aPropInfo,
     639             :                         HTML_FF_BOX|HTML_FF_BACKGROUND|HTML_FF_PADDING|HTML_FF_DIRECTION,
     640           0 :                         aFrmItemSet );
     641             : 
     642             :         // Insert fly frame. If the are columns, the fly frame's name is not
     643             :         // the sections name but a generated one.
     644           0 :         OUString aFlyName( aEmptyOUStr );
     645           0 :         if( nCols < 2 )
     646             :         {
     647           0 :             aFlyName = aId;
     648           0 :             aPropInfo.aId.clear();
     649             :         }
     650             : 
     651           0 :         InsertFlyFrame( aFrmItemSet, pCntxt, aFlyName, CONTEXT_FLAGS_ABSPOS );
     652             : 
     653           0 :         pCntxt->SetPopStack( true );
     654           0 :         bPositioned = true;
     655             :     }
     656             : 
     657           0 :     bool bAppended = false;
     658           0 :     if( !bPositioned )
     659             :     {
     660           0 :         if( pPam->GetPoint()->nContent.GetIndex() )
     661             :         {
     662           0 :             AppendTextNode( AM_SPACE );
     663           0 :             bAppended = true;
     664             :         }
     665             :         else
     666             :         {
     667           0 :             AddParSpace();
     668             :         }
     669             :     }
     670             : 
     671             :     // If there are less then 2 columns, no section is inserted.
     672           0 :     if( nCols >= 2 )
     673             :     {
     674           0 :         if( !bAppended )
     675             :         {
     676             :             // If the pam is at the start of a section, a additional text
     677             :             // node must be inserted. Otherwise, the new section will be
     678             :             // inserted in front of the old one.
     679           0 :             SwNodeIndex aPrvNdIdx( pPam->GetPoint()->nNode, -1 );
     680           0 :             if (aPrvNdIdx.GetNode().IsSectionNode())
     681             :             {
     682           0 :                 AppendTextNode();
     683           0 :                 bAppended = true;
     684           0 :             }
     685             :         }
     686           0 :         _HTMLAttrs *pPostIts = bAppended ? 0 : new _HTMLAttrs;
     687           0 :         SetAttr( true, true, pPostIts );
     688             : 
     689             :         // Make section name unique.
     690           0 :         OUString aName( pDoc->GetUniqueSectionName( !aId.isEmpty() ? &aId : 0 ) );
     691           0 :         SwSectionData aSection( CONTENT_SECTION, aName );
     692             : 
     693           0 :         SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
     694           0 :                                 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
     695           0 :         if( !IsNewDoc() )
     696           0 :             Reader::ResetFrameFormatAttrs(aFrmItemSet );
     697             : 
     698           0 :         if( nGutter && Application::GetDefaultDevice() )
     699             :         {
     700             :             nGutter = (sal_uInt16)Application::GetDefaultDevice()
     701             :                              ->PixelToLogic( Size(nGutter, 0),
     702           0 :                                              MapMode(MAP_TWIP) ).Width();
     703             :         }
     704             : 
     705           0 :         SwFormatCol aFormatCol;
     706           0 :         nPrcWidth = 100;
     707             : 
     708           0 :         aFormatCol.Init( nCols, nGutter, USHRT_MAX );
     709           0 :         aFrmItemSet.Put( aFormatCol );
     710             : 
     711             :         const SfxPoolItem *pItem;
     712           0 :         if( SfxItemState::SET == aItemSet.GetItemState( RES_BACKGROUND, false,
     713           0 :                                                    &pItem ) )
     714             :         {
     715           0 :             aFrmItemSet.Put( *pItem );
     716           0 :             aItemSet.ClearItem( RES_BACKGROUND );
     717             :         }
     718           0 :         if( SfxItemState::SET == aItemSet.GetItemState( RES_FRAMEDIR, false,
     719           0 :                                                    &pItem ) )
     720             :         {
     721           0 :             aFrmItemSet.Put( *pItem );
     722           0 :             aItemSet.ClearItem( RES_FRAMEDIR );
     723             :         }
     724           0 :         pDoc->InsertSwSection( *pPam, aSection, 0, &aFrmItemSet, false );
     725             : 
     726             :         // Jump to section, if this is requested.
     727           0 :         if( JUMPTO_REGION == eJumpTo && aName == sJmpMark )
     728             :         {
     729           0 :             bChkJumpMark = true;
     730           0 :             eJumpTo = JUMPTO_NONE;
     731             :         }
     732             : 
     733             :         SwTextNode* pOldTextNd =
     734           0 :             (bAppended) ? 0 : pPam->GetPoint()->nNode.GetNode().GetTextNode();
     735             : 
     736           0 :         pPam->Move( fnMoveBackward );
     737             : 
     738             :         // Move PageDesc and SwFormatBreak attributes of the current node
     739             :         // to the section's first node.
     740           0 :         if( pOldTextNd )
     741           0 :             MovePageDescAttrs( pOldTextNd, pPam->GetPoint()->nNode.GetIndex(),
     742           0 :                                true  );
     743             : 
     744           0 :         if( pPostIts )
     745             :         {
     746             :             // Move pending PostIts into the section.
     747           0 :             InsertAttrs( *pPostIts );
     748           0 :             delete pPostIts;
     749           0 :             pPostIts = 0;
     750             :         }
     751             : 
     752           0 :         pCntxt->SetSpansSection( true );
     753             : 
     754             :         // Insert a bookmark if its name differs from the section's name only.
     755           0 :         if( !aPropInfo.aId.isEmpty() && aPropInfo.aId==aName )
     756           0 :             aPropInfo.aId.clear();
     757             :     }
     758             : 
     759             :     // Additional attributes must be set as hard ones.
     760           0 :     if( bStyleParsed )
     761           0 :         InsertAttrs( aItemSet, aPropInfo, pCntxt, true );
     762             : 
     763           0 :     PushContext( pCntxt );
     764           0 : }
     765             : 
     766           1 : void SwHTMLParser::InsertFlyFrame( const SfxItemSet& rItemSet,
     767             :                                    _HTMLAttrContext *pCntxt,
     768             :                                    const OUString& rName,
     769             :                                    sal_uInt16 nFlags )
     770             : {
     771             :     RndStdIds eAnchorId =
     772           1 :         static_cast<const SwFormatAnchor&>(rItemSet.Get( RES_ANCHOR )).GetAnchorId();
     773             : 
     774             :     // Den Rahmen anlegen
     775           1 :     SwFlyFrameFormat* pFlyFormat = pDoc->MakeFlySection( eAnchorId, pPam->GetPoint(),
     776           1 :                                                     &rItemSet );
     777             :     // Ggf. den Namen setzen
     778           1 :     if( !rName.isEmpty() )
     779           1 :         pFlyFormat->SetName( rName );
     780             : 
     781           1 :     RegisterFlyFrm( pFlyFormat );
     782             : 
     783           1 :     const SwFormatContent& rFlyContent = pFlyFormat->GetContent();
     784           1 :     const SwNodeIndex& rFlyCntIdx = *rFlyContent.GetContentIdx();
     785           2 :     SwContentNode *pCNd = pDoc->GetNodes()[rFlyCntIdx.GetIndex()+1]
     786           2 :                             ->GetContentNode();
     787             : 
     788           1 :     SwPosition aNewPos( SwNodeIndex( rFlyCntIdx, 1 ), SwIndex( pCNd, 0 ) );
     789           1 :     SaveDocContext( pCntxt, nFlags, &aNewPos );
     790           1 : }
     791             : 
     792           5 : void SwHTMLParser::MovePageDescAttrs( SwNode *pSrcNd,
     793             :                                       sal_uLong nDestIdx,
     794             :                                       bool bFormatBreak )
     795             : {
     796             :     SwContentNode* pDestContentNd =
     797           5 :         pDoc->GetNodes()[nDestIdx]->GetContentNode();
     798             : 
     799             :     OSL_ENSURE( pDestContentNd, "Wieso ist das Ziel kein Content-Node?" );
     800             : 
     801           5 :     if( pSrcNd->IsContentNode() )
     802             :     {
     803           5 :         SwContentNode* pSrcContentNd = pSrcNd->GetContentNode();
     804             : 
     805             :         const SfxPoolItem* pItem;
     806          10 :         if( SfxItemState::SET == pSrcContentNd->GetSwAttrSet()
     807           5 :                 .GetItemState( RES_PAGEDESC, false, &pItem ) &&
     808           0 :             static_cast<const SwFormatPageDesc *>(pItem)->GetPageDesc() )
     809             :         {
     810           0 :             pDestContentNd->SetAttr( *pItem );
     811           0 :             pSrcContentNd->ResetAttr( RES_PAGEDESC );
     812             :         }
     813          10 :         if( SfxItemState::SET == pSrcContentNd->GetSwAttrSet()
     814           5 :                 .GetItemState( RES_BREAK, false, &pItem ) )
     815             :         {
     816           0 :             switch( static_cast<const SvxFormatBreakItem *>(pItem)->GetBreak() )
     817             :             {
     818             :             case SVX_BREAK_PAGE_BEFORE:
     819             :             case SVX_BREAK_PAGE_AFTER:
     820             :             case SVX_BREAK_PAGE_BOTH:
     821           0 :                 if( bFormatBreak )
     822           0 :                     pDestContentNd->SetAttr( *pItem );
     823           0 :                 pSrcContentNd->ResetAttr( RES_BREAK );
     824             :             default:
     825             :                 ;
     826             :             }
     827             :         }
     828             :     }
     829           0 :     else if( pSrcNd->IsTableNode() )
     830             :     {
     831           0 :         SwFrameFormat *pFrameFormat = pSrcNd->GetTableNode()->GetTable().GetFrameFormat();
     832             : 
     833             :         const SfxPoolItem* pItem;
     834           0 :         if( SfxItemState::SET == pFrameFormat->GetAttrSet().
     835           0 :                 GetItemState( RES_PAGEDESC, false, &pItem ) )
     836             :         {
     837           0 :             pDestContentNd->SetAttr( *pItem );
     838           0 :             pFrameFormat->ResetFormatAttr( RES_PAGEDESC );
     839             :         }
     840             :     }
     841         182 : }
     842             : 
     843             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11