summaryrefslogtreecommitdiff
path: root/sw/source/filter/html/htmlcss1.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/html/htmlcss1.cxx')
-rw-r--r--sw/source/filter/html/htmlcss1.cxx2485
1 files changed, 2485 insertions, 0 deletions
diff --git a/sw/source/filter/html/htmlcss1.cxx b/sw/source/filter/html/htmlcss1.cxx
new file mode 100644
index 000000000000..7fb4fd8502af
--- /dev/null
+++ b/sw/source/filter/html/htmlcss1.cxx
@@ -0,0 +1,2485 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: htmlcss1.cxx,v $
+ * $Revision: 1.27 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+
+#include "hintids.hxx"
+#include <svtools/itemiter.hxx>
+#include <svtools/whiter.hxx>
+#include <svtools/urihelper.hxx>
+#include <i18npool/mslangid.hxx>
+#include <sfx2/docfile.hxx>
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#include <svx/fhgtitem.hxx>
+#include <svx/brshitem.hxx>
+#include <svx/lrspitem.hxx>
+#include <svx/ulspitem.hxx>
+#ifndef _SVX_BOXITEM_HXX //autogen
+
+#include <svx/boxitem.hxx>
+#endif
+#include <svx/fhgtitem.hxx>
+#include <svx/flstitem.hxx>
+#include <svx/brkitem.hxx>
+#include <svx/keepitem.hxx>
+#include <svx/fontitem.hxx>
+#include <svx/langitem.hxx>
+#include <svx/frmdiritem.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtanchr.hxx>
+#include <fmtornt.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtfsize.hxx>
+#include "frmatr.hxx"
+#include <charfmt.hxx>
+#include <docary.hxx>
+
+
+#include "doc.hxx"
+#include "pam.hxx"
+#include "ndtxt.hxx"
+#include "poolfmt.hxx"
+#include "docsh.hxx"
+#include "paratr.hxx"
+#include "pagedesc.hxx"
+#include "css1kywd.hxx"
+#include "swcss1.hxx"
+#include "htmlnum.hxx"
+#include "swhtml.hxx"
+#include <numrule.hxx>
+
+using namespace ::com::sun::star;
+
+
+// Wie viele Zeilen/Zeichen sind fuer DropCaps erlaubt?
+// (Gibt es vielleicht woanders entsprechende Werte?)
+#define MAX_DROPCAP_LINES 9
+#define MAX_DROPCAP_CHARS 9
+
+void lcl_swcss1_setEncoding( SwFmt& rFmt, rtl_TextEncoding eEnc );
+
+/* */
+
+// Implementierung des SwCSS1Parsers (eigentlich swcss1.cxx)
+static struct SwCSS1ItemIds
+{
+ USHORT nFmtBreak;
+ USHORT nFmtPageDesc;
+ USHORT nFmtKeep;
+
+ SwCSS1ItemIds() :
+ nFmtBreak( RES_BREAK ),
+ nFmtPageDesc( RES_PAGEDESC ),
+ nFmtKeep( RES_KEEP )
+ {}
+
+} aItemIds;
+
+void SwCSS1Parser::ChgPageDesc( const SwPageDesc *pPageDesc,
+ const SwPageDesc& rNewPageDesc )
+{
+ USHORT nPageDescs = pDoc->GetPageDescCnt();
+ USHORT i;
+ for( i=0; i<nPageDescs; i++ )
+ if( pPageDesc == &(const_cast<const SwDoc *>(pDoc)->GetPageDesc(i)) )
+ {
+ pDoc->ChgPageDesc( i, rNewPageDesc );
+ return;
+ }
+
+ ASSERT( i<nPageDescs, "Seitenvorlage nicht gefunden" );
+}
+
+SwCSS1Parser::SwCSS1Parser( SwDoc *pD, sal_uInt32 aFHeights[7], const String& rBaseURL, BOOL bNewDoc ) :
+ SvxCSS1Parser( pD->GetAttrPool(), rBaseURL, MM50/2,
+ (USHORT*)&aItemIds, sizeof(aItemIds) / sizeof(USHORT) ),
+ pDoc( pD ),
+ nDropCapCnt( 0 ),
+ bIsNewDoc( bNewDoc ),
+ bBodyBGColorSet( FALSE ),
+ bBodyBackgroundSet( FALSE ),
+ bBodyTextSet( FALSE ),
+ bBodyLinkSet( FALSE ),
+ bBodyVLinkSet( FALSE ),
+ bSetFirstPageDesc( FALSE ),
+ bSetRightPageDesc( FALSE ),
+ bTableHeaderTxtCollSet( FALSE ),
+ bTableTxtCollSet( FALSE ),
+ bLinkCharFmtsSet( FALSE )
+{
+ aFontHeights[0] = aFHeights[0];
+ aFontHeights[1] = aFHeights[1];
+ aFontHeights[2] = aFHeights[2];
+ aFontHeights[3] = aFHeights[3];
+ aFontHeights[4] = aFHeights[4];
+ aFontHeights[5] = aFHeights[5];
+ aFontHeights[6] = aFHeights[6];
+}
+
+SwCSS1Parser::~SwCSS1Parser()
+{
+}
+
+
+/* */
+
+// Feature: PrintExt
+BOOL SwCSS1Parser::SetFmtBreak( SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rPropInfo )
+{
+ SvxBreak eBreak = SVX_BREAK_NONE;
+ BOOL bKeep = FALSE;
+ BOOL bSetKeep = FALSE, bSetBreak = FALSE, bSetPageDesc = FALSE;
+ const SwPageDesc *pPageDesc = 0;
+ switch( rPropInfo.ePageBreakBefore )
+ {
+ case SVX_CSS1_PBREAK_ALWAYS:
+ eBreak = SVX_BREAK_PAGE_BEFORE;
+ bSetBreak = TRUE;
+ break;
+ case SVX_CSS1_PBREAK_LEFT:
+ pPageDesc = GetLeftPageDesc( TRUE );
+ bSetPageDesc = TRUE;
+ break;
+ case SVX_CSS1_PBREAK_RIGHT:
+ pPageDesc = GetRightPageDesc( TRUE );
+ bSetPageDesc = TRUE;
+ break;
+ case SVX_CSS1_PBREAK_AUTO:
+ bSetBreak = bSetPageDesc = TRUE;
+ break;
+// case SVX_CSS1_PBREAK_AVOID:
+ // Hier koennte man SvxKeepItem am Absatz davor einfuegen
+// break;
+ default:
+ ;
+ }
+ switch( rPropInfo.ePageBreakAfter )
+ {
+ case SVX_CSS1_PBREAK_ALWAYS:
+ case SVX_CSS1_PBREAK_LEFT:
+ case SVX_CSS1_PBREAK_RIGHT:
+ // LEFT/RIGHT koennte man auch am Absatz davor setzen
+ eBreak = SVX_BREAK_PAGE_AFTER;
+ bSetBreak = TRUE;
+ break;
+ case SVX_CSS1_PBREAK_AUTO:
+ bSetBreak = bSetKeep = bSetPageDesc = TRUE;
+ break;
+ case SVX_CSS1_PBREAK_AVOID:
+ bKeep = bSetKeep = TRUE;
+ break;
+ default:
+ ;
+ }
+
+ if( bSetBreak )
+ rItemSet.Put( SvxFmtBreakItem( eBreak, RES_BREAK ) );
+ if( bSetPageDesc )
+ rItemSet.Put( SwFmtPageDesc( pPageDesc ) );
+ if( bSetKeep )
+ rItemSet.Put( SvxFmtKeepItem( bKeep, RES_KEEP ) );
+
+ return bSetBreak;
+}
+// /Feature: PrintExt
+
+static void SetCharFmtAttrs( SwCharFmt *pCharFmt, SfxItemSet& rItemSet )
+{
+ const SfxPoolItem *pItem;
+ static USHORT aWhichIds[3] = { RES_CHRATR_FONTSIZE,RES_CHRATR_CJK_FONTSIZE,
+ RES_CHRATR_CTL_FONTSIZE };
+ for( USHORT i=0; i<3; i++ )
+ {
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], FALSE,
+ &pItem ) &&
+ ((const SvxFontHeightItem *)pItem)->GetProp() != 100)
+ {
+ // %-Angaben beim FontHeight-Item werden nicht unterstuetzt
+ rItemSet.ClearItem( aWhichIds[i] );
+ }
+ }
+
+ pCharFmt->SetFmtAttr( rItemSet );
+
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, FALSE, &pItem ) )
+ {
+ // Ein Brush-Item mit RES_BACKGROUND muss noch in eines mit
+ // RES_CHRATR_BACKGROUND gewandelt werden
+
+ SvxBrushItem aBrushItem( *(const SvxBrushItem *)pItem );
+ aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
+ pCharFmt->SetFmtAttr( aBrushItem );
+ }
+}
+
+void SwCSS1Parser::SetLinkCharFmts()
+{
+ ASSERT( !bLinkCharFmtsSet, "Aufruf von SetLinkCharFmts unnoetig" );
+
+ SvxCSS1MapEntry *pStyleEntry =
+ GetTag( String::CreateFromAscii(OOO_STRING_SVTOOLS_HTML_anchor) );
+ SwCharFmt *pUnvisited = 0, *pVisited = 0;
+ if( pStyleEntry )
+ {
+ SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
+ BOOL bColorSet = (SFX_ITEM_SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
+ FALSE));
+ pUnvisited = GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL );
+ SetCharFmtAttrs( pUnvisited, rItemSet );
+ bBodyLinkSet |= bColorSet;
+
+ pVisited = GetCharFmtFromPool( RES_POOLCHR_INET_VISIT );
+ SetCharFmtAttrs( pVisited, rItemSet );
+ bBodyVLinkSet |= bColorSet;
+ }
+
+ String sTmp( String::CreateFromAscii(OOO_STRING_SVTOOLS_HTML_anchor) );
+ sTmp.Append( ':' );
+ sTmp.AppendAscii( sCSS1_link );
+ pStyleEntry = GetTag( sTmp );
+ if( pStyleEntry )
+ {
+ SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
+ BOOL bColorSet = (SFX_ITEM_SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
+ FALSE));
+ if( !pUnvisited )
+ pUnvisited = GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL );
+ SetCharFmtAttrs( pUnvisited, rItemSet );
+ bBodyLinkSet |= bColorSet;
+ }
+
+ sTmp.AssignAscii( OOO_STRING_SVTOOLS_HTML_anchor );
+ sTmp.Assign( ':' );
+ sTmp.AppendAscii( sCSS1_visited );
+ pStyleEntry = GetTag( sTmp );
+ if( pStyleEntry )
+ {
+ SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
+ BOOL bColorSet = (SFX_ITEM_SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
+ FALSE));
+ if( !pVisited )
+ pVisited = GetCharFmtFromPool( RES_POOLCHR_INET_VISIT );
+ SetCharFmtAttrs( pVisited, rItemSet );
+ bBodyVLinkSet |= bColorSet;
+ }
+
+ bLinkCharFmtsSet = TRUE;
+}
+
+static void SetTxtCollAttrs( SwTxtFmtColl *pColl, SfxItemSet& rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ SwCSS1Parser *pCSS1Parser )
+{
+ const SfxItemSet& rCollItemSet = pColl->GetAttrSet();
+ const SfxPoolItem *pCollItem, *pItem;
+
+ // linker, rechter Rand und Erstzeilen-Einzug
+ if( (rPropInfo.bLeftMargin || rPropInfo.bRightMargin ||
+ rPropInfo.bTextIndent) &&
+ (!rPropInfo.bLeftMargin || !rPropInfo.bRightMargin ||
+ !rPropInfo.bTextIndent) &&
+ SFX_ITEM_SET == rCollItemSet.GetItemState(RES_LR_SPACE,TRUE,&pCollItem) &&
+ SFX_ITEM_SET == rItemSet.GetItemState(RES_LR_SPACE,FALSE,&pItem) )
+ {
+ const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
+
+ SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem *)pCollItem) );
+ if( rPropInfo.bLeftMargin )
+ aLRItem.SetTxtLeft( pLRItem->GetTxtLeft() );
+ if( rPropInfo.bRightMargin )
+ aLRItem.SetRight( pLRItem->GetRight() );
+ if( rPropInfo.bTextIndent )
+ aLRItem.SetTxtFirstLineOfst( pLRItem->GetTxtFirstLineOfst() );
+
+ rItemSet.Put( aLRItem );
+ }
+
+ // oberer und unterer Rand
+ if( (rPropInfo.bTopMargin || rPropInfo.bBottomMargin) &&
+ (!rPropInfo.bTopMargin || !rPropInfo.bBottomMargin) &&
+ SFX_ITEM_SET == rCollItemSet.GetItemState(RES_UL_SPACE,TRUE,
+ &pCollItem) &&
+ SFX_ITEM_SET == rItemSet.GetItemState(RES_UL_SPACE,FALSE,&pItem) )
+ {
+ const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
+
+ SvxULSpaceItem aULItem( *((const SvxULSpaceItem *)pCollItem) );
+ if( rPropInfo.bTopMargin )
+ aULItem.SetUpper( pULItem->GetUpper() );
+ if( rPropInfo.bBottomMargin )
+ aULItem.SetLower( pULItem->GetLower() );
+
+ rItemSet.Put( aULItem );
+ }
+
+ static USHORT aWhichIds[3] = { RES_CHRATR_FONTSIZE,RES_CHRATR_CJK_FONTSIZE,
+ RES_CHRATR_CTL_FONTSIZE };
+ for( USHORT i=0; i<3; i++ )
+ {
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], FALSE,
+ &pItem ) &&
+ ((const SvxFontHeightItem *)pItem)->GetProp() != 100)
+ {
+ // %-Angaben beim FontHeight-Item werden nicht unterstuetzt
+ rItemSet.ClearItem( aWhichIds[i] );
+ }
+ }
+
+// Feature: PrintExt
+ pCSS1Parser->SetFmtBreak( rItemSet, rPropInfo );
+// /Feature: PrintExt
+
+ pColl->SetFmtAttr( rItemSet );
+}
+
+void SwCSS1Parser::SetTableTxtColl( BOOL bHeader )
+{
+ ASSERT( !(bHeader ? bTableHeaderTxtCollSet : bTableTxtCollSet),
+ "Aufruf von SetTableTxtColl unnoetig" );
+
+ USHORT nPoolId;
+ String sTag;
+ if( bHeader )
+ {
+ nPoolId = RES_POOLCOLL_TABLE_HDLN;
+ sTag.AssignAscii( OOO_STRING_SVTOOLS_HTML_tableheader );
+ }
+ else
+ {
+ nPoolId = RES_POOLCOLL_TABLE;
+ sTag.AssignAscii( OOO_STRING_SVTOOLS_HTML_tabledata );
+ }
+
+ SwTxtFmtColl *pColl = 0;
+
+ // The following entries will never be used again and may be changed.
+ SvxCSS1MapEntry *pStyleEntry = GetTag( sTag );
+ if( pStyleEntry )
+ {
+ pColl = GetTxtFmtColl( nPoolId, aEmptyStr );
+ SetTxtCollAttrs( pColl, pStyleEntry->GetItemSet(),
+ pStyleEntry->GetPropertyInfo(), this );
+ }
+
+ String sTmp( sTag );
+ sTmp.Append( ' ' );
+ sTmp.AppendAscii( OOO_STRING_SVTOOLS_HTML_parabreak );
+ pStyleEntry = GetTag( sTmp );
+ if( pStyleEntry )
+ {
+ if( !pColl )
+ pColl = GetTxtFmtColl( nPoolId, aEmptyStr );
+ SetTxtCollAttrs( pColl, pStyleEntry->GetItemSet(),
+ pStyleEntry->GetPropertyInfo(), this );
+ }
+
+ if( bHeader )
+ bTableHeaderTxtCollSet = TRUE;
+ else
+ bTableTxtCollSet = TRUE;
+}
+
+void SwCSS1Parser::SetPageDescAttrs( const SvxBrushItem *pBrush,
+ SfxItemSet *pItemSet2 )
+{
+ SvxBrushItem aBrushItem( RES_BACKGROUND );
+ SvxBoxItem aBoxItem( RES_BOX );
+ SvxFrameDirectionItem aFrmDirItem(FRMDIR_ENVIRONMENT, RES_FRAMEDIR);
+ BOOL bSetBrush = pBrush!=0, bSetBox = FALSE, bSetFrmDir = FALSE;
+ if( pBrush )
+ aBrushItem = *pBrush;
+
+ if( pItemSet2 )
+ {
+ const SfxPoolItem *pItem = 0;
+ if( SFX_ITEM_SET == pItemSet2->GetItemState( RES_BACKGROUND, FALSE,
+ &pItem ) )
+ {
+ // ein Hintergrund wird gesetzt
+ aBrushItem = *((const SvxBrushItem *)pItem);
+ pItemSet2->ClearItem( RES_BACKGROUND );
+ bSetBrush = TRUE;
+ }
+
+ if( SFX_ITEM_SET == pItemSet2->GetItemState( RES_BOX, FALSE, &pItem ) )
+ {
+ // eine Umrandung wird gesetzt
+ aBoxItem = *((const SvxBoxItem *)pItem);
+ pItemSet2->ClearItem( RES_BOX );
+ bSetBox = TRUE;
+ }
+
+ if( SFX_ITEM_SET == pItemSet2->GetItemState( RES_BOX, FALSE, &pItem ) )
+ {
+ // eine Umrandung wird gesetzt
+ aBoxItem = *((const SvxBoxItem *)pItem);
+ pItemSet2->ClearItem( RES_BOX );
+ bSetBox = TRUE;
+ }
+
+ if( SFX_ITEM_SET == pItemSet2->GetItemState( RES_FRAMEDIR, FALSE, &pItem ) )
+ {
+ // eine Umrandung wird gesetzt
+ aFrmDirItem = *static_cast< const SvxFrameDirectionItem *>( pItem );
+ pItemSet2->ClearItem( RES_FRAMEDIR );
+ bSetFrmDir = TRUE;
+ }
+ }
+
+ if( bSetBrush || bSetBox || bSetFrmDir )
+ {
+ static USHORT aPoolIds[] = { RES_POOLPAGE_HTML, RES_POOLPAGE_FIRST,
+ RES_POOLPAGE_LEFT, RES_POOLPAGE_RIGHT };
+ for( USHORT i=0; i<4; i++ )
+ {
+ const SwPageDesc *pPageDesc = GetPageDesc( aPoolIds[i], FALSE );
+ if( pPageDesc )
+ {
+ SwPageDesc aNewPageDesc( *pPageDesc );
+ SwFrmFmt &rMaster = aNewPageDesc.GetMaster();
+ if( bSetBrush )
+ rMaster.SetFmtAttr( aBrushItem );
+ if( bSetBox )
+ rMaster.SetFmtAttr( aBoxItem );
+ if( bSetFrmDir )
+ rMaster.SetFmtAttr( aFrmDirItem );
+
+ ChgPageDesc( pPageDesc, aNewPageDesc );
+ }
+ }
+ }
+}
+
+// Feature: PrintExt
+void SwCSS1Parser::SetPageDescAttrs( const SwPageDesc *pPageDesc,
+ SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rPropInfo )
+{
+ if( !pPageDesc )
+ return;
+
+ SwPageDesc aNewPageDesc( *pPageDesc );
+ SwFrmFmt &rMaster = aNewPageDesc.GetMaster();
+ const SfxItemSet& rPageItemSet = rMaster.GetAttrSet();
+ const SfxPoolItem *pPageItem, *pItem;
+ BOOL bChanged = FALSE;
+
+ // linker, rechter Rand und Erstzeilen-Einzug
+ if( (rPropInfo.bLeftMargin || rPropInfo.bRightMargin) &&
+ SFX_ITEM_SET == rItemSet.GetItemState(RES_LR_SPACE,FALSE,&pItem) )
+ {
+ if( (!rPropInfo.bLeftMargin || !rPropInfo.bRightMargin) &&
+ SFX_ITEM_SET == rPageItemSet.GetItemState(RES_LR_SPACE,
+ TRUE,&pPageItem) )
+ {
+ const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
+
+ SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem *)pPageItem) );
+ if( rPropInfo.bLeftMargin )
+ aLRItem.SetLeft( pLRItem->GetLeft() );
+ if( rPropInfo.bRightMargin )
+ aLRItem.SetRight( pLRItem->GetRight() );
+
+ rMaster.SetFmtAttr( aLRItem );
+ }
+ else
+ {
+ rMaster.SetFmtAttr( *pItem );
+ }
+ bChanged = TRUE;
+ }
+
+ // oberer und unterer Rand
+ if( (rPropInfo.bTopMargin || rPropInfo.bBottomMargin) &&
+ SFX_ITEM_SET == rItemSet.GetItemState(RES_UL_SPACE,FALSE,&pItem) )
+ {
+ if( (!rPropInfo.bTopMargin || !rPropInfo.bBottomMargin) &&
+ SFX_ITEM_SET == rPageItemSet.GetItemState(RES_UL_SPACE,
+ TRUE,&pPageItem) )
+ {
+ const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
+
+ SvxULSpaceItem aULItem( *((const SvxULSpaceItem *)pPageItem) );
+ if( rPropInfo.bTopMargin )
+ aULItem.SetUpper( pULItem->GetUpper() );
+ if( rPropInfo.bBottomMargin )
+ aULItem.SetLower( pULItem->GetLower() );
+
+ rMaster.SetFmtAttr( aULItem );
+ }
+ else
+ {
+ rMaster.SetFmtAttr( *pItem );
+ }
+ bChanged = TRUE;
+ }
+
+ // die Groesse
+ if( rPropInfo.eSizeType != SVX_CSS1_STYPE_NONE )
+ {
+ if( rPropInfo.eSizeType == SVX_CSS1_STYPE_TWIP )
+ {
+ rMaster.SetFmtAttr( SwFmtFrmSize( ATT_FIX_SIZE, rPropInfo.nWidth,
+ rPropInfo.nHeight ) );
+ bChanged = TRUE;
+ }
+ else
+ {
+ // Bei "size: auto|portrait|landscape" bleibt die bisherige
+ // Groesse der Vorlage erhalten. Bei "landscape" und "portrait"
+ // wird das Landscape-Flag gesetzt und evtl. die Breite/Hoehe
+ // vertauscht.
+ SwFmtFrmSize aFrmSz( rMaster.GetFrmSize() );
+ BOOL bLandscape = aNewPageDesc.GetLandscape();
+ if( ( bLandscape &&
+ rPropInfo.eSizeType == SVX_CSS1_STYPE_PORTRAIT ) ||
+ ( !bLandscape &&
+ rPropInfo.eSizeType == SVX_CSS1_STYPE_LANDSCAPE ) )
+ {
+ SwTwips nTmp = aFrmSz.GetHeight();
+ aFrmSz.SetHeight( aFrmSz.GetWidth() );
+ aFrmSz.SetWidth( nTmp );
+ rMaster.SetFmtAttr( aFrmSz );
+ aNewPageDesc.SetLandscape( !bLandscape );
+ bChanged = TRUE;
+ }
+ }
+ }
+
+ // Geht das wirklich?
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, FALSE, &pItem ) )
+ {
+ // eine Umrandung wird gesetzt
+ rMaster.SetFmtAttr( *pItem );
+ rItemSet.ClearItem( RES_BACKGROUND );
+ bChanged = TRUE;
+ }
+
+ if( bChanged )
+ ChgPageDesc( pPageDesc, aNewPageDesc );
+}
+// /Feature: PrintExt
+
+const SvxBrushItem& SwCSS1Parser::GetPageDescBackground() const
+{
+ return pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false )
+ ->GetMaster().GetBackground();
+}
+
+sal_uInt16 SwCSS1Parser::GetScriptFromClass( String& rClass,
+ sal_Bool bSubClassOnly )
+{
+ sal_uInt16 nScriptFlags = CSS1_SCRIPT_ALL;
+ xub_StrLen nLen = rClass.Len();
+ xub_StrLen nPos = nLen > 4 ? rClass.SearchBackward( '-' ) : STRING_NOTFOUND;
+
+ if( STRING_NOTFOUND == nPos )
+ {
+ if( bSubClassOnly )
+ return nScriptFlags;
+ nPos = 0;
+ }
+ else
+ {
+ nPos++;
+ nLen = nLen - nPos;
+ }
+
+ switch( nLen )
+ {
+ case 3:
+ if( rClass.EqualsIgnoreCaseAscii( "cjk", nPos, 3 ) )
+ {
+ nScriptFlags = CSS1_SCRIPT_CJK;
+ }
+ else if( rClass.EqualsIgnoreCaseAscii( "ctl", nPos, 3 ) )
+ {
+ nScriptFlags = CSS1_SCRIPT_CTL;
+ }
+ break;
+ case 7:
+ if( rClass.EqualsIgnoreCaseAscii( "western", nPos, 7 ) )
+ {
+ nScriptFlags = CSS1_SCRIPT_WESTERN;
+ }
+ break;
+ }
+ if( CSS1_SCRIPT_ALL != nScriptFlags )
+ {
+ if( nPos )
+ {
+ rClass.Erase( nPos-1 );
+ }
+ else
+ {
+ rClass.Erase();
+ }
+ }
+
+ return nScriptFlags;
+}
+
+static CSS1SelectorType GetTokenAndClass( const CSS1Selector *pSelector,
+ String& rToken, String& rClass,
+ sal_uInt16& rScriptFlags )
+{
+ rToken = pSelector->GetString();
+ rClass.Erase();
+ rScriptFlags = CSS1_SCRIPT_ALL;
+
+ CSS1SelectorType eType = pSelector->GetType();
+ if( CSS1_SELTYPE_ELEM_CLASS==eType )
+ {
+ xub_StrLen nPos = rToken.Search( '.' );
+ ASSERT( nPos != STRING_NOTFOUND, "kein Punkt in Class-Selektor???" );
+ if( nPos != STRING_NOTFOUND )
+ {
+ rClass = rToken.Copy( nPos+1 );
+ rToken.Erase( nPos );
+
+ rScriptFlags = SwCSS1Parser::GetScriptFromClass( rClass, sal_False );
+ if( !rClass.Len() )
+ eType = CSS1_SELTYPE_ELEMENT;
+ }
+ }
+
+ rToken.ToUpperAscii();
+ return eType;
+}
+
+extern BOOL lcl_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 );
+
+static void RemoveScriptItems( SfxItemSet& rItemSet, sal_uInt16 nScript,
+ const SfxItemSet *pParentItemSet = 0 )
+{
+ static sal_uInt16 aWhichIds[3][5] =
+ {
+ { RES_CHRATR_FONT, RES_CHRATR_FONTSIZE, RES_CHRATR_LANGUAGE,
+ RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT },
+ { RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT },
+ { RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE, RES_CHRATR_CTL_LANGUAGE,
+ RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT }
+ };
+
+ sal_uInt16 aClearItems[3] = { sal_False, sal_False, sal_False };
+ switch( nScript )
+ {
+ case CSS1_SCRIPT_WESTERN:
+ aClearItems[1] = aClearItems[2] = sal_True;
+ break;
+ case CSS1_SCRIPT_CJK:
+ aClearItems[0] = aClearItems[2] = sal_True;
+ break;
+ case CSS1_SCRIPT_CTL:
+ aClearItems[0] = aClearItems[1] = sal_True;
+ break;
+ case CSS1_SCRIPT_ALL:
+ break;
+ default:
+ ASSERT( aClearItems[0], "unknown script type" );
+ break;
+ }
+
+ for( sal_uInt16 j=0; j < 3; j++ )
+ {
+ for( sal_uInt16 i=0; i < 5; i++ )
+ {
+ sal_uInt16 nWhich = aWhichIds[j][i];
+ const SfxPoolItem *pItem;
+ if( aClearItems[j] ||
+ (pParentItemSet &&
+ SFX_ITEM_SET == rItemSet.GetItemState( nWhich, sal_False, &pItem ) &&
+ (0==i ? lcl_css1atr_equalFontItems( *pItem, pParentItemSet->Get(nWhich, sal_True ) )
+ : *pItem == pParentItemSet->Get(nWhich, sal_True ) ) ) )
+ {
+ rItemSet.ClearItem( nWhich );
+ }
+ }
+ }
+}
+
+BOOL SwCSS1Parser::StyleParsed( const CSS1Selector *pSelector,
+ SfxItemSet& rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo )
+{
+ if( !bIsNewDoc )
+ return TRUE;
+
+ CSS1SelectorType eSelType = pSelector->GetType();
+ const CSS1Selector *pNext = pSelector->GetNext();
+
+ if( CSS1_SELTYPE_ID==eSelType && !pNext )
+ {
+ InsertId( pSelector->GetString(), rItemSet, rPropInfo );
+ }
+ else if( CSS1_SELTYPE_CLASS==eSelType && !pNext )
+ {
+ String aClass( pSelector->GetString() );
+ sal_uInt16 nScript = GetScriptFromClass( aClass );
+ if( CSS1_SCRIPT_ALL != nScript )
+ {
+ SfxItemSet aScriptItemSet( rItemSet );
+ RemoveScriptItems( aScriptItemSet, nScript );
+ InsertClass( aClass, aScriptItemSet, rPropInfo );
+ }
+ else
+ {
+ InsertClass( aClass, rItemSet, rPropInfo );
+ }
+ }
+ else if( CSS1_SELTYPE_PAGE==eSelType )
+ {
+ if( !pNext ||
+ (CSS1_SELTYPE_PSEUDO == pNext->GetType() &&
+ (pNext->GetString().EqualsIgnoreCaseAscii(sCSS1_left) ||
+ pNext->GetString().EqualsIgnoreCaseAscii(sCSS1_right) ||
+ pNext->GetString().EqualsIgnoreCaseAscii(sCSS1_first)) ) )
+ // || CSS1_SELTYPE_ELEMENT == pNext->GetType() )
+ {
+ String aName;
+ if( pNext )
+ aName = pNext->GetString();
+ InsertPage( aName,
+ pNext != 0 /*CSS1_SELTYPE_PSEUDO == pNext->GetType()*/,
+ rItemSet, rPropInfo );
+ }
+ }
+
+ if( CSS1_SELTYPE_ELEMENT != eSelType &&
+ CSS1_SELTYPE_ELEM_CLASS != eSelType)
+ return TRUE;
+
+ // Token und Class zu dem Selektor holen
+ String aToken2, aClass;
+ sal_uInt16 nScript;
+ eSelType = GetTokenAndClass( pSelector, aToken2, aClass, nScript );
+ int nToken2 = GetHTMLToken( aToken2 );
+
+ // und noch ein ganz par Infos zum naechsten Element
+ CSS1SelectorType eNextType = pNext ? pNext->GetType()
+ : CSS1_SELTYPE_ELEMENT;
+
+ // Erstmal ein par Spezialfaelle
+ if( CSS1_SELTYPE_ELEMENT==eSelType )
+ {
+ switch( nToken2 )
+ {
+ case HTML_ANCHOR_ON:
+ if( !pNext )
+ {
+ InsertTag( aToken2, rItemSet, rPropInfo );
+ return FALSE;
+ }
+ else if( pNext && CSS1_SELTYPE_PSEUDO == eNextType )
+ {
+ // vielleicht A:visited oder A:link
+
+ String aPseudo( pNext->GetString() );
+ aPseudo.ToLowerAscii();
+
+ BOOL bInsert = FALSE;
+ switch( aPseudo.GetChar( 0 ))
+ {
+ case 'l':
+ if( aPseudo.EqualsAscii(sCSS1_link) )
+ {
+ bInsert = TRUE;
+ }
+ break;
+ case 'v':
+ if( aPseudo.EqualsAscii(sCSS1_visited) )
+ {
+ bInsert = TRUE;
+ }
+ break;
+ }
+ if( bInsert )
+ {
+ String sTmp( aToken2 );
+ (sTmp += ':') += aPseudo;
+ if( CSS1_SCRIPT_ALL != nScript )
+ {
+ SfxItemSet aScriptItemSet( rItemSet );
+ RemoveScriptItems( aScriptItemSet, nScript );
+ InsertTag( sTmp, aScriptItemSet, rPropInfo );
+ }
+ else
+ {
+ InsertTag( sTmp, rItemSet, rPropInfo );
+ }
+ return FALSE;
+ }
+ }
+ break;
+ case HTML_BODY_ON:
+ if( !pNext )
+ {
+ // BODY
+
+ // Den Hintergrund muessen wir vor dem Setzen abfragen,
+ // denn in SetPageDescAttrs wird er geloescht.
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET==rItemSet.GetItemState(RES_BACKGROUND,FALSE,&pItem) )
+ {
+ const SvxBrushItem *pBrushItem =
+ (const SvxBrushItem *)pItem;
+
+ /// OD 02.09.2002 #99657#
+ /// Body has a background color, if it is not "no fill"/"auto fill"
+ if( pBrushItem->GetColor() != COL_TRANSPARENT )
+ bBodyBGColorSet = TRUE;
+ if( GPOS_NONE != pBrushItem->GetGraphicPos() )
+ bBodyBackgroundSet = TRUE;
+ }
+
+ // Border and Padding
+ rPropInfo.SetBoxItem( rItemSet, MIN_BORDER_DIST );
+
+ // Ein par Attribute muessen an der Seitenvorlage gesetzt werden,
+ // und zwar die, die nicht vererbt werden
+ SetPageDescAttrs( 0, &rItemSet );
+
+ // alle noch uebrigen Optionen koennen an der Standard-Vorlage
+ // gesetzt werden und gelten dann automatisch als defaults
+ if( SFX_ITEM_SET==rItemSet.GetItemState(RES_CHRATR_COLOR,FALSE) )
+ bBodyTextSet = TRUE;
+ SetTxtCollAttrs(
+ GetTxtCollFromPool( RES_POOLCOLL_STANDARD ),
+ rItemSet, rPropInfo, this );
+
+ return FALSE;
+ }
+ break;
+ }
+ }
+ else if( CSS1_SELTYPE_ELEM_CLASS==eSelType && HTML_ANCHOR_ON==nToken2 &&
+ !pNext && aClass.Len() >= 9 &&
+ ('s' == aClass.GetChar(0) || 'S' == aClass.GetChar(0)) )
+ {
+ USHORT nPoolFmtId = 0;
+ if( aClass.EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_sdendnote_sym) )
+ nPoolFmtId = RES_POOLCHR_ENDNOTE;
+ else if( aClass.EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_sdfootnote_sym) )
+ nPoolFmtId = RES_POOLCHR_FOOTNOTE;
+ if( nPoolFmtId )
+ {
+ if( CSS1_SCRIPT_ALL == nScript )
+ {
+ SetCharFmtAttrs( GetCharFmtFromPool(nPoolFmtId), rItemSet );
+ }
+ else
+ {
+ SfxItemSet aScriptItemSet( rItemSet );
+ RemoveScriptItems( aScriptItemSet, nScript );
+ SetCharFmtAttrs( GetCharFmtFromPool(nPoolFmtId),
+ aScriptItemSet);
+ }
+ return FALSE;
+ }
+ }
+
+ // Jetzt werden die Selektoren verarbeitet, die zu einer Absatz-Vorlage
+ // gehoehren
+ USHORT nPoolCollId = 0;
+ switch( nToken2 )
+ {
+ case HTML_HEAD1_ON:
+ nPoolCollId = RES_POOLCOLL_HEADLINE1;
+ break;
+ case HTML_HEAD2_ON:
+ nPoolCollId = RES_POOLCOLL_HEADLINE2;
+ break;
+ case HTML_HEAD3_ON:
+ nPoolCollId = RES_POOLCOLL_HEADLINE3;
+ break;
+ case HTML_HEAD4_ON:
+ nPoolCollId = RES_POOLCOLL_HEADLINE4;
+ break;
+ case HTML_HEAD5_ON:
+ nPoolCollId = RES_POOLCOLL_HEADLINE5;
+ break;
+ case HTML_HEAD6_ON:
+ nPoolCollId = RES_POOLCOLL_HEADLINE6;
+ break;
+ case HTML_PARABREAK_ON:
+ if( aClass.Len() >= 9 &&
+ ('s' == aClass.GetChar(0) || 'S' == aClass.GetChar(0)) )
+ {
+ if( aClass.EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_sdendnote) )
+ nPoolCollId = RES_POOLCOLL_ENDNOTE;
+ else if( aClass.EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_sdfootnote) )
+ nPoolCollId = RES_POOLCOLL_FOOTNOTE;
+
+ if( nPoolCollId )
+ aClass = aEmptyStr;
+ else
+ nPoolCollId = RES_POOLCOLL_TEXT;
+ }
+ else
+ {
+ nPoolCollId = RES_POOLCOLL_TEXT;
+ }
+ break;
+ case HTML_ADDRESS_ON:
+ nPoolCollId = RES_POOLCOLL_SENDADRESS;
+ break;
+ case HTML_BLOCKQUOTE_ON:
+ nPoolCollId = RES_POOLCOLL_HTML_BLOCKQUOTE;
+ break;
+ case HTML_DT_ON:
+ nPoolCollId = RES_POOLCOLL_HTML_DT;
+ break;
+ case HTML_DD_ON:
+ nPoolCollId = RES_POOLCOLL_HTML_DD;
+ break;
+ case HTML_PREFORMTXT_ON:
+ nPoolCollId = RES_POOLCOLL_HTML_PRE;
+ break;
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ if( CSS1_SELTYPE_ELEMENT==eSelType && !pNext )
+ {
+ InsertTag( aToken2, rItemSet, rPropInfo );
+ return FALSE;
+ }
+ else if( CSS1_SELTYPE_ELEMENT==eSelType && pNext &&
+ (CSS1_SELTYPE_ELEMENT==eNextType ||
+ CSS1_SELTYPE_ELEM_CLASS==eNextType) )
+ {
+ // nicht TH und TD, aber TH P und TD P
+ String aSubToken, aSubClass;
+ GetTokenAndClass( pNext, aSubToken, aSubClass, nScript );
+ if( HTML_PARABREAK_ON == GetHTMLToken( aSubToken ) )
+ {
+ aClass = aSubClass;
+ pNext = pNext->GetNext();
+ eNextType = pNext ? pNext->GetType() : CSS1_SELTYPE_ELEMENT;
+
+ if( aClass.Len() || pNext )
+ {
+ nPoolCollId = static_cast< USHORT >(
+ HTML_TABLEHEADER_ON == nToken2 ? RES_POOLCOLL_TABLE_HDLN
+ : RES_POOLCOLL_TABLE );
+ }
+ else
+ {
+ String sTmp( aToken2 );
+ sTmp += ' ';
+ sTmp.AppendAscii( OOO_STRING_SVTOOLS_HTML_parabreak );
+
+ if( CSS1_SCRIPT_ALL == nScript )
+ {
+ InsertTag( sTmp, rItemSet, rPropInfo );
+ }
+ else
+ {
+ SfxItemSet aScriptItemSet( rItemSet );
+ RemoveScriptItems( aScriptItemSet, nScript );
+ InsertTag( sTmp, aScriptItemSet, rPropInfo );
+ }
+
+ return FALSE;
+ }
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ if( nPoolCollId )
+ {
+ if( !pNext ||
+ (CSS1_SELTYPE_PSEUDO==eNextType &&
+#ifdef FULL_FIRST_LETTER
+ pNext->GetString().EqualsIgnoreCaseAscii(sCSS1_first_letter)) )
+#else
+ pNext->GetString().EqualsIgnoreCaseAscii(sCSS1_first_letter) &&
+ SVX_ADJUST_LEFT == rPropInfo.eFloat) )
+#endif
+ {
+ // Entweder kein zusammengesetzter Selektor oder
+ // ein X:first-line { float: left; ... }
+
+ // Die Vorlage Suchen bzw. Anlegen
+ SwTxtFmtColl *pColl = GetTxtFmtColl( nPoolCollId, aEmptyStr );
+ SwTxtFmtColl* pParentColl = 0;
+ if( aClass.Len() )
+ {
+ String aName( pColl->GetName() );
+ AddClassName( aName, aClass );
+
+ pParentColl = pColl;
+ pColl = pDoc->FindTxtFmtCollByName( aName );
+ if( !pColl )
+ pColl = pDoc->MakeTxtFmtColl( aName, pParentColl );
+ }
+ if( !pNext )
+ {
+ // nur die Attribute an der Vorlage setzen
+ const SfxPoolItem *pItem;
+ const SvxBoxItem *pBoxItem = 0;
+ if( SFX_ITEM_SET ==
+ pColl->GetAttrSet().GetItemState(RES_BOX,TRUE,&pItem) )
+ pBoxItem = (const SvxBoxItem *)pItem;
+ rPropInfo.SetBoxItem( rItemSet, MIN_BORDER_DIST, pBoxItem );
+ if( CSS1_SCRIPT_ALL == nScript && !pParentColl )
+ {
+ SetTxtCollAttrs( pColl, rItemSet, rPropInfo, this );
+ }
+ else
+ {
+ SfxItemSet aScriptItemSet( rItemSet );
+ RemoveScriptItems( aScriptItemSet, nScript,
+ pParentColl ? &pParentColl->GetAttrSet() : 0 );
+ SetTxtCollAttrs( pColl, aScriptItemSet, rPropInfo, this );
+ }
+ }
+ else
+ {
+ // ein Drop-Cap-Attribut basteln
+ SwFmtDrop aDrop( pColl->GetDrop() );
+ aDrop.GetChars() = 1;
+
+ // die Attribute in das DropCap-Attribut einfuegen
+ if( CSS1_SCRIPT_ALL == nScript )
+ {
+ FillDropCap( aDrop, rItemSet, &pColl->GetName() );
+ }
+ else
+ {
+ SfxItemSet aScriptItemSet( rItemSet );
+ if( CSS1_SCRIPT_WESTERN != nScript )
+ {
+ aScriptItemSet.ClearItem( RES_CHRATR_FONT );
+ aScriptItemSet.ClearItem( RES_CHRATR_LANGUAGE );
+ aScriptItemSet.ClearItem( RES_CHRATR_POSTURE );
+ aScriptItemSet.ClearItem( RES_CHRATR_WEIGHT );
+ }
+ if( CSS1_SCRIPT_CJK != nScript )
+ {
+ aScriptItemSet.ClearItem( RES_CHRATR_CJK_FONT );
+ aScriptItemSet.ClearItem( RES_CHRATR_CJK_LANGUAGE );
+ aScriptItemSet.ClearItem( RES_CHRATR_CJK_POSTURE );
+ aScriptItemSet.ClearItem( RES_CHRATR_CJK_WEIGHT );
+ }
+ if( CSS1_SCRIPT_CTL != nScript )
+ {
+ aScriptItemSet.ClearItem( RES_CHRATR_CTL_FONT );
+ aScriptItemSet.ClearItem( RES_CHRATR_CTL_LANGUAGE );
+ aScriptItemSet.ClearItem( RES_CHRATR_CTL_POSTURE );
+ aScriptItemSet.ClearItem( RES_CHRATR_CTL_WEIGHT );
+ }
+ FillDropCap( aDrop, aScriptItemSet, &pColl->GetName() );
+ }
+
+ // Das Attribut nur setzen, wenn float: left angegeben wurde
+ // und das Initial ueber mehrere Zeilen geht. Sonst wird die
+ // ggf. angelegte Zeichen-Vorlage spaeter ueber den Namen
+ // gesucht und gesetzt.
+ if( aDrop.GetLines() > 1 &&
+ (SVX_ADJUST_LEFT == rPropInfo.eFloat ||
+ CSS1_SCRIPT_ALL == nScript) )
+ {
+ pColl->SetFmtAttr( aDrop );
+ }
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ // Jetzt werden die Selektoten verarbeitet, die zu einer Zechenvorlage
+ // gehoehren. Zusammengesetzte gibt es hier allerdings nich nicht.
+ if( pNext )
+ return TRUE;
+
+ SwCharFmt *pCFmt = GetChrFmt( static_cast< USHORT >(nToken2), aEmptyStr );
+ if( pCFmt )
+ {
+ SwCharFmt *pParentCFmt = 0;
+ if( aClass.Len() )
+ {
+ String aName( pCFmt->GetName() );
+ AddClassName( aName, aClass );
+ pParentCFmt = pCFmt;
+
+ pCFmt = pDoc->FindCharFmtByName( aName );
+ if( !pCFmt )
+ {
+ pCFmt = pDoc->MakeCharFmt( aName, pParentCFmt );
+ pCFmt->SetAuto( FALSE );
+ }
+ }
+
+ if( CSS1_SCRIPT_ALL == nScript && !pParentCFmt )
+ {
+ SetCharFmtAttrs( pCFmt, rItemSet );
+ }
+ else
+ {
+ SfxItemSet aScriptItemSet( rItemSet );
+ RemoveScriptItems( aScriptItemSet, nScript,
+ pParentCFmt ? &pParentCFmt->GetAttrSet() : 0 );
+ SetCharFmtAttrs( pCFmt, aScriptItemSet );
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+sal_uInt32 SwCSS1Parser::GetFontHeight( USHORT nSize ) const
+{
+ return aFontHeights[ nSize>6 ? 6 : nSize ];
+}
+
+const FontList *SwCSS1Parser::GetFontList() const
+{
+ const FontList *pFList = 0;
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ if( pDocSh )
+ {
+ const SvxFontListItem *pFListItem =
+ (const SvxFontListItem *)pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST);
+ if( pFListItem )
+ pFList = pFListItem->GetFontList();
+ }
+
+ return pFList;
+}
+
+/* */
+
+SwCharFmt* SwCSS1Parser::GetChrFmt( USHORT nToken2, const String& rClass ) const
+{
+ // die entsprechende Vorlage suchen
+ USHORT nPoolId = 0;
+ const sal_Char* sName = 0;
+ switch( nToken2 )
+ {
+ case HTML_EMPHASIS_ON: nPoolId = RES_POOLCHR_HTML_EMPHASIS; break;
+ case HTML_CITIATION_ON: nPoolId = RES_POOLCHR_HTML_CITIATION; break;
+ case HTML_STRONG_ON: nPoolId = RES_POOLCHR_HTML_STRONG; break;
+ case HTML_CODE_ON: nPoolId = RES_POOLCHR_HTML_CODE; break;
+ case HTML_SAMPLE_ON: nPoolId = RES_POOLCHR_HTML_SAMPLE; break;
+ case HTML_KEYBOARD_ON: nPoolId = RES_POOLCHR_HTML_KEYBOARD; break;
+ case HTML_VARIABLE_ON: nPoolId = RES_POOLCHR_HTML_VARIABLE; break;
+ case HTML_DEFINSTANCE_ON: nPoolId = RES_POOLCHR_HTML_DEFINSTANCE; break;
+ case HTML_TELETYPE_ON: nPoolId = RES_POOLCHR_HTML_TELETYPE; break;
+
+ case HTML_SHORTQUOTE_ON: sName = OOO_STRING_SVTOOLS_HTML_shortquote; break;
+ case HTML_LANGUAGE_ON: sName = OOO_STRING_SVTOOLS_HTML_language; break;
+ case HTML_AUTHOR_ON: sName = OOO_STRING_SVTOOLS_HTML_author; break;
+ case HTML_PERSON_ON: sName = OOO_STRING_SVTOOLS_HTML_person; break;
+ case HTML_ACRONYM_ON: sName = OOO_STRING_SVTOOLS_HTML_acronym; break;
+ case HTML_ABBREVIATION_ON: sName = OOO_STRING_SVTOOLS_HTML_abbreviation; break;
+ case HTML_INSERTEDTEXT_ON: sName = OOO_STRING_SVTOOLS_HTML_insertedtext; break;
+ case HTML_DELETEDTEXT_ON: sName = OOO_STRING_SVTOOLS_HTML_deletedtext; break;
+ }
+
+ // die Vorlage suchen oder anlegen (geht nur mit Namen)
+ if( !nPoolId && !sName )
+ return 0;
+
+ // Die Vorlage (ohne Class) suchen oder anlegen
+ SwCharFmt *pCFmt = 0;
+ if( nPoolId )
+ {
+ pCFmt = GetCharFmtFromPool( nPoolId );
+ }
+ else
+ {
+ String sCName( String::CreateFromAscii(sName) );
+ pCFmt = pDoc->FindCharFmtByName( sCName );
+ if( !pCFmt )
+ {
+ pCFmt = pDoc->MakeCharFmt( sCName, pDoc->GetDfltCharFmt() );
+ pCFmt->SetAuto( FALSE );
+ }
+ }
+
+ ASSERT( pCFmt, "Keine Zeichen-Vorlage???" );
+
+ // Wenn es eine Klasse gibt, die Klassen-Vorlage suchen aber nicht
+ // neu anlegen.
+ String aClass( rClass );
+ GetScriptFromClass( aClass, sal_False );
+ if( aClass.Len() )
+ {
+ String aTmp( pCFmt->GetName() );
+ AddClassName( aTmp, aClass );
+ SwCharFmt *pClassCFmt = pDoc->FindCharFmtByName( aTmp );
+ if( pClassCFmt )
+ {
+ pCFmt = pClassCFmt;
+ }
+ else
+ {
+ SvxCSS1MapEntry *pClass = GetClass( aClass );
+ if( pClass )
+ {
+ pCFmt = pDoc->MakeCharFmt( aTmp, pCFmt );
+ pCFmt->SetAuto( FALSE );
+ SfxItemSet aItemSet( pClass->GetItemSet() );
+ SetCharFmtAttrs( pCFmt, aItemSet );
+ }
+ }
+ }
+
+ return pCFmt;
+}
+
+
+/* */
+
+SwTxtFmtColl *SwCSS1Parser::GetTxtCollFromPool( USHORT nPoolId ) const
+{
+ USHORT nOldArrLen = pDoc->GetTxtFmtColls()->Count();
+
+ SwTxtFmtColl *pColl = pDoc->GetTxtCollFromPool( nPoolId, false );
+
+ if( bIsNewDoc )
+ {
+ USHORT nArrLen = pDoc->GetTxtFmtColls()->Count();
+ for( USHORT i=nOldArrLen; i<nArrLen; i++ )
+ lcl_swcss1_setEncoding( *(*pDoc->GetTxtFmtColls())[i],
+ GetDfltEncoding() );
+ }
+
+ return pColl;
+}
+
+SwCharFmt *SwCSS1Parser::GetCharFmtFromPool( USHORT nPoolId ) const
+{
+ USHORT nOldArrLen = pDoc->GetCharFmts()->Count();
+
+ SwCharFmt *pCharFmt = pDoc->GetCharFmtFromPool( nPoolId );
+
+ if( bIsNewDoc )
+ {
+ USHORT nArrLen = pDoc->GetCharFmts()->Count();
+
+ for( USHORT i=nOldArrLen; i<nArrLen; i++ )
+ lcl_swcss1_setEncoding( *(*pDoc->GetCharFmts())[i],
+ GetDfltEncoding() );
+ }
+
+ return pCharFmt;
+}
+
+SwTxtFmtColl *SwCSS1Parser::GetTxtFmtColl( USHORT nTxtColl,
+ const String& rClass )
+{
+ SwTxtFmtColl* pColl = 0;
+
+ String aClass( rClass );
+ GetScriptFromClass( aClass, sal_False );
+ if( RES_POOLCOLL_TEXT == nTxtColl && aClass.Len() >= 9 &&
+ ('s' == aClass.GetChar(0) || 'S' == aClass.GetChar(0) ) )
+ {
+ if( aClass.EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_sdendnote) )
+ {
+ nTxtColl = RES_POOLCOLL_ENDNOTE;
+ aClass = aEmptyStr;
+ }
+ else if( aClass.EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_sdfootnote) )
+ {
+ nTxtColl = RES_POOLCOLL_FOOTNOTE;
+ aClass = aEmptyStr;
+ }
+ }
+
+ String sName;
+ if( USER_FMT & nTxtColl ) // eine vom Reader angelegte
+ {
+ ASSERT( !this, "Wo kommt die Benutzer-Vorlage her?" );
+ pColl = GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
+ }
+ else
+ {
+ pColl = GetTxtCollFromPool( nTxtColl );
+ }
+
+ ASSERT( pColl, "Keine Absatz-Vorlage???" );
+ if( aClass.Len() )
+ {
+ String aTmp( pColl->GetName() );
+ AddClassName( aTmp, aClass );
+ SwTxtFmtColl* pClassColl = pDoc->FindTxtFmtCollByName( aTmp );
+
+ if( !pClassColl &&
+ (nTxtColl==RES_POOLCOLL_TABLE ||
+ nTxtColl==RES_POOLCOLL_TABLE_HDLN) )
+ {
+ // Wenn dieser Fall eintritt, dann wurde ein <TD><P CLASS=foo>
+ // gelesen, aber die TD.foo Vorlage nicht gefunden. Dann muessen
+ // wir P.foo nehmen, wenn es sie gibt.
+ SwTxtFmtColl* pCollText =
+ GetTxtCollFromPool( RES_POOLCOLL_TEXT );
+ aTmp = pCollText->GetName();
+ AddClassName( aTmp, aClass );
+ pClassColl = pDoc->FindTxtFmtCollByName( aTmp );
+ }
+
+ if( pClassColl )
+ {
+ pColl = pClassColl;
+ }
+ else
+ {
+ const SvxCSS1MapEntry *pClass = GetClass( aClass );
+ if( pClass )
+ {
+ pColl = pDoc->MakeTxtFmtColl( aTmp, pColl );
+ SfxItemSet aItemSet( pClass->GetItemSet() );
+ SvxCSS1PropertyInfo aPropInfo( pClass->GetPropertyInfo() );
+ aPropInfo.SetBoxItem( aItemSet, MIN_BORDER_DIST );
+ BOOL bPositioned = MayBePositioned( pClass->GetPropertyInfo() );
+ if( bPositioned )
+ aItemSet.ClearItem( RES_BACKGROUND );
+ SetTxtCollAttrs( pColl, aItemSet, aPropInfo,
+ this );
+ }
+ }
+
+ }
+
+ if( pColl )
+ lcl_swcss1_setEncoding( *pColl, GetDfltEncoding() );
+
+ return pColl;
+}
+
+SwPageDesc *SwCSS1Parser::GetMasterPageDesc()
+{
+ return pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
+}
+
+static SwPageDesc *FindPageDesc( SwDoc *pDoc, USHORT nPoolId, USHORT& rPage )
+{
+ USHORT nPageDescs = pDoc->GetPageDescCnt();
+ for( rPage=0; rPage < nPageDescs &&
+ const_cast<const SwDoc *>(pDoc)->
+ GetPageDesc(rPage).GetPoolFmtId() != nPoolId; rPage++ )
+ ;
+
+ return rPage < nPageDescs ? &pDoc->_GetPageDesc( rPage ) : 0;
+}
+
+const SwPageDesc *SwCSS1Parser::GetPageDesc( USHORT nPoolId, BOOL bCreate )
+{
+ if( RES_POOLPAGE_HTML == nPoolId )
+ return pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
+
+ USHORT nPage;
+ const SwPageDesc *pPageDesc = FindPageDesc( pDoc, nPoolId, nPage );
+ if( !pPageDesc && bCreate )
+ {
+ // Die erste Seite wird aus der rechten Seite erzeugt, wenn es die
+ // gibt.
+ SwPageDesc *pMasterPageDesc = 0;
+ if( RES_POOLPAGE_FIRST == nPoolId )
+ pMasterPageDesc = FindPageDesc( pDoc, RES_POOLPAGE_RIGHT, nPage );
+ if( !pMasterPageDesc )
+ pMasterPageDesc = pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
+
+ // Die neue Seitenvorlage entsteht aus dem Master durch kopieren.
+ SwPageDesc *pNewPageDesc = pDoc->
+ GetPageDescFromPool( nPoolId, false );
+
+ // dazu brauchen wir auch die Nummer der neuen Vorlage
+ pPageDesc = FindPageDesc( pDoc, nPoolId, nPage );
+ ASSERT( pPageDesc==pNewPageDesc, "Seitenvorlage nicht gefunden" );
+
+ pDoc->CopyPageDesc( *pMasterPageDesc, *pNewPageDesc, FALSE );
+
+ // Die Vorlagen an ihren neuen Zweck anpassen.
+ const SwPageDesc *pFollow = 0;
+ BOOL bSetFollowFollow = FALSE;
+ switch( nPoolId )
+ {
+ case RES_POOLPAGE_FIRST:
+ // Wenn es schon eine linke Seite gibt, dann ist das die
+ // Folge-Vorlage, sonst ist es die HTML-Vorlage.
+ pFollow = GetLeftPageDesc();
+ if( !pFollow )
+ pFollow = pMasterPageDesc;
+ break;
+
+ case RES_POOLPAGE_RIGHT:
+ // Wenn die linke Vorlage schon angelegt ist, passiert hier gar
+ // nichts. Sonst wird die linke Vorlage angelegt und sorgt auch
+ // fuer die richtige Verkettung mit der rechten Voralge.
+ GetLeftPageDesc( TRUE );
+ break;
+
+ case RES_POOLPAGE_LEFT:
+ // Die rechte Vorlage wird angelegt, wenn sie noch nicht existiert.
+ // Es findet aber keine Verkettung statt.
+ // Wenn schon eine erste Seitenvorlage existiert, wird die linke
+ // Vorlage die Folge-Vorlage der ersten Seite.
+ pFollow = GetRightPageDesc( TRUE );
+ bSetFollowFollow = TRUE;
+ {
+ const SwPageDesc *pFirstPageDesc = GetFirstPageDesc();
+ if( pFirstPageDesc )
+ {
+ SwPageDesc aNewFirstPageDesc( *pFirstPageDesc );
+ aNewFirstPageDesc.SetFollow( pNewPageDesc );
+ ChgPageDesc( pFirstPageDesc, aNewFirstPageDesc );
+ }
+ }
+ break;
+ }
+
+ if( pFollow )
+ {
+ SwPageDesc aNewPageDesc( *pNewPageDesc );
+ aNewPageDesc.SetFollow( pFollow );
+ ChgPageDesc( pNewPageDesc, aNewPageDesc );
+
+ if( bSetFollowFollow )
+ {
+ SwPageDesc aNewFollowPageDesc( *pFollow );
+ aNewFollowPageDesc.SetFollow( pNewPageDesc );
+ ChgPageDesc( pFollow, aNewFollowPageDesc );
+ }
+ }
+ pPageDesc = pNewPageDesc;
+ }
+
+ return pPageDesc;
+}
+
+
+BOOL SwCSS1Parser::MayBePositioned( const SvxCSS1PropertyInfo& rPropInfo,
+ BOOL bAutoWidth )
+{
+ // abs-pos
+ // left/top none auto twip perc
+ //
+ // none Z Z - -
+ // auto Z Z - -
+ // twip Z Z S/R -
+ // perc - - - -
+ //
+ // - 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)
+ return ( ( SVX_CSS1_POS_ABSOLUTE == rPropInfo.ePosition &&
+ SVX_CSS1_LTYPE_PERCENTAGE != rPropInfo.eLeftType &&
+ SVX_CSS1_LTYPE_PERCENTAGE != rPropInfo.eTopType &&
+ (SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType ||
+ SVX_CSS1_LTYPE_TWIP != rPropInfo.eTopType) ) ||
+ ( SVX_ADJUST_END != rPropInfo.eFloat ) ) &&
+ ( bAutoWidth ||
+ SVX_CSS1_LTYPE_TWIP == rPropInfo.eWidthType ||
+ SVX_CSS1_LTYPE_PERCENTAGE == rPropInfo.eWidthType );
+}
+
+
+/* */
+
+void SwCSS1Parser::AddClassName( String& rFmtName, const String& rClass )
+{
+ ASSERT( rClass.Len(), "Style-Klasse ohne Laenge?" );
+
+// ??????????
+// String aTmp( rClass );
+// GetpApp()->GetAppInternational().ToLower( aTmp );
+
+ (rFmtName += '.') += rClass;
+}
+
+/* */
+
+void SwCSS1Parser::FillDropCap( SwFmtDrop& rDrop,
+ SfxItemSet& rItemSet,
+ const String *pName )
+{
+ // die Anzahl der Zeilen entspricht in etwa einer %-Angabe
+ // fuer die Hoehe (was passiert mit absoluten Hoehen???)
+ BYTE nLines = rDrop.GetLines();
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_CHRATR_FONTSIZE, FALSE, &pItem ) )
+ {
+ USHORT nProp = ((const SvxFontHeightItem *)pItem)->GetProp();
+ nLines = (BYTE)((nProp + 50) / 100);
+ if( nLines < 1 )
+ nLines = 1;
+ else if( nLines > MAX_DROPCAP_LINES )
+ nLines = MAX_DROPCAP_LINES;
+
+ // Nur wenn nLines>1 ist, wird das Attribut auch gesetzt. Dann
+ // brauchen wir die Font-Hoehe aber auch nicht in der Zeichen-Vorlage.
+ if( nLines > 1 )
+ {
+ rItemSet.ClearItem( RES_CHRATR_FONTSIZE );
+ rItemSet.ClearItem( RES_CHRATR_CJK_FONTSIZE );
+ rItemSet.ClearItem( RES_CHRATR_CTL_FONTSIZE );
+ }
+ }
+
+ // Bei harter Attributierung (pName==0) koennen wir aufhoehren, wenn
+ // das Initial nur ueber eine Zeile geht.
+#ifdef FULL_FIRST_LETTER
+ if( nLines<=1 && !pName )
+#else
+ if( nLines<=1 )
+#endif
+ return;
+
+ rDrop.GetLines() = nLines;
+
+ // ein rechter Rand wird der Abstand zum Text!
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, FALSE, &pItem ) )
+ {
+ rDrop.GetDistance() = static_cast< USHORT >(
+ ((const SvxLRSpaceItem *)pItem)->GetRight() );
+ rItemSet.ClearItem( RES_LR_SPACE );
+ }
+
+ // Fuer alle anderen Attribute eine Zeichen-Vorlage anlegen
+ if( rItemSet.Count() )
+ {
+ SwCharFmt *pCFmt = 0;
+ String aName;
+ if( pName )
+ {
+ aName = *pName;
+ AddFirstLetterExt( aName );
+ pCFmt = pDoc->FindCharFmtByName( aName );
+ }
+ else
+ {
+ do
+ {
+ aName.AssignAscii( sCSS1_first_letter );
+ aName.Append( ' ' );
+ aName.Append(
+ String::CreateFromInt32( (sal_Int32)(++nDropCapCnt) ) );
+ }
+ while( pDoc->FindCharFmtByName(aName) );
+ }
+
+ if( !pCFmt )
+ {
+ pCFmt = pDoc->MakeCharFmt( aName, pDoc->GetDfltCharFmt() );
+ pCFmt->SetAuto( FALSE );
+ }
+ SetCharFmtAttrs( pCFmt, rItemSet );
+
+ // Die Zeichenvorlage braucht nur im Attribut gesetzt werden, wenn
+ // auch das Attribut gesetzt wird.
+ if( nLines > 1 )
+ rDrop.SetCharFmt( pCFmt );
+ }
+}
+
+/* */
+
+// CSS1-sezifisches des SwHTMLParsers
+
+_HTMLAttr **SwHTMLParser::GetAttrTabEntry( USHORT nWhich )
+{
+ // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
+ _HTMLAttr **ppAttr = 0;
+ switch( nWhich )
+ {
+ case RES_CHRATR_BLINK:
+ ppAttr = &aAttrTab.pBlink;
+ break;
+ case RES_CHRATR_CASEMAP:
+ ppAttr = &aAttrTab.pCaseMap;
+ break;
+ case RES_CHRATR_COLOR:
+ ppAttr = &aAttrTab.pFontColor;
+ break;
+ case RES_CHRATR_CROSSEDOUT:
+ ppAttr = &aAttrTab.pStrike;
+ break;
+ case RES_CHRATR_ESCAPEMENT:
+ ppAttr = &aAttrTab.pEscapement;
+ break;
+ case RES_CHRATR_FONT:
+ ppAttr = &aAttrTab.pFont;
+ break;
+ case RES_CHRATR_CJK_FONT:
+ ppAttr = &aAttrTab.pFontCJK;
+ break;
+ case RES_CHRATR_CTL_FONT:
+ ppAttr = &aAttrTab.pFontCTL;
+ break;
+ case RES_CHRATR_FONTSIZE:
+ ppAttr = &aAttrTab.pFontHeight;
+ break;
+ case RES_CHRATR_CJK_FONTSIZE:
+ ppAttr = &aAttrTab.pFontHeightCJK;
+ break;
+ case RES_CHRATR_CTL_FONTSIZE:
+ ppAttr = &aAttrTab.pFontHeightCTL;
+ break;
+ case RES_CHRATR_KERNING:
+ ppAttr = &aAttrTab.pKerning;
+ break;
+ case RES_CHRATR_POSTURE:
+ ppAttr = &aAttrTab.pItalic;
+ break;
+ case RES_CHRATR_CJK_POSTURE:
+ ppAttr = &aAttrTab.pItalicCJK;
+ break;
+ case RES_CHRATR_CTL_POSTURE:
+ ppAttr = &aAttrTab.pItalicCTL;
+ break;
+ case RES_CHRATR_UNDERLINE:
+ ppAttr = &aAttrTab.pUnderline;
+ break;
+ case RES_CHRATR_WEIGHT:
+ ppAttr = &aAttrTab.pBold;
+ break;
+ case RES_CHRATR_CJK_WEIGHT:
+ ppAttr = &aAttrTab.pBoldCJK;
+ break;
+ case RES_CHRATR_CTL_WEIGHT:
+ ppAttr = &aAttrTab.pBoldCTL;
+ break;
+ case RES_CHRATR_BACKGROUND:
+ ppAttr = &aAttrTab.pCharBrush;
+ break;
+
+ case RES_PARATR_LINESPACING:
+ ppAttr = &aAttrTab.pLineSpacing;
+ break;
+ case RES_PARATR_ADJUST:
+ ppAttr = &aAttrTab.pAdjust;
+ break;
+
+ case RES_LR_SPACE:
+ ppAttr = &aAttrTab.pLRSpace;
+ break;
+ case RES_UL_SPACE:
+ ppAttr = &aAttrTab.pULSpace;
+ break;
+ case RES_BOX:
+ ppAttr = &aAttrTab.pBox;
+ break;
+ case RES_BACKGROUND:
+ ppAttr = &aAttrTab.pBrush;
+ break;
+ case RES_BREAK:
+ ppAttr = &aAttrTab.pBreak;
+ break;
+ case RES_PAGEDESC:
+ ppAttr = &aAttrTab.pPageDesc;
+ break;
+ case RES_PARATR_SPLIT:
+ ppAttr = &aAttrTab.pSplit;
+ break;
+ case RES_PARATR_WIDOWS:
+ ppAttr = &aAttrTab.pWidows;
+ break;
+ case RES_PARATR_ORPHANS:
+ ppAttr = &aAttrTab.pOrphans;
+ break;
+ case RES_KEEP:
+ ppAttr = &aAttrTab.pKeep;
+ break;
+
+ case RES_CHRATR_LANGUAGE:
+ ppAttr = &aAttrTab.pLanguage;
+ break;
+ case RES_CHRATR_CJK_LANGUAGE:
+ ppAttr = &aAttrTab.pLanguageCJK;
+ break;
+ case RES_CHRATR_CTL_LANGUAGE:
+ ppAttr = &aAttrTab.pLanguageCTL;
+ break;
+
+ case RES_FRAMEDIR:
+ ppAttr = &aAttrTab.pDirection;
+ break;
+ }
+
+ return ppAttr;
+}
+
+void SwHTMLParser::NewStyle()
+{
+ String sType;
+
+ const HTMLOptions *pOptions2 = GetOptions();
+ for( USHORT i = pOptions2->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pOptions2)[--i];
+ if( HTML_O_TYPE==pOption->GetToken() )
+ sType = pOption->GetString();
+ }
+
+ bIgnoreRawData = sType.Len() &&
+ !sType.GetToken(0,';').EqualsAscii(sCSS_mimetype);
+}
+
+void SwHTMLParser::EndStyle()
+{
+ bIgnoreRawData = FALSE;
+
+ if( aStyleSource.Len() )
+ {
+ pCSS1Parser->ParseStyleSheet( aStyleSource );
+ aStyleSource.Erase();
+ }
+}
+
+BOOL SwHTMLParser::FileDownload( const String& rURL,
+ String& rStr )
+{
+ // View wegschmeissen (wegen Reschedule)
+ ViewShell *pOldVSh = CallEndAction();
+
+ // Ein Medium anlegen
+ SfxMedium aDLMedium( rURL, STREAM_READ | STREAM_SHARE_DENYWRITE, FALSE );
+
+ // Medium registrieren, damit abgebrochen werden kann
+ if( pDoc->GetDocShell() )
+ pDoc->GetDocShell()->RegisterTransfer( aDLMedium );
+
+ SvStream* pStream = aDLMedium.GetInStream();
+ if( pStream )
+ {
+ SvMemoryStream aStream;
+ aStream << *pStream;
+
+ aStream.Seek( STREAM_SEEK_TO_END );
+ DBG_ASSERT( aStream.Tell() < STRING_MAXLEN,
+ "File zu lang fuer einen String, Ende abgeschnitten" );
+ xub_StrLen nLen = aStream.Tell() < STRING_MAXLEN
+ ? (xub_StrLen)aStream.Tell()
+ : STRING_MAXLEN;
+
+ rStr = String( (const sal_Char *)aStream.GetData(), nLen,
+ GetSrcEncoding() );
+ }
+
+
+ // wurde abgebrochen?
+ if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
+ || 1 == pDoc->getReferenceCount() )
+ {
+ // wurde der Import vom SFX abgebrochen?
+ eState = SVPAR_ERROR;
+ pStream = 0;
+ }
+
+ // View wieder anlgen
+#if OSL_DEBUG_LEVEL > 1
+ ViewShell *pVSh =
+#endif
+ CallStartAction( pOldVSh );
+#if OSL_DEBUG_LEVEL > 1
+ ASSERT( pOldVSh == pVSh, "FileDownload: ViewShell wurde ausgetauscht" );
+ (void) pVSh;
+#endif
+
+ return pStream!=0;
+}
+
+void SwHTMLParser::InsertLink()
+{
+ BOOL bFinishDownload = FALSE;
+ if( pPendStack )
+ {
+ ASSERT( ShouldFinishFileDownload(),
+ "Pending-Stack ohne File-Download?" );
+
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+ ASSERT( !pPendStack, "Wo kommt der Pending-Stack her?" );
+
+ bFinishDownload = TRUE;
+ }
+ else
+ {
+ String sRel, sHRef, sType;
+
+ const HTMLOptions *pOptions2 = GetOptions();
+ for( USHORT i = pOptions2->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pOptions2)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_REL:
+ sRel = pOption->GetString();
+ break;
+ case HTML_O_HREF:
+ sHRef = URIHelper::SmartRel2Abs( INetURLObject( sBaseURL ), pOption->GetString(), Link(), false );
+ break;
+ case HTML_O_TYPE:
+ sType = pOption->GetString();
+ break;
+ }
+ }
+
+ if( sHRef.Len() && sRel.EqualsIgnoreCaseAscii( "STYLESHEET" ) &&
+ ( !sType.Len() ||
+ sType.GetToken(0,';').EqualsAscii(sCSS_mimetype) ) )
+ {
+ if( GetMedium() )
+ {
+ // Download des Style-Source starten
+ StartFileDownload( sHRef, 0, pDoc->GetDocShell() );
+ if( IsParserWorking() )
+ {
+ // Der Style wurde synchron geladen und wir koennen
+ // es direkt aufrufen.
+ bFinishDownload = TRUE;
+ }
+ else
+ {
+ // Der Style wird asynchron geladen und ist erst beim
+ // naechsten Continue-Aufruf da. Wir muessen deshalb einen
+ // Pending-Stack anlegen, damit wir hierher zurueckkehren
+ pPendStack = new SwPendingStack( HTML_LINK, pPendStack );
+ }
+ }
+ else
+ {
+ // File synchron holen
+ String sSource;
+ if( FileDownload( sHRef, sSource ) )
+ pCSS1Parser->ParseStyleSheet( sSource );
+ }
+ }
+ }
+
+ if( bFinishDownload )
+ {
+ String sSource;
+ if( FinishFileDownload(sSource) && sSource.Len() )
+ pCSS1Parser->ParseStyleSheet( sSource );
+ }
+}
+
+BOOL SwCSS1Parser::ParseStyleSheet( const String& rIn )
+{
+ if( !SvxCSS1Parser::ParseStyleSheet( rIn ) )
+ return FALSE;
+
+ SwPageDesc *pMasterPageDesc =
+ pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
+
+ SvxCSS1MapEntry *pPageEntry = GetPage( aEmptyStr, FALSE );
+ if( pPageEntry )
+ {
+ // @page (wirkt auf alle Seiten, die es schon gibt
+
+ SetPageDescAttrs( pMasterPageDesc, pPageEntry->GetItemSet(),
+ pPageEntry->GetPropertyInfo() );
+
+ // Fuer alle anderen Seiten-Vorlagen, die es schon gibt,
+ // muessen die Attribute auch noch gesetzt werden
+
+ SetPageDescAttrs( GetFirstPageDesc(), pPageEntry->GetItemSet(),
+ pPageEntry->GetPropertyInfo() );
+ SetPageDescAttrs( GetLeftPageDesc(), pPageEntry->GetItemSet(),
+ pPageEntry->GetPropertyInfo() );
+ SetPageDescAttrs( GetRightPageDesc(), pPageEntry->GetItemSet(),
+ pPageEntry->GetPropertyInfo() );
+// if( pNamedPageDescs )
+// {
+// for( USHORT i=0; i<pNamedPageDescs->Count(); i++ )
+// SetPageDescAttrs( (*pNamedPageDescs)[i],
+// pPageEntry->GetItemSet(),
+// pPageEntry->GetPropertyInfo() );
+// }
+
+ }
+
+ pPageEntry = GetPage( String::CreateFromAscii(sCSS1_first), TRUE );
+ if( pPageEntry )
+ {
+ SetPageDescAttrs( GetFirstPageDesc(TRUE), pPageEntry->GetItemSet(),
+ pPageEntry->GetPropertyInfo() );
+ bSetFirstPageDesc = TRUE;
+ }
+
+ pPageEntry = GetPage( String::CreateFromAscii(sCSS1_right), TRUE );
+ if( pPageEntry )
+ {
+ SetPageDescAttrs( GetRightPageDesc(TRUE), pPageEntry->GetItemSet(),
+ pPageEntry->GetPropertyInfo() );
+ bSetRightPageDesc = TRUE;
+ }
+
+ pPageEntry = GetPage( String::CreateFromAscii(sCSS1_left), TRUE );
+ if( pPageEntry )
+ SetPageDescAttrs( GetLeftPageDesc(TRUE), pPageEntry->GetItemSet(),
+ pPageEntry->GetPropertyInfo() );
+
+ // und jetzt noch die benannten Vorlagen
+// for( USHORT i=0; i < GetPageCount(); i++ )
+// {
+// pPageEntry = GetPage( i );
+// const String& rKey = pPageEntry->GetKey();
+// if( !rKey.Len() || rKey.GetChar(0) == ':' )
+// continue;
+//
+// String aName( rKey );
+// GetpApp()->GetAppInternational().ToLower( aName );
+// USHORT nPage = pDoc->MakePageDesc( aName );
+// SwPageDesc *pPageDesc = &pDoc->_GetPageDesc( nPage );
+//
+// // Die neue Seitenvorlage entsteht aus dem Master durch kopieren.
+// pDoc->CopyPageDesc( *pMasterPageDesc, *pPageDesc );
+// SetPageDescAttrs( pPageDesc, pPageEntry->GetItemSet(),
+// pPageEntry->GetPropertyInfo() );
+//
+// if( !pNamedPageDescs )
+// pNamedPageDescs = new SwHTMLPageDescs;
+// pNamedPageDescs->Insert( pPageDesc, pNamedPageDescs->Count() );
+// }
+
+ return TRUE;
+}
+
+BOOL SwHTMLParser::ParseStyleOptions( const String &rStyle,
+ const String &rId,
+ const String &rClass,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo &rPropInfo,
+ const String *pLang,
+ const String *pDir )
+{
+ BOOL bRet = FALSE;
+
+ if( rClass.Len() )
+ {
+ String aClass( rClass );
+ SwCSS1Parser::GetScriptFromClass( aClass );
+ SvxCSS1MapEntry *pClass = pCSS1Parser->GetClass( aClass );
+ if( pClass )
+ {
+ pCSS1Parser->MergeStyles( pClass->GetItemSet(),
+ pClass->GetPropertyInfo(),
+ rItemSet, rPropInfo, FALSE );
+ bRet = TRUE;
+ }
+ }
+
+ if( rId.Len() )
+ {
+ SvxCSS1MapEntry *pId = pCSS1Parser->GetId( rId );
+ if( pId )
+ pCSS1Parser->MergeStyles( pId->GetItemSet(),
+ pId->GetPropertyInfo(),
+ rItemSet, rPropInfo, rClass.Len()!=0 );
+ rPropInfo.aId = rId;
+ bRet = TRUE;
+ }
+
+ if( rStyle.Len() )
+ {
+ pCSS1Parser->ParseStyleOption( rStyle, rItemSet, rPropInfo );
+ bRet = TRUE;
+ }
+
+ if( bRet )
+ rPropInfo.SetBoxItem( rItemSet, MIN_BORDER_DIST );
+
+ if( pLang && pLang->Len() )
+ {
+ LanguageType eLang = MsLangId::convertIsoStringToLanguage( *pLang );
+ if( LANGUAGE_DONTKNOW != eLang )
+ {
+ SvxLanguageItem aLang( eLang, RES_CHRATR_LANGUAGE );
+ rItemSet.Put( aLang );
+ aLang.SetWhich( RES_CHRATR_CJK_LANGUAGE );
+ rItemSet.Put( aLang );
+ aLang.SetWhich( RES_CHRATR_CTL_LANGUAGE );
+ rItemSet.Put( aLang );
+
+ bRet = sal_True;
+ }
+ }
+ if( pDir && pDir->Len() )
+ {
+ String aValue( *pDir );
+ aValue.ToUpperAscii();
+ SvxFrameDirection eDir = FRMDIR_ENVIRONMENT;
+ if( aValue.EqualsAscii( "LTR" ) )
+ eDir = FRMDIR_HORI_LEFT_TOP;
+ else if( aValue.EqualsAscii( "RTL" ) )
+ eDir = FRMDIR_HORI_RIGHT_TOP;
+
+ if( FRMDIR_ENVIRONMENT != eDir )
+ {
+ SvxFrameDirectionItem aDir( eDir, RES_FRAMEDIR );
+ rItemSet.Put( aDir );
+
+ bRet = sal_True;
+ }
+ }
+
+ return bRet;
+}
+
+void SwHTMLParser::SetAnchorAndAdjustment( const SfxItemSet & /*rItemSet*/,
+ const SvxCSS1PropertyInfo &rPropInfo,
+ SfxItemSet &rFrmItemSet )
+{
+ SwFmtAnchor aAnchor;
+
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+ sal_Int16 eVertOri = text::VertOrientation::NONE;
+ sal_Int16 eHoriRel = text::RelOrientation::FRAME;
+ sal_Int16 eVertRel = text::RelOrientation::FRAME;
+ SwTwips nHoriPos = 0, nVertPos = 0;
+ SwSurround eSurround = SURROUND_THROUGHT;
+ if( SVX_CSS1_POS_ABSOLUTE == rPropInfo.ePosition )
+ {
+ if( SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType &&
+ SVX_CSS1_LTYPE_TWIP == rPropInfo.eTopType )
+ {
+ // Absolut positionierte Objekte sind seitengebunden, wenn
+ // sie nicht schon in einem Rahmen stehen und sonst
+ // Rahmengebunden.
+ const SwStartNode *pFlySttNd =
+ pDoc->GetNodes()[pPam->GetPoint()->nNode]->FindFlyStartNode();
+ if( pFlySttNd )
+ {
+ aAnchor.SetType( FLY_AT_FLY );
+ SwPosition aPos( *pFlySttNd );
+ aAnchor.SetAnchor( &aPos );
+ }
+ else
+ {
+ aAnchor.SetType( FLY_PAGE );
+ aAnchor.SetPageNum( 1 );
+ }
+ nHoriPos = rPropInfo.nLeft;
+ nVertPos = rPropInfo.nTop;
+ }
+ else
+ {
+ aAnchor.SetType( FLY_AT_CNTNT );
+ aAnchor.SetAnchor( pPam->GetPoint() );
+ eVertOri = text::VertOrientation::TOP;
+ eVertRel = text::RelOrientation::CHAR;
+ if( SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType )
+ {
+ eHoriOri = text::HoriOrientation::NONE;
+ eHoriRel = text::RelOrientation::PAGE_FRAME;
+ nHoriPos = rPropInfo.nLeft;
+ }
+ else
+ {
+ eHoriOri = text::HoriOrientation::LEFT;
+ eHoriRel = text::RelOrientation::FRAME; // wird noch umgeschossen
+ }
+ }
+ }
+ else
+ {
+ // fliessende Objekte werden Absatzgebunden eingefuegt, wenn
+ // der Absatz noch leer ist und sonst auto-gebunden.
+ // Auto-gebundene Rahmen werden zunaechst an der Position davor
+ // eingefuegt und erst spaeter verschoben.
+ xub_StrLen nCntnt = pPam->GetPoint()->nContent.GetIndex();
+ if( nCntnt )
+ {
+ aAnchor.SetType( FLY_AUTO_CNTNT );
+ pPam->Move( fnMoveBackward );
+ eVertOri = text::VertOrientation::CHAR_BOTTOM;
+ eVertRel = text::RelOrientation::CHAR;
+ }
+ else
+ {
+ aAnchor.SetType( FLY_AT_CNTNT );
+ eVertOri = text::VertOrientation::TOP;
+ eVertRel = text::RelOrientation::PRINT_AREA;
+ }
+
+ aAnchor.SetAnchor( pPam->GetPoint() );
+
+ if( nCntnt )
+ pPam->Move( fnMoveForward );
+
+ USHORT nLeftSpace = 0, nRightSpace = 0;
+ short nIndent = 0;
+ GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
+
+ if( SVX_ADJUST_RIGHT==rPropInfo.eFloat )
+ {
+ eHoriOri = text::HoriOrientation::RIGHT;
+ eHoriRel = nRightSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
+ eSurround = SURROUND_LEFT;
+ }
+ else
+ {
+ eHoriOri = text::HoriOrientation::LEFT;
+ eHoriRel = nLeftSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
+ eSurround = SURROUND_RIGHT;
+ }
+ }
+ rFrmItemSet.Put( aAnchor );
+
+ // Absolut Positioniert mit Durchlauf
+ rFrmItemSet.Put( SwFmtHoriOrient( nHoriPos, eHoriOri, eHoriRel ) );
+ rFrmItemSet.Put( SwFmtVertOrient( nVertPos, eVertOri, eVertRel ) );
+ rFrmItemSet.Put( SwFmtSurround( eSurround ) );
+}
+
+void SwHTMLParser::SetVarSize( SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo &rPropInfo,
+ SfxItemSet &rFrmItemSet,
+ SwTwips nDfltWidth, BYTE nDfltPrcWidth )
+{
+ SwFrmSize eSize = ATT_MIN_SIZE;
+ SwTwips nWidth = nDfltWidth, nHeight = MINFLY;
+ BYTE nPrcWidth = nDfltPrcWidth, nPrcHeight = 0;
+ switch( rPropInfo.eWidthType )
+ {
+ case SVX_CSS1_LTYPE_PERCENTAGE:
+ nPrcWidth = rPropInfo.nWidth > 0 ? (BYTE)rPropInfo.nWidth : 1;
+ nWidth = MINFLY;
+ break;
+ case SVX_CSS1_LTYPE_TWIP:
+ nWidth = rPropInfo.nWidth > MINFLY ? rPropInfo.nWidth : MINFLY;
+ nPrcWidth = 0;
+ break;
+ default:
+ ;
+ }
+ switch( rPropInfo.eHeightType )
+ {
+ case SVX_CSS1_LTYPE_PERCENTAGE:
+ nPrcHeight = rPropInfo.nHeight > 0 ? (BYTE)rPropInfo.nHeight : 1;
+ break;
+ case SVX_CSS1_LTYPE_TWIP:
+ // Netscape und MS-IE interpretieren die Hoehe regelwiedrig
+ // als Mindest-Hoehe, also machwn wir das auch so.
+ nHeight = rPropInfo.nHeight > MINFLY ? rPropInfo.nHeight : MINFLY;
+ break;
+ default:
+ ;
+ }
+
+ SwFmtFrmSize aFrmSize( eSize, nWidth, nHeight );
+ aFrmSize.SetWidthPercent( nPrcWidth );
+ aFrmSize.SetHeightPercent( nPrcHeight );
+ rFrmItemSet.Put( aFrmSize );
+}
+
+void SwHTMLParser::SetFrmFmtAttrs( SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo & /*rPropInfo*/,
+ USHORT nFlags,
+ SfxItemSet &rFrmItemSet )
+{
+ const SfxPoolItem *pItem;
+ if( (nFlags & HTML_FF_BOX) != 0 &&
+ SFX_ITEM_SET==rItemSet.GetItemState( RES_BOX, TRUE, &pItem ) )
+ {
+ if( (nFlags & HTML_FF_PADDING) == 0 )
+ {
+ SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
+ // Alle 4 Seiten gleichzeitig auf 0 setzen
+ aBoxItem.SetDistance( 0 );
+ rFrmItemSet.Put( aBoxItem );
+ }
+ else
+ {
+ rFrmItemSet.Put( *pItem );
+ }
+ rItemSet.ClearItem( RES_BOX );
+ }
+
+ if( (nFlags & HTML_FF_BACKGROUND) != 0 &&
+ SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, TRUE, &pItem ) )
+ {
+ rFrmItemSet.Put( *pItem );
+ rItemSet.ClearItem( RES_BACKGROUND );
+ }
+
+ if( (nFlags & HTML_FF_DIRECTION) != 0 &&
+ SFX_ITEM_SET==rItemSet.GetItemState( RES_FRAMEDIR, TRUE, &pItem ) )
+ {
+ rFrmItemSet.Put( *pItem );
+ rItemSet.ClearItem( RES_FRAMEDIR );
+ }
+}
+
+
+/* */
+
+_HTMLAttrContext *SwHTMLParser::PopContext( USHORT nToken, USHORT nLimit,
+ BOOL bRemove )
+{
+ USHORT nPos = aContexts.Count();
+ if( nPos <= nContextStMin )
+ return 0;
+
+ BOOL bFound = 0==nToken;
+ if( nToken )
+ {
+ // Stack-Eintrag zu dem Token suchen
+ while( nPos > nContextStMin )
+ {
+ USHORT nCntxtToken = aContexts[--nPos]->GetToken();
+ if( nCntxtToken == nToken )
+ {
+ bFound = TRUE;
+ break;
+ }
+ else if( nCntxtToken == nLimit ) // 0 als Token kommt nicht vor
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ nPos--;
+ }
+
+ _HTMLAttrContext *pCntxt = 0;
+ if( bFound )
+ {
+ pCntxt = aContexts[nPos];
+ if( bRemove )
+ aContexts.Remove( nPos, 1 );
+ }
+
+ return pCntxt;
+}
+
+BOOL SwHTMLParser::GetMarginsFromContext( USHORT& nLeft,
+ USHORT& nRight,
+ short& nIndent,
+ BOOL bIgnoreTopContext ) const
+{
+ USHORT nPos = aContexts.Count();
+ if( bIgnoreTopContext )
+ {
+ if( !nPos )
+ return FALSE;
+ else
+ nPos--;
+ }
+
+ while( nPos > nContextStAttrMin )
+ {
+ const _HTMLAttrContext *pCntxt = aContexts[--nPos];
+ if( pCntxt->IsLRSpaceChanged() )
+ {
+ pCntxt->GetMargins( nLeft, nRight, nIndent );
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL SwHTMLParser::GetMarginsFromContextWithNumBul( USHORT& nLeft,
+ USHORT& nRight,
+ short& nIndent ) const
+{
+ BOOL bRet = GetMarginsFromContext( nLeft, nRight, nIndent );
+ const SwHTMLNumRuleInfo& rInfo = ((SwHTMLParser*)this)->GetNumInfo();
+ if( rInfo.GetDepth() )
+ {
+ BYTE nLevel = (BYTE)( (rInfo.GetDepth() <= MAXLEVEL ? rInfo.GetDepth()
+ : MAXLEVEL) - 1 );
+ const SwNumFmt& rNumFmt = rInfo.GetNumRule()->Get(nLevel);
+ nLeft = nLeft + rNumFmt.GetAbsLSpace();
+ nIndent = rNumFmt.GetFirstLineOffset();
+ }
+
+ return bRet;
+}
+
+void SwHTMLParser::GetULSpaceFromContext( USHORT& nUpper,
+ USHORT& nLower ) const
+{
+ USHORT nDfltColl = 0;
+ String aDfltClass;
+
+ USHORT nPos = aContexts.Count();
+ while( nPos > nContextStAttrMin )
+ {
+ const _HTMLAttrContext *pCntxt = aContexts[--nPos];
+ if( pCntxt->IsULSpaceChanged() )
+ {
+ pCntxt->GetULSpace( nUpper, nLower );
+ return;
+ }
+ else if( !nDfltColl )
+ {
+ nDfltColl = pCntxt->GetDfltTxtFmtColl();
+ if( nDfltColl )
+ aDfltClass = pCntxt->GetClass();
+ }
+ }
+
+ if( !nDfltColl )
+ nDfltColl = RES_POOLCOLL_TEXT;
+
+ const SwTxtFmtColl *pColl =
+ pCSS1Parser->GetTxtFmtColl( nDfltColl, aDfltClass );
+ const SvxULSpaceItem& rULSpace = pColl->GetULSpace();
+ nUpper = rULSpace.GetUpper();
+ nLower = rULSpace.GetLower();
+}
+
+void SwHTMLParser::EndContextAttrs( _HTMLAttrContext *pContext, BOOL bRemove )
+{
+ _HTMLAttrs &rAttrs = pContext->GetAttrs();
+ for( USHORT i=0; i<rAttrs.Count(); i++ )
+ {
+ _HTMLAttr *pAttr = rAttrs[i];
+
+ if( RES_PARATR_DROP==pAttr->GetItem().Which() )
+ {
+ // Fuer DropCaps noch die Anzahl der Zeichen anpassen. Wenn
+ // es am Ende 0 sind, wird das Attribut invalidiert und dann
+ // von _SetAttr gar nicht erst gesetzt.
+ xub_StrLen nChars = pPam->GetPoint()->nContent.GetIndex();
+ if( nChars < 1 )
+ pAttr->Invalidate();
+ else if( nChars > MAX_DROPCAP_CHARS )
+ nChars = MAX_DROPCAP_CHARS;
+ ((SwFmtDrop&)pAttr->GetItem()).GetChars() = (BYTE)nChars;
+ }
+
+ EndAttr( pAttr );
+ }
+
+ if( bRemove && rAttrs.Count() )
+ rAttrs.Remove( 0, rAttrs.Count() );
+}
+
+void SwHTMLParser::InsertParaAttrs( const SfxItemSet& rItemSet )
+{
+ SfxItemIter aIter( rItemSet );
+
+ const SfxPoolItem *pItem = aIter.FirstItem();
+ while( pItem )
+ {
+ // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
+ USHORT nWhich = pItem->Which();
+ _HTMLAttr **ppAttr = GetAttrTabEntry( nWhich );
+
+ if( ppAttr )
+ {
+ NewAttr( ppAttr, *pItem );
+ if( RES_PARATR_BEGIN > nWhich )
+ (*ppAttr)->SetLikePara();
+ aParaAttrs.Insert( *ppAttr, aParaAttrs.Count() );
+ EndAttr( *ppAttr, 0, FALSE );
+ }
+
+ pItem = aIter.NextItem();
+ }
+}
+
+void lcl_swcss1_setEncoding( SwFmt& rFmt, rtl_TextEncoding eEnc )
+{
+ if( RTL_TEXTENCODING_DONTKNOW == eEnc )
+ return;
+
+ const SfxItemSet& rItemSet = rFmt.GetAttrSet();
+ static USHORT aWhichIds[3] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT,
+ RES_CHRATR_CTL_FONT };
+ const SfxPoolItem *pItem;
+ for( USHORT i=0; i<3; i++ )
+ {
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], FALSE,&pItem ) )
+ {
+ const SvxFontItem& rFont = *(const SvxFontItem *)pItem;
+ if( RTL_TEXTENCODING_SYMBOL != rFont.GetCharSet() )
+ {
+ SvxFontItem aFont( rFont.GetFamily(), rFont.GetFamilyName(),
+ rFont.GetStyleName(), rFont.GetPitch(),
+ eEnc, aWhichIds[i]);
+ rFmt.SetFmtAttr( aFont );
+ }
+ }
+ }
+}
+
+void SwCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
+{
+ if( eEnc != GetDfltEncoding() )
+ {
+ if( bIsNewDoc )
+ {
+ // Set new encoding as pool default
+ static USHORT aWhichIds[3] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT,
+ RES_CHRATR_CTL_FONT };
+ USHORT i;
+ for( i=0; i<3; i++ )
+ {
+ const SvxFontItem& rDfltFont =
+ (const SvxFontItem&)pDoc->GetDefault( aWhichIds[i]);
+ SvxFontItem aFont( rDfltFont.GetFamily(),
+ rDfltFont.GetFamilyName(),
+ rDfltFont.GetStyleName(),
+ rDfltFont.GetPitch(),
+ eEnc, aWhichIds[i] );
+ pDoc->SetDefault( aFont );
+ }
+
+ // Change all paragraph styles that do specify a font.
+ USHORT nArrLen = pDoc->GetTxtFmtColls()->Count();
+ for( i=1; i<nArrLen; i++ )
+ lcl_swcss1_setEncoding( *(*pDoc->GetTxtFmtColls())[i], eEnc );
+
+ // Change all character styles that do specify a font.
+ nArrLen = pDoc->GetCharFmts()->Count();
+ for( i=1; i<nArrLen; i++ )
+ lcl_swcss1_setEncoding( *(*pDoc->GetCharFmts())[i], eEnc );
+ }
+
+ SvxCSS1Parser::SetDfltEncoding( eEnc );
+ }
+}