blob: 953e2029c0bcdd78dd55d96f3428eefc2ed16384 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#include "hintids.hxx"
#include <svl/itemiter.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/brshitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <svtools/htmltokn.h>
#include "doc.hxx"
#include "pam.hxx"
#include "ndtxt.hxx"
#include "shellio.hxx"
#include "paratr.hxx"
#include "htmlnum.hxx"
#include "css1kywd.hxx"
#include "swcss1.hxx"
#include "swhtml.hxx"
using namespace ::com::sun::star;
/* */
class _HTMLAttrContext_SaveDoc
{
SwHTMLNumRuleInfo aNumRuleInfo; // In Umgebung gueltige Numerierung
SwPosition *pPos; // hierhin beim verlassen den
// Kontexts zurueckgesprungen
_HTMLAttrTable *pAttrTab; // In Umgebung gueltige Attribute,
// wenn Attributierung nicht
// beibehalten werden soll.
sal_uInt16 nContextStMin; // In Umgebung gueltige Stack-
// Untergrenze, wenn der Stack
// geschuetzt werden soll.
sal_uInt16 nContextStAttrMin; // In Umgebung gueltige Stack-
// Untergrenze, wenn die Attribute
// nicht beibehalten werden sollen.
sal_Bool bStripTrailingPara : 1; // letzen Absatz entfernen?
sal_Bool bKeepNumRules : 1; // Numerierung beibehalten?
sal_Bool bPopStack : 1; // Stack-Elemente oberhalb des
// zu schliessenden entfernen?
sal_Bool bFixHeaderDist : 1;
sal_Bool bFixFooterDist : 1;
public:
_HTMLAttrContext_SaveDoc() :
pPos( 0 ), pAttrTab( 0 ),
nContextStMin( USHRT_MAX ), nContextStAttrMin( USHRT_MAX ),
bStripTrailingPara( sal_False ), bKeepNumRules( sal_False ),
bPopStack( sal_False ),
bFixHeaderDist( sal_False ), bFixFooterDist( sal_False )
{}
~_HTMLAttrContext_SaveDoc() { delete pPos; delete pAttrTab; }
// Die Position gehoert uns, muss also angelegt und zerstoert werden
void SetPos( const SwPosition& rPos ) { pPos = new SwPosition(rPos); }
const SwPosition *GetPos() const { return pPos; }
// Der Index gehoert uns nicht. Kein Anlgen und Zerstoeren.
void SetNumInfo( const SwHTMLNumRuleInfo& rInf ) { aNumRuleInfo.Set(rInf); }
const SwHTMLNumRuleInfo& GetNumInfo() const { return aNumRuleInfo; }
_HTMLAttrTable *GetAttrTab( sal_Bool bCreate= sal_False );
void SetContextStMin( sal_uInt16 nMin ) { nContextStMin = nMin; }
sal_uInt16 GetContextStMin() const { return nContextStMin; }
void SetContextStAttrMin( sal_uInt16 nMin ) { nContextStAttrMin = nMin; }
sal_uInt16 GetContextStAttrMin() const { return nContextStAttrMin; }
void SetStripTrailingPara( sal_Bool bSet ) { bStripTrailingPara = bSet; }
sal_Bool GetStripTrailingPara() const { return bStripTrailingPara; }
void SetKeepNumRules( sal_Bool bSet ) { bKeepNumRules = bSet; }
sal_Bool GetKeepNumRules() const { return bKeepNumRules; }
void SetFixHeaderDist( sal_Bool bSet ) { bFixHeaderDist = bSet; }
sal_Bool GetFixHeaderDist() const { return bFixHeaderDist; }
void SetFixFooterDist( sal_Bool bSet ) { bFixFooterDist = bSet; }
sal_Bool GetFixFooterDist() const { return bFixFooterDist; }
};
_HTMLAttrTable *_HTMLAttrContext_SaveDoc::GetAttrTab( sal_Bool bCreate )
{
if( !pAttrTab && bCreate )
{
pAttrTab = new _HTMLAttrTable;
memset( pAttrTab, 0, sizeof( _HTMLAttrTable ));
}
return pAttrTab;
}
/* */
_HTMLAttrContext_SaveDoc *_HTMLAttrContext::GetSaveDocContext( sal_Bool bCreate )
{
if( !pSaveDocContext && bCreate )
pSaveDocContext = new _HTMLAttrContext_SaveDoc;
return pSaveDocContext;
}
void _HTMLAttrContext::ClearSaveDocContext()
{
delete pSaveDocContext;
pSaveDocContext = 0;
}
/* */
void SwHTMLParser::SplitAttrTab( const SwPosition& rNewPos )
{
// Hier darf es keine vorlauefigen Absatz-Attribute geben, den die
// koennten jetzt gesetzt werden und dann sind die Zeiger ungueltig!!!
ASSERT( !aParaAttrs.Count(),
"Hoechste Gefahr: Es gibt noch nicht-endgueltige Absatz-Attribute" );
if( aParaAttrs.Count() )
aParaAttrs.Remove( 0, aParaAttrs.Count() );
const SwNodeIndex* pOldEndPara = &pPam->GetPoint()->nNode;
xub_StrLen nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
const SwNodeIndex& rNewSttPara = rNewPos.nNode;
xub_StrLen nNewSttCnt = rNewPos.nContent.GetIndex();
sal_Bool bMoveBack = sal_False;
// alle noch offenen Attribute beenden und hinter der Tabelle
// neu aufspannen
_HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
nCnt--; ++pTbl )
{
_HTMLAttr *pAttr = *pTbl;
while( pAttr )
{
_HTMLAttr *pNext = pAttr->GetNext();
_HTMLAttr *pPrev = pAttr->GetPrev();
sal_uInt16 nWhich = pAttr->pItem->Which();
if( !nOldEndCnt && RES_PARATR_BEGIN <= nWhich &&
pAttr->GetSttParaIdx() < pOldEndPara->GetIndex() )
{
// Das Attribut muss eine Content-Position weiter vorne
// beendet werden
if( !bMoveBack )
{
bMoveBack = pPam->Move( fnMoveBackward );
nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
}
}
else if( bMoveBack )
{
pPam->Move( fnMoveForward );
nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
}
if( (RES_PARATR_BEGIN <= nWhich && bMoveBack) ||
pAttr->GetSttParaIdx() < pOldEndPara->GetIndex() ||
(pAttr->GetSttPara() == *pOldEndPara &&
pAttr->GetSttCnt() != nOldEndCnt) )
{
// Das Attribut muss gesetzt werden. Da wir
// das Original noch brauchen, weil Zeiger auf das Attribut
// noch in den Kontexten existieren, muessen wir es clonen.
// Die Next-Liste geht dabei verloren, aber die
// Previous-Liste bleibt erhalten
_HTMLAttr *pSetAttr = pAttr->Clone( *pOldEndPara, nOldEndCnt );
if( pNext )
pNext->InsertPrev( pSetAttr );
else
{
sal_uInt16 nTmp =
pSetAttr->bInsAtStart ? 0 : aSetAttrTab.Count();
aSetAttrTab.Insert( pSetAttr, nTmp );
}
}
else if( pPrev )
{
// Wenn das Attribut nicht gesetzt vor der Tabelle
// gesetzt werden muss, muessen der Previous-Attribute
// trotzdem gesetzt werden.
if( pNext )
pNext->InsertPrev( pPrev );
else
{
sal_uInt16 nTmp = pPrev->bInsAtStart ? 0 : aSetAttrTab.Count();
aSetAttrTab.Insert( pPrev, nTmp );
}
}
// den Start des Attributs neu setzen
pAttr->nSttPara = rNewSttPara;
pAttr->nEndPara = rNewSttPara;
pAttr->nSttCntnt = nNewSttCnt;
pAttr->nEndCntnt = nNewSttCnt;
pAttr->pPrev = 0;
pAttr = pNext;
}
}
if( bMoveBack )
pPam->Move( fnMoveForward );
}
void SwHTMLParser::SaveDocContext( _HTMLAttrContext *pCntxt,
sal_uInt16 nFlags,
const SwPosition *pNewPos )
{
_HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext( sal_True );
pSave->SetStripTrailingPara( (HTML_CNTXT_STRIP_PARA & nFlags) != 0 );
pSave->SetKeepNumRules( (HTML_CNTXT_KEEP_NUMRULE & nFlags) != 0 );
pSave->SetFixHeaderDist( (HTML_CNTXT_HEADER_DIST & nFlags) != 0 );
pSave->SetFixFooterDist( (HTML_CNTXT_FOOTER_DIST & nFlags) != 0 );
if( pNewPos )
{
// Wenn der PaM an eine andere Position gesetzt wird, muss
// die Numerierung gerettet werden..
if( !pSave->GetKeepNumRules() )
{
// Die Numerierung soll nicht beibehalten werden. Also muss
// der aktuelle Zustand gerettet und die Numerierung
// anschliessend ausgeschaltet werden.
pSave->SetNumInfo( GetNumInfo() );
GetNumInfo().Clear();
}
if( (HTML_CNTXT_KEEP_ATTRS & nFlags) != 0 )
{
// Attribute an aktueller Position beenden und an neuer neu anfangen
SplitAttrTab( *pNewPos );
}
else
{
_HTMLAttrTable *pSaveAttrTab = pSave->GetAttrTab( sal_True );
SaveAttrTab( *pSaveAttrTab );
}
pSave->SetPos( *pPam->GetPoint() );
*pPam->GetPoint() = *pNewPos;
}
// Mit dem Setzen von nContextStMin koennen automatisch auch
// keine gerade offenen Listen (DL/OL/UL) mehr beendet werden.
if( (HTML_CNTXT_PROTECT_STACK & nFlags) != 0 )
{
pSave->SetContextStMin( nContextStMin );
nContextStMin = aContexts.Count();
if( (HTML_CNTXT_KEEP_ATTRS & nFlags) == 0 )
{
pSave->SetContextStAttrMin( nContextStAttrMin );
nContextStAttrMin = aContexts.Count();
}
}
}
void SwHTMLParser::RestoreDocContext( _HTMLAttrContext *pCntxt )
{
_HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext();
if( !pSave )
return;
if( pSave->GetStripTrailingPara() )
StripTrailingPara();
if( pSave->GetPos() )
{
if( pSave->GetFixHeaderDist() || pSave->GetFixFooterDist() )
FixHeaderFooterDistance( pSave->GetFixHeaderDist(),
pSave->GetPos() );
_HTMLAttrTable *pSaveAttrTab = pSave->GetAttrTab();
if( !pSaveAttrTab )
{
// Attribute an aktueller Position beenden und an alter neu
// anfangen.
SplitAttrTab( *pSave->GetPos() );
}
else
{
RestoreAttrTab( *pSaveAttrTab );
}
*pPam->GetPoint() = *pSave->GetPos();
// Die bisherigen Attribute koennen wir schonmal setzen.
SetAttr();
}
if( USHRT_MAX != pSave->GetContextStMin() )
{
nContextStMin = pSave->GetContextStMin();
if( USHRT_MAX != pSave->GetContextStAttrMin() )
nContextStAttrMin = pSave->GetContextStAttrMin();
}
if( !pSave->GetKeepNumRules() )
{
// Die bisherige gemerkte Numerierung wieder setzen
GetNumInfo().Set( pSave->GetNumInfo() );
}
pCntxt->ClearSaveDocContext();
}
/* */
void SwHTMLParser::EndContext( _HTMLAttrContext *pContext )
{
if( pContext->GetPopStack() )
{
// Alle noch offenen Kontexte beenden. Der eigene
// Kontext muss bereits geloscht sein!
while( aContexts.Count() > nContextStMin )
{
_HTMLAttrContext *pCntxt = PopContext();
ASSERT( pCntxt != pContext,
"Kontext noch im Stack" );
if( pCntxt == pContext )
break;
EndContext( pCntxt );
delete pCntxt;
}
}
// Alle noch offenen Attribute beenden
if( pContext->HasAttrs() )
EndContextAttrs( pContext );
// Falls ein Bereich geoeffnet wurde, den verlassen. Da Bereiche
// auch innerhalb von absolut positionierten Objekten angelegt werden,
// muss das passieren, bever ein alter Dokument-Kontext restauriert wird.
if( pContext->GetSpansSection() )
EndSection();
// Rahmen und sonstige Sonderbereiche verlassen.
if( pContext->HasSaveDocContext() )
RestoreDocContext( pContext );
// Ggf. noch einen Ansatz-Umbruch einfuegen
if( AM_NONE != pContext->GetAppendMode() &&
pPam->GetPoint()->nContent.GetIndex() )
AppendTxtNode( pContext->GetAppendMode() );
// PRE-/LISTING- und XMP-Umgebungen wieder starten
if( pContext->IsFinishPREListingXMP() )
FinishPREListingXMP();
if( pContext->IsRestartPRE() )
StartPRE();
if( pContext->IsRestartXMP() )
StartXMP();
if( pContext->IsRestartListing() )
StartListing();
}
void SwHTMLParser::ClearContext( _HTMLAttrContext *pContext )
{
_HTMLAttrs &rAttrs = pContext->GetAttrs();
for( sal_uInt16 i=0; i<rAttrs.Count(); i++ )
{
// einfaches Loeschen reicht hier nicht, weil das
// Attribut auch aus seiner Liste ausgetragen werden
// muss. Theoretisch koennt man natuerlich auch die Liste
// und die Attribute getrennt loeschen, aber wenn man
// dann was falsch gemacht hat, sieht es uebel aus.
DeleteAttr( rAttrs[i] );
}
ASSERT( !pContext->GetSpansSection(),
"Bereich kann nicht mehr verlassen werden" );
ASSERT( !pContext->HasSaveDocContext(),
"Rahmen kann nicht mehr verlassen werden" );
// PRE-/LISTING- und XMP-Umgebungen wieder starten
if( pContext->IsFinishPREListingXMP() )
FinishPREListingXMP();
if( pContext->IsRestartPRE() )
StartPRE();
if( pContext->IsRestartXMP() )
StartXMP();
if( pContext->IsRestartListing() )
StartListing();
}
/* */
sal_Bool SwHTMLParser::DoPositioning( SfxItemSet &rItemSet,
SvxCSS1PropertyInfo &rPropInfo,
_HTMLAttrContext *pContext )
{
sal_Bool bRet = sal_False;
// Unter folgenden Umstaenden wird jetzt ein Rahmen aufgemacht:
// - das Tag wird absolut positioniert und left/top sind beide
// gegeben und enthalten auch keine %-Angabe, oder
// - das Tag soll fliessen, und
// - es wurde eine Breite angegeben (in beiden Faellen noetig)
if( SwCSS1Parser::MayBePositioned( rPropInfo ) )
{
SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
if( !IsNewDoc() )
Reader::ResetFrmFmtAttrs(aFrmItemSet );
// Ausrichtung setzen
SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE, rItemSet, rPropInfo,
aFrmItemSet );
// Groesse setzen
SetVarSize( rItemSet, rPropInfo, aFrmItemSet );
// Abstaende setzen
SetSpace( Size(0,0), rItemSet, rPropInfo, aFrmItemSet );
// Sonstige CSS1-Attribute Setzen
SetFrmFmtAttrs( rItemSet, rPropInfo,
HTML_FF_BOX|HTML_FF_PADDING|HTML_FF_BACKGROUND|HTML_FF_DIRECTION,
aFrmItemSet );
InsertFlyFrame( aFrmItemSet, pContext, rPropInfo.aId,
CONTEXT_FLAGS_ABSPOS );
pContext->SetPopStack( sal_True );
rPropInfo.aId.Erase();
bRet = sal_True;
}
return bRet;
}
sal_Bool SwHTMLParser::CreateContainer( const String& rClass,
SfxItemSet &rItemSet,
SvxCSS1PropertyInfo &rPropInfo,
_HTMLAttrContext *pContext )
{
sal_Bool bRet = sal_False;
if( rClass.EqualsIgnoreCaseAscii(sCSS1_class_abs_pos) &&
pCSS1Parser->MayBePositioned( rPropInfo ) )
{
// Container-Klasse
SfxItemSet *pFrmItemSet = pContext->GetFrmItemSet( pDoc );
if( !IsNewDoc() )
Reader::ResetFrmFmtAttrs( *pFrmItemSet );
SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE,
rItemSet, rPropInfo, *pFrmItemSet );
Size aDummy(0,0);
SetFixSize( aDummy, aDummy, sal_False, sal_False, rItemSet, rPropInfo,
*pFrmItemSet );
SetSpace( aDummy, rItemSet, rPropInfo, *pFrmItemSet );
SetFrmFmtAttrs( rItemSet, rPropInfo, HTML_FF_BOX|HTML_FF_BACKGROUND|HTML_FF_DIRECTION,
*pFrmItemSet );
bRet = sal_True;
}
return bRet;
}
/* */
void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
SvxCSS1PropertyInfo &rPropInfo,
_HTMLAttrContext *pContext,
sal_Bool bCharLvl )
{
// Ein DropCap-Attribut basteln, wenn auf Zeichen-Ebene vor dem
// ersten Zeichen ein float: left vorkommt
if( bCharLvl && !pPam->GetPoint()->nContent.GetIndex() &&
SVX_ADJUST_LEFT == rPropInfo.eFloat )
{
SwFmtDrop aDrop;
aDrop.GetChars() = 1;
pCSS1Parser->FillDropCap( aDrop, rItemSet );
// Nur wenn das Initial auch ueber mehrere Zeilen geht, wird das
// DropCap-Attribut gesetzt. Sonst setzten wir die Attribute hart.
if( aDrop.GetLines() > 1 )
{
NewAttr( &aAttrTab.pDropCap, aDrop );
_HTMLAttrs &rAttrs = pContext->GetAttrs();
rAttrs.Insert( aAttrTab.pDropCap, rAttrs.Count() );
return;
}
}
// Feature: PrintExt
if( !bCharLvl )
pCSS1Parser->SetFmtBreak( rItemSet, rPropInfo );
// /Feature: PrintExt
ASSERT( aContexts.Count() <= nContextStAttrMin ||
aContexts[aContexts.Count()-1] != pContext,
"SwHTMLParser::InsertAttrs: Kontext doch schon auf dem Stack" );
SfxItemIter aIter( rItemSet );
const SfxPoolItem *pItem = aIter.FirstItem();
while( pItem )
{
_HTMLAttr **ppAttr = 0;
switch( pItem->Which() )
{
case RES_LR_SPACE:
{
// Absatz-Einzuege muessen addiert werden und werden immer
// nur absatzweise gesetzt (fuer den ersten Absatz hier,
// fuer alle folgenden in SetTxtCollAttrs)
const SvxLRSpaceItem *pLRItem =
(const SvxLRSpaceItem *)pItem;
// die bisherigen Absatz-Abstaende holen (ohne die vom
// obersten Kontext, denn den veraendern wir ja gerade) ...
sal_uInt16 nOldLeft = 0, nOldRight = 0;
short nOldIndent = 0;
sal_Bool bIgnoreTop = aContexts.Count() > nContextStMin &&
aContexts[aContexts.Count()-1] == pContext;
GetMarginsFromContext( nOldLeft, nOldRight, nOldIndent,
bIgnoreTop );
// und noch die aktuell gueltigen
sal_uInt16 nLeft = nOldLeft, nRight = nOldRight;
short nIndent = nOldIndent;
pContext->GetMargins( nLeft, nRight, nIndent );
// ... und die neuen Abstaende zu den alten addieren
// Hier werden nicht die aus dem Item genommen, sondern die
// extra gemerkten, weil die auch negativ sein koennen. Die
// Abfrage ueber das Item funktioniert aber trotzdem, denn
// fuer negative Werte wird das Item (mit Wert 0) auch
// eingefuegt.
if( rPropInfo.bLeftMargin )
{
ASSERT( rPropInfo.nLeftMargin < 0 ||
rPropInfo.nLeftMargin == pLRItem->GetTxtLeft(),
"linker Abstand stimmt nicht mit Item ueberein" );
if( rPropInfo.nLeftMargin < 0 &&
-rPropInfo.nLeftMargin > nOldLeft )
nLeft = 0;
else
nLeft = nOldLeft + static_cast< sal_uInt16 >(rPropInfo.nLeftMargin);
}
if( rPropInfo.bRightMargin )
{
ASSERT( rPropInfo.nRightMargin < 0 ||
rPropInfo.nRightMargin == pLRItem->GetRight(),
"rechter Abstand stimmt nicht mit Item ueberein" );
if( rPropInfo.nRightMargin < 0 &&
-rPropInfo.nRightMargin > nOldRight )
nRight = 0;
else
nRight = nOldRight + static_cast< sal_uInt16 >(rPropInfo.nRightMargin);
}
if( rPropInfo.bTextIndent )
nIndent = pLRItem->GetTxtFirstLineOfst();
// und die Werte fuer nachfolgende Absaetze merken
pContext->SetMargins( nLeft, nRight, nIndent );
// das Attribut noch am aktuellen Absatz setzen
SvxLRSpaceItem aLRItem( *pLRItem );
aLRItem.SetTxtFirstLineOfst( nIndent );
aLRItem.SetTxtLeft( nLeft );
aLRItem.SetRight( nRight );
NewAttr( &aAttrTab.pLRSpace, aLRItem );
EndAttr( aAttrTab.pLRSpace, 0, sal_False );
}
break;
case RES_UL_SPACE:
if( !rPropInfo.bTopMargin || !rPropInfo.bBottomMargin )
{
sal_uInt16 nUpper = 0, nLower = 0;
GetULSpaceFromContext( nUpper, nLower );
SvxULSpaceItem aULSpace( *((const SvxULSpaceItem *)pItem) );
if( !rPropInfo.bTopMargin )
aULSpace.SetUpper( nUpper );
if( !rPropInfo.bBottomMargin )
aULSpace.SetLower( nLower );
NewAttr( &aAttrTab.pULSpace, aULSpace );
// ... und noch die Kontext-Information speichern
_HTMLAttrs &rAttrs = pContext->GetAttrs();
rAttrs.Insert( aAttrTab.pULSpace, rAttrs.Count() );
pContext->SetULSpace( aULSpace.GetUpper(), aULSpace.GetLower() );
}
else
{
ppAttr = &aAttrTab.pULSpace;
}
break;
case RES_CHRATR_FONTSIZE:
// es werden keine Attribute mit %-Angaben gesetzt
if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
ppAttr = &aAttrTab.pFontHeight;
break;
case RES_CHRATR_CJK_FONTSIZE:
// es werden keine Attribute mit %-Angaben gesetzt
if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
ppAttr = &aAttrTab.pFontHeightCJK;
break;
case RES_CHRATR_CTL_FONTSIZE:
// es werden keine Attribute mit %-Angaben gesetzt
if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
ppAttr = &aAttrTab.pFontHeightCTL;
break;
case RES_BACKGROUND:
if( bCharLvl )
{
// das Frame-Attr ggf. in ein Char-Attr umwandeln
SvxBrushItem aBrushItem( *(const SvxBrushItem *)pItem );
aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
// Das Attribut setzen ...
NewAttr( &aAttrTab.pCharBrush, aBrushItem );
// ... und noch die Kontext-Information speichern
_HTMLAttrs &rAttrs = pContext->GetAttrs();
rAttrs.Insert( aAttrTab.pCharBrush, rAttrs.Count() );
}
else if( pContext->GetToken() != HTML_TABLEHEADER_ON &&
pContext->GetToken() != HTML_TABLEDATA_ON )
{
ppAttr = &aAttrTab.pBrush;
}
break;
default:
// den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
ppAttr = GetAttrTabEntry( pItem->Which() );
break;
}
if( ppAttr )
{
// Das Attribut setzen ...
NewAttr( ppAttr, *pItem );
// ... und noch die Kontext-Information speichern
_HTMLAttrs &rAttrs = pContext->GetAttrs();
rAttrs.Insert( *ppAttr, rAttrs.Count() );
}
// auf zum naechsten Item
pItem = aIter.NextItem();
}
if( rPropInfo.aId.Len() )
InsertBookmark( rPropInfo.aId );
}
void SwHTMLParser::InsertAttr( _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
_HTMLAttrContext *pCntxt )
{
if( !ppAttr )
{
ppAttr = GetAttrTabEntry( rItem.Which() );
if( !ppAttr )
return;
}
// das Attribut setzen
NewAttr( ppAttr, rItem );
// und im Kontext merken
_HTMLAttrs &rAttrs = pCntxt->GetAttrs();
rAttrs.Insert( *ppAttr, rAttrs.Count() );
}
void SwHTMLParser::SplitPREListingXMP( _HTMLAttrContext *pCntxt )
{
// PRE/Listing/XMP soll beim beenden des Kontexts beendet werden.
pCntxt->SetFinishPREListingXMP( sal_True );
// Und die jetzt gueltigen Flags sollen wieder gesetzt werden.
if( IsReadPRE() )
pCntxt->SetRestartPRE( sal_True );
if( IsReadXMP() )
pCntxt->SetRestartXMP( sal_True );
if( IsReadListing() )
pCntxt->SetRestartListing( sal_True );
// PRE/Listing/XMP wird auuserdem sofort beendet
FinishPREListingXMP();
}
SfxItemSet *_HTMLAttrContext::GetFrmItemSet( SwDoc *pCreateDoc )
{
if( !pFrmItemSet && pCreateDoc )
pFrmItemSet = new SfxItemSet( pCreateDoc->GetAttrPool(),
RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
return pFrmItemSet;
}