1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: htmlsect.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
37 #include "hintids.hxx"
39 #ifndef _APP_HXX //autogen
40 #include <vcl/svapp.hxx>
42 #ifndef _WRKWIN_HXX //autogen
43 #include <vcl/wrkwin.hxx>
45 #include <svx/adjitem.hxx>
46 #include <svx/ulspitem.hxx>
47 #include <svx/brkitem.hxx>
48 #include <svtools/htmltokn.h>
50 #include <svtools/htmlkywd.hxx>
52 #include <sfx2/linkmgr.hxx>
53 #include <rtl/uri.hxx>
54 #include <fmtornt.hxx>
55 #include <fmthdft.hxx>
56 #include <fmtcntnt.hxx>
57 #include <fmtfsize.hxx>
58 #include <fmtclds.hxx>
59 #include <fmtanchr.hxx>
60 #include <fmtpdsc.hxx>
61 #include <fmtsrnd.hxx>
62 #include <fmtflcnt.hxx>
67 #include "shellio.hxx"
68 #include "section.hxx"
69 #include "poolfmt.hxx"
70 #include "pagedesc.hxx"
71 #include "swtable.hxx"
75 #include <svtools/urihelper.hxx>
77 #define CONTEXT_FLAGS_MULTICOL (HTML_CNTXT_STRIP_PARA | \
78 HTML_CNTXT_KEEP_NUMRULE | \
79 HTML_CNTXT_KEEP_ATTRS)
80 //#define CONTEXT_FLAGS_HDRFTR (HTML_CNTXT_STRIP_PARA|HTML_CNTXT_PROTECT_STACK)
81 #define CONTEXT_FLAGS_HDRFTR (CONTEXT_FLAGS_MULTICOL)
82 #define CONTEXT_FLAGS_FTN (CONTEXT_FLAGS_MULTICOL)
85 using namespace ::com::sun::star
;
90 void SwHTMLParser::NewDivision( int nToken
)
92 String aId
, aHRef
, aStyle
, aClass
, aLang
, aDir
;
93 SvxAdjust eAdjust
= HTML_CENTER_ON
==nToken
? SVX_ADJUST_CENTER
96 sal_Bool bHeader
=sal_False
, bFooter
=sal_False
;
97 const HTMLOptions
*pHTMLOptions
= GetOptions();
98 for( sal_uInt16 i
= pHTMLOptions
->Count(); i
; )
100 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
101 switch( pOption
->GetToken() )
104 aId
= pOption
->GetString();
107 if( HTML_DIVISION_ON
==nToken
)
108 eAdjust
= (SvxAdjust
)pOption
->GetEnum( aHTMLPAlignTable
,
109 static_cast< sal_uInt16
>(eAdjust
) );
112 aStyle
= pOption
->GetString();
115 aClass
= pOption
->GetString();
118 aLang
= pOption
->GetString();
121 aDir
= pOption
->GetString();
124 aHRef
= pOption
->GetString();
128 const String
& rType
= pOption
->GetString();
129 if( rType
.EqualsIgnoreCaseAscii( "HEADER" ) )
131 else if( rType
.EqualsIgnoreCaseAscii( "FOOTER" ) )
137 sal_Bool bAppended
= sal_False
;
138 if( pPam
->GetPoint()->nContent
.GetIndex() )
140 AppendTxtNode( bHeader
||bFooter
||aId
.Len()||aHRef
.Len() ? AM_NORMAL
142 bAppended
= sal_True
;
145 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( static_cast< sal_uInt16
>(nToken
) );
147 sal_Bool bStyleParsed
= sal_False
, bPositioned
= sal_False
;
148 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
149 SvxCSS1PropertyInfo aPropInfo
;
150 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
152 bStyleParsed
= ParseStyleOptions( aStyle
, aId
, aClass
,
153 aItemSet
, aPropInfo
, &aLang
, &aDir
);
156 bPositioned
= HTML_DIVISION_ON
== nToken
&& aClass
.Len() &&
157 CreateContainer( aClass
, aItemSet
, aPropInfo
,
160 bPositioned
= DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
164 if( !bPositioned
&& (bHeader
|| bFooter
) && IsNewDoc() )
166 SwPageDesc
*pPageDesc
= pCSS1Parser
->GetMasterPageDesc();
167 SwFrmFmt
& rPageFmt
= pPageDesc
->GetMaster();
170 sal_Bool bNew
= sal_False
;
171 sal_uInt16 nFlags
= CONTEXT_FLAGS_HDRFTR
;
174 pHdFtFmt
= (SwFrmFmt
*)rPageFmt
.GetHeader().GetHeaderFmt();
177 // noch keine Header, dann erzeuge einen.
178 rPageFmt
.SetFmtAttr( SwFmtHeader( sal_True
));
179 pHdFtFmt
= (SwFrmFmt
*)rPageFmt
.GetHeader().GetHeaderFmt();
182 nFlags
|= HTML_CNTXT_HEADER_DIST
;
186 pHdFtFmt
= (SwFrmFmt
*)rPageFmt
.GetFooter().GetFooterFmt();
189 // noch keine Footer, dann erzeuge einen.
190 rPageFmt
.SetFmtAttr( SwFmtFooter( sal_True
));
191 pHdFtFmt
= (SwFrmFmt
*)rPageFmt
.GetFooter().GetFooterFmt();
194 nFlags
|= HTML_CNTXT_FOOTER_DIST
;
197 const SwFmtCntnt
& rFlyCntnt
= pHdFtFmt
->GetCntnt();
198 const SwNodeIndex
& rCntntStIdx
= *rFlyCntnt
.GetCntntIdx();
203 pCNd
= pDoc
->GetNodes()[rCntntStIdx
.GetIndex()+1]
208 // Einen neuen Node zu Beginn der Section anlegen
209 SwNodeIndex
aSttIdx( rCntntStIdx
, 1 );
210 pCNd
= pDoc
->GetNodes().MakeTxtNode( aSttIdx
,
211 pCSS1Parser
->GetTxtCollFromPool(RES_POOLCOLL_TEXT
));
213 // Den bisherigen Inhalt der Section loeschen
214 SwPaM
aDelPam( aSttIdx
);
217 const SwStartNode
*pStNd
=
218 (const SwStartNode
*)pDoc
->GetNodes()[rCntntStIdx
];
219 aDelPam
.GetPoint()->nNode
= pStNd
->EndOfSectionIndex() - 1;
221 pDoc
->DelFullPara( aDelPam
);
223 // Die Seitenvorlage aktualisieren
224 for( sal_uInt16 i
=0; i
< pDoc
->GetPageDescCnt(); i
++ )
226 if( RES_POOLPAGE_HTML
==const_cast<const SwDoc
*>(pDoc
)
227 ->GetPageDesc(i
).GetPoolFmtId() )
229 pDoc
->ChgPageDesc( i
, *pPageDesc
);
235 SwPosition
aNewPos( SwNodeIndex( rCntntStIdx
, 1 ), SwIndex( pCNd
, 0 ) );
236 SaveDocContext( pCntxt
, nFlags
, &aNewPos
);
238 else if( !bPositioned
&& aId
.Len() > 9 &&
239 ('s' == aId
.GetChar(0) || 'S' == aId
.GetChar(0) ) &&
240 ('d' == aId
.GetChar(1) || 'D' == aId
.GetChar(1) ) )
242 sal_Bool bEndNote
= sal_False
, bFootNote
= sal_False
;
243 if( aId
.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_sdendnote
, 9 ) == COMPARE_EQUAL
)
245 else if( aId
.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote
, 10 ) == COMPARE_EQUAL
)
246 bFootNote
= sal_True
;
247 if( bFootNote
|| bEndNote
)
249 SwNodeIndex
*pStartNdIdx
= GetFootEndNoteSection( aId
);
253 pDoc
->GetNodes()[pStartNdIdx
->GetIndex()+1]->GetCntntNode();
254 SwNodeIndex aTmpSwNodeIndex
= SwNodeIndex(*pCNd
);
255 SwPosition
aNewPos( aTmpSwNodeIndex
, SwIndex( pCNd
, 0 ) );
256 SaveDocContext( pCntxt
, CONTEXT_FLAGS_FTN
, &aNewPos
);
257 aId
= aPropInfo
.aId
= aEmptyStr
;
262 // Bereiche fuegen wir in Rahmen nur dann ein, wenn der Bereich gelinkt ist.
263 if( (aId
.Len() && !bPositioned
) || aHRef
.Len() )
265 // Bereich einfuegen (muss vor dem Setzten von Attributen erfolgen,
266 // weil die Section vor der PaM-Position eingefuegt.
268 // wenn wir im ersten Node einer Section stehen, wir die neue
269 // Section nicht in der aktuellen, sondern vor der aktuellen
270 // Section eingefuegt. Deshalb muessen wir dann einen Node
271 // einfuegen. UND IN LOESCHEN!!!
274 SwNodeIndex
aPrvNdIdx( pPam
->GetPoint()->nNode
, -1 );
275 if( (pDoc
->GetNodes()[aPrvNdIdx
])->IsSectionNode() )
278 bAppended
= sal_True
;
281 _HTMLAttrs
*pPostIts
= bAppended
? 0 : new _HTMLAttrs
;
282 SetAttr( sal_True
, sal_True
, pPostIts
);
284 // Namen der Section eindeutig machen
285 String
aName( pDoc
->GetUniqueSectionName( aId
.Len() ? &aId
: 0 ) );
289 sal_Unicode cDelim
= 255U;
291 xub_StrLen nPos
= aHRef
.SearchBackward( cDelim
);
292 xub_StrLen nPos2
= STRING_NOTFOUND
;
293 if( STRING_NOTFOUND
!= nPos
)
295 nPos2
= aHRef
.SearchBackward( cDelim
, nPos
);
296 if( STRING_NOTFOUND
!= nPos2
)
298 xub_StrLen nTmp
= nPos
;
303 if( STRING_NOTFOUND
== nPos
)
305 aURL
= URIHelper::SmartRel2Abs(INetURLObject( sBaseURL
), aHRef
, Link(), false);
309 aURL
= URIHelper::SmartRel2Abs(INetURLObject( sBaseURL
), aHRef
.Copy( 0, nPos
), Link(), false );
310 aURL
+= sfx2::cTokenSeperator
;
311 if( STRING_NOTFOUND
== nPos2
)
313 aURL
+= aHRef
.Copy( nPos
+1 );
317 aURL
+= aHRef
.Copy( nPos
+1, nPos2
- (nPos
+1) );
318 aURL
+= sfx2::cTokenSeperator
;
319 aURL
+= String(rtl::Uri::decode( aHRef
.Copy( nPos2
+1 ),
320 rtl_UriDecodeWithCharset
,
321 RTL_TEXTENCODING_ISO_8859_1
));
327 SwSection
aSection( aHRef
.Len() ? FILE_LINK_SECTION
328 : CONTENT_SECTION
, aName
);
331 aSection
.SetLinkFileName( aHRef
);
332 aSection
.SetProtect();
335 SfxItemSet
aFrmItemSet( pDoc
->GetAttrPool(),
336 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
338 Reader::ResetFrmFmtAttrs(aFrmItemSet
);
340 const SfxPoolItem
*pItem
;
341 if( SFX_ITEM_SET
== aItemSet
.GetItemState( RES_BACKGROUND
, sal_False
,
344 aFrmItemSet
.Put( *pItem
);
345 aItemSet
.ClearItem( RES_BACKGROUND
);
347 if( SFX_ITEM_SET
== aItemSet
.GetItemState( RES_FRAMEDIR
, sal_False
,
350 aFrmItemSet
.Put( *pItem
);
351 aItemSet
.ClearItem( RES_FRAMEDIR
);
354 pDoc
->InsertSwSection( *pPam
, aSection
, &aFrmItemSet
, false );
356 // ggfs. einen Bereich anspringen
357 if( JUMPTO_REGION
== eJumpTo
&& aName
== sJmpMark
)
359 bChkJumpMark
= sal_True
;
360 eJumpTo
= JUMPTO_NONE
;
363 SwTxtNode
* pOldTxtNd
=
364 bAppended
? 0 : pDoc
->GetNodes()[pPam
->GetPoint()->nNode
]
367 pPam
->Move( fnMoveBackward
);
369 // PageDesc- und SwFmtBreak Attribute vom aktuellen Node in den
370 // (ersten) Node des Bereich verschieben.
372 MovePageDescAttrs( pOldTxtNd
, pPam
->GetPoint()->nNode
.GetIndex(),
377 // noch vorhandene PostIts in den ersten Absatz
378 // der Tabelle setzen
379 InsertAttrs( *pPostIts
);
384 pCntxt
->SetSpansSection( sal_True
);
386 // keine text::Bookmarks mit dem gleichen Namen wie Bereiche einfuegen
387 if( aPropInfo
.aId
.Len() && aPropInfo
.aId
==aName
)
388 aPropInfo
.aId
.Erase();
392 pCntxt
->SetAppendMode( AM_NOSPACE
);
395 if( SVX_ADJUST_END
!= eAdjust
)
397 InsertAttr( &aAttrTab
.pAdjust
, SvxAdjustItem(eAdjust
, RES_PARATR_ADJUST
), pCntxt
);
402 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, sal_True
);
404 PushContext( pCntxt
);
407 void SwHTMLParser::EndDivision( int /*nToken*/ )
409 // Stack-Eintrag zu dem Token suchen (weil wir noch den Div-Stack
410 // haben unterscheiden wir erst einmal nicht zwischen DIV und CENTER
411 _HTMLAttrContext
*pCntxt
= 0;
412 sal_uInt16 nPos
= aContexts
.Count();
413 while( !pCntxt
&& nPos
>nContextStMin
)
415 switch( aContexts
[--nPos
]->GetToken() )
418 case HTML_DIVISION_ON
:
419 pCntxt
= aContexts
[nPos
];
420 aContexts
.Remove( nPos
, 1 );
428 EndContext( pCntxt
);
429 SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
435 void SwHTMLParser::FixHeaderFooterDistance( sal_Bool bHeader
,
436 const SwPosition
*pOldPos
)
438 SwPageDesc
*pPageDesc
= pCSS1Parser
->GetMasterPageDesc();
439 SwFrmFmt
& rPageFmt
= pPageDesc
->GetMaster();
442 bHeader
? (SwFrmFmt
*)rPageFmt
.GetHeader().GetHeaderFmt()
443 : (SwFrmFmt
*)rPageFmt
.GetFooter().GetFooterFmt();
444 ASSERT( pHdFtFmt
, "Doch keine Kopf- oder Fusszeile" );
446 const SwFmtCntnt
& rFlyCntnt
= pHdFtFmt
->GetCntnt();
447 const SwNodeIndex
& rCntntStIdx
= *rFlyCntnt
.GetCntntIdx();
452 nPrvNxtIdx
= pDoc
->GetNodes()[rCntntStIdx
]->EndOfSectionIndex()-1;
456 nPrvNxtIdx
= pOldPos
->nNode
.GetIndex() - 1;
459 sal_uInt16 nSpace
= 0;
460 SwTxtNode
*pTxtNode
= pDoc
->GetNodes()[nPrvNxtIdx
]->GetTxtNode();
463 const SvxULSpaceItem
& rULSpace
=
464 ((const SvxULSpaceItem
&)pTxtNode
465 ->SwCntntNode::GetAttr( RES_UL_SPACE
));
467 // Der untere Absatz-Abstand wird zum Abstand zur
468 // Kopf- oder Fusszeile
469 nSpace
= rULSpace
.GetLower();
471 // und anschliessend auf einen vernuenftigen Wert
473 const SvxULSpaceItem
& rCollULSpace
=
474 pTxtNode
->GetAnyFmtColl().GetULSpace();
475 if( rCollULSpace
.GetUpper() == rULSpace
.GetUpper() )
476 pTxtNode
->ResetAttr( RES_UL_SPACE
);
479 SvxULSpaceItem( rULSpace
.GetUpper(),
480 rCollULSpace
.GetLower(), RES_UL_SPACE
) );
485 nPrvNxtIdx
= pOldPos
->nNode
.GetIndex();
489 nPrvNxtIdx
= rCntntStIdx
.GetIndex() + 1;
492 pTxtNode
= pDoc
->GetNodes()[nPrvNxtIdx
]
496 const SvxULSpaceItem
& rULSpace
=
497 ((const SvxULSpaceItem
&)pTxtNode
498 ->SwCntntNode::GetAttr( RES_UL_SPACE
));
500 // Der obere Absatz-Abstand wird zum Abstand zur
501 // Kopf- oder Fusszeile, wenn er groesser ist als
502 // der untere vom Absatz davor
503 if( rULSpace
.GetUpper() > nSpace
)
504 nSpace
= rULSpace
.GetUpper();
506 // und anschliessend auf einen vernuenftigen Wert gesetzt
507 const SvxULSpaceItem
& rCollULSpace
=
508 pTxtNode
->GetAnyFmtColl().GetULSpace();
509 if( rCollULSpace
.GetLower() == rULSpace
.GetLower() )
510 pTxtNode
->ResetAttr( RES_UL_SPACE
);
513 SvxULSpaceItem( rCollULSpace
.GetUpper(),
514 rULSpace
.GetLower(), RES_UL_SPACE
) );
517 SvxULSpaceItem
aULSpace( RES_UL_SPACE
);
519 aULSpace
.SetLower( nSpace
);
521 aULSpace
.SetUpper( nSpace
);
523 pHdFtFmt
->SetFmtAttr( aULSpace
);
526 sal_Bool
SwHTMLParser::EndSection( sal_Bool bLFStripped
)
528 SwEndNode
*pEndNd
= pDoc
->GetNodes()[pPam
->GetPoint()->nNode
.GetIndex()+1]
530 if( pEndNd
&& pEndNd
->StartOfSectionNode()->IsSectionNode() )
532 // den Bereich beenden
535 pPam
->Move( fnMoveForward
);
539 ASSERT( !this, "Falsche PaM Position Beenden eines Bereichs" );
544 sal_Bool
SwHTMLParser::EndSections( sal_Bool bLFStripped
)
546 sal_Bool bSectionClosed
= sal_False
;
547 sal_uInt16 nPos
= aContexts
.Count();
548 while( nPos
>nContextStMin
)
550 _HTMLAttrContext
*pCntxt
= aContexts
[--nPos
];
551 if( pCntxt
->GetSpansSection() && EndSection( bLFStripped
) )
553 bSectionClosed
= sal_True
;
554 pCntxt
->SetSpansSection( sal_False
);
555 bLFStripped
= sal_False
;
559 return bSectionClosed
;
564 void SwHTMLParser::NewMultiCol()
566 String aId
, aStyle
, aClass
, aLang
, aDir
;
568 sal_uInt16 nCols
= 0, nGutter
= 10;
569 sal_Bool bPrcWidth
= sal_True
;
571 const HTMLOptions
*pHTMLOptions
= GetOptions();
574 for( i
= pHTMLOptions
->Count(); i
; )
576 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
577 switch( pOption
->GetToken() )
580 aId
= pOption
->GetString();
583 aStyle
= pOption
->GetString();
586 aClass
= pOption
->GetString();
589 aLang
= pOption
->GetString();
592 aDir
= pOption
->GetString();
595 nCols
= (sal_uInt16
)pOption
->GetNumber();
598 nWidth
= pOption
->GetNumber();
599 bPrcWidth
= (pOption
->GetString().Search('%') != STRING_NOTFOUND
);
600 if( bPrcWidth
&& nWidth
>100 )
604 nGutter
= (sal_uInt16
)pOption
->GetNumber();
610 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( HTML_MULTICOL_ON
);
612 //.is the multicol elememt contained in a container? That may be the
613 // case for 5.0 documents.
614 sal_Bool bInCntnr
= sal_False
;
615 i
= aContexts
.Count();
616 while( !bInCntnr
&& i
> nContextStMin
)
617 bInCntnr
= 0 != aContexts
[--i
]->GetFrmItemSet();
619 // Parse style sheets, but don't position anything by now.
620 sal_Bool bStyleParsed
= sal_False
;
621 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
622 SvxCSS1PropertyInfo aPropInfo
;
623 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
624 bStyleParsed
= ParseStyleOptions( aStyle
, aId
, aClass
,
625 aItemSet
, aPropInfo
, &aLang
, &aDir
);
628 sal_uInt8 nPrcWidth
= bPrcWidth
? (sal_uInt8
)nWidth
: 0;
629 sal_uInt16 nTwipWidth
= 0;
630 if( !bPrcWidth
&& nWidth
&& Application::GetDefaultDevice() )
632 nTwipWidth
= (sal_uInt16
)Application::GetDefaultDevice()
633 ->PixelToLogic( Size(nWidth
, 0),
634 MapMode(MAP_TWIP
) ).Width();
637 if( !nPrcWidth
&& nTwipWidth
< MINFLY
)
641 sal_Bool bPositioned
= sal_False
;
642 if( bInCntnr
|| pCSS1Parser
->MayBePositioned( aPropInfo
, sal_True
) )
644 SfxItemSet
aFrmItemSet( pDoc
->GetAttrPool(),
645 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
647 Reader::ResetFrmFmtAttrs(aFrmItemSet
);
649 SetAnchorAndAdjustment( text::VertOrientation::NONE
, text::HoriOrientation::NONE
, aItemSet
, aPropInfo
,
652 // The width is either the WIDTH attribute's value or contained
653 // in some style option.
654 SetVarSize( aItemSet
, aPropInfo
, aFrmItemSet
, nTwipWidth
, nPrcWidth
);
656 SetSpace( Size(0,0), aItemSet
, aPropInfo
, aFrmItemSet
);
658 // Set some other frame attributes. If the background is set, its
659 // it will be cleared here. That for, it won't be set at the section,
661 SetFrmFmtAttrs( aItemSet
, aPropInfo
,
662 HTML_FF_BOX
|HTML_FF_BACKGROUND
|HTML_FF_PADDING
|HTML_FF_DIRECTION
,
665 // Insert fly frame. If the are columns, the fly frame's name is not
666 // the sections name but a generated one.
667 String
aFlyName( aEmptyStr
);
671 aPropInfo
.aId
.Erase();
674 InsertFlyFrame( aFrmItemSet
, pCntxt
, aFlyName
, CONTEXT_FLAGS_ABSPOS
);
676 pCntxt
->SetPopStack( sal_True
);
677 bPositioned
= sal_True
;
680 sal_Bool bAppended
= sal_False
;
683 if( pPam
->GetPoint()->nContent
.GetIndex() )
685 AppendTxtNode( AM_SPACE
);
686 bAppended
= sal_True
;
694 // If there are less then 2 columns, no section is inserted.
699 // If the pam is at the start of a section, a additional text
700 // node must be inserted. Otherwise, the new section will be
701 // inserted in front of the old one.
702 SwNodeIndex
aPrvNdIdx( pPam
->GetPoint()->nNode
, -1 );
703 if( (pDoc
->GetNodes()[aPrvNdIdx
])->IsSectionNode() )
706 bAppended
= sal_True
;
709 _HTMLAttrs
*pPostIts
= bAppended
? 0 : new _HTMLAttrs
;
710 SetAttr( sal_True
, sal_True
, pPostIts
);
712 // Make section name unique.
713 String
aName( pDoc
->GetUniqueSectionName( aId
.Len() ? &aId
: 0 ) );
714 SwSection
aSection( CONTENT_SECTION
, aName
);
716 SfxItemSet
aFrmItemSet( pDoc
->GetAttrPool(),
717 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
719 Reader::ResetFrmFmtAttrs(aFrmItemSet
);
721 if( nGutter
&& Application::GetDefaultDevice() )
723 nGutter
= (sal_uInt16
)Application::GetDefaultDevice()
724 ->PixelToLogic( Size(nGutter
, 0),
725 MapMode(MAP_TWIP
) ).Width();
729 #ifndef WIDTH_SUPPORTED_BY_SECTIONS
733 aFmtCol
.Init( nCols
, nGutter
, nPrcWidth
? USHRT_MAX
: nTwipWidth
);
734 aFrmItemSet
.Put( aFmtCol
);
736 const SfxPoolItem
*pItem
;
737 if( SFX_ITEM_SET
== aItemSet
.GetItemState( RES_BACKGROUND
, sal_False
,
740 aFrmItemSet
.Put( *pItem
);
741 aItemSet
.ClearItem( RES_BACKGROUND
);
743 if( SFX_ITEM_SET
== aItemSet
.GetItemState( RES_FRAMEDIR
, sal_False
,
746 aFrmItemSet
.Put( *pItem
);
747 aItemSet
.ClearItem( RES_FRAMEDIR
);
749 pDoc
->InsertSwSection( *pPam
, aSection
, &aFrmItemSet
, false );
751 // Jump to section, if this is requested.
752 if( JUMPTO_REGION
== eJumpTo
&& aName
== sJmpMark
)
754 bChkJumpMark
= sal_True
;
755 eJumpTo
= JUMPTO_NONE
;
758 SwTxtNode
* pOldTxtNd
=
759 bAppended
? 0 : pDoc
->GetNodes()[pPam
->GetPoint()->nNode
]
762 pPam
->Move( fnMoveBackward
);
764 // Move PageDesc and SwFmtBreak attributes of the current node
765 // to the section's first node.
767 MovePageDescAttrs( pOldTxtNd
, pPam
->GetPoint()->nNode
.GetIndex(),
772 // Move pending PostIts into the section.
773 InsertAttrs( *pPostIts
);
778 pCntxt
->SetSpansSection( sal_True
);
780 // Insert a bookmark if its name differs from the section's name only.
781 if( aPropInfo
.aId
.Len() && aPropInfo
.aId
==aName
)
782 aPropInfo
.aId
.Erase();
785 // Additional attributes must be set as hard ones.
787 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, sal_True
);
789 PushContext( pCntxt
);
794 void SwHTMLParser::InsertFlyFrame( const SfxItemSet
& rItemSet
,
795 _HTMLAttrContext
*pCntxt
,
799 RndStdIds eAnchorId
=
800 ((const SwFmtAnchor
&)rItemSet
.Get( RES_ANCHOR
)).GetAnchorId();
802 // Den Rahmen anlegen
803 SwFlyFrmFmt
* pFlyFmt
= pDoc
->MakeFlySection( eAnchorId
, pPam
->GetPoint(),
805 // Ggf. den Namen setzen
807 pFlyFmt
->SetName( rName
);
809 RegisterFlyFrm( pFlyFmt
);
811 const SwFmtCntnt
& rFlyCntnt
= pFlyFmt
->GetCntnt();
812 const SwNodeIndex
& rFlyCntIdx
= *rFlyCntnt
.GetCntntIdx();
813 SwCntntNode
*pCNd
= pDoc
->GetNodes()[rFlyCntIdx
.GetIndex()+1]
816 SwPosition
aNewPos( SwNodeIndex( rFlyCntIdx
, 1 ), SwIndex( pCNd
, 0 ) );
817 SaveDocContext( pCntxt
, nFlags
, &aNewPos
);
823 void SwHTMLParser::MovePageDescAttrs( SwNode
*pSrcNd
,
827 SwCntntNode
* pDestCntntNd
=
828 pDoc
->GetNodes()[nDestIdx
]->GetCntntNode();
830 ASSERT( pDestCntntNd
, "Wieso ist das Ziel kein Content-Node?" );
832 if( pSrcNd
->IsCntntNode() )
834 SwCntntNode
* pSrcCntntNd
= pSrcNd
->GetCntntNode();
836 const SfxPoolItem
* pItem
;
837 if( SFX_ITEM_SET
== pSrcCntntNd
->GetSwAttrSet()
838 .GetItemState( RES_PAGEDESC
, sal_False
, &pItem
) &&
839 ((SwFmtPageDesc
*)pItem
)->GetPageDesc() )
841 pDestCntntNd
->SetAttr( *pItem
);
842 pSrcCntntNd
->ResetAttr( RES_PAGEDESC
);
844 if( SFX_ITEM_SET
== pSrcCntntNd
->GetSwAttrSet()
845 .GetItemState( RES_BREAK
, sal_False
, &pItem
) )
847 switch( ((SvxFmtBreakItem
*)pItem
)->GetBreak() )
849 case SVX_BREAK_PAGE_BEFORE
:
850 case SVX_BREAK_PAGE_AFTER
:
851 case SVX_BREAK_PAGE_BOTH
:
853 pDestCntntNd
->SetAttr( *pItem
);
854 pSrcCntntNd
->ResetAttr( RES_BREAK
);
860 else if( pSrcNd
->IsTableNode() )
862 SwFrmFmt
*pFrmFmt
= pSrcNd
->GetTableNode()->GetTable().GetFrmFmt();
864 const SfxPoolItem
* pItem
;
865 if( SFX_ITEM_SET
== pFrmFmt
->GetAttrSet().
866 GetItemState( RES_PAGEDESC
, sal_False
, &pItem
) )
868 pDestCntntNd
->SetAttr( *pItem
);
869 pFrmFmt
->ResetFmtAttr( RES_PAGEDESC
);