build fix
[LibreOffice.git] / sw / source / filter / html / htmlctxt.cxx
blob6f40d68142d351aa8a413827555e95f91f5d85e8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "hintids.hxx"
21 #include <svl/itemiter.hxx>
22 #include <editeng/lrspitem.hxx>
23 #include <editeng/ulspitem.hxx>
24 #include <editeng/brushitem.hxx>
25 #include <editeng/fhgtitem.hxx>
26 #include <svtools/htmltokn.h>
27 #include <editeng/boxitem.hxx>
29 #include "doc.hxx"
30 #include "pam.hxx"
31 #include "ndtxt.hxx"
32 #include "shellio.hxx"
33 #include "paratr.hxx"
34 #include "htmlnum.hxx"
35 #include "css1kywd.hxx"
36 #include "swcss1.hxx"
37 #include "swhtml.hxx"
39 using namespace ::com::sun::star;
41 class HTMLAttrContext_SaveDoc
43 SwHTMLNumRuleInfo aNumRuleInfo; // In Umgebung gueltige Numerierung
44 SwPosition *pPos; // hierhin beim verlassen den
45 // Kontexts zurueckgesprungen
46 HTMLAttrTable *pAttrTab; // In Umgebung gueltige Attribute,
47 // wenn Attributierung nicht
48 // beibehalten werden soll.
50 size_t nContextStMin; // In Umgebung gueltige Stack-
51 // Untergrenze, wenn der Stack
52 // geschuetzt werden soll.
53 size_t nContextStAttrMin; // In Umgebung gueltige Stack-
54 // Untergrenze, wenn die Attribute
55 // nicht beibehalten werden sollen.
57 bool bStripTrailingPara : 1; // letzen Absatz entfernen?
58 bool bKeepNumRules : 1; // Numerierung beibehalten?
59 bool bFixHeaderDist : 1;
60 bool bFixFooterDist : 1;
62 public:
64 HTMLAttrContext_SaveDoc() :
65 pPos( nullptr ), pAttrTab( nullptr ),
66 nContextStMin( SIZE_MAX ), nContextStAttrMin( SIZE_MAX ),
67 bStripTrailingPara( false ), bKeepNumRules( false ),
68 bFixHeaderDist( false ), bFixFooterDist( false )
71 ~HTMLAttrContext_SaveDoc() { delete pPos; delete pAttrTab; }
73 // Die Position gehoert uns, muss also angelegt und zerstoert werden
74 void SetPos( const SwPosition& rPos ) { pPos = new SwPosition(rPos); }
75 const SwPosition *GetPos() const { return pPos; }
77 // Der Index gehoert uns nicht. Kein Anlgen und Zerstoeren.
78 void SetNumInfo( const SwHTMLNumRuleInfo& rInf ) { aNumRuleInfo.Set(rInf); }
79 const SwHTMLNumRuleInfo& GetNumInfo() const { return aNumRuleInfo; }
81 HTMLAttrTable *GetAttrTab( bool bCreate= false );
83 void SetContextStMin( size_t nMin ) { nContextStMin = nMin; }
84 size_t GetContextStMin() const { return nContextStMin; }
86 void SetContextStAttrMin( size_t nMin ) { nContextStAttrMin = nMin; }
87 size_t GetContextStAttrMin() const { return nContextStAttrMin; }
89 void SetStripTrailingPara( bool bSet ) { bStripTrailingPara = bSet; }
90 bool GetStripTrailingPara() const { return bStripTrailingPara; }
92 void SetKeepNumRules( bool bSet ) { bKeepNumRules = bSet; }
93 bool GetKeepNumRules() const { return bKeepNumRules; }
95 void SetFixHeaderDist( bool bSet ) { bFixHeaderDist = bSet; }
96 bool GetFixHeaderDist() const { return bFixHeaderDist; }
98 void SetFixFooterDist( bool bSet ) { bFixFooterDist = bSet; }
99 bool GetFixFooterDist() const { return bFixFooterDist; }
102 HTMLAttrTable *HTMLAttrContext_SaveDoc::GetAttrTab( bool bCreate )
104 if( !pAttrTab && bCreate )
106 pAttrTab = new HTMLAttrTable;
107 memset( pAttrTab, 0, sizeof( HTMLAttrTable ));
109 return pAttrTab;
112 HTMLAttrContext_SaveDoc *HTMLAttrContext::GetSaveDocContext( bool bCreate )
114 if( !pSaveDocContext && bCreate )
115 pSaveDocContext = new HTMLAttrContext_SaveDoc;
117 return pSaveDocContext;
120 void HTMLAttrContext::ClearSaveDocContext()
122 delete pSaveDocContext;
123 pSaveDocContext = nullptr;
126 void SwHTMLParser::SplitAttrTab( const SwPosition& rNewPos )
128 // preliminary paragraph attributes are not allowed here, they could
129 // be set here and then the pointers become invalid!
130 OSL_ENSURE(m_aParaAttrs.empty(),
131 "Danger: there are non-final paragraph attributes");
132 if( !m_aParaAttrs.empty() )
133 m_aParaAttrs.clear();
135 const SwNodeIndex* pOldEndPara = &m_pPam->GetPoint()->nNode;
136 sal_Int32 nOldEndCnt = m_pPam->GetPoint()->nContent.GetIndex();
138 const SwNodeIndex& rNewSttPara = rNewPos.nNode;
139 sal_Int32 nNewSttCnt = rNewPos.nContent.GetIndex();
141 bool bMoveBack = false;
143 // alle noch offenen Attribute beenden und hinter der Tabelle
144 // neu aufspannen
145 HTMLAttr** pHTMLAttributes = reinterpret_cast<HTMLAttr**>(&m_aAttrTab);
146 for (auto nCnt = sizeof(HTMLAttrTable) / sizeof(HTMLAttr*); nCnt--; ++pHTMLAttributes)
148 HTMLAttr *pAttr = *pHTMLAttributes;
149 while( pAttr )
151 HTMLAttr *pNext = pAttr->GetNext();
152 HTMLAttr *pPrev = pAttr->GetPrev();
154 sal_uInt16 nWhich = pAttr->pItem->Which();
155 if( !nOldEndCnt && RES_PARATR_BEGIN <= nWhich &&
156 pAttr->GetSttParaIdx() < pOldEndPara->GetIndex() )
158 // Das Attribut muss eine Content-Position weiter vorne
159 // beendet werden
160 if( !bMoveBack )
162 bMoveBack = m_pPam->Move( fnMoveBackward );
163 nOldEndCnt = m_pPam->GetPoint()->nContent.GetIndex();
166 else if( bMoveBack )
168 m_pPam->Move( fnMoveForward );
169 nOldEndCnt = m_pPam->GetPoint()->nContent.GetIndex();
170 bMoveBack = false;
173 if( (RES_PARATR_BEGIN <= nWhich && bMoveBack) ||
174 pAttr->GetSttParaIdx() < pOldEndPara->GetIndex() ||
175 (pAttr->GetSttPara() == *pOldEndPara &&
176 pAttr->GetSttCnt() != nOldEndCnt) )
178 // Das Attribut muss gesetzt werden. Da wir
179 // das Original noch brauchen, weil Zeiger auf das Attribut
180 // noch in den Kontexten existieren, muessen wir es clonen.
181 // Die Next-Liste geht dabei verloren, aber die
182 // Previous-Liste bleibt erhalten
183 HTMLAttr *pSetAttr = pAttr->Clone( *pOldEndPara, nOldEndCnt );
185 if( pNext )
186 pNext->InsertPrev( pSetAttr );
187 else
189 if (pSetAttr->bInsAtStart)
190 m_aSetAttrTab.push_front( pSetAttr );
191 else
192 m_aSetAttrTab.push_back( pSetAttr );
195 else if( pPrev )
197 // Wenn das Attribut nicht gesetzt vor der Tabelle
198 // gesetzt werden muss, muessen der Previous-Attribute
199 // trotzdem gesetzt werden.
200 if( pNext )
201 pNext->InsertPrev( pPrev );
202 else
204 if (pPrev->bInsAtStart)
205 m_aSetAttrTab.push_front( pPrev );
206 else
207 m_aSetAttrTab.push_back( pPrev );
211 // den Start des Attributs neu setzen
212 pAttr->nSttPara = rNewSttPara;
213 pAttr->nEndPara = rNewSttPara;
214 pAttr->nSttContent = nNewSttCnt;
215 pAttr->nEndContent = nNewSttCnt;
216 pAttr->pPrev = nullptr;
218 pAttr = pNext;
222 if( bMoveBack )
223 m_pPam->Move( fnMoveForward );
227 void SwHTMLParser::SaveDocContext( HTMLAttrContext *pCntxt,
228 HtmlContextFlags nFlags,
229 const SwPosition *pNewPos )
231 HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext( true );
232 pSave->SetStripTrailingPara( bool(HtmlContextFlags::StripPara & nFlags) );
233 pSave->SetKeepNumRules( bool(HtmlContextFlags::KeepNumrule & nFlags) );
234 pSave->SetFixHeaderDist( bool(HtmlContextFlags::HeaderDist & nFlags) );
235 pSave->SetFixFooterDist( bool(HtmlContextFlags::FooterDist & nFlags) );
237 if( pNewPos )
239 // Wenn der PaM an eine andere Position gesetzt wird, muss
240 // die Numerierung gerettet werden..
241 if( !pSave->GetKeepNumRules() )
243 // Die Numerierung soll nicht beibehalten werden. Also muss
244 // der aktuelle Zustand gerettet und die Numerierung
245 // anschliessend ausgeschaltet werden.
246 pSave->SetNumInfo( GetNumInfo() );
247 GetNumInfo().Clear();
250 if( HtmlContextFlags::KeepAttrs & nFlags )
252 // Attribute an aktueller Position beenden und an neuer neu anfangen
253 SplitAttrTab( *pNewPos );
255 else
257 HTMLAttrTable *pSaveAttrTab = pSave->GetAttrTab( true );
258 SaveAttrTab( *pSaveAttrTab );
261 pSave->SetPos( *m_pPam->GetPoint() );
262 *m_pPam->GetPoint() = *pNewPos;
265 // Mit dem Setzen von nContextStMin koennen automatisch auch
266 // keine gerade offenen Listen (DL/OL/UL) mehr beendet werden.
267 if( HtmlContextFlags::ProtectStack & nFlags )
269 pSave->SetContextStMin( m_nContextStMin );
270 m_nContextStMin = m_aContexts.size();
272 if( HtmlContextFlags::KeepAttrs & nFlags )
274 pSave->SetContextStAttrMin( m_nContextStAttrMin );
275 m_nContextStAttrMin = m_aContexts.size();
280 void SwHTMLParser::RestoreDocContext( HTMLAttrContext *pCntxt )
282 HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext();
283 if( !pSave )
284 return;
286 if( pSave->GetStripTrailingPara() )
287 StripTrailingPara();
289 if( pSave->GetPos() )
291 if( pSave->GetFixHeaderDist() || pSave->GetFixFooterDist() )
292 FixHeaderFooterDistance( pSave->GetFixHeaderDist(),
293 pSave->GetPos() );
295 HTMLAttrTable *pSaveAttrTab = pSave->GetAttrTab();
296 if( !pSaveAttrTab )
298 // Attribute an aktueller Position beenden und an alter neu
299 // anfangen.
300 SplitAttrTab( *pSave->GetPos() );
302 else
304 RestoreAttrTab( *pSaveAttrTab );
307 *m_pPam->GetPoint() = *pSave->GetPos();
309 // Die bisherigen Attribute koennen wir schonmal setzen.
310 SetAttr();
313 if( SIZE_MAX != pSave->GetContextStMin() )
315 m_nContextStMin = pSave->GetContextStMin();
316 if( SIZE_MAX != pSave->GetContextStAttrMin() )
317 m_nContextStAttrMin = pSave->GetContextStAttrMin();
320 if( !pSave->GetKeepNumRules() )
322 // Die bisherige gemerkte Numerierung wieder setzen
323 GetNumInfo().Set( pSave->GetNumInfo() );
326 pCntxt->ClearSaveDocContext();
329 void SwHTMLParser::EndContext( HTMLAttrContext *pContext )
331 if( pContext->GetPopStack() )
333 // Alle noch offenen Kontexte beenden. Der eigene
334 // Kontext muss bereits geloscht sein!
335 while( m_aContexts.size() > m_nContextStMin )
337 HTMLAttrContext *pCntxt = PopContext();
338 OSL_ENSURE( pCntxt != pContext,
339 "Kontext noch im Stack" );
340 if( pCntxt == pContext )
341 break;
343 EndContext( pCntxt );
344 delete pCntxt;
348 // Alle noch offenen Attribute beenden
349 if( pContext->HasAttrs() )
350 EndContextAttrs( pContext );
352 // Falls ein Bereich geoeffnet wurde, den verlassen. Da Bereiche
353 // auch innerhalb von absolut positionierten Objekten angelegt werden,
354 // muss das passieren, bever ein alter Dokument-Kontext restauriert wird.
355 if( pContext->GetSpansSection() )
356 EndSection();
358 // Rahmen und sonstige Sonderbereiche verlassen.
359 if( pContext->HasSaveDocContext() )
360 RestoreDocContext( pContext );
362 // Ggf. noch einen Ansatz-Umbruch einfuegen
363 if( AM_NONE != pContext->GetAppendMode() &&
364 m_pPam->GetPoint()->nContent.GetIndex() )
365 AppendTextNode( pContext->GetAppendMode() );
367 // PRE-/LISTING- und XMP-Umgebungen wieder starten
368 if( pContext->IsFinishPREListingXMP() )
369 FinishPREListingXMP();
371 if( pContext->IsRestartPRE() )
372 StartPRE();
374 if( pContext->IsRestartXMP() )
375 StartXMP();
377 if( pContext->IsRestartListing() )
378 StartListing();
381 void SwHTMLParser::ClearContext( HTMLAttrContext *pContext )
383 HTMLAttrs &rAttrs = pContext->GetAttrs();
384 for( auto pAttr : rAttrs )
386 // einfaches Loeschen reicht hier nicht, weil das
387 // Attribut auch aus seiner Liste ausgetragen werden
388 // muss. Theoretisch koennt man natuerlich auch die Liste
389 // und die Attribute getrennt loeschen, aber wenn man
390 // dann was falsch gemacht hat, sieht es uebel aus.
391 DeleteAttr( pAttr );
394 OSL_ENSURE( !pContext->GetSpansSection(),
395 "Bereich kann nicht mehr verlassen werden" );
397 OSL_ENSURE( !pContext->HasSaveDocContext(),
398 "Rahmen kann nicht mehr verlassen werden" );
400 // PRE-/LISTING- und XMP-Umgebungen wieder starten
401 if( pContext->IsFinishPREListingXMP() )
402 FinishPREListingXMP();
404 if( pContext->IsRestartPRE() )
405 StartPRE();
407 if( pContext->IsRestartXMP() )
408 StartXMP();
410 if( pContext->IsRestartListing() )
411 StartListing();
414 bool SwHTMLParser::DoPositioning( SfxItemSet &rItemSet,
415 SvxCSS1PropertyInfo &rPropInfo,
416 HTMLAttrContext *pContext )
418 bool bRet = false;
420 // Unter folgenden Umstaenden wird jetzt ein Rahmen aufgemacht:
421 // - das Tag wird absolut positioniert und left/top sind beide
422 // gegeben und enthalten auch keine %-Angabe, oder
423 // - das Tag soll fliessen, und
424 // - es wurde eine Breite angegeben (in beiden Faellen noetig)
425 if( SwCSS1Parser::MayBePositioned( rPropInfo ) )
427 SfxItemSet aFrameItemSet( m_pDoc->GetAttrPool(),
428 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
429 if( !IsNewDoc() )
430 Reader::ResetFrameFormatAttrs(aFrameItemSet );
432 // Ausrichtung setzen
433 SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE, rItemSet, rPropInfo,
434 aFrameItemSet );
436 // Groesse setzen
437 SetVarSize( rItemSet, rPropInfo, aFrameItemSet );
439 // Abstaende setzen
440 SetSpace( Size(0,0), rItemSet, rPropInfo, aFrameItemSet );
442 // Sonstige CSS1-Attribute Setzen
443 SetFrameFormatAttrs( rItemSet, rPropInfo,
444 HtmlFrameFormatFlags::Box|HtmlFrameFormatFlags::Padding|HtmlFrameFormatFlags::Background|HtmlFrameFormatFlags::Direction,
445 aFrameItemSet );
447 InsertFlyFrame(aFrameItemSet, pContext, rPropInfo.m_aId);
448 pContext->SetPopStack( true );
449 rPropInfo.m_aId.clear();
450 bRet = true;
453 return bRet;
456 bool SwHTMLParser::CreateContainer( const OUString& rClass,
457 SfxItemSet &rItemSet,
458 SvxCSS1PropertyInfo &rPropInfo,
459 HTMLAttrContext *pContext )
461 bool bRet = false;
462 if( rClass.equalsIgnoreAsciiCase( "sd-abs-pos" ) &&
463 SwCSS1Parser::MayBePositioned( rPropInfo ) )
465 // Container-Klasse
466 SfxItemSet *pFrameItemSet = pContext->GetFrameItemSet( m_pDoc );
467 if( !IsNewDoc() )
468 Reader::ResetFrameFormatAttrs( *pFrameItemSet );
470 SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE,
471 rItemSet, rPropInfo, *pFrameItemSet );
472 Size aDummy(0,0);
473 SetFixSize( aDummy, aDummy, false, false, rItemSet, rPropInfo,
474 *pFrameItemSet );
475 SetSpace( aDummy, rItemSet, rPropInfo, *pFrameItemSet );
476 SetFrameFormatAttrs( rItemSet, rPropInfo, HtmlFrameFormatFlags::Box|HtmlFrameFormatFlags::Background|HtmlFrameFormatFlags::Direction,
477 *pFrameItemSet );
479 bRet = true;
482 return bRet;
485 void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
486 SvxCSS1PropertyInfo &rPropInfo,
487 HTMLAttrContext *pContext,
488 bool bCharLvl )
490 // Ein DropCap-Attribut basteln, wenn auf Zeichen-Ebene vor dem
491 // ersten Zeichen ein float: left vorkommt
492 if( bCharLvl && !m_pPam->GetPoint()->nContent.GetIndex() &&
493 SVX_ADJUST_LEFT == rPropInfo.m_eFloat )
495 SwFormatDrop aDrop;
496 aDrop.GetChars() = 1;
498 m_pCSS1Parser->FillDropCap( aDrop, rItemSet );
500 // Nur wenn das Initial auch ueber mehrere Zeilen geht, wird das
501 // DropCap-Attribut gesetzt. Sonst setzten wir die Attribute hart.
502 if( aDrop.GetLines() > 1 )
504 NewAttr( &m_aAttrTab.pDropCap, aDrop );
506 HTMLAttrs &rAttrs = pContext->GetAttrs();
507 rAttrs.push_back( m_aAttrTab.pDropCap );
509 return;
513 if( !bCharLvl )
514 m_pCSS1Parser->SetFormatBreak( rItemSet, rPropInfo );
516 OSL_ENSURE(m_aContexts.size() <= m_nContextStAttrMin ||
517 m_aContexts.back() != pContext,
518 "SwHTMLParser::InsertAttrs: Context already on the Stack");
520 SfxItemIter aIter( rItemSet );
522 const SfxPoolItem *pItem = aIter.FirstItem();
523 while( pItem )
525 HTMLAttr **ppAttr = nullptr;
527 switch( pItem->Which() )
529 case RES_LR_SPACE:
531 // Absatz-Einzuege muessen addiert werden und werden immer
532 // nur absatzweise gesetzt (fuer den ersten Absatz hier,
533 // fuer alle folgenden in SetTextCollAttrs)
535 const SvxLRSpaceItem *pLRItem =
536 static_cast<const SvxLRSpaceItem *>(pItem);
538 // die bisherigen Absatz-Abstaende holen (ohne die vom
539 // obersten Kontext, denn den veraendern wir ja gerade) ...
540 sal_uInt16 nOldLeft = 0, nOldRight = 0;
541 short nOldIndent = 0;
542 bool bIgnoreTop = m_aContexts.size() > m_nContextStMin &&
543 m_aContexts.back() == pContext;
544 GetMarginsFromContext( nOldLeft, nOldRight, nOldIndent,
545 bIgnoreTop );
547 // und noch die aktuell gueltigen
548 sal_uInt16 nLeft = nOldLeft, nRight = nOldRight;
549 short nIndent = nOldIndent;
550 pContext->GetMargins( nLeft, nRight, nIndent );
552 // ... und die neuen Abstaende zu den alten addieren
553 // Hier werden nicht die aus dem Item genommen, sondern die
554 // extra gemerkten, weil die auch negativ sein koennen. Die
555 // Abfrage ueber das Item funktioniert aber trotzdem, denn
556 // fuer negative Werte wird das Item (mit Wert 0) auch
557 // eingefuegt.
558 if( rPropInfo.m_bLeftMargin )
560 OSL_ENSURE( rPropInfo.m_nLeftMargin < 0 ||
561 rPropInfo.m_nLeftMargin == pLRItem->GetTextLeft(),
562 "linker Abstand stimmt nicht mit Item ueberein" );
563 if( rPropInfo.m_nLeftMargin < 0 &&
564 -rPropInfo.m_nLeftMargin > nOldLeft )
565 nLeft = 0;
566 else
567 nLeft = nOldLeft + static_cast< sal_uInt16 >(rPropInfo.m_nLeftMargin);
569 if( rPropInfo.m_bRightMargin )
571 OSL_ENSURE( rPropInfo.m_nRightMargin < 0 ||
572 rPropInfo.m_nRightMargin == pLRItem->GetRight(),
573 "rechter Abstand stimmt nicht mit Item ueberein" );
574 if( rPropInfo.m_nRightMargin < 0 &&
575 -rPropInfo.m_nRightMargin > nOldRight )
576 nRight = 0;
577 else
578 nRight = nOldRight + static_cast< sal_uInt16 >(rPropInfo.m_nRightMargin);
580 if( rPropInfo.m_bTextIndent )
581 nIndent = pLRItem->GetTextFirstLineOfst();
583 // und die Werte fuer nachfolgende Absaetze merken
584 pContext->SetMargins( nLeft, nRight, nIndent );
586 // das Attribut noch am aktuellen Absatz setzen
587 SvxLRSpaceItem aLRItem( *pLRItem );
588 aLRItem.SetTextFirstLineOfst( nIndent );
589 aLRItem.SetTextLeft( nLeft );
590 aLRItem.SetRight( nRight );
591 NewAttr( &m_aAttrTab.pLRSpace, aLRItem );
592 EndAttr( m_aAttrTab.pLRSpace, false );
594 break;
596 case RES_UL_SPACE:
597 if( !rPropInfo.m_bTopMargin || !rPropInfo.m_bBottomMargin )
599 sal_uInt16 nUpper = 0, nLower = 0;
600 GetULSpaceFromContext( nUpper, nLower );
601 SvxULSpaceItem aULSpace( *static_cast<const SvxULSpaceItem *>(pItem) );
602 if( !rPropInfo.m_bTopMargin )
603 aULSpace.SetUpper( nUpper );
604 if( !rPropInfo.m_bBottomMargin )
605 aULSpace.SetLower( nLower );
607 NewAttr( &m_aAttrTab.pULSpace, aULSpace );
609 // ... und noch die Kontext-Information speichern
610 HTMLAttrs &rAttrs = pContext->GetAttrs();
611 rAttrs.push_back( m_aAttrTab.pULSpace );
613 pContext->SetULSpace( aULSpace.GetUpper(), aULSpace.GetLower() );
615 else
617 ppAttr = &m_aAttrTab.pULSpace;
619 break;
620 case RES_CHRATR_FONTSIZE:
621 // es werden keine Attribute mit %-Angaben gesetzt
622 if( static_cast<const SvxFontHeightItem *>(pItem)->GetProp() == 100 )
623 ppAttr = &m_aAttrTab.pFontHeight;
624 break;
625 case RES_CHRATR_CJK_FONTSIZE:
626 // es werden keine Attribute mit %-Angaben gesetzt
627 if( static_cast<const SvxFontHeightItem *>(pItem)->GetProp() == 100 )
628 ppAttr = &m_aAttrTab.pFontHeightCJK;
629 break;
630 case RES_CHRATR_CTL_FONTSIZE:
631 // es werden keine Attribute mit %-Angaben gesetzt
632 if( static_cast<const SvxFontHeightItem *>(pItem)->GetProp() == 100 )
633 ppAttr = &m_aAttrTab.pFontHeightCTL;
634 break;
636 case RES_BACKGROUND:
637 if( bCharLvl )
639 // das Frame-Attr ggf. in ein Char-Attr umwandeln
640 SvxBrushItem aBrushItem( *static_cast<const SvxBrushItem *>(pItem) );
641 aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
643 // Das Attribut setzen ...
644 NewAttr( &m_aAttrTab.pCharBrush, aBrushItem );
646 // ... und noch die Kontext-Information speichern
647 HTMLAttrs &rAttrs = pContext->GetAttrs();
648 rAttrs.push_back( m_aAttrTab.pCharBrush );
650 else if( pContext->GetToken() != HTML_TABLEHEADER_ON &&
651 pContext->GetToken() != HTML_TABLEDATA_ON )
653 ppAttr = &m_aAttrTab.pBrush;
655 break;
657 case RES_BOX:
658 if( bCharLvl )
660 SvxBoxItem aBoxItem( *static_cast<const SvxBoxItem *>(pItem) );
661 aBoxItem.SetWhich( RES_CHRATR_BOX );
663 NewAttr( &m_aAttrTab.pCharBox, aBoxItem );
665 HTMLAttrs &rAttrs = pContext->GetAttrs();
666 rAttrs.push_back( m_aAttrTab.pCharBox );
668 else
670 ppAttr = &m_aAttrTab.pBox;
672 break;
674 default:
675 // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
676 ppAttr = GetAttrTabEntry( pItem->Which() );
677 break;
680 if( ppAttr )
682 // Das Attribut setzen ...
683 NewAttr( ppAttr, *pItem );
685 // ... und noch die Kontext-Information speichern
686 HTMLAttrs &rAttrs = pContext->GetAttrs();
687 rAttrs.push_back( *ppAttr );
690 // auf zum naechsten Item
691 pItem = aIter.NextItem();
694 if( !rPropInfo.m_aId.isEmpty() )
695 InsertBookmark( rPropInfo.m_aId );
698 void SwHTMLParser::InsertAttr( HTMLAttr **ppAttr, const SfxPoolItem & rItem,
699 HTMLAttrContext *pCntxt )
701 if( !ppAttr )
703 ppAttr = GetAttrTabEntry( rItem.Which() );
704 if( !ppAttr )
705 return;
708 // das Attribut setzen
709 NewAttr( ppAttr, rItem );
711 // und im Kontext merken
712 HTMLAttrs &rAttrs = pCntxt->GetAttrs();
713 rAttrs.push_back( *ppAttr );
716 void SwHTMLParser::SplitPREListingXMP( HTMLAttrContext *pCntxt )
718 // PRE/Listing/XMP soll beim beenden des Kontexts beendet werden.
719 pCntxt->SetFinishPREListingXMP( true );
721 // Und die jetzt gueltigen Flags sollen wieder gesetzt werden.
722 if( IsReadPRE() )
723 pCntxt->SetRestartPRE( true );
724 if( IsReadXMP() )
725 pCntxt->SetRestartXMP( true );
726 if( IsReadListing() )
727 pCntxt->SetRestartListing( true );
729 // PRE/Listing/XMP wird auuserdem sofort beendet
730 FinishPREListingXMP();
733 SfxItemSet *HTMLAttrContext::GetFrameItemSet( SwDoc *pCreateDoc )
735 if( !pFrameItemSet && pCreateDoc )
736 pFrameItemSet = new SfxItemSet( pCreateDoc->GetAttrPool(),
737 RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
738 return pFrameItemSet;
741 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */