1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <rtl/uri.hxx>
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>
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>
46 #include "shellio.hxx"
47 #include "section.hxx"
48 #include "poolfmt.hxx"
49 #include "pagedesc.hxx"
50 #include "swtable.hxx"
56 using namespace ::com::sun::star
;
58 void SwHTMLParser::NewDivision( int nToken
)
61 OUString aStyle
, aLang
, aDir
;
63 SvxAdjust eAdjust
= HTML_CENTER_ON
==nToken
? SVX_ADJUST_CENTER
66 bool bHeader
=false, bFooter
=false;
67 const HTMLOptions
& rHTMLOptions
= GetOptions();
68 for (size_t i
= rHTMLOptions
.size(); i
; )
70 const HTMLOption
& rOption
= rHTMLOptions
[--i
];
71 switch( rOption
.GetToken() )
74 aId
= rOption
.GetString();
77 if( HTML_DIVISION_ON
==nToken
)
78 eAdjust
= (SvxAdjust
)rOption
.GetEnum( aHTMLPAlignTable
,
79 static_cast< sal_uInt16
>(eAdjust
) );
82 aStyle
= rOption
.GetString();
85 aClass
= rOption
.GetString();
88 aLang
= rOption
.GetString();
91 aDir
= rOption
.GetString();
94 aHRef
= rOption
.GetString();
98 const OUString
& rType
= rOption
.GetString();
99 if( rType
.equalsIgnoreAsciiCase("header") )
101 else if( rType
.equalsIgnoreAsciiCase("footer") )
107 bool bAppended
= false;
108 if( m_pPam
->GetPoint()->nContent
.GetIndex() )
110 AppendTextNode( bHeader
||bFooter
||!aId
.isEmpty()|| !aHRef
.isEmpty() ? AM_NORMAL
115 HTMLAttrContext
*pCntxt
= new HTMLAttrContext( static_cast< sal_uInt16
>(nToken
) );
117 bool bStyleParsed
= false, bPositioned
= false;
118 SfxItemSet
aItemSet( m_pDoc
->GetAttrPool(), m_pCSS1Parser
->GetWhichMap() );
119 SvxCSS1PropertyInfo aPropInfo
;
120 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
122 bStyleParsed
= ParseStyleOptions( aStyle
, aId
, aClass
,
123 aItemSet
, aPropInfo
, &aLang
, &aDir
);
126 if ( aPropInfo
.m_nColumnCount
>= 2 )
129 NewMultiCol( aPropInfo
.m_nColumnCount
);
132 bPositioned
= HTML_DIVISION_ON
== nToken
&& !aClass
.isEmpty() &&
133 CreateContainer( aClass
, aItemSet
, aPropInfo
,
136 bPositioned
= DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
140 if( !bPositioned
&& (bHeader
|| bFooter
) && IsNewDoc() )
142 SwPageDesc
*pPageDesc
= m_pCSS1Parser
->GetMasterPageDesc();
143 SwFrameFormat
& rPageFormat
= pPageDesc
->GetMaster();
145 SwFrameFormat
*pHdFtFormat
;
147 HtmlContextFlags nFlags
= HtmlContextFlags::MultiColMask
;
150 pHdFtFormat
= const_cast<SwFrameFormat
*>(rPageFormat
.GetHeader().GetHeaderFormat());
153 // noch keine Header, dann erzeuge einen.
154 rPageFormat
.SetFormatAttr( SwFormatHeader( true ));
155 pHdFtFormat
= const_cast<SwFrameFormat
*>(rPageFormat
.GetHeader().GetHeaderFormat());
158 nFlags
|= HtmlContextFlags::HeaderDist
;
162 pHdFtFormat
= const_cast<SwFrameFormat
*>(rPageFormat
.GetFooter().GetFooterFormat());
165 // noch keine Footer, dann erzeuge einen.
166 rPageFormat
.SetFormatAttr( SwFormatFooter( true ));
167 pHdFtFormat
= const_cast<SwFrameFormat
*>(rPageFormat
.GetFooter().GetFooterFormat());
170 nFlags
|= HtmlContextFlags::FooterDist
;
173 const SwFormatContent
& rFlyContent
= pHdFtFormat
->GetContent();
174 const SwNodeIndex
& rContentStIdx
= *rFlyContent
.GetContentIdx();
179 pCNd
= m_pDoc
->GetNodes()[rContentStIdx
.GetIndex()+1]
184 // Einen neuen Node zu Beginn der Section anlegen
185 SwNodeIndex
aSttIdx( rContentStIdx
, 1 );
186 pCNd
= m_pDoc
->GetNodes().MakeTextNode( aSttIdx
,
187 m_pCSS1Parser
->GetTextCollFromPool(RES_POOLCOLL_TEXT
));
189 // Den bisherigen Inhalt der Section loeschen
190 SwPaM
aDelPam( aSttIdx
);
193 const SwStartNode
*pStNd
=
194 static_cast<const SwStartNode
*>( &rContentStIdx
.GetNode() );
195 aDelPam
.GetPoint()->nNode
= pStNd
->EndOfSectionIndex() - 1;
197 m_pDoc
->getIDocumentContentOperations().DelFullPara( aDelPam
);
199 // Die Seitenvorlage aktualisieren
200 for( size_t i
=0; i
< m_pDoc
->GetPageDescCnt(); i
++ )
202 if( RES_POOLPAGE_HTML
== m_pDoc
->GetPageDesc(i
).GetPoolFormatId() )
204 m_pDoc
->ChgPageDesc( i
, *pPageDesc
);
210 SwPosition
aNewPos( SwNodeIndex( rContentStIdx
, 1 ), SwIndex( pCNd
, 0 ) );
211 SaveDocContext( pCntxt
, nFlags
, &aNewPos
);
213 else if( !bPositioned
&& aId
.getLength() > 9 &&
214 (aId
[0] == 's' || aId
[0] == 'S' ) &&
215 (aId
[1] == 'd' || aId
[1] == 'D' ) )
217 bool bEndNote
= false, bFootNote
= false;
218 if( aId
.startsWithIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdendnote
) )
220 else if( aId
.startsWithIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_sdfootnote
) )
222 if( bFootNote
|| bEndNote
)
224 SwNodeIndex
*pStartNdIdx
= GetFootEndNoteSection( aId
);
227 SwContentNode
*pCNd
=
228 m_pDoc
->GetNodes()[pStartNdIdx
->GetIndex()+1]->GetContentNode();
229 SwNodeIndex aTmpSwNodeIndex
= SwNodeIndex(*pCNd
);
230 SwPosition
aNewPos( aTmpSwNodeIndex
, SwIndex( pCNd
, 0 ) );
231 SaveDocContext( pCntxt
, HtmlContextFlags::MultiColMask
, &aNewPos
);
233 aPropInfo
.m_aId
.clear();
238 // Bereiche fuegen wir in Rahmen nur dann ein, wenn der Bereich gelinkt ist.
239 if( (!aId
.isEmpty() && !bPositioned
) || !aHRef
.isEmpty() )
241 // Bereich einfuegen (muss vor dem Setzten von Attributen erfolgen,
242 // weil die Section vor der PaM-Position eingefuegt.
244 // wenn wir im ersten Node einer Section stehen, wir die neue
245 // Section nicht in der aktuellen, sondern vor der aktuellen
246 // Section eingefuegt. Deshalb muessen wir dann einen Node
247 // einfuegen. UND IN LOESCHEN!!!
250 SwNodeIndex
aPrvNdIdx( m_pPam
->GetPoint()->nNode
, -1 );
251 if (aPrvNdIdx
.GetNode().IsSectionNode())
257 HTMLAttrs
*pPostIts
= bAppended
? nullptr : new HTMLAttrs
;
258 SetAttr( true, true, pPostIts
);
260 // Namen der Section eindeutig machen
261 const OUString
aName( m_pDoc
->GetUniqueSectionName( !aId
.isEmpty() ? &aId
: nullptr ) );
263 if( !aHRef
.isEmpty() )
265 sal_Unicode cDelim
= 255U;
266 sal_Int32 nPos
= aHRef
.lastIndexOf( cDelim
);
267 sal_Int32 nPos2
= -1;
270 nPos2
= aHRef
.lastIndexOf( cDelim
, nPos
);
273 sal_Int32 nTmp
= nPos
;
281 aURL
= URIHelper::SmartRel2Abs(INetURLObject( m_sBaseURL
), aHRef
, Link
<OUString
*, bool>(), false);
285 aURL
= URIHelper::SmartRel2Abs(INetURLObject( m_sBaseURL
), aHRef
.copy( 0, nPos
), Link
<OUString
*, bool>(), false )
286 + OUStringLiteral1(sfx2::cTokenSeparator
);
289 aURL
+= aHRef
.copy( nPos
+1 );
293 aURL
+= aHRef
.copy( nPos
+1, nPos2
- (nPos
+1) )
294 + OUStringLiteral1(sfx2::cTokenSeparator
)
295 + rtl::Uri::decode( aHRef
.copy( nPos2
+1 ),
296 rtl_UriDecodeWithCharset
,
297 RTL_TEXTENCODING_ISO_8859_1
);
303 SwSectionData
aSection( (!aHRef
.isEmpty()) ? FILE_LINK_SECTION
304 : CONTENT_SECTION
, aName
);
305 if( !aHRef
.isEmpty() )
307 aSection
.SetLinkFileName( aHRef
);
308 aSection
.SetProtectFlag(true);
311 SfxItemSet
aFrameItemSet( m_pDoc
->GetAttrPool(),
312 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
314 Reader::ResetFrameFormatAttrs(aFrameItemSet
);
316 const SfxPoolItem
*pItem
;
317 if( SfxItemState::SET
== aItemSet
.GetItemState( RES_BACKGROUND
, false,
320 aFrameItemSet
.Put( *pItem
);
321 aItemSet
.ClearItem( RES_BACKGROUND
);
323 if( SfxItemState::SET
== aItemSet
.GetItemState( RES_FRAMEDIR
, false,
326 aFrameItemSet
.Put( *pItem
);
327 aItemSet
.ClearItem( RES_FRAMEDIR
);
330 m_pDoc
->InsertSwSection( *m_pPam
, aSection
, nullptr, &aFrameItemSet
, false );
332 // ggfs. einen Bereich anspringen
333 if( JUMPTO_REGION
== m_eJumpTo
&& aName
== m_sJmpMark
)
335 m_bChkJumpMark
= true;
336 m_eJumpTo
= JUMPTO_NONE
;
339 SwTextNode
* pOldTextNd
=
340 (bAppended
) ? nullptr : m_pPam
->GetPoint()->nNode
.GetNode().GetTextNode();
342 m_pPam
->Move( fnMoveBackward
);
344 // PageDesc- und SwFormatBreak Attribute vom aktuellen Node in den
345 // (ersten) Node des Bereich verschieben.
347 MovePageDescAttrs( pOldTextNd
, m_pPam
->GetPoint()->nNode
.GetIndex(),
352 // noch vorhandene PostIts in den ersten Absatz
353 // der Tabelle setzen
354 InsertAttrs( *pPostIts
);
359 pCntxt
->SetSpansSection( true );
361 // keine text::Bookmarks mit dem gleichen Namen wie Bereiche einfuegen
362 if( !aPropInfo
.m_aId
.isEmpty() && aPropInfo
.m_aId
==aName
)
363 aPropInfo
.m_aId
.clear();
367 pCntxt
->SetAppendMode( AM_NOSPACE
);
370 if( SVX_ADJUST_END
!= eAdjust
)
372 InsertAttr( &m_aAttrTab
.pAdjust
, SvxAdjustItem(eAdjust
, RES_PARATR_ADJUST
), pCntxt
);
377 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, true );
379 PushContext( pCntxt
);
382 void SwHTMLParser::EndDivision( int /*nToken*/ )
384 // Stack-Eintrag zu dem Token suchen (weil wir noch den Div-Stack
385 // haben unterscheiden wir erst einmal nicht zwischen DIV und CENTER
386 HTMLAttrContext
*pCntxt
= nullptr;
387 auto nPos
= m_aContexts
.size();
388 while( !pCntxt
&& nPos
>m_nContextStMin
)
390 switch( m_aContexts
[--nPos
]->GetToken() )
393 case HTML_DIVISION_ON
:
394 pCntxt
= m_aContexts
[nPos
];
395 m_aContexts
.erase( m_aContexts
.begin() + nPos
);
403 EndContext( pCntxt
);
404 SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
410 void SwHTMLParser::FixHeaderFooterDistance( bool bHeader
,
411 const SwPosition
*pOldPos
)
413 SwPageDesc
*pPageDesc
= m_pCSS1Parser
->GetMasterPageDesc();
414 SwFrameFormat
& rPageFormat
= pPageDesc
->GetMaster();
416 SwFrameFormat
*pHdFtFormat
=
417 bHeader
? const_cast<SwFrameFormat
*>(rPageFormat
.GetHeader().GetHeaderFormat())
418 : const_cast<SwFrameFormat
*>(rPageFormat
.GetFooter().GetFooterFormat());
419 OSL_ENSURE( pHdFtFormat
, "Doch keine Kopf- oder Fusszeile" );
421 const SwFormatContent
& rFlyContent
= pHdFtFormat
->GetContent();
422 const SwNodeIndex
& rContentStIdx
= *rFlyContent
.GetContentIdx();
424 sal_uLong nPrvNxtIdx
;
427 nPrvNxtIdx
= rContentStIdx
.GetNode().EndOfSectionIndex()-1;
431 nPrvNxtIdx
= pOldPos
->nNode
.GetIndex() - 1;
434 sal_uInt16 nSpace
= 0;
435 SwTextNode
*pTextNode
= m_pDoc
->GetNodes()[nPrvNxtIdx
]->GetTextNode();
438 const SvxULSpaceItem
& rULSpace
=
439 static_cast<const SvxULSpaceItem
&>(pTextNode
440 ->SwContentNode::GetAttr( RES_UL_SPACE
));
442 // Der untere Absatz-Abstand wird zum Abstand zur
443 // Kopf- oder Fusszeile
444 nSpace
= rULSpace
.GetLower();
446 // und anschliessend auf einen vernuenftigen Wert
448 const SvxULSpaceItem
& rCollULSpace
=
449 pTextNode
->GetAnyFormatColl().GetULSpace();
450 if( rCollULSpace
.GetUpper() == rULSpace
.GetUpper() )
451 pTextNode
->ResetAttr( RES_UL_SPACE
);
454 SvxULSpaceItem( rULSpace
.GetUpper(),
455 rCollULSpace
.GetLower(), RES_UL_SPACE
) );
460 nPrvNxtIdx
= pOldPos
->nNode
.GetIndex();
464 nPrvNxtIdx
= rContentStIdx
.GetIndex() + 1;
467 pTextNode
= m_pDoc
->GetNodes()[nPrvNxtIdx
]
471 const SvxULSpaceItem
& rULSpace
=
472 static_cast<const SvxULSpaceItem
&>(pTextNode
473 ->SwContentNode::GetAttr( RES_UL_SPACE
));
475 // Der obere Absatz-Abstand wird zum Abstand zur
476 // Kopf- oder Fusszeile, wenn er groesser ist als
477 // der untere vom Absatz davor
478 if( rULSpace
.GetUpper() > nSpace
)
479 nSpace
= rULSpace
.GetUpper();
481 // und anschliessend auf einen vernuenftigen Wert gesetzt
482 const SvxULSpaceItem
& rCollULSpace
=
483 pTextNode
->GetAnyFormatColl().GetULSpace();
484 if( rCollULSpace
.GetLower() == rULSpace
.GetLower() )
485 pTextNode
->ResetAttr( RES_UL_SPACE
);
488 SvxULSpaceItem( rCollULSpace
.GetUpper(),
489 rULSpace
.GetLower(), RES_UL_SPACE
) );
492 SvxULSpaceItem
aULSpace( RES_UL_SPACE
);
494 aULSpace
.SetLower( nSpace
);
496 aULSpace
.SetUpper( nSpace
);
498 pHdFtFormat
->SetFormatAttr( aULSpace
);
501 bool SwHTMLParser::EndSection( bool bLFStripped
)
503 SwEndNode
*pEndNd
= m_pDoc
->GetNodes()[m_pPam
->GetPoint()->nNode
.GetIndex()+1]
505 if( pEndNd
&& pEndNd
->StartOfSectionNode()->IsSectionNode() )
507 // den Bereich beenden
510 m_pPam
->Move( fnMoveForward
);
514 OSL_ENSURE( false, "Falsche PaM Position Beenden eines Bereichs" );
519 bool SwHTMLParser::EndSections( bool bLFStripped
)
521 bool bSectionClosed
= false;
522 auto nPos
= m_aContexts
.size();
523 while( nPos
>m_nContextStMin
)
525 HTMLAttrContext
*pCntxt
= m_aContexts
[--nPos
];
526 if( pCntxt
->GetSpansSection() && EndSection( bLFStripped
) )
528 bSectionClosed
= true;
529 pCntxt
->SetSpansSection( false );
534 return bSectionClosed
;
537 void SwHTMLParser::NewMultiCol( sal_uInt16 columnsFromCss
)
540 OUString aStyle
, aClass
, aLang
, aDir
;
542 sal_uInt16 nCols
= columnsFromCss
, nGutter
= 10;
543 bool bPrcWidth
= true;
545 const HTMLOptions
& rHTMLOptions
= GetOptions();
546 for (size_t i
= rHTMLOptions
.size(); i
; )
548 const HTMLOption
& rOption
= rHTMLOptions
[--i
];
549 switch( rOption
.GetToken() )
552 aId
= rOption
.GetString();
555 aStyle
= rOption
.GetString();
558 aClass
= rOption
.GetString();
561 aLang
= rOption
.GetString();
564 aDir
= rOption
.GetString();
567 nCols
= (sal_uInt16
)rOption
.GetNumber();
570 nWidth
= rOption
.GetNumber();
571 bPrcWidth
= (rOption
.GetString().indexOf('%') != -1);
572 if( bPrcWidth
&& nWidth
>100 )
576 nGutter
= (sal_uInt16
)rOption
.GetNumber();
582 HTMLAttrContext
*pCntxt
= new HTMLAttrContext( HTML_MULTICOL_ON
);
584 //.is the multicol element contained in a container? That may be the
585 // case for 5.0 documents.
586 bool bInCntnr
= false;
587 auto i
= m_aContexts
.size();
588 while( !bInCntnr
&& i
> m_nContextStMin
)
589 bInCntnr
= nullptr != m_aContexts
[--i
]->GetFrameItemSet();
591 // Parse style sheets, but don't position anything by now.
592 bool bStyleParsed
= false;
593 SfxItemSet
aItemSet( m_pDoc
->GetAttrPool(), m_pCSS1Parser
->GetWhichMap() );
594 SvxCSS1PropertyInfo aPropInfo
;
595 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
596 bStyleParsed
= ParseStyleOptions( aStyle
, aId
, aClass
,
597 aItemSet
, aPropInfo
, &aLang
, &aDir
);
600 sal_uInt8 nPrcWidth
= bPrcWidth
? (sal_uInt8
)nWidth
: 0;
601 SwTwips nTwipWidth
= 0;
602 if( !bPrcWidth
&& nWidth
&& Application::GetDefaultDevice() )
604 nTwipWidth
= Application::GetDefaultDevice()
605 ->PixelToLogic( Size(nWidth
, 0),
606 MapMode(MapUnit::MapTwip
) ).Width();
609 if( !nPrcWidth
&& nTwipWidth
< MINFLY
)
613 bool bPositioned
= false;
614 if( bInCntnr
|| SwCSS1Parser::MayBePositioned( aPropInfo
, true ) )
616 SfxItemSet
aFrameItemSet( m_pDoc
->GetAttrPool(),
617 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
619 Reader::ResetFrameFormatAttrs(aFrameItemSet
);
621 SetAnchorAndAdjustment( text::VertOrientation::NONE
, text::HoriOrientation::NONE
, aItemSet
, aPropInfo
,
624 // The width is either the WIDTH attribute's value or contained
625 // in some style option.
626 SetVarSize( aItemSet
, aPropInfo
, aFrameItemSet
, nTwipWidth
, nPrcWidth
);
628 SetSpace( Size(0,0), aItemSet
, aPropInfo
, aFrameItemSet
);
630 // Set some other frame attributes. If the background is set, its
631 // it will be cleared here. That for, it won't be set at the section,
633 SetFrameFormatAttrs( aItemSet
, aPropInfo
,
634 HtmlFrameFormatFlags::Box
|HtmlFrameFormatFlags::Background
|HtmlFrameFormatFlags::Padding
|HtmlFrameFormatFlags::Direction
,
637 // Insert fly frame. If the are columns, the fly frame's name is not
638 // the sections name but a generated one.
639 OUString
aFlyName( aEmptyOUStr
);
643 aPropInfo
.m_aId
.clear();
646 InsertFlyFrame(aFrameItemSet
, pCntxt
, aFlyName
);
648 pCntxt
->SetPopStack( true );
652 bool bAppended
= false;
655 if( m_pPam
->GetPoint()->nContent
.GetIndex() )
657 AppendTextNode( AM_SPACE
);
666 // If there are less then 2 columns, no section is inserted.
671 // If the pam is at the start of a section, a additional text
672 // node must be inserted. Otherwise, the new section will be
673 // inserted in front of the old one.
674 SwNodeIndex
aPrvNdIdx( m_pPam
->GetPoint()->nNode
, -1 );
675 if (aPrvNdIdx
.GetNode().IsSectionNode())
681 HTMLAttrs
*pPostIts
= bAppended
? nullptr : new HTMLAttrs
;
682 SetAttr( true, true, pPostIts
);
684 // Make section name unique.
685 OUString
aName( m_pDoc
->GetUniqueSectionName( !aId
.isEmpty() ? &aId
: nullptr ) );
686 SwSectionData
aSection( CONTENT_SECTION
, aName
);
688 SfxItemSet
aFrameItemSet( m_pDoc
->GetAttrPool(),
689 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
691 Reader::ResetFrameFormatAttrs(aFrameItemSet
);
693 if( nGutter
&& Application::GetDefaultDevice() )
695 nGutter
= (sal_uInt16
)Application::GetDefaultDevice()
696 ->PixelToLogic( Size(nGutter
, 0),
697 MapMode(MapUnit::MapTwip
) ).Width();
700 SwFormatCol aFormatCol
;
702 aFormatCol
.Init( nCols
, nGutter
, USHRT_MAX
);
703 aFrameItemSet
.Put( aFormatCol
);
705 const SfxPoolItem
*pItem
;
706 if( SfxItemState::SET
== aItemSet
.GetItemState( RES_BACKGROUND
, false,
709 aFrameItemSet
.Put( *pItem
);
710 aItemSet
.ClearItem( RES_BACKGROUND
);
712 if( SfxItemState::SET
== aItemSet
.GetItemState( RES_FRAMEDIR
, false,
715 aFrameItemSet
.Put( *pItem
);
716 aItemSet
.ClearItem( RES_FRAMEDIR
);
718 m_pDoc
->InsertSwSection( *m_pPam
, aSection
, nullptr, &aFrameItemSet
, false );
720 // Jump to section, if this is requested.
721 if( JUMPTO_REGION
== m_eJumpTo
&& aName
== m_sJmpMark
)
723 m_bChkJumpMark
= true;
724 m_eJumpTo
= JUMPTO_NONE
;
727 SwTextNode
* pOldTextNd
=
728 (bAppended
) ? nullptr : m_pPam
->GetPoint()->nNode
.GetNode().GetTextNode();
730 m_pPam
->Move( fnMoveBackward
);
732 // Move PageDesc and SwFormatBreak attributes of the current node
733 // to the section's first node.
735 MovePageDescAttrs( pOldTextNd
, m_pPam
->GetPoint()->nNode
.GetIndex(),
740 // Move pending PostIts into the section.
741 InsertAttrs( *pPostIts
);
746 pCntxt
->SetSpansSection( true );
748 // Insert a bookmark if its name differs from the section's name only.
749 if( !aPropInfo
.m_aId
.isEmpty() && aPropInfo
.m_aId
==aName
)
750 aPropInfo
.m_aId
.clear();
753 // Additional attributes must be set as hard ones.
755 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, true );
757 PushContext( pCntxt
);
760 void SwHTMLParser::InsertFlyFrame( const SfxItemSet
& rItemSet
,
761 HTMLAttrContext
*pCntxt
,
762 const OUString
& rName
)
764 RndStdIds eAnchorId
=
765 static_cast<const SwFormatAnchor
&>(rItemSet
.Get( RES_ANCHOR
)).GetAnchorId();
767 // Den Rahmen anlegen
768 SwFlyFrameFormat
* pFlyFormat
= m_pDoc
->MakeFlySection( eAnchorId
, m_pPam
->GetPoint(),
770 // Ggf. den Namen setzen
771 if( !rName
.isEmpty() )
772 pFlyFormat
->SetName( rName
);
774 RegisterFlyFrame( pFlyFormat
);
776 const SwFormatContent
& rFlyContent
= pFlyFormat
->GetContent();
777 const SwNodeIndex
& rFlyCntIdx
= *rFlyContent
.GetContentIdx();
778 SwContentNode
*pCNd
= m_pDoc
->GetNodes()[rFlyCntIdx
.GetIndex()+1]
781 SwPosition
aNewPos( SwNodeIndex( rFlyCntIdx
, 1 ), SwIndex( pCNd
, 0 ) );
782 const HtmlContextFlags nFlags
= (HtmlContextFlags::ProtectStack
|HtmlContextFlags::StripPara
);
783 SaveDocContext( pCntxt
, nFlags
, &aNewPos
);
786 void SwHTMLParser::MovePageDescAttrs( SwNode
*pSrcNd
,
790 SwContentNode
* pDestContentNd
=
791 m_pDoc
->GetNodes()[nDestIdx
]->GetContentNode();
793 OSL_ENSURE( pDestContentNd
, "Wieso ist das Ziel kein Content-Node?" );
795 if( pSrcNd
->IsContentNode() )
797 SwContentNode
* pSrcContentNd
= pSrcNd
->GetContentNode();
799 const SfxPoolItem
* pItem
;
800 if( SfxItemState::SET
== pSrcContentNd
->GetSwAttrSet()
801 .GetItemState( RES_PAGEDESC
, false, &pItem
) &&
802 static_cast<const SwFormatPageDesc
*>(pItem
)->GetPageDesc() )
804 pDestContentNd
->SetAttr( *pItem
);
805 pSrcContentNd
->ResetAttr( RES_PAGEDESC
);
807 if( SfxItemState::SET
== pSrcContentNd
->GetSwAttrSet()
808 .GetItemState( RES_BREAK
, false, &pItem
) )
810 switch( static_cast<const SvxFormatBreakItem
*>(pItem
)->GetBreak() )
812 case SvxBreak::PageBefore
:
813 case SvxBreak::PageAfter
:
814 case SvxBreak::PageBoth
:
816 pDestContentNd
->SetAttr( *pItem
);
817 pSrcContentNd
->ResetAttr( RES_BREAK
);
824 else if( pSrcNd
->IsTableNode() )
826 SwFrameFormat
*pFrameFormat
= pSrcNd
->GetTableNode()->GetTable().GetFrameFormat();
828 const SfxPoolItem
* pItem
;
829 if( SfxItemState::SET
== pFrameFormat
->GetAttrSet().
830 GetItemState( RES_PAGEDESC
, false, &pItem
) )
832 pDestContentNd
->SetAttr( *pItem
);
833 pFrameFormat
->ResetFormatAttr( RES_PAGEDESC
);
838 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */