Update ooo320-m1
[ooovba.git] / sw / source / filter / html / htmlctxt.cxx
blobf23e852d09ad20a21dec437e46263a5ae5c6ba99
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: htmlctxt.cxx,v $
10 * $Revision: 1.12 $
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"
35 #include "hintids.hxx"
36 #include <svtools/itemiter.hxx>
37 #include <svx/lrspitem.hxx>
38 #include <svx/ulspitem.hxx>
39 #include <svx/brshitem.hxx>
40 #include <svx/fhgtitem.hxx>
41 #include <svtools/htmltokn.h>
43 #include "doc.hxx"
44 #include "pam.hxx"
45 #include "ndtxt.hxx"
46 #include "shellio.hxx"
47 #include "paratr.hxx"
48 #include "htmlnum.hxx"
49 #include "css1kywd.hxx"
50 #include "swcss1.hxx"
51 #include "swhtml.hxx"
53 using namespace ::com::sun::star;
56 /* \f */
59 class _HTMLAttrContext_SaveDoc
61 SwHTMLNumRuleInfo aNumRuleInfo; // In Umgebung gueltige Numerierung
62 SwPosition *pPos; // hierhin beim verlassen den
63 // Kontexts zurueckgesprungen
64 _HTMLAttrTable *pAttrTab; // In Umgebung gueltige Attribute,
65 // wenn Attributierung nicht
66 // beibehalten werden soll.
68 USHORT nContextStMin; // In Umgebung gueltige Stack-
69 // Untergrenze, wenn der Stack
70 // geschuetzt werden soll.
71 USHORT nContextStAttrMin; // In Umgebung gueltige Stack-
72 // Untergrenze, wenn die Attribute
73 // nicht beibehalten werden sollen.
75 BOOL bStripTrailingPara : 1; // letzen Absatz entfernen?
76 BOOL bKeepNumRules : 1; // Numerierung beibehalten?
77 BOOL bPopStack : 1; // Stack-Elemente oberhalb des
78 // zu schliessenden entfernen?
79 BOOL bFixHeaderDist : 1;
80 BOOL bFixFooterDist : 1;
82 public:
84 _HTMLAttrContext_SaveDoc() :
85 pPos( 0 ), pAttrTab( 0 ),
86 nContextStMin( USHRT_MAX ), nContextStAttrMin( USHRT_MAX ),
87 bStripTrailingPara( FALSE ), bKeepNumRules( FALSE ),
88 bPopStack( FALSE ),
89 bFixHeaderDist( FALSE ), bFixFooterDist( FALSE )
92 ~_HTMLAttrContext_SaveDoc() { delete pPos; delete pAttrTab; }
94 // Die Position gehoert uns, muss also angelegt und zerstoert werden
95 void SetPos( const SwPosition& rPos ) { pPos = new SwPosition(rPos); }
96 const SwPosition *GetPos() const { return pPos; }
98 // Der Index gehoert uns nicht. Kein Anlgen und Zerstoeren.
99 void SetNumInfo( const SwHTMLNumRuleInfo& rInf ) { aNumRuleInfo.Set(rInf); }
100 const SwHTMLNumRuleInfo& GetNumInfo() const { return aNumRuleInfo; }
102 _HTMLAttrTable *GetAttrTab( BOOL bCreate= FALSE );
104 void SetContextStMin( USHORT nMin ) { nContextStMin = nMin; }
105 USHORT GetContextStMin() const { return nContextStMin; }
107 void SetContextStAttrMin( USHORT nMin ) { nContextStAttrMin = nMin; }
108 USHORT GetContextStAttrMin() const { return nContextStAttrMin; }
110 void SetStripTrailingPara( BOOL bSet ) { bStripTrailingPara = bSet; }
111 BOOL GetStripTrailingPara() const { return bStripTrailingPara; }
113 void SetKeepNumRules( BOOL bSet ) { bKeepNumRules = bSet; }
114 BOOL GetKeepNumRules() const { return bKeepNumRules; }
116 void SetFixHeaderDist( BOOL bSet ) { bFixHeaderDist = bSet; }
117 BOOL GetFixHeaderDist() const { return bFixHeaderDist; }
119 void SetFixFooterDist( BOOL bSet ) { bFixFooterDist = bSet; }
120 BOOL GetFixFooterDist() const { return bFixFooterDist; }
123 _HTMLAttrTable *_HTMLAttrContext_SaveDoc::GetAttrTab( BOOL bCreate )
125 if( !pAttrTab && bCreate )
127 pAttrTab = new _HTMLAttrTable;
128 memset( pAttrTab, 0, sizeof( _HTMLAttrTable ));
130 return pAttrTab;
133 /* \f */
135 _HTMLAttrContext_SaveDoc *_HTMLAttrContext::GetSaveDocContext( BOOL bCreate )
137 if( !pSaveDocContext && bCreate )
138 pSaveDocContext = new _HTMLAttrContext_SaveDoc;
140 return pSaveDocContext;
143 void _HTMLAttrContext::ClearSaveDocContext()
145 delete pSaveDocContext;
146 pSaveDocContext = 0;
149 /* \f */
151 void SwHTMLParser::SplitAttrTab( const SwPosition& rNewPos )
153 // Hier darf es keine vorlauefigen Absatz-Attribute geben, den die
154 // koennten jetzt gesetzt werden und dann sind die Zeiger ungueltig!!!
155 ASSERT( !aParaAttrs.Count(),
156 "Hoechste Gefahr: Es gibt noch nicht-endgueltige Absatz-Attribute" );
157 if( aParaAttrs.Count() )
158 aParaAttrs.Remove( 0, aParaAttrs.Count() );
160 const SwNodeIndex* pOldEndPara = &pPam->GetPoint()->nNode;
161 xub_StrLen nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
163 const SwNodeIndex& rNewSttPara = rNewPos.nNode;
164 xub_StrLen nNewSttCnt = rNewPos.nContent.GetIndex();
166 BOOL bMoveBack = FALSE;
168 // alle noch offenen Attribute beenden und hinter der Tabelle
169 // neu aufspannen
170 _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
171 for( USHORT nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
172 nCnt--; ++pTbl )
174 _HTMLAttr *pAttr = *pTbl;
175 while( pAttr )
177 _HTMLAttr *pNext = pAttr->GetNext();
178 _HTMLAttr *pPrev = pAttr->GetPrev();
180 USHORT nWhich = pAttr->pItem->Which();
181 if( !nOldEndCnt && RES_PARATR_BEGIN <= nWhich &&
182 pAttr->GetSttParaIdx() < pOldEndPara->GetIndex() )
184 // Das Attribut muss eine Content-Position weiter vorne
185 // beendet werden
186 if( !bMoveBack )
188 bMoveBack = pPam->Move( fnMoveBackward );
189 nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
192 else if( bMoveBack )
194 pPam->Move( fnMoveForward );
195 nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
198 if( RES_PARATR_BEGIN <= nWhich && bMoveBack ||
199 pAttr->GetSttParaIdx() < pOldEndPara->GetIndex() ||
200 (pAttr->GetSttPara() == *pOldEndPara &&
201 pAttr->GetSttCnt() != nOldEndCnt) )
203 // Das Attribut muss gesetzt werden. Da wir
204 // das Original noch brauchen, weil Zeiger auf das Attribut
205 // noch in den Kontexten existieren, muessen wir es clonen.
206 // Die Next-Liste geht dabei verloren, aber die
207 // Previous-Liste bleibt erhalten
208 _HTMLAttr *pSetAttr = pAttr->Clone( *pOldEndPara, nOldEndCnt );
210 if( pNext )
211 pNext->InsertPrev( pSetAttr );
212 else
214 USHORT nTmp =
215 pSetAttr->bInsAtStart ? 0 : aSetAttrTab.Count();
216 aSetAttrTab.Insert( pSetAttr, nTmp );
219 else if( pPrev )
221 // Wenn das Attribut nicht gesetzt vor der Tabelle
222 // gesetzt werden muss, muessen der Previous-Attribute
223 // trotzdem gesetzt werden.
224 if( pNext )
225 pNext->InsertPrev( pPrev );
226 else
228 USHORT nTmp = pPrev->bInsAtStart ? 0 : aSetAttrTab.Count();
229 aSetAttrTab.Insert( pPrev, nTmp );
233 // den Start des Attributs neu setzen
234 pAttr->nSttPara = rNewSttPara;
235 pAttr->nEndPara = rNewSttPara;
236 pAttr->nSttCntnt = nNewSttCnt;
237 pAttr->nEndCntnt = nNewSttCnt;
238 pAttr->pPrev = 0;
240 pAttr = pNext;
244 if( bMoveBack )
245 pPam->Move( fnMoveForward );
249 void SwHTMLParser::SaveDocContext( _HTMLAttrContext *pCntxt,
250 USHORT nFlags,
251 const SwPosition *pNewPos )
253 _HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext( TRUE );
254 pSave->SetStripTrailingPara( (HTML_CNTXT_STRIP_PARA & nFlags) != 0 );
255 pSave->SetKeepNumRules( (HTML_CNTXT_KEEP_NUMRULE & nFlags) != 0 );
256 pSave->SetFixHeaderDist( (HTML_CNTXT_HEADER_DIST & nFlags) != 0 );
257 pSave->SetFixFooterDist( (HTML_CNTXT_FOOTER_DIST & nFlags) != 0 );
259 if( pNewPos )
261 // Wenn der PaM an eine andere Position gesetzt wird, muss
262 // die Numerierung gerettet werden..
263 if( !pSave->GetKeepNumRules() )
265 // Die Numerierung soll nicht beibehalten werden. Also muss
266 // der aktuelle Zustand gerettet und die Numerierung
267 // anschliessend ausgeschaltet werden.
268 pSave->SetNumInfo( GetNumInfo() );
269 GetNumInfo().Clear();
272 if( (HTML_CNTXT_KEEP_ATTRS & nFlags) != 0 )
274 // Attribute an aktueller Position beenden und an neuer neu anfangen
275 SplitAttrTab( *pNewPos );
277 else
279 _HTMLAttrTable *pSaveAttrTab = pSave->GetAttrTab( TRUE );
280 SaveAttrTab( *pSaveAttrTab );
284 pSave->SetPos( *pPam->GetPoint() );
285 *pPam->GetPoint() = *pNewPos;
288 // Mit dem Setzen von nContextStMin koennen automatisch auch
289 // keine gerade offenen Listen (DL/OL/UL) mehr beendet werden.
290 if( (HTML_CNTXT_PROTECT_STACK & nFlags) != 0 )
292 pSave->SetContextStMin( nContextStMin );
293 nContextStMin = aContexts.Count();
295 if( (HTML_CNTXT_KEEP_ATTRS & nFlags) == 0 )
297 pSave->SetContextStAttrMin( nContextStAttrMin );
298 nContextStAttrMin = aContexts.Count();
303 void SwHTMLParser::RestoreDocContext( _HTMLAttrContext *pCntxt )
305 _HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext();
306 if( !pSave )
307 return;
309 if( pSave->GetStripTrailingPara() )
310 StripTrailingPara();
312 if( pSave->GetPos() )
314 if( pSave->GetFixHeaderDist() || pSave->GetFixFooterDist() )
315 FixHeaderFooterDistance( pSave->GetFixHeaderDist(),
316 pSave->GetPos() );
318 _HTMLAttrTable *pSaveAttrTab = pSave->GetAttrTab();
319 if( !pSaveAttrTab )
321 // Attribute an aktueller Position beenden und an alter neu
322 // anfangen.
323 SplitAttrTab( *pSave->GetPos() );
325 else
327 RestoreAttrTab( *pSaveAttrTab );
330 *pPam->GetPoint() = *pSave->GetPos();
332 // Die bisherigen Attribute koennen wir schonmal setzen.
333 SetAttr();
336 if( USHRT_MAX != pSave->GetContextStMin() )
338 nContextStMin = pSave->GetContextStMin();
339 if( USHRT_MAX != pSave->GetContextStAttrMin() )
340 nContextStAttrMin = pSave->GetContextStAttrMin();
343 if( !pSave->GetKeepNumRules() )
345 // Die bisherige gemerkte Numerierung wieder setzen
346 GetNumInfo().Set( pSave->GetNumInfo() );
349 pCntxt->ClearSaveDocContext();
352 /* \f */
354 void SwHTMLParser::EndContext( _HTMLAttrContext *pContext )
356 if( pContext->GetPopStack() )
358 // Alle noch offenen Kontexte beenden. Der eigene
359 // Kontext muss bereits geloscht sein!
360 while( aContexts.Count() > nContextStMin )
362 _HTMLAttrContext *pCntxt = PopContext();
363 ASSERT( pCntxt != pContext,
364 "Kontext noch im Stack" );
365 if( pCntxt == pContext )
366 break;
368 EndContext( pCntxt );
369 delete pCntxt;
373 // Alle noch offenen Attribute beenden
374 if( pContext->HasAttrs() )
375 EndContextAttrs( pContext );
377 // Falls ein Bereich geoeffnet wurde, den verlassen. Da Bereiche
378 // auch innerhalb von absolut positionierten Objekten angelegt werden,
379 // muss das passieren, bever ein alter Dokument-Kontext restauriert wird.
380 if( pContext->GetSpansSection() )
381 EndSection();
383 // Rahmen und sonstige Sonderbereiche verlassen.
384 if( pContext->HasSaveDocContext() )
385 RestoreDocContext( pContext );
387 // Ggf. noch einen Ansatz-Umbruch einfuegen
388 if( AM_NONE != pContext->GetAppendMode() &&
389 pPam->GetPoint()->nContent.GetIndex() )
390 AppendTxtNode( pContext->GetAppendMode() );
392 // PRE-/LISTING- und XMP-Umgebungen wieder starten
393 if( pContext->IsFinishPREListingXMP() )
394 FinishPREListingXMP();
396 if( pContext->IsRestartPRE() )
397 StartPRE();
399 if( pContext->IsRestartXMP() )
400 StartXMP();
402 if( pContext->IsRestartListing() )
403 StartListing();
406 void SwHTMLParser::ClearContext( _HTMLAttrContext *pContext )
408 _HTMLAttrs &rAttrs = pContext->GetAttrs();
409 for( USHORT i=0; i<rAttrs.Count(); i++ )
411 // einfaches Loeschen reicht hier nicht, weil das
412 // Attribut auch aus seiner Liste ausgetragen werden
413 // muss. Theoretisch koennt man natuerlich auch die Liste
414 // und die Attribute getrennt loeschen, aber wenn man
415 // dann was falsch gemacht hat, sieht es uebel aus.
416 DeleteAttr( rAttrs[i] );
419 ASSERT( !pContext->GetSpansSection(),
420 "Bereich kann nicht mehr verlassen werden" );
422 ASSERT( !pContext->HasSaveDocContext(),
423 "Rahmen kann nicht mehr verlassen werden" );
425 // PRE-/LISTING- und XMP-Umgebungen wieder starten
426 if( pContext->IsFinishPREListingXMP() )
427 FinishPREListingXMP();
429 if( pContext->IsRestartPRE() )
430 StartPRE();
432 if( pContext->IsRestartXMP() )
433 StartXMP();
435 if( pContext->IsRestartListing() )
436 StartListing();
439 /* \f */
441 BOOL SwHTMLParser::DoPositioning( SfxItemSet &rItemSet,
442 SvxCSS1PropertyInfo &rPropInfo,
443 _HTMLAttrContext *pContext )
445 BOOL bRet = FALSE;
447 // Unter folgenden Umstaenden wird jetzt ein Rahmen aufgemacht:
448 // - das Tag wird absolut positioniert und left/top sind beide
449 // gegeben und enthalten auch keine %-Angabe, oder
450 // - das Tag soll fliessen, und
451 // - es wurde eine Breite angegeben (in beiden Faellen noetig)
452 if( SwCSS1Parser::MayBePositioned( rPropInfo ) )
454 SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
455 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
456 if( !IsNewDoc() )
457 Reader::ResetFrmFmtAttrs(aFrmItemSet );
459 // Ausrichtung setzen
460 SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE, rItemSet, rPropInfo,
461 aFrmItemSet );
463 // Groesse setzen
464 SetVarSize( rItemSet, rPropInfo, aFrmItemSet );
466 // Abstaende setzen
467 SetSpace( Size(0,0), rItemSet, rPropInfo, aFrmItemSet );
469 // Sonstige CSS1-Attribute Setzen
470 SetFrmFmtAttrs( rItemSet, rPropInfo,
471 HTML_FF_BOX|HTML_FF_PADDING|HTML_FF_BACKGROUND|HTML_FF_DIRECTION,
472 aFrmItemSet );
474 InsertFlyFrame( aFrmItemSet, pContext, rPropInfo.aId,
475 CONTEXT_FLAGS_ABSPOS );
476 pContext->SetPopStack( TRUE );
477 rPropInfo.aId.Erase();
478 bRet = TRUE;
481 return bRet;
484 BOOL SwHTMLParser::CreateContainer( const String& rClass,
485 SfxItemSet &rItemSet,
486 SvxCSS1PropertyInfo &rPropInfo,
487 _HTMLAttrContext *pContext )
489 BOOL bRet = FALSE;
490 if( rClass.EqualsIgnoreCaseAscii(sCSS1_class_abs_pos) &&
491 pCSS1Parser->MayBePositioned( rPropInfo ) )
493 // Container-Klasse
494 SfxItemSet *pFrmItemSet = pContext->GetFrmItemSet( pDoc );
495 if( !IsNewDoc() )
496 Reader::ResetFrmFmtAttrs( *pFrmItemSet );
498 SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE,
499 rItemSet, rPropInfo, *pFrmItemSet );
500 Size aDummy(0,0);
501 SetFixSize( aDummy, aDummy, FALSE, FALSE, rItemSet, rPropInfo,
502 *pFrmItemSet );
503 SetSpace( aDummy, rItemSet, rPropInfo, *pFrmItemSet );
504 SetFrmFmtAttrs( rItemSet, rPropInfo, HTML_FF_BOX|HTML_FF_BACKGROUND|HTML_FF_DIRECTION,
505 *pFrmItemSet );
507 bRet = TRUE;
510 return bRet;
513 /* \f */
515 void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
516 SvxCSS1PropertyInfo &rPropInfo,
517 _HTMLAttrContext *pContext,
518 BOOL bCharLvl )
520 // Ein DropCap-Attribut basteln, wenn auf Zeichen-Ebene vor dem
521 // ersten Zeichen ein float: left vorkommt
522 if( bCharLvl && !pPam->GetPoint()->nContent.GetIndex() &&
523 SVX_ADJUST_LEFT == rPropInfo.eFloat )
525 SwFmtDrop aDrop;
526 aDrop.GetChars() = 1;
528 pCSS1Parser->FillDropCap( aDrop, rItemSet );
530 // Nur wenn das Initial auch ueber mehrere Zeilen geht, wird das
531 // DropCap-Attribut gesetzt. Sonst setzten wir die Attribute hart.
532 if( aDrop.GetLines() > 1 )
534 NewAttr( &aAttrTab.pDropCap, aDrop );
536 _HTMLAttrs &rAttrs = pContext->GetAttrs();
537 rAttrs.Insert( aAttrTab.pDropCap, rAttrs.Count() );
539 return;
543 // Feature: PrintExt
544 if( !bCharLvl )
545 pCSS1Parser->SetFmtBreak( rItemSet, rPropInfo );
546 // /Feature: PrintExt
548 ASSERT( aContexts.Count() <= nContextStAttrMin ||
549 aContexts[aContexts.Count()-1] != pContext,
550 "SwHTMLParser::InsertAttrs: Kontext doch schon auf dem Stack" );
552 SfxItemIter aIter( rItemSet );
554 const SfxPoolItem *pItem = aIter.FirstItem();
555 while( pItem )
557 _HTMLAttr **ppAttr = 0;
559 switch( pItem->Which() )
561 case RES_LR_SPACE:
563 // Absatz-Einzuege muessen addiert werden und werden immer
564 // nur absatzweise gesetzt (fuer den ersten Absatz hier,
565 // fuer alle folgenden in SetTxtCollAttrs)
567 const SvxLRSpaceItem *pLRItem =
568 (const SvxLRSpaceItem *)pItem;
570 // die bisherigen Absatz-Abstaende holen (ohne die vom
571 // obersten Kontext, denn den veraendern wir ja gerade) ...
572 USHORT nOldLeft = 0, nOldRight = 0;
573 short nOldIndent = 0;
574 BOOL bIgnoreTop = aContexts.Count() > nContextStMin &&
575 aContexts[aContexts.Count()-1] == pContext;
576 GetMarginsFromContext( nOldLeft, nOldRight, nOldIndent,
577 bIgnoreTop );
580 // und noch die aktuell gueltigen
581 USHORT nLeft = nOldLeft, nRight = nOldRight;
582 short nIndent = nOldIndent;
583 pContext->GetMargins( nLeft, nRight, nIndent );
585 // ... und die neuen Abstaende zu den alten addieren
586 // Hier werden nicht die aus dem Item genommen, sondern die
587 // extra gemerkten, weil die auch negativ sein koennen. Die
588 // Abfrage ueber das Item funktioniert aber trotzdem, denn
589 // fuer negative Werte wird das Item (mit Wert 0) auch
590 // eingefuegt.
591 if( rPropInfo.bLeftMargin )
593 ASSERT( rPropInfo.nLeftMargin < 0 ||
594 rPropInfo.nLeftMargin == pLRItem->GetTxtLeft(),
595 "linker Abstand stimmt nicht mit Item ueberein" );
596 if( rPropInfo.nLeftMargin < 0 &&
597 -rPropInfo.nLeftMargin > nOldLeft )
598 nLeft = 0;
599 else
600 nLeft = nOldLeft + static_cast< USHORT >(rPropInfo.nLeftMargin);
602 if( rPropInfo.bRightMargin )
604 ASSERT( rPropInfo.nRightMargin < 0 ||
605 rPropInfo.nRightMargin == pLRItem->GetRight(),
606 "rechter Abstand stimmt nicht mit Item ueberein" );
607 if( rPropInfo.nRightMargin < 0 &&
608 -rPropInfo.nRightMargin > nOldRight )
609 nRight = 0;
610 else
611 nRight = nOldRight + static_cast< USHORT >(rPropInfo.nRightMargin);
613 if( rPropInfo.bTextIndent )
614 nIndent = pLRItem->GetTxtFirstLineOfst();
616 // und die Werte fuer nachfolgende Absaetze merken
617 pContext->SetMargins( nLeft, nRight, nIndent );
619 // das Attribut noch am aktuellen Absatz setzen
620 SvxLRSpaceItem aLRItem( *pLRItem );
621 aLRItem.SetTxtFirstLineOfst( nIndent );
622 aLRItem.SetTxtLeft( nLeft );
623 aLRItem.SetRight( nRight );
624 NewAttr( &aAttrTab.pLRSpace, aLRItem );
625 EndAttr( aAttrTab.pLRSpace, 0, FALSE );
627 break;
629 case RES_UL_SPACE:
630 if( !rPropInfo.bTopMargin || !rPropInfo.bBottomMargin )
632 USHORT nUpper = 0, nLower = 0;
633 GetULSpaceFromContext( nUpper, nLower );
634 SvxULSpaceItem aULSpace( *((const SvxULSpaceItem *)pItem) );
635 if( !rPropInfo.bTopMargin )
636 aULSpace.SetUpper( nUpper );
637 if( !rPropInfo.bBottomMargin )
638 aULSpace.SetLower( nLower );
640 NewAttr( &aAttrTab.pULSpace, aULSpace );
642 // ... und noch die Kontext-Information speichern
643 _HTMLAttrs &rAttrs = pContext->GetAttrs();
644 rAttrs.Insert( aAttrTab.pULSpace, rAttrs.Count() );
646 pContext->SetULSpace( aULSpace.GetUpper(), aULSpace.GetLower() );
648 else
650 ppAttr = &aAttrTab.pULSpace;
652 break;
653 case RES_CHRATR_FONTSIZE:
654 // es werden keine Attribute mit %-Angaben gesetzt
655 if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
656 ppAttr = &aAttrTab.pFontHeight;
657 break;
658 case RES_CHRATR_CJK_FONTSIZE:
659 // es werden keine Attribute mit %-Angaben gesetzt
660 if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
661 ppAttr = &aAttrTab.pFontHeightCJK;
662 break;
663 case RES_CHRATR_CTL_FONTSIZE:
664 // es werden keine Attribute mit %-Angaben gesetzt
665 if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
666 ppAttr = &aAttrTab.pFontHeightCTL;
667 break;
669 case RES_BACKGROUND:
670 if( bCharLvl )
672 // das Frame-Attr ggf. in ein Char-Attr umwandeln
673 SvxBrushItem aBrushItem( *(const SvxBrushItem *)pItem );
674 aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
676 // Das Attribut setzen ...
677 NewAttr( &aAttrTab.pCharBrush, aBrushItem );
679 // ... und noch die Kontext-Information speichern
680 _HTMLAttrs &rAttrs = pContext->GetAttrs();
681 rAttrs.Insert( aAttrTab.pCharBrush, rAttrs.Count() );
683 else if( pContext->GetToken() != HTML_TABLEHEADER_ON &&
684 pContext->GetToken() != HTML_TABLEDATA_ON )
686 ppAttr = &aAttrTab.pBrush;
688 break;
690 default:
691 // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
692 ppAttr = GetAttrTabEntry( pItem->Which() );
693 break;
696 if( ppAttr )
698 // Das Attribut setzen ...
699 NewAttr( ppAttr, *pItem );
701 // ... und noch die Kontext-Information speichern
702 _HTMLAttrs &rAttrs = pContext->GetAttrs();
703 rAttrs.Insert( *ppAttr, rAttrs.Count() );
706 // auf zum naechsten Item
707 pItem = aIter.NextItem();
710 if( rPropInfo.aId.Len() )
711 InsertBookmark( rPropInfo.aId );
714 void SwHTMLParser::InsertAttr( _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
715 _HTMLAttrContext *pCntxt )
717 if( !ppAttr )
719 ppAttr = GetAttrTabEntry( rItem.Which() );
720 if( !ppAttr )
721 return;
724 // das Attribut setzen
725 NewAttr( ppAttr, rItem );
727 // und im Kontext merken
728 _HTMLAttrs &rAttrs = pCntxt->GetAttrs();
729 rAttrs.Insert( *ppAttr, rAttrs.Count() );
732 void SwHTMLParser::SplitPREListingXMP( _HTMLAttrContext *pCntxt )
734 // PRE/Listing/XMP soll beim beenden des Kontexts beendet werden.
735 pCntxt->SetFinishPREListingXMP( TRUE );
737 // Und die jetzt gueltigen Flags sollen wieder gesetzt werden.
738 if( IsReadPRE() )
739 pCntxt->SetRestartPRE( TRUE );
740 if( IsReadXMP() )
741 pCntxt->SetRestartXMP( TRUE );
742 if( IsReadListing() )
743 pCntxt->SetRestartListing( TRUE );
745 // PRE/Listing/XMP wird auuserdem sofort beendet
746 FinishPREListingXMP();
749 SfxItemSet *_HTMLAttrContext::GetFrmItemSet( SwDoc *pCreateDoc )
751 if( !pFrmItemSet && pCreateDoc )
752 pFrmItemSet = new SfxItemSet( pCreateDoc->GetAttrPool(),
753 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
754 return pFrmItemSet;