summaryrefslogtreecommitdiff
path: root/sw/source/filter/html
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/html')
-rw-r--r--sw/source/filter/html/SwAppletImpl.cxx208
-rw-r--r--sw/source/filter/html/css1atr.cxx3859
-rw-r--r--sw/source/filter/html/css1kywd.cxx281
-rw-r--r--sw/source/filter/html/css1kywd.hxx291
-rw-r--r--sw/source/filter/html/htmlatr.cxx3494
-rw-r--r--sw/source/filter/html/htmlbas.cxx369
-rw-r--r--sw/source/filter/html/htmlcss1.cxx2477
-rw-r--r--sw/source/filter/html/htmlctxt.cxx752
-rw-r--r--sw/source/filter/html/htmldraw.cxx859
-rw-r--r--sw/source/filter/html/htmlfld.cxx670
-rw-r--r--sw/source/filter/html/htmlfld.hxx92
-rw-r--r--sw/source/filter/html/htmlfldw.cxx539
-rw-r--r--sw/source/filter/html/htmlfly.cxx1929
-rw-r--r--sw/source/filter/html/htmlfly.hxx137
-rw-r--r--sw/source/filter/html/htmlflyt.cxx516
-rw-r--r--sw/source/filter/html/htmlform.cxx2661
-rw-r--r--sw/source/filter/html/htmlform.hxx52
-rw-r--r--sw/source/filter/html/htmlforw.cxx1447
-rw-r--r--sw/source/filter/html/htmlftn.cxx621
-rw-r--r--sw/source/filter/html/htmlgrin.cxx1448
-rw-r--r--sw/source/filter/html/htmlnum.cxx987
-rw-r--r--sw/source/filter/html/htmlnum.hxx131
-rw-r--r--sw/source/filter/html/htmlplug.cxx1401
-rw-r--r--sw/source/filter/html/htmlsect.cxx862
-rw-r--r--sw/source/filter/html/htmltab.cxx5600
-rw-r--r--sw/source/filter/html/htmltabw.cxx1265
-rw-r--r--sw/source/filter/html/htmlvsh.hxx55
-rw-r--r--sw/source/filter/html/makefile.mk83
-rw-r--r--sw/source/filter/html/parcss1.cxx1426
-rw-r--r--sw/source/filter/html/parcss1.hxx307
-rw-r--r--sw/source/filter/html/svxcss1.cxx3311
-rw-r--r--sw/source/filter/html/svxcss1.hxx435
-rw-r--r--sw/source/filter/html/swcss1.hxx227
-rw-r--r--sw/source/filter/html/swhtml.cxx5521
-rw-r--r--sw/source/filter/html/swhtml.hxx1040
-rw-r--r--sw/source/filter/html/wrthtml.cxx1439
-rw-r--r--sw/source/filter/html/wrthtml.hxx603
37 files changed, 47395 insertions, 0 deletions
diff --git a/sw/source/filter/html/SwAppletImpl.cxx b/sw/source/filter/html/SwAppletImpl.cxx
new file mode 100644
index 000000000000..39761ebbd810
--- /dev/null
+++ b/sw/source/filter/html/SwAppletImpl.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <SwAppletImpl.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svl/urihelper.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+
+#include <comphelper/embeddedobjectcontainer.hxx>
+#include <sot/clsids.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <svtools/embedhlp.hxx>
+
+using namespace com::sun::star;
+
+namespace {
+
+static char const sHTML_O_archive[] = "ARCHIVE";
+static char const sHTML_O_Archives[] = "ARCHIVES";
+static char const sHTML_O_Object[] = "OBJECT";
+
+}
+
+USHORT SwApplet_Impl::GetOptionType( const String& rName, BOOL bApplet )
+{
+ USHORT nType = bApplet ? SWHTML_OPTTYPE_PARAM : SWHTML_OPTTYPE_TAG;
+
+ switch( rName.GetChar(0) )
+ {
+ case 'A':
+ case 'a':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_align ) ||
+ rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_alt ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ else if( bApplet &&
+ (rName.EqualsIgnoreCaseAscii( sHTML_O_archive ) ||
+ rName.EqualsIgnoreCaseAscii( sHTML_O_Archives )) )
+ nType = SWHTML_OPTTYPE_TAG;
+ break;
+ case 'C':
+ case 'c':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_class ) ||
+ (bApplet && (rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_code ) ||
+ rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_codebase ))) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'H':
+ case 'h':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_height ) )
+ nType = SWHTML_OPTTYPE_SIZE;
+ else if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_hspace ) ||
+ (!bApplet && rName.EqualsIgnoreCaseAscii( OOO_STRING_SW_HTML_O_Hidden )) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'I':
+ case 'i':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_id ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'M':
+ case 'm':
+ if( bApplet && rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_mayscript ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'N':
+ case 'n':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_name ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'O':
+ case 'o':
+ if( bApplet && rName.EqualsIgnoreCaseAscii( sHTML_O_Object ) )
+ nType = SWHTML_OPTTYPE_TAG;
+ break;
+ case 'S':
+ case 's':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_style ) ||
+ (!bApplet && rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_src )) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'T':
+ case 't':
+ if( !bApplet && rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_type ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'V':
+ case 'v':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_vspace ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'W':
+ case 'w':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_width ) )
+ nType = SWHTML_OPTTYPE_SIZE;
+ break;
+ }
+
+ return nType;
+}
+SwApplet_Impl::SwApplet_Impl( SfxItemPool& rPool, USHORT nWhich1, USHORT nWhich2 ) :
+ aItemSet( rPool, nWhich1, nWhich2 )
+{
+}
+
+void SwApplet_Impl::CreateApplet( const String& rCode, const String& rName,
+ BOOL bMayScript, const String& rCodeBase,
+ const String& rDocumentBaseURL )
+{
+ comphelper::EmbeddedObjectContainer aCnt;
+ ::rtl::OUString aName;
+
+ // create Applet; it will be in running state
+ xApplet = aCnt.CreateEmbeddedObject( SvGlobalName( SO3_APPLET_CLASSID ).GetByteSequence(), aName );
+ ::svt::EmbeddedObjectRef::TryRunningState( xApplet );
+
+ INetURLObject aUrlBase(rDocumentBaseURL);
+ aUrlBase.removeSegment();
+
+ String sDocBase = aUrlBase.GetMainURL(INetURLObject::NO_DECODE);
+ uno::Reference < beans::XPropertySet > xSet( xApplet->getComponent(), uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("AppletCode"), uno::makeAny( ::rtl::OUString( rCode ) ) );
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("AppletName"), uno::makeAny( ::rtl::OUString( rName ) ) );
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("AppletIsScript"), uno::makeAny( sal_Bool(bMayScript) ) );
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("AppletDocBase"), uno::makeAny( ::rtl::OUString(sDocBase) ) );
+ if ( rCodeBase.Len() )
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("AppletCodeBase"), uno::makeAny( ::rtl::OUString( rCodeBase ) ) );
+ else
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("AppletCodeBase"), uno::makeAny( ::rtl::OUString( sDocBase ) ) );
+ }
+}
+#ifdef SOLAR_JAVA
+sal_Bool SwApplet_Impl::CreateApplet( const String& rBaseURL )
+{
+ String aCode, aName, aCodeBase;
+ sal_Bool bMayScript = sal_False;
+
+ sal_uInt32 nArgCount = aCommandList.Count();
+ for( sal_uInt32 i=0; i<nArgCount; i++ )
+ {
+ const SvCommand& rArg = aCommandList[i];
+ const String& rName = rArg.GetCommand();
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_code ) )
+ aCode = rArg.GetArgument();
+ else if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_codebase ) )
+ aCodeBase = INetURLObject::GetAbsURL( rBaseURL, rArg.GetArgument() );
+ else if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_name ) )
+ aName = rArg.GetArgument();
+ else if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_mayscript ) )
+ bMayScript = sal_True;
+ }
+
+ if( !aCode.Len() )
+ return sal_False;
+ CreateApplet( aCode, aName, bMayScript, aCodeBase, rBaseURL );
+ return sal_True;
+}
+#endif
+
+SwApplet_Impl::~SwApplet_Impl()
+{
+}
+void SwApplet_Impl::FinishApplet()
+{
+ //xApplet->EnableSetModified( TRUE );
+ uno::Reference < beans::XPropertySet > xSet( xApplet->getComponent(), uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ uno::Sequence < beans::PropertyValue > aProps;
+ aCommandList.FillSequence( aProps );
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("AppletCommands"), uno::makeAny( aProps ) );
+ }
+}
+
+#ifdef SOLAR_JAVA
+void SwApplet_Impl::AppendParam( const String& rName, const String& rValue )
+{
+ aCommandList.Append( rName, rValue );
+}
+#endif
diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx
new file mode 100644
index 000000000000..7edd84270886
--- /dev/null
+++ b/sw/source/filter/html/css1atr.cxx
@@ -0,0 +1,3859 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <svl/whiter.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <svx/xoutbmp.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svx/htmlmode.hxx>
+#include <svl/urihelper.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/bigint.hxx>
+#include <unotools/charclass.hxx>
+#include <i18npool/mslangid.hxx>
+#include <charfmt.hxx>
+#include <fmtcol.hxx>
+#include <fmtfsize.hxx>
+#include <fmtornt.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtlsplt.hxx>
+#include <pagedesc.hxx>
+#include <fmtanchr.hxx>
+#include <docary.hxx>
+#include <pam.hxx>
+#include <viewsh.hxx>
+#include <viewopt.hxx>
+#include <swtable.hxx>
+// OTES
+#include <ftninfo.hxx>
+#include <ftnidx.hxx>
+#include <txtftn.hxx>
+#include <fmtftn.hxx>
+// FOOTNOTES
+#include <dcontact.hxx>
+
+#include "doc.hxx"
+#include "swerror.h"
+#include "charatr.hxx"
+#include "paratr.hxx"
+#include "frmatr.hxx"
+#include "poolfmt.hxx"
+#include "fltini.hxx"
+#include "css1kywd.hxx"
+#include "wrthtml.hxx"
+#include "htmlnum.hxx"
+
+#include <IDocumentStylePoolAccess.hxx>
+#include <numrule.hxx>
+
+/*
+ * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
+ * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
+ * definiert und mit der akt. verglichen. Bei unterschieden wird der
+ * Compiler schon meckern.
+ *
+ * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
+ * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
+ */
+#if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
+
+#define ATTRFNTAB_SIZE 130
+#if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
+#error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
+#endif
+
+#endif
+
+#define HTML_HEADSPACE (12*20)
+
+#define CSS1_BACKGROUND_ATTR 1
+#define CSS1_BACKGROUND_PAGE 2
+#define CSS1_BACKGROUND_TABLE 3
+#define CSS1_BACKGROUND_FLY 4
+#define CSS1_BACKGROUND_SECTION 5
+
+#define CSS1_FRMSIZE_WIDTH 0x01
+#define CSS1_FRMSIZE_VARHEIGHT 0x02
+#define CSS1_FRMSIZE_MINHEIGHT 0x04
+#define CSS1_FRMSIZE_FIXHEIGHT 0x08
+#define CSS1_FRMSIZE_ANYHEIGHT 0x0e
+#define CSS1_FRMSIZE_PIXEL 0x10
+
+using namespace ::com::sun::star;
+
+//-----------------------------------------------------------------------
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_rule_end, " }" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_span_tag_end, "\">" );
+const sal_Char cCSS1_style_opt_end = '\"';
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sHTML_FTN_fontheight, "57%" );
+
+extern SwAttrFnTab aCSS1AttrFnTab;
+
+static Writer& OutCSS1_SwFmt( Writer& rWrt, const SwFmt& rFmt,
+ IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate );
+static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rFmt,
+ IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate,
+ USHORT nRefPoolId, BOOL bExtRef,
+ BOOL bPseudo=TRUE );
+static Writer& OutCSS1_SwFtnInfo( Writer& rWrt, const SwEndNoteInfo& rInfo,
+ SwDoc *pDoc, USHORT nNotes, BOOL bEndNote );
+static void OutCSS1_SwFmtDropAttrs( SwHTMLWriter& rHWrt,
+ const SwFmtDrop& rDrop,
+ const SfxItemSet *pCharFmtItemSet=0 );
+static Writer& OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( Writer& rWrt,
+ const SvxUnderlineItem *pUItem,
+ const SvxOverlineItem *pOItem,
+ const SvxCrossedOutItem *pCOItem,
+ const SvxBlinkItem *pBItem );
+static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt );
+static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt );
+static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt );
+static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt );
+static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
+ const SvxULSpaceItem *pULSpace,
+ const SvxLRSpaceItem *pLRSpace );
+static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
+ const SfxItemSet& rItemSet,
+ BOOL bDeep );
+static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
+ USHORT nMode, const String *pGrfName );
+static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt );
+static Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt );
+static Writer& OutCSS1_SwFmtFrmSize( Writer& rWrt, const SfxPoolItem& rHt,
+ USHORT nMode );
+static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
+ const SfxItemSet& rItemSet,
+ BOOL bDeep );
+static Writer& OutCSS1_SwFmtLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt );
+
+static void ConvToHex( USHORT nHex, ByteString& rStr )
+{
+ sal_Char aNToABuf[] = "00";
+
+ // Pointer an das Bufferende setzen
+ sal_Char *pStr = aNToABuf + (sizeof(aNToABuf)-1);
+ for( BYTE n = 0; n < 2; ++n )
+ {
+ *(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
+ if( *pStr > '9' )
+ *pStr += 39;
+ nHex >>= 4;
+ }
+
+ rStr.Append( aNToABuf );
+}
+
+static void GetCSS1Color( const Color& rColor, ByteString& rStr )
+{
+ rStr += '#';
+
+ ConvToHex( rColor.GetRed(), rStr );
+ ConvToHex( rColor.GetGreen(), rStr );
+ ConvToHex( rColor.GetBlue(), rStr );
+}
+
+class SwCSS1OutMode
+{
+ SwHTMLWriter& rWrt;
+ USHORT nOldMode;
+
+public:
+
+ SwCSS1OutMode( SwHTMLWriter& rHWrt, USHORT nMode, BOOL bStartFirst=TRUE,
+ const String *pSelector=0 ) :
+ rWrt( rHWrt ),
+ nOldMode( rHWrt.nCSS1OutMode )
+ {
+ rWrt.nCSS1OutMode = nMode;
+ if( bStartFirst )
+ rWrt.bFirstCSS1Property = TRUE;
+ if( pSelector )
+ rWrt.aCSS1Selector = *pSelector;
+ }
+
+ ~SwCSS1OutMode()
+ {
+ rWrt.nCSS1OutMode = nOldMode;
+ }
+};
+
+
+
+void SwHTMLWriter::OutCSS1_Property( const sal_Char *pProp,
+ const sal_Char *pVal,
+ const String *pSVal )
+{
+ ByteString sOut;
+
+ if( bFirstCSS1Rule && (nCSS1OutMode & CSS1_OUTMODE_RULE_ON)!=0 )
+ {
+ bFirstCSS1Rule = FALSE;
+ OutNewLine();
+ ((((sOut += '<') += OOO_STRING_SVTOOLS_HTML_style) += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += "=\"text/css\">";
+ Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ OutNewLine();
+ Strm() << '<' << OOO_STRING_SVTOOLS_HTML_comment;
+
+ IncIndentLevel();
+ }
+
+ if( bFirstCSS1Property )
+ {
+ switch( nCSS1OutMode & CSS1_OUTMODE_ANY_ON )
+ {
+ case CSS1_OUTMODE_SPAN_TAG_ON:
+ case CSS1_OUTMODE_SPAN_TAG1_ON:
+ if( bTagOn )
+ {
+ ((((sOut += '<') += OOO_STRING_SVTOOLS_HTML_span) += ' ') += OOO_STRING_SVTOOLS_HTML_O_style) += "=\"";
+ }
+ else
+ {
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, FALSE );
+ return;
+ }
+ break;
+
+ case CSS1_OUTMODE_RULE_ON:
+ {
+ ByteString sTmp( aCSS1Selector, eDestEnc );
+ OutNewLine();
+ (sOut = sTmp) += " { ";
+ }
+ break;
+
+ case CSS1_OUTMODE_STYLE_OPT_ON:
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_style) += "=\"";
+ break;
+ }
+ bFirstCSS1Property = FALSE;
+ }
+ else
+ {
+ sOut += "; ";
+ }
+
+
+ (sOut += pProp) += ": ";
+ if( nCSS1OutMode & CSS1_OUTMODE_ENCODE )
+ {
+ // In STYLE-Optionen den String codieren
+ Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ if( pVal )
+ HTMLOutFuncs::Out_String( Strm(), String::CreateFromAscii(pVal),
+ eDestEnc, &aNonConvertableCharacters );
+ else if( pSVal )
+ HTMLOutFuncs::Out_String( Strm(), *pSVal, eDestEnc, &aNonConvertableCharacters );
+ }
+ else
+ {
+ // Im STYLE-Tag des String direct ausgeben
+ if( pVal )
+ sOut += pVal;
+ else if( pSVal )
+ {
+ ByteString sTmp( *pSVal, eDestEnc );
+ sOut += sTmp;
+ }
+ }
+
+ if( sOut.Len() )
+ Strm() << sOut.GetBuffer();
+}
+
+static void AddUnitPropertyValue( long nVal, FieldUnit eUnit, ByteString& rOut )
+{
+ if( nVal < 0 )
+ {
+ // Vorzeichen extra behandeln
+ nVal = -nVal;
+ rOut += '-';
+ }
+
+ // Die umgerechnete Einheit ergibt sich aus (x * nMul)/(nDiv*nFac*10)
+ long nMul = 1000;
+ long nDiv = 1;
+ long nFac = 100;
+ const sal_Char *pUnit;
+ switch( eUnit )
+ {
+ case FUNIT_100TH_MM:
+ ASSERT( FUNIT_MM == eUnit, "Masseinheit wird nicht unterstuetzt" );
+ case FUNIT_MM:
+ // 0.01mm = 0.57twip
+ nMul = 25400; // 25.4 * 1000
+ nDiv = 1440; // 72 * 20;
+ nFac = 100;
+ pUnit = sCSS1_UNIT_mm;
+ break;
+
+ case FUNIT_M:
+ case FUNIT_KM:
+ ASSERT( FUNIT_CM == eUnit, "Masseinheit wird nicht unterstuetzt" );
+ case FUNIT_CM:
+#ifdef EXACT_VALUES
+ // 0.001cm = 0.57twip
+ nMul = 25400; // 2.54 * 10000
+ nDiv = 1440; // 72 * 20;
+ nFac = 1000;
+#else
+ // 0.01cm = 5.7twip (ist zwar ungenau, aber die UI ist auch ungenau)
+ nMul = 2540; // 2.54 * 1000
+ nDiv = 1440; // 72 * 20;
+ nFac = 100;
+#endif
+ pUnit = sCSS1_UNIT_cm;
+ break;
+
+ case FUNIT_TWIP:
+ ASSERT( FUNIT_POINT == eUnit, "Masseinheit wird nicht unterstuetzt" );
+ case FUNIT_POINT:
+#ifdef EXACT_VALUES
+ // 0.01pt = 0.2twip
+ nMul = 1000;
+ nDiv = 20;
+ nFac = 100;
+#else
+ // 0.1pt = 2.0twip (ist zwar ungenau, aber die UI ist auch ungenau)
+ nMul = 100;
+ nDiv = 20;
+ nFac = 10;
+#endif
+ pUnit = sCSS1_UNIT_pt;
+ break;
+
+ case FUNIT_PICA:
+#ifdef EXACT_VALUES
+ // 0.001pc = 0.24twip
+ nMul = 10000;
+ nDiv = 12 * 20;
+ nFac = 1000;
+#else
+ // 0.01pc = 2.40twip (ist zwar ungenau, aber die UI ist auch ungenau)
+ nMul = 1000;
+ nDiv = 240; // 12 * 20;
+ nFac = 100;
+#endif
+ pUnit = sCSS1_UNIT_pc;
+ break;
+
+ case FUNIT_NONE:
+ case FUNIT_FOOT:
+ case FUNIT_MILE:
+ case FUNIT_CUSTOM:
+ case FUNIT_PERCENT:
+ case FUNIT_INCH:
+ default:
+ ASSERT( FUNIT_INCH == eUnit, "Masseinheit wird nicht unterstuetzt" );
+#ifdef EXACT_VALUES
+ // 0.0001in = 0.144twip
+ nMul = 100000;
+ nDiv = 1440; // 72 * 20;
+ nFac = 10000;
+#else
+ // 0.01in = 14.4twip (ist zwar ungenau, aber die UI ist auch ungenau)
+ nMul = 1000;
+ nDiv = 1440; // 72 * 20;
+ nFac = 100;
+#endif
+ pUnit = sCSS1_UNIT_inch;
+ break;
+ }
+
+ long nLongVal = 0;
+ BOOL bOutLongVal = TRUE;
+ if( nVal > LONG_MAX / nMul )
+ {
+ // Zum Unrechnen der Einheit wird ein BigInt benoetigt
+#ifdef SAL_INT64_IS_STRUCT
+ BigInt nBigVal( nVal );
+ nBigVal *= nMul;
+ nBigVal /= nDiv;
+ nBigVal += 5;
+ nBigVal /= 10;
+
+ if( nBigVal.IsLong() )
+ {
+ // Zum Ausgeben des Wertes reicht ein long.
+ nLongVal = (long)nBigVal;
+ }
+ else
+ {
+ BigInt nBigFac( nFac );
+ BigInt nBig10( 10 );
+ rOut += (long)(nBigVal / nBigFac);
+ if( !(nBigVal % nBigFac).IsZero() )
+ {
+ rOut += '.';
+ while( nFac > 1 && !(nBigVal % nBigFac).IsZero() )
+ {
+ nFac /= 10;
+ nBigFac = nFac;
+ rOut += (int)((nBigVal / nBigFac) % nBig10 );
+ }
+ }
+ bOutLongVal = FALSE;
+ }
+#else
+ sal_Int64 nBigVal( nVal );
+ nBigVal *= nMul;
+ nBigVal /= nDiv;
+ nBigVal += 5;
+ nBigVal /= 10;
+
+ if( nBigVal <= LONG_MAX )
+ {
+ // Zum Ausgeben des Wertes reicht ein long.
+ nLongVal = (long)nBigVal;
+ }
+ else
+ {
+ rOut += ByteString::CreateFromInt64( nBigVal / (sal_Int64)nFac );
+ if( (nBigVal % (sal_Int64)nFac) != 0 )
+ {
+ rOut += '.';
+ while( nFac > 1 && (nBigVal % (sal_Int64)nFac) != 0 )
+ {
+ nFac /= 10;
+ rOut += ByteString::CreateFromInt64(
+ (nBigVal / (sal_Int64)nFac) % (sal_Int64)10 );
+ }
+ }
+ bOutLongVal = FALSE;
+ }
+#endif
+ }
+ else
+ {
+ nLongVal = nVal * nMul;
+ nLongVal /= nDiv;
+ nLongVal += 5;
+ nLongVal /= 10;
+ }
+
+ if( bOutLongVal )
+ {
+ rOut += ByteString::CreateFromInt32( nLongVal/nFac );
+ if( (nLongVal % nFac) != 0 )
+ {
+ rOut += '.';
+ while( nFac > 1 && (nLongVal % nFac) != 0 )
+ {
+ nFac /= 10;
+ rOut += ByteString::CreateFromInt32( (nLongVal / nFac) % 10 );
+ }
+ }
+ }
+
+ rOut.Append( pUnit );
+}
+
+void SwHTMLWriter::OutCSS1_UnitProperty( const sal_Char *pProp, long nVal )
+{
+ ByteString sOut;
+ AddUnitPropertyValue( nVal, eCSS1Unit, sOut );
+ OutCSS1_PropertyAscii( pProp, sOut );
+}
+
+void SwHTMLWriter::OutCSS1_PixelProperty( const sal_Char *pProp, long nVal,
+ BOOL bVert )
+{
+ if( nVal && Application::GetDefaultDevice() )
+ {
+ Size aSz( bVert ? 0 : nVal, bVert ? nVal : 0 );
+ aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode( MAP_TWIP) );
+ nVal = bVert ? aSz.Height() : aSz.Width();
+ if( !nVal )
+ nVal = 1;
+ }
+
+ ByteString sOut( ByteString::CreateFromInt32( nVal ) );
+ sOut.Append( sCSS1_UNIT_px );
+ OutCSS1_PropertyAscii( pProp, sOut );
+}
+
+void SwHTMLWriter::OutCSS1_SfxItemSet( const SfxItemSet& rItemSet,
+ BOOL bDeep )
+{
+ // den ItemSet ausgeben, und zwar inklusive aller Attribute
+ Out_SfxItemSet( aCSS1AttrFnTab, *this, rItemSet, bDeep );
+
+ // ein par Attribute benoetigen eine Spezial-Behandlung
+ const SfxPoolItem *pItem = 0;
+
+ // Underline, Overline, CrossedOut und Blink bilden zusammen eine CSS1-Property
+ // (geht natuerlich nicht bei Hints)
+ if( !IsCSS1Source(CSS1_OUTMODE_HINT) )
+ {
+ const SvxUnderlineItem *pUnderlineItem = 0;
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_UNDERLINE, bDeep, &pItem ))
+ pUnderlineItem = (const SvxUnderlineItem *)pItem;
+
+ const SvxOverlineItem *pOverlineItem = 0;
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_OVERLINE, bDeep, &pItem ))
+ pOverlineItem = (const SvxOverlineItem *)pItem;
+
+ const SvxCrossedOutItem *pCrossedOutItem = 0;
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_CROSSEDOUT, bDeep, &pItem ))
+ pCrossedOutItem = (const SvxCrossedOutItem *)pItem;
+
+ const SvxBlinkItem *pBlinkItem = 0;
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_BLINK, bDeep, &pItem ))
+ pBlinkItem = (const SvxBlinkItem *)pItem;
+
+ if( pUnderlineItem || pOverlineItem || pCrossedOutItem || pBlinkItem )
+ OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( *this, pUnderlineItem,
+ pOverlineItem,
+ pCrossedOutItem,
+ pBlinkItem );
+
+ OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( *this, rItemSet, bDeep );
+ }
+
+ if( !bFirstCSS1Property )
+ {
+ // wenn eine Property als Bestandteil einer Style-Option
+ // ausgegeben wurde, muss die Optiomn noch beendet werden
+ ByteString sOut;
+ switch( nCSS1OutMode & CSS1_OUTMODE_ANY_OFF )
+ {
+ case CSS1_OUTMODE_SPAN_TAG_OFF:
+ sOut = sCSS1_span_tag_end;
+ break;
+
+ case CSS1_OUTMODE_STYLE_OPT_OFF:
+ sOut = cCSS1_style_opt_end;
+ break;
+
+ case CSS1_OUTMODE_RULE_OFF:
+ sOut = sCSS1_rule_end;
+ break;
+ }
+ if( sOut.Len() )
+ Strm() << sOut.GetBuffer();
+ }
+}
+
+void SwHTMLWriter::OutStyleSheet( const SwPageDesc& rPageDesc, BOOL bUsed )
+{
+ bFirstCSS1Rule = TRUE;
+
+// Feature: PrintExt
+ if( IsHTMLMode(HTMLMODE_PRINT_EXT) )
+ {
+ const SwPageDesc *pFirstPageDesc = 0;
+ USHORT nFirstRefPoolId = RES_POOLPAGE_HTML;
+ bCSS1IgnoreFirstPageDesc = TRUE;
+
+ // Erstmal versuchen wir zu erraten, wie das Dokument so augebaut ist.
+ // Erlaubt sind nur die Vorlagen HTML, erste Seite, linke Seite und
+ // rechte Seite.
+ // Eine erste Seite wird nur exportiert, wenn die erste Seite auch
+ // wirklich die Vorlage "erste Seite" ist.
+ // Linke und rechte Seiten werden nur exportiert, wenn diese beiden
+ // Vorlagen untereinander verkettet werden.
+ // Wenn andere Vorlagen verwendet werden, wird nur in sehr einfachen
+ // Faellen etwas exportiert.
+ const SwPageDesc *pPageDesc = &rPageDesc;
+ const SwPageDesc *pFollow = rPageDesc.GetFollow();
+ if( RES_POOLPAGE_FIRST == pPageDesc->GetPoolFmtId() &&
+ pFollow != pPageDesc &&
+ !IsPoolUserFmt( pFollow->GetPoolFmtId() ) )
+ {
+ // Das Dokument hat eine erste Seite
+ pFirstPageDesc = pPageDesc;
+ pPageDesc = pFollow;
+ pFollow = pPageDesc->GetFollow();
+ }
+
+ IDocumentStylePoolAccess* pStylePoolAccess = getIDocumentStylePoolAccess();
+ if( pPageDesc == pFollow )
+ {
+ // Das Dokument ist einseitig. Egal welche Seite verwendet wird,
+ // es wird kein zweiseitiges Dokument daraus gemacht.
+ // Die Attributierung wird relativ zur HTML-Seitenvorlage
+ // aus der HTML-Vorlage exportiert.
+ OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, pTemplate,
+ RES_POOLPAGE_HTML, TRUE, FALSE );
+ nFirstRefPoolId = pFollow->GetPoolFmtId();
+ }
+ else if( (RES_POOLPAGE_LEFT == pPageDesc->GetPoolFmtId() &&
+ RES_POOLPAGE_RIGHT == pFollow->GetPoolFmtId()) ||
+ (RES_POOLPAGE_RIGHT == pPageDesc->GetPoolFmtId() &&
+ RES_POOLPAGE_LEFT == pFollow->GetPoolFmtId()) )
+ {
+ // Das Dokument ist zweiseitig
+ OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, pTemplate,
+ RES_POOLPAGE_HTML, TRUE );
+ OutCSS1_SwPageDesc( *this, *pFollow, pStylePoolAccess, pTemplate,
+ RES_POOLPAGE_HTML, TRUE );
+ nFirstRefPoolId = RES_POOLPAGE_RIGHT;
+ bCSS1IgnoreFirstPageDesc = FALSE;
+ }
+ // Alles andere bekommen wir nicht hin.
+
+ if( pFirstPageDesc )
+ OutCSS1_SwPageDesc( *this, *pFirstPageDesc, pStylePoolAccess, pTemplate,
+ nFirstRefPoolId, FALSE );
+ }
+// /Feature: PrintExt
+
+
+ // The text body style has to be exported always (if it is changed compared
+ // to the template), because it is used as reference for any style
+ // that maps to <P>, and that's especially the standard style
+ getIDocumentStylePoolAccess()->GetTxtCollFromPool( RES_POOLCOLL_TEXT, false );
+
+ // das Default-TextStyle wir nicht mit ausgegeben !!
+ // das 0-Style ist das Default, wird nie ausgegeben !!
+ USHORT nArrLen = pDoc->GetTxtFmtColls()->Count();
+ USHORT i;
+
+ for( i = 1; i < nArrLen; i++ )
+ {
+ const SwTxtFmtColl* pColl = (*pDoc->GetTxtFmtColls())[i];
+ USHORT nPoolId = pColl->GetPoolFmtId();
+ if( !bUsed || nPoolId == RES_POOLCOLL_TEXT ||
+ pDoc->IsUsed( *pColl ) )
+ OutCSS1_SwFmt( *this, *pColl, pDoc, pTemplate );
+ }
+
+ // das Default-TextStyle wir nicht mit ausgegeben !!
+ nArrLen = pDoc->GetCharFmts()->Count();
+ for( i=1; i<nArrLen; i++ )
+ {
+ const SwCharFmt *pCFmt = (*pDoc->GetCharFmts())[i];
+ USHORT nPoolId = pCFmt->GetPoolFmtId();
+ if( !bUsed || nPoolId == RES_POOLCHR_INET_NORMAL ||
+ nPoolId == RES_POOLCHR_INET_VISIT ||
+ pDoc->IsUsed( *pCFmt ) )
+ OutCSS1_SwFmt( *this, *pCFmt, pDoc, pTemplate );
+ }
+
+ const SwFtnIdxs& rIdxs = pDoc->GetFtnIdxs();
+ nArrLen = rIdxs.Count();
+ USHORT nEnd = 0, nFtn = 0;
+ for( i=0; i < nArrLen; i++ )
+ {
+ if( rIdxs[i]->GetFtn().IsEndNote() )
+ nEnd++;
+ else
+ nFtn++;
+ }
+ OutCSS1_SwFtnInfo( *this, pDoc->GetFtnInfo(), pDoc, nFtn, FALSE );
+ OutCSS1_SwFtnInfo( *this, pDoc->GetEndNoteInfo(), pDoc, nEnd, TRUE );
+
+ if( !bFirstCSS1Rule )
+ {
+ DecIndentLevel();
+ OutNewLine();
+ Strm() << "-->";
+
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_style, FALSE );
+ }
+ else
+ {
+ bFirstCSS1Rule = FALSE;
+ }
+
+ nDfltTopMargin = 0;
+ nDfltBottomMargin = 0;
+}
+
+//-----------------------------------------------------------------------
+
+// wenn pPseudo gesetzt ist werden Styles-Sheets ausgegeben,
+// sonst wird nur nach Token und Class fuer ein Format gesucht
+USHORT SwHTMLWriter::GetCSS1Selector( const SwFmt *pFmt, ByteString& rToken,
+ String& rClass, USHORT& rRefPoolId,
+ String *pPseudo )
+{
+ USHORT nDeep = 0;
+ rToken.Erase(); rClass.Erase();
+ rRefPoolId = 0;
+ if( pPseudo )
+ pPseudo->Erase();
+
+ BOOL bChrFmt = RES_CHRFMT==pFmt->Which();
+
+ // Nach oben die Formate abklappern, bis man auf eine Standard-
+ // oder eine HTML-Tag-Vorlage trifft
+ const SwFmt *pPFmt = pFmt;
+ while( pPFmt && !pPFmt->IsDefault() )
+ {
+ BOOL bStop = FALSE;
+ USHORT nPoolId = pPFmt->GetPoolFmtId();
+ if( USER_FMT & nPoolId )
+ {
+ // Benutzer-Vorlagen
+ const String& rNm = pPFmt->GetName();
+ switch( rNm.GetChar(0) )
+ {
+ // nicht mehr unterstuetzt:
+ // OOO_STRING_SVTOOLS_HTML_author
+ // OOO_STRING_SVTOOLS_HTML_acronym
+ // OOO_STRING_SVTOOLS_HTML_abbreviation
+ // OOO_STRING_SVTOOLS_HTML_deletedtext
+ // OOO_STRING_SVTOOLS_HTML_insertedtext
+ // OOO_STRING_SVTOOLS_HTML_language
+ // OOO_STRING_SVTOOLS_HTML_person
+ case 'B': if( !bChrFmt && rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_blockquote) )
+ {
+ rRefPoolId = RES_POOLCOLL_HTML_BLOCKQUOTE;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_blockquote );
+ }
+ break;
+ case 'C': if( bChrFmt )
+ {
+ if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_citiation) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_CITIATION;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_citiation );
+ }
+ else if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_code) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_CODE;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_code );
+ }
+ }
+ break;
+ case 'D': if( bChrFmt && rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_definstance) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_DEFINSTANCE;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_definstance);
+ }
+ else if( !bChrFmt )
+ {
+ USHORT nDefListLvl = GetDefListLvl( rNm, nPoolId );
+ // Die Vorlagen DD 1/DT 1 werden ausgegeben,
+ // aber keine von ihnen abgeleiteten Vorlagen,
+ // auch nicht DD 2/DT 2 etc.
+ if( nDefListLvl )
+ {
+ if( pPseudo &&
+ (nDeep || (nDefListLvl & 0x0fff) > 1) )
+ {
+ bStop = TRUE;
+ }
+ else if( nDefListLvl & HTML_DLCOLL_DD )
+ {
+ rRefPoolId = RES_POOLCOLL_HTML_DD;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_dd );
+ }
+ else
+ {
+ rRefPoolId = RES_POOLCOLL_HTML_DT;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_dt );
+ }
+ }
+ }
+ break;
+ case 'E': if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_emphasis ) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_EMPHASIS;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_emphasis );
+ }
+ break;
+ case 'H': if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_horzrule ) )
+ // HR nicht ausgeben!
+ bStop = (nDeep==0);
+ break;
+ case 'K': if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_keyboard ) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_KEYBOARD;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_keyboard );
+ }
+ break;
+ case 'L': if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_listing ) )
+ {
+ // Listing als PRE exportieren bzw. von
+ // PRE abgeleitete Vorlage exportieren
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
+ rRefPoolId = RES_POOLCOLL_HTML_PRE;
+ nDeep = CSS1_FMT_CMPREF;
+ }
+ break;
+ case 'P': if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_preformtxt ) )
+ {
+ rRefPoolId = RES_POOLCOLL_HTML_PRE;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
+ }
+ break;
+ case 'S': if( bChrFmt )
+ {
+ if( rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_sample ) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_SAMPLE;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_sample );
+ }
+ else if( rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_strong ) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_STRONG;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_strong );
+ }
+ }
+ break;
+ case 'T': if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_teletype ) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_TELETYPE;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_teletype );
+ }
+ break;
+ case 'V': if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_variable ) )
+ {
+ rRefPoolId = RES_POOLCHR_HTML_VARIABLE;
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_variable );
+ }
+ break;
+ case 'X': if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_xmp ) )
+ {
+ // XMP als PRE exportieren (aber nicht die
+ // Vorlage als Style)
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
+ rRefPoolId = RES_POOLCOLL_HTML_PRE;
+ nDeep = CSS1_FMT_CMPREF;
+ }
+ break;
+ }
+
+ // Wenn eine PoolId gesetzt ist, entspricht der Name der
+ // Vorlage dem szugehoerigen Token
+ ASSERT( rRefPoolId != 0 == rToken.Len() > 0,
+ "Token missing" );
+ }
+ else
+ {
+ // Pool-Vorlagen
+ switch( nPoolId )
+ {
+ // Absatz-Vorlagen
+ case RES_POOLCOLL_HEADLINE_BASE:
+ case RES_POOLCOLL_STANDARD:
+ // diese Vorlagen nicht ausgeben
+ bStop = (nDeep==0);
+ break;
+ case RES_POOLCOLL_TEXT:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
+ break;
+ case RES_POOLCOLL_HEADLINE1:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_head1 );
+ break;
+ case RES_POOLCOLL_HEADLINE2:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_head2 );
+ break;
+ case RES_POOLCOLL_HEADLINE3:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_head3 );
+ break;
+ case RES_POOLCOLL_HEADLINE4:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_head4 );
+ break;
+ case RES_POOLCOLL_HEADLINE5:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_head5 );
+ break;
+ case RES_POOLCOLL_HEADLINE6:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_head6 );
+ break;
+ case RES_POOLCOLL_SENDADRESS:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_address );
+ break;
+ case RES_POOLCOLL_HTML_BLOCKQUOTE:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_blockquote );
+ break;
+ case RES_POOLCOLL_HTML_PRE:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
+ break;
+
+ case RES_POOLCOLL_HTML_DD:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_dd );
+ break;
+ case RES_POOLCOLL_HTML_DT:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_dt );
+ break;
+
+ case RES_POOLCOLL_TABLE:
+ if( pPseudo )
+ {
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_tabledata );
+ rToken.Append( ' ' );
+ rToken.Append( OOO_STRING_SVTOOLS_HTML_parabreak );
+ }
+ else
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
+ break;
+ case RES_POOLCOLL_TABLE_HDLN:
+ if( pPseudo )
+ {
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_tableheader );
+ rToken.Append( ' ' );
+ rToken.Append( OOO_STRING_SVTOOLS_HTML_parabreak );
+ }
+ else
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
+ break;
+ case RES_POOLCOLL_HTML_HR:
+ // HR nicht ausgeben!
+ bStop = (nDeep==0);
+ break;
+ case RES_POOLCOLL_FOOTNOTE:
+ if( !nDeep )
+ {
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
+ rClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote );
+ rRefPoolId = RES_POOLCOLL_TEXT;
+ nDeep = CSS1_FMT_CMPREF;
+ }
+ break;
+ case RES_POOLCOLL_ENDNOTE:
+ if( !nDeep )
+ {
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
+ rClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote );
+ rRefPoolId = RES_POOLCOLL_TEXT;
+ nDeep = CSS1_FMT_CMPREF;
+ }
+ break;
+
+ // Zeichen-Vorlagen
+ case RES_POOLCHR_HTML_EMPHASIS:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_emphasis );
+ break;
+ case RES_POOLCHR_HTML_CITIATION:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_citiation );
+ break;
+ case RES_POOLCHR_HTML_STRONG:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_strong );
+ break;
+ case RES_POOLCHR_HTML_CODE:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_code );
+ break;
+ case RES_POOLCHR_HTML_SAMPLE:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_sample );
+ break;
+ case RES_POOLCHR_HTML_KEYBOARD:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_keyboard );
+ break;
+ case RES_POOLCHR_HTML_VARIABLE:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_variable );
+ break;
+ case RES_POOLCHR_HTML_DEFINSTANCE:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_definstance );
+ break;
+ case RES_POOLCHR_HTML_TELETYPE:
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_teletype );
+ break;
+
+ case RES_POOLCHR_INET_NORMAL:
+ if( pPseudo )
+ {
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_anchor );
+ pPseudo->AssignAscii( sCSS1_link );
+ }
+ break;
+ case RES_POOLCHR_INET_VISIT:
+ if( pPseudo )
+ {
+ rToken.Assign( OOO_STRING_SVTOOLS_HTML_anchor );
+ pPseudo->AssignAscii( sCSS1_visited );
+ }
+ break;
+ }
+
+ // Wenn ein Token gesetzt ist, enthaelt nPoolId die dazugehoerige
+ // Vorlage
+ if( rToken.Len() && !rRefPoolId )
+ rRefPoolId = nPoolId;
+ }
+
+ if( rToken.Len() || bStop )
+ {
+ // Anhalten wenn eine HTML-Tag-Vorlage gefunden wurde
+ break;
+ }
+ else
+ {
+ // sonst weitersuchen
+ nDeep++;
+ pPFmt = pPFmt->DerivedFrom();
+ }
+ }
+
+ if( rToken.Len() )
+ {
+ // Es ist eine HTML-Tag-Vorlage
+ if( !nDeep )
+ nDeep = CSS1_FMT_ISTAG;
+ }
+ else
+ {
+ // Es ist keine HTML-Tag-Vorlage und auch keine davon abgeleitete
+ nDeep = 0;
+ }
+ if( nDeep > 0 && nDeep < CSS1_FMT_SPECIAL )
+ {
+ // Wenn die Vorlage von einer HTML-Vorlage abgeleitet ist,
+ // wird sie als <TOKEN>.<CLASS> exportiert, sonst als .<CLASS>.
+ // <CLASS> ergibt sich aus dem Namen der Vorlage durch entfernen
+ // aller Zeichen vor und inklusive dem ersten '.'
+ rClass = pFmt->GetName();
+ xub_StrLen nPos = rClass.Search( '.' );
+ if( nPos != STRING_NOTFOUND && rClass.Len() > nPos+1 )
+ {
+ rClass.Erase( 0, nPos+1 );
+ }
+
+ GetAppCharClass().toLower( rClass );
+ while( STRING_NOTFOUND != rClass.SearchAndReplace( '.', '-' ) )
+ ;
+ while( STRING_NOTFOUND != rClass.SearchAndReplace( ' ', '-' ) )
+ ;
+ while( STRING_NOTFOUND != rClass.SearchAndReplace( '_', '-' ) )
+ ;
+ }
+
+ return nDeep;
+}
+
+static USHORT GetCSS1Selector( const SwFmt *pFmt, String& rSelector,
+ USHORT& rRefPoolId )
+{
+ ByteString aToken;
+ String aClass;
+ String aPseudo;
+
+ USHORT nDeep = SwHTMLWriter::GetCSS1Selector( pFmt, aToken, aClass,
+ rRefPoolId, &aPseudo );
+ if( nDeep )
+ {
+ if( aToken.Len() )
+ rSelector = String( aToken, RTL_TEXTENCODING_ASCII_US );
+ else
+ rSelector.Erase();
+
+ if( aClass.Len() )
+ (rSelector += '.') += aClass;
+ if( aPseudo.Len() )
+ (rSelector += ':') += aPseudo;
+ }
+
+ return nDeep;
+}
+
+const SwFmt *SwHTMLWriter::GetTemplateFmt( USHORT nPoolFmtId,
+ IDocumentStylePoolAccess* pTemplate /*SwDoc *pTemplate*/)
+{
+ const SwFmt *pRefFmt = 0;
+
+ if( pTemplate )
+ {
+ ASSERT( !(USER_FMT & nPoolFmtId),
+ "In der Dok-Vorlage gibt es keine Benutzer-Vorlagen" );
+ if( POOLGRP_NOCOLLID & nPoolFmtId )
+ pRefFmt = pTemplate->GetCharFmtFromPool( nPoolFmtId );
+ else
+ pRefFmt = pTemplate->GetTxtCollFromPool( nPoolFmtId, false );
+ }
+
+ return pRefFmt;
+}
+
+const SwFmt *SwHTMLWriter::GetParentFmt( const SwFmt& rFmt, USHORT nDeep )
+{
+ ASSERT( nDeep != USHRT_MAX, "GetParent fuer HTML-Vorlage aufgerufen!" );
+ const SwFmt *pRefFmt = 0;
+
+ if( nDeep > 0 )
+ {
+ // hier wird die HTML-Tag-Vorlage, von der die Vorlage abgeleitet
+ // ist als Referenz geholt
+ pRefFmt = &rFmt;
+ for( USHORT i=nDeep; i>0; i-- )
+ pRefFmt = pRefFmt->DerivedFrom();
+
+ if( pRefFmt && pRefFmt->IsDefault() )
+ pRefFmt = 0;
+ }
+
+ return pRefFmt;
+}
+
+BOOL lcl_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 )
+{
+ return ((const SvxFontItem &)r1).GetFamilyName() ==
+ ((const SvxFontItem &)r2).GetFamilyName() &&
+ ((const SvxFontItem &)r1).GetFamily() ==
+ ((const SvxFontItem &)r2).GetFamily();
+}
+
+void SwHTMLWriter::SubtractItemSet( SfxItemSet& rItemSet,
+ const SfxItemSet& rRefItemSet,
+ BOOL bSetDefaults,
+ BOOL bClearSame,
+ const SfxItemSet *pRefScriptItemSet )
+{
+ ASSERT( bSetDefaults || bClearSame,
+ "SwHTMLWriter::SubtractItemSet: Bei diesen Flags passiert nix" );
+ SfxItemSet aRefItemSet( *rRefItemSet.GetPool(), rRefItemSet.GetRanges() );
+ aRefItemSet.Set( rRefItemSet );
+
+ // und mit dem Attr-Set der Vorlage vergleichen
+ SfxWhichIter aIter( rItemSet );
+ USHORT nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ const SfxPoolItem *pRefItem, *pItem;
+ BOOL bItemSet = ( SFX_ITEM_SET ==
+ rItemSet.GetItemState( nWhich, FALSE, &pItem) );
+ BOOL bRefItemSet;
+
+ if( pRefScriptItemSet )
+ {
+ switch( nWhich )
+ {
+ case RES_CHRATR_FONT:
+ case RES_CHRATR_FONTSIZE:
+ case RES_CHRATR_LANGUAGE:
+ case RES_CHRATR_POSTURE:
+ case RES_CHRATR_WEIGHT:
+ case RES_CHRATR_CJK_FONT:
+ case RES_CHRATR_CJK_FONTSIZE:
+ case RES_CHRATR_CJK_LANGUAGE:
+ case RES_CHRATR_CJK_POSTURE:
+ case RES_CHRATR_CJK_WEIGHT:
+ case RES_CHRATR_CTL_FONT:
+ case RES_CHRATR_CTL_FONTSIZE:
+ case RES_CHRATR_CTL_LANGUAGE:
+ case RES_CHRATR_CTL_POSTURE:
+ case RES_CHRATR_CTL_WEIGHT:
+ bRefItemSet = ( SFX_ITEM_SET ==
+ pRefScriptItemSet->GetItemState( nWhich, TRUE, &pRefItem) );
+ break;
+ default:
+ bRefItemSet = ( SFX_ITEM_SET ==
+ aRefItemSet.GetItemState( nWhich, FALSE, &pRefItem) );
+ break;
+ }
+ }
+ else
+ {
+ bRefItemSet = ( SFX_ITEM_SET ==
+ aRefItemSet.GetItemState( nWhich, FALSE, &pRefItem) );
+ }
+
+ if( bItemSet )
+ {
+ if( (bClearSame || pRefScriptItemSet) && bRefItemSet &&
+ ( *pItem == *pRefItem ||
+ ((RES_CHRATR_FONT == nWhich ||
+ RES_CHRATR_CJK_FONT == nWhich ||
+ RES_CHRATR_CTL_FONT == nWhich) &&
+ lcl_css1atr_equalFontItems( *pItem, *pRefItem )) ) )
+ {
+ // das Attribut ist mit dem gleichen Wert in beiden
+ // Vorlagen vorhanden und muss nicht ausgegeben werden
+ rItemSet.ClearItem( nWhich );
+ }
+ }
+ else
+ {
+ if( (bSetDefaults || pRefScriptItemSet) && bRefItemSet )
+ {
+ // das Attribut ist nur in der Referenz vorhanden. Das
+ // Default muss ggf. ausgegeben werden
+ rItemSet.Put( rItemSet.GetPool()->GetDefaultItem(nWhich) );
+ }
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void SwHTMLWriter::PrepareFontList( const SvxFontItem& rFontItem,
+ String& rNames,
+ sal_Unicode cQuote, BOOL bGeneric )
+{
+ rNames = aEmptyStr;
+ const String& rName = rFontItem.GetFamilyName();
+ BOOL bContainsKeyword = FALSE;
+ if( rName.Len() )
+ {
+ xub_StrLen nStrPos = 0;
+ while( nStrPos != STRING_NOTFOUND )
+ {
+ String aName = rName.GetToken( 0, ';', nStrPos );
+ aName.EraseTrailingChars().EraseLeadingChars();
+ if( !aName.Len() )
+ continue;
+
+ BOOL bIsKeyword = FALSE;
+ switch( aName.GetChar( 0 ) )
+ {
+ case 'c':
+ case 'C':
+ bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_cursive );
+ break;
+
+ case 'f':
+ case 'F':
+ bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_fantasy );
+ break;
+
+ case 'm':
+ case 'M':
+ bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_monospace );
+ break;
+
+ case 's':
+ case 'S':
+ bIsKeyword =
+ aName.EqualsIgnoreCaseAscii( sCSS1_PV_serif ) ||
+ aName.EqualsIgnoreCaseAscii( sCSS1_PV_sans_serif );
+ break;
+ }
+
+ bContainsKeyword |= bIsKeyword;
+
+ if( rNames.Len() )
+ rNames.AppendAscii( ", " );
+ if( cQuote && !bIsKeyword )
+ rNames += cQuote;
+ rNames += aName;
+ if( cQuote && !bIsKeyword )
+ rNames += cQuote;
+ }
+ }
+
+ if( !bContainsKeyword && bGeneric )
+ {
+ const sal_Char *pStr = 0;
+ switch( rFontItem.GetFamily() )
+ {
+ case FAMILY_ROMAN: pStr = sCSS1_PV_serif; break;
+ case FAMILY_SWISS: pStr = sCSS1_PV_sans_serif; break;
+ case FAMILY_SCRIPT: pStr = sCSS1_PV_cursive; break;
+ case FAMILY_DECORATIVE: pStr = sCSS1_PV_fantasy; break;
+ case FAMILY_MODERN: pStr = sCSS1_PV_monospace; break;
+ default:
+ ;
+ }
+
+ if( pStr )
+ {
+ if( rNames.Len() )
+ rNames.AppendAscii( ", " );
+ rNames.AppendAscii( pStr );
+ }
+ }
+}
+
+sal_Bool SwHTMLWriter::HasScriptDependentItems( const SfxItemSet& rItemSet,
+ sal_Bool bCheckDropCap )
+{
+ static sal_uInt16 aWhichIds[] =
+ {
+ RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT,
+ RES_CHRATR_FONTSIZE, RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CTL_FONTSIZE,
+ RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
+ RES_CHRATR_POSTURE, RES_CHRATR_CJK_POSTURE, RES_CHRATR_CTL_POSTURE,
+ RES_CHRATR_WEIGHT, RES_CHRATR_CJK_WEIGHT, RES_CHRATR_CTL_WEIGHT,
+ 0, 0, 0
+ };
+
+ for( sal_uInt16 i=0; aWhichIds[i]; i += 3 )
+ {
+ const SfxPoolItem *pItem = 0, *pItemCJK = 0, *pItemCTL = 0, *pTmp;
+ sal_uInt16 nItemCount = 0;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], sal_False,
+ &pTmp ) )
+ {
+ pItem = pTmp;
+ nItemCount++;
+ }
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i+1], sal_False,
+ &pTmp ) )
+ {
+ pItemCJK = pTmp;
+ nItemCount++;
+ }
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i+2], sal_False,
+ &pTmp ) )
+ {
+ pItemCTL = pTmp;
+ nItemCount++;
+ }
+
+ // If some of the items are set, but not all, we need script dependent
+ // styles
+ if( nItemCount > 0 && nItemCount < 3 )
+ return sal_True;
+
+ if( 3 == nItemCount )
+ {
+ // If all items are set, but some of them have different values,
+ // we need script dependent styles, too. For font items, we have
+ // to take care about their special HTML/CSS1 representation.
+ if( RES_CHRATR_FONT == aWhichIds[i] )
+ {
+ if( !lcl_css1atr_equalFontItems( *pItem, *pItemCJK ) ||
+ !lcl_css1atr_equalFontItems( *pItem, *pItemCTL ) ||
+ !lcl_css1atr_equalFontItems( *pItemCJK, *pItemCTL ) )
+ return sal_True;
+ }
+ else
+ {
+ if( !( *pItem == *pItemCJK ) ||
+ !( *pItem == *pItemCTL ) ||
+ !( *pItemCJK == *pItemCTL ) )
+ return sal_True;
+ }
+ }
+ }
+
+ const SfxPoolItem *pItem;
+ if( bCheckDropCap &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_PARATR_DROP, sal_True,
+ &pItem ) )
+ {
+ const SwFmtDrop *pDrop = (const SwFmtDrop *)pItem;
+ const SwCharFmt *pDCCharFmt = pDrop->GetCharFmt();
+ if( pDCCharFmt )
+ {
+ SfxItemSet aTstItemSet( *pDCCharFmt->GetAttrSet().GetPool(),
+ RES_CHRATR_FONT, RES_CHRATR_FONT,
+ RES_CHRATR_POSTURE, RES_CHRATR_POSTURE,
+ RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
+ RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT,
+ RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT,
+ RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONT,
+ RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT,
+ 0 );
+ aTstItemSet.Set( pDCCharFmt->GetAttrSet(), sal_True );
+ return HasScriptDependentItems( aTstItemSet, sal_False );
+ }
+ }
+
+ return sal_False;
+}
+
+static sal_Bool OutCSS1Rule( SwHTMLWriter& rHTMLWrt, const String& rSelector,
+ const SfxItemSet& rItemSet, sal_Bool bHasClass,
+ sal_Bool bCheckForPseudo )
+{
+ sal_Bool bScriptDependent = sal_False;
+ if( SwHTMLWriter::HasScriptDependentItems( rItemSet,
+ rHTMLWrt.IsHTMLMode(HTMLMODE_DROPCAPS) && bHasClass ) )
+ {
+ bScriptDependent = sal_True;
+ String aSelector( rSelector );
+
+ String aPseudo;
+ if( bCheckForPseudo )
+ {
+ xub_StrLen nPos = aSelector.SearchBackward( ':' );
+ if( STRING_NOTFOUND != nPos )
+ {
+ aPseudo = aSelector.Copy( nPos );
+ aSelector.Erase( nPos );
+ }
+ }
+
+ if( !bHasClass )
+ {
+ // If we are exporting styles for a tag we have to export a tag
+ // rule for all properties that aren't style dependent and
+ // some class rule for the additional style dependen properties
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &rSelector );
+ rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, FALSE );
+ }
+
+ SfxItemSet aScriptItemSet( *rItemSet.GetPool(),
+ RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
+ RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE,
+ RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
+ RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
+ 0 );
+ aScriptItemSet.Put( rItemSet );
+
+ String aNewSelector( aSelector );
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".western") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &aNewSelector );
+ rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, FALSE );
+ }
+
+ aNewSelector = aSelector;
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".cjk") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &aNewSelector );
+ rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, FALSE );
+ }
+
+ aNewSelector = aSelector;
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".ctl") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &aNewSelector );
+ rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, FALSE );
+ }
+ }
+ else
+ {
+ // If ther are script dependencies and we are derived from a tag,
+ // when we have to export a style dependent class for all
+ // scripts
+ String aNewSelector( aSelector );
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &aNewSelector );
+ rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, FALSE );
+ }
+
+ aNewSelector = aSelector;
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &aNewSelector );
+ rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, FALSE );
+ }
+
+ aNewSelector = aSelector;
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &aNewSelector );
+ rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, FALSE );
+ }
+ }
+ }
+ else
+ {
+ // If there are no script dependencies, when all items are
+ // exported in one step. For hyperlinks only, a script information
+ // must be there, because these two chr formats don't support
+ // script dependencies by now.
+ SwCSS1OutMode aMode( rHTMLWrt,
+ rHTMLWrt.nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &rSelector );
+ rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, FALSE );
+ }
+
+ return bScriptDependent;
+}
+
+static void OutCSS1DropCapRule(
+ SwHTMLWriter& rHTMLWrt, const String& rSelector,
+ const SwFmtDrop& rDrop, sal_Bool bHasClass,
+ sal_Bool bHasScriptDependencies )
+{
+ const SwCharFmt *pDCCharFmt = rDrop.GetCharFmt();
+ if( (bHasScriptDependencies && bHasClass) ||
+ (pDCCharFmt && SwHTMLWriter::HasScriptDependentItems( pDCCharFmt->GetAttrSet(), sal_False ) ) )
+ {
+ String aSelector( rSelector );
+
+ String aPseudo;
+ xub_StrLen nPos = aSelector.SearchBackward( ':' );
+ if( STRING_NOTFOUND != nPos )
+ {
+ aPseudo = aSelector.Copy( nPos );
+ aSelector.Erase( nPos );
+ }
+
+ if( !bHasClass )
+ {
+ // If we are exporting styles for a tag we have to export a tag
+ // rule for all properties that aren't style dependent and
+ // some class rule for the additional style dependen properties
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
+ TRUE, &rSelector );
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
+ }
+
+ SfxItemSet aScriptItemSet( rHTMLWrt.pDoc->GetAttrPool(),
+ RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
+ RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE,
+ RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
+ RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
+ 0 );
+ if( pDCCharFmt )
+ aScriptItemSet.Set( pDCCharFmt->GetAttrSet(), sal_True );
+
+ String aNewSelector( aSelector );
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".western") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
+ TRUE, &aNewSelector );
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet );
+ }
+
+ aNewSelector = aSelector;
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".cjk") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
+ TRUE, &aNewSelector );
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet );
+ }
+
+ aNewSelector = aSelector;
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".ctl") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
+ TRUE, &aNewSelector );
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop, &aScriptItemSet );
+ }
+ }
+ else
+ {
+ // If ther are script dependencies and we are derived from a tag,
+ // when we have to export a style dependent class for all
+ // scripts
+ String aNewSelector( aSelector );
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
+ TRUE, &aNewSelector );
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
+ }
+
+ aNewSelector = aSelector;
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
+ TRUE, &aNewSelector );
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
+ }
+
+ aNewSelector = aSelector;
+ aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
+ aNewSelector.Append( aPseudo );
+ {
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
+ TRUE, &aNewSelector );
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
+ }
+ }
+ }
+ else
+ {
+ // If there are no script dependencies, when all items are
+ // exported in one step. For hyperlinks only, a script information
+ // must be there, because these two chr formats don't support
+ // script dependencies by now.
+ SwCSS1OutMode aMode( rHTMLWrt,
+ rHTMLWrt.nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
+ TRUE, &rSelector );
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
+ }
+}
+
+static Writer& OutCSS1_SwFmt( Writer& rWrt, const SwFmt& rFmt,
+ IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ BOOL bCharFmt = FALSE;
+ switch( rFmt.Which() )
+ {
+ case RES_CHRFMT:
+ bCharFmt = TRUE;
+ break;
+
+ case RES_TXTFMTCOLL:
+ case RES_CONDTXTFMTCOLL:
+ // diese Vorlagen-Typen koennen exportiert werden
+ break;
+
+ default:
+ // und diese nicht
+ return rWrt;
+ }
+
+ // den Selector und die auszugebende Attr-Set-Tiefe ermitteln
+ String aSelector;
+ USHORT nRefPoolId = 0;
+ USHORT nDeep = GetCSS1Selector( &rFmt, aSelector, nRefPoolId );
+ if( !nDeep )
+ return rWrt; // von keiner HTML-Vorlage abgeleitet
+
+ USHORT nPoolFmtId = rFmt.GetPoolFmtId();
+
+ // Den auszugebenden Attr-Set bestimmen. Hier muessen 3 Faelle
+ // unterschieden werden:
+ // - HTML-Tag-Vorlagen (nDeep==USHRT_MAX):
+ // Es werden die Attrs ausgegeben
+ // - die in der Vorlage gesetzt sind, aber nicht im Original aus
+ // der HTML-Vorlage
+ // - die Default-Attrs fuer die Attrs, die im Original aus der
+ // HTML-Vorlage gesetzt sind, aber nicht in der vorliegeden Vorlage.
+ // - direkt von HTML-Vorlagen abgeleitete Vorlagen (nDeep==1):
+ // Es weren nur die Attribute des Vorlagen-Item-Set ohne seine
+ // Parents ausgegeben.
+ // - indirekt von HTML-Tag-Vorlagen abgeleitete Vorlagen (nDeep>1)
+ // Es werden die Attribute des Vorlagen-Item-Sets inkl. seiner Parents,
+ // aber ohne die Attribute, die in der HTML-Tag-Vorlage gesetzt sind,
+ // ausgegeben.
+
+ // einen Item-Set mit allen Attributen aus der Vorlage anlegen
+ // (ausser fuer nDeep==1)
+ const SfxItemSet& rFmtItemSet = rFmt.GetAttrSet();
+ SfxItemSet aItemSet( *rFmtItemSet.GetPool(), rFmtItemSet.GetRanges() );
+ aItemSet.Set( rFmtItemSet, TRUE ); // Was nDeep!=1 that is not working
+ // for script dependent items buts should
+ // not make a deifference for any other
+
+ BOOL bSetDefaults = TRUE, bClearSame = TRUE;
+ const SwFmt *pRefFmt = 0;
+ const SwFmt *pRefFmtScript = 0;
+ switch( nDeep )
+ {
+ case CSS1_FMT_ISTAG:
+ pRefFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
+ break;
+ case CSS1_FMT_CMPREF:
+ pRefFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pDoc );
+ pRefFmtScript = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
+ bClearSame = FALSE;
+ break;
+ default:
+ pRefFmt = SwHTMLWriter::GetParentFmt( rFmt, nDeep );
+ pRefFmtScript = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
+ bSetDefaults = FALSE;
+ break;
+ }
+
+ if( pRefFmt )
+ {
+ // Den Item-Set der Referenz-Vorlage (inkl. seiner Parents) vom
+ // ItemSet abziehen
+ SwHTMLWriter::SubtractItemSet( aItemSet, pRefFmt->GetAttrSet(),
+ bSetDefaults, bClearSame,
+ pRefFmtScript
+ ? &pRefFmtScript->GetAttrSet()
+ : 0 );
+
+ if( !bCharFmt )
+ {
+ const SvxULSpaceItem& rULItem = pRefFmt->GetULSpace();
+ rHTMLWrt.nDfltTopMargin = rULItem.GetUpper();
+ rHTMLWrt.nDfltBottomMargin = rULItem.GetLower();
+ }
+ }
+ else if( CSS1_FMT_ISTAG==nDeep && !bCharFmt )
+ {
+ // die Default-Abstaende nach oben und unten setzen (fuer den
+ // Fall, dass es keine Vorlage als Referenz gibt)
+ rHTMLWrt.nDfltTopMargin = 0;
+ rHTMLWrt.nDfltBottomMargin = HTML_PARSPACE;
+ if( USER_FMT & nPoolFmtId )
+ {
+ // Benutzer-Vorlagen
+ const String& rNm = rFmt.GetName();
+ switch( rNm.GetChar(0) )
+ {
+ case 'D': if( rNm.EqualsAscii("DD 1") || rNm.EqualsAscii("DT 1") )
+ rHTMLWrt.nDfltBottomMargin = 0;
+ break;
+ case 'L': if(rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_listing) )
+ rHTMLWrt.nDfltBottomMargin = 0;
+ break;
+ case 'P': if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_preformtxt) )
+ rHTMLWrt.nDfltBottomMargin = 0;
+ break;
+ case 'X': if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_xmp) )
+ rHTMLWrt.nDfltBottomMargin = 0;
+ break;
+ }
+ }
+ else
+ {
+ // Pool-Vorlagen
+ switch( nPoolFmtId )
+ {
+ case RES_POOLCOLL_HEADLINE1:
+ case RES_POOLCOLL_HEADLINE2:
+ case RES_POOLCOLL_HEADLINE3:
+ case RES_POOLCOLL_HEADLINE4:
+ case RES_POOLCOLL_HEADLINE5:
+ case RES_POOLCOLL_HEADLINE6:
+ rHTMLWrt.nDfltTopMargin = HTML_HEADSPACE;
+ break;
+ case RES_POOLCOLL_SENDADRESS:
+ case RES_POOLCOLL_HTML_DT:
+ case RES_POOLCOLL_HTML_DD:
+ case RES_POOLCOLL_HTML_PRE:
+ rHTMLWrt.nDfltBottomMargin = 0;
+ break;
+ }
+ }
+ }
+
+ // wo nicht auszugeben ist ...
+ if( !aItemSet.Count() )
+ return rWrt;
+
+ // There is no support for script dependent hyperlinks by now.
+ sal_Bool bCheckForPseudo = sal_False;
+ if( bCharFmt &&
+ (RES_POOLCHR_INET_NORMAL==nRefPoolId ||
+ RES_POOLCHR_INET_VISIT==nRefPoolId) )
+ bCheckForPseudo = sal_True;
+
+
+ // jetzt die Attribute (inkl. Selektor) ausgeben
+ sal_Bool bHasScriptDependencies = sal_False;
+ if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, CSS1_FMT_ISTAG != nDeep,
+ bCheckForPseudo ) )
+ {
+ if( bCharFmt )
+ rHTMLWrt.aScriptTextStyles.Insert( new String( rFmt.GetName() ) );
+ else
+ {
+ if( nPoolFmtId==RES_POOLCOLL_TEXT )
+ rHTMLWrt.aScriptParaStyles.Insert
+ (new String( pDoc->GetTxtCollFromPool
+ ( RES_POOLCOLL_STANDARD, false )->GetName()
+ ) );
+ rHTMLWrt.aScriptParaStyles.Insert( new String( rFmt.GetName() ) );
+ }
+ bHasScriptDependencies = sal_True;
+ }
+
+ if( nPoolFmtId==RES_POOLCOLL_TEXT && !rHTMLWrt.bFirstCSS1Property )
+ rHTMLWrt.bPoolCollTextModified = TRUE;
+
+ // Drop-Caps ausgeben
+ const SfxPoolItem *pItem;
+ if( rHTMLWrt.IsHTMLMode(HTMLMODE_DROPCAPS) &&
+ SFX_ITEM_SET==aItemSet.GetItemState( RES_PARATR_DROP, FALSE, &pItem ))
+ {
+ String sOut( aSelector );
+ sOut.Append( ':');
+ sOut.AppendAscii( sCSS1_first_letter );
+ const SwFmtDrop *pDrop = (const SwFmtDrop *)pItem;
+ OutCSS1DropCapRule( rHTMLWrt, sOut, *pDrop, CSS1_FMT_ISTAG != nDeep, bHasScriptDependencies );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rPageDesc,
+ IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate,
+ USHORT nRefPoolId, BOOL bExtRef,
+ BOOL bPseudo )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SwPageDesc* pRefPageDesc = 0;
+ if( !bExtRef )
+ pRefPageDesc = pDoc->GetPageDescFromPool( nRefPoolId, false );
+ else if( pTemplate )
+ pRefPageDesc = pTemplate->GetPageDescFromPool( nRefPoolId, false );
+
+ String aSelector( '@' );
+ aSelector.AppendAscii( sCSS1_page );
+
+ if( bPseudo )
+ {
+ const sal_Char *pPseudo = 0;
+ switch( rPageDesc.GetPoolFmtId() )
+ {
+ case RES_POOLPAGE_FIRST: pPseudo = sCSS1_first; break;
+ case RES_POOLPAGE_LEFT: pPseudo = sCSS1_left; break;
+ case RES_POOLPAGE_RIGHT: pPseudo = sCSS1_right; break;
+ }
+ if( pPseudo )
+ {
+ aSelector.Append( ':' );
+ aSelector.AppendAscii( pPseudo );
+ }
+ }
+
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE_ON|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &aSelector );
+
+ // Die Groesse: Wenn sie sich nur durch das Landscape-Flag unterscheidet,
+ // wird nur Portrait oder Landscape exportiert. Sonst wird die Groesse
+ // exportiert.
+ BOOL bRefLandscape = pRefPageDesc ? pRefPageDesc->GetLandscape() : FALSE;
+ Size aRefSz;
+ const Size& rSz = rPageDesc.GetMaster().GetFrmSize().GetSize();
+ if( pRefPageDesc )
+ {
+ aRefSz = pRefPageDesc->GetMaster().GetFrmSize().GetSize();
+ if( bRefLandscape != rPageDesc.GetLandscape() )
+ {
+ long nTmp = aRefSz.Height();
+ aRefSz.Height() = aRefSz.Width();
+ aRefSz.Width() = nTmp;
+ }
+ }
+
+ // Boeser uebler Hack: Auf der Seiten-Tabpage gibt es leichte
+ // Rundungsfehler bei der Seitengroesse. Unter anderem wegen bug
+ // 25535 wird dummerweise auch noch immer Size-Item vom Dialog geputtet,
+ // auch wenn man gar nichts geaendert hat. Folge: Sobald man einmal im
+ // Seiten-Dialog war und ihn mit OK verlassen hat, bekommt man eine
+ // neue Seitengroesse, die dann hier exportiert wuerde. Um das
+ // vermeiden erlauben wir hier kleine Abweichungen.
+ if( Abs( rSz.Width() - aRefSz.Width() ) <= 2 &&
+ Abs( rSz.Height() - aRefSz.Height() ) <= 2 )
+ {
+ if( bRefLandscape != rPageDesc.GetLandscape() )
+ {
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_size,
+ rPageDesc.GetLandscape() ? sCSS1_PV_landscape
+ : sCSS1_PV_portrait );
+ }
+ }
+ else
+ {
+ ByteString sVal;
+ AddUnitPropertyValue( rSz.Width(), rHTMLWrt.GetCSS1Unit(), sVal );
+ sVal += ' ';
+ AddUnitPropertyValue( rSz.Height(), rHTMLWrt.GetCSS1Unit(), sVal );
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_size, sVal );
+ }
+
+ // Die Abstand-Attribute koennen auf gwohnte Weise exportiert werden
+ const SwFrmFmt &rMaster = rPageDesc.GetMaster();
+ SfxItemSet aItemSet( *rMaster.GetAttrSet().GetPool(),
+ RES_LR_SPACE, RES_UL_SPACE );
+ aItemSet.Set( rMaster.GetAttrSet(), TRUE );
+
+ if( pRefPageDesc )
+ {
+ SwHTMLWriter::SubtractItemSet( aItemSet,
+ pRefPageDesc->GetMaster().GetAttrSet(),
+ TRUE );
+ }
+
+ OutCSS1_SvxULSpace_SvxLRSpace( rWrt, aItemSet, FALSE );
+
+ // Wenn fuer einen Pseudo-Selektor keine Property ausgegeben wurde, muessen
+ // wir trotzdem etwas ausgeben, damit beim Import die entsprechende
+ // Vorlage angelegt wird.
+ if( rHTMLWrt.bFirstCSS1Property && bPseudo )
+ {
+ rHTMLWrt.OutNewLine();
+ ByteString sTmp( aSelector, rHTMLWrt.eDestEnc );
+ rWrt.Strm() << sTmp.GetBuffer() << " {";
+ rHTMLWrt.bFirstCSS1Property = FALSE;
+ }
+
+ if( !rHTMLWrt.bFirstCSS1Property )
+ rWrt.Strm() << sCSS1_rule_end;
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SwFtnInfo( Writer& rWrt, const SwEndNoteInfo& rInfo,
+ SwDoc *pDoc, USHORT nNotes, BOOL bEndNote )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ String aSelector;
+
+ if( nNotes > 0 )
+ {
+ aSelector.AssignAscii( OOO_STRING_SVTOOLS_HTML_anchor );
+ aSelector.Append( '.');
+ aSelector.AppendAscii( bEndNote ? OOO_STRING_SVTOOLS_HTML_sdendnote_anc
+ : OOO_STRING_SVTOOLS_HTML_sdfootnote_anc );
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
+ TRUE, &aSelector );
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size,
+ sHTML_FTN_fontheight );
+ rHTMLWrt.Strm() << sCSS1_rule_end;
+ }
+
+ const SwCharFmt *pSymCharFmt = rInfo.GetCharFmt( *pDoc );
+ if( pSymCharFmt )
+ {
+ const SfxItemSet& rFmtItemSet = pSymCharFmt->GetAttrSet();
+ SfxItemSet aItemSet( *rFmtItemSet.GetPool(), rFmtItemSet.GetRanges() );
+ aItemSet.Set( rFmtItemSet, TRUE );
+
+ // Wenn es Fuss- bzw. Endnoten gibt, dann muessen alles Attribute
+ // ausgegeben werden, damit Netscape das Dokument richtig anzeigt.
+ // Anderenfalls genuegt es, die Unterschiede zur Fuss-/Endnoten
+ // Vorlage rauszuschreiben.
+ if( nNotes == 0 && rHTMLWrt.pTemplate )
+ {
+ SwFmt *pRefFmt = rHTMLWrt.pTemplate->GetCharFmtFromPool(
+ static_cast< sal_uInt16 >(bEndNote ? RES_POOLCHR_ENDNOTE : RES_POOLCHR_FOOTNOTE) );
+ if( pRefFmt )
+ SwHTMLWriter::SubtractItemSet( aItemSet, pRefFmt->GetAttrSet(),
+ TRUE );
+ }
+ if( aItemSet.Count() )
+ {
+ aSelector.AssignAscii( OOO_STRING_SVTOOLS_HTML_anchor );
+ aSelector.Append( '.');
+ aSelector.AppendAscii( bEndNote ? OOO_STRING_SVTOOLS_HTML_sdendnote_sym
+ : OOO_STRING_SVTOOLS_HTML_sdfootnote_sym );
+ if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, sal_True, sal_False ))
+ rHTMLWrt.aScriptTextStyles.Insert( new String( pSymCharFmt->GetName() ) );
+ }
+ }
+
+ return rWrt;
+}
+
+Writer& OutCSS1_BodyTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet,
+ String aEmbBGGrfName )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
+ CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_BODY );
+
+
+ // Es werden nur die Attribute der Seiten-Vorlage ausgegeben.
+ // Die Attribute der Standard-Absatz-Vorlage werden schon beim
+ // Export der Absatz-Vorlagen beruecksichtigt.
+
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, FALSE,
+ &pItem ) )
+ {
+ OutCSS1_SvxBrush( rWrt, *pItem, CSS1_BACKGROUND_PAGE,
+ &aEmbBGGrfName );
+ }
+
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, FALSE,
+ &pItem ))
+ {
+ OutCSS1_SvxBox( rWrt, *pItem );
+ }
+
+ if( !rHTMLWrt.bFirstCSS1Property )
+ {
+ // wenn eine Property als Bestandteil einer Style-Option
+ // ausgegeben wurde, muss die Optiomn noch beendet werden
+ rWrt.Strm() << '\"';
+ }
+
+ return rWrt;
+}
+
+Writer& OutCSS1_ParaTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ SwCSS1OutMode aMode( rHTMLWrt, rHTMLWrt.nCSS1Script|CSS1_OUTMODE_STYLE_OPT |
+ CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA );
+ rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, FALSE );
+
+ return rWrt;
+}
+
+Writer& OutCSS1_HintSpanTag( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_SPAN_TAG |
+ CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_HINT );
+
+ Out( aCSS1AttrFnTab, rHt, rWrt );
+
+ if( !rHTMLWrt.bFirstCSS1Property && rHTMLWrt.bTagOn )
+ rWrt.Strm() << sCSS1_span_tag_end;
+
+ return rWrt;
+}
+
+Writer& OutCSS1_HintStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
+ CSS1_OUTMODE_ENCODE|
+ CSS1_OUTMODE_HINT );
+
+ Out( aCSS1AttrFnTab, rHt, rWrt );
+
+ if( !rHTMLWrt.bFirstCSS1Property )
+ rWrt.Strm() << '\"';
+
+ return rWrt;
+}
+
+// Wrapper fuer die Ausgabe von Tabellen-Hintergruenden
+Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
+ CSS1_OUTMODE_ENCODE|
+ CSS1_OUTMODE_TABLEBOX );
+ OutCSS1_SvxBrush( rWrt, rHt, CSS1_BACKGROUND_TABLE, 0 );
+
+ if( !rHTMLWrt.bFirstCSS1Property )
+ rWrt.Strm() << '\"';
+
+ return rWrt;
+}
+
+
+Writer& OutCSS1_NumBulListStyleOpt( Writer& rWrt, const SwNumRule& rNumRule,
+ BYTE nLevel )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT |
+ CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA );
+
+ const SwNumFmt& rNumFmt = rNumRule.Get( nLevel );
+
+ long nLSpace = rNumFmt.GetAbsLSpace();
+ long nFirstLineOffset = rNumFmt.GetFirstLineOffset();
+ long nDfltFirstLineOffset = HTML_NUMBUL_INDENT;
+ if( nLevel > 0 )
+ {
+ const SwNumFmt& rPrevNumFmt = rNumRule.Get( nLevel-1 );
+ nLSpace -= rPrevNumFmt.GetAbsLSpace();
+ nDfltFirstLineOffset = rPrevNumFmt.GetFirstLineOffset();
+ }
+
+ if( rHTMLWrt.IsHTMLMode(HTMLMODE_LSPACE_IN_NUMBUL) &&
+ nLSpace != HTML_NUMBUL_MARGINLEFT )
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLSpace );
+
+ if( rHTMLWrt.IsHTMLMode(HTMLMODE_FRSTLINE_IN_NUMBUL) &&
+ nFirstLineOffset != nDfltFirstLineOffset )
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent, nFirstLineOffset );
+
+ if( !rHTMLWrt.bFirstCSS1Property )
+ rWrt.Strm() << '\"';
+
+ return rWrt;
+}
+
+//-----------------------------------------------------------------------
+
+void SwHTMLWriter::OutCSS1_FrmFmtOptions( const SwFrmFmt& rFrmFmt,
+ sal_uInt32 nFrmOpts,
+ const SdrObject *pSdrObj,
+ const SfxItemSet *pItemSet )
+{
+ SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
+ CSS1_OUTMODE_ENCODE|
+ CSS1_OUTMODE_FRAME );
+
+ const SwFmtHoriOrient& rHoriOri = rFrmFmt.GetHoriOrient();
+ SvxLRSpaceItem aLRItem( rFrmFmt.GetLRSpace() );
+ SvxULSpaceItem aULItem( rFrmFmt.GetULSpace() );
+ if( nFrmOpts & HTML_FRMOPT_S_ALIGN )
+ {
+ const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
+ switch( rAnchor.GetAnchorId() )
+ {
+ case FLY_AT_PARA:
+ case FLY_AT_CHAR:
+ if( text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
+ text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
+ {
+ if( !(nFrmOpts & HTML_FRMOPT_ALIGN) )
+ {
+ // float
+ const sal_Char *pStr = text::HoriOrientation::RIGHT==rHoriOri.GetHoriOrient()
+ ? sCSS1_PV_right
+ : sCSS1_PV_left;
+ OutCSS1_PropertyAscii( sCSS1_P_float, pStr );
+ }
+ break;
+ }
+
+ case FLY_AT_PAGE:
+ case FLY_AT_FLY:
+ {
+ // position
+ OutCSS1_PropertyAscii( sCSS1_P_position, sCSS1_PV_absolute );
+
+ // Fuer top/left muessen die Abstaende des Rahmens von
+ // der Position abgezogen werden, da sie in CSS1 noch
+ // zur Position addiert werden.
+ // Das funktioniert auch fuer automatisch ausgerichtete
+ // Rahmen, obwohl der Abstand da ja auch im Writer noch
+ // addiert wird. Denn auch in diesem Fall enthalten
+ // die Orient-Attribute die korrekte Position
+
+ // top
+ long nXPos=0, nYPos=0;
+ BOOL bOutXPos = FALSE, bOutYPos = FALSE;
+ if( RES_DRAWFRMFMT == rFrmFmt.Which() )
+ {
+ ASSERT( pSdrObj, "Kein SdrObject uebergeben. Ineffizient" );
+ if( !pSdrObj )
+ pSdrObj = rFrmFmt.FindSdrObject();
+ ASSERT( pSdrObj, "Wo ist das SdrObject" );
+ if( pSdrObj )
+ {
+ Point aPos( pSdrObj->GetRelativePos() );
+ nXPos = aPos.A();
+ nYPos = aPos.B();
+ }
+ bOutXPos = bOutYPos = TRUE;
+ }
+ else
+ {
+ bOutXPos = text::RelOrientation::CHAR != rHoriOri.GetRelationOrient();
+ nXPos = text::HoriOrientation::NONE == rHoriOri.GetHoriOrient()
+ ? rHoriOri.GetPos() : 0;
+
+ const SwFmtVertOrient& rVertOri = rFrmFmt.GetVertOrient();
+ bOutYPos = text::RelOrientation::CHAR != rVertOri.GetRelationOrient();
+ nYPos = text::VertOrientation::NONE == rVertOri.GetVertOrient()
+ ? rVertOri.GetPos() : 0;
+ }
+
+ if( bOutYPos )
+ {
+ if( IsHTMLMode( HTMLMODE_FLY_MARGINS) )
+ {
+ nYPos -= aULItem.GetUpper();
+ if( nYPos < 0 )
+ {
+ aULItem.SetUpper( (USHORT)(aULItem.GetUpper() + nYPos) );
+ nYPos = 0;
+ }
+ }
+
+ OutCSS1_UnitProperty( sCSS1_P_top, nYPos );
+ }
+
+ if( bOutXPos )
+ {
+ // left
+ if( IsHTMLMode( HTMLMODE_FLY_MARGINS) )
+ {
+ nXPos -= aLRItem.GetLeft();
+ if( nXPos < 0 )
+ {
+ aLRItem.SetLeft( (USHORT)(aLRItem.GetLeft() + nXPos) );
+ nXPos = 0;
+ }
+ }
+
+ OutCSS1_UnitProperty( sCSS1_P_left, nXPos );
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ // width/height
+ if( nFrmOpts & HTML_FRMOPT_S_SIZE )
+ {
+ if( RES_DRAWFRMFMT == rFrmFmt.Which() )
+ {
+ ASSERT( pSdrObj, "Kein SdrObject uebergeben. Ineffizient" );
+ if( !pSdrObj )
+ pSdrObj = rFrmFmt.FindSdrObject();
+ ASSERT( pSdrObj, "Wo ist das SdrObject" );
+ if( pSdrObj )
+ {
+ Size aTwipSz( pSdrObj->GetLogicRect().GetSize() );
+ if( nFrmOpts & HTML_FRMOPT_S_WIDTH )
+ {
+ if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
+ OutCSS1_PixelProperty( sCSS1_P_width, aTwipSz.Width(),
+ FALSE );
+ else
+ OutCSS1_UnitProperty( sCSS1_P_width, aTwipSz.Width() );
+ }
+ if( nFrmOpts & HTML_FRMOPT_S_HEIGHT )
+ {
+ if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
+ OutCSS1_PixelProperty( sCSS1_P_height, aTwipSz.Height(),
+ TRUE );
+ else
+ OutCSS1_UnitProperty( sCSS1_P_height, aTwipSz.Height() );
+ }
+ }
+ }
+ else
+ {
+ ASSERT( HTML_FRMOPT_ABSSIZE & nFrmOpts,
+ "Absolute Groesse wird exportiert" );
+ ASSERT( HTML_FRMOPT_ANYSIZE & nFrmOpts,
+ "Jede Groesse wird exportiert" );
+ USHORT nMode = 0;
+ if( nFrmOpts & HTML_FRMOPT_S_WIDTH )
+ nMode |= CSS1_FRMSIZE_WIDTH;
+ if( nFrmOpts & HTML_FRMOPT_S_HEIGHT )
+ nMode |= (CSS1_FRMSIZE_MINHEIGHT|CSS1_FRMSIZE_FIXHEIGHT);
+ if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
+ nMode |= CSS1_FRMSIZE_PIXEL;
+
+ OutCSS1_SwFmtFrmSize( *this, rFrmFmt.GetFrmSize(), nMode );
+ }
+ }
+
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+ // margin-*
+ if( (nFrmOpts & HTML_FRMOPT_S_SPACE) &&
+ IsHTMLMode( HTMLMODE_FLY_MARGINS) )
+ {
+ const SvxLRSpaceItem *pLRItem = 0;
+ const SvxULSpaceItem *pULItem = 0;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, TRUE ) )
+ pLRItem = &aLRItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, TRUE ) )
+ pULItem = &aULItem;
+ if( pLRItem || pULItem )
+ OutCSS1_SvxULSpace_SvxLRSpace( *this, pULItem, pLRItem );
+ }
+
+ // border
+ if( nFrmOpts & HTML_FRMOPT_S_BORDER )
+ {
+ const SfxPoolItem* pItem;
+ if( nFrmOpts & HTML_FRMOPT_S_NOBORDER )
+ OutCSS1_SvxBox( *this, rFrmFmt.GetBox() );
+ else if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOX, TRUE, &pItem ) )
+ OutCSS1_SvxBox( *this, *pItem );
+ }
+
+ // background (wenn, dann muss auch eine Farbe ausgegeben werden)
+ if( nFrmOpts & HTML_FRMOPT_S_BACKGROUND )
+ OutCSS1_FrmFmtBackground( rFrmFmt );
+
+ if( pItemSet )
+ OutCSS1_SfxItemSet( *pItemSet, FALSE );
+
+ if( !bFirstCSS1Property )
+ Strm() << '\"';
+}
+
+void SwHTMLWriter::OutCSS1_TableFrmFmtOptions( const SwFrmFmt& rFrmFmt )
+{
+ SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
+ CSS1_OUTMODE_ENCODE|
+ CSS1_OUTMODE_TABLE );
+
+ const SfxPoolItem *pItem;
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, FALSE, &pItem ) )
+ OutCSS1_SvxBrush( *this, *pItem, CSS1_BACKGROUND_TABLE, 0 );
+
+ if( IsHTMLMode( HTMLMODE_PRINT_EXT ) )
+ OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( *this, rItemSet, FALSE );
+
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_LAYOUT_SPLIT, FALSE, &pItem ) )
+ OutCSS1_SwFmtLayoutSplit( *this, *pItem );
+
+ if( !bFirstCSS1Property )
+ Strm() << '\"';
+}
+
+void SwHTMLWriter::OutCSS1_SectionFmtOptions( const SwFrmFmt& rFrmFmt )
+{
+ SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
+ CSS1_OUTMODE_ENCODE|
+ CSS1_OUTMODE_SECTION );
+
+ const SfxPoolItem *pItem;
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, FALSE, &pItem ) )
+ OutCSS1_SvxBrush( *this, *pItem, CSS1_BACKGROUND_SECTION, 0 );
+
+ if( !bFirstCSS1Property )
+ Strm() << '\"';
+}
+
+static BOOL OutCSS1_FrmFmtBrush( SwHTMLWriter& rWrt,
+ const SvxBrushItem& rBrushItem )
+{
+ BOOL bWritten = FALSE;
+ /// OD 02.09.2002 #99657#
+ /// output brush of frame format, if its background color is not "no fill"/"auto fill"
+ /// or it has a background graphic.
+ if( rBrushItem.GetColor() != COL_TRANSPARENT ||
+ 0 != rBrushItem.GetGraphicLink() ||
+ 0 != rBrushItem.GetGraphicPos() )
+ {
+ OutCSS1_SvxBrush( rWrt, rBrushItem, CSS1_BACKGROUND_FLY, 0 );
+ bWritten = TRUE;
+ }
+ return bWritten;
+}
+
+void SwHTMLWriter::OutCSS1_FrmFmtBackground( const SwFrmFmt& rFrmFmt )
+{
+ // Wenn der Rahmen selbst einen Hintergrund hat, wird der ausgegeben.
+ if( OutCSS1_FrmFmtBrush( *this, rFrmFmt.GetBackground() ) )
+ return;
+
+ // Wenn der Rahmen nicht seitengebunden ist, wird sonst muss der
+ // Hintergrund vom Anker betrachtet
+ const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
+ RndStdIds eAnchorId = rAnchor.GetAnchorId();
+ const SwPosition *pAnchorPos = rAnchor.GetCntntAnchor();
+ if (FLY_AT_PAGE != eAnchorId && pAnchorPos)
+ {
+ const SwNode& rNode = pAnchorPos->nNode.GetNode();
+ if( rNode.IsCntntNode() )
+ {
+ // Wenn der Rahmen in einem Content-Node verankert ist,
+ // wird der Hintergrund von Content-Node ausgegeben, wenn
+ // der einen hat.
+ if( OutCSS1_FrmFmtBrush( *this,
+ rNode.GetCntntNode()->GetSwAttrSet().GetBackground()) )
+ return;
+
+ // Sonst koennen wir evtl. auch in einer Tabelle stehen
+ const SwTableNode *pTableNd = rNode.FindTableNode();
+ if( pTableNd )
+ {
+ const SwStartNode *pBoxSttNd = rNode.FindTableBoxStartNode();
+ const SwTableBox *pBox =
+ pTableNd->GetTable().GetTblBox( pBoxSttNd->GetIndex() );
+
+ // Wenn die Box einen Hintergrund hat, nehmen wir den.
+ if( OutCSS1_FrmFmtBrush( *this,
+ pBox->GetFrmFmt()->GetBackground() ) )
+ return;
+
+ // Sonst betrachten wir den der Lines
+ const SwTableLine *pLine = pBox->GetUpper();
+ while( pLine )
+ {
+ if( OutCSS1_FrmFmtBrush( *this,
+ pLine->GetFrmFmt()->GetBackground() ) )
+ return;
+ pBox = pLine->GetUpper();
+ pLine = pBox ? pBox->GetUpper() : 0;
+ }
+
+ // Wenn da auch nichts war den der Tabelle.
+ if( OutCSS1_FrmFmtBrush( *this,
+ pTableNd->GetTable().GetFrmFmt()->GetBackground() ) )
+ return;
+ }
+
+ }
+
+ // Wenn der Anker wieder in einem Fly-Frame steht, dann
+ // wird der Hintergrund des Fly-Frames ausgegeben.
+ const SwFrmFmt *pFrmFmt = rNode.GetFlyFmt();
+ if( pFrmFmt )
+ {
+ OutCSS1_FrmFmtBackground( *pFrmFmt );
+ return;
+ }
+ }
+
+ // Schliesslich bleibt noch der Hintergrund der Seite uebrig und als
+ // letzte Rettung das Item der Config.
+ ASSERT( pCurrPageDesc, "Keine Seiten-Vorlage gemerkt" );
+ if( !OutCSS1_FrmFmtBrush( *this,
+ pCurrPageDesc->GetMaster().GetBackground() ) )
+ {
+ Color aColor( COL_WHITE );
+
+ // Die Hintergrund-Farbe wird normalerweise nur in Browse-Mode
+ // benutzt. Wir benutzen si bei einem HTML-Dokument immer und
+ // bei einem Text-Dokument nur, wenn es im Browse-Mode angezeigt
+ // wird.
+ if( pDoc->get(IDocumentSettingAccess::HTML_MODE) ||
+ pDoc->get(IDocumentSettingAccess::BROWSE_MODE))
+ {
+ ViewShell *pVSh = 0;
+ pDoc->GetEditShell( &pVSh );
+ if ( pVSh &&
+ COL_TRANSPARENT != pVSh->GetViewOptions()->GetRetoucheColor().GetColor())
+ aColor = pVSh->GetViewOptions()->GetRetoucheColor().GetColor();
+ }
+
+ ByteString sOut;
+ GetCSS1Color( aColor, sOut );
+ OutCSS1_PropertyAscii( sCSS1_P_background, sOut );
+ }
+}
+
+//-----------------------------------------------------------------------
+
+static Writer& OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( Writer& rWrt,
+ const SvxUnderlineItem *pUItem,
+ const SvxOverlineItem *pOItem,
+ const SvxCrossedOutItem *pCOItem,
+ const SvxBlinkItem *pBItem )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ BOOL bNone = FALSE;
+
+ const sal_Char *pUStr = 0;
+ if( pUItem )
+ {
+ switch( pUItem->GetLineStyle() )
+ {
+ case UNDERLINE_NONE:
+ bNone = TRUE;
+ break;
+ case UNDERLINE_DONTKNOW:
+ break;
+ default:
+ if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ {
+ // das geht auch in HTML und muss nicht als STYLE-Option
+ // und darf nicht als Hint geschrieben werden
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "Underline als Hint schreiben?" );
+ pUStr = sCSS1_PV_underline;
+ }
+ break;
+ }
+ }
+
+ const sal_Char *pOStr = 0;
+ if( pOItem )
+ {
+ switch( pOItem->GetLineStyle() )
+ {
+ case UNDERLINE_NONE:
+ bNone = TRUE;
+ break;
+ case UNDERLINE_DONTKNOW:
+ break;
+ default:
+ if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ {
+ // das geht auch in HTML und muss nicht als STYLE-Option
+ // und darf nicht als Hint geschrieben werden
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "Overline als Hint schreiben?" );
+ pOStr = sCSS1_PV_overline;
+ }
+ break;
+ }
+ }
+
+ const sal_Char *pCOStr = 0;
+ if( pCOItem )
+ {
+ switch( pCOItem->GetStrikeout() )
+ {
+ case STRIKEOUT_NONE:
+ bNone = TRUE;
+ break;
+ case STRIKEOUT_DONTKNOW:
+ break;
+ default:
+ if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ {
+ // das geht auch in HTML und muss nicht als STYLE-Option
+ // und darf nicht als Hint geschrieben werden
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "CrossedOut als Hint schreiben?" );
+ pCOStr = sCSS1_PV_line_through;
+ }
+ break;
+ }
+ }
+
+ const sal_Char *pBStr = 0;
+ if( pBItem && rHTMLWrt.IsHTMLMode(HTMLMODE_BLINK) )
+ {
+ if( !pBItem->GetValue() )
+ {
+ bNone = TRUE;
+ }
+ else if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ {
+ // das geht auch in HTML und muss nicht als STYLE-Option
+ // und darf nicht als Hint geschrieben werden
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "Blink als Hint schreiben?" );
+ pBStr = sCSS1_PV_blink;
+ }
+ }
+
+ ByteString sOut;
+ if( pUStr )
+ sOut.Append( pUStr );
+
+ if( pOStr )
+ {
+ if( sOut.Len() )
+ sOut += ' ';
+
+ sOut.Append( pOStr );
+ }
+
+ if( pCOStr )
+ {
+ if( sOut.Len() )
+ sOut += ' ';
+
+ sOut.Append( pCOStr );
+ }
+
+ if( pBStr )
+ {
+ if( sOut.Len() )
+ sOut += ' ';
+
+ sOut.Append( pBStr );
+ }
+
+ if( sOut.Len() )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sOut );
+ else if( bNone )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sCSS1_PV_none );
+
+ return rWrt;
+}
+
+
+static Writer& OutCSS1_SvxCaseMap( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ if( !rHTMLWrt.IsHTMLMode(HTMLMODE_SMALL_CAPS) )
+ return rWrt;
+
+ const sal_Char *pStr = 0;
+ switch( ((const SvxCaseMapItem&)rHt).GetCaseMap() )
+ {
+ case SVX_CASEMAP_NOT_MAPPED: pStr = sCSS1_PV_normal; break;
+ case SVX_CASEMAP_KAPITAELCHEN: pStr = sCSS1_PV_small_caps; break;
+ default:
+ ;
+ }
+
+ if( pStr )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, pStr );
+
+ return rWrt;
+}
+
+
+static Writer& OutCSS1_SvxColor( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Farben muessen nicht in der Style-Option ausgegeben werden.
+ if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) &&
+ !rHTMLWrt.bCfgPreferStyles )
+ return rWrt;
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "Farbe wirklich als Hint ausgeben?" );
+
+ Color aColor( ((const SvxColorItem&)rHt).GetValue() );
+ if( COL_AUTO == aColor.GetColor() )
+ aColor.SetColor( COL_BLACK );
+
+ ByteString sOut;
+ GetCSS1Color( aColor, sOut );
+
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_color, sOut );
+
+ return rWrt;
+}
+
+
+static Writer& OutCSS1_SvxCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ // Mit dieser Methode werden nur Hints ausgegeben!
+ // Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.
+
+ if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
+ OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
+ 0, 0, (const SvxCrossedOutItem *)&rHt, 0 );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxFont( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Fonts muessen nicht in der Style-Option ausgegeben werden.
+ if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ return rWrt;
+
+ sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
+ switch( rHt.Which() )
+ {
+ case RES_CHRATR_CJK_FONT: nScript = CSS1_OUTMODE_CJK; break;
+ case RES_CHRATR_CTL_FONT: nScript = CSS1_OUTMODE_CTL; break;
+ }
+ if( !rHTMLWrt.IsCSS1Script( nScript ) )
+ return rWrt;
+
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "Font wirklich als Hint ausgeben?" );
+
+ String sOut;
+ // MS IE3b1 hat mit einfachen Haekchen Probleme
+ USHORT nMode = rHTMLWrt.nCSS1OutMode & CSS1_OUTMODE_ANY_ON;
+ sal_Unicode cQuote = nMode == CSS1_OUTMODE_RULE_ON ? '\"' : '\'';
+ SwHTMLWriter::PrepareFontList( ((const SvxFontItem&)rHt), sOut, cQuote,
+ TRUE );
+
+ rHTMLWrt.OutCSS1_Property( sCSS1_P_font_family, sOut );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxFontHeight( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Font-Hoehen muessen nicht in der Style-Option ausgegeben werden.
+ // Fuer Drop-Caps wird ein andewres font-size ausgegeben
+ if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ||
+ rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_DROPCAP ) )
+ return rWrt;
+
+ sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
+ switch( rHt.Which() )
+ {
+ case RES_CHRATR_CJK_FONTSIZE: nScript = CSS1_OUTMODE_CJK; break;
+ case RES_CHRATR_CTL_FONTSIZE: nScript = CSS1_OUTMODE_CTL; break;
+ }
+ if( !rHTMLWrt.IsCSS1Script( nScript ) )
+ return rWrt;
+
+ UINT32 nHeight = ((const SvxFontHeightItem&)rHt).GetHeight();
+ if( rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) )
+ {
+ // einen Hint nur dann ausgeben wenn es auch was bringt
+ USHORT nSize = rHTMLWrt.GetHTMLFontSize( nHeight );
+ if( rHTMLWrt.aFontHeights[nSize-1] == nHeight )
+ return rWrt;
+ }
+ ByteString sHeight( ByteString::CreateFromInt32(
+ (sal_Int32)(nHeight/20) ) );
+ sHeight.Append( sCSS1_UNIT_pt );
+
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size, sHeight );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
+ switch( rHt.Which() )
+ {
+ case RES_CHRATR_CJK_POSTURE: nScript = CSS1_OUTMODE_CJK; break;
+ case RES_CHRATR_CTL_POSTURE: nScript = CSS1_OUTMODE_CTL; break;
+ }
+ if( !rHTMLWrt.IsCSS1Script( nScript ) )
+ return rWrt;
+
+ const sal_Char *pStr = 0;
+ switch( ((const SvxPostureItem&)rHt).GetPosture() )
+ {
+ case ITALIC_NONE: pStr = sCSS1_PV_normal; break;
+ case ITALIC_OBLIQUE: pStr = sCSS1_PV_oblique; break;
+ case ITALIC_NORMAL:
+ if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ {
+ // das geht auch in HTML und muss nicht als STYLE-Option
+ // und darf nicht als Hint geschrieben werden
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "Italic als Hint schreiben?" );
+ pStr = sCSS1_PV_italic;
+ }
+ break;
+ default:
+ ;
+ }
+
+ if( pStr )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_style, pStr );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxKerning( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Kerning-Item nur ausgeben, wenn volle Style-Unterst?tzung da ist
+ if( !rHTMLWrt.IsHTMLMode(HTMLMODE_FULL_STYLES) )
+ return rWrt;
+
+ INT16 nValue = ((const SvxKerningItem&)rHt).GetValue();
+ if( nValue )
+ {
+ ByteString sOut;
+ if( nValue < 0 )
+ {
+ sOut = '-';
+ nValue = -nValue;
+ }
+
+ // Breite als n.n pt
+ nValue = (nValue + 1) / 2; // 1/10pt
+ sOut.Append( ByteString::CreateFromInt32( (sal_Int32)(nValue / 10) ) );
+ sOut.Append( '.' );
+ sOut.Append( ByteString::CreateFromInt32( (sal_Int32)(nValue % 10) ) );
+ sOut.Append( sCSS1_UNIT_pt );
+
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing, sOut );
+ }
+ else
+ {
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing,
+ sCSS1_PV_normal );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxLanguage( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Language will be exported rules only
+ if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ return rWrt;
+
+ sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
+ switch( rHt.Which() )
+ {
+ case RES_CHRATR_CJK_LANGUAGE: nScript = CSS1_OUTMODE_CJK; break;
+ case RES_CHRATR_CTL_LANGUAGE: nScript = CSS1_OUTMODE_CTL; break;
+ }
+ if( !rHTMLWrt.IsCSS1Script( nScript ) )
+ return rWrt;
+
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "Language wirklich als Hint ausgeben?" );
+
+ LanguageType eLang = ((const SvxLanguageItem &)rHt).GetLanguage();
+ if( LANGUAGE_DONTKNOW == eLang )
+ return rWrt;
+
+ String sOut = MsLangId::convertLanguageToIsoString( eLang );
+
+ rHTMLWrt.OutCSS1_Property( sCSS1_P_so_language, sOut );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxUnderline( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ // Mit dieser Methode werden nur Hints ausgegeben!
+ // Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.
+
+ if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
+ OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
+ (const SvxUnderlineItem *)&rHt, 0, 0, 0 );
+
+ return rWrt;
+}
+
+
+static Writer& OutCSS1_SvxOverline( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ // Mit dieser Methode werden nur Hints ausgegeben!
+ // Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.
+
+ if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
+ OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
+ 0, (const SvxOverlineItem *)&rHt, 0, 0 );
+
+ return rWrt;
+}
+
+
+static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
+ switch( rHt.Which() )
+ {
+ case RES_CHRATR_CJK_WEIGHT: nScript = CSS1_OUTMODE_CJK; break;
+ case RES_CHRATR_CTL_WEIGHT: nScript = CSS1_OUTMODE_CTL; break;
+ }
+ if( !rHTMLWrt.IsCSS1Script( nScript ) )
+ return rWrt;
+
+ const sal_Char *pStr = 0;
+ switch( ((const SvxWeightItem&)rHt).GetWeight() )
+ {
+ case WEIGHT_ULTRALIGHT: pStr = sCSS1_PV_extra_light; break;
+ case WEIGHT_LIGHT: pStr = sCSS1_PV_light; break;
+ case WEIGHT_SEMILIGHT: pStr = sCSS1_PV_demi_light; break;
+ case WEIGHT_NORMAL: pStr = sCSS1_PV_normal; break;
+ case WEIGHT_SEMIBOLD: pStr = sCSS1_PV_demi_bold; break;
+ case WEIGHT_BOLD:
+ if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ {
+ // das geht auch in HTML und muss nicht als STYLE-Option
+ // und darf nicht als Hint geschrieben werden
+ ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
+ "Fett als Hint schreiben?" );
+ pStr = sCSS1_PV_bold;
+ }
+ break;
+ case WEIGHT_ULTRABOLD: pStr = sCSS1_PV_extra_bold; break;
+ default:
+ pStr = sCSS1_PV_normal;;
+ }
+
+ if( pStr )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_weight, pStr );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxBlink( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ // Mit dieser Methode werden nur Hints ausgegeben!
+ // Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.
+
+ if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
+ OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
+ 0, 0, 0, (const SvxBlinkItem *)&rHt );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxLineSpacing( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // #60393#: Netscape4 hat massive Probleme mit den Zellenhoehen
+ // wenn der Zeilenabstand innerhalb einer Tabelle geaendert wird
+ // und die Breite der Tabelle nicht automatisch berechnet wird
+ // (also wenn eine WIDTH-Option vorhanden ist).
+ if( rHTMLWrt.bOutTable && rHTMLWrt.bCfgNetscape4 )
+ return rWrt;
+
+ const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)rHt;
+
+ USHORT nHeight = 0;
+ USHORT nPrcHeight = 0;
+ SvxLineSpace eLineSpace = rLSItem.GetLineSpaceRule();
+ switch( rLSItem.GetInterLineSpaceRule() )
+ {
+ case SVX_INTER_LINE_SPACE_OFF:
+ case SVX_INTER_LINE_SPACE_FIX:
+ {
+ switch( eLineSpace )
+ {
+ case SVX_LINE_SPACE_MIN:
+ case SVX_LINE_SPACE_FIX:
+ nHeight = rLSItem.GetLineHeight();
+ break;
+ case SVX_LINE_SPACE_AUTO:
+ nPrcHeight = 100;
+ break;
+ default:
+ ;
+ }
+ }
+ break;
+ case SVX_INTER_LINE_SPACE_PROP:
+ nPrcHeight = rLSItem.GetPropLineSpace();
+ break;
+
+ default:
+ ;
+ }
+
+ if( nHeight )
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_line_height, (long)nHeight );
+ else if( nPrcHeight )
+ {
+ ByteString sHeight(
+ ByteString::CreateFromInt32( (sal_Int32)nPrcHeight ) );
+ sHeight += '%';
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_line_height, sHeight );
+ }
+
+ return rWrt;
+
+}
+
+static Writer& OutCSS1_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Alignment in Style-Option nur ausgeben, wenn das Tag kein
+ // ALIGN=xxx zulaesst
+ if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) &&
+ !rHTMLWrt.bNoAlign)
+ return rWrt;
+
+ const sal_Char* pStr = 0;
+ switch( ((const SvxAdjustItem&)rHt).GetAdjust() )
+ {
+ case SVX_ADJUST_LEFT: pStr = sCSS1_PV_left; break;
+ case SVX_ADJUST_RIGHT: pStr = sCSS1_PV_right; break;
+ case SVX_ADJUST_BLOCK: pStr = sCSS1_PV_justify; break;
+ case SVX_ADJUST_CENTER: pStr = sCSS1_PV_center; break;
+ default:
+ ;
+ }
+
+ if( pStr )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_align, pStr );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxFmtSplit( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const sal_Char *pStr = ((const SvxFmtSplitItem&)rHt).GetValue()
+ ? sCSS1_PV_auto
+ : sCSS1_PV_avoid;
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SwFmtLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const sal_Char *pStr = ((const SwFmtLayoutSplit&)rHt).GetValue()
+ ? sCSS1_PV_auto
+ : sCSS1_PV_avoid;
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxWidows( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ ByteString aStr(
+ ByteString::CreateFromInt32( ((const SvxWidowsItem&)rHt).GetValue() ) );
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_widows, aStr );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxOrphans( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ ByteString aStr(
+ ByteString::CreateFromInt32( ((const SvxOrphansItem&)rHt).GetValue() ) );
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_orphans, aStr );
+
+ return rWrt;
+}
+
+static void OutCSS1_SwFmtDropAttrs( SwHTMLWriter& rHWrt,
+ const SwFmtDrop& rDrop,
+ const SfxItemSet *pCharFmtItemSet )
+{
+ // Text fliesst rechts drumrum
+ rHWrt.OutCSS1_PropertyAscii( sCSS1_P_float, sCSS1_PV_left );
+
+ // Anzahl der Zeilen -> %-Angabe fuer Font-Hoehe!
+ ByteString sOut( ByteString::CreateFromInt32( rDrop.GetLines()*100 ) );
+ sOut += '%';
+ rHWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size, sOut );
+
+ // Abstand zum Text = rechter Rand
+ USHORT nDistance = rDrop.GetDistance();
+ if( nDistance > 0 )
+ rHWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right, nDistance );
+
+ const SwCharFmt *pDCCharFmt = rDrop.GetCharFmt();
+ if( pCharFmtItemSet )
+ rHWrt.OutCSS1_SfxItemSet( *pCharFmtItemSet );
+ else if( pDCCharFmt )
+ rHWrt.OutCSS1_SfxItemSet( pDCCharFmt->GetAttrSet() );
+ else if( (rHWrt.nCSS1OutMode & CSS1_OUTMODE_ANY_OFF) == CSS1_OUTMODE_RULE_OFF )
+ rHWrt.Strm() << sCSS1_rule_end;
+
+}
+
+static Writer& OutCSS1_SwFmtDrop( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // nie als Option eines Absatzes ausgeben, sondern nur als Hints
+ if( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) )
+ return rWrt;
+
+ if( rHTMLWrt.bTagOn )
+ {
+ SwCSS1OutMode aMode( rHTMLWrt,
+ rHTMLWrt.nCSS1Script|CSS1_OUTMODE_SPAN_TAG1_ON|CSS1_OUTMODE_ENCODE|
+ CSS1_OUTMODE_DROPCAP );
+
+ OutCSS1_SwFmtDropAttrs( rHTMLWrt, (const SwFmtDrop&)rHt );
+ // Ein "> wird schon vom aufrufenden OutCSS1_HintAsSpanTag geschrieben.
+ }
+ else
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, FALSE );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SwFmtFrmSize( Writer& rWrt, const SfxPoolItem& rHt,
+ USHORT nMode )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ ByteString sOut;
+ const SwFmtFrmSize& rFSItem = (const SwFmtFrmSize&)rHt;
+
+ if( nMode & CSS1_FRMSIZE_WIDTH )
+ {
+ BYTE nPrcWidth = rFSItem.GetWidthPercent();
+ if( nPrcWidth )
+ {
+ (sOut = ByteString::CreateFromInt32( nPrcWidth) ) += '%';
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_width, sOut );
+ }
+ else if( nMode & CSS1_FRMSIZE_PIXEL )
+ {
+ rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_width,
+ rFSItem.GetSize().Width(), FALSE );
+ }
+ else
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_width,
+ rFSItem.GetSize().Width() );
+ }
+ }
+
+ if( nMode & CSS1_FRMSIZE_ANYHEIGHT )
+ {
+ BOOL bOutHeight = FALSE;
+ switch( rFSItem.GetHeightSizeType() )
+ {
+ case ATT_FIX_SIZE:
+ bOutHeight = (nMode & CSS1_FRMSIZE_FIXHEIGHT) != 0;
+ break;
+ case ATT_MIN_SIZE:
+ bOutHeight = (nMode & CSS1_FRMSIZE_MINHEIGHT) != 0;
+ break;
+ case ATT_VAR_SIZE:
+ bOutHeight = (nMode & CSS1_FRMSIZE_VARHEIGHT) != 0;
+ break;
+ default:
+ ASSERT( bOutHeight, "Hoehe wird nicht exportiert" );
+ break;
+ }
+
+ if( bOutHeight )
+ {
+ BYTE nPrcHeight = rFSItem.GetHeightPercent();
+ if( nPrcHeight )
+ {
+ (sOut = ByteString::CreateFromInt32( nPrcHeight ) ) += '%';
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_height, sOut );
+ }
+ else if( nMode & CSS1_FRMSIZE_PIXEL )
+ {
+ rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_height,
+ rFSItem.GetSize().Width(),
+ TRUE );
+ }
+ else
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_height,
+ rFSItem.GetSize().Height() );
+ }
+ }
+ }
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SvxLRSpaceItem& rLRItem = (const SvxLRSpaceItem&)rHt;
+
+ // Der Export der harten Attributierung ist unnoetig, wenn die
+ // neuen Werte denen der aktuellen Vorlage entsprechen
+
+ // Einen linken Rand kann es durch eine Liste bereits in der
+ // Umgebung geben
+ long nLeftMargin = (long)rLRItem.GetTxtLeft() - rHTMLWrt.nLeftMargin;
+ if( rHTMLWrt.nDfltLeftMargin != nLeftMargin )
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLeftMargin );
+ }
+
+ if( rHTMLWrt.nDfltRightMargin != rLRItem.GetRight() )
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right,
+ (long)rLRItem.GetRight() );
+ }
+
+ // Der Erstzeilen-Einzug kann den Platz fuer eine Numerierung
+ // enthalten
+ long nFirstLineIndent = (long)rLRItem.GetTxtFirstLineOfst() -
+ rHTMLWrt.nFirstLineIndent;
+ if( rHTMLWrt.nDfltFirstLineIndent != nFirstLineIndent )
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent,
+ nFirstLineIndent );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)rHt;
+
+ if( rHTMLWrt.nDfltTopMargin != rULItem.GetUpper() )
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_top,
+ (long)rULItem.GetUpper() );
+ }
+
+ if( rHTMLWrt.nDfltBottomMargin != rULItem.GetLower() )
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_bottom,
+ (long)rULItem.GetLower() );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
+ const SvxULSpaceItem *pULItem,
+ const SvxLRSpaceItem *pLRItem )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ if( pLRItem && pULItem &&
+ pLRItem->GetLeft() == pLRItem->GetRight() &&
+ pLRItem->GetLeft() == pULItem->GetUpper() &&
+ pLRItem->GetLeft() == pULItem->GetLower() &&
+ pLRItem->GetLeft() != rHTMLWrt.nDfltLeftMargin &&
+ pLRItem->GetRight() != rHTMLWrt.nDfltRightMargin &&
+ pULItem->GetUpper() != rHTMLWrt.nDfltTopMargin &&
+ pULItem->GetLower() != rHTMLWrt.nDfltBottomMargin )
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin, (long)pLRItem->GetLeft() );
+ }
+ else
+ {
+ if( pLRItem )
+ OutCSS1_SvxLRSpace( rWrt, *pLRItem );
+ if( pULItem )
+ OutCSS1_SvxULSpace( rWrt, *pULItem );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
+ const SfxItemSet& rItemSet,
+ BOOL bDeep )
+{
+ const SvxULSpaceItem *pULSpace = 0;
+ const SvxLRSpaceItem *pLRSpace = 0;
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, bDeep, &pItem ) )
+ pLRSpace = (const SvxLRSpaceItem *)pItem;
+
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, bDeep, &pItem ) )
+ pULSpace = (const SvxULSpaceItem *)pItem;
+
+ if( pLRSpace || pULSpace )
+ OutCSS1_SvxULSpace_SvxLRSpace( rWrt, pULSpace, pLRSpace );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
+ const SvxFmtBreakItem *pBreakItem,
+ const SwFmtPageDesc *pPDescItem,
+ const SvxFmtKeepItem *pKeepItem )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ if( !rHTMLWrt.IsHTMLMode(HTMLMODE_PRINT_EXT) )
+ return rWrt;
+
+ const sal_Char *pBreakBefore = 0;
+ const sal_Char *pBreakAfter = 0;
+
+ if( pKeepItem )
+ {
+ pBreakAfter = pKeepItem->GetValue() ? sCSS1_PV_avoid : sCSS1_PV_auto;
+ }
+ if( pBreakItem )
+ {
+ switch( pBreakItem->GetBreak() )
+ {
+ case SVX_BREAK_NONE:
+ pBreakBefore = sCSS1_PV_auto;
+ if( !pBreakAfter )
+ pBreakAfter = sCSS1_PV_auto;
+ break;
+
+ case SVX_BREAK_PAGE_BEFORE:
+ pBreakBefore = sCSS1_PV_always;
+ break;
+
+ case SVX_BREAK_PAGE_AFTER:
+ pBreakAfter= sCSS1_PV_always;
+ break;
+
+ default:
+ ;
+ }
+ }
+ if( pPDescItem )
+ {
+ const SwPageDesc *pPDesc = pPDescItem->GetPageDesc();
+ if( pPDesc )
+ {
+ switch( pPDesc->GetPoolFmtId() )
+ {
+ case RES_POOLPAGE_LEFT: pBreakBefore = sCSS1_PV_left; break;
+ case RES_POOLPAGE_RIGHT: pBreakBefore = sCSS1_PV_right; break;
+ default: pBreakBefore = sCSS1_PV_always; break;
+ }
+ }
+ else if( !pBreakBefore )
+ {
+ pBreakBefore = sCSS1_PV_auto;
+ }
+ }
+
+ if( pBreakBefore )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_before,
+ pBreakBefore );
+ if( pBreakAfter )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_after,
+ pBreakAfter );
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
+ const SfxItemSet& rItemSet,
+ BOOL bDeep )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ const SfxPoolItem *pItem;
+ const SvxFmtBreakItem *pBreakItem = 0;
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BREAK, bDeep, &pItem ))
+ pBreakItem = (const SvxFmtBreakItem *)pItem;
+
+ const SwFmtPageDesc *pPDescItem = 0;
+ if( ( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ||
+ !rHTMLWrt.bCSS1IgnoreFirstPageDesc ||
+ rHTMLWrt.pStartNdIdx->GetIndex() !=
+ rHTMLWrt.pCurPam->GetPoint()->nNode.GetIndex() ) &&
+ SFX_ITEM_SET==rItemSet.GetItemState( RES_PAGEDESC, bDeep, &pItem ))
+ pPDescItem = (const SwFmtPageDesc*)pItem;
+
+ const SvxFmtKeepItem *pKeepItem = 0;
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_KEEP, bDeep, &pItem ))
+ pKeepItem = (const SvxFmtKeepItem *)pItem;
+
+ if( pBreakItem || pPDescItem || pKeepItem )
+ OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( rWrt, pBreakItem,
+ pPDescItem, pKeepItem );
+
+ return rWrt;
+}
+
+// Wrapper fuer OutCSS1_SfxItemSet etc.
+static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ OutCSS1_SvxBrush( rWrt, rHt, CSS1_BACKGROUND_ATTR, 0 );
+ return rWrt;
+}
+
+
+static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
+ USHORT nMode, const String *pGrfName )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Das Zeichen-Attribut wird nicht ausgegeben, wenn gerade
+ // Optionen ausgegeben werden
+ if( rHt.Which() < RES_CHRATR_END &&
+ rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+ return rWrt;
+
+ // Erstmal ein par Werte holen
+// const Brush &rBrush = ((const SvxBrushItem &)rHt).GetBrush();
+ const Color & rColor = ((const SvxBrushItem &)rHt).GetColor();
+ const String *pLink = pGrfName ? pGrfName
+ : ((const SvxBrushItem &)rHt).GetGraphicLink();
+ SvxGraphicPosition ePos = ((const SvxBrushItem &)rHt).GetGraphicPos();
+
+ if( CSS1_BACKGROUND_PAGE==nMode )
+ {
+ // Fuer Seitenvorlagen wurde der Grafik-Name uebergeben. Es wird
+ // nur ein Attribut ausgegeben, wenn die Grafik nicht gekachelt ist.
+ ASSERT( pLink, "Wo ist der Grafik-Name der Seitenvorlage?" );
+ if( !pLink || !pLink->Len() || GPOS_TILED==ePos )
+ return rWrt;
+ }
+
+ // Erstmal die Farbe holen
+ BOOL bColor = FALSE;
+ /// OD 02.09.2002 #99657#
+ /// set <bTransparent> to TRUE, if color is "no fill"/"auto fill"
+ BOOL bTransparent = (rColor.GetColor() == COL_TRANSPARENT);
+ Color aColor;
+ if( !bTransparent )
+ {
+ aColor = rColor;
+ bColor = TRUE;
+ }
+
+ // und jetzt eine Grafik
+ String sGrfNm;
+
+ if( !pLink )
+ {
+ // embeddete Grafik -> WriteEmbedded schreiben
+ const Graphic* pGrf = ((const SvxBrushItem &)rHt).GetGraphic();
+ if( pGrf )
+ {
+ // Grafik als (JPG-)File speichern
+ const String* pTempFileName = rHTMLWrt.GetOrigFileName();
+ if( pTempFileName )
+ sGrfNm = *pTempFileName;
+ USHORT nErr = XOutBitmap::WriteGraphic( *pGrf, sGrfNm,
+ String::CreateFromAscii("JPG"),
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE );
+ if( !nErr ) // fehlerhaft, da ist nichts auszugeben
+ {
+ sGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(rWrt.GetBaseURL()), sGrfNm,
+ URIHelper::GetMaybeFileHdl() );
+ pLink = &sGrfNm;
+ }
+ else
+ {
+ rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ }
+ }
+ }
+ else if( !pGrfName && rHTMLWrt.bCfgCpyLinkedGrfs )
+ {
+ sGrfNm = *pLink;
+ rWrt.CopyLocalFileToINet( sGrfNm );
+ pLink = &sGrfNm;
+ }
+
+ // In Tabellen wird nur dann etwas exportiert, wenn eine Grafik
+ // existiert.
+ if( CSS1_BACKGROUND_TABLE==nMode && !pLink )
+ return rWrt;
+
+ // ggf. noch die Ausrichtung der Grafik
+ const sal_Char *pRepeat = 0, *pHori = 0, *pVert = 0;
+ if( pLink )
+ {
+ if( GPOS_TILED==ePos )
+ {
+ pRepeat = sCSS1_PV_repeat;
+ }
+ else
+ {
+ switch( ePos )
+ {
+ case GPOS_LT:
+ case GPOS_MT:
+ case GPOS_RT:
+ pHori = sCSS1_PV_top;
+ break;
+
+ case GPOS_LM:
+ case GPOS_MM:
+ case GPOS_RM:
+ pHori = sCSS1_PV_middle;
+ break;
+
+ case GPOS_LB:
+ case GPOS_MB:
+ case GPOS_RB:
+ pHori = sCSS1_PV_bottom;
+ break;
+
+ default:
+ ;
+ }
+
+ switch( ePos )
+ {
+ case GPOS_LT:
+ case GPOS_LM:
+ case GPOS_LB:
+ pVert = sCSS1_PV_left;
+ break;
+
+ case GPOS_MT:
+ case GPOS_MM:
+ case GPOS_MB:
+ pVert = sCSS1_PV_center;
+ break;
+
+ case GPOS_RT:
+ case GPOS_RM:
+ case GPOS_RB:
+ pVert = sCSS1_PV_right;
+ break;
+
+ default:
+ ;
+ }
+
+ if( pHori || pVert )
+ pRepeat = sCSS1_PV_no_repeat;
+ }
+ }
+
+ // jetzt den String zusammen bauen
+ String sOut;
+ if( !pLink && !bColor )
+ {
+ // keine Farbe und kein Link, aber ein transparenter Brush
+ if( bTransparent && CSS1_BACKGROUND_FLY != nMode )
+ sOut.AssignAscii( sCSS1_PV_transparent );
+ }
+ else
+ {
+ if( bColor )
+ {
+ ByteString sTmp;
+ GetCSS1Color( aColor, sTmp );
+ sOut += String( sTmp, RTL_TEXTENCODING_ASCII_US );
+ }
+
+ if( pLink )
+ {
+ if( bColor )
+ sOut += ' ';
+
+ sOut.AppendAscii( sCSS1_url );
+ sOut.Append( '(' );
+ sOut.Append( String(URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(),
+ *pLink)));
+
+ sOut.Append( ')' );
+
+ if( pRepeat )
+ {
+ sOut.Append( ' ' );
+ sOut.AppendAscii( pRepeat );
+ }
+
+ if( pHori )
+ {
+ sOut.Append( ' ' );
+ sOut.AppendAscii( pHori );
+ }
+ if( pVert )
+ {
+ sOut.Append( ' ' );
+ sOut.AppendAscii( pVert );
+ }
+
+ sOut.Append( ' ' );
+ sOut.AppendAscii( sCSS1_PV_scroll );
+ }
+ }
+
+ if( sOut.Len() )
+ rHTMLWrt.OutCSS1_Property( sCSS1_P_background, sOut );
+
+ return rWrt;
+}
+
+static void OutCSS1_SvxBorderLine( SwHTMLWriter& rHTMLWrt,
+ const sal_Char *pProperty,
+ const SvxBorderLine *pLine )
+{
+ if( !pLine )
+ {
+ rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sCSS1_PV_none );
+ return;
+ }
+
+ BOOL bDouble = FALSE;
+ INT32 nWidth = pLine->GetOutWidth();
+ if( pLine->GetInWidth() )
+ {
+ nWidth += pLine->GetDistance();
+ nWidth += pLine->GetInWidth();
+ bDouble = TRUE;
+ }
+
+ ByteString sOut;
+ if( Application::GetDefaultDevice() &&
+ nWidth <= Application::GetDefaultDevice()->PixelToLogic(
+ Size( 1, 1 ), MapMode( MAP_TWIP) ).Width() )
+ {
+ // Wenn die Breite kleiner ist als ein Pixel, dann als 1px
+ // ausgeben, damit Netscape und IE die Linie auch darstellen.
+ sOut += "1px";
+ }
+ else
+ {
+ nWidth *= 5; // 1/100pt
+
+ // Breite als n.nn pt
+ sOut += ByteString::CreateFromInt32( nWidth / 100 );
+ (((sOut += '.')
+ += ByteString::CreateFromInt32((nWidth/10) % 10))
+ += ByteString::CreateFromInt32(nWidth % 10)) += sCSS1_UNIT_pt;
+ }
+
+ // Linien-Stil: solid oder double
+ ((sOut += ' ')
+ += (bDouble ? sCSS1_PV_double : sCSS1_PV_solid)) += ' ';
+
+ // und noch die Farbe
+ GetCSS1Color( pLine->GetColor(), sOut );
+
+ rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sOut );
+}
+
+static Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Das Zeichen-Attribut wird nicht ausgegeben, wenn gerade
+ // Optionen ausgegeben werden
+ if( !rHTMLWrt.IsHTMLMode(HTMLMODE_PARA_BORDER))
+ return rWrt;
+
+ const SvxBoxItem& rBoxItem = (const SvxBoxItem&)rHt;
+ const SvxBorderLine *pTop = rBoxItem.GetTop();
+ const SvxBorderLine *pBottom = rBoxItem.GetBottom();
+ const SvxBorderLine *pLeft = rBoxItem.GetLeft();
+ const SvxBorderLine *pRight = rBoxItem.GetRight();
+
+ if( (pTop && pBottom && pLeft && pRight &&
+ *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) ||
+ (!pTop && !pBottom && !pLeft && !pRight) )
+ {
+ // alle Linien gesetzt und gleich oder alle Linien nicht gesetzt
+ // => border : ...
+ OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border, pTop );
+ }
+ else
+ {
+ // sonst alle Linien individuell ausgeben
+ OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_top, pTop );
+ OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_bottom, pBottom );
+ OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_left, pLeft );
+ OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_right, pRight );
+ }
+
+ long nTopDist = pTop ? rBoxItem.GetDistance( BOX_LINE_TOP ) : 0;
+ long nBottomDist = pBottom ? rBoxItem.GetDistance( BOX_LINE_BOTTOM ) : 0;
+ long nLeftDist = pLeft ? rBoxItem.GetDistance( BOX_LINE_LEFT ) : 0;
+ long nRightDist = pRight ? rBoxItem.GetDistance( BOX_LINE_RIGHT ) : 0;
+
+ if( nTopDist == nBottomDist && nLeftDist == nRightDist )
+ {
+ ByteString sVal;
+ AddUnitPropertyValue( nTopDist, rHTMLWrt.GetCSS1Unit(), sVal );
+ if( nTopDist != nLeftDist )
+ {
+ sVal += ' ';
+ AddUnitPropertyValue( nLeftDist, rHTMLWrt.GetCSS1Unit(), sVal );
+ }
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_padding, sVal );
+ }
+ else
+ {
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_top, nTopDist );
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_bottom, nBottomDist );
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_left, nLeftDist );
+ rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_right, nRightDist );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutCSS1_SvxFrameDirection( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = static_cast< SwHTMLWriter& >( rWrt );
+
+ // Language will be exported rules only
+ if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_TEMPLATE ) )
+ return rWrt;
+
+ sal_uInt16 nDir =
+ static_cast< const SvxFrameDirectionItem& >( rHt ).GetValue();
+ sal_Char *pStr = 0;
+ switch( nDir )
+ {
+ case FRMDIR_HORI_LEFT_TOP:
+ case FRMDIR_VERT_TOP_LEFT:
+ pStr = sCSS1_PV_ltr;
+ break;
+ case FRMDIR_HORI_RIGHT_TOP:
+ case FRMDIR_VERT_TOP_RIGHT:
+ pStr = sCSS1_PV_rtl;
+ break;
+ case FRMDIR_ENVIRONMENT:
+ pStr = sCSS1_PV_inherit;
+ break;
+ }
+
+ if( pStr )
+ rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_direction, pStr );
+
+ return rWrt;
+}
+
+/*
+ * lege hier die Tabellen fuer die HTML-Funktions-Pointer auf
+ * die Ausgabe-Funktionen an.
+ * Es sind lokale Strukturen, die nur innerhalb der HTML-DLL
+ * bekannt sein muessen.
+ */
+
+
+SwAttrFnTab aCSS1AttrFnTab = {
+/* RES_CHRATR_CASEMAP */ OutCSS1_SvxCaseMap,
+/* RES_CHRATR_CHARSETCOLOR */ 0,
+/* RES_CHRATR_COLOR */ OutCSS1_SvxColor,
+/* RES_CHRATR_CONTOUR */ 0,
+/* RES_CHRATR_CROSSEDOUT */ OutCSS1_SvxCrossedOut,
+/* RES_CHRATR_ESCAPEMENT */ 0,
+/* RES_CHRATR_FONT */ OutCSS1_SvxFont,
+/* RES_CHRATR_FONTSIZE */ OutCSS1_SvxFontHeight,
+/* RES_CHRATR_KERNING */ OutCSS1_SvxKerning,
+/* RES_CHRATR_LANGUAGE */ OutCSS1_SvxLanguage,
+/* RES_CHRATR_POSTURE */ OutCSS1_SvxPosture,
+/* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
+/* RES_CHRATR_SHADOWED */ 0,
+/* RES_CHRATR_UNDERLINE */ OutCSS1_SvxUnderline,
+/* RES_CHRATR_WEIGHT */ OutCSS1_SvxFontWeight,
+/* RES_CHRATR_WORDLINEMODE */ 0,
+/* RES_CHRATR_AUTOKERN */ 0,
+/* RES_CHRATR_BLINK */ OutCSS1_SvxBlink,
+/* RES_CHRATR_NOHYPHEN */ 0, // Neu: nicht trennen
+/* RES_CHRATR_NOLINEBREAK */ 0, // Neu: nicht umbrechen
+/* RES_CHRATR_BACKGROUND */ OutCSS1_SvxBrush, // Neu: Zeichenhintergrund
+/* RES_CHRATR_CJK_FONT */ OutCSS1_SvxFont,
+/* RES_CHRATR_CJK_FONTSIZE */ OutCSS1_SvxFontHeight,
+/* RES_CHRATR_CJK_LANGUAGE */ OutCSS1_SvxLanguage,
+/* RES_CHRATR_CJK_POSTURE */ OutCSS1_SvxPosture,
+/* RES_CHRATR_CJK_WEIGHT */ OutCSS1_SvxFontWeight,
+/* RES_CHRATR_CTL_FONT */ OutCSS1_SvxFont,
+/* RES_CHRATR_CTL_FONTSIZE */ OutCSS1_SvxFontHeight,
+/* RES_CHRATR_CTL_LANGUAGE */ OutCSS1_SvxLanguage,
+/* RES_CHRATR_CTL_POSTURE */ OutCSS1_SvxPosture,
+/* RES_CHRATR_CTL_WEIGHT */ OutCSS1_SvxFontWeight,
+/* RES_CHRATR_ROTATE */ 0,
+/* RES_CHRATR_EMPHASIS_MARK */ 0,
+/* RES_CHRATR_TWO_LINES */ 0,
+/* RES_CHRATR_SCALEW */ 0,
+/* RES_CHRATR_RELIEF */ 0,
+/* RES_CHRATR_HIDDEN */ 0,
+/* RES_CHRATR_OVERLINE */ OutCSS1_SvxOverline,
+/* RES_CHRATR_DUMMY1 */ 0,
+/* RES_CHRATR_DUMMY2 */ 0,
+
+/* RES_TXTATR_REFMARK */ 0,
+/* RES_TXTATR_TOXMARK */ 0,
+/* RES_TXTATR_META */ 0,
+/* RES_TXTATR_METAFIELD */ 0,
+/* RES_TXTATR_AUTOFMT */ 0,
+/* RES_TXTATR_INETFMT */ 0,
+/* RES_TXTATR_CHARFMT */ 0,
+/* RES_TXTATR_CJK_RUBY */ 0,
+/* RES_TXTATR_UNKNOWN_CONTAINER */ 0,
+/* RES_TXTATR_DUMMY5 */ 0,
+
+/* RES_TXTATR_FIELD */ 0,
+/* RES_TXTATR_FLYCNT */ 0,
+/* RES_TXTATR_FTN */ 0,
+/* RES_TXTATR_DUMMY4 */ 0,
+/* RES_TXTATR_DUMMY3 */ 0,
+/* RES_TXTATR_DUMMY1 */ 0, // Dummy:
+/* RES_TXTATR_DUMMY2 */ 0, // Dummy:
+
+/* RES_PARATR_LINESPACING */ OutCSS1_SvxLineSpacing,
+/* RES_PARATR_ADJUST */ OutCSS1_SvxAdjust,
+/* RES_PARATR_SPLIT */ OutCSS1_SvxFmtSplit,
+/* RES_PARATR_WIDOWS */ OutCSS1_SvxWidows,
+/* RES_PARATR_ORPHANS */ OutCSS1_SvxOrphans,
+/* RES_PARATR_TABSTOP */ 0,
+/* RES_PARATR_HYPHENZONE*/ 0,
+/* RES_PARATR_DROP */ OutCSS1_SwFmtDrop,
+/* RES_PARATR_REGISTER */ 0, // neu: Registerhaltigkeit
+/* RES_PARATR_NUMRULE */ 0, // Dummy:
+/* RES_PARATR_SCRIPTSPACE */ 0, // Dummy:
+/* RES_PARATR_HANGINGPUNCTUATION */ 0, // Dummy:
+/* RES_PARATR_FORBIDDEN_RULES */ 0, // new
+/* RES_PARATR_VERTALIGN */ 0, // new
+/* RES_PARATR_SNAPTOGRID*/ 0, // new
+/* RES_PARATR_CONNECT_TO_BORDER */ 0, // new
+/* RES_PARATR_OUTLINELEVEL */ 0, // new since cws outlinelevel
+
+/* RES_PARATR_LIST_ID */ 0, // new
+/* RES_PARATR_LIST_LEVEL */ 0, // new
+/* RES_PARATR_LIST_ISRESTART */ 0, // new
+/* RES_PARATR_LIST_RESTARTVALUE */ 0, // new
+/* RES_PARATR_LIST_ISCOUNTED */ 0, // new
+
+/* RES_FILL_ORDER */ 0,
+/* RES_FRM_SIZE */ 0,
+/* RES_PAPER_BIN */ 0,
+/* RES_LR_SPACE */ OutCSS1_SvxLRSpace,
+/* RES_UL_SPACE */ OutCSS1_SvxULSpace,
+/* RES_PAGEDESC */ 0,
+/* RES_BREAK */ 0,
+/* RES_CNTNT */ 0,
+/* RES_HEADER */ 0,
+/* RES_FOOTER */ 0,
+/* RES_PRINT */ 0,
+/* RES_OPAQUE */ 0,
+/* RES_PROTECT */ 0,
+/* RES_SURROUND */ 0,
+/* RES_VERT_ORIENT */ 0,
+/* RES_HORI_ORIENT */ 0,
+/* RES_ANCHOR */ 0,
+/* RES_BACKGROUND */ OutCSS1_SvxBrush,
+/* RES_BOX */ OutCSS1_SvxBox,
+/* RES_SHADOW */ 0,
+/* RES_FRMMACRO */ 0,
+/* RES_COL */ 0,
+/* RES_KEEP */ 0,
+/* RES_URL */ 0,
+/* RES_EDIT_IN_READONLY */ 0,
+/* RES_LAYOUT_SPLIT */ 0,
+/* RES_CHAIN */ 0,
+/* RES_TEXTGRID */ 0,
+/* RES_LINENUMBER */ 0,
+/* RES_FTN_AT_TXTEND */ 0,
+/* RES_END_AT_TXTEND */ 0,
+/* RES_COLUMNBALANCE */ 0,
+/* RES_FRAMEDIR */ OutCSS1_SvxFrameDirection,
+/* RES_HEADER_FOOTER_EAT_SPACING */ 0,
+/* RES_FRMATR_DUMMY9 */ 0, // Dummy:
+/* RES_FOLLOW_TEXT_FLOW */ 0,
+/* RES_WRAP_INFLUENCE_ON_OBJPOS */ 0,
+/* RES_FRMATR_DUMMY2 */ 0, // Dummy:
+/* RES_AUTO_STYLE */ 0, // Dummy:
+/* RES_FRMATR_DUMMY4 */ 0, // Dummy:
+/* RES_FRMATR_DUMMY5 */ 0, // Dummy:
+
+/* RES_GRFATR_MIRRORGRF */ 0,
+/* RES_GRFATR_CROPGRF */ 0,
+/* RES_GRFATR_ROTATION */ 0,
+/* RES_GRFATR_LUMINANCE */ 0,
+/* RES_GRFATR_CONTRAST */ 0,
+/* RES_GRFATR_CHANNELR */ 0,
+/* RES_GRFATR_CHANNELG */ 0,
+/* RES_GRFATR_CHANNELB */ 0,
+/* RES_GRFATR_GAMMA */ 0,
+/* RES_GRFATR_INVERT */ 0,
+/* RES_GRFATR_TRANSPARENCY */ 0,
+/* RES_GRFATR_DRWAMODE */ 0,
+/* RES_GRFATR_DUMMY1 */ 0,
+/* RES_GRFATR_DUMMY2 */ 0,
+/* RES_GRFATR_DUMMY3 */ 0,
+/* RES_GRFATR_DUMMY4 */ 0,
+/* RES_GRFATR_DUMMY5 */ 0,
+
+/* RES_BOXATR_FORMAT */ 0,
+/* RES_BOXATR_FORMULA */ 0,
+/* RES_BOXATR_VALUE */ 0
+};
diff --git a/sw/source/filter/html/css1kywd.cxx b/sw/source/filter/html/css1kywd.cxx
new file mode 100644
index 000000000000..63d319a8ac12
--- /dev/null
+++ b/sw/source/filter/html/css1kywd.cxx
@@ -0,0 +1,281 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "css1kywd.hxx"
+
+/* */
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS_mimetype, "text/css" );
+
+/* */
+
+// ein par allgemeine Strings
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_import, "import" );
+
+// Feature: PrintExt
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_page, "page" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_media, "media" );
+// /Feature: PrintExt
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_important, "important" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_link, "link" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_visited, "visited" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_first_letter, "first-letter" );
+
+// Feature: PrintExt
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_left, "left" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_right, "right" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_first, "first" );
+// /Feature: PrintExt
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_url, "url" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_rgb, "rgb" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_UNIT_pt, "pt" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_UNIT_mm, "mm" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_UNIT_cm, "cm" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_UNIT_pc, "pc" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_UNIT_inch, "in" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_UNIT_px, "px" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_UNIT_em, "em" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_UNIT_ex, "ex" );
+
+/* */
+
+// Strings fuer Font-Properties
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_font_family, "font-family" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_serif, "serif" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_sans_serif, "sans-serif" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_cursive, "cursive" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_fantasy, "fantasy" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_monospace, "monospace" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_font_style, "font-style" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_normal, "normal" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_italic, "italic" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_oblique, "oblique" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_font_variant, "font-variant" );
+
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_normal, "normal" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_small_caps, "small-caps" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_font_weight, "font-weight" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_extra_light, "extra-light" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_light, "light" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_demi_light, "demi-light" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_medium, "medium" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_demi_bold, "demi-bold" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_bold, "bold" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_extra_bold, "extra-bold" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_lighter, "lighter" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_bolder, "bolder" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_font_size, "font-size" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_xx_small, "xx-small" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_x_small, "x-small" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_small, "small" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_medium, "medium" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_large, "large" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_x_large, "x-large" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_xx_large, "xx-large" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_larger, "larger" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_smaller, "smaller" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_font, "font" );
+
+
+
+/* */
+
+// Strings fuer Farb- und Hintergrund-Properties
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_color, "color" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_background, "background" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_background_color, "background-color" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_transparent, "transparent" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_repeat, "repeat" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_repeat_x, "repeat-x" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_repeat_y, "repeat-y" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_no_repeat, "no-repeat" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_top, "top" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_middle, "middle" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_bottom, "bottom" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_scroll, "scroll" );
+
+
+/* */
+
+// Strings fuer Text-Properties
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_letter_spacing, "letter-spacing" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_text_decoration, "text-decoration" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_none, "none" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_underline, "underline" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_overline, "overline" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_line_through, "line-through" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_blink, "blink" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_text_align, "text-align" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_left, "left" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_center, "center" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_right, "right" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_justify, "justify" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_text_indent, "text-indent" );
+
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_line_height, "line-height" );
+
+
+/* */
+
+// Strings fuer Box-Properties
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_margin_left, "margin-left" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_margin_right, "margin-right" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_margin_top, "margin-top" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_margin_bottom, "margin-bottom" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_margin, "margin" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_padding_top, "padding-top" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_padding_bottom, "padding-bottom" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_padding_left, "padding-left" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_padding_right, "padding-right" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_padding, "padding" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_auto, "auto" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_left_width, "border-left-width" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_right_width, "border-right-width" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_top_width, "border-top-width" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_bottom_width, "border-bottom-width" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_width, "border-width" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_color, "border-color" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_style, "border-style" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_left, "border-left" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_right, "border-right" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_top, "border-top" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border_bottom, "border-bottom" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_border, "border" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_thin, "thin" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_medium, "medium" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_thick, "thick" );
+
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_none, "none" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_dotted, "dotted" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_dashed, "dashed" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_solid, "solid" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_double, "double" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_groove, "groove" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_ridge, "ridge" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_inset, "inset" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_outset, "outset" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_width, "width" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_height, "height" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_float, "float" );
+
+/* */
+
+// Strings fuer Positioning
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_position, "position" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_absolute, "absolute" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_relative, "relative" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_static, "static" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_left, "left" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_top, "top" );
+
+/* */
+
+// Feature: PrintExt
+
+// Strings fuer Printing Extensions
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_page_break_before, "page-break-before" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_page_break_after, "page-break-after" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_page_break_inside, "page-break-inside" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_size, "size" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_widows, "widows" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_orphans, "orphans" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_marks, "marks" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_always, "always" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_avoid, "avoid" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_portrait, "portrait" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_landscape, "landscape" );
+
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_crop, "crop" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_cross, "cross" );
+
+// /Feature: PrintExt
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_class_abs_pos, "sd-abs-pos" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_so_language, "so-language" );
+
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_P_direction, "direction" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_ltr, "ltr" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_rtl, "rtl" );
+sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_PV_inherit, "inherit" );
diff --git a/sw/source/filter/html/css1kywd.hxx b/sw/source/filter/html/css1kywd.hxx
new file mode 100644
index 000000000000..7994ab32c616
--- /dev/null
+++ b/sw/source/filter/html/css1kywd.hxx
@@ -0,0 +1,291 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _CSS1KYWD_HXX
+#define _CSS1KYWD_HXX
+
+#include <tools/string.hxx>
+
+#ifndef CSS1_CONSTASCII_DECL
+#define CSS1_CONSTASCII_DECL( n, s ) n[sizeof(s)]
+#endif
+#ifndef CSS1_CONSTASCII_DEF
+#define CSS1_CONSTASCII_DEF( n, s ) n[sizeof(s)] = s
+#endif
+
+/* */
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS_mimetype, "text/css" );
+
+/* */
+
+// ein par allgemeine Strings
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_import, "import" );
+
+// Feature: PrintExt
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_page, "page" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_media, "media" );
+// /Feature: PrintExt
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_important, "important" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_link, "link" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_visited, "visited" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_first_letter, "first-letter" );
+
+// Feature: PrintExt
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_left, "left" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_right, "right" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_first, "first" );
+// /Feature: PrintExt
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_url, "url" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_rgb, "rgb" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_UNIT_pt, "pt" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_UNIT_mm, "mm" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_UNIT_cm, "cm" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_UNIT_pc, "pc" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_UNIT_inch, "in" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_UNIT_px, "px" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_UNIT_em, "em" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_UNIT_ex, "ex" );
+
+/* */
+
+// Strings fuer Font-Properties
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_font_family, "font-family" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_serif, "serif" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_sans_serif, "sans-serif" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_cursive, "cursive" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_fantasy, "fantasy" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_monospace, "monospace" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_font_style, "font-style" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_normal, "normal" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_italic, "italic" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_oblique, "oblique" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_font_variant, "font-variant" );
+
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_normal, "normal" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_small_caps, "small-caps" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_font_weight, "font-weight" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_extra_light, "extra-light" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_light, "light" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_demi_light, "demi-light" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_medium, "medium" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_demi_bold, "demi-bold" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_bold, "bold" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_extra_bold, "extra-bold" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_lighter, "lighter" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_bolder, "bolder" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_font_size, "font-size" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_xx_small, "xx-small" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_x_small, "x-small" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_small, "small" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_medium, "medium" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_large, "large" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_x_large, "x-large" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_xx_large, "xx-large" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_larger, "larger" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_smaller, "smaller" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_font, "font" );
+
+
+
+/* */
+
+// Strings fuer Farb- und Hintergrund-Properties
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_color, "color" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_background, "background" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_background_color, "background-color" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_transparent, "transparent" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_repeat, "repeat" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_repeat_x, "repeat-x" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_repeat_y, "repeat-y" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_no_repeat, "no-repeat" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_top, "top" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_middle, "middle" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_bottom, "bottom" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_scroll, "scroll" );
+
+
+/* */
+
+// Strings fuer Text-Properties
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_letter_spacing, "letter-spacing" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_text_decoration, "text-decoration" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_none, "none" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_underline, "underline" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_overline, "overline" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_line_through, "line-through" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_blink, "blink" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_text_align, "text-align" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_left, "left" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_center, "center" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_right, "right" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_justify, "justify" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_text_indent, "text-indent" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_line_height, "line-height" );
+
+
+/* */
+
+// Strings fuer Box-Properties
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_margin_left, "margin-left" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_margin_right, "margin-right" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_margin_top, "margin-top" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_margin_bottom, "margin-bottom" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_margin, "margin" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_padding_top, "padding-top" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_padding_bottom, "padding-bottom" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_padding_left, "padding-left" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_padding_right, "padding-right" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_padding, "padding" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_auto, "auto" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_left_width, "border-left-width" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_right_width, "border-right-width" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_top_width, "border-top-width" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_bottom_width, "border-bottom-width" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_width, "border-width" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_color, "border-color" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_style, "border-style" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_left, "border-left" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_right, "border-right" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_top, "border-top" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border_bottom, "border-bottom" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_border, "border" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_thin, "thin" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_medium, "medium" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_thick, "thick" );
+
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_none, "none" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_dotted, "dotted" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_dashed, "dashed" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_solid, "solid" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_double, "double" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_groove, "groove" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_ridge, "ridge" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_inset, "inset" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_outset, "outset" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_width, "width" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_height, "height" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_float, "float" );
+
+/* */
+
+// Strings fuer Positioning
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_position, "position" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_absolute, "absolute" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_relative, "relative" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_static, "static" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_left, "left" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_top, "top" );
+
+/* */
+
+// Feature: PrintExt
+
+// Strings fuer Printing Extensions
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_page_break_before, "page-break-before" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_page_break_after, "page-break-after" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_page_break_inside, "page-break-inside" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_size, "size" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_widows, "widows" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_orphans, "orphans" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_marks, "marks" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_always, "always" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_avoid, "avoid" );
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_portrait, "portrait" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_landscape, "landscape" );
+
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_crop, "crop" );
+//sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_cross, "cross" );
+
+// /Feature: PrintExt
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_class_abs_pos, "sd-abs-pos" );
+
+
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_so_language, "so-language" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_P_direction, "direction" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_ltr, "ltr" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_rtl, "rtl" );
+extern sal_Char __FAR_DATA CSS1_CONSTASCII_DECL( sCSS1_PV_inherit, "inherit" );
+
+#endif
+
+
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
new file mode 100644
index 000000000000..573d5c7ebc5f
--- /dev/null
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -0,0 +1,3494 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <com/sun/star/i18n/ScriptType.hpp>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/sfx.hrc>
+#if !defined _SVSTDARR_XUB_STRLEN_DECL || !defined _SVSTDARR_USHORTS_DECL
+#define _SVSTDARR_XUB_STRLEN
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#endif
+#include <svtools/htmlout.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmltokn.h>
+#include <svl/whiter.hxx>
+#include <svx/htmlmode.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <fchrfmt.hxx>
+#include <fmtautofmt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtclds.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtflcnt.hxx>
+#include <fmtinfmt.hxx>
+#include <fmtftn.hxx>
+#include <txatbase.hxx>
+#include <frmatr.hxx>
+#include <charfmt.hxx>
+#include <fmtfld.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <ndtxt.hxx>
+#include <paratr.hxx>
+#include <poolfmt.hxx>
+#include <pagedesc.hxx>
+#include <swtable.hxx>
+#include "fldbas.hxx"
+#include <breakit.hxx>
+#include <htmlnum.hxx>
+#include <wrthtml.hxx>
+#include <htmlfly.hxx>
+#include <numrule.hxx>
+
+using namespace ::com::sun::star;
+
+/*
+ * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
+ * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
+ * definiert und mit der akt. verglichen. Bei unterschieden wird der
+ * Compiler schon meckern.
+ *
+ * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
+ * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
+ */
+#if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
+
+#define ATTRFNTAB_SIZE 130
+#if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
+#error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
+#endif
+
+#ifdef FORMAT_TABELLE
+// da sie nicht benutzt wird!
+#define FORMATTAB_SIZE 7
+#if FORMATTAB_SIZE != RES_FMT_END - RES_FMT_BEGIN
+#error Format-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
+#endif
+#endif
+
+#define NODETAB_SIZE 3
+#if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
+#error Node-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
+#endif
+
+#endif
+
+#define HTML_BULLETCHAR_DISC 34
+#define HTML_BULLETCHAR_CIRCLE 38
+#define HTML_BULLETCHAR_SQUARE 36
+
+#define COLFUZZY 20
+
+//-----------------------------------------------------------------------
+
+HTMLOutEvent __FAR_DATA aAnchorEventTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_O_SDonclick, OOO_STRING_SVTOOLS_HTML_O_onclick, SFX_EVENT_MOUSECLICK_OBJECT },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonmouseover, OOO_STRING_SVTOOLS_HTML_O_onmouseover, SFX_EVENT_MOUSEOVER_OBJECT },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonmouseout, OOO_STRING_SVTOOLS_HTML_O_onmouseout, SFX_EVENT_MOUSEOUT_OBJECT },
+ { 0, 0, 0 }
+};
+
+static Writer& OutHTML_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt );
+
+static Writer& OutHTML_HoriSpacer( Writer& rWrt, INT16 nSize )
+{
+ ASSERT( nSize>0, "horizontaler SPACER mit negativem Wert?" )
+ if( nSize <= 0 )
+ return rWrt;
+
+ if( Application::GetDefaultDevice() )
+ {
+ nSize = (INT16)Application::GetDefaultDevice()
+ ->LogicToPixel( Size(nSize,0), MapMode(MAP_TWIP) ).Width();
+ }
+
+ ByteString sOut( '<' );
+ (((((((((sOut += OOO_STRING_SVTOOLS_HTML_spacer)
+ += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=') += OOO_STRING_SVTOOLS_HTML_SPTYPE_horizontal)
+ += ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
+ +=ByteString::CreateFromInt32(nSize)) += '>';
+
+ rWrt.Strm() << sOut.GetBuffer();
+
+ return rWrt;
+}
+
+USHORT SwHTMLWriter::GetDefListLvl( const String& rNm, USHORT nPoolId )
+{
+ if( nPoolId == RES_POOLCOLL_HTML_DD )
+ {
+ return 1 | HTML_DLCOLL_DD;
+ }
+ else if( nPoolId == RES_POOLCOLL_HTML_DT )
+ {
+ return 1 | HTML_DLCOLL_DT;
+ }
+
+ String sDTDD( String::CreateFromAscii(OOO_STRING_SVTOOLS_HTML_dt) );
+ sDTDD += ' ';
+ if( COMPARE_EQUAL == sDTDD.CompareTo( rNm, sDTDD.Len() ) )
+ // DefinitionList - term
+ return (USHORT)rNm.Copy( sDTDD.Len() ).ToInt32() | HTML_DLCOLL_DT;
+
+ sDTDD.AssignAscii( OOO_STRING_SVTOOLS_HTML_dd );
+ sDTDD += ' ';
+ if( COMPARE_EQUAL == sDTDD.CompareTo( rNm, sDTDD.Len() ) )
+ // DefinitionList - definition
+ return (USHORT)rNm.Copy( sDTDD.Len() ).ToInt32() | HTML_DLCOLL_DD;
+
+ return 0;
+}
+
+void SwHTMLWriter::OutAndSetDefList( USHORT nNewLvl )
+{
+ // eventuell muss erst mal eine Liste aufgemacht werden
+ if( nDefListLvl < nNewLvl )
+ {
+ // output </pre> for the previous(!) pararagraph, if required.
+ // Preferable, the <pre> is exported by OutHTML_SwFmtOff for the
+ // previous paragraph already, but that's not possible, because a very
+ // deep look at the next paragraph (this one) is required to figure
+ // out that a def list starts here.
+
+ ChangeParaToken( 0 );
+
+ // entsprechend dem Level-Unterschied schreiben!
+ for( USHORT i=nDefListLvl; i<nNewLvl; i++ )
+ {
+ if( bLFPossible )
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist, TRUE );
+ IncIndentLevel();
+ bLFPossible = TRUE;
+ }
+ }
+ else if( nDefListLvl > nNewLvl )
+ {
+ for( USHORT i=nNewLvl ; i < nDefListLvl; i++ )
+ {
+ DecIndentLevel();
+ if( bLFPossible )
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_deflist, FALSE );
+ bLFPossible = TRUE;
+ }
+ }
+
+ nDefListLvl = nNewLvl;
+}
+
+
+void SwHTMLWriter::ChangeParaToken( USHORT nNew )
+{
+ if( nNew != nLastParaToken && HTML_PREFORMTXT_ON == nLastParaToken )
+ {
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_preformtxt, FALSE );
+ bLFPossible = TRUE;
+ }
+ nLastParaToken = nNew;
+}
+
+sal_uInt16 SwHTMLWriter::GetCSS1ScriptForScriptType( sal_uInt16 nScriptType )
+{
+ sal_uInt16 nRet = CSS1_OUTMODE_ANY_SCRIPT;
+
+ switch( nScriptType )
+ {
+ case i18n::ScriptType::LATIN:
+ nRet = CSS1_OUTMODE_WESTERN;
+ break;
+ case i18n::ScriptType::ASIAN:
+ nRet = CSS1_OUTMODE_CJK;
+ break;
+ case i18n::ScriptType::COMPLEX:
+ nRet = CSS1_OUTMODE_CTL;
+ break;
+ }
+
+ return nRet;
+}
+
+// fuer die Formate muesste eine einzige Ausgabe-Funktion genuegen !
+/*
+ * Formate wie folgt ausgeben:
+ * - fuer Formate, fuer die es entsprechende HTML-Tags gibt wird das
+ * Tag ausgegeben
+ * - fuer alle anderen wird ein Absatz-Tag <P> ausgegeben und bUserFmt
+ * gesetzt
+ * - Wenn eine Absatz-Ausrichtung am uebergebenen Item-Set des Nodes
+ * oder im Item-Set des Format gesetzt ist, wird ein ALIGN=xxx ausgegeben,
+ * sofern HTML es zulaesst
+ * - in jedem Fall wird harte Attributierung als STYLE-Option geschrieben.
+ * Wenn bUserFmt nicht gesetzt ist, wird nur der uebergebene Item-Set
+ * betrachtet. Sonst werden auch Attribute des Formats ausgegeben.
+ */
+
+struct SwHTMLTxtCollOutputInfo
+{
+ ByteString aToken; // auszugendens End-Token
+ SfxItemSet *pItemSet; // harte Attributierung
+
+ BOOL bInNumBulList; // in einer Aufzaehlungs-Liste;
+ BOOL bParaPossible; // ein </P> darf zusaetzlich ausgegeben werden
+ BOOL bOutPara; // ein </P> soll ausgegeben werden
+ BOOL bOutDiv; // write a </DIV>
+
+ SwHTMLTxtCollOutputInfo() :
+ pItemSet( 0 ),
+ bInNumBulList( FALSE ),
+ bParaPossible( FALSE ),
+ bOutPara( FALSE ),
+ bOutDiv( FALSE )
+ {}
+
+ ~SwHTMLTxtCollOutputInfo();
+
+ BOOL HasParaToken() const { return aToken.Len()==1 && aToken.GetChar(0)=='P'; }
+ BOOL ShouldOutputToken() const { return bOutPara || !HasParaToken(); }
+};
+
+SwHTMLTxtCollOutputInfo::~SwHTMLTxtCollOutputInfo()
+{
+ delete pItemSet;
+}
+
+struct SwHTMLFmtInfo
+{
+ const SwFmt *pFmt; // das Format selbst
+ const SwFmt *pRefFmt; // das Vergleichs-Format
+
+ ByteString aToken; // das auszugebende Token
+ String aClass; // die auszugebende Klasse
+
+ SfxItemSet *pItemSet; // der auszugebende Attribut-Set
+
+ sal_Int32 nLeftMargin; // ein par default-Werte fuer
+ sal_Int32 nRightMargin; // Absatz-Vorlagen
+ short nFirstLineIndent;
+
+ USHORT nTopMargin;
+ USHORT nBottomMargin;
+
+ sal_Bool bScriptDependent;
+
+ // Konstruktor fuer einen Dummy zum Suchen
+ SwHTMLFmtInfo( const SwFmt *pF ) :
+ pFmt( pF ), pItemSet( 0 )
+ {}
+
+
+ // Konstruktor zum Erstellen der Format-Info
+ SwHTMLFmtInfo( const SwFmt *pFmt, SwDoc *pDoc, SwDoc *pTemlate,
+ BOOL bOutStyles, LanguageType eDfltLang=LANGUAGE_DONTKNOW,
+ sal_uInt16 nScript=CSS1_OUTMODE_ANY_SCRIPT,
+ BOOL bHardDrop=FALSE );
+ ~SwHTMLFmtInfo();
+
+ friend BOOL operator==( const SwHTMLFmtInfo& rInfo1,
+ const SwHTMLFmtInfo& rInfo2 )
+ {
+ return (long)rInfo1.pFmt == (long)rInfo2.pFmt;
+ }
+
+ friend BOOL operator<( const SwHTMLFmtInfo& rInfo1,
+ const SwHTMLFmtInfo& rInfo2 )
+ {
+ return (long)rInfo1.pFmt < (long)rInfo2.pFmt;
+ }
+
+};
+
+SV_IMPL_OP_PTRARR_SORT( SwHTMLFmtInfos, SwHTMLFmtInfo* )
+
+SwHTMLFmtInfo::SwHTMLFmtInfo( const SwFmt *pF, SwDoc *pDoc, SwDoc *pTemplate,
+ BOOL bOutStyles,
+ LanguageType eDfltLang,
+ sal_uInt16 nCSS1Script, BOOL bHardDrop ) :
+ pFmt( pF ), pItemSet( 0 ), bScriptDependent( sal_False )
+{
+ USHORT nRefPoolId = 0;
+ // Den Selektor des Formats holen
+ USHORT nDeep = SwHTMLWriter::GetCSS1Selector( pFmt, aToken, aClass,
+ nRefPoolId );
+ ASSERT( nDeep ? aToken.Len()>0 : aToken.Len()==0,
+ "Hier stimmt doch was mit dem Token nicht!" );
+ ASSERT( nDeep ? nRefPoolId : !nRefPoolId,
+ "Hier stimmt doch was mit der Vergleichs-Vorlage nicht!" );
+
+ BOOL bTxtColl = pFmt->Which() == RES_TXTFMTCOLL ||
+ pFmt->Which() == RES_CONDTXTFMTCOLL;
+
+ const SwFmt *pReferenceFmt = 0; // Vergleichs-Format
+ sal_Bool bSetDefaults = sal_True, bClearSame = sal_True;
+ if( nDeep != 0 )
+ {
+ // Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
+ // solchen abgeleitet
+ if( !bOutStyles )
+ {
+ // wenn keine Styles exportiert werden, muss evtl. zusaetlich
+ // harte Attributierung geschrieben werden
+ switch( nDeep )
+ {
+ case CSS1_FMT_ISTAG:
+ case CSS1_FMT_CMPREF:
+ // fuer HTML-Tag-Vorlagen die Unterscheide zum Original
+ // (sofern verfuegbar)
+ pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId,
+ pTemplate );
+ break;
+
+ default:
+ // sonst die zur HTML-Tag-Vorlage des Originals oder des
+ // aktuellen Doks, wenn die nicht verfuegbar ist
+ if( pTemplate )
+ pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId,
+ pTemplate );
+ else
+ pReferenceFmt = SwHTMLWriter::GetParentFmt( *pFmt, nDeep );
+ break;
+ }
+ }
+ }
+ else if( bTxtColl )
+ {
+ // Nicht von einer HTML-Tag-Vorlage abgeleitete Absatz-Vorlagen
+ // muessen als harte Attributierung relativ zur Textkoerper-Volage
+ // exportiert werden. Fuer Nicht-Styles-Export sollte die der
+ // HTML-Vorlage als Referenz dienen
+ if( !bOutStyles && pTemplate )
+ pReferenceFmt = pTemplate->GetTxtCollFromPool( RES_POOLCOLL_TEXT, false );
+ else
+ pReferenceFmt = pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT, false );
+ }
+
+ if( pReferenceFmt || nDeep==0 )
+ {
+ pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
+ pFmt->GetAttrSet().GetRanges() );
+ // wenn Unterschiede zu einer anderen Vorlage geschrieben werden
+ // sollen ist harte Attributierung noetig. Fuer Vorlagen, die
+ // nicht von HTML-Tag-Vorlagen abgeleitet sind, gilt das immer
+
+ pItemSet->Set( pFmt->GetAttrSet(), TRUE );
+
+ if( pReferenceFmt )
+ SwHTMLWriter::SubtractItemSet( *pItemSet, pReferenceFmt->GetAttrSet(),
+ bSetDefaults, bClearSame );
+
+ // einen leeren Item-Set gleich loeschen, das spart speater
+ // Arbeit
+ if( !pItemSet->Count() )
+ {
+ delete pItemSet;
+ pItemSet = 0;
+ }
+ }
+
+ if( bTxtColl )
+ {
+ if( bOutStyles )
+ {
+ // We have to add hard attributes for any script dependent
+ // item that is not accessed by the style
+ static sal_uInt16 aWhichIds[3][4] =
+ {
+ { RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
+ RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT },
+ { RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
+ RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT },
+ { RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE,
+ RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT }
+ };
+
+ sal_uInt16 nRef = 0;
+ sal_uInt16 aSets[2] = {0,0};
+ switch( nCSS1Script )
+ {
+ case CSS1_OUTMODE_WESTERN:
+ nRef = 0;
+ aSets[0] = 1;
+ aSets[1] = 2;
+ break;
+ case CSS1_OUTMODE_CJK:
+ nRef = 1;
+ aSets[0] = 0;
+ aSets[1] = 2;
+ break;
+ case CSS1_OUTMODE_CTL:
+ nRef = 2;
+ aSets[0] = 0;
+ aSets[1] = 1;
+ break;
+ }
+ for( sal_uInt16 i=0; i<4; i++ )
+ {
+ const SfxPoolItem& rRef = pFmt->GetFmtAttr( aWhichIds[nRef][i] );
+ for( sal_uInt16 j=0; j<2; j++ )
+ {
+ const SfxPoolItem& rSet = pFmt->GetFmtAttr( aWhichIds[aSets[j]][i] );
+ if( rSet != rRef )
+ {
+ if( !pItemSet )
+ pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
+ pFmt->GetAttrSet().GetRanges() );
+ pItemSet->Put( rSet );
+ }
+ }
+ }
+ }
+
+ // Ggf. noch ein DropCap-Attribut uebernehmen
+ if( bOutStyles && bHardDrop && nDeep != 0 )
+ {
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET==pFmt->GetAttrSet().GetItemState(
+ RES_PARATR_DROP, TRUE, &pItem ) )
+ {
+ BOOL bPut = TRUE;
+ if( pTemplate )
+ {
+ pReferenceFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
+ const SfxPoolItem *pRefItem;
+ BOOL bRefItemSet =
+ SFX_ITEM_SET==pReferenceFmt->GetAttrSet().GetItemState(
+ RES_PARATR_DROP, TRUE, &pRefItem );
+ bPut = !bRefItemSet || *pItem!=*pRefItem;
+ }
+ if( bPut )
+ {
+ if( !pItemSet )
+ pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
+ pFmt->GetAttrSet().GetRanges() );
+ pItemSet->Put( *pItem );
+ }
+ }
+ }
+
+
+ // Die diversen default-Abstaende aus der Vorlage oder der
+ // Vergleischs-Vorlage merken
+ const SvxLRSpaceItem &rLRSpace =
+ (pReferenceFmt ? pReferenceFmt : pFmt)->GetLRSpace();
+ nLeftMargin = rLRSpace.GetTxtLeft();
+ nRightMargin = rLRSpace.GetRight();
+ nFirstLineIndent = rLRSpace.GetTxtFirstLineOfst();
+
+ const SvxULSpaceItem &rULSpace =
+ (pReferenceFmt ? pReferenceFmt : pFmt)->GetULSpace();
+ nTopMargin = rULSpace.GetUpper();
+ nBottomMargin = rULSpace.GetLower();
+
+ // export language if it differs from the default language
+ sal_uInt16 nWhichId =
+ SwHTMLWriter::GetLangWhichIdFromScript( nCSS1Script );
+ const SvxLanguageItem& rLang =
+ (const SvxLanguageItem&)pFmt->GetFmtAttr( nWhichId );
+ LanguageType eLang = rLang.GetLanguage();
+ if( eLang != eDfltLang )
+ {
+ if( !pItemSet )
+ pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
+ pFmt->GetAttrSet().GetRanges() );
+ pItemSet->Put( rLang );
+ }
+
+ static sal_uInt16 aWhichIds[3] =
+ { RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
+ RES_CHRATR_CTL_LANGUAGE };
+ for( sal_uInt16 i=0; i<3; i++ )
+ {
+ if( aWhichIds[i] != nWhichId )
+ {
+ const SvxLanguageItem& rTmpLang =
+ (const SvxLanguageItem&)pFmt->GetFmtAttr(aWhichIds[i]);
+ if( rTmpLang.GetLanguage() != eLang )
+ {
+ if( !pItemSet )
+ pItemSet = new SfxItemSet( *pFmt->GetAttrSet().GetPool(),
+ pFmt->GetAttrSet().GetRanges() );
+ pItemSet->Put( rTmpLang );
+ }
+ }
+ }
+ }
+}
+
+SwHTMLFmtInfo::~SwHTMLFmtInfo()
+{
+ delete pItemSet;
+}
+
+void OutHTML_SwFmt( Writer& rWrt, const SwFmt& rFmt,
+ const SfxItemSet *pNodeItemSet,
+ SwHTMLTxtCollOutputInfo& rInfo )
+{
+ ASSERT( RES_CONDTXTFMTCOLL==rFmt.Which() || RES_TXTFMTCOLL==rFmt.Which(),
+ "keine Absatz-Vorlage" );
+
+ SwHTMLWriter & rHWrt = (SwHTMLWriter&)rWrt;
+
+ // Erstmal ein par Flags ...
+ USHORT nNewDefListLvl = 0;
+ USHORT nNumStart = USHRT_MAX;
+ BOOL bForceDL = FALSE;
+ BOOL bDT = FALSE;
+ rInfo.bInNumBulList = FALSE; // Wir sind in einer Liste?
+ BOOL bNumbered = FALSE; // Der aktuelle Absatz ist numeriert
+ BOOL bPara = FALSE; // das aktuelle Token ist <P>
+ rInfo.bParaPossible = FALSE; // ein <P> darf zusaetzlich ausgegeben werden
+ BOOL bNoEndTag = FALSE; // kein End-Tag ausgeben
+
+ rHWrt.bNoAlign = FALSE; // kein ALIGN=... moeglich
+ BOOL bNoStyle = FALSE; // kein STYLE=... moeglich
+ BYTE nBulletGrfLvl = 255; // Die auszugebende Bullet-Grafik
+
+ // Sind wir in einer Aufzaehlungs- oder Numerierungliste?
+ const SwTxtNode* pTxtNd = rWrt.pCurPam->GetNode()->GetTxtNode();
+
+ SwHTMLNumRuleInfo aNumInfo;
+ if( rHWrt.GetNextNumInfo() )
+ {
+ aNumInfo = *rHWrt.GetNextNumInfo();
+ rHWrt.ClearNextNumInfo();
+ }
+ else
+ {
+ aNumInfo.Set( *pTxtNd );
+ }
+
+ if( aNumInfo.GetNumRule() )
+ {
+ rInfo.bInNumBulList = TRUE;
+ nNewDefListLvl = 0;
+
+ // ist der aktuelle Absatz numeriert?
+ bNumbered = aNumInfo.IsNumbered();
+ BYTE nLvl = aNumInfo.GetLevel();
+
+ ASSERT( pTxtNd->GetActualListLevel() == nLvl,
+ "Gemerkter Num-Level ist falsch" );
+ ASSERT( bNumbered == static_cast< BOOL >(pTxtNd->IsCountedInList()),
+ "Gemerkter Numerierungs-Zustand ist falsch" );
+
+ if( bNumbered )
+ {
+ nBulletGrfLvl = nLvl; // nur veruebergehend!!!
+ // --> OD 2005-11-15 #i57919#
+ // correction of re-factoring done by cws swnumtree:
+ // - <nNumStart> has to contain the restart value, if the
+ // numbering is restarted at this text node. Value <USHRT_MAX>
+ // indicates, that no additional restart value has to be written.
+ if ( pTxtNd->IsListRestart() )
+ {
+ nNumStart = static_cast< USHORT >(pTxtNd->GetActualListStartValue());
+ }
+ // <--
+ DBG_ASSERT( rHWrt.nLastParaToken == 0,
+ "<PRE> wurde nicht vor <LI> beendet." );
+ }
+ }
+
+ // Jetzt holen wir das Token und ggf. die Klasse
+ SwHTMLFmtInfo aFmtInfo( &rFmt );
+ USHORT nArrayPos;
+ const SwHTMLFmtInfo *pFmtInfo;
+ if( rHWrt.aTxtCollInfos.Seek_Entry( &aFmtInfo, &nArrayPos ) )
+ {
+ pFmtInfo = rHWrt.aTxtCollInfos[nArrayPos];
+ }
+ else
+ {
+ pFmtInfo = new SwHTMLFmtInfo( &rFmt, rWrt.pDoc, rHWrt.pTemplate,
+ rHWrt.bCfgOutStyles, rHWrt.eLang,
+ rHWrt.nCSS1Script,
+ !rHWrt.IsHTMLMode(HTMLMODE_DROPCAPS) );
+ rHWrt.aTxtCollInfos.C40_PTR_INSERT( SwHTMLFmtInfo, pFmtInfo );
+ String aName( rFmt.GetName() );
+ if( rHWrt.aScriptParaStyles.Seek_Entry( &aName ) )
+ ((SwHTMLFmtInfo *)pFmtInfo)->bScriptDependent = sal_True;
+ }
+
+ // Jetzt wird festgelegt, was aufgrund des Tokens so moeglich ist
+ USHORT nToken = 0; // Token fuer Tag-Wechsel
+ BOOL bOutNewLine = FALSE; // nur ein LF ausgeben?
+ if( pFmtInfo->aToken.Len() )
+ {
+ // Es ist eine HTML-Tag-Vorlage oder die Vorlage ist von einer
+ // solchen abgeleitet
+ rInfo.aToken = pFmtInfo->aToken;
+
+ // der erste Buchstabe reicht meistens
+ switch( rInfo.aToken.GetChar( 0 ) )
+ {
+ case 'A': ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_address),
+ "Doch kein ADDRESS?" );
+ rInfo.bParaPossible = TRUE;
+ rHWrt.bNoAlign = TRUE;
+ break;
+
+ case 'B': ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_blockquote),
+ "Doch kein BLOCKQUOTE?" );
+ rInfo.bParaPossible = TRUE;
+ rHWrt.bNoAlign = TRUE;
+ break;
+
+ case 'P': if( rInfo.aToken.Len() == 1 )
+ {
+ bPara = TRUE;
+ }
+ else
+ {
+ ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_preformtxt),
+ "Doch kein PRE?" );
+ if( HTML_PREFORMTXT_ON == rHWrt.nLastParaToken )
+ {
+ bOutNewLine = TRUE;
+ }
+ else
+ {
+ nToken = HTML_PREFORMTXT_ON;
+ rHWrt.bNoAlign = TRUE;
+ bNoEndTag = TRUE;
+ }
+ }
+ break;
+
+ case 'D': ASSERT( rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_dt) ||
+ rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_dd),
+ "Doch kein DD/DT?" );
+ bDT = rInfo.aToken.Equals(OOO_STRING_SVTOOLS_HTML_dt);
+ rInfo.bParaPossible = !bDT;
+ rHWrt.bNoAlign = TRUE;
+ bForceDL = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ // alle Vorlagen, die nicht einem HTML-Tag entsprechen oder von
+ // diesem abgeleitet sind, werden als <P> exportiert
+
+ rInfo.aToken = OOO_STRING_SVTOOLS_HTML_parabreak;
+ bPara = TRUE;
+ }
+
+ // Falls noetig, die harte Attributierung der Vorlage uebernehmen
+ if( pFmtInfo->pItemSet )
+ {
+ ASSERT( !rInfo.pItemSet, "Wo kommt der Item-Set her?" );
+ rInfo.pItemSet = new SfxItemSet( *pFmtInfo->pItemSet );
+ }
+
+ // und noch die harte Attributierung des Absatzes dazunehmen
+ if( pNodeItemSet )
+ {
+ if( rInfo.pItemSet )
+ rInfo.pItemSet->Put( *pNodeItemSet );
+ else
+ rInfo.pItemSet = new SfxItemSet( *pNodeItemSet );
+ }
+
+ // den unteren Absatz-Abstand brauchen wir noch
+ const SvxULSpaceItem& rULSpace =
+ pNodeItemSet ? ((const SvxULSpaceItem &)pNodeItemSet->Get(RES_UL_SPACE))
+ : rFmt.GetULSpace();
+
+
+ if( (rHWrt.bOutHeader &&
+ rWrt.pCurPam->GetPoint()->nNode.GetIndex() ==
+ rWrt.pCurPam->GetMark()->nNode.GetIndex()) ||
+ rHWrt.bOutFooter )
+ {
+ if( rHWrt.bCfgOutStyles )
+ {
+ SvxULSpaceItem aULSpaceItem( rULSpace );
+ if( rHWrt.bOutHeader )
+ aULSpaceItem.SetLower( rHWrt.nHeaderFooterSpace );
+ else
+ aULSpaceItem.SetUpper( rHWrt.nHeaderFooterSpace );
+
+ if( !rInfo.pItemSet )
+ rInfo.pItemSet = new SfxItemSet(
+ *rFmt.GetAttrSet().GetPool(),
+ RES_UL_SPACE, RES_UL_SPACE );
+ rInfo.pItemSet->Put( aULSpaceItem );
+ }
+ rHWrt.bOutHeader = FALSE;
+ rHWrt.bOutFooter = FALSE;
+ }
+
+ if( bOutNewLine )
+ {
+ // nur einen Zeilen-Umbruch (ohne Einrueckung) am Absatz-Anfang
+ // ausgeben
+ rInfo.aToken.Erase(); // kein End-Tag ausgeben
+ rWrt.Strm() << SwHTMLWriter::sNewLine;
+
+ return;
+ }
+
+
+ // soll ein ALIGN=... geschrieben werden?
+ const SfxPoolItem* pAdjItem = 0;
+ const SfxPoolItem* pItem;
+
+ if( rInfo.pItemSet &&
+ SFX_ITEM_SET == rInfo.pItemSet->GetItemState( RES_PARATR_ADJUST,
+ FALSE, &pItem ) )
+ {
+ pAdjItem = pItem;
+ }
+
+ // Unteren Absatz-Abstand beachten ? (nie im letzen Absatz von
+ // Tabellen)
+ BOOL bUseParSpace = !rHWrt.bOutTable ||
+ (rWrt.pCurPam->GetPoint()->nNode.GetIndex() !=
+ rWrt.pCurPam->GetMark()->nNode.GetIndex());
+ // Wenn Styles exportiert werden, wird aus eingerueckten Absaetzen
+ // eine Definitions-Liste
+ const SvxLRSpaceItem& rLRSpace =
+ pNodeItemSet ? ((const SvxLRSpaceItem &)pNodeItemSet->Get(RES_LR_SPACE))
+ : rFmt.GetLRSpace();
+ if( (!rHWrt.bCfgOutStyles || bForceDL) && !rInfo.bInNumBulList )
+ {
+ sal_Int32 nLeftMargin;
+ if( bForceDL )
+ nLeftMargin = rLRSpace.GetTxtLeft();
+ else
+ nLeftMargin = rLRSpace.GetTxtLeft() > pFmtInfo->nLeftMargin
+ ? rLRSpace.GetTxtLeft() - pFmtInfo->nLeftMargin
+ : 0;
+
+ if( nLeftMargin > 0 && rHWrt.nDefListMargin > 0 )
+ {
+ nNewDefListLvl = static_cast< USHORT >((nLeftMargin + (rHWrt.nDefListMargin/2)) /
+ rHWrt.nDefListMargin);
+ if( nNewDefListLvl == 0 && bForceDL && !bDT )
+ nNewDefListLvl = 1;
+ }
+ else
+ {
+ // If the left margin is 0 or negative, emulating indent
+ // with <dd> does not work. We then set a def list only if
+ // the dd style is used.
+ nNewDefListLvl = (bForceDL&& !bDT) ? 1 : 0;
+ }
+
+ BOOL bIsNextTxtNode =
+ rWrt.pDoc->GetNodes()[rWrt.pCurPam->GetPoint()->nNode.GetIndex()+1]
+ ->IsTxtNode();
+
+ if( bForceDL && bDT )
+ {
+ // Statt eines DD muessen wir hier auch ein DT der Ebene
+ // darueber nehmen
+ nNewDefListLvl++;
+ }
+ else if( !nNewDefListLvl && !rHWrt.bCfgOutStyles && bPara &&
+ rULSpace.GetLower()==0 &&
+ ((bUseParSpace && bIsNextTxtNode) || rHWrt.nDefListLvl==1) &&
+ (!pAdjItem || SVX_ADJUST_LEFT==
+ ((const SvxAdjustItem *)pAdjItem)->GetAdjust()) )
+ {
+ // Absaetze ohne unteren Abstand als DT exportieren
+ nNewDefListLvl = 1;
+ bDT = TRUE;
+ rInfo.bParaPossible = FALSE;
+ rHWrt.bNoAlign = TRUE;
+ }
+ }
+
+ if( nNewDefListLvl != rHWrt.nDefListLvl )
+ rHWrt.OutAndSetDefList( nNewDefListLvl );
+
+ // ggf. eine Aufzaehlung- oder Numerierungsliste beginnen
+ if( rInfo.bInNumBulList )
+ {
+ ASSERT( !rHWrt.nDefListLvl, "DL in OL geht nicht!" );
+ OutHTML_NumBulListStart( rHWrt, aNumInfo );
+
+ if( bNumbered )
+ {
+ if( rHWrt.aBulletGrfs[nBulletGrfLvl].Len() )
+ bNumbered = FALSE;
+ else
+ nBulletGrfLvl = 255;
+ }
+ }
+
+ // Die Defaults aus der Vorlage merken, denn sie muessen nicht
+ // exportiert werden
+ rHWrt.nDfltLeftMargin = pFmtInfo->nLeftMargin;
+ rHWrt.nDfltRightMargin = pFmtInfo->nRightMargin;
+ rHWrt.nDfltFirstLineIndent = pFmtInfo->nFirstLineIndent;
+
+ if( rInfo.bInNumBulList )
+ {
+ if( !rHWrt.IsHTMLMode( HTMLMODE_LSPACE_IN_NUMBUL ) )
+ rHWrt.nDfltLeftMargin = rLRSpace.GetTxtLeft();
+
+ // In Numerierungs-Listen keinen Ertzeilen-Einzug ausgeben.
+ rHWrt.nFirstLineIndent = rLRSpace.GetTxtFirstLineOfst();
+ }
+
+ if( rInfo.bInNumBulList && bNumbered && bPara && !rHWrt.bCfgOutStyles )
+ {
+ // ein einzelnes LI hat keinen Abstand
+ rHWrt.nDfltTopMargin = 0;
+ rHWrt.nDfltBottomMargin = 0;
+ }
+ else if( rHWrt.nDefListLvl && bPara )
+ {
+ // ein einzelnes DD hat auch keinen Abstand
+ rHWrt.nDfltTopMargin = 0;
+ rHWrt.nDfltBottomMargin = 0;
+ }
+ else
+ {
+ rHWrt.nDfltTopMargin = pFmtInfo->nTopMargin;
+ // #60393#: Wenn im letzten Absatz einer Tabelle der
+ // untere Absatz-Abstand veraendert wird, vertut sich
+ // Netscape total. Deshalb exportieren wir hier erstmal
+ // nichts, indem wir den Abstand aus dem Absatz als Default
+ // setzen.
+ if( rHWrt.bCfgNetscape4 && !bUseParSpace )
+ rHWrt.nDfltBottomMargin = rULSpace.GetLower();
+ else
+ rHWrt.nDfltBottomMargin = pFmtInfo->nBottomMargin;
+ }
+
+ if( rHWrt.nDefListLvl )
+ {
+ rHWrt.nLeftMargin =
+ (rHWrt.nDefListLvl-1) * rHWrt.nDefListMargin;
+ }
+
+ if( rHWrt.bLFPossible )
+ rHWrt.OutNewLine(); // Absatz-Tag in neue Zeile
+ rInfo.bOutPara = FALSE;
+
+ // das ist jetzt unser neues Token
+ rHWrt.ChangeParaToken( nToken );
+
+ BOOL bHasParSpace = bUseParSpace && rULSpace.GetLower() > 0;
+
+ // ggf ein List-Item aufmachen
+ if( rInfo.bInNumBulList && bNumbered )
+ {
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_li;
+ if( USHRT_MAX != nNumStart )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += '=')
+ += ByteString::CreateFromInt32(nNumStart);
+ sOut += '>';
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+
+ if( rHWrt.nDefListLvl > 0 && !bForceDL )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), bDT ? OOO_STRING_SVTOOLS_HTML_dt : OOO_STRING_SVTOOLS_HTML_dd );
+ }
+
+ if( pAdjItem &&
+ rHWrt.IsHTMLMode( HTMLMODE_NO_CONTROL_CENTERING ) &&
+ rHWrt.HasControls() )
+ {
+ // #64687#: The align=... attribute does behave strange in netscape
+ // if there are controls in a paragraph, because the control and
+ // all text behind the control does not recognize this attribute.
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_division;
+ rWrt.Strm() << sOut.GetBuffer();
+
+ rHWrt.bTxtAttr = FALSE;
+ rHWrt.bOutOpts = TRUE;
+ OutHTML_SvxAdjust( rWrt, *pAdjItem );
+ rWrt.Strm() << '>';
+ pAdjItem = 0;
+ rHWrt.bNoAlign = FALSE;
+ rInfo.bOutDiv = TRUE;
+ rHWrt.IncIndentLevel();
+ rHWrt.bLFPossible = TRUE;
+ rHWrt.OutNewLine();
+ }
+
+ // fuer BLOCKQUOTE, ADDRESS und DD wird noch ein Absatz-Token
+ // ausgegeben, wenn,
+ // - keine Styles geschrieben werden, und
+ // - ein untere Abstand oder eine Absatz-Ausrichtung existiert
+ ByteString aToken = rInfo.aToken;
+ if( !rHWrt.bCfgOutStyles && rInfo.bParaPossible && !bPara &&
+ (bHasParSpace || pAdjItem) )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rInfo.aToken.GetBuffer() );
+ aToken = OOO_STRING_SVTOOLS_HTML_parabreak;
+ bPara = TRUE;
+ rHWrt.bNoAlign = FALSE;
+ bNoStyle = FALSE;
+ }
+
+ LanguageType eLang = rInfo.pItemSet
+ ? ((const SvxLanguageItem&)rInfo.pItemSet->Get(SwHTMLWriter::GetLangWhichIdFromScript(rHWrt.nCSS1Script))).GetLanguage()
+ : rHWrt.eLang;
+
+ if( rInfo.pItemSet )
+ {
+ static sal_uInt16 aWhichIds[3] = { RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE };
+
+ for( sal_uInt16 i=0; i<3; i++ )
+ {
+ // export language if it differs from the default language only.
+ const SfxPoolItem *pTmpItem;
+ if( SFX_ITEM_SET == rInfo.pItemSet->GetItemState( aWhichIds[i],
+ sal_True, &pTmpItem ) &&
+ ((const SvxLanguageItem *)pTmpItem)->GetLanguage() == eLang )
+ rInfo.pItemSet->ClearItem( aWhichIds[i] );
+ }
+ }
+
+ // and the text direction
+ sal_uInt16 nDir = rHWrt.GetHTMLDirection(
+ (pNodeItemSet ? static_cast < const SvxFrameDirectionItem& >(
+ pNodeItemSet->Get( RES_FRAMEDIR ) )
+ : rFmt.GetFrmDir() ).GetValue() );
+
+ // Ein <P> wird nur geschrieben, wenn
+ // - wir in keiner OL/UL/DL sind, oder
+ // - der Absatz einer OL/UL nicht numeriert ist, oder
+ // - keine Styles exportiert werden und
+ // - ein unterer Abstand oder
+ // - eine Absatz-Ausrichtung existiert, ode
+ // - Styles exportiert werden und,
+ // - die Textkoerper-Vorlage geaendert wurde, oder
+ // - ein Benutzer-Format exportiert wird, oder
+ // - Absatz-Attribute existieren
+ if( !bPara ||
+ (!rInfo.bInNumBulList && !rHWrt.nDefListLvl) ||
+ (rInfo.bInNumBulList && !bNumbered) ||
+ (!rHWrt.bCfgOutStyles &&
+ (bHasParSpace || pAdjItem ||
+ (eLang != LANGUAGE_DONTKNOW && eLang != rHWrt.eLang))) ||
+ nDir != rHWrt.nDirection ||
+ rHWrt.bCfgOutStyles )
+ {
+ // jetzt werden Optionen ausgegeben
+ rHWrt.bTxtAttr = FALSE;
+ rHWrt.bOutOpts = TRUE;
+
+ ByteString sOut( '<' );
+ sOut += aToken;
+
+ if( eLang != LANGUAGE_DONTKNOW && eLang != rHWrt.eLang )
+ {
+ rWrt.Strm() << sOut.GetBuffer();
+ rHWrt.OutLanguage( eLang );
+ sOut.Erase();
+ }
+
+ if( nDir != rHWrt.nDirection )
+ {
+ if( sOut.Len() )
+ {
+ rWrt.Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ }
+ rHWrt.OutDirection( nDir );
+ }
+
+ if( rHWrt.bCfgOutStyles &&
+ (pFmtInfo->aClass.Len() || pFmtInfo->bScriptDependent) )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ String aClass( pFmtInfo->aClass );
+ if( pFmtInfo->bScriptDependent )
+ {
+ if( aClass.Len() )
+ aClass += '-';
+ switch( rHWrt.nCSS1Script )
+ {
+ case CSS1_OUTMODE_WESTERN:
+ aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
+ break;
+ case CSS1_OUTMODE_CJK:
+ aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
+ break;
+ case CSS1_OUTMODE_CTL:
+ aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
+ break;
+ }
+ }
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aClass,
+ rHWrt.eDestEnc, &rHWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ rWrt.Strm() << sOut.GetBuffer();
+
+ // ggf. Ausrichtung ausgeben.
+ if( !rHWrt.bNoAlign && pAdjItem )
+ OutHTML_SvxAdjust( rWrt, *pAdjItem );
+
+ // und nun ggf. noch die STYLE-Option
+ if( rHWrt.bCfgOutStyles && rInfo.pItemSet && !bNoStyle)
+ {
+ OutCSS1_ParaTagStyleOpt( rWrt, *rInfo.pItemSet );
+ }
+
+ rWrt.Strm() << '>';
+
+ // Soll ein </P> geschrieben wenrden
+ rInfo.bOutPara =
+ bPara &&
+ ( rHWrt.bCfgOutStyles ||
+ (!rHWrt.bCfgOutStyles && bHasParSpace) );
+
+ // wenn kein End-Tag geschrieben werden soll, es loeschen
+ if( bNoEndTag )
+ rInfo.aToken.Erase();
+ }
+
+ // ??? Warum nicht ueber den Hint-Mechanismus ???
+ if( rHWrt.IsHTMLMode(HTMLMODE_FIRSTLINE) )
+ {
+ const SvxLRSpaceItem& rLRSpaceTmp =
+ pNodeItemSet ? ((const SvxLRSpaceItem &)pNodeItemSet->Get(RES_LR_SPACE))
+ : rFmt.GetLRSpace();
+ if( rLRSpaceTmp.GetTxtFirstLineOfst() > 0 )
+ {
+ OutHTML_HoriSpacer( rWrt, rLRSpaceTmp.GetTxtFirstLineOfst() );
+ }
+ }
+
+ if( nBulletGrfLvl != 255 )
+ {
+ ASSERT( aNumInfo.GetNumRule(), "Wo ist die Numerierung geblieben???" );
+ ASSERT( nBulletGrfLvl < MAXLEVEL, "So viele Ebenen gibt's nicht" );
+ const SwNumFmt& rNumFmt = aNumInfo.GetNumRule()->Get(nBulletGrfLvl);
+
+ OutHTML_BulletImage( rWrt, OOO_STRING_SVTOOLS_HTML_image, 0,
+ rHWrt.aBulletGrfs[nBulletGrfLvl],
+ rNumFmt.GetGraphicSize(), rNumFmt.GetGraphicOrientation() );
+ }
+
+ rHWrt.GetNumInfo() = aNumInfo;
+
+ // die Defaults zuruecksetzen
+ rHWrt.nDfltLeftMargin = 0;
+ rHWrt.nDfltRightMargin = 0;
+ rHWrt.nDfltFirstLineIndent = 0;
+ rHWrt.nDfltTopMargin = 0;
+ rHWrt.nDfltBottomMargin = 0;
+ rHWrt.nLeftMargin = 0;
+ rHWrt.nFirstLineIndent = 0;
+}
+
+void OutHTML_SwFmtOff( Writer& rWrt, const SwHTMLTxtCollOutputInfo& rInfo )
+{
+ SwHTMLWriter & rHWrt = (SwHTMLWriter&)rWrt;
+
+ // wenn es kein Token gibt haben wir auch nichts auszugeben
+ if( !rInfo.aToken.Len() )
+ {
+ rHWrt.FillNextNumInfo();
+ const SwHTMLNumRuleInfo& rNextInfo = *rHWrt.GetNextNumInfo();
+ // Auch in PRE muss eine Bullet-Liste beendet werden
+ if( rInfo.bInNumBulList )
+ {
+
+ const SwHTMLNumRuleInfo& rNRInfo = rHWrt.GetNumInfo();
+ if( rNextInfo.GetNumRule() != rNRInfo.GetNumRule() ||
+ rNextInfo.GetDepth() != rNRInfo.GetDepth() ||
+ rNextInfo.IsNumbered() || rNextInfo.IsRestart() )
+ rHWrt.ChangeParaToken( 0 );
+ OutHTML_NumBulListEnd( rHWrt, rNextInfo );
+ }
+ else if( rNextInfo.GetNumRule() != 0 )
+ rHWrt.ChangeParaToken( 0 );
+
+ return;
+ }
+
+ if( rInfo.ShouldOutputToken() )
+ {
+ if( rHWrt.bLFPossible )
+ rHWrt.OutNewLine( TRUE );
+
+ // fuer BLOCKQUOTE, ADDRESS und DD wird ggf noch ein
+ // Absatz-Token ausgegeben, wenn
+ // - keine Styles geschrieben werden, und
+ // - ein untere Abstand existiert
+ if( rInfo.bParaPossible && rInfo.bOutPara )
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_parabreak, FALSE );
+
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rInfo.aToken.GetBuffer(),
+ FALSE );
+ rHWrt.bLFPossible = !rInfo.aToken.Equals( OOO_STRING_SVTOOLS_HTML_dt ) &&
+ !rInfo.aToken.Equals( OOO_STRING_SVTOOLS_HTML_dd ) &&
+ !rInfo.aToken.Equals( OOO_STRING_SVTOOLS_HTML_li );
+ }
+ if( rInfo.bOutDiv )
+ {
+ rHWrt.DecIndentLevel();
+ if( rHWrt.bLFPossible )
+ rHWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_division, FALSE );
+ rHWrt.bLFPossible = TRUE;
+ }
+
+ // ggf. eine Aufzaehlung- oder Numerierungsliste beenden
+ if( rInfo.bInNumBulList )
+ {
+ rHWrt.FillNextNumInfo();
+ OutHTML_NumBulListEnd( rHWrt, *rHWrt.GetNextNumInfo() );
+ }
+}
+
+
+class HTMLSttEndPos
+{
+ xub_StrLen nStart;
+ xub_StrLen nEnd;
+ SfxPoolItem* pItem;
+
+public:
+
+ HTMLSttEndPos( const SfxPoolItem& rItem, xub_StrLen nStt, xub_StrLen nE );
+ ~HTMLSttEndPos();
+
+ const SfxPoolItem *GetItem() const { return pItem; }
+
+ void SetStart( xub_StrLen nStt ) { nStart = nStt; }
+ xub_StrLen GetStart() const { return nStart; }
+
+ xub_StrLen GetEnd() const { return nEnd; }
+ void SetEnd( xub_StrLen nE ) { nEnd = nE; }
+};
+
+HTMLSttEndPos::HTMLSttEndPos( const SfxPoolItem& rItem, xub_StrLen nStt,
+ xub_StrLen nE ) :
+ nStart( nStt ),
+ nEnd( nE ),
+ pItem( rItem.Clone() )
+{}
+
+HTMLSttEndPos::~HTMLSttEndPos()
+{
+ delete pItem;
+}
+
+typedef HTMLSttEndPos *HTMLSttEndPosPtr;
+SV_DECL_PTRARR( _HTMLEndLst, HTMLSttEndPosPtr, 5, 5 )
+
+enum HTMLOnOffState { HTML_NOT_SUPPORTED, // nicht unterst. Attribut
+ HTML_REAL_VALUE, // Attribut mit Wert
+ HTML_ON_VALUE, // Attribut entspricht On-Tag
+ HTML_OFF_VALUE, // Attribut entspricht Off-Tag
+ HTML_CHRFMT_VALUE, // Attribut fuer Zeichenvorlage
+ HTML_COLOR_VALUE, // Attribut fuer Vordergrundfarbe
+ HTML_STYLE_VALUE, // Attribut muss als Style exp.
+ HTML_DROPCAP_VALUE, // DropCap-Attributs
+ HTML_AUTOFMT_VALUE }; // Attribute for automatic character styles
+
+
+class HTMLEndPosLst
+{
+ _HTMLEndLst aStartLst; // nach Anfangs-Psoitionen sortierte Liste
+ _HTMLEndLst aEndLst; // nach End-Psotionen sortierte Liste
+ SvXub_StrLens aScriptChgLst; // positions where script changes
+ // 0 is not contained in this list,
+ // but the text length
+ SvUShorts aScriptLst; // the script that is valif up to the position
+ // contained in aScriptChgList at the same index
+
+ SwDoc *pDoc; // das aktuelle Dokument
+ SwDoc* pTemplate; // die HTML-Vorlage (oder 0)
+ const Color* pDfltColor;// die Default-Vordergrund-Farbe
+ SvStringsSortDtor& rScriptTxtStyles; //
+
+ ULONG nHTMLMode;
+ BOOL bOutStyles : 1; // werden Styles exportiert
+
+
+ // die Position eines Items in der Start-/Ende-Liste suchen
+ USHORT _FindStartPos( const HTMLSttEndPos *pPos ) const;
+ USHORT _FindEndPos( const HTMLSttEndPos *pPos ) const;
+
+ // Eine SttEndPos in die Start- und Ende-Listen eintragen bzw. aus
+ // ihnen loeschen, wobei die Ende-Position bekannt ist
+ void _InsertItem( HTMLSttEndPos *pPos, USHORT nEndPos );
+ void _RemoveItem( USHORT nEndPos );
+
+ // die "Art" es Attributs ermitteln
+ HTMLOnOffState GetHTMLItemState( const SfxPoolItem& rItem );
+
+ // Existiert ein bestimmtes On-Tag-Item
+ BOOL ExistsOnTagItem( USHORT nWhich, xub_StrLen nPos );
+
+ // Existiert ein Item zum ausschalten eines Attributs, das genauso
+ // exportiert wird wie das uebergebene Item im gleichen Bereich?
+ BOOL ExistsOffTagItem( USHORT nWhich, xub_StrLen nStartPos,
+ xub_StrLen nEndPos );
+
+
+ // das Ende eines gesplitteten Items anpassen
+ void FixSplittedItem( HTMLSttEndPos *pPos, USHORT nStartPos,
+ xub_StrLen nNewEnd );
+
+ // Ein Attribut in die Listen eintragen und ggf. aufteilen
+ void InsertItem( const SfxPoolItem& rItem, xub_StrLen nStart,
+ xub_StrLen nEnd );
+
+ // Ein bereits vorhandenes Attribut aufteilen
+ void SplitItem( const SfxPoolItem& rItem, xub_StrLen nStart,
+ xub_StrLen nEnd );
+
+ // Insert without taking care of script
+ void InsertNoScript( const SfxPoolItem& rItem, xub_StrLen nStart,
+ xub_StrLen nEnd, SwHTMLFmtInfos& rFmtInfos,
+ BOOL bParaAttrs=FALSE );
+
+ const SwHTMLFmtInfo *GetFmtInfo( const SwFmt& rFmt,
+ SwHTMLFmtInfos& rFmtInfos );
+
+public:
+
+ HTMLEndPosLst( SwDoc *pDoc, SwDoc* pTemplate, const Color* pDfltColor,
+ BOOL bOutStyles, ULONG nHTMLMode,
+ const String& rText, SvStringsSortDtor& rStyles );
+ ~HTMLEndPosLst();
+
+ // Ein Attribut einfuegen
+ void Insert( const SfxPoolItem& rItem, xub_StrLen nStart, xub_StrLen nEnd,
+ SwHTMLFmtInfos& rFmtInfos, BOOL bParaAttrs=FALSE );
+ void Insert( const SfxItemSet& rItemSet, xub_StrLen nStart, xub_StrLen nEnd,
+ SwHTMLFmtInfos& rFmtInfos, BOOL bDeep,
+ BOOL bParaAttrs=FALSE );
+ void Insert( const SwDrawFrmFmt& rFmt, xub_StrLen nPos,
+ SwHTMLFmtInfos& rFmtInfos );
+
+ sal_uInt16 GetScriptAtPos( xub_StrLen nPos,
+ sal_uInt16 nWeak=CSS1_OUTMODE_ANY_SCRIPT );
+
+ void OutStartAttrs( SwHTMLWriter& rHWrt, xub_StrLen nPos,
+ HTMLOutContext *pContext = 0 );
+ void OutEndAttrs( SwHTMLWriter& rHWrt, xub_StrLen nPos,
+ HTMLOutContext *pContext = 0 );
+
+ USHORT Count() const { return aEndLst.Count(); }
+
+ BOOL IsHTMLMode( ULONG nMode ) const { return (nHTMLMode & nMode) != 0; }
+};
+
+
+USHORT HTMLEndPosLst::_FindStartPos( const HTMLSttEndPos *pPos ) const
+{
+ USHORT i;
+ for( i = 0; i < aStartLst.Count() && aStartLst[i] != pPos; i++ )
+ ;
+
+ ASSERT( i != aStartLst.Count(), "Item nicht in Start-Liste gefunden!" );
+
+ return i==aStartLst.Count() ? USHRT_MAX : i;
+}
+
+USHORT HTMLEndPosLst::_FindEndPos( const HTMLSttEndPos *pPos ) const
+{
+ USHORT i;
+
+ for( i = 0; i < aEndLst.Count() && aEndLst[i] != pPos; i++ )
+ ;
+
+ ASSERT( i != aEndLst.Count(), "Item nicht in Ende-Liste gefunden" );
+
+ return i==aEndLst.Count() ? USHRT_MAX : i;
+}
+
+
+void HTMLEndPosLst::_InsertItem( HTMLSttEndPos *pPos, USHORT nEndPos )
+{
+ // In der Start-Liste das Attribut hinter allen vorher und an
+ // der gleichen Position gestarteten Attributen einfuegen
+ xub_StrLen nStart = pPos->GetStart();
+ USHORT i;
+
+ for( i = 0; i < aStartLst.Count() &&
+ aStartLst[i]->GetStart() <= nStart; i++ )
+ ;
+ aStartLst.Insert( pPos, i );
+
+ // die Position in der Ende-Liste wurde uebergeben
+ aEndLst.Insert( pPos, nEndPos );
+}
+
+void HTMLEndPosLst::_RemoveItem( USHORT nEndPos )
+{
+ HTMLSttEndPos *pPos = aEndLst[nEndPos];
+
+ // jetzt Suchen wir es in der Start-Liste
+ USHORT nStartPos = _FindStartPos( pPos );
+ if( nStartPos != USHRT_MAX )
+ aStartLst.Remove( nStartPos, 1 );
+
+ aEndLst.Remove( nEndPos, 1 );
+
+ delete pPos;
+}
+
+HTMLOnOffState HTMLEndPosLst::GetHTMLItemState( const SfxPoolItem& rItem )
+{
+ HTMLOnOffState eState = HTML_NOT_SUPPORTED;
+ switch( rItem.Which() )
+ {
+ case RES_CHRATR_POSTURE:
+ case RES_CHRATR_CJK_POSTURE:
+ case RES_CHRATR_CTL_POSTURE:
+ switch( ((const SvxPostureItem&)rItem).GetPosture() )
+ {
+ case ITALIC_NORMAL:
+ eState = HTML_ON_VALUE;
+ break;
+ case ITALIC_NONE:
+ eState = HTML_OFF_VALUE;
+ break;
+ default:
+ if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
+ eState = HTML_STYLE_VALUE;
+ break;
+ }
+ break;
+
+ case RES_CHRATR_CROSSEDOUT:
+ switch( ((const SvxCrossedOutItem&)rItem).GetStrikeout() )
+ {
+ case STRIKEOUT_SINGLE:
+ case STRIKEOUT_DOUBLE:
+ eState = HTML_ON_VALUE;
+ break;
+ case STRIKEOUT_NONE:
+ eState = HTML_OFF_VALUE;
+ break;
+ default:
+ ;
+ }
+ break;
+
+ case RES_CHRATR_ESCAPEMENT:
+ switch( (const SvxEscapement)
+ ((const SvxEscapementItem&)rItem).GetEnumValue() )
+ {
+ case SVX_ESCAPEMENT_SUPERSCRIPT:
+ case SVX_ESCAPEMENT_SUBSCRIPT:
+ eState = HTML_ON_VALUE;
+ break;
+ case SVX_ESCAPEMENT_OFF:
+ eState = HTML_OFF_VALUE;
+ break;
+ default:
+ ;
+ }
+ break;
+
+ case RES_CHRATR_UNDERLINE:
+ switch( ((const SvxUnderlineItem&)rItem).GetLineStyle() )
+ {
+ case UNDERLINE_SINGLE:
+ eState = HTML_ON_VALUE;
+ break;
+ case UNDERLINE_NONE:
+ eState = HTML_OFF_VALUE;
+ break;
+ default:
+ if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
+ eState = HTML_STYLE_VALUE;
+ break;
+ }
+ break;
+
+ case RES_CHRATR_OVERLINE:
+ if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
+ eState = HTML_STYLE_VALUE;
+ break;
+
+ case RES_CHRATR_WEIGHT:
+ case RES_CHRATR_CJK_WEIGHT:
+ case RES_CHRATR_CTL_WEIGHT:
+ switch( ((const SvxWeightItem&)rItem).GetWeight() )
+ {
+ case WEIGHT_BOLD:
+ eState = HTML_ON_VALUE;
+ break;
+ case WEIGHT_NORMAL:
+ eState = HTML_OFF_VALUE;
+ break;
+ default:
+ if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
+ eState = HTML_STYLE_VALUE;
+ break;
+ }
+ break;
+
+ case RES_CHRATR_BLINK:
+ if( IsHTMLMode(HTMLMODE_BLINK) )
+ eState = ((const SvxBlinkItem&)rItem).GetValue() ? HTML_ON_VALUE
+ : HTML_OFF_VALUE;
+ break;
+
+ case RES_CHRATR_COLOR:
+ eState = HTML_COLOR_VALUE;
+ break;
+
+ case RES_CHRATR_FONT:
+ case RES_CHRATR_FONTSIZE:
+ case RES_CHRATR_LANGUAGE:
+ case RES_CHRATR_CJK_FONT:
+ case RES_CHRATR_CJK_FONTSIZE:
+ case RES_CHRATR_CJK_LANGUAGE:
+ case RES_CHRATR_CTL_FONT:
+ case RES_CHRATR_CTL_FONTSIZE:
+ case RES_CHRATR_CTL_LANGUAGE:
+ case RES_TXTATR_INETFMT:
+ eState = HTML_REAL_VALUE;
+ break;
+
+ case RES_TXTATR_CHARFMT:
+ eState = HTML_CHRFMT_VALUE;
+ break;
+
+ case RES_TXTATR_AUTOFMT:
+ eState = HTML_AUTOFMT_VALUE;
+ break;
+
+ case RES_CHRATR_CASEMAP:
+ if( IsHTMLMode(HTMLMODE_SMALL_CAPS) )
+ eState = HTML_STYLE_VALUE;
+
+ case RES_CHRATR_KERNING:
+ if( IsHTMLMode(HTMLMODE_FULL_STYLES) )
+ eState = HTML_STYLE_VALUE;
+ break;
+
+ case RES_CHRATR_BACKGROUND:
+ if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
+ eState = HTML_STYLE_VALUE;
+ break;
+
+ case RES_PARATR_DROP:
+ eState = HTML_DROPCAP_VALUE;
+ break;
+
+// default:
+// eState = HTML_NOT_SUPPORTED;
+// break;
+ }
+
+ return eState;
+}
+
+BOOL HTMLEndPosLst::ExistsOnTagItem( USHORT nWhich, xub_StrLen nPos )
+{
+ for( USHORT i=0; i<aStartLst.Count(); i++ )
+ {
+ HTMLSttEndPos *pTest = aStartLst[i];
+
+ if( pTest->GetStart() > nPos )
+ {
+ // dieses uns alle folgenden Attribute beginnen spaeter
+ break;
+ }
+ else if( pTest->GetEnd() > nPos )
+ {
+ // das Attribut beginnt vor oder an der aktuellen Position
+ // und endet hinter ihr
+ const SfxPoolItem *pItem = pTest->GetItem();
+ if( pItem->Which() == nWhich &&
+ HTML_ON_VALUE == GetHTMLItemState(*pItem) )
+ {
+ // ein On-Tag-Attibut wurde gefunden
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL HTMLEndPosLst::ExistsOffTagItem( USHORT nWhich, xub_StrLen nStartPos,
+ xub_StrLen nEndPos )
+{
+ if( nWhich != RES_CHRATR_CROSSEDOUT &&
+ nWhich != RES_CHRATR_UNDERLINE &&
+ nWhich != RES_CHRATR_BLINK )
+ {
+ return FALSE;
+ }
+
+ for( USHORT i=0; i<aStartLst.Count(); i++ )
+ {
+ HTMLSttEndPos *pTest = aStartLst[i];
+
+ if( pTest->GetStart() > nStartPos )
+ {
+ // dieses uns alle folgenden Attribute beginnen spaeter
+ break;
+ }
+ else if( pTest->GetStart()==nStartPos &&
+ pTest->GetEnd()==nEndPos )
+ {
+ // das Attribut beginnt vor oder an der aktuellen Position
+ // und endet hinter ihr
+ const SfxPoolItem *pItem = pTest->GetItem();
+ USHORT nTstWhich = pItem->Which() ;
+ if( (nTstWhich == RES_CHRATR_CROSSEDOUT ||
+ nTstWhich == RES_CHRATR_UNDERLINE ||
+ nTstWhich == RES_CHRATR_BLINK) &&
+ HTML_OFF_VALUE == GetHTMLItemState(*pItem) )
+ {
+ // Ein Off-Tag-Attibut wurde gefunden, das genauso
+ // exportiert wird, wie das aktuelle Item
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+void HTMLEndPosLst::FixSplittedItem( HTMLSttEndPos *pPos, xub_StrLen nNewEnd,
+ USHORT nStartPos )
+{
+ // die End-Position entsprechend fixen
+ pPos->SetEnd( nNewEnd );
+
+ // das Item aus der End-Liste entfernen
+ USHORT nEndPos = _FindEndPos( pPos );
+ if( nEndPos != USHRT_MAX )
+ aEndLst.Remove( nEndPos, 1 );
+
+ // es wird von nun an als letztes an der entsprechenden Position
+ // beendet
+ for( nEndPos=0; nEndPos < aEndLst.Count() &&
+ aEndLst[nEndPos]->GetEnd() <= nNewEnd; nEndPos++ )
+ ;
+ aEndLst.Insert( pPos, nEndPos );
+
+ // jetzt noch die spaeter gestarteten Attribute anpassen
+ for( USHORT i=nStartPos+1; i<aStartLst.Count(); i++ )
+ {
+ HTMLSttEndPos *pTest = aStartLst[i];
+ xub_StrLen nTestEnd = pTest->GetEnd();
+ if( pTest->GetStart() >= nNewEnd )
+ {
+ // das Test-Attribut und alle folgenden beginnen, nachdem das
+ // gesplittete Attribut endet
+ break;
+ }
+ else if( nTestEnd > nNewEnd )
+ {
+ // das Test-Attribut beginnt, bevor das gesplittete Attribut
+ // endet und endet danach, muss also auch gesplittet werden
+
+ // das neue Ende setzen
+ pTest->SetEnd( nNewEnd );
+
+ // das Attribut aus der End-Liste entfernen
+ USHORT nEPos = _FindEndPos( pTest );
+ if( nEPos != USHRT_MAX )
+ aEndLst.Remove( nEPos, 1 );
+
+ // es endet jetzt als erstes Attribut an der entsprechenden
+ // Position. Diese Position in der Ende-Liste kennen wir schon.
+ aEndLst.Insert(pTest, nEndPos );
+
+ // den "Rest" des Attributs neu einfuegen
+ InsertItem( *pTest->GetItem(), nNewEnd, nTestEnd );
+ }
+ }
+}
+
+
+void HTMLEndPosLst::InsertItem( const SfxPoolItem& rItem, xub_StrLen nStart,
+ xub_StrLen nEnd )
+{
+ USHORT i;
+ for( i = 0; i < aEndLst.Count(); i++ )
+ {
+ HTMLSttEndPos *pTest = aEndLst[i];
+ xub_StrLen nTestEnd = pTest->GetEnd();
+ if( nTestEnd <= nStart )
+ {
+ // das Test-Attribut endet, bevor das neue beginnt
+ continue;
+ }
+ else if( nTestEnd < nEnd )
+ {
+ // das Test-Attribut endet, bevor das neue endet. Das
+ // neue Attribut muss deshalb aufgesplittet werden
+ _InsertItem( new HTMLSttEndPos( rItem, nStart, nTestEnd ), i );
+ nStart = nTestEnd;
+ }
+ else
+ {
+ // das Test-Attribut (und alle folgenden) endet, bevor das neue
+ // endet
+ break;
+ }
+ }
+
+ // ein Attribut muss noch eingefuegt werden
+ _InsertItem( new HTMLSttEndPos( rItem, nStart, nEnd ), i );
+}
+
+
+
+void HTMLEndPosLst::SplitItem( const SfxPoolItem& rItem, xub_StrLen nStart,
+ xub_StrLen nEnd )
+{
+ USHORT nWhich = rItem.Which();
+
+ // erstmal muessen wir die alten Items anhand der Startliste suchen
+ // und die neuen Item-Bereiche festlegen
+
+ for( USHORT i=0; i<aStartLst.Count(); i++ )
+ {
+ HTMLSttEndPos *pTest = aStartLst[i];
+ xub_StrLen nTestStart = pTest->GetStart();
+ xub_StrLen nTestEnd = pTest->GetEnd();
+
+ if( nTestStart >= nEnd )
+ {
+ // dieses und alle nachfolgenden Attribute beginnen spaeter
+ break;
+ }
+ else if( nTestEnd > nStart )
+ {
+ // das Test Attribut endet im zu loeschenenden Bereich
+ const SfxPoolItem *pItem = pTest->GetItem();
+
+ // nur entsprechende On-Tag Attribute muessen beruecksichtigt
+ // werden
+ if( pItem->Which() == nWhich &&
+ HTML_ON_VALUE == GetHTMLItemState( *pItem ) )
+ {
+ BOOL bDelete = TRUE;
+
+ if( nTestStart < nStart )
+ {
+ // der Start des neuen Attribut entspricht
+ // dem neuen Ende des Attribts
+ FixSplittedItem( pTest, nStart, i );
+ bDelete = FALSE;
+ }
+ else
+ {
+ // das Test-Item beginnt erst hinter dem neuen
+ // Ende des Attribts und kann deshalb komplett
+ // geloescht werden
+ aStartLst.Remove( i, 1 );
+ i--;
+
+ USHORT nEndPos = _FindEndPos( pTest );
+ if( nEndPos != USHRT_MAX )
+ aEndLst.Remove( nEndPos, 1 );
+ }
+
+ // ggf den zweiten Teil des gesplitteten Attribts einfuegen
+ if( nTestEnd > nEnd )
+ {
+ InsertItem( *pTest->GetItem(), nEnd, nTestEnd );
+ }
+
+ if( bDelete )
+ delete pTest;
+ }
+ }
+ }
+}
+
+const SwHTMLFmtInfo *HTMLEndPosLst::GetFmtInfo( const SwFmt& rFmt,
+ SwHTMLFmtInfos& rFmtInfos )
+{
+ const SwHTMLFmtInfo *pFmtInfo;
+ SwHTMLFmtInfo aFmtInfo( &rFmt );
+ USHORT nPos;
+ if( rFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
+ {
+ pFmtInfo = rFmtInfos[nPos];
+ }
+ else
+ {
+ pFmtInfo = new SwHTMLFmtInfo( &rFmt, pDoc, pTemplate,
+ bOutStyles );
+ rFmtInfos.C40_PTR_INSERT( SwHTMLFmtInfo, pFmtInfo );
+ String aName( rFmt.GetName() );
+ if( rScriptTxtStyles.Seek_Entry( &aName ) )
+ ((SwHTMLFmtInfo *)pFmtInfo)->bScriptDependent = sal_True;
+ }
+
+ return pFmtInfo;
+}
+
+HTMLEndPosLst::HTMLEndPosLst( SwDoc *pD, SwDoc* pTempl,
+ const Color* pDfltCol, BOOL bStyles,
+ ULONG nMode, const String& rText,
+ SvStringsSortDtor& rStyles ):
+ pDoc( pD ),
+ pTemplate( pTempl ),
+ pDfltColor( pDfltCol ),
+ rScriptTxtStyles( rStyles ),
+ nHTMLMode( nMode ),
+ bOutStyles( bStyles )
+{
+ xub_StrLen nEndPos = rText.Len();
+ xub_StrLen nPos = 0;
+ while( nPos < nEndPos )
+ {
+ sal_uInt16 nScript = pBreakIt->GetBreakIter()->getScriptType( rText, nPos );
+ nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( rText, nPos, nScript );
+ aScriptChgLst.Insert( nPos, aScriptChgLst.Count() );
+ aScriptLst.Insert( nScript, aScriptLst.Count() );
+ }
+}
+
+HTMLEndPosLst::~HTMLEndPosLst()
+{
+ ASSERT( !aStartLst.Count(), "Start-Liste im Destruktor nicht leer" );
+ ASSERT( !aEndLst.Count(), "End-Liste im Destruktor nicht leer" );
+}
+
+
+
+void HTMLEndPosLst::InsertNoScript( const SfxPoolItem& rItem,
+ xub_StrLen nStart, xub_StrLen nEnd,
+ SwHTMLFmtInfos& rFmtInfos, BOOL bParaAttrs )
+{
+ // kein Bereich ?? dann nicht aufnehmen, wird nie wirksam !!
+ if( nStart != nEnd )
+ {
+ BOOL bSet = FALSE, bSplit = FALSE;
+ switch( GetHTMLItemState(rItem) )
+ {
+ case HTML_ON_VALUE:
+ // das Attribut wird ausgegeben, wenn es nicht sowieso
+ // schon an ist
+ if( !ExistsOnTagItem( rItem.Which(), nStart ) )
+ bSet = TRUE;
+ break;
+
+ case HTML_OFF_VALUE:
+ // wenn das entsprechne Attribut an ist, wird es gesplittet,
+ // Zusaetlich wird es aber als Style ausgegeben, wenn es nicht
+ // am ganzen Absatz gesetzt ist, weil es dann ja schon mit dem
+ // ABsatz-Tag ausgegeben wurde.
+ if( ExistsOnTagItem( rItem.Which(), nStart ) )
+ bSplit = TRUE;
+ bSet = bOutStyles && !bParaAttrs &&
+ !ExistsOffTagItem( rItem.Which(), nStart, nEnd );
+ break;
+
+ case HTML_REAL_VALUE:
+ // das Attribut kann immer ausgegeben werden
+ bSet = TRUE;
+ break;
+
+ case HTML_STYLE_VALUE:
+ // Das Attribut kann nur als CSS1 ausgegeben werden. Wenn
+ // es am Absatz gesetzt ist, wurde es schon mit dem
+ // Absatz-Tag ausgegeben. Einzige Ausnahme ist das
+ // Zeichen-Hintergrund-Attribut. Es muss immer wie ein
+ // Hint behandelt werden.
+ bSet = bOutStyles &&
+ (!bParaAttrs
+ || rItem.Which()==RES_CHRATR_BACKGROUND
+ || rItem.Which()==RES_CHRATR_OVERLINE);
+ break;
+
+ case HTML_CHRFMT_VALUE:
+ {
+ ASSERT( RES_TXTATR_CHARFMT == rItem.Which(),
+ "Doch keine Zeichen-Vorlage" );
+ const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rItem;
+ const SwCharFmt* pFmt = rChrFmt.GetCharFmt();
+
+ const SwHTMLFmtInfo *pFmtInfo = GetFmtInfo( *pFmt, rFmtInfos );
+ if( pFmtInfo->aToken.Len() )
+ {
+ // das Zeichenvorlagen-Tag muss vor den harten
+ // Attributen ausgegeben werden
+ InsertItem( rItem, nStart, nEnd );
+ }
+ if( pFmtInfo->pItemSet )
+ {
+ Insert( *pFmtInfo->pItemSet, nStart, nEnd,
+ rFmtInfos, TRUE, bParaAttrs );
+ }
+ }
+ break;
+
+ case HTML_AUTOFMT_VALUE:
+ {
+ const SwFmtAutoFmt& rAutoFmt = (const SwFmtAutoFmt&)rItem;
+ const boost::shared_ptr<SfxItemSet> pSet = rAutoFmt.GetStyleHandle();
+ if( pSet.get() )
+ Insert( *pSet.get(), nStart, nEnd, rFmtInfos, TRUE, bParaAttrs );
+ }
+ break;
+
+ case HTML_COLOR_VALUE:
+ // Eine Vordergrund-Farbe als Absatz-Attribut wird nur
+ // exportiert, wenn sie nicht der Default-Farbe entspricht.
+ {
+ ASSERT( RES_CHRATR_COLOR == rItem.Which(),
+ "Doch keine Vordergrund-Farbe" );
+ Color aColor( ((const SvxColorItem&)rItem).GetValue() );
+ if( COL_AUTO == aColor.GetColor() )
+ aColor.SetColor( COL_BLACK );
+ bSet = !bParaAttrs || !pDfltColor ||
+ !pDfltColor->IsRGBEqual( aColor );
+ }
+ break;
+
+ case HTML_DROPCAP_VALUE:
+ {
+ ASSERT( RES_PARATR_DROP == rItem.Which(),
+ "Doch kein Drop-Cap" );
+ const SwFmtDrop& rDrop = (const SwFmtDrop&)rItem;
+ nEnd = nStart + rDrop.GetChars();
+ if( !bOutStyles )
+ {
+ // Zumindest die Attribute der Zeichenvorlage uebernehmen
+ const SwCharFmt *pCharFmt = rDrop.GetCharFmt();
+ if( pCharFmt )
+ {
+ Insert( pCharFmt->GetAttrSet(), nStart, nEnd,
+ rFmtInfos, TRUE, bParaAttrs );
+ }
+ }
+ else
+ {
+ bSet = TRUE;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+
+ if( bSet )
+ InsertItem( rItem, nStart, nEnd );
+ if( bSplit )
+ SplitItem( rItem, nStart, nEnd );
+ }
+}
+
+void HTMLEndPosLst::Insert( const SfxPoolItem& rItem,
+ xub_StrLen nStart, xub_StrLen nEnd,
+ SwHTMLFmtInfos& rFmtInfos, BOOL bParaAttrs )
+{
+ sal_Bool bDependsOnScript = sal_False, bDependsOnAnyScript = sal_False;
+ sal_uInt16 nScript = i18n::ScriptType::LATIN;
+ switch( rItem.Which() )
+ {
+ case RES_CHRATR_FONT:
+ case RES_CHRATR_FONTSIZE:
+ case RES_CHRATR_LANGUAGE:
+ case RES_CHRATR_POSTURE:
+ case RES_CHRATR_WEIGHT:
+ bDependsOnScript = sal_True;
+ nScript = i18n::ScriptType::LATIN;
+ break;
+
+ case RES_CHRATR_CJK_FONT:
+ case RES_CHRATR_CJK_FONTSIZE:
+ case RES_CHRATR_CJK_LANGUAGE:
+ case RES_CHRATR_CJK_POSTURE:
+ case RES_CHRATR_CJK_WEIGHT:
+ bDependsOnScript = sal_True;
+ nScript = i18n::ScriptType::ASIAN;
+ break;
+
+ case RES_CHRATR_CTL_FONT:
+ case RES_CHRATR_CTL_FONTSIZE:
+ case RES_CHRATR_CTL_LANGUAGE:
+ case RES_CHRATR_CTL_POSTURE:
+ case RES_CHRATR_CTL_WEIGHT:
+ bDependsOnScript = sal_True;
+ nScript = i18n::ScriptType::COMPLEX;
+ break;
+ case RES_TXTATR_CHARFMT:
+ {
+ const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rItem;
+ const SwCharFmt* pFmt = rChrFmt.GetCharFmt();
+ const SwHTMLFmtInfo *pFmtInfo = GetFmtInfo( *pFmt, rFmtInfos );
+ if( pFmtInfo->bScriptDependent )
+ {
+ bDependsOnScript = sal_True;
+ bDependsOnAnyScript = sal_True;
+ }
+ }
+ break;
+ case RES_TXTATR_INETFMT:
+ {
+ if( GetFmtInfo( *pDoc->GetCharFmtFromPool(
+ RES_POOLCHR_INET_NORMAL), rFmtInfos )->bScriptDependent ||
+ GetFmtInfo( *pDoc->GetCharFmtFromPool(
+ RES_POOLCHR_INET_VISIT), rFmtInfos )->bScriptDependent )
+ {
+ bDependsOnScript = sal_True;
+ bDependsOnAnyScript = sal_True;
+ }
+ }
+ break;
+ }
+
+ if( bDependsOnScript )
+ {
+ sal_uInt16 nScriptChgs = aScriptChgLst.Count();
+ xub_StrLen nPos = nStart;
+ for( sal_uInt16 i=0; i < nScriptChgs; i++ )
+ {
+ xub_StrLen nChgPos = aScriptChgLst[i];
+ if( nPos >= nChgPos )
+ {
+ // the hint starts behind or at the next script change,
+ // so we may continue with this position.
+ continue;
+ }
+ if( nEnd <= nChgPos )
+ {
+ // the (rest of) the hint ends before or at the next script
+ // change, so we can insert it, but only if it belongs
+ // to the current script.
+ if( bDependsOnAnyScript || nScript == aScriptLst[i] )
+ InsertNoScript( rItem, nPos, nEnd, rFmtInfos,
+ bParaAttrs );
+ break;
+ }
+
+ // the hint starts before the next script change and ends behind
+ // it, so we can insert a hint upto the next script change and
+ // continue with the rest of the hint.
+ if( bDependsOnAnyScript || nScript == aScriptLst[i] )
+ InsertNoScript( rItem, nPos, nChgPos, rFmtInfos, bParaAttrs );
+ nPos = nChgPos;
+ }
+ }
+ else
+ {
+ InsertNoScript( rItem, nStart, nEnd, rFmtInfos, bParaAttrs );
+ }
+}
+
+void HTMLEndPosLst::Insert( const SfxItemSet& rItemSet,
+ xub_StrLen nStart, xub_StrLen nEnd,
+ SwHTMLFmtInfos& rFmtInfos,
+ BOOL bDeep, BOOL bParaAttrs )
+{
+ SfxWhichIter aIter( rItemSet );
+
+ USHORT nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( nWhich, bDeep, &pItem ) )
+ {
+ Insert( *pItem, nStart, nEnd, rFmtInfos, bParaAttrs );
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void HTMLEndPosLst::Insert( const SwDrawFrmFmt& rFmt, xub_StrLen nPos,
+ SwHTMLFmtInfos& rFmtInfos )
+{
+ // der Type-Cast ist nur noetig, um nicht seinetwegen
+ // svdrwobt.hxx zu includem
+ const SdrObject* pTextObj =
+ (const SdrObject *)SwHTMLWriter::GetMarqueeTextObj( rFmt );
+
+ if( pTextObj )
+ {
+ // die Edit-Engine-Attribute des Objekts als SW-Attribute holen
+ // und als Hints einsortieren. Wegen der Menge der Hints werden
+ // Styles hierbei nicht beruecksichtigt!
+ const SfxItemSet& rFmtItemSet = rFmt.GetAttrSet();
+ SfxItemSet aItemSet( *rFmtItemSet.GetPool(), RES_CHRATR_BEGIN,
+ RES_CHRATR_END );
+ SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet, pTextObj, TRUE );
+ BOOL bOutStylesOld = bOutStyles;
+ bOutStyles = FALSE;
+ Insert( aItemSet, nPos, nPos+1, rFmtInfos, FALSE, FALSE );
+ bOutStyles = bOutStylesOld;
+ }
+}
+
+sal_uInt16 HTMLEndPosLst::GetScriptAtPos( xub_StrLen nPos ,
+ sal_uInt16 nWeak )
+{
+ sal_uInt16 nRet = CSS1_OUTMODE_ANY_SCRIPT;
+
+ sal_uInt16 nScriptChgs = aScriptChgLst.Count();
+ sal_uInt16 i=0;
+ while( i < nScriptChgs && nPos >= aScriptChgLst[i] )
+ i++;
+ ASSERT( i < nScriptChgs, "script list is to short" );
+ if( i < nScriptChgs )
+ {
+ if( i18n::ScriptType::WEAK == aScriptLst[i] )
+ nRet = nWeak;
+ else
+ nRet = SwHTMLWriter::GetCSS1ScriptForScriptType( aScriptLst[i] );
+ }
+
+ return nRet;
+}
+
+void HTMLEndPosLst::OutStartAttrs( SwHTMLWriter& rHWrt, xub_StrLen nPos,
+ HTMLOutContext *pContext )
+{
+ rHWrt.bTagOn = TRUE;
+
+ // die Attribute in der Start-Liste sind aufsteigend sortiert
+ for( USHORT i=0; i< aStartLst.Count(); i++ )
+ {
+ HTMLSttEndPos *pPos = aStartLst[i];
+ xub_StrLen nStart = pPos->GetStart();
+ if( nStart > nPos )
+ {
+ // dieses und alle folgenden Attribute werden erst noch geoeffnet
+ break;
+ }
+ else if( nStart == nPos )
+ {
+ // das Attribut ausgeben
+ sal_uInt16 nCSS1Script = rHWrt.nCSS1Script;
+ sal_uInt16 nWhich = pPos->GetItem()->Which();
+ if( RES_TXTATR_CHARFMT == nWhich ||
+ RES_TXTATR_INETFMT == nWhich ||
+ RES_PARATR_DROP == nWhich )
+ {
+ rHWrt.nCSS1Script = GetScriptAtPos( nPos, nCSS1Script );
+ }
+ if( pContext )
+ {
+ HTMLOutFuncs::FlushToAscii( rHWrt.Strm(), *pContext );
+ pContext = 0; // one time ony
+ }
+ Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
+ rHWrt.nCSS1Script = nCSS1Script;
+ }
+ }
+}
+
+void HTMLEndPosLst::OutEndAttrs( SwHTMLWriter& rHWrt, xub_StrLen nPos,
+ HTMLOutContext *pContext )
+{
+ rHWrt.bTagOn = FALSE;
+
+ // die Attribute in der End-Liste sind aufsteigend sortiert
+ USHORT i=0;
+ while( i < aEndLst.Count() )
+ {
+ HTMLSttEndPos *pPos = aEndLst[i];
+ xub_StrLen nEnd = pPos->GetEnd();
+
+ if( STRING_MAXLEN==nPos || nEnd == nPos )
+ {
+ if( pContext )
+ {
+ HTMLOutFuncs::FlushToAscii( rHWrt.Strm(), *pContext );
+ pContext = 0; // one time ony
+ }
+ Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
+ _RemoveItem( i );
+ }
+ else if( nEnd > nPos )
+ {
+ // dieses und alle folgenden Attribute werden erst spaeter beendet
+ break;
+ }
+ else
+ {
+ // Das Attribut wird vor der aktuellen Position beendet. Das
+ // darf nicht sein, aber wie koennen trotzdem damit umgehen
+ ASSERT( nEnd >= nPos,
+ "Das Attribut sollte schon laengst beendet sein" );
+ i++;
+ }
+ }
+}
+
+
+/* Ausgabe der Nodes */
+Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode )
+{
+ SwTxtNode * pNd = &((SwTxtNode&)rNode);
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const String& rStr = pNd->GetTxt();
+ xub_StrLen nEnde = rStr.Len();
+
+ // Besonderheit: leere Node und HR-Vorlage (horizontaler Strich)
+ // nur ein <HR> ausgeben
+ USHORT nPoolId = pNd->GetAnyFmtColl().GetPoolFmtId();
+
+ if( !nEnde && (RES_POOLCOLL_HTML_HR==nPoolId ||
+ pNd->GetAnyFmtColl().GetName().EqualsAscii( OOO_STRING_SVTOOLS_HTML_horzrule) ) )
+ {
+ // dann die absatz-gebundenen Grafiken/OLE-Objekte im Absatz
+ // MIB 8.7.97: Ein <PRE> spannen wir um die Linie auf. Dann stimmen
+ // zwar die Abstaende nicht, aber sonst bekommen wir einen leeren
+ // Absatz hinter dem <HR> und das ist noch unschoener.
+ rHTMLWrt.ChangeParaToken( 0 );
+
+ // Alle an dem Node verankerten Rahmen ausgeben
+ rHTMLWrt.OutFlyFrm( rNode.GetIndex(), 0, HTML_POS_ANY );
+
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine(); // Absatz-Tag in eine neue Zeile
+
+ rHTMLWrt.bLFPossible = TRUE;
+
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_horzrule;
+
+ const SfxItemSet* pItemSet = pNd->GetpSwAttrSet();
+ if( !pItemSet )
+ {
+ rWrt.Strm() << sOut.GetBuffer() << '>';
+ return rHTMLWrt;
+ }
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pItemSet->GetItemState( RES_LR_SPACE, FALSE, &pItem ))
+ {
+ sal_Int32 nLeft = ((SvxLRSpaceItem*)pItem)->GetLeft();
+ sal_Int32 nRight = ((SvxLRSpaceItem*)pItem)->GetRight();
+ if( nLeft || nRight )
+ {
+ const SwFrmFmt& rPgFmt =
+ rHTMLWrt.pDoc->GetPageDescFromPool
+ ( RES_POOLPAGE_HTML, false )->GetMaster();
+ const SwFmtFrmSize& rSz = rPgFmt.GetFrmSize();
+ const SvxLRSpaceItem& rLR = rPgFmt.GetLRSpace();
+ const SwFmtCol& rCol = rPgFmt.GetCol();
+
+ long nPageWidth = rSz.GetWidth() - rLR.GetLeft() - rLR.GetRight();
+
+ if( 1 < rCol.GetNumCols() )
+ nPageWidth /= rCol.GetNumCols();
+
+ const SwTableNode* pTblNd = pNd->FindTableNode();
+ if( pTblNd )
+ {
+ const SwTableBox* pBox = pTblNd->GetTable().GetTblBox(
+ pNd->StartOfSectionIndex() );
+ if( pBox )
+ nPageWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
+ }
+
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=';
+ rWrt.Strm() << sOut.GetBuffer();
+ rWrt.OutULong( rHTMLWrt.ToPixel(nPageWidth-nLeft-nRight) );
+
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=';
+ if( !nLeft )
+ sOut += OOO_STRING_SVTOOLS_HTML_AL_left;
+ else if( !nRight )
+ sOut += OOO_STRING_SVTOOLS_HTML_AL_right;
+ else
+ sOut += OOO_STRING_SVTOOLS_HTML_AL_center;
+ }
+ }
+ rWrt.Strm() << sOut.GetBuffer();
+ if( SFX_ITEM_SET == pItemSet->GetItemState( RES_BOX, FALSE, &pItem ))
+ {
+ const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
+ const SvxBorderLine* pBorderLine = pBoxItem->GetBottom();
+ if( pBorderLine )
+ {
+ USHORT nWidth = pBorderLine->GetOutWidth() +
+ pBorderLine->GetInWidth() +
+ pBorderLine->GetDistance();
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=';
+ rWrt.Strm() << sOut.GetBuffer();
+ rWrt.OutULong( rHTMLWrt.ToPixel(nWidth) );
+
+ const Color& rBorderColor = pBorderLine->GetColor();
+ if( !rBorderColor.IsRGBEqual( Color(COL_GRAY) ) )
+ {
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_Color( rWrt.Strm(), rBorderColor,
+ rHTMLWrt.eDestEnc );
+ }
+
+ if( !pBorderLine->GetInWidth() )
+ {
+ (sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_noshade;
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+ }
+ }
+ rWrt.Strm() << '>';
+ return rHTMLWrt;
+ }
+
+ // Die leeren Nodes mit 2pt Font-Hoehe und der Stand-Vorlage, die
+ // vor Tabellen und Bereichen eingefuegt werden, nicht exportieren,
+ // Bookmarks oder absatzgebundene Grafiken aber schon.
+ // MIB 21.7.97: Ausserdem auch keine leeren Tabellen-Zellen exportieren.
+ if( !nEnde && (nPoolId == RES_POOLCOLL_STANDARD ||
+ nPoolId == RES_POOLCOLL_TABLE ||
+ nPoolId == RES_POOLCOLL_TABLE_HDLN) )
+ {
+ // Der aktuelle Node ist leer und enthaelt Standard-Vorlage ...
+ const SfxPoolItem* pItem;
+ const SfxItemSet *pItemSet = pNd->GetpSwAttrSet();
+ if( pItemSet && pItemSet->Count() &&
+ SFX_ITEM_SET == pItemSet->GetItemState( RES_CHRATR_FONTSIZE, FALSE, &pItem ) &&
+ 40 == ((const SvxFontHeightItem *)pItem)->GetHeight() )
+ {
+ // ... ausserdem ist die 2pt Schrift eingestellt ...
+ ULONG nNdPos = rWrt.pCurPam->GetPoint()->nNode.GetIndex();
+ const SwNode *pNextNd = rWrt.pDoc->GetNodes()[nNdPos+1];
+ const SwNode *pPrevNd = rWrt.pDoc->GetNodes()[nNdPos-1];
+ BOOL bStdColl = nPoolId == RES_POOLCOLL_STANDARD;
+ if( ( bStdColl && (pNextNd->IsTableNode() ||
+ pNextNd->IsSectionNode()) ) ||
+ ( !bStdColl && pNextNd->IsEndNode() &&
+ pPrevNd->IsStartNode() &&
+ SwTableBoxStartNode==
+ pPrevNd->GetStartNode()->GetStartNodeType() ) )
+ {
+ // ... und er steht vor einer Tabelle ohne einem Bereich
+ rHTMLWrt.OutBookmarks();
+ rHTMLWrt.bLFPossible = !rHTMLWrt.nLastParaToken;
+
+ // Alle an dem Node verankerten Rahmen ausgeben
+ rHTMLWrt.OutFlyFrm( rNode.GetIndex(), 0, HTML_POS_ANY );
+ rHTMLWrt.bLFPossible = FALSE;
+
+ return rWrt;
+ }
+ }
+ }
+
+ // PagePreaks uns PagDescs abfangen
+ BOOL bPageBreakBehind = FALSE;
+ if( rHTMLWrt.bCfgFormFeed &&
+ !(rHTMLWrt.bOutTable || rHTMLWrt.bOutFlyFrame) &&
+ rHTMLWrt.pStartNdIdx->GetIndex() !=
+ rHTMLWrt.pCurPam->GetPoint()->nNode.GetIndex() )
+ {
+ BOOL bPageBreakBefore = FALSE;
+ const SfxPoolItem* pItem;
+ const SfxItemSet* pItemSet = pNd->GetpSwAttrSet();
+
+ if( pItemSet )
+ {
+ if( SFX_ITEM_SET ==
+ pItemSet->GetItemState( RES_PAGEDESC, TRUE, &pItem ) &&
+ ((SwFmtPageDesc *)pItem)->GetPageDesc() )
+ bPageBreakBefore = TRUE;
+ else if( SFX_ITEM_SET ==
+ pItemSet->GetItemState( RES_BREAK, TRUE, &pItem ) )
+ {
+ switch( ((SvxFmtBreakItem *)pItem)->GetBreak() )
+ {
+ case SVX_BREAK_PAGE_BEFORE:
+ bPageBreakBefore = TRUE;
+ break;
+ case SVX_BREAK_PAGE_AFTER:
+ bPageBreakBehind = TRUE;
+ break;
+ case SVX_BREAK_PAGE_BOTH:
+ bPageBreakBefore = TRUE;
+ bPageBreakBehind = TRUE;
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+ if( bPageBreakBefore )
+ rWrt.Strm() << '\f';
+ }
+
+ // eventuell eine Form oeffnen
+ rHTMLWrt.OutForm();
+
+ // An dem Node "verankerte" Seitenegebunde Rahmen ausgeben
+ BOOL bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
+ 0, HTML_POS_PREFIX );
+ // An dem Node verankerte Rahmen ausgeben, die vor dem
+ // Absatz-Tag geschrieben werden sollen.
+ if( bFlysLeft )
+ bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
+ 0, HTML_POS_BEFORE );
+
+ if( rHTMLWrt.pCurPam->GetPoint()->nNode == rHTMLWrt.pCurPam->GetMark()->nNode )
+ nEnde = rHTMLWrt.pCurPam->GetMark()->nContent.GetIndex();
+
+ // gibt es harte Attribute, die als Optionen geschrieben werden muessen?
+ rHTMLWrt.bTagOn = TRUE;
+
+ // jetzt das Tag des Absatzes ausgeben
+ const SwFmt& rFmt = pNd->GetAnyFmtColl();
+ SwHTMLTxtCollOutputInfo aFmtInfo;
+ BOOL bOldLFPossible = rHTMLWrt.bLFPossible;
+ OutHTML_SwFmt( rWrt, rFmt, pNd->GetpSwAttrSet(), aFmtInfo );
+
+ // Wenn vor dem Absatz-Tag keine neue Zeile aufgemacht wurde, dann
+ // tun wir das jetzt
+ rHTMLWrt.bLFPossible = !rHTMLWrt.nLastParaToken;
+ if( !bOldLFPossible && rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+
+
+ // dann die Bookmarks (inkl. End-Tag)
+ rHTMLWrt.bOutOpts = FALSE;
+ rHTMLWrt.OutBookmarks();
+
+ // jetzt ist noch mal eine gute Gelegenheit fuer ein LF, sofern es noch
+ // erlaubt ist
+ if( rHTMLWrt.bLFPossible &&
+ rHTMLWrt.GetLineLen() >= rHTMLWrt.nWhishLineLen )
+ {
+ rHTMLWrt.OutNewLine();
+ }
+ rHTMLWrt.bLFPossible = FALSE;
+
+ // Text, der aus einer Outline-Numerierung kommt ermitteln
+ xub_StrLen nOffset = 0;
+ String aOutlineTxt;
+ String aFullText;
+ // --> OD 2006-06-12 #b6435904#
+ // export numbering string as plain text only for the outline numbering,
+ // because the outline numbering isn't exported as a numbering - see <SwHTMLNumRuleInfo::Set(..)>
+ if ( pNd->IsOutline() &&
+ pNd->GetNumRule() == pNd->GetDoc()->GetOutlineNumRule() )
+ // <--
+ {
+ aOutlineTxt = pNd->GetNumString();
+ nOffset = nOffset + aOutlineTxt.Len();
+ aFullText = aOutlineTxt;
+ }
+ String aFootEndNoteSym;
+ if( rHTMLWrt.pFmtFtn )
+ {
+ aFootEndNoteSym = rHTMLWrt.GetFootEndNoteSym( *rHTMLWrt.pFmtFtn );
+ nOffset = nOffset + aFootEndNoteSym.Len();
+ aFullText += aFootEndNoteSym;
+ }
+
+ // gibt es harte Attribute, die als Tags geschrieben werden muessen?
+ aFullText += rStr;
+ HTMLEndPosLst aEndPosLst( rWrt.pDoc, rHTMLWrt.pTemplate,
+ rHTMLWrt.pDfltColor, rHTMLWrt.bCfgOutStyles,
+ rHTMLWrt.GetHTMLMode(), aFullText,
+ rHTMLWrt.aScriptTextStyles );
+ if( aFmtInfo.pItemSet )
+ {
+ aEndPosLst.Insert( *aFmtInfo.pItemSet, 0, nEnde + nOffset,
+ rHTMLWrt.aChrFmtInfos, FALSE, TRUE );
+ }
+
+
+ if( aOutlineTxt.Len() || rHTMLWrt.pFmtFtn )
+ {
+ // Absatz-Attribute ausgeben, damit der Text die Attribute des
+ // Absatzes bekommt.
+ aEndPosLst.OutStartAttrs( rHTMLWrt, 0 );
+
+ // Theoretisch muesste man hier die Zeichen-Vorlage der Numerierung
+ // beachten. Da man die ueber die UI nicht setzen kann, ignorieren
+ // wir sie erstmal.
+
+ if( aOutlineTxt.Len() )
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aOutlineTxt,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters);
+
+ if( rHTMLWrt.pFmtFtn )
+ {
+ rHTMLWrt.OutFootEndNoteSym( *rHTMLWrt.pFmtFtn, aFootEndNoteSym,
+ aEndPosLst.GetScriptAtPos( aOutlineTxt.Len(), rHTMLWrt.nCSS1Script ) );
+ rHTMLWrt.pFmtFtn = 0;
+ }
+ }
+
+ // erstmal den Start berichtigen. D.h. wird nur ein Teil vom Satz
+ // ausgegeben, so muessen auch da die Attribute stimmen!!
+ rHTMLWrt.bTxtAttr = TRUE;
+
+
+ USHORT nAttrPos = 0;
+ xub_StrLen nStrPos = rHTMLWrt.pCurPam->GetPoint()->nContent.GetIndex();
+ const SwTxtAttr * pHt = 0;
+ USHORT nCntAttr = pNd->HasHints() ? pNd->GetSwpHints().Count() : 0;
+ if( nCntAttr && nStrPos > *( pHt = pNd->GetSwpHints()[ 0 ] )->GetStart() )
+ {
+ // Ok, es gibt vorher Attribute, die ausgegeben werden muessen
+ do {
+ aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset );
+
+ nAttrPos++;
+ if( RES_TXTATR_FIELD == pHt->Which() ) // Felder nicht
+ continue; // ausgeben
+
+ if ( pHt->GetEnd() && !pHt->HasDummyChar() )
+ {
+ xub_StrLen nHtEnd = *pHt->GetEnd(),
+ nHtStt = *pHt->GetStart();
+ if( !rHTMLWrt.bWriteAll && nHtEnd <= nStrPos )
+ continue;
+
+ // leere Hints am Anfang nicht beachten, oder ??
+ if( nHtEnd == nHtStt )
+ continue;
+
+ // Attribut in die Liste aufnehemen
+ if( rHTMLWrt.bWriteAll )
+ aEndPosLst.Insert( pHt->GetAttr(), nHtStt + nOffset,
+ nHtEnd + nOffset,
+ rHTMLWrt.aChrFmtInfos );
+ else
+ {
+ xub_StrLen nTmpStt = nHtStt < nStrPos ? nStrPos : nHtStt;
+ xub_StrLen nTmpEnd = nHtEnd < nEnde ? nHtEnd : nEnde;
+ aEndPosLst.Insert( pHt->GetAttr(), nTmpStt + nOffset,
+ nTmpEnd + nOffset,
+ rHTMLWrt.aChrFmtInfos );
+ }
+ continue;
+ // aber nicht ausgeben, das erfolgt spaeter !!
+ }
+
+ } while( nAttrPos < nCntAttr && nStrPos >
+ *( pHt = pNd->GetSwpHints()[ nAttrPos ] )->GetStart() );
+
+ // dann gebe mal alle gesammelten Attribute von der String-Pos aus
+ aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset );
+ aEndPosLst.OutStartAttrs( rHTMLWrt, nStrPos + nOffset );
+ }
+
+ BOOL bWriteBreak = (HTML_PREFORMTXT_ON != rHTMLWrt.nLastParaToken);
+ if( bWriteBreak && pNd->GetNumRule() )
+ bWriteBreak = FALSE;
+
+ {
+ HTMLOutContext aContext( rHTMLWrt.eDestEnc );
+
+ xub_StrLen nPreSplitPos = 0;
+ for( ; nStrPos < nEnde; nStrPos++ )
+ {
+ aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
+
+ // Die an der aktuellen Position verankerten Rahmen ausgeben
+ if( bFlysLeft )
+ bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
+ nStrPos, HTML_POS_INSIDE,
+ &aContext );
+
+ BOOL bOutChar = TRUE;
+ const SwTxtAttr * pTxtHt = 0;
+ if( nAttrPos < nCntAttr && *pHt->GetStart() == nStrPos
+ && nStrPos != nEnde )
+ {
+ do {
+ if ( pHt->GetEnd() && !pHt->HasDummyChar() )
+ {
+ if( RES_CHRATR_KERNING == pHt->Which() &&
+ rHTMLWrt.IsHTMLMode(HTMLMODE_FIRSTLINE) &&
+ *pHt->GetEnd() - nStrPos == 1 &&
+ ' ' == rStr.GetChar(nStrPos) &&
+ ((const SvxKerningItem&)pHt->GetAttr()).GetValue() > 0 )
+ {
+ // Wenn erlaubt, wird das Ding als Spacer exportiert
+
+ bOutChar = FALSE; // Space nicht ausgeben
+ bWriteBreak = FALSE; // der Absatz ist aber auch nicht leer
+ HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
+ OutHTML_HoriSpacer( rWrt,
+ ((const SvxKerningItem&)pHt->GetAttr()).GetValue() );
+
+ // Der Hint braucht nun doch nicht weiter
+ // beruecksichtigt werden.
+ }
+ else if( *pHt->GetEnd() != nStrPos )
+ {
+ // Hints mit Ende einsortieren, wenn sie keinen
+ // leeren Bereich aufspannen (Hints, die keinen
+ // Bereich aufspannen werden ignoriert
+ aEndPosLst.Insert( pHt->GetAttr(), nStrPos + nOffset,
+ *pHt->GetEnd() + nOffset,
+ rHTMLWrt.aChrFmtInfos );
+ }
+ }
+ else
+ {
+ // Hints ohne-Ende werden als letztes ausgebeben
+ ASSERT( !pTxtHt,
+ "Wieso gibt es da schon ein Attribut ohne Ende?" );
+ if( rHTMLWrt.nTxtAttrsToIgnore>0 )
+ {
+ rHTMLWrt.nTxtAttrsToIgnore--;
+ }
+ else
+ {
+ pTxtHt = pHt;
+ USHORT nFldWhich;
+ if( RES_TXTATR_FIELD != pHt->Which() ||
+ ( RES_POSTITFLD != (nFldWhich = ((const SwFmtFld&)pHt->GetAttr()).GetFld()->Which()) &&
+ RES_SCRIPTFLD != nFldWhich ) )
+ bWriteBreak = FALSE;
+ }
+ bOutChar = FALSE; // keine 255 ausgeben
+ }
+ } while( ++nAttrPos < nCntAttr && nStrPos ==
+ *( pHt = pNd->GetSwpHints()[ nAttrPos ] )->GetStart() );
+ }
+
+ // Manche Draw-Formate koennen auch noch Attribute mitbringen
+ if( pTxtHt && RES_TXTATR_FLYCNT == pTxtHt->Which() )
+ {
+ const SwFrmFmt* pFrmFmt =
+ ((const SwFmtFlyCnt &)pTxtHt->GetAttr()).GetFrmFmt();
+
+ if( RES_DRAWFRMFMT == pFrmFmt->Which() )
+ aEndPosLst.Insert( *((const SwDrawFrmFmt *)pFrmFmt),
+ nStrPos + nOffset,
+ rHTMLWrt.aChrFmtInfos );
+ }
+
+ aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
+ aEndPosLst.OutStartAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
+
+ if( pTxtHt )
+ {
+ rHTMLWrt.bLFPossible = !rHTMLWrt.nLastParaToken && nStrPos > 0 &&
+ rStr.GetChar(nStrPos-1) == ' ';
+ sal_uInt16 nCSS1Script = rHTMLWrt.nCSS1Script;
+ rHTMLWrt.nCSS1Script = aEndPosLst.GetScriptAtPos(
+ nStrPos + nOffset, nCSS1Script );
+ HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
+ Out( aHTMLAttrFnTab, pTxtHt->GetAttr(), rHTMLWrt );
+ rHTMLWrt.nCSS1Script = nCSS1Script;
+ rHTMLWrt.bLFPossible = FALSE;
+ }
+
+ if( bOutChar )
+ {
+ sal_Unicode c = rStr.GetChar( nStrPos );
+ // versuche nach ungefaehr 255 Zeichen eine neue Zeile zu
+ // beginnen, aber nicht in PRE und nur bei Spaces
+ if( ' '==c && !rHTMLWrt.nLastParaToken )
+ {
+ xub_StrLen nLineLen;
+ if( rHTMLWrt.nLastParaToken )
+ nLineLen = nStrPos - nPreSplitPos;
+ else
+ nLineLen = rHTMLWrt.GetLineLen();
+
+ xub_StrLen nWordLen = rStr.Search( ' ', nStrPos+1 );
+ if( nWordLen == STRING_NOTFOUND )
+ nWordLen = nEnde;
+ nWordLen = nWordLen - nStrPos;
+
+ if( nLineLen >= rHTMLWrt.nWhishLineLen ||
+ (nLineLen+nWordLen) >= rHTMLWrt.nWhishLineLen )
+ {
+ HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
+ rHTMLWrt.OutNewLine();
+ bOutChar = FALSE;
+ if( rHTMLWrt.nLastParaToken )
+ nPreSplitPos = nStrPos+1;
+ }
+ }
+
+ if( bOutChar )
+ {
+ if( 0x0a == c )
+ {
+ HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak );
+ }
+ else
+ HTMLOutFuncs::Out_Char( rWrt.Strm(), c, aContext, &rHTMLWrt.aNonConvertableCharacters );
+
+ // Wenn das letzte Zeichen eines Absatzed ein harter
+ // Zeilen-Umbruch ist brauchen wir noch ein <BR> mehr, weil
+ // Netscape & Co in diesem Fall fuer den naechsten Absatz
+ // nicht in die naechste Zeile gehen.
+ bWriteBreak = (0x0a == c) &&
+ (HTML_PREFORMTXT_ON != rHTMLWrt.nLastParaToken);
+ }
+ }
+ }
+ HTMLOutFuncs::FlushToAscii( rWrt.Strm(), aContext );
+ }
+
+ aEndPosLst.OutEndAttrs( rHTMLWrt, STRING_MAXLEN );
+
+ // Die an der letzten Position verankerten Rahmen ausgeben
+ if( bFlysLeft )
+ bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
+ nEnde, HTML_POS_INSIDE );
+ ASSERT( !bFlysLeft, "Es wurden nicht alle Rahmen gespeichert!" );
+
+ rHTMLWrt.bTxtAttr = FALSE;
+
+ if( bWriteBreak )
+ {
+ BOOL bEndOfCell = rHTMLWrt.bOutTable &&
+ rWrt.pCurPam->GetPoint()->nNode.GetIndex() ==
+ rWrt.pCurPam->GetMark()->nNode.GetIndex();
+
+ if( bEndOfCell && !nEnde &&
+ rHTMLWrt.IsHTMLMode(HTMLMODE_NBSP_IN_TABLES) )
+ {
+ // Wenn der letzte Absatz einer Tabellezelle leer ist und
+ // wir fuer den MS-IE exportieren, schreiben wir statt eines
+ // <BR> ein &nbsp;
+ rWrt.Strm() << '&' << OOO_STRING_SVTOOLS_HTML_S_nbsp << ';';
+ }
+ else
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak );
+ const SvxULSpaceItem& rULSpace =
+ (const SvxULSpaceItem &)pNd->GetSwAttrSet().Get(RES_UL_SPACE);
+ if( rULSpace.GetLower() > 0 && !bEndOfCell &&
+ !rHTMLWrt.IsHTMLMode(HTMLMODE_NO_BR_AT_PAREND) )
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_linebreak );
+ rHTMLWrt.bLFPossible = TRUE;
+ }
+ }
+
+ if( rHTMLWrt.bClearLeft || rHTMLWrt.bClearRight )
+ {
+ const sal_Char *pStr;
+ if( rHTMLWrt.bClearLeft )
+ {
+ if( rHTMLWrt.bClearRight )
+ pStr = OOO_STRING_SVTOOLS_HTML_AL_all;
+ else
+ pStr = OOO_STRING_SVTOOLS_HTML_AL_left;
+ }
+ else
+ pStr = OOO_STRING_SVTOOLS_HTML_AL_right;
+
+ ByteString sOut( OOO_STRING_SVTOOLS_HTML_linebreak );
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += pStr;
+
+ HTMLOutFuncs::Out_AsciiTag( rHTMLWrt.Strm(), sOut.GetBuffer() );
+ rHTMLWrt.bClearLeft = FALSE;
+ rHTMLWrt.bClearRight = FALSE;
+
+ rHTMLWrt.bLFPossible = TRUE;
+ }
+
+ // wenn ein LF nicht schon erlaubt ist wird es erlaubt, wenn der
+ // Absatz mit einem ' ' endet
+ if( !rHTMLWrt.bLFPossible && !rHTMLWrt.nLastParaToken &&
+ nEnde > 0 && ' ' == rStr.GetChar(nEnde-1) )
+ rHTMLWrt.bLFPossible = TRUE;
+
+ rHTMLWrt.bTagOn = FALSE;
+ OutHTML_SwFmtOff( rWrt, aFmtInfo );
+
+ // eventuell eine Form schliessen
+ rHTMLWrt.OutForm( FALSE );
+
+ if( bPageBreakBehind )
+ rWrt.Strm() << '\f';
+
+ return rHTMLWrt;
+}
+
+
+sal_uInt32 SwHTMLWriter::ToPixel( sal_uInt32 nVal ) const
+{
+ if( Application::GetDefaultDevice() && nVal )
+ {
+ nVal = Application::GetDefaultDevice()->LogicToPixel(
+ Size( nVal, nVal ), MapMode( MAP_TWIP ) ).Width();
+ if( !nVal ) // wo ein Twip ist sollte auch ein Pixel sein
+ nVal = 1;
+ }
+ return nVal;
+}
+
+
+static Writer& OutHTML_CSS1Attr( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ // wenn gerade Hints geschrieben werden versuchen wir den Hint als
+ // CSS1-Attribut zu schreiben
+
+ if( ((SwHTMLWriter&)rWrt).bCfgOutStyles && ((SwHTMLWriter&)rWrt).bTxtAttr )
+ OutCSS1_HintSpanTag( rWrt, rHt );
+
+ return rWrt;
+}
+
+
+/* File CHRATR.HXX: */
+
+static Writer& OutHTML_SvxColor( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ // die Default-Farbe nur Schreiben, wenn sie als Hint vorkommt
+ //if( rHTMLWrt.bTagOn && !rHTMLWrt.bTxtAttr && rHTMLWrt.pDfltColor
+ // && rColor == *rHTMLWrt.pDfltColor )
+ // return rWrt;
+
+ if( !rHTMLWrt.bTxtAttr && rHTMLWrt.bCfgOutStyles && rHTMLWrt.bCfgPreferStyles )
+ {
+ // Font-Farbe nicht als Tag schreiben, wenn Styles normalen Tags
+ // vorgezogen werden
+ return rWrt;
+ }
+
+ if( rHTMLWrt.bTagOn )
+ {
+ Color aColor( ((const SvxColorItem&)rHt).GetValue() );
+ if( COL_AUTO == aColor.GetColor() )
+ aColor.SetColor( COL_BLACK );
+
+ ByteString sOut( '<' );
+ (((sOut += OOO_STRING_SVTOOLS_HTML_font) += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_Color( rWrt.Strm(), aColor, rHTMLWrt.eDestEnc ) << '>';
+ }
+ else
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font, FALSE );
+
+ return rWrt;
+}
+
+
+static Writer& OutHTML_SwPosture( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ const FontItalic nPosture = ((const SvxPostureItem&)rHt).GetPosture();
+ if( ITALIC_NORMAL == nPosture )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_italic, rHTMLWrt.bTagOn );
+ }
+ else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
+ {
+ // vielleicht als CSS1-Attribut ?
+ OutCSS1_HintSpanTag( rWrt, rHt );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutHTML_SvxFont( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ if( rHTMLWrt.bTagOn )
+ {
+ String aNames;
+ SwHTMLWriter::PrepareFontList( ((const SvxFontItem&)rHt), aNames, 0,
+ rHTMLWrt.IsHTMLMode(HTMLMODE_FONT_GENERIC) );
+ ByteString sOut( '<' );
+ (((sOut += OOO_STRING_SVTOOLS_HTML_font) += ' ') += OOO_STRING_SVTOOLS_HTML_O_face) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aNames, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters )
+ << "\">";
+ }
+ else
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font , FALSE );
+
+ return rWrt;
+}
+
+static Writer& OutHTML_SvxFontHeight( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ if( rHTMLWrt.bTagOn )
+ {
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_font;
+
+ UINT32 nHeight = ((const SvxFontHeightItem&)rHt).GetHeight();
+ USHORT nSize = rHTMLWrt.GetHTMLFontSize( nHeight );
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_size) += '=')
+ += ByteString::CreateFromInt32( nSize );
+ rWrt.Strm() << sOut.GetBuffer();
+
+ if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr &&
+ rHTMLWrt.aFontHeights[nSize-1] != nHeight )
+ {
+ // wenn die Groesse keiner HTML-Groesse entspricht,
+ // wird sie noch zusatzlich als Style-Option exportiert
+ OutCSS1_HintStyleOpt( rWrt, rHt );
+ }
+ rWrt.Strm() << '>';
+ }
+ else
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_font, FALSE );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutHTML_SvxLanguage( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ LanguageType eLang = ((const SvxLanguageItem &)rHt).GetLanguage();
+ if( LANGUAGE_DONTKNOW == eLang )
+ return rWrt;
+
+ if( rHTMLWrt.bTagOn )
+ {
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_span;
+ rWrt.Strm() << sOut.GetBuffer();
+ rHTMLWrt.OutLanguage( ((const SvxLanguageItem &)rHt).GetLanguage() );
+ rWrt.Strm() << '>';
+ }
+ else
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, FALSE );
+ }
+
+ return rWrt;
+}
+static Writer& OutHTML_SwWeight( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ const FontWeight nBold = ((const SvxWeightItem&)rHt).GetWeight();
+ if( WEIGHT_BOLD == nBold )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_bold, rHTMLWrt.bTagOn );
+ }
+ else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
+ {
+ // vielleicht als CSS1-Attribut ?
+ OutCSS1_HintSpanTag( rWrt, rHt );
+ }
+
+ return rWrt;
+}
+
+
+static Writer& OutHTML_SwCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ // Wegen Netscape schrieben wir hier STRIKE und nicht S raus!
+ const FontStrikeout nStrike = ((const SvxCrossedOutItem&)rHt).GetStrikeout();
+ if( STRIKEOUT_NONE != nStrike )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_strike, rHTMLWrt.bTagOn );
+ }
+ else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
+ {
+ // vielleicht als CSS1-Attribut ?
+ OutCSS1_HintSpanTag( rWrt, rHt );
+ }
+
+ return rWrt;
+}
+
+
+static Writer& OutHTML_SvxEscapement( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ const SvxEscapement eEscape =
+ (const SvxEscapement)((const SvxEscapementItem&)rHt).GetEnumValue();
+ const sal_Char *pStr = 0;
+ switch( eEscape )
+ {
+ case SVX_ESCAPEMENT_SUPERSCRIPT: pStr = OOO_STRING_SVTOOLS_HTML_superscript; break;
+ case SVX_ESCAPEMENT_SUBSCRIPT: pStr = OOO_STRING_SVTOOLS_HTML_subscript; break;
+ default:
+ ;
+ }
+
+ if( pStr )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, rHTMLWrt.bTagOn );
+ }
+ else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
+ {
+ // vielleicht als CSS1-Attribut ?
+ OutCSS1_HintSpanTag( rWrt, rHt );
+ }
+
+ return rWrt;
+}
+
+
+
+static Writer& OutHTML_SwUnderline( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ const FontUnderline eUnder = ((const SvxUnderlineItem&)rHt).GetLineStyle();
+ if( UNDERLINE_NONE != eUnder )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_underline, rHTMLWrt.bTagOn );
+ }
+ else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
+ {
+ // vielleicht als CSS1-Attribut ?
+ OutCSS1_HintSpanTag( rWrt, rHt );
+ }
+
+ return rWrt;
+}
+
+
+static Writer& OutHTML_SwFlyCnt( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+ SwFmtFlyCnt& rFlyCnt = (SwFmtFlyCnt&)rHt;
+
+ const SwFrmFmt& rFmt = *rFlyCnt.GetFrmFmt();
+ const SdrObject *pSdrObj = 0;
+
+ SwHTMLFrmType eType =
+ (SwHTMLFrmType)rHTMLWrt.GuessFrmType( rFmt, pSdrObj );
+ BYTE nMode = aHTMLOutFrmAsCharTable[eType][rHTMLWrt.nExportMode];
+ rHTMLWrt.OutFrmFmt( nMode, rFmt, pSdrObj );
+ return rWrt;
+}
+
+
+// Das ist jetzt unser Blink-Item. Blinkend wird eingeschaltet, indem man
+// das Item auf TRUE setzt!
+static Writer& OutHTML_SwBlink( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts || !rHTMLWrt.IsHTMLMode(HTMLMODE_BLINK) )
+ return rWrt;
+
+ if( ((const SvxBlinkItem&)rHt).GetValue() )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_blink, rHTMLWrt.bTagOn );
+ }
+ else if( rHTMLWrt.bCfgOutStyles && rHTMLWrt.bTxtAttr )
+ {
+ // vielleicht als CSS1-Attribut ?
+ OutCSS1_HintSpanTag( rWrt, rHt );
+ }
+
+ return rWrt;
+}
+
+Writer& OutHTML_INetFmt( Writer& rWrt, const SwFmtINetFmt& rINetFmt, BOOL bOn )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ String aURL( rINetFmt.GetValue() );
+ const SvxMacroTableDtor *pMacTable = rINetFmt.GetMacroTbl();
+ BOOL bEvents = pMacTable != 0 && pMacTable->Count() > 0;
+
+ // Gibt es ueberhaupt etwas auszugeben?
+ if( !aURL.Len() && !bEvents && !rINetFmt.GetName().Len() )
+ return rWrt;
+
+ // Tag aus? Dann nur ein </A> ausgeben.
+ if( !bOn )
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_anchor, FALSE );
+ return rWrt;
+ }
+
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_anchor;
+
+ sal_Bool bScriptDependent = sal_False;
+ {
+ const SwCharFmt* pFmt = rWrt.pDoc->GetCharFmtFromPool(
+ RES_POOLCHR_INET_NORMAL );
+ SwHTMLFmtInfo aFmtInfo( pFmt );
+ USHORT nPos;
+ if( rHTMLWrt.aChrFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
+ {
+ bScriptDependent = rHTMLWrt.aChrFmtInfos[nPos]->bScriptDependent;
+ }
+ }
+ if( !bScriptDependent )
+ {
+ const SwCharFmt* pFmt = rWrt.pDoc->GetCharFmtFromPool(
+ RES_POOLCHR_INET_VISIT );
+ SwHTMLFmtInfo aFmtInfo( pFmt );
+ USHORT nPos;
+ if( rHTMLWrt.aChrFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
+ {
+ bScriptDependent = rHTMLWrt.aChrFmtInfos[nPos]->bScriptDependent;
+ }
+ }
+
+ if( bScriptDependent )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"";
+ switch( rHTMLWrt.nCSS1Script )
+ {
+ case CSS1_OUTMODE_WESTERN:
+ sOut += "western";
+ break;
+ case CSS1_OUTMODE_CJK:
+ sOut += "cjk";
+ break;
+ case CSS1_OUTMODE_CTL:
+ sOut += "ctl";
+ break;
+ }
+ sOut += '\"';
+ }
+
+ rWrt.Strm() << sOut.GetBuffer();
+
+#define REL_HACK
+#ifdef REL_HACK
+ String sRel;
+#endif
+
+ if( aURL.Len() || bEvents )
+ {
+#ifdef REL_HACK
+ String sTmp( aURL );
+ sTmp.ToUpperAscii();
+ xub_StrLen nPos = sTmp.SearchAscii( "\" REL=" );
+ if( nPos!=STRING_NOTFOUND )
+ {
+ sRel = aURL.Copy( nPos+1 );
+ aURL.Erase( nPos );
+ }
+#endif
+ aURL.EraseLeadingChars().EraseTrailingChars();
+
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ rHTMLWrt.OutHyperlinkHRefValue( aURL );
+ sOut = '\"';
+ }
+ else
+ sOut.Erase();
+
+ if( rINetFmt.GetName().Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rINetFmt.GetName(),
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ const String& rTarget = rINetFmt.GetTargetFrame();
+ if( rTarget.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rTarget, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+#ifdef REL_HACK
+ if( sRel.Len() )
+ sOut += ByteString( sRel, RTL_TEXTENCODING_ASCII_US );
+#endif
+ if( sOut.Len() )
+ rWrt.Strm() << sOut.GetBuffer();
+
+ if( bEvents )
+ HTMLOutFuncs::Out_Events( rWrt.Strm(), *pMacTable, aAnchorEventTable,
+ rHTMLWrt.bCfgStarBasic, rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ rWrt.Strm() << ">";
+
+ return rWrt;
+}
+
+static Writer& OutHTML_SwFmtINetFmt( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ const SwFmtINetFmt& rINetFmt = (const SwFmtINetFmt&)rHt;
+
+ if( rHTMLWrt.bTagOn )
+ {
+ // ggf. ein noch offenes Attribut voruebergehend beenden
+ if( rHTMLWrt.aINetFmts.Count() )
+ {
+ SwFmtINetFmt *pINetFmt =
+ rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
+ OutHTML_INetFmt( rWrt, *pINetFmt, FALSE );
+ }
+
+ // jetzt das neue aufmachen
+ OutHTML_INetFmt( rWrt, rINetFmt, TRUE );
+
+ // und merken
+ const SwFmtINetFmt *pINetFmt = new SwFmtINetFmt( rINetFmt );
+ rHTMLWrt.aINetFmts.C40_INSERT( SwFmtINetFmt, pINetFmt,
+ rHTMLWrt.aINetFmts.Count() );
+ }
+ else
+ {
+ // das
+ OutHTML_INetFmt( rWrt, rINetFmt, FALSE );
+
+ ASSERT( rHTMLWrt.aINetFmts.Count(), "da fehlt doch ein URL-Attribut" );
+ if( rHTMLWrt.aINetFmts.Count() )
+ {
+ // das eigene Attribut vom Stack holen
+ SwFmtINetFmt *pINetFmt =
+ rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
+
+ rHTMLWrt.aINetFmts.Remove( rHTMLWrt.aINetFmts.Count()-1, 1 );
+ delete pINetFmt;
+ }
+
+ if( rHTMLWrt.aINetFmts.Count() )
+ {
+ // es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
+ // werden muss
+ SwFmtINetFmt *pINetFmt =
+ rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
+ OutHTML_INetFmt( rWrt, *pINetFmt, TRUE );
+ }
+ }
+
+ return rWrt;
+}
+
+static Writer& OutHTML_SwTxtCharFmt( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bOutOpts )
+ return rWrt;
+
+ const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rHt;
+ const SwCharFmt* pFmt = rChrFmt.GetCharFmt();
+
+ if( !pFmt )
+ {
+ return rWrt;
+ }
+
+ SwHTMLFmtInfo aFmtInfo( pFmt );
+ USHORT nPos;
+ if( !rHTMLWrt.aChrFmtInfos.Seek_Entry( &aFmtInfo, &nPos ) )
+ return rWrt;
+
+ const SwHTMLFmtInfo *pFmtInfo = rHTMLWrt.aChrFmtInfos[nPos];
+ ASSERT( pFmtInfo, "Wieso gint es keine Infos ueber die Zeichenvorlage?" );
+
+ if( rHTMLWrt.bTagOn )
+ {
+ ByteString sOut( '<' );
+ if( pFmtInfo->aToken.Len() > 0 )
+ sOut += pFmtInfo->aToken;
+ else
+ sOut += OOO_STRING_SVTOOLS_HTML_span;
+ if( rHTMLWrt.bCfgOutStyles &&
+ (pFmtInfo->aClass.Len() || pFmtInfo->bScriptDependent) )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ String aClass( pFmtInfo->aClass );
+ if( pFmtInfo->bScriptDependent )
+ {
+ if( aClass.Len() )
+ aClass += '-';
+ switch( rHTMLWrt.nCSS1Script )
+ {
+ case CSS1_OUTMODE_WESTERN:
+ aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("western") );
+ break;
+ case CSS1_OUTMODE_CJK:
+ aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("cjk") );
+ break;
+ case CSS1_OUTMODE_CTL:
+ aClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("ctl") );
+ break;
+ }
+ }
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aClass,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ sOut += '>';
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+ else
+ {
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
+ pFmtInfo->aToken.Len() ? pFmtInfo->aToken.GetBuffer()
+ : OOO_STRING_SVTOOLS_HTML_span,
+ FALSE );
+ }
+
+ return rWrt;
+}
+
+static Writer& OutHTML_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( !rHTMLWrt.bOutOpts || !rHTMLWrt.bTagOn )
+ return rWrt;
+
+ SvxAdjustItem& rAdjust = (SvxAdjustItem&)rHt;
+ const sal_Char* pStr = 0;
+ switch( rAdjust.GetAdjust() )
+ {
+ case SVX_ADJUST_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_AL_center; break;
+ case SVX_ADJUST_LEFT: pStr = OOO_STRING_SVTOOLS_HTML_AL_left; break;
+ case SVX_ADJUST_RIGHT: pStr = OOO_STRING_SVTOOLS_HTML_AL_right; break;
+ case SVX_ADJUST_BLOCK: pStr = OOO_STRING_SVTOOLS_HTML_AL_justify; break;
+ default:
+ ;
+ }
+ if( pStr )
+ {
+ ByteString sOut( ' ' );
+ ((sOut += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+
+ return rWrt;
+}
+
+/*
+ * lege hier die Tabellen fuer die HTML-Funktions-Pointer auf
+ * die Ausgabe-Funktionen an.
+ * Es sind lokale Strukturen, die nur innerhalb der HTML-DLL
+ * bekannt sein muessen.
+ */
+
+
+SwAttrFnTab aHTMLAttrFnTab = {
+/* RES_CHRATR_CASEMAP */ OutHTML_CSS1Attr,
+/* RES_CHRATR_CHARSETCOLOR */ 0,
+/* RES_CHRATR_COLOR */ OutHTML_SvxColor,
+/* RES_CHRATR_CONTOUR */ 0,
+/* RES_CHRATR_CROSSEDOUT */ OutHTML_SwCrossedOut,
+/* RES_CHRATR_ESCAPEMENT */ OutHTML_SvxEscapement,
+/* RES_CHRATR_FONT */ OutHTML_SvxFont,
+/* RES_CHRATR_FONTSIZE */ OutHTML_SvxFontHeight,
+/* RES_CHRATR_KERNING */ OutHTML_CSS1Attr,
+/* RES_CHRATR_LANGUAGE */ OutHTML_SvxLanguage,
+/* RES_CHRATR_POSTURE */ OutHTML_SwPosture,
+/* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
+/* RES_CHRATR_SHADOWED */ 0,
+/* RES_CHRATR_UNDERLINE */ OutHTML_SwUnderline,
+/* RES_CHRATR_WEIGHT */ OutHTML_SwWeight,
+/* RES_CHRATR_WORDLINEMODE */ 0,
+/* RES_CHRATR_AUTOKERN */ 0,
+/* RES_CHRATR_BLINK */ OutHTML_SwBlink,
+/* RES_CHRATR_NOHYPHEN */ 0, // Neu: nicht trennen
+/* RES_CHRATR_NOLINEBREAK */ 0, // Neu: nicht umbrechen
+/* RES_CHRATR_BACKGROUND */ OutHTML_CSS1Attr, // Neu: Zeichenhintergrund
+/* RES_CHRATR_CJK_FONT */ OutHTML_SvxFont,
+/* RES_CHRATR_CJK_FONTSIZE */ OutHTML_SvxFontHeight,
+/* RES_CHRATR_CJK_LANGUAGE */ OutHTML_SvxLanguage,
+/* RES_CHRATR_CJK_POSTURE */ OutHTML_SwPosture,
+/* RES_CHRATR_CJK_WEIGHT */ OutHTML_SwWeight,
+/* RES_CHRATR_CTL_FONT */ OutHTML_SvxFont,
+/* RES_CHRATR_CTL_FONTSIZE */ OutHTML_SvxFontHeight,
+/* RES_CHRATR_CTL_LANGUAGE */ OutHTML_SvxLanguage,
+/* RES_CHRATR_CTL_POSTURE */ OutHTML_SwPosture,
+/* RES_CHRATR_CTL_WEIGHT */ OutHTML_SwWeight,
+/* RES_CHRATR_ROTATE */ 0,
+/* RES_CHRATR_EMPHASIS_MARK */ 0,
+/* RES_CHRATR_TWO_LINES */ 0,
+/* RES_CHRATR_SCALEW */ 0,
+/* RES_CHRATR_RELIEF */ 0,
+/* RES_CHRATR_HIDDEN */ 0,
+/* RES_CHRATR_OVERLINE */ OutHTML_CSS1Attr,
+/* RES_CHRATR_DUMMY1 */ 0,
+/* RES_CHRATR_DUMMY2 */ 0,
+
+/* RES_TXTATR_REFMARK */ 0,
+/* RES_TXTATR_TOXMARK */ 0,
+/* RES_TXTATR_META */ 0,
+/* RES_TXTATR_METAFIELD */ 0,
+/* RES_TXTATR_AUTOFMT */ 0,
+/* RES_TXTATR_INETFMT */ OutHTML_SwFmtINetFmt,
+/* RES_TXTATR_CHARFMT */ OutHTML_SwTxtCharFmt,
+/* RES_TXTATR_CJK_RUBY */ 0,
+/* RES_TXTATR_UNKNOWN_CONTAINER */ 0,
+/* RES_TXTATR_DUMMY5 */ 0,
+
+/* RES_TXTATR_FIELD */ OutHTML_SwFmtFld,
+/* RES_TXTATR_FLYCNT */ OutHTML_SwFlyCnt,
+/* RES_TXTATR_FTN */ OutHTML_SwFmtFtn,
+/* RES_TXTATR_DUMMY4 */ 0,
+/* RES_TXTATR_DUMMY3 */ 0,
+/* RES_TXTATR_DUMMY1 */ 0, // Dummy:
+/* RES_TXTATR_DUMMY2 */ 0, // Dummy:
+
+/* RES_PARATR_LINESPACING */ 0,
+/* RES_PARATR_ADJUST */ OutHTML_SvxAdjust,
+/* RES_PARATR_SPLIT */ 0,
+/* RES_PARATR_WIDOWS */ 0,
+/* RES_PARATR_ORPHANS */ 0,
+/* RES_PARATR_TABSTOP */ 0,
+/* RES_PARATR_HYPHENZONE*/ 0,
+/* RES_PARATR_DROP */ OutHTML_CSS1Attr,
+/* RES_PARATR_REGISTER */ 0, // neu: Registerhaltigkeit
+/* RES_PARATR_NUMRULE */ 0, // Dummy:
+/* RES_PARATR_SCRIPTSPACE */ 0, // Dummy:
+/* RES_PARATR_HANGINGPUNCTUATION */ 0, // Dummy:
+/* RES_PARATR_FORBIDDEN_RULES */ 0, // new
+/* RES_PARATR_VERTALIGN */ 0, // new
+/* RES_PARATR_SNAPTOGRID*/ 0, // new
+/* RES_PARATR_CONNECT_TO_BORDER */ 0, // new
+
+/* RES_PARATR_LIST_ID */ 0, // new
+/* RES_PARATR_LIST_LEVEL */ 0, // new
+/* RES_PARATR_LIST_ISRESTART */ 0, // new
+/* RES_PARATR_LIST_RESTARTVALUE */ 0, // new
+/* RES_PARATR_LIST_ISCOUNTED */ 0, // new
+
+/* RES_FILL_ORDER */ 0,
+/* RES_FRM_SIZE */ 0,
+/* RES_PAPER_BIN */ 0,
+/* RES_LR_SPACE */ 0,
+/* RES_UL_SPACE */ 0,
+/* RES_PAGEDESC */ 0,
+/* RES_BREAK */ 0,
+/* RES_CNTNT */ 0,
+/* RES_HEADER */ 0,
+/* RES_FOOTER */ 0,
+/* RES_PRINT */ 0,
+/* RES_OPAQUE */ 0,
+/* RES_PROTECT */ 0,
+/* RES_SURROUND */ 0,
+/* RES_VERT_ORIENT */ 0,
+/* RES_HORI_ORIENT */ 0,
+/* RES_ANCHOR */ 0,
+/* RES_BACKGROUND */ 0,
+/* RES_BOX */ 0,
+/* RES_SHADOW */ 0,
+/* RES_FRMMACRO */ 0,
+/* RES_COL */ 0,
+/* RES_KEEP */ 0,
+/* RES_URL */ 0,
+/* RES_EDIT_IN_READONLY */ 0,
+/* RES_LAYOUT_SPLIT */ 0,
+/* RES_FRMATR_DUMMY1 */ 0, // Dummy:
+/* RES_FRMATR_DUMMY2 */ 0, // Dummy:
+/* RES_AUTO_STYLE */ 0, // Dummy:
+/* RES_FRMATR_DUMMY4 */ 0, // Dummy:
+/* RES_FRMATR_DUMMY5 */ 0, // Dummy:
+/* RES_FRMATR_DUMMY6 */ 0, // Dummy:
+/* RES_FRMATR_DUMMY7 */ 0, // Dummy:
+/* RES_FRMATR_DUMMY8 */ 0, // Dummy:
+/* RES_FRMATR_DUMMY9 */ 0, // Dummy:
+/* RES_FOLLOW_TEXT_FLOW */ 0,
+/* RES_WRAP_INFLUENCE_ON_OBJPOS */ 0,
+/* RES_FRMATR_DUMMY2 */ 0, // Dummy:
+/* RES_AUTO_STYLE */ 0, // Dummy:
+/* RES_FRMATR_DUMMY4 */ 0, // Dummy:
+/* RES_FRMATR_DUMMY5 */ 0, // Dummy:
+
+/* RES_GRFATR_MIRRORGRF */ 0,
+/* RES_GRFATR_CROPGRF */ 0,
+/* RES_GRFATR_ROTATION */ 0,
+/* RES_GRFATR_LUMINANCE */ 0,
+/* RES_GRFATR_CONTRAST */ 0,
+/* RES_GRFATR_CHANNELR */ 0,
+/* RES_GRFATR_CHANNELG */ 0,
+/* RES_GRFATR_CHANNELB */ 0,
+/* RES_GRFATR_GAMMA */ 0,
+/* RES_GRFATR_INVERT */ 0,
+/* RES_GRFATR_TRANSPARENCY */ 0,
+/* RES_GRFATR_DRWAMODE */ 0,
+/* RES_GRFATR_DUMMY1 */ 0,
+/* RES_GRFATR_DUMMY2 */ 0,
+/* RES_GRFATR_DUMMY3 */ 0,
+/* RES_GRFATR_DUMMY4 */ 0,
+/* RES_GRFATR_DUMMY5 */ 0,
+
+/* RES_BOXATR_FORMAT */ 0,
+/* RES_BOXATR_FORMULA */ 0,
+/* RES_BOXATR_VALUE */ 0
+};
diff --git a/sw/source/filter/html/htmlbas.cxx b/sw/source/filter/html/htmlbas.cxx
new file mode 100644
index 000000000000..6a6bcc04b34c
--- /dev/null
+++ b/sw/source/filter/html/htmlbas.cxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <sfx2/sfx.hrc>
+
+#define _SVSTDARR_STRINGSSORTDTOR
+#include <svl/svstdarr.hxx>
+#include <basic/sbx.hxx>
+#include <basic/basmgr.hxx>
+#include <basic/sbmod.hxx>
+#include <sfx2/evntconf.hxx>
+#include <sfx2/app.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <fmtornt.hxx>
+#include <fmtfld.hxx>
+
+#include "doc.hxx"
+#include "docsh.hxx"
+#include "docufld.hxx"
+#include "wrthtml.hxx"
+#include "swhtml.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+
+
+static HTMLOutEvent __FAR_DATA aBodyEventTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_O_SDonload, OOO_STRING_SVTOOLS_HTML_O_onload, SFX_EVENT_OPENDOC },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonunload, OOO_STRING_SVTOOLS_HTML_O_onunload, SFX_EVENT_PREPARECLOSEDOC },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonfocus, OOO_STRING_SVTOOLS_HTML_O_onfocus, SFX_EVENT_ACTIVATEDOC },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonblur, OOO_STRING_SVTOOLS_HTML_O_onblur, SFX_EVENT_DEACTIVATEDOC },
+ { 0, 0, 0 }
+};
+
+
+void SwHTMLParser::NewScript()
+{
+ ParseScriptOptions( aScriptType, sBaseURL, eScriptLang, aScriptURL,
+ aBasicLib, aBasicModule );
+
+ if( aScriptURL.Len() )
+ {
+ // Den Inhalt des Script-Tags ignorieren
+ bIgnoreRawData = TRUE;
+ }
+}
+
+void SwHTMLParser::EndScript()
+{
+ BOOL bInsIntoBasic = FALSE,
+ bInsSrcIntoFld = FALSE;
+
+ switch( eScriptLang )
+ {
+ case HTML_SL_STARBASIC:
+ bInsIntoBasic = TRUE;
+ break;
+ default:
+ bInsSrcIntoFld = TRUE;
+ break;
+ }
+
+ bIgnoreRawData = FALSE;
+ aScriptSource.ConvertLineEnd();
+
+// MIB 23.5.97: SGML-Kommentare brauchen nicht mehr entfernt zu werden,
+// weil JS das jetzt selber kann.
+// RemoveSGMLComment( aScriptSource, TRUE );
+
+ // Ausser StarBasic und unbenutzem JavaScript jedes Script oder den
+ // Modulnamen in einem Feld merken merken
+ if( bInsSrcIntoFld && !bIgnoreHTMLComments )
+ {
+ SwScriptFieldType *pType =
+ (SwScriptFieldType*)pDoc->GetSysFldType( RES_SCRIPTFLD );
+
+ SwScriptField aFld( pType, aScriptType,
+ aScriptURL.Len() ? aScriptURL : aScriptSource,
+ aScriptURL.Len()!=0 );
+ InsertAttr( SwFmtFld( aFld ) );
+ }
+
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ if( aScriptSource.Len() && pDocSh &&
+ bInsIntoBasic && IsNewDoc() )
+ {
+ // Fuer JavaScript und StarBasic noch ein Basic-Modul anlegen
+ // Das Basic entfernt natuerlich weiterhin keine SGML-Kommentare
+ RemoveSGMLComment( aScriptSource, TRUE );
+
+ // get library name
+ ::rtl::OUString aLibName;
+ if( aBasicLib.Len() )
+ aLibName = aBasicLib;
+ else
+ aLibName = ::rtl::OUString::createFromAscii( "Standard" );
+
+ // get module library container
+ Reference< script::XLibraryContainer > xModLibContainer( pDocSh->GetBasicContainer(), UNO_QUERY );
+
+ if ( xModLibContainer.is() )
+ {
+ Reference< container::XNameContainer > xModLib;
+ if ( xModLibContainer->hasByName( aLibName ) )
+ {
+ // get module library
+ Any aElement = xModLibContainer->getByName( aLibName );
+ aElement >>= xModLib;
+ }
+ else
+ {
+ // create module library
+ xModLib = xModLibContainer->createLibrary( aLibName );
+ }
+
+ if ( xModLib.is() )
+ {
+ if( !aBasicModule.Len() )
+ {
+ // create module name
+ BOOL bFound = TRUE;
+ while( bFound )
+ {
+ aBasicModule.AssignAscii( "Modul" );
+ aBasicModule += String::CreateFromInt32( (sal_Int32)(++nSBModuleCnt) );
+ bFound = xModLib->hasByName( ::rtl::OUString( aBasicModule ) );
+ }
+ }
+
+ // create module
+ ::rtl::OUString aModName( aBasicModule );
+ if ( !xModLib->hasByName( aModName ) )
+ {
+ Any aElement;
+ aElement <<= ::rtl::OUString( aScriptSource );
+ xModLib->insertByName( aModName , aElement );
+ }
+ }
+ }
+
+ // get dialog library container
+ Reference< script::XLibraryContainer > xDlgLibContainer( pDocSh->GetDialogContainer(), UNO_QUERY );
+
+ if ( xDlgLibContainer.is() )
+ {
+ if ( !xDlgLibContainer->hasByName( aLibName ) )
+ {
+ // create dialog library
+ xDlgLibContainer->createLibrary( aLibName );
+ }
+ }
+ }
+
+ aScriptSource.Erase();
+ aScriptType.Erase();
+ aScriptURL.Erase();
+
+ aBasicLib.Erase();
+ aBasicModule.Erase();
+}
+
+void SwHTMLParser::AddScriptSource()
+{
+ // Hier merken wir und nur ein par Strings
+ if( aToken.Len() > 2 &&
+ (HTML_SL_STARBASIC==eScriptLang && aToken.GetChar( 0 ) == '\'') )
+ {
+ xub_StrLen nPos = STRING_NOTFOUND;
+ if( !aBasicLib.Len() )
+ {
+ nPos = aToken.SearchAscii( OOO_STRING_SVTOOLS_HTML_SB_library );
+ if( nPos != STRING_NOTFOUND )
+ {
+ aBasicLib =
+ aToken.Copy( nPos + sizeof(OOO_STRING_SVTOOLS_HTML_SB_library) - 1 );
+ aBasicLib.EraseLeadingChars().EraseTrailingChars();
+ }
+ }
+
+ if( !aBasicModule.Len() && nPos==STRING_NOTFOUND )
+ {
+ nPos = aToken.SearchAscii( OOO_STRING_SVTOOLS_HTML_SB_module );
+ if( nPos != STRING_NOTFOUND )
+ {
+ aBasicModule =
+ aToken.Copy( nPos + sizeof(OOO_STRING_SVTOOLS_HTML_SB_module) - 1 );
+ aBasicModule.EraseLeadingChars().EraseTrailingChars();
+ }
+ }
+
+ if( nPos==STRING_NOTFOUND )
+ {
+ if( aScriptSource.Len() )
+ aScriptSource += '\n';
+ (aScriptSource += aToken);
+ }
+ }
+ else if( aScriptSource.Len() || aToken.Len() )
+ {
+ // Leerzeilen am Anfang werden ignoriert
+ if( aScriptSource.Len() )
+ {
+ aScriptSource += '\n';
+ }
+ else
+ {
+ // Wir stehen hinter dem CR/LF der Zeile davor
+ nScriptStartLineNr = GetLineNr() - 1;
+ }
+ aScriptSource += aToken;
+ }
+}
+
+void SwHTMLParser::InsertBasicDocEvent( rtl::OUString aEvent, const String& rName,
+ ScriptType eScrType,
+ const String& rScrType )
+{
+ ASSERT( rName.Len(), "InsertBasicDocEvent() ohne Macro gerufen" );
+ if( !rName.Len() )
+ return;
+
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ ASSERT( pDocSh, "Wo ist die DocShell?" );
+ if( !pDocSh )
+ return;
+
+ String sEvent( rName );
+ sEvent.ConvertLineEnd();
+ String sScriptType;
+ if( EXTENDED_STYPE == eScrType )
+ sScriptType = rScrType;
+
+ rtl::OUString aEventName;
+
+ SfxEventConfiguration* pECfg = SFX_APP()->GetEventConfig();
+ pECfg->ConfigureEvent( aEvent, SvxMacro( sEvent, sScriptType, eScrType ),
+ pDocSh );
+}
+
+void SwHTMLWriter::OutBasic()
+{
+ if( !bCfgStarBasic )
+ return;
+
+ SFX_APP()->EnterBasicCall();
+
+ BasicManager *pBasicMan = pDoc->GetDocShell()->GetBasicManager();
+ ASSERT( pBasicMan, "Wo ist der Basic-Manager?" );
+ //JP 17.07.96: Bug 29538 - nur das DocumentBasic schreiben
+ if( !pBasicMan || pBasicMan == SFX_APP()->GetBasicManager() )
+ {
+ SFX_APP()->LeaveBasicCall();
+ return;
+ }
+
+ // und jetzt alle StarBasic-Module und alle unbenutzen JavaSrript-Module
+ // ausgeben
+ for( USHORT i=0; i<pBasicMan->GetLibCount(); i++ )
+ {
+ StarBASIC *pBasic = pBasicMan->GetLib( i );
+ const String& rLibName = pBasic->GetName();
+
+ SbxArray *pModules = pBasic->GetModules();
+ for( USHORT j=0; j<pModules->Count(); j++ )
+ {
+ const SbModule *pModule = PTR_CAST( SbModule, pModules->Get(j) );
+ ASSERT( pModule, "Wo ist das Modul?" );
+
+ String sLang(
+ String::CreateFromAscii( SVX_MACRO_LANGUAGE_STARBASIC ) );
+ ScriptType eType = STARBASIC;
+
+ if( 0==i && 0==j )
+ {
+ OutNewLine();
+ ByteString sOut( '<' );
+ sOut.Append( OOO_STRING_SVTOOLS_HTML_meta );
+ sOut.Append( ' ' );
+ sOut.Append( OOO_STRING_SVTOOLS_HTML_O_httpequiv );
+ sOut.Append( "=\"" );
+ sOut.Append( OOO_STRING_SVTOOLS_HTML_META_content_script_type );
+ sOut.Append( "\" " );
+ sOut.Append( OOO_STRING_SVTOOLS_HTML_O_content );
+ sOut.Append( "=\"text/x-" );
+ Strm() << sOut.GetBuffer();
+ // Entities aren't welcome here
+ ByteString sLang8( sLang, eDestEnc );
+ Strm() << sLang8.GetBuffer() << "\">";
+ }
+
+ const String& rModName = pModule->GetName();
+ Strm() << SwHTMLWriter::sNewLine; // nicht einruecken!
+ HTMLOutFuncs::OutScript( Strm(), GetBaseURL(), pModule->GetSource(),
+ sLang, eType, aEmptyStr,
+ &rLibName, &rModName,
+ eDestEnc, &aNonConvertableCharacters );
+ }
+ }
+
+ SFX_APP()->LeaveBasicCall();
+}
+
+static const char* aEventNames[] =
+{
+ "OnLoad", "OnPrepareUnload", "OnFocus", "OnUnfocus"
+};
+
+void SwHTMLWriter::OutBasicBodyEvents()
+{
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ if( !pDocSh )
+ return;
+
+ SvxMacroTableDtor *pDocTable = new SvxMacroTableDtor;
+
+ uno::Reference< document::XEventsSupplier > xSup( pDocSh->GetModel(), uno::UNO_QUERY );
+ uno::Reference < container::XNameReplace > xEvents = xSup->getEvents();
+ for ( sal_Int32 i=0; i<4; i++ )
+ {
+ SvxMacro* pMacro = SfxEventConfiguration::ConvertToMacro( xEvents->getByName( ::rtl::OUString::createFromAscii(aEventNames[i]) ), pDocSh, TRUE );
+ if ( pMacro )
+ pDocTable->Insert( aBodyEventTable[i].nEvent, pMacro );
+ }
+
+ if( pDocTable && pDocTable->Count() )
+ HTMLOutFuncs::Out_Events( Strm(), *pDocTable, aBodyEventTable,
+ bCfgStarBasic, eDestEnc, &aNonConvertableCharacters );
+}
+
+
diff --git a/sw/source/filter/html/htmlcss1.cxx b/sw/source/filter/html/htmlcss1.cxx
new file mode 100644
index 000000000000..9d05d833c2d2
--- /dev/null
+++ b/sw/source/filter/html/htmlcss1.cxx
@@ -0,0 +1,2477 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <svl/itemiter.hxx>
+#include <svl/whiter.hxx>
+#include <svl/urihelper.hxx>
+#include <i18npool/mslangid.hxx>
+#include <sfx2/docfile.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/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 <svx/svxids.hrc>
+
+#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_AT_PAGE );
+ aAnchor.SetPageNum( 1 );
+ }
+ nHoriPos = rPropInfo.nLeft;
+ nVertPos = rPropInfo.nTop;
+ }
+ else
+ {
+ aAnchor.SetType( FLY_AT_PARA );
+ 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_AT_CHAR );
+ pPam->Move( fnMoveBackward );
+ eVertOri = text::VertOrientation::CHAR_BOTTOM;
+ eVertRel = text::RelOrientation::CHAR;
+ }
+ else
+ {
+ aAnchor.SetType( FLY_AT_PARA );
+ 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 );
+ }
+}
diff --git a/sw/source/filter/html/htmlctxt.cxx b/sw/source/filter/html/htmlctxt.cxx
new file mode 100644
index 000000000000..485ac5dd2a2b
--- /dev/null
+++ b/sw/source/filter/html/htmlctxt.cxx
@@ -0,0 +1,752 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <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.
+
+ USHORT nContextStMin; // In Umgebung gueltige Stack-
+ // Untergrenze, wenn der Stack
+ // geschuetzt werden soll.
+ USHORT nContextStAttrMin; // In Umgebung gueltige Stack-
+ // Untergrenze, wenn die Attribute
+ // nicht beibehalten werden sollen.
+
+ BOOL bStripTrailingPara : 1; // letzen Absatz entfernen?
+ BOOL bKeepNumRules : 1; // Numerierung beibehalten?
+ BOOL bPopStack : 1; // Stack-Elemente oberhalb des
+ // zu schliessenden entfernen?
+ BOOL bFixHeaderDist : 1;
+ BOOL bFixFooterDist : 1;
+
+public:
+
+ _HTMLAttrContext_SaveDoc() :
+ pPos( 0 ), pAttrTab( 0 ),
+ nContextStMin( USHRT_MAX ), nContextStAttrMin( USHRT_MAX ),
+ bStripTrailingPara( FALSE ), bKeepNumRules( FALSE ),
+ bPopStack( FALSE ),
+ bFixHeaderDist( FALSE ), bFixFooterDist( 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( BOOL bCreate= FALSE );
+
+ void SetContextStMin( USHORT nMin ) { nContextStMin = nMin; }
+ USHORT GetContextStMin() const { return nContextStMin; }
+
+ void SetContextStAttrMin( USHORT nMin ) { nContextStAttrMin = nMin; }
+ USHORT GetContextStAttrMin() const { return nContextStAttrMin; }
+
+ void SetStripTrailingPara( BOOL bSet ) { bStripTrailingPara = bSet; }
+ BOOL GetStripTrailingPara() const { return bStripTrailingPara; }
+
+ void SetKeepNumRules( BOOL bSet ) { bKeepNumRules = bSet; }
+ BOOL GetKeepNumRules() const { return bKeepNumRules; }
+
+ void SetFixHeaderDist( BOOL bSet ) { bFixHeaderDist = bSet; }
+ BOOL GetFixHeaderDist() const { return bFixHeaderDist; }
+
+ void SetFixFooterDist( BOOL bSet ) { bFixFooterDist = bSet; }
+ BOOL GetFixFooterDist() const { return bFixFooterDist; }
+};
+
+_HTMLAttrTable *_HTMLAttrContext_SaveDoc::GetAttrTab( BOOL bCreate )
+{
+ if( !pAttrTab && bCreate )
+ {
+ pAttrTab = new _HTMLAttrTable;
+ memset( pAttrTab, 0, sizeof( _HTMLAttrTable ));
+ }
+ return pAttrTab;
+}
+
+/* */
+
+_HTMLAttrContext_SaveDoc *_HTMLAttrContext::GetSaveDocContext( 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();
+
+ BOOL bMoveBack = FALSE;
+
+ // alle noch offenen Attribute beenden und hinter der Tabelle
+ // neu aufspannen
+ _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
+ for( USHORT nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
+ nCnt--; ++pTbl )
+ {
+ _HTMLAttr *pAttr = *pTbl;
+ while( pAttr )
+ {
+ _HTMLAttr *pNext = pAttr->GetNext();
+ _HTMLAttr *pPrev = pAttr->GetPrev();
+
+ USHORT 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
+ {
+ USHORT 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
+ {
+ USHORT 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,
+ USHORT nFlags,
+ const SwPosition *pNewPos )
+{
+ _HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext( 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( 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( USHORT 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();
+}
+
+/* */
+
+BOOL SwHTMLParser::DoPositioning( SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo &rPropInfo,
+ _HTMLAttrContext *pContext )
+{
+ BOOL bRet = 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( TRUE );
+ rPropInfo.aId.Erase();
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+BOOL SwHTMLParser::CreateContainer( const String& rClass,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo &rPropInfo,
+ _HTMLAttrContext *pContext )
+{
+ BOOL bRet = 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, FALSE, FALSE, rItemSet, rPropInfo,
+ *pFrmItemSet );
+ SetSpace( aDummy, rItemSet, rPropInfo, *pFrmItemSet );
+ SetFrmFmtAttrs( rItemSet, rPropInfo, HTML_FF_BOX|HTML_FF_BACKGROUND|HTML_FF_DIRECTION,
+ *pFrmItemSet );
+
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+/* */
+
+void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo &rPropInfo,
+ _HTMLAttrContext *pContext,
+ 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) ...
+ USHORT nOldLeft = 0, nOldRight = 0;
+ short nOldIndent = 0;
+ BOOL bIgnoreTop = aContexts.Count() > nContextStMin &&
+ aContexts[aContexts.Count()-1] == pContext;
+ GetMarginsFromContext( nOldLeft, nOldRight, nOldIndent,
+ bIgnoreTop );
+
+
+ // und noch die aktuell gueltigen
+ USHORT 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< USHORT >(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< USHORT >(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, FALSE );
+ }
+ break;
+
+ case RES_UL_SPACE:
+ if( !rPropInfo.bTopMargin || !rPropInfo.bBottomMargin )
+ {
+ USHORT 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( TRUE );
+
+ // Und die jetzt gueltigen Flags sollen wieder gesetzt werden.
+ if( IsReadPRE() )
+ pCntxt->SetRestartPRE( TRUE );
+ if( IsReadXMP() )
+ pCntxt->SetRestartXMP( TRUE );
+ if( IsReadListing() )
+ pCntxt->SetRestartListing( 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;
+}
diff --git a/sw/source/filter/html/htmldraw.cxx b/sw/source/filter/html/htmldraw.cxx
new file mode 100644
index 000000000000..e0f8be92c93e
--- /dev/null
+++ b/sw/source/filter/html/htmldraw.cxx
@@ -0,0 +1,859 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/eeitem.hxx>
+
+#ifndef _OUTLINER_HXX //autogen
+#define _EEITEMID_HXX
+#include <editeng/outliner.hxx>
+#endif
+#include <svx/xfillit.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <svl/itemiter.hxx>
+#include <svl/whiter.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <svx/svdpool.hxx>
+
+
+#include "charatr.hxx"
+#include <frmfmt.hxx>
+#include <fmtanchr.hxx>
+#include <fmtsrnd.hxx>
+#include "ndtxt.hxx"
+#include "doc.hxx"
+#include "dcontact.hxx"
+#include "poolfmt.hxx"
+#include "swcss1.hxx"
+#include "swhtml.hxx"
+#include "wrthtml.hxx"
+
+using namespace ::com::sun::star;
+
+
+const sal_uInt32 HTML_FRMOPTS_MARQUEE =
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SPACE;
+
+const sal_uInt32 HTML_FRMOPTS_MARQUEE_CSS1 =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SPACE;
+
+static HTMLOptionEnum __FAR_DATA aHTMLMarqBehaviorTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_BEHAV_scroll, SDRTEXTANI_SCROLL },
+ { OOO_STRING_SVTOOLS_HTML_BEHAV_alternate, SDRTEXTANI_ALTERNATE },
+ { OOO_STRING_SVTOOLS_HTML_BEHAV_slide, SDRTEXTANI_SLIDE },
+ { 0, 0 }
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLMarqDirectionTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_AL_left, SDRTEXTANI_LEFT },
+ { OOO_STRING_SVTOOLS_HTML_AL_right, SDRTEXTANI_RIGHT },
+ { 0, 0 }
+};
+
+/* */
+void SwHTMLParser::InsertDrawObject( SdrObject* pNewDrawObj,
+ const Size& rPixSpace,
+ sal_Int16 eVertOri,
+ sal_Int16 eHoriOri,
+ SfxItemSet& rCSS1ItemSet,
+ SvxCSS1PropertyInfo& rCSS1PropInfo,
+ sal_Bool bHidden )
+{
+ // always on top of text.
+ // OD 02.07.2003 #108784# but in invisible layer. <ConnectToLayout> will
+ // move the object to the visible layer.
+ pNewDrawObj->SetLayer( pDoc->GetInvisibleHeavenId() );
+
+ SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs( aFrmSet );
+
+ sal_uInt16 nLeftSpace = 0, nRightSpace = 0, nUpperSpace = 0, nLowerSpace = 0;
+ if( (rPixSpace.Width() || rPixSpace.Height()) && Application::GetDefaultDevice() )
+ {
+ Size aTwipSpc( rPixSpace.Width(), rPixSpace.Height() );
+ aTwipSpc =
+ Application::GetDefaultDevice()->PixelToLogic( aTwipSpc,
+ MapMode(MAP_TWIP) );
+ nLeftSpace = nRightSpace = (sal_uInt16)aTwipSpc.Width();
+ nUpperSpace = nLowerSpace = (sal_uInt16)aTwipSpc.Height();
+ }
+
+ // linken/rechten Rand setzen
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_LR_SPACE, sal_True, &pItem ) )
+ {
+ // Ggf. den Erstzeilen-Einzug noch plaetten
+ const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
+ SvxLRSpaceItem aLRItem( *pLRItem );
+ aLRItem.SetTxtFirstLineOfst( 0 );
+ if( rCSS1PropInfo.bLeftMargin )
+ {
+ nLeftSpace = static_cast< sal_uInt16 >(aLRItem.GetLeft());
+ rCSS1PropInfo.bLeftMargin = sal_False;
+ }
+ if( rCSS1PropInfo.bRightMargin )
+ {
+ nRightSpace = static_cast< sal_uInt16 >(aLRItem.GetRight());
+ rCSS1PropInfo.bRightMargin = sal_False;
+ }
+ rCSS1ItemSet.ClearItem( RES_LR_SPACE );
+ }
+ if( nLeftSpace || nRightSpace )
+ {
+ SvxLRSpaceItem aLRItem( RES_LR_SPACE );
+ aLRItem.SetLeft( nLeftSpace );
+ aLRItem.SetRight( nRightSpace );
+ aFrmSet.Put( aLRItem );
+ }
+
+ // oberen/unteren Rand setzen
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_UL_SPACE, sal_True, &pItem ) )
+ {
+ // Ggf. den Erstzeilen-Einzug noch plaetten
+ const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
+ if( rCSS1PropInfo.bTopMargin )
+ {
+ nUpperSpace = pULItem->GetUpper();
+ rCSS1PropInfo.bTopMargin = sal_False;
+ }
+ if( rCSS1PropInfo.bBottomMargin )
+ {
+ nLowerSpace = pULItem->GetLower();
+ rCSS1PropInfo.bBottomMargin = sal_False;
+ }
+
+ rCSS1ItemSet.ClearItem( RES_UL_SPACE );
+ }
+ if( nUpperSpace || nLowerSpace )
+ {
+ SvxULSpaceItem aULItem( RES_UL_SPACE );
+ aULItem.SetUpper( nUpperSpace );
+ aULItem.SetLower( nLowerSpace );
+ aFrmSet.Put( aULItem );
+ }
+
+ SwFmtAnchor aAnchor( FLY_AS_CHAR );
+ if( SVX_CSS1_POS_ABSOLUTE == rCSS1PropInfo.ePosition &&
+ SVX_CSS1_LTYPE_TWIP == rCSS1PropInfo.eLeftType &&
+ SVX_CSS1_LTYPE_TWIP == rCSS1PropInfo.eTopType )
+ {
+ 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_AT_PAGE );
+ }
+ // OD 2004-04-13 #i26791# - direct positioning for <SwDoc::Insert(..)>
+ pNewDrawObj->SetRelativePos( Point(rCSS1PropInfo.nLeft + nLeftSpace,
+ rCSS1PropInfo.nTop + nUpperSpace) );
+ aFrmSet.Put( SwFmtSurround(SURROUND_THROUGHT) );
+ }
+ else if( SVX_ADJUST_LEFT == rCSS1PropInfo.eFloat ||
+ text::HoriOrientation::LEFT == eHoriOri )
+ {
+ aAnchor.SetType( FLY_AT_PARA );
+ aFrmSet.Put( SwFmtSurround(bHidden ? SURROUND_THROUGHT
+ : SURROUND_RIGHT) );
+ // OD 2004-04-13 #i26791# - direct positioning for <SwDoc::Insert(..)>
+ pNewDrawObj->SetRelativePos( Point(nLeftSpace, nUpperSpace) );
+ }
+ else if( text::VertOrientation::NONE != eVertOri )
+ {
+ aFrmSet.Put( SwFmtVertOrient( 0, eVertOri ) );
+ }
+
+ if (FLY_AT_PAGE == aAnchor.GetAnchorId())
+ {
+ aAnchor.SetPageNum( 1 );
+ }
+ else if( FLY_AT_FLY != aAnchor.GetAnchorId() )
+ {
+ aAnchor.SetAnchor( pPam->GetPoint() );
+ }
+ aFrmSet.Put( aAnchor );
+
+ pDoc->Insert( *pPam, *pNewDrawObj, &aFrmSet, NULL );
+}
+
+/* */
+
+static void PutEEPoolItem( SfxItemSet &rEEItemSet,
+ const SfxPoolItem& rSwItem )
+{
+
+ sal_uInt16 nEEWhich = 0;
+
+ switch( rSwItem.Which() )
+ {
+ case RES_CHRATR_COLOR: nEEWhich = EE_CHAR_COLOR; break;
+ case RES_CHRATR_CROSSEDOUT: nEEWhich = EE_CHAR_STRIKEOUT; break;
+ case RES_CHRATR_ESCAPEMENT: nEEWhich = EE_CHAR_ESCAPEMENT; break;
+ case RES_CHRATR_FONT: nEEWhich = EE_CHAR_FONTINFO; break;
+ case RES_CHRATR_CJK_FONT: nEEWhich = EE_CHAR_FONTINFO_CJK; break;
+ case RES_CHRATR_CTL_FONT: nEEWhich = EE_CHAR_FONTINFO_CTL; break;
+ case RES_CHRATR_FONTSIZE: nEEWhich = EE_CHAR_FONTHEIGHT; break;
+ case RES_CHRATR_CJK_FONTSIZE: nEEWhich = EE_CHAR_FONTHEIGHT_CJK; break;
+ case RES_CHRATR_CTL_FONTSIZE: nEEWhich = EE_CHAR_FONTHEIGHT_CTL; break;
+ case RES_CHRATR_KERNING: nEEWhich = EE_CHAR_KERNING; break;
+ case RES_CHRATR_POSTURE: nEEWhich = EE_CHAR_ITALIC; break;
+ case RES_CHRATR_CJK_POSTURE: nEEWhich = EE_CHAR_ITALIC_CJK; break;
+ case RES_CHRATR_CTL_POSTURE: nEEWhich = EE_CHAR_ITALIC_CTL; break;
+ case RES_CHRATR_UNDERLINE: nEEWhich = EE_CHAR_UNDERLINE; break;
+ case RES_CHRATR_WEIGHT: nEEWhich = EE_CHAR_WEIGHT; break;
+ case RES_CHRATR_CJK_WEIGHT: nEEWhich = EE_CHAR_WEIGHT_CJK; break;
+ case RES_CHRATR_CTL_WEIGHT: nEEWhich = EE_CHAR_WEIGHT_CTL; break;
+ case RES_BACKGROUND:
+ case RES_CHRATR_BACKGROUND:
+ {
+ const SvxBrushItem& rBrushItem = (const SvxBrushItem&)rSwItem;
+ rEEItemSet.Put( XFillStyleItem(XFILL_SOLID) );
+ rEEItemSet.Put( XFillColorItem(aEmptyStr,
+ rBrushItem.GetColor()) );
+ }
+ break;
+ }
+
+ if( nEEWhich )
+ {
+ SfxPoolItem *pEEItem = rSwItem.Clone();
+ pEEItem->SetWhich( nEEWhich );
+ rEEItemSet.Put( *pEEItem );
+ delete pEEItem;
+ }
+}
+
+void SwHTMLParser::NewMarquee( HTMLTable *pCurTable )
+{
+
+ ASSERT( !pMarquee, "Marquee in Marquee???" );
+ aContents.Erase();
+
+ String aId, aStyle, aClass;
+
+ long nWidth=0, nHeight=0;
+ sal_Bool bPrcWidth = sal_False, bDirection = sal_False, bBGColor = sal_False;
+ Size aSpace( 0, 0 );
+ sal_Int16 eVertOri = text::VertOrientation::TOP;
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+ SdrTextAniKind eAniKind = SDRTEXTANI_SCROLL;
+ SdrTextAniDirection eAniDir = SDRTEXTANI_LEFT;
+ sal_uInt16 nCount = 0, nDelay = 60;
+ sal_Int16 nAmount = -6;
+ Color aBGColor;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ sal_uInt16 nArrLen = pHTMLOptions->Count();
+ for ( sal_uInt16 i=0; i<nArrLen; i++ )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+
+ case HTML_O_BEHAVIOR:
+ eAniKind =
+ (SdrTextAniKind)pOption->GetEnum( aHTMLMarqBehaviorTable,
+ static_cast< sal_uInt16 >(eAniKind) );
+ break;
+
+ case HTML_O_BGCOLOR:
+ pOption->GetColor( aBGColor );
+ bBGColor = sal_True;
+ break;
+
+ case HTML_O_DIRECTION:
+ eAniDir =
+ (SdrTextAniDirection)pOption->GetEnum( aHTMLMarqDirectionTable,
+ static_cast< sal_uInt16 >(eAniDir) );
+ bDirection = sal_True;
+ break;
+
+ case HTML_O_LOOP:
+ if( pOption->GetString().
+ EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_LOOP_infinite) )
+ {
+ nCount = 0;
+ }
+ else
+ {
+ sal_uInt32 nLoop = pOption->GetSNumber();
+ nCount = (sal_uInt16)(nLoop>0 ? nLoop : 0 );
+ }
+ break;
+
+ case HTML_O_SCROLLAMOUNT:
+ nAmount = -((sal_Int16)pOption->GetNumber());
+ break;
+
+ case HTML_O_SCROLLDELAY:
+ nDelay = (sal_uInt16)pOption->GetNumber();
+ break;
+
+ case HTML_O_WIDTH:
+ // erstmal nur als Pixelwerte merken!
+ nWidth = pOption->GetNumber();
+ bPrcWidth = pOption->GetString().Search('%') != STRING_NOTFOUND;
+ if( bPrcWidth && nWidth>100 )
+ nWidth = 100;
+ break;
+
+ case HTML_O_HEIGHT:
+ // erstmal nur als Pixelwerte merken!
+ nHeight = pOption->GetNumber();
+ if( pOption->GetString().Search('%') != STRING_NOTFOUND )
+ nHeight = 0;
+ break;
+
+ case HTML_O_HSPACE:
+ // erstmal nur als Pixelwerte merken!
+ aSpace.Height() = pOption->GetNumber();
+ break;
+
+ case HTML_O_VSPACE:
+ // erstmal nur als Pixelwerte merken!
+ aSpace.Width() = pOption->GetNumber();
+ break;
+
+ case HTML_O_ALIGN:
+ eVertOri =
+ pOption->GetEnum( aHTMLImgVAlignTable,
+ text::VertOrientation::TOP );
+ eHoriOri =
+ pOption->GetEnum( aHTMLImgHAlignTable,
+ text::HoriOrientation::NONE );
+ break;
+ }
+ }
+
+ // Ein DrawTxtobj anlegen
+ // --> OD 2005-08-08 #i52858# - method name changed
+ SdrModel* pModel = pDoc->GetOrCreateDrawModel();
+ // <--
+ SdrPage* pPg = pModel->GetPage( 0 );
+ pMarquee = SdrObjFactory::MakeNewObject( SdrInventor,
+ OBJ_TEXT, pPg, pModel );
+ if( !pMarquee )
+ return;
+
+ pPg->InsertObject( pMarquee );
+
+ if( aId.Len() )
+ InsertBookmark( aId );
+
+ // (Nur) Alternate leueft per Default von links nach rechts
+ if( SDRTEXTANI_ALTERNATE==eAniKind && !bDirection )
+ eAniDir = SDRTEXTANI_RIGHT;
+
+ // die fuer das Scrollen benoetigten Attribute umsetzen
+ sal_uInt16 aWhichMap[7] = { XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
+ EE_CHAR_START, EE_CHAR_END,
+ 0 };
+ SfxItemSet aItemSet( pModel->GetItemPool(), aWhichMap );
+ aItemSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
+ aItemSet.Put( SdrTextAutoGrowHeightItem( sal_True ) );
+ aItemSet.Put( SdrTextAniKindItem( eAniKind ) );
+ aItemSet.Put( SdrTextAniDirectionItem( eAniDir ) );
+ aItemSet.Put( SdrTextAniCountItem( nCount ) );
+ aItemSet.Put( SdrTextAniDelayItem( nDelay ) );
+ aItemSet.Put( SdrTextAniAmountItem( nAmount ) );
+ if( SDRTEXTANI_ALTERNATE==eAniKind )
+ {
+ // (Nur) Alternate startet und stoppt per default Inside
+ aItemSet.Put( SdrTextAniStartInsideItem(sal_True) );
+ aItemSet.Put( SdrTextAniStopInsideItem(sal_True) );
+ if( SDRTEXTANI_LEFT==eAniDir )
+ aItemSet.Put( SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT) );
+ }
+
+ // die Default-Farbe (aus der Standard-Vorlage) setzen, damit ueberhaupt
+ // eine sinnvolle Farbe gesetzt ist.
+ const Color& rDfltColor =
+ pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )
+ ->GetColor().GetValue();
+ aItemSet.Put( SvxColorItem( rDfltColor, EE_CHAR_COLOR ) );
+
+ // Die Attribute der aktuellen Absatzvorlage setzen
+ sal_uInt16 nWhichIds[] =
+ {
+ RES_CHRATR_COLOR, RES_CHRATR_CROSSEDOUT, RES_CHRATR_ESCAPEMENT,
+ RES_CHRATR_FONT, RES_CHRATR_FONTSIZE, RES_CHRATR_KERNING,
+ RES_CHRATR_POSTURE, RES_CHRATR_UNDERLINE, RES_CHRATR_WEIGHT,
+ RES_CHRATR_BACKGROUND,
+ RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
+ RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT,
+ RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE,
+ RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT,
+ 0
+ };
+ const SwTxtNode *pTxtNd = pDoc->GetNodes()[pPam->GetPoint()->nNode]
+ ->GetTxtNode();
+ if( pTxtNd )
+ {
+ const SfxItemSet& rItemSet = pTxtNd->GetAnyFmtColl().GetAttrSet();
+ const SfxPoolItem *pItem;
+ for( sal_uInt16 i=0; nWhichIds[i]; i++ )
+ {
+ if( SFX_ITEM_SET == rItemSet.GetItemState( nWhichIds[i], sal_True, &pItem ) )
+ PutEEPoolItem( aItemSet, *pItem );
+ }
+ }
+
+ // die Attribute der Umgebung am Draw-Objekt setzen
+ _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
+ for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
+ nCnt--; ++pTbl )
+ {
+ _HTMLAttr *pAttr = *pTbl;
+ if( pAttr )
+ PutEEPoolItem( aItemSet, pAttr->GetItem() );
+ }
+
+ if( bBGColor )
+ {
+ aItemSet.Put( XFillStyleItem(XFILL_SOLID) );
+ aItemSet.Put( XFillColorItem(aEmptyStr, aBGColor) );
+ }
+
+ // Styles parsen (funktioniert hier nur fuer Attribute, die auch
+ // am Zeichen-Objekt gesetzt werden koennen)
+ SfxItemSet aStyleItemSet( pDoc->GetAttrPool(),
+ pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) &&
+ ParseStyleOptions( aStyle, aId, aClass, aStyleItemSet, aPropInfo ) )
+ {
+ SfxItemIter aIter( aStyleItemSet );
+
+ const SfxPoolItem *pItem = aIter.FirstItem();
+ while( pItem )
+ {
+ PutEEPoolItem( aItemSet, *pItem );
+ pItem = aIter.NextItem();
+ }
+ }
+
+ // jetzt noch die Groesse setzen
+ Size aTwipSz( bPrcWidth ? 0 : nWidth, nHeight );
+ if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
+ {
+ aTwipSz = Application::GetDefaultDevice()
+ ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
+ }
+
+ if( SVX_CSS1_LTYPE_TWIP== aPropInfo.eWidthType )
+ {
+ aTwipSz.Width() = aPropInfo.nWidth;
+ nWidth = 1; // != 0;
+ bPrcWidth = sal_False;
+ }
+ if( SVX_CSS1_LTYPE_TWIP== aPropInfo.eHeightType )
+ aTwipSz.Height() = aPropInfo.nHeight;
+
+ bFixMarqueeWidth = sal_False;
+ if( !nWidth || bPrcWidth )
+ {
+ if( pTable )
+ {
+ if( !pCurTable )
+ {
+ // Die Laufschrift steht in einer Tabelle, aber nicht
+ // in einer Zelle. Da jetzt keine vernuenftige Zuordung
+ // zu einer Zelle moeglich ist, passen wir hir die
+ // Breite dem Inhalt der Laufschrift an.
+ bFixMarqueeWidth = sal_True;
+ }
+ else if( !nWidth )
+ {
+ // Da wir wissen, in welcher Zelle die Laufschrift ist,
+ // koennen wir die Breite auch anpassen. Keine Breitenangabe
+ // wird wie 100% behandelt.
+ nWidth = 100;
+ bPrcWidth = sal_True;
+ }
+ aTwipSz.Width() = MINLAY;
+ }
+ else
+ {
+ long nBrowseWidth = GetCurrentBrowseWidth();
+ aTwipSz.Width() = !nWidth ? nBrowseWidth
+ : (nWidth*nBrowseWidth) / 100;
+ }
+ }
+
+ // Die Hoehe ist nur eine Mindest-Hoehe
+ if( aTwipSz.Height() < MINFLY )
+ aTwipSz.Height() = MINFLY;
+ aItemSet.Put( SdrTextMinFrameHeightItem( aTwipSz.Height() ) );
+
+ pMarquee->SetMergedItemSetAndBroadcast(aItemSet);
+
+ if( aTwipSz.Width() < MINFLY )
+ aTwipSz.Width() = MINFLY;
+ pMarquee->SetLogicRect( Rectangle( 0, 0, aTwipSz.Width(), aTwipSz.Height() ) );
+
+ // und das Objekt in das Dok einfuegen
+ InsertDrawObject( pMarquee, aSpace, eVertOri, eHoriOri, aStyleItemSet,
+ aPropInfo );
+
+ // Das Zeichen-Objekt der Tabelle bekanntmachen. Ist ein bisserl
+ // umstaendlich, weil noch ueber den Parser gegangen wird, obwohl die
+ // Tabelle bekannt ist, aber anderenfalls muesste man die Tabelle
+ // oeffentlich machen, und das ist auch nicht schoen. Das globale
+ // pTable kann uebrigens auch nicht verwendet werden, denn die
+ // Laufschrift kann sich auch mal in einer Sub-Tabelle befinden.
+ if( pCurTable && bPrcWidth)
+ RegisterDrawObjectToTable( pCurTable, pMarquee, (sal_uInt8)nWidth );
+}
+
+void SwHTMLParser::EndMarquee()
+{
+ ASSERT( pMarquee && OBJ_TEXT==pMarquee->GetObjIdentifier(),
+ "kein Marquee oder falscher Typ" );
+
+ if( bFixMarqueeWidth )
+ {
+ // Da es keine fixe Hoehe gibt, das Text-Objekt erstmal breiter
+ // als den Text machen, damit nicht umgebrochen wird.
+ const Rectangle& rOldRect = pMarquee->GetLogicRect();
+ pMarquee->SetLogicRect( Rectangle( rOldRect.TopLeft(),
+ Size( USHRT_MAX, 240 ) ) );
+ }
+
+ // den gesammelten Text einfuegen
+ ((SdrTextObj*)pMarquee)->SetText( aContents );
+ pMarquee->SetMergedItemSetAndBroadcast( pMarquee->GetMergedItemSet() );
+
+ if( bFixMarqueeWidth )
+ {
+ // die Groesse dem Text anpassen.
+ ((SdrTextObj*)pMarquee)->FitFrameToTextSize();
+ }
+
+ aContents.Erase();
+ pMarquee = 0;
+}
+
+void SwHTMLParser::InsertMarqueeText()
+{
+ ASSERT( pMarquee && OBJ_TEXT==pMarquee->GetObjIdentifier(),
+ "kein Marquee oder falscher Typ" );
+
+ // das akteulle Textstueck an den Text anhaengen
+ aContents += aToken;
+}
+
+void SwHTMLParser::ResizeDrawObject( SdrObject* pObj, SwTwips nWidth )
+{
+ ASSERT( OBJ_TEXT==pObj->GetObjIdentifier(),
+ "kein Marquee oder falscher Typ" );
+
+ if( OBJ_TEXT!=pObj->GetObjIdentifier() )
+ return;
+
+ // die alte Groesse
+ const Rectangle& rOldRect = pObj->GetLogicRect();
+ Size aNewSz( nWidth, rOldRect.GetSize().Height() );
+ pObj->SetLogicRect( Rectangle( rOldRect.TopLeft(), aNewSz ) );
+}
+
+/* */
+
+const SdrObject *SwHTMLWriter::GetMarqueeTextObj( const SwDrawFrmFmt& rFmt )
+{
+ const SdrObject* pObj = rFmt.FindSdrObject();
+ return (pObj && ::IsMarqueeTextObj( *pObj )) ? pObj : 0;
+}
+
+void SwHTMLWriter::GetEEAttrsFromDrwObj( SfxItemSet& rItemSet,
+ const SdrObject *pObj,
+ sal_Bool bSetDefaults )
+{
+ // die Edit script::Engine-Attribute aus dem Objekt holen
+ SfxItemSet rObjItemSet = pObj->GetMergedItemSet();
+
+ // ueber die Edit script::Engine-Attribute iterieren und die Attribute
+ // in SW-Attrs wandeln bzw. default setzen
+ SfxWhichIter aIter( rObjItemSet );
+ sal_uInt16 nEEWhich = aIter.FirstWhich();
+ while( nEEWhich )
+ {
+ const SfxPoolItem *pEEItem;
+ sal_Bool bSet = SFX_ITEM_SET == rObjItemSet.GetItemState( nEEWhich, sal_False,
+ &pEEItem );
+
+ if( bSet || bSetDefaults )
+ {
+ sal_uInt16 nSwWhich = 0;
+ switch( nEEWhich )
+ {
+ case EE_CHAR_COLOR: nSwWhich = RES_CHRATR_COLOR; break;
+ case EE_CHAR_STRIKEOUT: nSwWhich = RES_CHRATR_CROSSEDOUT; break;
+ case EE_CHAR_ESCAPEMENT: nSwWhich = RES_CHRATR_ESCAPEMENT; break;
+ case EE_CHAR_FONTINFO: nSwWhich = RES_CHRATR_FONT; break;
+ case EE_CHAR_FONTINFO_CJK: nSwWhich = RES_CHRATR_CJK_FONT; break;
+ case EE_CHAR_FONTINFO_CTL: nSwWhich = RES_CHRATR_CTL_FONT; break;
+ case EE_CHAR_FONTHEIGHT: nSwWhich = RES_CHRATR_FONTSIZE; break;
+ case EE_CHAR_FONTHEIGHT_CJK:nSwWhich = RES_CHRATR_CJK_FONTSIZE; break;
+ case EE_CHAR_FONTHEIGHT_CTL:nSwWhich = RES_CHRATR_CTL_FONTSIZE; break;
+ case EE_CHAR_KERNING: nSwWhich = RES_CHRATR_KERNING; break;
+ case EE_CHAR_ITALIC: nSwWhich = RES_CHRATR_POSTURE; break;
+ case EE_CHAR_ITALIC_CJK: nSwWhich = RES_CHRATR_CJK_POSTURE; break;
+ case EE_CHAR_ITALIC_CTL: nSwWhich = RES_CHRATR_CTL_POSTURE; break;
+ case EE_CHAR_UNDERLINE: nSwWhich = RES_CHRATR_UNDERLINE; break;
+ case EE_CHAR_WEIGHT: nSwWhich = RES_CHRATR_WEIGHT; break;
+ case EE_CHAR_WEIGHT_CJK: nSwWhich = RES_CHRATR_CJK_WEIGHT; break;
+ case EE_CHAR_WEIGHT_CTL: nSwWhich = RES_CHRATR_CTL_WEIGHT; break;
+ }
+
+ if( nSwWhich )
+ {
+ // wenn das Item nicht gesetzt ist nehmen wir ggf. das
+ // Default-Item
+ if( !bSet )
+ pEEItem = &rObjItemSet.GetPool()->GetDefaultItem(nEEWhich);
+
+ // jetzt Clonen wir das Item mit der Which-Id des Writers
+ SfxPoolItem *pSwItem = pEEItem->Clone();
+ pSwItem->SetWhich( nSwWhich );
+ rItemSet.Put( *pSwItem );
+ delete pSwItem;
+ }
+ }
+
+ nEEWhich = aIter.NextWhich();
+ }
+}
+
+
+Writer& OutHTML_DrawFrmFmtAsMarquee( Writer& rWrt,
+ const SwDrawFrmFmt& rFmt,
+ const SdrObject& rSdrObject )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ ASSERT( rWrt.pDoc->GetDrawModel(), "Da gibt's ein Draw-Obj ohne ein Draw-Model zu haben?" );
+ const SdrTextObj *pTextObj = (const SdrTextObj *)&rSdrObject;
+
+ // Gibt es ueberhaupt auszugebenden Text
+ const OutlinerParaObject *pOutlinerParaObj =
+ pTextObj->GetOutlinerParaObject();
+ if( !pOutlinerParaObj )
+ return rWrt;
+
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_marquee;
+
+ // Die Attribute des Objektd holen
+ const SfxItemSet& rItemSet = pTextObj->GetMergedItemSet();
+
+ // BEHAVIOUR
+ SdrTextAniKind eAniKind = pTextObj->GetTextAniKind();
+ ASSERT( SDRTEXTANI_SCROLL==eAniKind ||
+ SDRTEXTANI_ALTERNATE==eAniKind ||
+ SDRTEXTANI_SLIDE==eAniKind,
+ "Text-Draw-Objekt nicht fuer Marquee geeignet" )
+
+ const sal_Char *pStr = 0;
+ switch( eAniKind )
+ {
+ case SDRTEXTANI_SCROLL: pStr = OOO_STRING_SVTOOLS_HTML_BEHAV_scroll; break;
+ case SDRTEXTANI_SLIDE: pStr = OOO_STRING_SVTOOLS_HTML_BEHAV_slide; break;
+ case SDRTEXTANI_ALTERNATE: pStr = OOO_STRING_SVTOOLS_HTML_BEHAV_alternate; break;
+ default:
+ ;
+ }
+
+ if( pStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_behavior) += '=') += pStr;
+
+ // DIRECTION
+ pStr = 0;
+ SdrTextAniDirection eAniDir = pTextObj->GetTextAniDirection();
+ switch( eAniDir )
+ {
+ case SDRTEXTANI_LEFT: pStr = OOO_STRING_SVTOOLS_HTML_AL_left; break;
+ case SDRTEXTANI_RIGHT: pStr = OOO_STRING_SVTOOLS_HTML_AL_right; break;
+ default:
+ ;
+ }
+
+ if( pStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_direction) += '=') += pStr;
+
+ // LOOP
+ sal_Int32 nCount =
+ ((const SdrTextAniCountItem&)rItemSet.Get( SDRATTR_TEXT_ANICOUNT ))
+ .GetValue();
+ if( 0==nCount )
+ nCount = SDRTEXTANI_SLIDE==eAniKind ? 1 : -1;
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_loop) += '=')
+ += ByteString::CreateFromInt32( nCount );
+
+ // SCROLLDELAY
+ sal_uInt16 nDelay =
+ ((const SdrTextAniDelayItem&)rItemSet.Get( SDRATTR_TEXT_ANIDELAY ))
+ .GetValue();
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_scrolldelay) += '=')
+ += ByteString::CreateFromInt32( nDelay );
+
+ // SCROLLAMOUNT
+ sal_Int16 nAmount =
+ ((const SdrTextAniAmountItem&)rItemSet.Get( SDRATTR_TEXT_ANIAMOUNT ))
+ .GetValue();
+ if( nAmount < 0 )
+ {
+ nAmount = -nAmount;
+ }
+ else if( nAmount && Application::GetDefaultDevice() )
+ {
+ nAmount = (sal_uInt16)(Application::GetDefaultDevice()
+ ->LogicToPixel( Size(nAmount,0),
+ MapMode(MAP_TWIP) ).Width());
+ }
+ if( nAmount )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_scrollamount) += '=')
+ += ByteString::CreateFromInt32( nAmount );
+
+ Size aTwipSz( pTextObj->GetLogicRect().GetSize() );
+ if( pTextObj->IsAutoGrowWidth() )
+ aTwipSz.Width() = 0;
+ // Die Hoehe ist bei MS eine Mindesthoehe, also geben wir auch die
+ // Mindestheoehe aus, wenn es sie gibt. Da eine Mindesthoehe MINFLY
+ // mit hoher Wahrscheinlichkeit vom Import kommt, wird sie nicht mit
+ // ausgegeben. Falsch machen kann man da nichst, denn jeder Font ist
+ // hoeher.
+ if( pTextObj->IsAutoGrowHeight() )
+ {
+ aTwipSz.Height() = pTextObj->GetMinTextFrameHeight();
+ if( MINFLY==aTwipSz.Height() )
+ aTwipSz.Height() = 0;
+ }
+
+ if( (aTwipSz.Width() || aTwipSz.Height()) &&
+ Application::GetDefaultDevice() )
+ {
+ Size aPixelSz =
+ Application::GetDefaultDevice()->LogicToPixel( aTwipSz,
+ MapMode(MAP_TWIP) );
+ if( !aPixelSz.Width() && aTwipSz.Width() )
+ aPixelSz.Width() = 1;
+ if( !aPixelSz.Height() && aTwipSz.Height() )
+ aPixelSz.Height() = 1;
+
+ if( aPixelSz.Width() )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=')
+ += ByteString::CreateFromInt32( aPixelSz.Width() );
+
+ if( aPixelSz.Height() )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
+ += ByteString::CreateFromInt32( aPixelSz.Height() );
+ }
+
+ // BGCOLOR
+ XFillStyle eFillStyle =
+ ((const XFillStyleItem&)rItemSet.Get(XATTR_FILLSTYLE)).GetValue();
+ if( XFILL_SOLID==eFillStyle )
+ {
+ const Color& rFillColor =
+ ((const XFillColorItem&)rItemSet.Get(XATTR_FILLCOLOR)).GetColorValue();
+
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_bgcolor) += '=';
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_Color( rWrt.Strm(), rFillColor, rHTMLWrt.eDestEnc );
+ sOut.Erase();
+ }
+
+ if( sOut.Len() )
+ rWrt.Strm() << sOut.GetBuffer();
+
+ // und nun noch ALIGN, HSPACE und VSPACE
+ ByteString aEndTags;
+ sal_uInt32 nFrmFlags = HTML_FRMOPTS_MARQUEE;
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_DRAW ) )
+ nFrmFlags |= HTML_FRMOPTS_MARQUEE_CSS1;
+ rHTMLWrt.OutFrmFmtOptions( rFmt, aEmptyStr, aEndTags, nFrmFlags );
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_DRAW ) )
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFmt, nFrmFlags, &rSdrObject );
+
+
+ rWrt.Strm() << '>';
+
+ // Was jetzt kommt ist das Gegenstueck zu SdrTextObjectt::SetText()
+ Outliner aOutliner(0, OUTLINERMODE_TEXTOBJECT);
+ aOutliner.SetUpdateMode( sal_False );
+ aOutliner.SetText( *pOutlinerParaObj );
+ String aText( aOutliner.GetText( aOutliner.GetParagraph(0),
+ aOutliner.GetParagraphCount() ) );
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aText,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_marquee, sal_False );
+
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ return rWrt;
+}
+
+
diff --git a/sw/source/filter/html/htmlfld.cxx b/sw/source/filter/html/htmlfld.cxx
new file mode 100644
index 000000000000..28fd4124bf05
--- /dev/null
+++ b/sw/source/filter/html/htmlfld.cxx
@@ -0,0 +1,670 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+#include "docsh.hxx"
+#include <svtools/htmltokn.h>
+#include <svl/zformat.hxx>
+#include <unotools/useroptions.hxx>
+#include <fmtfld.hxx>
+#include <ndtxt.hxx>
+#include <doc.hxx>
+#include <fldbas.hxx>
+#include <docufld.hxx>
+#include <flddat.hxx>
+#include <htmlfld.hxx>
+#include <swhtml.hxx>
+
+using namespace nsSwDocInfoSubType;
+using namespace ::com::sun::star;
+
+struct HTMLNumFmtTblEntry
+{
+ const sal_Char *pName;
+ NfIndexTableOffset eFmt;
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLFldTypeTable[] =
+{
+ { OOO_STRING_SW_HTML_FT_author, RES_AUTHORFLD },
+ { OOO_STRING_SW_HTML_FT_sender, RES_EXTUSERFLD },
+ { "DATE", RES_DATEFLD },
+ { "TIME", RES_TIMEFLD },
+ { OOO_STRING_SW_HTML_FT_datetime,RES_DATETIMEFLD },
+ { OOO_STRING_SW_HTML_FT_page, RES_PAGENUMBERFLD },
+ { OOO_STRING_SW_HTML_FT_docinfo, RES_DOCINFOFLD },
+ { OOO_STRING_SW_HTML_FT_docstat, RES_DOCSTATFLD },
+ { OOO_STRING_SW_HTML_FT_filename,RES_FILENAMEFLD },
+ { 0, 0 }
+};
+
+static HTMLNumFmtTblEntry __FAR_DATA aHTMLDateFldFmtTable[] =
+{
+ { "SSYS", NF_DATE_SYSTEM_SHORT },
+ { "LSYS", NF_DATE_SYSTEM_LONG },
+ { "DMY", NF_DATE_SYS_DDMMYY, },
+ { "DMYY", NF_DATE_SYS_DDMMYYYY, },
+ { "DMMY", NF_DATE_SYS_DMMMYY, },
+ { "DMMYY", NF_DATE_SYS_DMMMYYYY, },
+ { "DMMMY", NF_DATE_DIN_DMMMMYYYY },
+ { "DMMMYY", NF_DATE_DIN_DMMMMYYYY },
+ { "DDMMY", NF_DATE_SYS_NNDMMMYY },
+ { "DDMMMY", NF_DATE_SYS_NNDMMMMYYYY },
+ { "DDMMMYY", NF_DATE_SYS_NNDMMMMYYYY },
+ { "DDDMMMY", NF_DATE_SYS_NNNNDMMMMYYYY },
+ { "DDDMMMYY", NF_DATE_SYS_NNNNDMMMMYYYY },
+ { "MY", NF_DATE_SYS_MMYY },
+ { "MD", NF_DATE_DIN_MMDD },
+ { "YMD", NF_DATE_DIN_YYMMDD },
+ { "YYMD", NF_DATE_DIN_YYYYMMDD },
+ { 0, NF_NUMERIC_START }
+};
+
+static HTMLNumFmtTblEntry __FAR_DATA aHTMLTimeFldFmtTable[] =
+{
+ { "SYS", NF_TIME_HHMMSS },
+ { "SSMM24", NF_TIME_HHMM },
+ { "SSMM12", NF_TIME_HHMMAMPM },
+ { 0, NF_NUMERIC_START }
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLPageNumFldFmtTable[] =
+{
+ { OOO_STRING_SW_HTML_FF_uletter, SVX_NUM_CHARS_UPPER_LETTER },
+ { OOO_STRING_SW_HTML_FF_lletter, SVX_NUM_CHARS_LOWER_LETTER },
+ { OOO_STRING_SW_HTML_FF_uroman, SVX_NUM_ROMAN_UPPER },
+ { OOO_STRING_SW_HTML_FF_lroman, SVX_NUM_ROMAN_LOWER },
+ { OOO_STRING_SW_HTML_FF_arabic, SVX_NUM_ARABIC },
+ { OOO_STRING_SW_HTML_FF_none, SVX_NUM_NUMBER_NONE },
+ { OOO_STRING_SW_HTML_FF_char, SVX_NUM_CHAR_SPECIAL },
+ { OOO_STRING_SW_HTML_FF_page, SVX_NUM_PAGEDESC },
+ { OOO_STRING_SW_HTML_FF_ulettern, SVX_NUM_CHARS_UPPER_LETTER_N },
+ { OOO_STRING_SW_HTML_FF_llettern, SVX_NUM_CHARS_LOWER_LETTER_N },
+ { 0, 0 }
+};
+
+
+static HTMLOptionEnum __FAR_DATA aHTMLExtUsrFldSubTable[] =
+{
+ { OOO_STRING_SW_HTML_FS_company, EU_COMPANY },
+ { OOO_STRING_SW_HTML_FS_firstname, EU_FIRSTNAME },
+ { OOO_STRING_SW_HTML_FS_name, EU_NAME },
+ { OOO_STRING_SW_HTML_FS_shortcut, EU_SHORTCUT },
+ { OOO_STRING_SW_HTML_FS_street, EU_STREET },
+ { OOO_STRING_SW_HTML_FS_country, EU_COUNTRY },
+ { OOO_STRING_SW_HTML_FS_zip, EU_ZIP },
+ { OOO_STRING_SW_HTML_FS_city, EU_CITY },
+ { OOO_STRING_SW_HTML_FS_title, EU_TITLE },
+ { OOO_STRING_SW_HTML_FS_position, EU_POSITION },
+ { OOO_STRING_SW_HTML_FS_pphone, EU_PHONE_PRIVATE },
+ { OOO_STRING_SW_HTML_FS_cphone, EU_PHONE_COMPANY },
+ { OOO_STRING_SW_HTML_FS_fax, EU_FAX },
+ { OOO_STRING_SW_HTML_FS_email, EU_EMAIL },
+ { OOO_STRING_SW_HTML_FS_state, EU_STATE },
+ { 0, 0 }
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLAuthorFldFmtTable[] =
+{
+ { OOO_STRING_SW_HTML_FF_name, AF_NAME },
+ { OOO_STRING_SW_HTML_FF_shortcut, AF_SHORTCUT },
+ { 0, 0 }
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLPageNumFldSubTable[] =
+{
+ { OOO_STRING_SW_HTML_FS_random, PG_RANDOM },
+ { OOO_STRING_SW_HTML_FS_next, PG_NEXT },
+ { OOO_STRING_SW_HTML_FS_prev, PG_PREV },
+ { 0, 0 }
+};
+
+// UGLY: these are extensions of nsSwDocInfoSubType (in inc/docufld.hxx)
+// these are necessary for importing document info fields written by
+// older versions of OOo (< 3.0) which did not have DI_CUSTOM fields
+ const SwDocInfoSubType DI_INFO1 = DI_SUBTYPE_END + 1;
+ const SwDocInfoSubType DI_INFO2 = DI_SUBTYPE_END + 2;
+ const SwDocInfoSubType DI_INFO3 = DI_SUBTYPE_END + 3;
+ const SwDocInfoSubType DI_INFO4 = DI_SUBTYPE_END + 4;
+
+static HTMLOptionEnum __FAR_DATA aHTMLDocInfoFldSubTable[] =
+{
+ { OOO_STRING_SW_HTML_FS_title, DI_TITEL },
+ { OOO_STRING_SW_HTML_FS_theme, DI_THEMA },
+ { OOO_STRING_SW_HTML_FS_keys, DI_KEYS },
+ { OOO_STRING_SW_HTML_FS_comment, DI_COMMENT },
+ { "INFO1", DI_INFO1 },
+ { "INFO2", DI_INFO2 },
+ { "INFO3", DI_INFO3 },
+ { "INFO4", DI_INFO4 },
+ { OOO_STRING_SW_HTML_FS_custom, DI_CUSTOM },
+ { OOO_STRING_SW_HTML_FS_create, DI_CREATE },
+ { OOO_STRING_SW_HTML_FS_change, DI_CHANGE },
+ { 0, 0 }
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLDocInfoFldFmtTable[] =
+{
+ { OOO_STRING_SW_HTML_FF_author, DI_SUB_AUTHOR },
+ { OOO_STRING_SW_HTML_FF_time, DI_SUB_TIME },
+ { OOO_STRING_SW_HTML_FF_date, DI_SUB_DATE },
+ { 0, 0 }
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLDocStatFldSubTable[] =
+{
+ { OOO_STRING_SW_HTML_FS_page, DS_PAGE },
+ { OOO_STRING_SW_HTML_FS_para, DS_PARA },
+ { OOO_STRING_SW_HTML_FS_word, DS_WORD },
+ { OOO_STRING_SW_HTML_FS_char, DS_CHAR },
+ { OOO_STRING_SW_HTML_FS_tbl, DS_TBL },
+ { OOO_STRING_SW_HTML_FS_grf, DS_GRF },
+ { OOO_STRING_SW_HTML_FS_ole, DS_OLE },
+ { 0, 0 }
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLFileNameFldFmtTable[] =
+{
+ { OOO_STRING_SW_HTML_FF_name, FF_NAME },
+ { OOO_STRING_SW_HTML_FF_pathname, FF_PATHNAME },
+ { OOO_STRING_SW_HTML_FF_path, FF_PATH },
+ { OOO_STRING_SW_HTML_FF_name_noext, FF_NAME_NOEXT },
+ { 0, 0 }
+};
+
+/* */
+
+USHORT SwHTMLParser::GetNumType( const String& rStr, USHORT nDfltType )
+{
+ USHORT nType = nDfltType;
+ const HTMLOptionEnum *pOptEnums = aHTMLPageNumFldFmtTable;
+ while( pOptEnums->pName )
+ if( !rStr.EqualsIgnoreCaseAscii( pOptEnums->pName ) )
+ pOptEnums++;
+ else
+ break;
+
+ if( pOptEnums->pName )
+ nType = pOptEnums->nValue;
+
+ return nType;
+}
+
+
+void SwHTMLParser::NewField()
+{
+ BOOL bKnownType = FALSE, bFixed = FALSE,
+ bHasNumFmt = FALSE, bHasNumValue = FALSE;
+ USHORT nType = 0;
+ String aValue, aNumFmt, aNumValue, aName;
+ const HTMLOption *pSubOption=0, *pFmtOption=0;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ USHORT i;
+
+ for( i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_TYPE:
+ bKnownType = pOption->GetEnum( nType, aHTMLFldTypeTable );
+ break;
+ case HTML_O_SUBTYPE:
+ pSubOption = pOption;
+ break;
+ case HTML_O_FORMAT:
+ pFmtOption = pOption;
+ break;
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ break;
+ case HTML_O_VALUE:
+ aValue = pOption->GetString();
+ break;
+ case HTML_O_SDNUM:
+ aNumFmt = pOption->GetString();
+ bHasNumFmt = TRUE;
+ break;
+ case HTML_O_SDVAL:
+ aNumValue = pOption->GetString();
+ bHasNumValue = TRUE;
+ break;
+ case HTML_O_SDFIXED:
+ bFixed = TRUE;
+ break;
+ }
+ }
+
+ if( !bKnownType )
+ return;
+
+ // Autor und Absender werden nur als als variables Feld eingefuegt,
+ // wenn man das Dok selbst als letztes geaendert hat oder es noch
+ // niemend geandert hat und man das Dok erstellt hat. Sonst
+ // wird ein Fixed-Feld daraus gemacht.
+ if( !bFixed &&
+ (RES_EXTUSERFLD == (RES_FIELDS)nType ||
+ RES_AUTHORFLD == (RES_FIELDS)nType) )
+ {
+ SvtUserOptions aOpt;
+ const String& rUser = aOpt.GetFullName();
+ SwDocShell *pDocShell(pDoc->GetDocShell());
+ DBG_ASSERT(pDocShell, "no SwDocShell");
+ if (pDocShell) {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xDPS->getDocumentProperties());
+ DBG_ASSERT(xDocProps.is(), "Doc has no DocumentProperties");
+ const String& rChanged = xDocProps->getModifiedBy();
+ const String& rCreated = xDocProps->getAuthor();
+ if( !rUser.Len() ||
+ (rChanged.Len() ? rUser != rChanged : rUser != rCreated) )
+ bFixed = TRUE;
+ }
+ }
+
+ USHORT nWhich = nType;
+ if( RES_DATEFLD==nType || RES_TIMEFLD==nType )
+ nWhich = RES_DATETIMEFLD;
+
+ SwFieldType* pType = pDoc->GetSysFldType( nWhich );
+ SwField *pFld = 0;
+ BOOL bInsOnEndTag = FALSE;
+
+ switch( (RES_FIELDS)nType )
+ {
+ case RES_EXTUSERFLD:
+ if( pSubOption )
+ {
+ USHORT nSub;
+ ULONG nFmt = 0;
+ if( bFixed )
+ {
+ nFmt |= AF_FIXED;
+ bInsOnEndTag = TRUE;
+ }
+ if( pSubOption->GetEnum( nSub, aHTMLExtUsrFldSubTable ) )
+ pFld = new SwExtUserField( (SwExtUserFieldType*)pType,
+ nSub, nFmt );
+ }
+ break;
+
+ case RES_AUTHORFLD:
+ {
+ USHORT nFmt = AF_NAME;
+ if( pFmtOption )
+ pFmtOption->GetEnum( nFmt, aHTMLAuthorFldFmtTable );
+ if( bFixed )
+ {
+ nFmt |= AF_FIXED;
+ bInsOnEndTag = TRUE;
+ }
+
+ pFld = new SwAuthorField( (SwAuthorFieldType *)pType, nFmt );
+ }
+ break;
+
+ case RES_DATEFLD:
+ case RES_TIMEFLD:
+ {
+ ULONG nNumFmt = 0;
+ ULONG nTime = Time().GetTime(), nDate = Date().GetDate();
+ USHORT nSub = 0;
+ BOOL bValidFmt = FALSE;
+ HTMLNumFmtTblEntry * pFmtTbl;
+
+ if( RES_DATEFLD==nType )
+ {
+ nSub = DATEFLD;
+ pFmtTbl = aHTMLDateFldFmtTable;
+ if( aValue.Len() )
+ nDate = (ULONG)aValue.ToInt32();
+ }
+ else
+ {
+ nSub = TIMEFLD;
+ pFmtTbl = aHTMLTimeFldFmtTable;
+ if( aValue.Len() )
+ nTime = (ULONG)aValue.ToInt32();
+ }
+ if( aValue.Len() )
+ nSub |= FIXEDFLD;
+
+ SvNumberFormatter *pFormatter = pDoc->GetNumberFormatter();
+ if( pFmtOption )
+ {
+ const String& rFmt = pFmtOption->GetString();
+ for( USHORT k = 0; pFmtTbl[k].pName; k++ )
+ {
+ if( rFmt.EqualsIgnoreCaseAscii( pFmtTbl[k].pName ) )
+ {
+ nNumFmt = pFormatter->GetFormatIndex(
+ pFmtTbl[k].eFmt, LANGUAGE_SYSTEM);
+ bValidFmt = TRUE;
+ break;
+ }
+ }
+ }
+ if( !bValidFmt )
+ nNumFmt = pFormatter->GetFormatIndex( pFmtTbl[i].eFmt,
+ LANGUAGE_SYSTEM);
+
+ pFld = new SwDateTimeField( (SwDateTimeFieldType *)pType,
+ nSub, nNumFmt );
+
+ if (nSub & FIXEDFLD)
+ ((SwDateTimeField *)pFld)->SetDateTime( DateTime(Date(nDate), Time(nTime)) );
+ }
+ break;
+
+ case RES_DATETIMEFLD:
+ if( bHasNumFmt )
+ {
+ USHORT nSub = 0;
+
+ SvNumberFormatter *pFormatter = pDoc->GetNumberFormatter();
+ sal_uInt32 nNumFmt;
+ LanguageType eLang;
+ double dValue = GetTableDataOptionsValNum(
+ nNumFmt, eLang, aNumValue, aNumFmt,
+ *pDoc->GetNumberFormatter() );
+ short nFmtType = pFormatter->GetType( nNumFmt );
+ switch( nFmtType )
+ {
+ case NUMBERFORMAT_DATE: nSub = DATEFLD; break;
+ case NUMBERFORMAT_TIME: nSub = TIMEFLD; break;
+ }
+
+ if( nSub )
+ {
+ if( bHasNumValue )
+ nSub |= FIXEDFLD;
+
+ pFld = new SwDateTimeField( (SwDateTimeFieldType *)pType,
+ nSub, nNumFmt );
+ if( bHasNumValue )
+ ((SwDateTimeField *)pFld)->SetValue( dValue );
+ }
+ }
+ break;
+
+ case RES_PAGENUMBERFLD:
+ if( pSubOption )
+ {
+ USHORT nSub;
+ if( pSubOption->GetEnum( nSub, aHTMLPageNumFldSubTable ) )
+ {
+ USHORT nFmt = SVX_NUM_PAGEDESC;
+ if( pFmtOption )
+ pFmtOption->GetEnum( nFmt, aHTMLPageNumFldFmtTable );
+
+ short nOff = 0;
+
+ if( (SvxExtNumType)nFmt!=SVX_NUM_CHAR_SPECIAL && aValue.Len() )
+ nOff = (short)aValue.ToInt32();
+ else if( (SwPageNumSubType)nSub == PG_NEXT )
+ nOff = 1;
+ else if( (SwPageNumSubType)nSub == PG_PREV )
+ nOff = -1;
+
+ if( (SvxExtNumType)nFmt==SVX_NUM_CHAR_SPECIAL &&
+ (SwPageNumSubType)nSub==PG_RANDOM )
+ nFmt = SVX_NUM_PAGEDESC;
+
+ pFld = new SwPageNumberField( (SwPageNumberFieldType *)pType, nSub, nFmt, nOff );
+ if( (SvxExtNumType)nFmt==SVX_NUM_CHAR_SPECIAL )
+ ((SwPageNumberField *)pFld)->SetUserString( aValue );
+ }
+ }
+ break;
+
+ case RES_DOCINFOFLD:
+ if( pSubOption )
+ {
+ USHORT nSub;
+ if( pSubOption->GetEnum( nSub, aHTMLDocInfoFldSubTable ) )
+ {
+ USHORT nExtSub = 0;
+ if( DI_CREATE==(SwDocInfoSubType)nSub ||
+ DI_CHANGE==(SwDocInfoSubType)nSub )
+ {
+ nExtSub = DI_SUB_AUTHOR;
+ if( pFmtOption )
+ pFmtOption->GetEnum( nExtSub, aHTMLDocInfoFldFmtTable );
+ nSub |= nExtSub;
+ }
+
+ sal_uInt32 nNumFmt = 0;
+ double dValue = 0;
+ if( bHasNumFmt && (DI_SUB_DATE==nExtSub || DI_SUB_TIME==nExtSub) )
+ {
+ LanguageType eLang;
+ dValue = GetTableDataOptionsValNum(
+ nNumFmt, eLang, aNumValue, aNumFmt,
+ *pDoc->GetNumberFormatter() );
+ bFixed &= bHasNumValue;
+ }
+ else
+ bHasNumValue = FALSE;
+
+ if( nSub >= DI_INFO1 && nSub <= DI_INFO4 && aName.Len() == 0 )
+ {
+ // backward compatibility for OOo 2:
+ // map to names stored in AddMetaUserDefined
+ aName = m_InfoNames[nSub - DI_INFO1];
+ nSub = DI_CUSTOM;
+ }
+
+ if( bFixed )
+ {
+ nSub |= DI_SUB_FIXED;
+ bInsOnEndTag = TRUE;
+ }
+
+ pFld = new SwDocInfoField( (SwDocInfoFieldType *)pType,
+ nSub, aName, nNumFmt );
+ if( bHasNumValue )
+ ((SwDocInfoField*)pFld)->SetValue( dValue );
+ }
+ }
+ break;
+
+ case RES_DOCSTATFLD:
+ if( pSubOption )
+ {
+ USHORT nSub;
+ if( pSubOption->GetEnum( nSub, aHTMLDocStatFldSubTable ) )
+ {
+ USHORT nFmt = SVX_NUM_ARABIC;
+ if( pFmtOption )
+ pFmtOption->GetEnum( nFmt, aHTMLPageNumFldFmtTable );
+ pFld = new SwDocStatField( (SwDocStatFieldType *)pType,
+ nSub, nFmt );
+ bUpdateDocStat |= (DS_PAGE != nFmt);
+ }
+ }
+ break;
+
+ case RES_FILENAMEFLD:
+ {
+ USHORT nFmt = FF_NAME;
+ if( pFmtOption )
+ pFmtOption->GetEnum( nFmt, aHTMLFileNameFldFmtTable );
+ if( bFixed )
+ {
+ nFmt |= FF_FIXED;
+ bInsOnEndTag = TRUE;
+ }
+
+ pFld = new SwFileNameField( (SwFileNameFieldType *)pType, nFmt );
+ }
+ break;
+ default:
+ ;
+ }
+
+ if( pFld )
+ {
+ if( bInsOnEndTag )
+ {
+ pField = pFld;
+ }
+ else
+ {
+ pDoc->InsertPoolItem( *pPam, SwFmtFld(*pFld), 0 );
+ delete pFld;
+ }
+ bInField = TRUE;
+ }
+}
+
+void SwHTMLParser::EndField()
+{
+ if( pField )
+ {
+ switch( pField->Which() )
+ {
+ case RES_DOCINFOFLD:
+ ASSERT( ((SwDocInfoField*)pField)->IsFixed(),
+ "DokInfo-Feld haette nicht gemerkt werden muessen" );
+ ((SwDocInfoField*)pField)->SetExpansion( aContents );
+ break;
+
+ case RES_EXTUSERFLD:
+ ASSERT( ((SwExtUserField*)pField)->IsFixed(),
+ "ExtUser-Feld haette nicht gemerkt werden muessen" );
+ ((SwExtUserField*)pField)->SetExpansion( aContents );
+ break;
+
+ case RES_AUTHORFLD:
+ ASSERT( ((SwAuthorField*)pField)->IsFixed(),
+ "Author-Feld haette nicht gemerkt werden muessen" );
+ ((SwAuthorField*)pField)->SetExpansion( aContents );
+ break;
+
+ case RES_FILENAMEFLD:
+ ASSERT( ((SwFileNameField*)pField)->IsFixed(),
+ "FileName-Feld haette nicht gemerkt werden muessen" );
+ ((SwFileNameField*)pField)->SetExpansion( aContents );
+ break;
+ }
+
+ pDoc->InsertPoolItem( *pPam, SwFmtFld(*pField), 0 );
+ delete pField;
+ pField = 0;
+ }
+
+ bInField = FALSE;
+ aContents.Erase();
+}
+
+void SwHTMLParser::InsertFieldText()
+{
+ if( pField )
+ {
+ // das aktuelle Textstueck an den Text anhaengen
+ aContents += aToken;
+ }
+}
+
+void SwHTMLParser::InsertCommentText( const sal_Char *pTag )
+{
+ BOOL bEmpty = aContents.Len() == 0;
+ if( !bEmpty )
+ aContents += '\n';
+
+ aContents += aToken;
+ if( bEmpty && pTag )
+ {
+ String aTmp( aContents );
+ aContents.AssignAscii( "HTML: <" );
+ aContents.AppendAscii( pTag );
+ aContents.Append( '>' );
+ aContents.Append( aTmp );
+ }
+}
+
+void SwHTMLParser::InsertComment( const String& rComment, const sal_Char *pTag )
+{
+ String aComment( rComment );
+ if( pTag )
+ {
+ aComment.AppendAscii( "</" );
+ aComment.AppendAscii( pTag );
+ aComment.Append( '>' );
+ }
+
+ // MIB 24.06.97: Wenn ein PostIt nach einen Space eingefuegt
+ // werden soll, fuegen wir es vor dem Space ein. Dann gibt es
+ // weniger Probleme beim Formatieren (bug #40483#)
+ xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
+ SwTxtNode *pTxtNd = pPam->GetNode()->GetTxtNode();
+ BOOL bMoveFwd = FALSE;
+ if( nPos>0 && pTxtNd && ' '==pTxtNd->GetTxt().GetChar(nPos-1) )
+ {
+ bMoveFwd = TRUE;
+
+ ULONG nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
+ xub_StrLen nIdx = pPam->GetPoint()->nContent.GetIndex();
+ for( USHORT i = aSetAttrTab.Count(); i > 0; )
+ {
+ _HTMLAttr *pAttr = aSetAttrTab[--i];
+ if( pAttr->GetSttParaIdx() != nNodeIdx ||
+ pAttr->GetSttCnt() != nIdx )
+ break;
+
+ if( RES_TXTATR_FIELD == pAttr->pItem->Which() &&
+ RES_SCRIPTFLD == ((const SwFmtFld *)pAttr->pItem)->GetFld()
+ ->GetTyp()->Which() )
+ {
+ bMoveFwd = FALSE;
+ break;
+ }
+ }
+
+ if( bMoveFwd )
+ pPam->Move( fnMoveBackward );
+ }
+
+ SwPostItField aPostItFld(
+ (SwPostItFieldType*)pDoc->GetSysFldType( RES_POSTITFLD ),
+ aEmptyStr, aComment, DateTime() );
+ InsertAttr( SwFmtFld( aPostItFld ) );
+
+ if( bMoveFwd )
+ pPam->Move( fnMoveForward );
+}
+
diff --git a/sw/source/filter/html/htmlfld.hxx b/sw/source/filter/html/htmlfld.hxx
new file mode 100644
index 000000000000..2ba89a9af6de
--- /dev/null
+++ b/sw/source/filter/html/htmlfld.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _HTMLFLD_HXX
+#define _HTMLFLD_HXX
+
+#include "sal/config.h"
+
+#define OOO_STRING_SW_HTML_FT_author "AUTHOR"
+#define OOO_STRING_SW_HTML_FT_sender "SENDER"
+#define OOO_STRING_SW_HTML_FT_datetime "DATETIME"
+#define OOO_STRING_SW_HTML_FT_page "PAGE"
+#define OOO_STRING_SW_HTML_FT_docinfo "DOCINFO"
+#define OOO_STRING_SW_HTML_FT_docstat "DOCSTAT"
+#define OOO_STRING_SW_HTML_FT_filename "FILENAME"
+#define OOO_STRING_SW_HTML_FS_company "COMPANY"
+#define OOO_STRING_SW_HTML_FS_firstname "FIRSTNAME"
+#define OOO_STRING_SW_HTML_FS_name "NAME"
+#define OOO_STRING_SW_HTML_FS_shortcut "SHORTCUT"
+#define OOO_STRING_SW_HTML_FS_street "STREET"
+#define OOO_STRING_SW_HTML_FS_country "COUNTRY"
+#define OOO_STRING_SW_HTML_FS_zip "ZIP"
+#define OOO_STRING_SW_HTML_FS_city "CITY"
+#define OOO_STRING_SW_HTML_FS_title "TITLE"
+#define OOO_STRING_SW_HTML_FS_position "POSITION"
+#define OOO_STRING_SW_HTML_FS_pphone "PPHONE"
+#define OOO_STRING_SW_HTML_FS_cphone "CPHONE"
+#define OOO_STRING_SW_HTML_FS_fax "FAX"
+#define OOO_STRING_SW_HTML_FS_email "EMAIL"
+#define OOO_STRING_SW_HTML_FS_state "STATE"
+#define OOO_STRING_SW_HTML_FS_random "RANDOM"
+#define OOO_STRING_SW_HTML_FS_next "NEXT"
+#define OOO_STRING_SW_HTML_FS_prev "PREV"
+#define OOO_STRING_SW_HTML_FS_theme "THEME"
+#define OOO_STRING_SW_HTML_FS_keys "KEYS"
+#define OOO_STRING_SW_HTML_FS_comment "COMMENT"
+#define OOO_STRING_SW_HTML_FS_custom "CUSTOM"
+#define OOO_STRING_SW_HTML_FS_create "CREATE"
+#define OOO_STRING_SW_HTML_FS_change "CHANGE"
+#define OOO_STRING_SW_HTML_FS_page "PAGE"
+#define OOO_STRING_SW_HTML_FS_para "PARAGRAPH"
+#define OOO_STRING_SW_HTML_FS_word "WORD"
+#define OOO_STRING_SW_HTML_FS_char "CHAR"
+#define OOO_STRING_SW_HTML_FS_tbl "TABLE"
+#define OOO_STRING_SW_HTML_FS_grf "GRAPHIC"
+#define OOO_STRING_SW_HTML_FS_ole "OLE"
+#define OOO_STRING_SW_HTML_FF_name "NAME"
+#define OOO_STRING_SW_HTML_FF_shortcut "SHORTCUT"
+#define OOO_STRING_SW_HTML_FF_uletter "ULETTER"
+#define OOO_STRING_SW_HTML_FF_lletter "LLETTER"
+#define OOO_STRING_SW_HTML_FF_uroman "UROMAN"
+#define OOO_STRING_SW_HTML_FF_lroman "LROMAN"
+#define OOO_STRING_SW_HTML_FF_arabic "ARABIC"
+#define OOO_STRING_SW_HTML_FF_none "NONE"
+#define OOO_STRING_SW_HTML_FF_char "CHAR"
+#define OOO_STRING_SW_HTML_FF_page "PAGE"
+#define OOO_STRING_SW_HTML_FF_ulettern "ULETTERN"
+#define OOO_STRING_SW_HTML_FF_llettern "LLETTERN"
+#define OOO_STRING_SW_HTML_FF_author "AUTHOR"
+#define OOO_STRING_SW_HTML_FF_time "TIME"
+#define OOO_STRING_SW_HTML_FF_date "DATE"
+#define OOO_STRING_SW_HTML_FF_pathname "PATHNAME"
+#define OOO_STRING_SW_HTML_FF_path "PATH"
+#define OOO_STRING_SW_HTML_FF_name_noext "NAME-NOEXT"
+
+#endif
+
+
diff --git a/sw/source/filter/html/htmlfldw.cxx b/sw/source/filter/html/htmlfldw.cxx
new file mode 100644
index 000000000000..50b7bdc7ddc8
--- /dev/null
+++ b/sw/source/filter/html/htmlfldw.cxx
@@ -0,0 +1,539 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <com/sun/star/i18n/ScriptType.hpp>
+#include <tools/string.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/htmltokn.h>
+#include <fmtfld.hxx>
+#include <doc.hxx>
+#include <breakit.hxx>
+#include <ndtxt.hxx>
+#include <txtfld.hxx>
+#include "fldbas.hxx"
+#include "docufld.hxx"
+#include "flddat.hxx"
+#include "htmlfld.hxx"
+#include "wrthtml.hxx"
+
+using namespace nsSwDocInfoSubType;
+
+const sal_Char *SwHTMLWriter::GetNumFormat( USHORT nFmt )
+{
+ const sal_Char *pFmtStr = 0;
+
+ switch( (SvxExtNumType)nFmt )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER: pFmtStr = OOO_STRING_SW_HTML_FF_uletter; break;
+ case SVX_NUM_CHARS_LOWER_LETTER: pFmtStr = OOO_STRING_SW_HTML_FF_lletter; break;
+ case SVX_NUM_ROMAN_UPPER: pFmtStr = OOO_STRING_SW_HTML_FF_uroman; break;
+ case SVX_NUM_ROMAN_LOWER: pFmtStr = OOO_STRING_SW_HTML_FF_lroman; break;
+ case SVX_NUM_ARABIC: pFmtStr = OOO_STRING_SW_HTML_FF_arabic; break;
+ case SVX_NUM_NUMBER_NONE: pFmtStr = OOO_STRING_SW_HTML_FF_none; break;
+ case SVX_NUM_CHAR_SPECIAL: pFmtStr = OOO_STRING_SW_HTML_FF_char; break;
+ case SVX_NUM_PAGEDESC: pFmtStr = OOO_STRING_SW_HTML_FF_page; break;
+ case SVX_NUM_CHARS_UPPER_LETTER_N: pFmtStr = OOO_STRING_SW_HTML_FF_ulettern; break;
+ case SVX_NUM_CHARS_LOWER_LETTER_N: pFmtStr = OOO_STRING_SW_HTML_FF_llettern; break;
+ default:
+ ;
+ }
+
+ return pFmtStr;
+}
+
+extern BOOL lcl_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 );
+static Writer& OutHTML_SwField( Writer& rWrt, const SwField* pFld,
+ const SwTxtNode& rTxtNd, xub_StrLen nFldPos )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SwFieldType* pFldTyp = pFld->GetTyp();
+ USHORT nField = pFldTyp->Which();
+ ULONG nFmt = pFld->GetFormat();
+
+ const sal_Char *pTypeStr=0, // TYPE
+ *pSubStr=0, // SUBTYPE
+ *pFmtStr=0; // FORMAT (SW)
+ String aValue; // VALUE (SW)
+ BOOL bNumFmt=FALSE; // SDNUM (Number-Formatter-Format)
+ BOOL bNumValue=FALSE; // SDVAL (Number-Formatter-Value)
+ double dNumValue = 0.0; // SDVAL (Number-Formatter-Value)
+ BOOL bFixed=FALSE; // SDFIXED
+ String aName; // NAME (CUSTOM)
+
+ switch( nField )
+ {
+ case RES_EXTUSERFLD:
+ pTypeStr = OOO_STRING_SW_HTML_FT_sender;
+ switch( (SwExtUserSubType)pFld->GetSubType() )
+ {
+ case EU_COMPANY: pSubStr = OOO_STRING_SW_HTML_FS_company; break;
+ case EU_FIRSTNAME: pSubStr = OOO_STRING_SW_HTML_FS_firstname; break;
+ case EU_NAME: pSubStr = OOO_STRING_SW_HTML_FS_name; break;
+ case EU_SHORTCUT: pSubStr = OOO_STRING_SW_HTML_FS_shortcut; break;
+ case EU_STREET: pSubStr = OOO_STRING_SW_HTML_FS_street; break;
+ case EU_COUNTRY: pSubStr = OOO_STRING_SW_HTML_FS_country; break;
+ case EU_ZIP: pSubStr = OOO_STRING_SW_HTML_FS_zip; break;
+ case EU_CITY: pSubStr = OOO_STRING_SW_HTML_FS_city; break;
+ case EU_TITLE: pSubStr = OOO_STRING_SW_HTML_FS_title; break;
+ case EU_POSITION: pSubStr = OOO_STRING_SW_HTML_FS_position; break;
+ case EU_PHONE_PRIVATE: pSubStr = OOO_STRING_SW_HTML_FS_pphone; break;
+ case EU_PHONE_COMPANY: pSubStr = OOO_STRING_SW_HTML_FS_cphone; break;
+ case EU_FAX: pSubStr = OOO_STRING_SW_HTML_FS_fax; break;
+ case EU_EMAIL: pSubStr = OOO_STRING_SW_HTML_FS_email; break;
+ case EU_STATE: pSubStr = OOO_STRING_SW_HTML_FS_state; break;
+ default:
+ ;
+ }
+ ASSERT( pSubStr, "ubekannter Subtyp fuer SwExtUserField" );
+ bFixed = ((const SwExtUserField*)pFld)->IsFixed();
+ break;
+
+ case RES_AUTHORFLD:
+ pTypeStr = OOO_STRING_SW_HTML_FT_author;
+ switch( (SwAuthorFormat)nFmt & 0xff)
+ {
+ case AF_NAME: pFmtStr = OOO_STRING_SW_HTML_FF_name; break;
+ case AF_SHORTCUT: pFmtStr = OOO_STRING_SW_HTML_FF_shortcut; break;
+ }
+ ASSERT( pFmtStr, "ubekanntes Format fuer SwAuthorField" );
+ bFixed = ((const SwAuthorField*)pFld)->IsFixed();
+ break;
+
+ case RES_DATETIMEFLD:
+ pTypeStr = OOO_STRING_SW_HTML_FT_datetime;
+ bNumFmt = TRUE;
+ if( ((SwDateTimeField*)pFld)->IsFixed() )
+ {
+ bNumValue = TRUE;
+ dNumValue = ((SwDateTimeField*)pFld)->GetValue();
+ }
+ break;
+
+ case RES_PAGENUMBERFLD:
+ {
+ pTypeStr = OOO_STRING_SW_HTML_FT_page;
+ SwPageNumSubType eSubType = (SwPageNumSubType)pFld->GetSubType();
+ switch( eSubType )
+ {
+ case PG_RANDOM: pSubStr = OOO_STRING_SW_HTML_FS_random; break;
+ case PG_NEXT: pSubStr = OOO_STRING_SW_HTML_FS_next; break;
+ case PG_PREV: pSubStr = OOO_STRING_SW_HTML_FS_prev; break;
+ }
+ ASSERT( pSubStr, "ubekannter Subtyp fuer SwPageNumberField" );
+ pFmtStr = SwHTMLWriter::GetNumFormat( static_cast< sal_uInt16 >(nFmt) );
+
+ if( (SvxExtNumType)nFmt==SVX_NUM_CHAR_SPECIAL )
+ {
+ aValue = ((const SwPageNumberField *)pFld)->GetUserString();
+ }
+ else
+ {
+ const String& rValue = pFld->GetPar2();
+ short nValue = (short)rValue.ToInt32();
+ if( (eSubType == PG_NEXT && nValue!=1) ||
+ (eSubType == PG_PREV && nValue!=-1) ||
+ (eSubType == PG_RANDOM && nValue!=0) )
+ {
+ aValue = rValue;
+ }
+ }
+ }
+ break;
+ case RES_DOCINFOFLD:
+ {
+ USHORT nSubType = pFld->GetSubType();
+ pTypeStr = OOO_STRING_SW_HTML_FT_docinfo;
+ USHORT nExtSubType = nSubType & 0x0f00;
+ nSubType &= 0x00ff;
+
+ switch( nSubType )
+ {
+ case DI_TITEL: pSubStr = OOO_STRING_SW_HTML_FS_title; break;
+ case DI_THEMA: pSubStr = OOO_STRING_SW_HTML_FS_theme; break;
+ case DI_KEYS: pSubStr = OOO_STRING_SW_HTML_FS_keys; break;
+ case DI_COMMENT: pSubStr = OOO_STRING_SW_HTML_FS_comment; break;
+ case DI_CREATE: pSubStr = OOO_STRING_SW_HTML_FS_create; break;
+ case DI_CHANGE: pSubStr = OOO_STRING_SW_HTML_FS_change; break;
+ case DI_CUSTOM: pSubStr = OOO_STRING_SW_HTML_FS_custom; break;
+ default: pTypeStr = 0; break;
+ }
+
+ if( DI_CUSTOM == nSubType ) {
+ aName = static_cast<const SwDocInfoField*>(pFld)->GetName();
+ }
+
+ if( DI_CREATE == nSubType || DI_CHANGE == nSubType )
+ {
+ switch( nExtSubType )
+ {
+ case DI_SUB_AUTHOR:
+ pFmtStr = OOO_STRING_SW_HTML_FF_author;
+ break;
+ case DI_SUB_TIME:
+ pFmtStr = OOO_STRING_SW_HTML_FF_time;
+ bNumFmt = TRUE;
+ break;
+ case DI_SUB_DATE:
+ pFmtStr = OOO_STRING_SW_HTML_FF_date;
+ bNumFmt = TRUE;
+ break;
+ }
+ }
+ bFixed = ((const SwDocInfoField*)pFld)->IsFixed();
+ if( bNumFmt )
+ {
+ if( bFixed )
+ {
+ // Fuer ein fixes Feld och den Num-Value ausgeben.
+ // Fixe Felder ohne Zahlenformate sollte es
+ // eigentlich nicht geben. ASSERT ist unten.
+ dNumValue = ((const SwDocInfoField*)pFld)->GetValue();
+ bNumValue = TRUE;
+ }
+ else if( !nFmt )
+ {
+ // Nicht fixe Felder muessen kein Zahlenformat haben,
+ // wenn sie aus 4.0-Dokumenten stammen.
+ bNumFmt = FALSE;
+ }
+ }
+ }
+ break;
+
+ case RES_DOCSTATFLD:
+ {
+ pTypeStr = OOO_STRING_SW_HTML_FT_docstat;
+ USHORT nSubType = pFld->GetSubType();
+ switch( nSubType )
+ {
+ case DS_PAGE: pSubStr = OOO_STRING_SW_HTML_FS_page; break;
+ case DS_PARA: pSubStr = OOO_STRING_SW_HTML_FS_para; break;
+ case DS_WORD: pSubStr = OOO_STRING_SW_HTML_FS_word; break;
+ case DS_CHAR: pSubStr = OOO_STRING_SW_HTML_FS_char; break;
+ case DS_TBL: pSubStr = OOO_STRING_SW_HTML_FS_tbl; break;
+ case DS_GRF: pSubStr = OOO_STRING_SW_HTML_FS_grf; break;
+ case DS_OLE: pSubStr = OOO_STRING_SW_HTML_FS_ole; break;
+ default: pTypeStr = 0; break;
+ }
+ pFmtStr = SwHTMLWriter::GetNumFormat( static_cast< sal_uInt16 >(nFmt) );
+ }
+ break;
+
+ case RES_FILENAMEFLD:
+ pTypeStr = OOO_STRING_SW_HTML_FT_filename;
+ switch( (SwFileNameFormat)(nFmt & ~FF_FIXED) )
+ {
+ case FF_NAME: pFmtStr = OOO_STRING_SW_HTML_FF_name; break;
+ case FF_PATHNAME: pFmtStr = OOO_STRING_SW_HTML_FF_pathname; break;
+ case FF_PATH: pFmtStr = OOO_STRING_SW_HTML_FF_path; break;
+ case FF_NAME_NOEXT: pFmtStr = OOO_STRING_SW_HTML_FF_name_noext; break;
+ default:
+ ;
+ }
+ bFixed = ((const SwFileNameField*)pFld)->IsFixed();
+ ASSERT( pFmtStr, "unbekanntes Format fuer SwFileNameField" );
+ break;
+ }
+
+ // <SDFIELD>-Tag ausgeben
+ if( pTypeStr )
+ {
+ ByteString sOut( '<' );
+ ((((sOut += OOO_STRING_SVTOOLS_HTML_sdfield) += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=')
+ += pTypeStr;
+ if( pSubStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_subtype) += '=') += pSubStr;
+ if( pFmtStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_format) += '=') += pFmtStr;
+ if( aName.Len() )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"");
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ if( aValue.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aValue, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ if( bNumFmt )
+ {
+ ASSERT( nFmt, "Zahlenformat ist 0" );
+ sOut = HTMLOutFuncs::CreateTableDataOptionsValNum( sOut,
+ bNumValue, dNumValue, nFmt,
+ *rHTMLWrt.pDoc->GetNumberFormatter(),
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+
+ }
+ if( bFixed )
+ (sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_sdfixed;
+ sOut += '>';
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+
+ // Inhalt des Feldes ausgeben
+ String const sExpand( pFld->ExpandField(rWrt.pDoc->IsClipBoard()) );
+ sal_Bool bNeedsCJKProcessing = sal_False;
+ if( sExpand.Len() )
+ {
+ sal_uInt16 nScriptType = pBreakIt->GetBreakIter()->getScriptType( sExpand, 0 );
+ xub_StrLen nPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( sExpand, 0,
+ nScriptType );
+
+ sal_uInt16 nScript =
+ SwHTMLWriter::GetCSS1ScriptForScriptType( nScriptType );
+ if( nPos < sExpand.Len() || nScript != rHTMLWrt.nCSS1Script )
+ {
+ bNeedsCJKProcessing = sal_True;
+ }
+ }
+
+ if( bNeedsCJKProcessing )
+ {
+ SfxItemSet aScriptItemSet( rWrt.pDoc->GetAttrPool(),
+ RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
+ RES_CHRATR_POSTURE, RES_CHRATR_POSTURE,
+ RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
+ RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
+ 0 );
+ rTxtNd.GetAttr( aScriptItemSet, nFldPos, nFldPos+1 );
+
+ sal_uInt16 aWesternWhichIds[4] =
+ { RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
+ RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT };
+ sal_uInt16 aCJKWhichIds[4] =
+ { RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
+ RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT };
+ sal_uInt16 aCTLWhichIds[4] =
+ { RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE,
+ RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT };
+
+ sal_uInt16 *pRefWhichIds = 0;
+ switch( rHTMLWrt.nCSS1Script )
+ {
+ case CSS1_OUTMODE_WESTERN:
+ pRefWhichIds = aWesternWhichIds;
+ break;
+ case CSS1_OUTMODE_CJK:
+ pRefWhichIds = aCJKWhichIds;
+ break;
+ case CSS1_OUTMODE_CTL:
+ pRefWhichIds = aCTLWhichIds;
+ break;
+ }
+
+ xub_StrLen nPos = 0;
+ do
+ {
+ sal_uInt16 nScriptType = pBreakIt->GetBreakIter()->getScriptType( sExpand, nPos );
+ sal_uInt16 nScript =
+ SwHTMLWriter::GetCSS1ScriptForScriptType( nScriptType );
+ xub_StrLen nEndPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript(
+ sExpand, nPos, nScriptType );
+ if( nScript != CSS1_OUTMODE_ANY_SCRIPT &&
+ /* #108791# */ nScript != rHTMLWrt.nCSS1Script )
+ {
+ sal_uInt16 *pWhichIds = 0;
+ switch( nScript )
+ {
+ case CSS1_OUTMODE_WESTERN: pWhichIds = aWesternWhichIds; break;
+ case CSS1_OUTMODE_CJK: pWhichIds = aCJKWhichIds; break;
+ case CSS1_OUTMODE_CTL: pWhichIds = aCTLWhichIds; break;
+ }
+
+ rHTMLWrt.bTagOn = TRUE;
+ const SfxPoolItem *aItems[5];
+ sal_uInt16 nItems = 0;
+ for( sal_uInt16 i=0; i<4; i++ )
+ {
+ const SfxPoolItem *pRefItem =
+ aScriptItemSet.GetItem( pRefWhichIds[i] );
+ const SfxPoolItem *pItem =
+ aScriptItemSet.GetItem( pWhichIds[i] );
+ if( pRefItem && pItem &&
+ !(0==i ? lcl_css1atr_equalFontItems( *pRefItem, *pItem )
+ : *pRefItem == *pItem) )
+ {
+ Out( aHTMLAttrFnTab, *pItem, rHTMLWrt );
+ aItems[nItems++] = pItem;
+ }
+ }
+
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand.Copy( nPos, nEndPos ),
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+
+ rHTMLWrt.bTagOn = FALSE;
+ while( nItems )
+ Out( aHTMLAttrFnTab, *aItems[--nItems], rHTMLWrt );
+
+ }
+ else
+ {
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand.Copy( nPos, nEndPos ),
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ }
+ nPos = nEndPos;
+ }
+ while( nPos < sExpand.Len() );
+ }
+ else
+ {
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ }
+
+ // Off-Tag ausgeben
+ if( pTypeStr )
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_sdfield, FALSE );
+
+ return rWrt;
+}
+
+
+Writer& OutHTML_SwFmtFld( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwFmtFld & rFld = (SwFmtFld&)rHt;
+ const SwField* pFld = rFld.GetFld();
+ const SwFieldType* pFldTyp = pFld->GetTyp();
+
+ if( RES_SETEXPFLD == pFldTyp->Which() &&
+ (nsSwGetSetExpType::GSE_STRING & pFld->GetSubType()) )
+ {
+ int bOn = FALSE;
+ if( pFldTyp->GetName().EqualsAscii("HTML_ON" ) )
+ bOn = TRUE;
+ else if( !pFldTyp->GetName().EqualsAscii( "HTML_OFF" ) )
+ return rWrt;
+
+ String rTxt( pFld->GetPar2() );
+ rTxt.EraseLeadingChars().EraseTrailingChars();
+ rWrt.Strm() << '<';
+ if( !bOn )
+ rWrt.Strm() << '/';
+ // TODO: HTML-Tags are written without entitities, that for, characters
+ // not contained in the destination encoding are lost!
+ ByteString sTmp( rTxt, ((SwHTMLWriter&)rWrt).eDestEnc );
+ rWrt.Strm() << sTmp.GetBuffer() << '>';
+ }
+ else if( RES_POSTITFLD == pFldTyp->Which() )
+ {
+ // Kommentare werden im ANSI-Zeichensetz, aber mit System-Zeilen-
+ // Umbruechen gesschrieben.
+ const String& rComment = pFld->GetPar2();
+ BOOL bWritten = FALSE;
+
+ if( (rComment.Len() >= 6 && '<' == rComment.GetChar(0) &&
+ '>' == rComment.GetChar(rComment.Len()-1) &&
+ rComment.Copy( 1, 4 ).EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_meta)) ||
+ (rComment.Len() >= 7 &&
+ rComment.Copy( 0, 4 ).EqualsAscii( "<!--" ) &&
+ rComment.Copy( rComment.Len()-3, 3 ).EqualsAscii( "-->" )) )
+ {
+ // META-Tags direkt ausgeben
+ String sComment( rComment );
+ sComment.ConvertLineEnd( GetSystemLineEnd() );
+ // TODO: HTML-Tags are written without entitities, that for,
+ // characters not contained in the destination encoding are lost!
+ ByteString sTmp( sComment, ((SwHTMLWriter&)rWrt).eDestEnc );
+ rWrt.Strm() << sTmp.GetBuffer();
+ bWritten = TRUE;
+ }
+ else if( rComment.Len() >= 7 &&
+ '>' == rComment.GetChar(rComment.Len()-1) &&
+ rComment.Copy(0,5).EqualsIgnoreCaseAscii("HTML:") )
+ {
+ String sComment( rComment.Copy(5) );
+ sComment.EraseLeadingChars();
+ if( '<' == sComment.GetChar(0) )
+ {
+ sComment.ConvertLineEnd( GetSystemLineEnd() );
+ // TODO: HTML-Tags are written without entitities, that for,
+ // characters not contained in the destination encoding are
+ // lost!
+ ByteString sTmp( sComment, ((SwHTMLWriter&)rWrt).eDestEnc );
+ rWrt.Strm() << sTmp.GetBuffer();
+ bWritten = TRUE;
+ }
+
+ }
+
+ if( !bWritten )
+ {
+ ByteString sOut( '<' );
+
+ String sComment( rComment );
+ sComment.ConvertLineEnd( GetSystemLineEnd() );
+ // TODO: ???
+ (((sOut += OOO_STRING_SVTOOLS_HTML_comment) += ' ')
+ += ByteString( sComment, ((SwHTMLWriter&)rWrt).eDestEnc ))
+ += " -->";
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+ }
+ else if( RES_SCRIPTFLD == pFldTyp->Which() )
+ {
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( TRUE );
+
+ BOOL bURL = ((const SwScriptField *)pFld)->IsCodeURL();
+ const String& rType = pFld->GetPar1();
+ String aContents, aURL;
+ if(bURL)
+ aURL = pFld->GetPar2();
+ else
+ aContents = pFld->GetPar2();
+
+ // sonst ist es der Script-Inhalt selbst. Da nur noh JavaScript
+ // in Feldern landet, muss es sich um JavaSrript handeln ...:)
+ HTMLOutFuncs::OutScript( rWrt.Strm(), rWrt.GetBaseURL(), aContents, rType, JAVASCRIPT,
+ aURL, 0, 0, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( TRUE );
+ }
+ else
+ {
+ const SwTxtFld *pTxtFld = rFld.GetTxtFld();
+ ASSERT( pTxtFld, "Where is the txt fld?" );
+ if( pTxtFld )
+ OutHTML_SwField( rWrt, pFld, pTxtFld->GetTxtNode(),
+ *pTxtFld->GetStart() );
+ }
+ return rWrt;
+}
+
+
diff --git a/sw/source/filter/html/htmlfly.cxx b/sw/source/filter/html/htmlfly.cxx
new file mode 100644
index 000000000000..88fe896d6a17
--- /dev/null
+++ b/sw/source/filter/html/htmlfly.cxx
@@ -0,0 +1,1929 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <svx/svxids.hrc>
+#include "hintids.hxx"
+#include <tools/string.hxx>
+#include <svl/urihelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/imap.hxx>
+#include <svtools/imapobj.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <svx/xoutbmp.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brshitem.hxx>
+
+
+#include <fmtanchr.hxx>
+#include <fmtornt.hxx>
+#include <fmturl.hxx>
+#include <fmtfsize.hxx>
+#include <fmtclds.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtinfmt.hxx>
+#include <txtinet.hxx>
+#include "frmatr.hxx"
+#include <grfatr.hxx>
+#include <flypos.hxx>
+#include <docary.hxx>
+#include <ndgrf.hxx>
+
+#include "doc.hxx"
+#include "ndtxt.hxx"
+#include "pam.hxx"
+#include "swerror.h"
+#include "frmfmt.hxx"
+#include "wrthtml.hxx"
+#include "css1kywd.hxx"
+#include "htmlfly.hxx"
+
+using namespace ::com::sun::star;
+
+////////////////////////////////////////////////////////////
+
+const ULONG HTML_FRMOPTS_IMG_ALL =
+ HTML_FRMOPT_ALT |
+ HTML_FRMOPT_SIZE |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_BORDER |
+ HTML_FRMOPT_NAME;
+const ULONG HTML_FRMOPTS_IMG_CNTNR =
+ HTML_FRMOPTS_IMG_ALL |
+ HTML_FRMOPT_ABSSIZE;
+const ULONG HTML_FRMOPTS_IMG =
+ HTML_FRMOPTS_IMG_ALL |
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SPACE |
+ HTML_FRMOPT_BRCLEAR;
+const ULONG HTML_FRMOPTS_IMG_CSS1 =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SPACE;
+
+const ULONG HTML_FRMOPTS_DIV =
+ HTML_FRMOPT_ID |
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SIZE |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_ABSSIZE |
+ HTML_FRMOPT_S_SPACE |
+ HTML_FRMOPT_S_BORDER |
+ HTML_FRMOPT_S_BACKGROUND |
+ HTML_FRMOPT_BRCLEAR |
+ HTML_FRMOPT_DIR;
+
+const ULONG HTML_FRMOPTS_MULTICOL =
+ HTML_FRMOPT_ID |
+ HTML_FRMOPT_WIDTH |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_ABSSIZE |
+ HTML_FRMOPT_DIR;
+const ULONG HTML_FRMOPTS_MULTICOL_CNTNR =
+ HTML_FRMOPTS_MULTICOL;
+const ULONG HTML_FRMOPTS_MULTICOL_CSS1 =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SIZE |
+ HTML_FRMOPT_S_SPACE |
+ HTML_FRMOPT_S_BORDER|
+ HTML_FRMOPT_S_BACKGROUND;
+
+const ULONG HTML_FRMOPTS_SPACER =
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SIZE |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_BRCLEAR |
+ HTML_FRMOPT_MARGINSIZE |
+ HTML_FRMOPT_ABSSIZE;
+
+const ULONG HTML_FRMOPTS_CNTNR =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SPACE |
+ HTML_FRMOPT_S_WIDTH |
+ HTML_FRMOPT_ANYSIZE |
+ HTML_FRMOPT_ABSSIZE |
+ HTML_FRMOPT_S_PIXSIZE;
+
+
+static Writer& OutHTML_FrmFmtTableNode( Writer& rWrt, const SwFrmFmt& rFrmFmt );
+static Writer& OutHTML_FrmFmtAsMulticol( Writer& rWrt, const SwFrmFmt& rFmt,
+ BOOL bInCntnr );
+static Writer& OutHTML_FrmFmtAsSpacer( Writer& rWrt, const SwFrmFmt& rFmt );
+static Writer& OutHTML_FrmFmtAsDivOrSpan( Writer& rWrt,
+ const SwFrmFmt& rFrmFmt, BOOL bSpan );
+static Writer& OutHTML_FrmFmtAsImage( Writer& rWrt, const SwFrmFmt& rFmt,
+ BOOL bInCntnr );
+
+static Writer& OutHTML_FrmFmtGrfNode( Writer& rWrt, const SwFrmFmt& rFmt,
+ BOOL bInCntnr );
+
+static Writer& OutHTML_FrmFmtAsMarquee( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ const SdrObject& rSdrObj );
+//-----------------------------------------------------------------------
+
+extern HTMLOutEvent __FAR_DATA aAnchorEventTable[];
+
+static HTMLOutEvent __FAR_DATA aImageEventTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_O_SDonload, OOO_STRING_SVTOOLS_HTML_O_onload, SVX_EVENT_IMAGE_LOAD },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonabort, OOO_STRING_SVTOOLS_HTML_O_onabort, SVX_EVENT_IMAGE_ABORT },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonerror, OOO_STRING_SVTOOLS_HTML_O_onerror, SVX_EVENT_IMAGE_ERROR },
+ { 0, 0, 0 }
+};
+
+static HTMLOutEvent __FAR_DATA aIMapEventTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_O_SDonmouseover, OOO_STRING_SVTOOLS_HTML_O_onmouseover, SFX_EVENT_MOUSEOVER_OBJECT },
+ { OOO_STRING_SVTOOLS_HTML_O_SDonmouseout, OOO_STRING_SVTOOLS_HTML_O_onmouseout, SFX_EVENT_MOUSEOUT_OBJECT },
+ { 0, 0, 0 }
+};
+
+
+
+SV_IMPL_OP_PTRARR_SORT( SwHTMLPosFlyFrms, SwHTMLPosFlyFrmPtr )
+
+USHORT SwHTMLWriter::GuessFrmType( const SwFrmFmt& rFrmFmt,
+ const SdrObject*& rpSdrObj )
+{
+ SwHTMLFrmType eType;
+
+ if( RES_DRAWFRMFMT == rFrmFmt.Which() )
+ {
+ // Als Default irgendein Zeichen-Objekt
+ eType = HTML_FRMTYPE_DRAW;
+
+ const SdrObject *pObj =
+ SwHTMLWriter::GetMarqueeTextObj( (const SwDrawFrmFmt &)rFrmFmt );
+ if( pObj )
+ {
+ // Laufschrift
+ rpSdrObj = pObj;
+ eType = HTML_FRMTYPE_MARQUEE;
+ }
+ else
+ {
+ pObj = GetHTMLControl( (const SwDrawFrmFmt &)rFrmFmt );
+
+ if( pObj )
+ {
+ // Form-Control
+ rpSdrObj = pObj;
+ eType = HTML_FRMTYPE_CONTROL;
+ }
+ }
+ }
+ else
+ {
+ // Als Default ein Textrahmen
+ eType = HTML_FRMTYPE_TEXT;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
+ const SwNode* pNd = pDoc->GetNodes()[ nStt ];
+
+ if( pNd->IsGrfNode() )
+ {
+ // Grafik - Node
+ eType = HTML_FRMTYPE_GRF;
+ }
+ else if( pNd->IsOLENode() )
+ {
+ // Applet, Plugin, Floating-Frame
+ eType = (SwHTMLFrmType)GuessOLENodeFrmType( *pNd );
+ }
+ else
+ {
+ ULONG nEnd = pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
+
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_COL,
+ TRUE, &pItem ) &&
+ ((const SwFmtCol *)pItem)->GetNumCols() > 1 )
+ {
+ // spaltiger Rahmen
+ eType = HTML_FRMTYPE_MULTICOL;
+ }
+ else if( pNd->IsTableNode() )
+ {
+ const SwTableNode *pTblNd = pNd->GetTableNode();
+ ULONG nTblEnd = pTblNd->EndOfSectionIndex();
+
+ if( nTblEnd+1 == nEnd )
+ {
+ // Tabelle
+ eType = HTML_FRMTYPE_TABLE;
+ }
+ else if( nTblEnd+2 == nEnd )
+ {
+ // Tabelle mit Unterschrft
+ eType = HTML_FRMTYPE_TABLE_CAP;
+ }
+ }
+ else if( pNd->IsTxtNode() )
+ {
+ const SwTxtNode *pTxtNd = pNd->GetTxtNode();
+
+ BOOL bEmpty = FALSE;
+ if( nStt==nEnd-1 && !pTxtNd->Len() )
+ {
+ // leerer Rahmen? Nur wenn kein Rahmen am
+ // Text- oder Start-Node verankert ist.
+ bEmpty = TRUE;
+ if( pHTMLPosFlyFrms )
+ {
+ for( USHORT i=0; i<pHTMLPosFlyFrms->Count(); i++ )
+ {
+ ULONG nIdx = (*pHTMLPosFlyFrms)[i]
+ ->GetNdIndex().GetIndex();
+ bEmpty = (nIdx != nStt) && (nIdx != nStt-1);
+ if( !bEmpty || nIdx > nStt )
+ break;
+ }
+ }
+ }
+ if( bEmpty )
+ {
+ const SvxBrushItem& rBrush = rFrmFmt.GetBackground();
+ /// OD 02.09.2002 #99657#
+ /// background is not empty, if it has a background graphic
+ /// or its background color is not "no fill"/"auto fill".
+ if( GPOS_NONE != rBrush.GetGraphicPos() ||
+ rBrush.GetColor() != COL_TRANSPARENT )
+ bEmpty = FALSE;
+ }
+ if( bEmpty )
+ {
+ // leerer Rahmen
+ eType = HTML_FRMTYPE_EMPTY;
+ }
+ else if( pDoc->GetNodes()[nStt+1]->IsTableNode() )
+ {
+ const SwTableNode *pTblNd =
+ pDoc->GetNodes()[nStt+1]->GetTableNode();
+ if( pTblNd->EndOfSectionIndex()+1 == nEnd )
+ {
+ // Tabelle mit Ueberschrift
+ eType = HTML_FRMTYPE_TABLE_CAP;
+ }
+ }
+ }
+ }
+ }
+
+ return static_cast< USHORT >(eType);
+}
+
+void SwHTMLWriter::CollectFlyFrms()
+{
+ ASSERT( HTML_CFG_MAX+1 == MAX_BROWSERS,
+ "number of browser configurations has changed" );
+
+ BYTE nSz = (BYTE)Min( pDoc->GetSpzFrmFmts()->Count(), USHORT(255) );
+ SwPosFlyFrms aFlyPos( nSz, nSz );
+ pDoc->GetAllFlyFmts( aFlyPos, bWriteAll ? 0 : pCurPam, TRUE );
+
+ for( USHORT i=0; i< aFlyPos.Count(); i++ )
+ {
+ const SwFrmFmt& rFrmFmt = aFlyPos[i]->GetFmt();
+ const SdrObject *pSdrObj = 0;
+ const SwPosition *pAPos;
+ const SwCntntNode *pACNd;
+ SwHTMLFrmType eType = (SwHTMLFrmType)GuessFrmType( rFrmFmt, pSdrObj );
+
+ BYTE nMode;
+ const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
+ sal_Int16 eHoriRel = rFrmFmt.GetHoriOrient().GetRelationOrient();
+ switch( rAnchor.GetAnchorId() )
+ {
+ case FLY_AT_PAGE:
+ case FLY_AT_FLY:
+ nMode = aHTMLOutFrmPageFlyTable[eType][nExportMode];
+ break;
+
+ case FLY_AT_PARA:
+ // Absatz-gebundene Rahmen werden nur dann vor den
+ // Absatz geschrieben, wenn der Absatz einen Abstand
+ // hat.
+ if( text::RelOrientation::FRAME == eHoriRel &&
+ (pAPos = rAnchor.GetCntntAnchor()) != 0 &&
+ (pACNd = pAPos->nNode.GetNode().GetCntntNode()) != 0 )
+ {
+ const SvxLRSpaceItem& rLRItem =
+ (const SvxLRSpaceItem&)pACNd->GetAttr(RES_LR_SPACE);
+ if( rLRItem.GetTxtLeft() || rLRItem.GetRight() )
+ {
+ nMode = aHTMLOutFrmParaFrameTable[eType][nExportMode];
+ break;
+ }
+ }
+ nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
+ break;
+
+ case FLY_AT_CHAR:
+ if( text::RelOrientation::FRAME == eHoriRel || text::RelOrientation::PRINT_AREA == eHoriRel )
+ nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
+ else
+ nMode = aHTMLOutFrmParaOtherTable[eType][nExportMode];
+ break;
+
+ default:
+ nMode = aHTMLOutFrmParaPrtAreaTable[eType][nExportMode];
+ break;
+ }
+
+ if( !pHTMLPosFlyFrms )
+ pHTMLPosFlyFrms = new SwHTMLPosFlyFrms;
+
+ SwHTMLPosFlyFrm *pNew =
+ new SwHTMLPosFlyFrm( *aFlyPos[i], pSdrObj, nMode );
+ pHTMLPosFlyFrms->Insert( pNew );
+ }
+}
+
+BOOL SwHTMLWriter::OutFlyFrm( ULONG nNdIdx, xub_StrLen nCntntIdx, BYTE nPos,
+ HTMLOutContext *pContext )
+{
+ BOOL bFlysLeft = FALSE; // Noch Flys an aktueller Node-Position da?
+
+ // OutFlyFrm kan rekursiv aufgerufen werden. Deshalb muss man
+ // manchmal wieder von vorne anfangen, nachdem ein Fly ausgegeben
+ // wurde.
+ BOOL bRestart = TRUE;
+ while( pHTMLPosFlyFrms && bRestart )
+ {
+ bFlysLeft = bRestart = FALSE;
+
+ // suche nach dem Anfang der FlyFrames
+ USHORT i;
+
+ for( i = 0; i < pHTMLPosFlyFrms->Count() &&
+ (*pHTMLPosFlyFrms)[i]->GetNdIndex().GetIndex() < nNdIdx; i++ )
+ ;
+ for( ; !bRestart && i < pHTMLPosFlyFrms->Count() &&
+ (*pHTMLPosFlyFrms)[i]->GetNdIndex().GetIndex() == nNdIdx; i++ )
+ {
+ SwHTMLPosFlyFrm *pPosFly = (*pHTMLPosFlyFrms)[i];
+ if( ( HTML_POS_ANY == nPos ||
+ pPosFly->GetOutPos() == nPos ) &&
+ pPosFly->GetCntntIndex() == nCntntIdx )
+ {
+ // Erst entfernen ist wichtig, weil in tieferen
+ // Rekursionen evtl. weitere Eintraege oder das
+ // ganze Array geloscht werden koennte.
+ pHTMLPosFlyFrms->Remove( i, 1 );
+ i--;
+ if( !pHTMLPosFlyFrms->Count() )
+ {
+ delete pHTMLPosFlyFrms;
+ pHTMLPosFlyFrms = 0;
+ bRestart = TRUE; // nicht wirklich, nur raus
+ // aus der Schleife
+ }
+
+ if( pContext )
+ {
+ HTMLOutFuncs::FlushToAscii(Strm(), *pContext );
+ pContext = 0; // one time only
+ }
+
+ OutFrmFmt( pPosFly->GetOutMode(), pPosFly->GetFmt(),
+ pPosFly->GetSdrObject() );
+ switch( pPosFly->GetOutFn() )
+ {
+ case HTML_OUT_DIV:
+ case HTML_OUT_SPAN:
+ case HTML_OUT_MULTICOL:
+ case HTML_OUT_TBLNODE:
+ bRestart = TRUE; // Hier wird's evtl rekursiv
+ break;
+ }
+ delete pPosFly;
+ }
+ else
+ {
+ bFlysLeft = TRUE;
+ }
+ }
+ }
+
+ return bFlysLeft;
+}
+
+void SwHTMLWriter::OutFrmFmt( BYTE nMode, const SwFrmFmt& rFrmFmt,
+ const SdrObject *pSdrObject )
+{
+ BYTE nCntnrMode = SwHTMLPosFlyFrm::GetOutCntnr( nMode );
+ BYTE nOutMode = SwHTMLPosFlyFrm::GetOutFn(nMode);
+ const sal_Char *pCntnrStr = 0;
+ if( HTML_CNTNR_NONE != nCntnrMode )
+ {
+
+ if( bLFPossible && HTML_CNTNR_DIV == nCntnrMode )
+ OutNewLine();
+
+ ByteString sOut( '<' );
+ pCntnrStr = (HTML_CNTNR_DIV == nCntnrMode)
+ ? OOO_STRING_SVTOOLS_HTML_division
+ : OOO_STRING_SVTOOLS_HTML_span;
+ sOut += pCntnrStr;
+ ((((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"")
+ += sCSS1_class_abs_pos) += '\"';
+ Strm() << sOut.GetBuffer();
+
+ // Fuer Nicht-Zeichenobekte eine Breite ausgeben
+ ULONG nFrmFlags = HTML_FRMOPTS_CNTNR;
+
+ // Fuer spaltige Rahmen koennen wir auch noch den Hintergrund ausgeben.
+ if( HTML_OUT_MULTICOL == nOutMode )
+ nFrmFlags |= HTML_FRMOPT_S_BACKGROUND|HTML_FRMOPT_S_BORDER;
+
+ if( IsHTMLMode( HTMLMODE_BORDER_NONE ) )
+ nFrmFlags |= HTML_FRMOPT_S_NOBORDER;
+ OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags, pSdrObject );
+ Strm() << '>';
+
+ if( HTML_CNTNR_DIV == nCntnrMode )
+ {
+ IncIndentLevel();
+ bLFPossible = TRUE;
+ }
+ }
+
+ switch( nOutMode )
+ {
+ case HTML_OUT_TBLNODE: // OK
+ ASSERT( !pCntnrStr, "Table: Container ist hier nicht vorgesehen" );
+ OutHTML_FrmFmtTableNode( *this, rFrmFmt );
+ break;
+ case HTML_OUT_GRFNODE: // OK
+ OutHTML_FrmFmtGrfNode( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ case HTML_OUT_OLENODE: // OK
+ OutHTML_FrmFmtOLENode( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ case HTML_OUT_OLEGRF: // OK
+ OutHTML_FrmFmtOLENodeGrf( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ case HTML_OUT_DIV:
+ case HTML_OUT_SPAN:
+ ASSERT( !pCntnrStr, "Div: Container ist hier nicht vorgesehen" );
+ OutHTML_FrmFmtAsDivOrSpan( *this, rFrmFmt, HTML_OUT_SPAN==nOutMode );
+ break;
+ case HTML_OUT_MULTICOL: // OK
+ OutHTML_FrmFmtAsMulticol( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ case HTML_OUT_SPACER: // OK
+ ASSERT( !pCntnrStr, "Spacer: Container ist hier nicht vorgesehen" );
+ OutHTML_FrmFmtAsSpacer( *this, rFrmFmt );
+ break;
+ case HTML_OUT_CONTROL: // OK
+ OutHTML_DrawFrmFmtAsControl( *this,
+ (const SwDrawFrmFmt &)rFrmFmt, *pSdrObject,
+ pCntnrStr != 0 );
+ break;
+ case HTML_OUT_AMARQUEE:
+ OutHTML_FrmFmtAsMarquee( *this, rFrmFmt, *pSdrObject );
+ break;
+ case HTML_OUT_MARQUEE:
+ ASSERT( !pCntnrStr, "Marquee: Container ist hier nicht vorgesehen" );
+ OutHTML_DrawFrmFmtAsMarquee( *this,
+ (const SwDrawFrmFmt &)rFrmFmt, *pSdrObject );
+ break;
+ case HTML_OUT_GRFFRM:
+ OutHTML_FrmFmtAsImage( *this, rFrmFmt, pCntnrStr != 0 );
+ break;
+ }
+
+ if( HTML_CNTNR_DIV == nCntnrMode )
+ {
+ DecIndentLevel();
+ if( bLFPossible )
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_division, FALSE );
+ bLFPossible = TRUE;
+ }
+ else if( HTML_CNTNR_SPAN == nCntnrMode )
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, FALSE );
+}
+
+
+void SwHTMLWriter::OutFrmFmtOptions( const SwFrmFmt &rFrmFmt,
+ const String& rAlternateTxt,
+ ByteString &rEndTags,
+ sal_uInt32 nFrmOpts )
+{
+ ByteString sOut;
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+
+ // Name
+ if( (nFrmOpts & (HTML_FRMOPT_ID|HTML_FRMOPT_NAME)) &&
+ rFrmFmt.GetName().Len() )
+ {
+ const sal_Char *pStr =
+ (nFrmOpts & HTML_FRMOPT_ID) ? OOO_STRING_SVTOOLS_HTML_O_id : OOO_STRING_SVTOOLS_HTML_O_name;
+ ((sOut += ' ') += pStr) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), rFrmFmt.GetName(), eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ // Name
+ if( nFrmOpts & HTML_FRMOPT_DIR )
+ {
+ sal_uInt16 nDir = GetHTMLDirection( rItemSet );
+ Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ OutDirection( nDir );
+ }
+
+
+ // ALT
+ if( (nFrmOpts & HTML_FRMOPT_ALT) && rAlternateTxt.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_alt) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), rAlternateTxt, eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ // ALIGN
+ const sal_Char *pStr = 0;
+ RndStdIds eAnchorId = rFrmFmt.GetAnchor().GetAnchorId();
+ if( (nFrmOpts & HTML_FRMOPT_ALIGN) &&
+ ((FLY_AT_PARA == eAnchorId) || (FLY_AT_CHAR == eAnchorId)) )
+ {
+ // MIB 12.3.98: Ist es nicht schlauer, absatzgebundene
+ // Rahmen notfalls links auszurichten als sie
+ // zeichengebunden einzufuegen???
+ const SwFmtHoriOrient& rHoriOri = rFrmFmt.GetHoriOrient();
+ if( !(nFrmOpts & HTML_FRMOPT_S_ALIGN) ||
+ text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
+ text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
+ {
+ pStr = text::HoriOrientation::RIGHT == rHoriOri.GetHoriOrient()
+ ? OOO_STRING_SVTOOLS_HTML_AL_right
+ : OOO_STRING_SVTOOLS_HTML_AL_left;
+ }
+ }
+ if( (nFrmOpts & HTML_FRMOPT_ALIGN) && !pStr &&
+ ( (nFrmOpts & HTML_FRMOPT_S_ALIGN) == 0 ||
+ (FLY_AS_CHAR == eAnchorId) ) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_VERT_ORIENT, TRUE, &pItem ))
+ {
+ switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
+ {
+ case text::VertOrientation::LINE_TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_top; break;
+ case text::VertOrientation::CHAR_TOP:
+ case text::VertOrientation::BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; // geht nicht
+ case text::VertOrientation::LINE_CENTER:
+ case text::VertOrientation::CHAR_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; // geht nicht
+ case text::VertOrientation::CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
+ case text::VertOrientation::LINE_BOTTOM:
+ case text::VertOrientation::CHAR_BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; // geht nicht
+ case text::VertOrientation::TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
+ case text::VertOrientation::NONE: break;
+ }
+ }
+ if( pStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
+
+
+ // HSPACE und VSPACE
+ Size aTwipSpc( 0, 0 );
+ if( (nFrmOpts & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, TRUE, &pItem ))
+ {
+ aTwipSpc.Width() =
+ ( ((SvxLRSpaceItem*)pItem)->GetLeft() +
+ ((SvxLRSpaceItem*)pItem)->GetRight() ) / 2;
+ nDfltLeftMargin = nDfltRightMargin = aTwipSpc.Width();
+ }
+ if( (nFrmOpts & (HTML_FRMOPT_SPACE|HTML_FRMOPT_MARGINSIZE)) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, TRUE, &pItem ))
+ {
+ aTwipSpc.Height() =
+ ( ((SvxULSpaceItem*)pItem)->GetUpper() +
+ ((SvxULSpaceItem*)pItem)->GetLower() ) / 2;
+ nDfltTopMargin = nDfltBottomMargin = (USHORT)aTwipSpc.Height();
+ }
+
+ if( (nFrmOpts & HTML_FRMOPT_SPACE) &&
+ (aTwipSpc.Width() || aTwipSpc.Height()) &&
+ Application::GetDefaultDevice() )
+ {
+ Size aPixelSpc =
+ Application::GetDefaultDevice()->LogicToPixel( aTwipSpc,
+ MapMode(MAP_TWIP) );
+ if( !aPixelSpc.Width() && aTwipSpc.Width() )
+ aPixelSpc.Width() = 1;
+ if( !aPixelSpc.Height() && aTwipSpc.Height() )
+ aPixelSpc.Height() = 1;
+
+ if( aPixelSpc.Width() )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_hspace) += '=')
+ += ByteString::CreateFromInt32( aPixelSpc.Width() );
+ }
+
+ if( aPixelSpc.Height() )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_vspace) += '=')
+ += ByteString::CreateFromInt32( aPixelSpc.Height() );
+ }
+ }
+
+ // Der Abstand muss bei der Groesse beruecksichtigt, wenn das entsprechende
+ // Flag gesetzt ist.
+ if( (nFrmOpts & HTML_FRMOPT_MARGINSIZE) )
+ {
+ aTwipSpc.Width() *= -2;
+ aTwipSpc.Height() *= -2;
+ }
+ else
+ {
+ aTwipSpc.Width() = 0;
+ aTwipSpc.Height() = 0;
+ }
+
+ if( !(nFrmOpts & HTML_FRMOPT_ABSSIZE) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, TRUE, &pItem ))
+ {
+ const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
+
+ aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_LEFT );
+ aTwipSpc.Width() += pBoxItem->CalcLineSpace( BOX_LINE_RIGHT );
+ aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_TOP );
+ aTwipSpc.Height() += pBoxItem->CalcLineSpace( BOX_LINE_BOTTOM );
+ }
+
+ // WIDTH und/oder HEIGHT
+ // ATT_VAR_SIZE/ATT_MIN_SIZE nur ausgeben, wenn ANYSIZE gesezut ist
+ if( (nFrmOpts & HTML_FRMOPT_SIZE) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_FRM_SIZE, TRUE, &pItem ) &&
+ ( (nFrmOpts & HTML_FRMOPT_ANYSIZE) ||
+ ATT_FIX_SIZE == ((const SwFmtFrmSize *)pItem)->GetHeightSizeType()) )
+ {
+ const SwFmtFrmSize *pFSItem = (const SwFmtFrmSize *)pItem;
+ BYTE nPrcWidth = pFSItem->GetWidthPercent();
+ BYTE nPrcHeight = pFSItem->GetHeightPercent();
+
+ // Groesse des Objekts Twips ohne Raender
+ Size aTwipSz( (nPrcWidth ? 0
+ : pFSItem->GetWidth()-aTwipSpc.Width()),
+ (nPrcHeight ? 0
+ : pFSItem->GetHeight()-aTwipSpc.Height()) );
+
+ ASSERT( aTwipSz.Width() >= 0 && aTwipSz.Height() >= 0,
+ "Rahmengroesse minus Abstand < 0!!!???" );
+ if( aTwipSz.Width() < 0 )
+ aTwipSz.Width() = 0;
+ if( aTwipSz.Height() < 0 )
+ aTwipSz.Height() = 0;
+
+ Size aPixelSz( 0, 0 );
+ if( (aTwipSz.Width() || aTwipSz.Height()) &&
+ Application::GetDefaultDevice() )
+ {
+ aPixelSz =
+ Application::GetDefaultDevice()->LogicToPixel( aTwipSz,
+ MapMode(MAP_TWIP) );
+ if( !aPixelSz.Width() && aTwipSz.Width() )
+ aPixelSz.Width() = 1;
+ if( !aPixelSz.Height() && aTwipSz.Height() )
+ aPixelSz.Height() = 1;
+ }
+
+ if( (nFrmOpts & HTML_FRMOPT_WIDTH) &&
+ ((nPrcWidth && nPrcWidth!=255) || aPixelSz.Width()) )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=';
+ if( nPrcWidth )
+ (sOut += ByteString::CreateFromInt32( nPrcWidth )) += '%';
+ else
+ sOut += ByteString::CreateFromInt32( aPixelSz.Width() );
+ }
+
+ if( (nFrmOpts & HTML_FRMOPT_HEIGHT) &&
+ ((nPrcHeight && nPrcHeight!=255) || aPixelSz.Height()) )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=';
+ if( nPrcHeight )
+ (sOut += ByteString::CreateFromInt32( nPrcHeight )) += '%';
+ else
+ sOut += ByteString::CreateFromInt32( aPixelSz.Height() );
+ }
+ }
+
+ if( sOut.Len() )
+ Strm() << sOut.GetBuffer();
+
+ // Umlauf fuer absatzgeb. Grafiken als <BR CLEAR=...> in den String
+ // schreiben
+ if( (nFrmOpts & HTML_FRMOPT_BRCLEAR) &&
+ ((FLY_AT_PARA == rFrmFmt.GetAnchor().GetAnchorId()) ||
+ (FLY_AT_CHAR == rFrmFmt.GetAnchor().GetAnchorId())) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_SURROUND, TRUE, &pItem ))
+ {
+ const SwFmtSurround* pSurround = (const SwFmtSurround*)pItem;
+ sal_Int16 eHoriOri = rFrmFmt.GetHoriOrient().GetHoriOrient();
+ pStr = 0;
+ SwSurround eSurround = pSurround->GetSurround();
+ BOOL bAnchorOnly = pSurround->IsAnchorOnly();
+ switch( eHoriOri )
+ {
+ case text::HoriOrientation::RIGHT:
+ {
+ switch( eSurround )
+ {
+ case SURROUND_NONE:
+ case SURROUND_RIGHT:
+ pStr = OOO_STRING_SVTOOLS_HTML_AL_right;
+ break;
+ case SURROUND_LEFT:
+ case SURROUND_PARALLEL:
+ if( bAnchorOnly )
+ bClearRight = TRUE;
+ break;
+ default:
+ ;
+ }
+ }
+ break;
+
+ default:
+ // #67508#: If a frame is centered, it gets left aligned. This
+ // should be taken into account here, too.
+ {
+ switch( eSurround )
+ {
+ case SURROUND_NONE:
+ case SURROUND_LEFT:
+ pStr = OOO_STRING_SVTOOLS_HTML_AL_left;
+ break;
+ case SURROUND_RIGHT:
+ case SURROUND_PARALLEL:
+ if( bAnchorOnly )
+ bClearLeft = TRUE;
+ break;
+ default:
+ ;
+ }
+ }
+ break;
+
+ }
+
+ if( pStr )
+ {
+ (((((((sOut = '<') += OOO_STRING_SVTOOLS_HTML_linebreak) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_clear) += '=') += pStr) += '>') += rEndTags;
+ rEndTags = sOut;
+ }
+ }
+}
+
+
+Writer& OutHTML_Image( Writer& rWrt, const SwFrmFmt &rFrmFmt,
+ const String &rGrfName, const String& rAlternateTxt,
+ const Size &rRealSize, sal_uInt32 nFrmOpts,
+ const sal_Char *pMarkType,
+ const ImageMap *pAltImgMap )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // ggf. ein noch offenes Attribut voruebergehend beenden
+ if( rHTMLWrt.aINetFmts.Count() )
+ {
+ SwFmtINetFmt *pINetFmt =
+ rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
+ OutHTML_INetFmt( rWrt, *pINetFmt, FALSE );
+ }
+
+ String aGrfNm( rGrfName );
+ if( !HTMLOutFuncs::PrivateURLToInternalImg(aGrfNm) )
+ aGrfNm = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), aGrfNm);
+
+ const SfxPoolItem* pItem;
+ const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
+
+ const SwFmtURL *pURLItem = 0;
+
+ // das URL-Attribut nur beruecksichtigen, wenn keine Image-Map
+ // uebergeben wurde
+ if( !pAltImgMap &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_URL, TRUE, &pItem ))
+ {
+ pURLItem = (const SwFmtURL *)pItem;
+ }
+
+ // Image-Map rausschreiben
+ const ImageMap *pIMap = pAltImgMap;
+ if( !pIMap && pURLItem )
+ {
+ pIMap = pURLItem->GetMap();
+ }
+
+ String aIMapName;
+ if( pIMap )
+ {
+ // den Namen eindeutig machen
+ aIMapName = pIMap->GetName();
+ String aNameBase;
+ if( aIMapName.Len() )
+ aNameBase = aIMapName;
+ else
+ aNameBase.AssignAscii( OOO_STRING_SVTOOLS_HTML_map );
+ if( !aIMapName.Len() )
+ (aIMapName = aNameBase)
+ += String::CreateFromInt32( rHTMLWrt.nImgMapCnt );
+
+ BOOL bFound;
+ do
+ {
+ bFound = FALSE;
+ for( USHORT i=0; i<rHTMLWrt.aImgMapNames.Count(); i++ )
+ {
+ // TODO: Unicode: Comparison is case insensitive for ASCII
+ // characters only now!
+ if( aIMapName.EqualsIgnoreCaseAscii(*rHTMLWrt.aImgMapNames[i]) )
+ {
+ bFound = TRUE;
+ break;
+ }
+ }
+ if( bFound )
+ {
+ rHTMLWrt.nImgMapCnt++;
+ (aIMapName = aNameBase)
+ += String::CreateFromInt32( rHTMLWrt.nImgMapCnt );
+ }
+
+ } while( bFound );
+
+ BOOL bScale = FALSE;
+ //Size aGrfSize( rNode.GetTwipSize() );
+ Fraction aScaleX( 1, 1 );
+ Fraction aScaleY( 1, 1 );
+
+ const SwFmtFrmSize& rFrmSize = rFrmFmt.GetFrmSize();
+ const SvxBoxItem& rBox = rFrmFmt.GetBox();
+
+ if( !rFrmSize.GetWidthPercent() && rRealSize.Width() )
+ {
+ SwTwips nWidth = rFrmSize.GetWidth();
+ nWidth -= ( rBox.CalcLineSpace(BOX_LINE_LEFT) +
+ rBox.CalcLineSpace(BOX_LINE_RIGHT) );
+
+ ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
+ if( nWidth<=0 ) // sollte nicht passieren
+ nWidth = 1;
+
+ if( rRealSize.Width() != nWidth )
+ {
+ aScaleX = Fraction( nWidth, rRealSize.Width() );
+ bScale = TRUE;
+ }
+ }
+ if( !rFrmSize.GetHeightPercent() && rRealSize.Height() )
+ {
+ SwTwips nHeight = rFrmSize.GetHeight();
+ nHeight -= ( rBox.CalcLineSpace(BOX_LINE_TOP) +
+ rBox.CalcLineSpace(BOX_LINE_BOTTOM) );
+
+ ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
+ if( nHeight<=0 )
+ nHeight = 1;
+
+ if( rRealSize.Height() != nHeight )
+ {
+ aScaleY = Fraction( nHeight, rRealSize.Height() );
+ bScale = TRUE;
+ }
+ }
+
+ rHTMLWrt.aImgMapNames.Insert( new String(aIMapName),
+ rHTMLWrt.aImgMapNames.Count() );
+
+ ByteString aIndMap, aIndArea;
+ const sal_Char *pLF = 0, *pIndArea = 0, *pIndMap = 0;
+#if defined(UNX)
+ sal_Char aLF[2] = "\x00";
+#endif
+
+ if( rHTMLWrt.bLFPossible )
+ {
+ rHTMLWrt.OutNewLine( TRUE );
+ rHTMLWrt.GetIndentString( aIndMap );
+ rHTMLWrt.GetIndentString( aIndArea, 1 );
+#if defined(UNX)
+ aLF[0] = SwHTMLWriter::sNewLine;
+ pLF = aLF;
+#else
+ pLF = SwHTMLWriter::sNewLine;
+#endif
+ pIndArea = aIndArea.GetBuffer();
+ pIndMap = aIndMap.GetBuffer();
+ }
+
+ if( bScale )
+ {
+ ImageMap aScaledIMap( *pIMap );
+ aScaledIMap.Scale( aScaleX, aScaleY );
+ HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), aScaledIMap, aIMapName,
+ aIMapEventTable,
+ rHTMLWrt.bCfgStarBasic,
+ pLF, pIndArea, pIndMap,
+ rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ }
+ else
+ {
+ HTMLOutFuncs::Out_ImageMap( rWrt.Strm(), rWrt.GetBaseURL(), *pIMap, aIMapName,
+ aIMapEventTable,
+ rHTMLWrt.bCfgStarBasic,
+ pLF, pIndArea, pIndMap,
+ rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ }
+ }
+
+ // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( TRUE );
+
+ // Attribute die ausserhelb der Grafik geschreiben werden muessen sammeln
+ ByteString sOut;
+ ByteString aEndTags;
+
+ // implizite Sprungmarke -> <A NAME=...></A>...<IMG ...>
+ if( pMarkType && rFrmFmt.GetName().Len() )
+ rHTMLWrt.OutImplicitMark( rFrmFmt.GetName(), pMarkType );
+
+ // URL -> <A>...<IMG ... >...</A>
+ const SvxMacroItem *pMacItem = 0;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRMMACRO, TRUE, &pItem ))
+ pMacItem = (const SvxMacroItem *)pItem;
+
+ if( pURLItem || pMacItem )
+ {
+ String aMapURL;
+ String aName;
+ String aTarget;
+ if( pURLItem )
+ {
+ aMapURL = pURLItem->GetURL();
+ aName = pURLItem->GetName();
+ aTarget = pURLItem->GetTargetFrameName();
+ }
+ BOOL bEvents = pMacItem && pMacItem->GetMacroTable().Count();
+
+ if( aMapURL.Len() || aName.Len() || aTarget.Len() || bEvents )
+ {
+ (sOut = '<') += OOO_STRING_SVTOOLS_HTML_anchor;
+
+ // Ein HREF nur Ausgaben, wenn es einen Link oder Makros gibt
+ if( aMapURL.Len() || bEvents )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ rHTMLWrt.OutHyperlinkHRefValue( aMapURL );
+ sOut = '\"';
+ }
+
+ if( aName.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aName,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ if( aTarget.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aTarget,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ if( sOut.Len() )
+ {
+ rWrt.Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ }
+
+ if( pMacItem )
+ {
+ const SvxMacroTableDtor& rMacTable = pMacItem->GetMacroTable();
+ if( rMacTable.Count() )
+ HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable,
+ aAnchorEventTable,
+ rHTMLWrt.bCfgStarBasic,
+ rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ }
+
+ rWrt.Strm() << ">";
+ (((sOut = "</") += OOO_STRING_SVTOOLS_HTML_anchor) += ">") += aEndTags;
+ aEndTags = sOut;
+ }
+ }
+
+ // Umrandung -> <FONT COLOR = ...>...<IMG ... >...</FONT>
+ USHORT nBorderWidth = 0;
+ if( (nFrmOpts & HTML_FRMOPT_BORDER) &&
+ SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, TRUE, &pItem ))
+ {
+ Size aTwipBorder( 0, 0 );
+ const SvxBoxItem* pBoxItem = (const SvxBoxItem*)pItem;
+
+ const SvxBorderLine *pColBorderLine = 0;
+ const SvxBorderLine *pBorderLine = pBoxItem->GetLeft();
+ if( pBorderLine )
+ {
+ pColBorderLine = pBorderLine;
+ aTwipBorder.Width() += pBorderLine->GetOutWidth();
+ }
+
+ pBorderLine = pBoxItem->GetRight();
+ if( pBorderLine )
+ {
+ pColBorderLine = pBorderLine;
+ aTwipBorder.Width() += pBorderLine->GetOutWidth();
+ }
+
+ pBorderLine = pBoxItem->GetTop();
+ if( pBorderLine )
+ {
+ pColBorderLine = pBorderLine;
+ aTwipBorder.Height() += pBorderLine->GetOutWidth();
+ }
+
+ pBorderLine = pBoxItem->GetBottom();
+ if( pBorderLine )
+ {
+ pColBorderLine = pBorderLine;
+ aTwipBorder.Height() += pBorderLine->GetOutWidth();
+ }
+
+ aTwipBorder.Width() /= 2;
+ aTwipBorder.Height() /= 2;
+
+ if( (aTwipBorder.Width() || aTwipBorder.Height()) &&
+ Application::GetDefaultDevice() )
+ {
+ Size aPixelBorder =
+ Application::GetDefaultDevice()->LogicToPixel( aTwipBorder,
+ MapMode(MAP_TWIP) );
+ if( !aPixelBorder.Width() && aTwipBorder.Width() )
+ aPixelBorder.Width() = 1;
+ if( !aPixelBorder.Height() && aTwipBorder.Height() )
+ aPixelBorder.Height() = 1;
+
+ if( aPixelBorder.Width() )
+ aPixelBorder.Height() = 0;
+
+ nBorderWidth =
+ (USHORT)(aPixelBorder.Width() + aPixelBorder.Height());
+ }
+
+ if( pColBorderLine )
+ {
+ sOut = '<';
+ (((sOut += OOO_STRING_SVTOOLS_HTML_font) += ' ') += OOO_STRING_SVTOOLS_HTML_O_color) += '=';
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_Color( rWrt.Strm(),
+ pColBorderLine->GetColor(), rHTMLWrt.eDestEnc ) << '>';
+
+ (((sOut = "</" ) += OOO_STRING_SVTOOLS_HTML_font) += '>') += aEndTags;
+ aEndTags = sOut;
+ }
+ }
+
+ sOut = '<';
+ (((sOut += OOO_STRING_SVTOOLS_HTML_image) += ' ') += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aGrfNm, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << '\"';
+
+ // Events
+ sOut.Erase();
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRMMACRO, TRUE, &pItem ))
+ {
+ const SvxMacroTableDtor& rMacTable =
+ ((const SvxMacroItem *)pItem)->GetMacroTable();
+ if( rMacTable.Count() )
+ HTMLOutFuncs::Out_Events( rWrt.Strm(), rMacTable, aImageEventTable,
+ rHTMLWrt.bCfgStarBasic, rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ }
+
+ // ALT, ALIGN, WIDTH, HEIGHT, HSPACE, VSPACE
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, rAlternateTxt, aEndTags, nFrmOpts );
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) )
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmOpts );
+
+
+ if( nFrmOpts & HTML_FRMOPT_BORDER )
+ {
+ (((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_border) += '=')
+ += ByteString::CreateFromInt32( nBorderWidth );
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+
+ if( pURLItem && pURLItem->IsServerMap() )
+ {
+ (sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_ismap;
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+ if( aIMapName.Len() )
+ {
+ ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_usemap) += "=\"#";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aIMapName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << '\"';
+ }
+
+ rHTMLWrt.Strm() << '>';
+
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ if( rHTMLWrt.aINetFmts.Count() )
+ {
+ // es ist noch ein Attribut auf dem Stack, das wieder geoeffnet
+ // werden muss
+ SwFmtINetFmt *pINetFmt =
+ rHTMLWrt.aINetFmts[ rHTMLWrt.aINetFmts.Count()-1 ];
+ OutHTML_INetFmt( rWrt, *pINetFmt, TRUE );
+ }
+
+ return rHTMLWrt;
+}
+
+Writer& OutHTML_BulletImage( Writer& rWrt,
+ const sal_Char *pTag,
+ const SvxBrushItem* pBrush,
+ String &rGrfName,
+ const Size &rSize,
+ const SwFmtVertOrient* pVertOrient )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // Wenn es ein BrushItem gibt, muss die Grafiknoch exportiert werden
+ const String *pLink = 0;
+ if( pBrush )
+ {
+ pLink = pBrush->GetGraphicLink();
+
+ // embeddete Grafik -> WriteEmbedded schreiben
+ if( !pLink )
+ {
+ const Graphic* pGrf = pBrush->GetGraphic();
+ if( pGrf )
+ {
+ // Grafik als (JPG-)File speichern
+ if( rHTMLWrt.GetOrigFileName() )
+ rGrfName = *rHTMLWrt.GetOrigFileName();
+ USHORT nErr = XOutBitmap::WriteGraphic( *pGrf, rGrfName,
+ String::CreateFromAscii("JPG"),
+ (XOUTBMP_USE_GIF_IF_SENSIBLE |
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE));
+ if( !nErr )
+ {
+ rGrfName = URIHelper::SmartRel2Abs(
+ INetURLObject( rWrt.GetBaseURL() ), rGrfName,
+ URIHelper::GetMaybeFileHdl() );
+ pLink = &rGrfName;
+ }
+ else
+ {
+ rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ }
+ }
+ }
+ else
+ {
+ rGrfName = *pLink;
+ if( rHTMLWrt.bCfgCpyLinkedGrfs )
+ {
+ rHTMLWrt.CopyLocalFileToINet( rGrfName );
+ pLink = &rGrfName;
+ }
+ }
+ }
+ else
+ {
+ pLink = &rGrfName;
+ }
+
+ ByteString sOut;
+ if( pTag )
+ (sOut += '<') += pTag;
+
+ if( pLink )
+ {
+ sOut += ' ';
+ String s( *pLink );
+ if( !HTMLOutFuncs::PrivateURLToInternalImg(s) )
+ s = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), s);
+ (sOut += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), s, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+
+ // Groesse des Objekts Twips ohne Raender
+ Size aPixelSz( 0, 0 );
+ if( (rSize.Width() || rSize.Height()) && Application::GetDefaultDevice() )
+ {
+ aPixelSz =
+ Application::GetDefaultDevice()->LogicToPixel( rSize,
+ MapMode(MAP_TWIP) );
+ if( !aPixelSz.Width() && rSize.Width() )
+ aPixelSz.Width() = 1;
+ if( !aPixelSz.Height() && rSize.Height() )
+ aPixelSz.Height() = 1;
+ }
+
+ if( aPixelSz.Width() )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=')
+ += ByteString::CreateFromInt32( aPixelSz.Width() );
+
+ if( aPixelSz.Height() )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
+ += ByteString::CreateFromInt32( aPixelSz.Height() );
+
+ if( pVertOrient )
+ {
+ const sal_Char *pStr = 0;
+ switch( pVertOrient->GetVertOrient() )
+ {
+ case text::VertOrientation::LINE_TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_top; break;
+ case text::VertOrientation::CHAR_TOP:
+ case text::VertOrientation::BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_texttop; break; // geht nicht
+ case text::VertOrientation::LINE_CENTER:
+ case text::VertOrientation::CHAR_CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_absmiddle; break; // geht nicht
+ case text::VertOrientation::CENTER: pStr = OOO_STRING_SVTOOLS_HTML_VA_middle; break;
+ case text::VertOrientation::LINE_BOTTOM:
+ case text::VertOrientation::CHAR_BOTTOM: pStr = OOO_STRING_SVTOOLS_HTML_VA_absbottom; break; // geht nicht
+ case text::VertOrientation::TOP: pStr = OOO_STRING_SVTOOLS_HTML_VA_bottom; break;
+ case text::VertOrientation::NONE: break;
+ }
+ if( pStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += pStr;
+ }
+ }
+
+ if( pTag )
+ sOut += '>';
+ rWrt.Strm() << sOut.GetBuffer();
+
+ return rWrt;
+}
+
+
+//-----------------------------------------------------------------------
+
+static Writer& OutHTML_FrmFmtTableNode( Writer& rWrt, const SwFrmFmt& rFrmFmt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
+ ULONG nEnd = rHTMLWrt.pDoc->GetNodes()[nStt-1]->EndOfSectionIndex();
+
+ String aCaption;
+ BOOL bTopCaption = FALSE;
+
+ // Nicht const, weil GetTable spater mal nicht const ist
+ SwNode *pNd = rHTMLWrt.pDoc->GetNodes()[ nStt ];
+ SwTableNode *pTblNd = pNd->GetTableNode();
+ const SwTxtNode *pTxtNd = pNd->GetTxtNode();
+ if( !pTblNd && pTxtNd )
+ {
+ // Tabelle mit Ueberschrift
+ bTopCaption = TRUE;
+ pTblNd = rHTMLWrt.pDoc->GetNodes()[nStt+1]->GetTableNode();
+ }
+ ASSERT( pTblNd, "Rahmen enthaelt keine Tabelle" );
+ if( pTblNd )
+ {
+ ULONG nTblEnd = pTblNd->EndOfSectionIndex();
+ ASSERT( nTblEnd == nEnd - 1 ||
+ (nTblEnd == nEnd - 2 && !bTopCaption),
+ "Ungeuelter Rahmen-Inhalt fuer Tabelle" );
+
+ if( nTblEnd == nEnd - 2 )
+ pTxtNd = rHTMLWrt.pDoc->GetNodes()[nTblEnd+1]->GetTxtNode();
+ }
+ if( pTxtNd )
+ aCaption = pTxtNd->GetTxt();
+
+ {
+ HTMLSaveData aSaveData( rHTMLWrt, pTblNd->GetIndex()+1,
+ pTblNd->EndOfSectionIndex(),
+ sal_True, &rFrmFmt );
+ rHTMLWrt.bOutFlyFrame = sal_True;
+ OutHTML_SwTblNode( rHTMLWrt, *pTblNd, &rFrmFmt, &aCaption,
+ bTopCaption );
+ }
+
+ return rWrt;
+}
+
+static Writer & OutHTML_FrmFmtAsMulticol( Writer& rWrt,
+ const SwFrmFmt& rFrmFmt,
+ BOOL bInCntnr )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ rHTMLWrt.ChangeParaToken( 0 );
+
+ // Die aktulle <DL> beenden!
+ rHTMLWrt.OutAndSetDefList( 0 );
+
+ // als Multicol ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_multicol;
+
+ const SwFmtCol& rFmtCol = rFrmFmt.GetCol();
+
+ // die Anzahl der Spalten als COLS ausgeben
+ USHORT nCols = rFmtCol.GetNumCols();
+ if( nCols )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=')
+ += ByteString::CreateFromInt32( nCols );
+
+ // die Gutter-Breite (Minimalwert) als GUTTER
+ USHORT nGutter = rFmtCol.GetGutterWidth( TRUE );
+ if( nGutter!=USHRT_MAX )
+ {
+ if( nGutter && Application::GetDefaultDevice() )
+ {
+ nGutter = (USHORT)Application::GetDefaultDevice()
+ ->LogicToPixel( Size(nGutter,0),
+ MapMode(MAP_TWIP) ).Width();
+ }
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_gutter) += '=')
+ += ByteString::CreateFromInt32( nGutter );
+ }
+
+ rWrt.Strm() << sOut.GetBuffer();
+
+ // WIDTH
+ ULONG nFrmFlags = bInCntnr ? HTML_FRMOPTS_MULTICOL_CNTNR
+ : HTML_FRMOPTS_MULTICOL;
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
+ nFrmFlags |= HTML_FRMOPTS_MULTICOL_CSS1;
+ ByteString aEndTags;
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags, nFrmFlags );
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags );
+
+ rWrt.Strm() << '>';
+
+ rHTMLWrt.bLFPossible = TRUE;
+ rHTMLWrt.IncIndentLevel(); // den Inhalt von Multicol einruecken;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
+ const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
+ ASSERT( pSttNd, "Wo ist der Start-Node" );
+
+ {
+ // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
+ // wieder hergestellt wird.
+ HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
+ pSttNd->EndOfSectionIndex(),
+ sal_True, &rFrmFmt );
+ rHTMLWrt.bOutFlyFrame = sal_True;
+ rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
+ }
+
+// rHTMLWrt.ChangeParaToken( 0 ); // MIB 8.7.97: Passiert jetzt in Out_SwDoc
+
+ rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_multicol, FALSE );
+ rHTMLWrt.bLFPossible = TRUE;
+
+ return rWrt;
+}
+
+static Writer& OutHTML_FrmFmtAsSpacer( Writer& rWrt, const SwFrmFmt& rFrmFmt )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // wenn meoglich vor der Grafik einen Zeilen-Umbruch ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( TRUE );
+
+ ByteString sOut('<');
+ ((((sOut += OOO_STRING_SVTOOLS_HTML_spacer) += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=')
+ += OOO_STRING_SVTOOLS_HTML_SPTYPE_block;
+ rWrt.Strm() << sOut.GetBuffer();
+
+ // ALIGN, WIDTH, HEIGHT
+ ByteString aEndTags;
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags,
+ HTML_FRMOPTS_SPACER );
+
+ rWrt.Strm() << '>';
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ return rWrt;
+}
+
+static Writer& OutHTML_FrmFmtAsDivOrSpan( Writer& rWrt,
+ const SwFrmFmt& rFrmFmt, BOOL bSpan)
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const sal_Char *pStr = 0;
+ if( !bSpan )
+ {
+ rHTMLWrt.ChangeParaToken( 0 );
+
+ // Die aktulle <DL> beenden!
+ rHTMLWrt.OutAndSetDefList( 0 );
+ pStr = OOO_STRING_SVTOOLS_HTML_division;
+ }
+ else
+ pStr = OOO_STRING_SVTOOLS_HTML_span;
+
+ // als DIV ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+
+ ByteString sOut( '<' );
+ sOut += pStr;
+
+ rWrt.Strm() << sOut.GetBuffer();
+ ByteString aEndTags;
+ ULONG nFrmFlags = HTML_FRMOPTS_DIV;
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_BORDER_NONE ) )
+ nFrmFlags |= HTML_FRMOPT_S_NOBORDER;
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, aEmptyStr, aEndTags, nFrmFlags );
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmFlags );
+ rWrt.Strm() << '>';
+
+ rHTMLWrt.IncIndentLevel(); // den Inhalt einruecken
+ rHTMLWrt.bLFPossible = TRUE;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
+
+ // Am Start-Node verankerte Rahmen-gebundene Rahmen ausgeben
+ rHTMLWrt.OutFlyFrm( nStt, 0, HTML_POS_ANY );
+
+ const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
+ ASSERT( pSttNd, "Wo ist der Start-Node" );
+
+ {
+ // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
+ // wieder hergestellt wird.
+ HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
+ pSttNd->EndOfSectionIndex(),
+ sal_True, &rFrmFmt );
+ rHTMLWrt.bOutFlyFrame = sal_True;
+ rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
+ }
+
+ rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, FALSE );
+
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ return rWrt;
+}
+
+static Writer & OutHTML_FrmFmtAsImage( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ BOOL /*bInCntnr*/ )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ ImageMap aIMap;
+ Graphic aGrf( ((SwFrmFmt &)rFrmFmt).MakeGraphic( &aIMap ) );
+
+ String aGrfNm;
+ if( rHTMLWrt.GetOrigFileName() )
+ aGrfNm = *rHTMLWrt.GetOrigFileName();
+ if( aGrf.GetType() == GRAPHIC_NONE ||
+ XOutBitmap::WriteGraphic( aGrf, aGrfNm,
+ String::CreateFromAscii( "JPG" ),
+ (XOUTBMP_USE_GIF_IF_POSSIBLE|
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE) ) != 0 )
+ {
+ // leer oder fehlerhaft, da ist nichts auszugeben
+ rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ return rWrt;
+ }
+
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(rWrt.GetBaseURL()), aGrfNm,
+ URIHelper::GetMaybeFileHdl() );
+ Size aSz( 0, 0 );
+ OutHTML_Image( rWrt, rFrmFmt, aGrfNm, rFrmFmt.GetName(), aSz,
+ HTML_FRMOPTS_GENIMG, pMarkToFrame,
+ aIMap.GetIMapObjectCount() ? &aIMap : 0 );
+ return rWrt;
+}
+
+
+static Writer& OutHTML_FrmFmtGrfNode( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ BOOL bInCntnr )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
+ SwGrfNode *pGrfNd = rHTMLWrt.pDoc->GetNodes()[ nStt ]->GetGrfNode();
+ ASSERT( pGrfNd, "Grf-Node erwartet" );
+ if( !pGrfNd )
+ return rWrt;
+
+ const SwMirrorGrf& rMirror = pGrfNd->GetSwAttrSet().GetMirrorGrf();
+
+ String aGrfNm;
+ if( !pGrfNd->IsLinkedFile() || RES_MIRROR_GRAPH_DONT != rMirror.GetValue() )
+ {
+ // Grafik als File-Referenz speichern (als JPEG-Grafik speichern)
+ if( rHTMLWrt.GetOrigFileName() )
+ aGrfNm = *rHTMLWrt.GetOrigFileName();
+ pGrfNd->SwapIn( TRUE );
+
+ ULONG nFlags = XOUTBMP_USE_GIF_IF_SENSIBLE |
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE;
+ switch( rMirror.GetValue() )
+ {
+ case RES_MIRROR_GRAPH_VERT: nFlags = XOUTBMP_MIRROR_HORZ; break;
+ case RES_MIRROR_GRAPH_HOR: nFlags = XOUTBMP_MIRROR_VERT; break;
+ case RES_MIRROR_GRAPH_BOTH:
+ nFlags = XOUTBMP_MIRROR_VERT | XOUTBMP_MIRROR_HORZ;
+ break;
+ }
+
+ Size aMM100Size;
+ const SwFmtFrmSize& rSize = rFrmFmt.GetFrmSize();
+ aMM100Size = OutputDevice::LogicToLogic( rSize.GetSize(),
+ MapMode( MAP_TWIP ), MapMode( MAP_100TH_MM ));
+
+ USHORT nErr = XOutBitmap::WriteGraphic( pGrfNd->GetGrf(), aGrfNm,
+ String::CreateFromAscii("JPG"), nFlags, &aMM100Size );
+ if( nErr ) // fehlerhaft, da ist nichts auszugeben
+ {
+ rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ return rWrt;
+ }
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(rWrt.GetBaseURL()), aGrfNm,
+ URIHelper::GetMaybeFileHdl() );
+ }
+ else
+ {
+ pGrfNd->GetFileFilterNms( &aGrfNm, 0 );
+ if( rHTMLWrt.bCfgCpyLinkedGrfs )
+ rWrt.CopyLocalFileToINet( aGrfNm );
+ }
+
+ ULONG nFrmFlags = bInCntnr ? HTML_FRMOPTS_IMG_CNTNR : HTML_FRMOPTS_IMG;
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bInCntnr )
+ nFrmFlags |= HTML_FRMOPTS_IMG_CSS1;
+ OutHTML_Image( rWrt, rFrmFmt, aGrfNm, pGrfNd->GetTitle(),
+ pGrfNd->GetTwipSize(), nFrmFlags, pMarkToGraphic );
+
+ return rWrt;
+}
+
+
+static Writer& OutHTML_FrmFmtAsMarquee( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ const SdrObject& rSdrObj )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // die Edit-Engine-Attribute des Objekts als SW-Attribute holen
+ // und als Hints einsortieren
+ const SfxItemSet& rFmtItemSet = rFrmFmt.GetAttrSet();
+ SfxItemSet aItemSet( *rFmtItemSet.GetPool(), RES_CHRATR_BEGIN,
+ RES_CHRATR_END );
+ SwHTMLWriter::GetEEAttrsFromDrwObj( aItemSet, &rSdrObj, TRUE );
+ BOOL bCfgOutStylesOld = rHTMLWrt.bCfgOutStyles;
+ rHTMLWrt.bCfgOutStyles = FALSE;
+ rHTMLWrt.bTxtAttr = TRUE;
+ rHTMLWrt.bTagOn = TRUE;
+ Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, FALSE );
+ rHTMLWrt.bTxtAttr = FALSE;
+
+ OutHTML_DrawFrmFmtAsMarquee( rHTMLWrt,
+ (const SwDrawFrmFmt &)rFrmFmt,
+ rSdrObj );
+ rHTMLWrt.bTxtAttr = TRUE;
+ rHTMLWrt.bTagOn = FALSE;
+ Out_SfxItemSet( aHTMLAttrFnTab, rWrt, aItemSet, FALSE );
+ rHTMLWrt.bTxtAttr = FALSE;
+ rHTMLWrt.bCfgOutStyles = bCfgOutStylesOld;
+
+ return rWrt;
+}
+
+//-----------------------------------------------------------------------
+
+Writer& OutHTML_HeaderFooter( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ BOOL bHeader )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // als Multicol ausgeben
+ rHTMLWrt.OutNewLine();
+ ByteString sOut( OOO_STRING_SVTOOLS_HTML_division );
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=';
+ sOut += (bHeader ? "HEADER" : "FOOTER" );
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.GetBuffer() );
+
+ rHTMLWrt.IncIndentLevel(); // den Inhalt von Multicol einruecken;
+
+ // Einen Spacer fuer den Absatnd zusammenbasteln. Da durch das
+ // <DL> bzw. </DL> immer einer Absatz-Abstand entsteht, wird der
+ // ggf. abgezogen.
+ const SvxULSpaceItem& rULSpace = rFrmFmt.GetULSpace();
+ USHORT nSize = bHeader ? rULSpace.GetLower() : rULSpace.GetUpper();
+ rHTMLWrt.nHeaderFooterSpace = nSize;
+
+ ByteString aSpacer;
+ if( rHTMLWrt.IsHTMLMode(HTMLMODE_VERT_SPACER) &&
+ nSize > HTML_PARSPACE && Application::GetDefaultDevice() )
+ {
+ nSize -= HTML_PARSPACE;
+ nSize = (INT16)Application::GetDefaultDevice()
+ ->LogicToPixel( Size(nSize,0), MapMode(MAP_TWIP) ).Width();
+
+ ((((((((aSpacer = OOO_STRING_SVTOOLS_HTML_spacer) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_type) += '=') += OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_size) += '=') += ByteString::CreateFromInt32(nSize);
+ }
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
+ const SwStartNode* pSttNd = rWrt.pDoc->GetNodes()[nStt]->GetStartNode();
+ ASSERT( pSttNd, "Wo ist der Start-Node" );
+
+ if( !bHeader && aSpacer.Len() )
+ {
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), aSpacer.GetBuffer() );
+ }
+
+ {
+ // in einem Block damit rechtzeitig vor dem Ende der alte Zustand
+ // wieder hergestellt wird. pFlyFmt braucht hier nicht gestzt zu
+ // werden, denn PageDesc-Attribute koennen hier nicht vorkommen
+ HTMLSaveData aSaveData( rHTMLWrt, nStt+1,
+ pSttNd->EndOfSectionIndex() );
+
+ if( bHeader )
+ rHTMLWrt.bOutHeader = TRUE;
+ else
+ rHTMLWrt.bOutFooter = TRUE;
+
+ rHTMLWrt.Out_SwDoc( rWrt.pCurPam );
+ }
+
+ if( bHeader && aSpacer.Len() )
+ {
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), aSpacer.GetBuffer() );
+ }
+
+ rHTMLWrt.DecIndentLevel(); // den Inhalt von Multicol einruecken;
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_division, FALSE );
+
+ rHTMLWrt.nHeaderFooterSpace = 0;
+
+ return rWrt;
+}
+
+
+void SwHTMLWriter::AddLinkTarget( const String& rURL )
+{
+ if( !rURL.Len() || rURL.GetChar(0) != '#' )
+ return;
+
+ // There might be a '|' as delimiter (if the link has been inserted
+ // freshly) or a '%7c' or a '%7C' if the document has been saved and
+ // loaded already.
+ xub_StrLen nPos = rURL.Len();
+ sal_Bool bFound = sal_False, bEncoded = sal_False;
+ while( !bFound && nPos > 0 )
+ {
+ sal_Unicode c = rURL.GetChar( --nPos );
+ switch( c )
+ {
+ case cMarkSeperator:
+ bFound = sal_True;
+ break;
+ case '%':
+ bFound = (rURL.Len() - nPos) >=3 &&
+ rURL.GetChar( nPos+1 ) == '7' &&
+ ((c =rURL.GetChar( nPos+2 )) == 'C' || c == 'c');
+ if( bFound )
+ bEncoded = sal_True;
+ }
+ }
+ if( !bFound || nPos < 2 ) // mindetsens "#a|..."
+ return;
+
+ String aURL( rURL.Copy( 1 ) );
+
+ String sCmp( aURL.Copy( bEncoded ? nPos+2 : nPos ) ); // nPos-1+1/3 (-1 wg. Erase)
+ sCmp.EraseAllChars();
+ if( !sCmp.Len() )
+ return;
+
+ sCmp.ToLowerAscii();
+
+ if( sCmp.EqualsAscii( pMarkToRegion ) ||
+ sCmp.EqualsAscii( pMarkToFrame ) ||
+ sCmp.EqualsAscii( pMarkToGraphic ) ||
+ sCmp.EqualsAscii( pMarkToOLE ) ||
+ sCmp.EqualsAscii( pMarkToTable ) )
+ {
+ // Einfach nur in einem sortierten Array merken
+ if( bEncoded )
+ {
+ aURL.Erase( nPos, 2 );
+ aURL.SetChar( nPos-1, cMarkSeperator );
+ }
+ aImplicitMarks.Insert( new String( aURL ) );
+ }
+ else if( sCmp.EqualsAscii( pMarkToOutline ) )
+ {
+ // Hier brauchen wir Position und Name. Deshalb sortieren wir
+ // ein USHORT und ein String-Array selbst
+ String aOutline( aURL.Copy( 0, nPos-1 ) );
+ SwPosition aPos( *pCurPam->GetPoint() );
+ if( pDoc->GotoOutline( aPos, aOutline ) )
+ {
+ ULONG nIdx = aPos.nNode.GetIndex();
+
+ USHORT nIns=0;
+ while( nIns < aOutlineMarkPoss.Count() &&
+ aOutlineMarkPoss[nIns] < nIdx )
+ nIns++;
+
+ aOutlineMarkPoss.Insert( nIdx, nIns );
+ if( bEncoded )
+ {
+ aURL.Erase( nPos, 2 );
+ aURL.SetChar( nPos-1, cMarkSeperator );
+ }
+ aOutlineMarks.Insert( new String( aURL ), nIns );
+ }
+ }
+ else if( sCmp.EqualsAscii( pMarkToText ) )
+ {
+ //
+ }
+}
+
+void SwHTMLWriter::CollectLinkTargets()
+{
+ const SwFmtINetFmt* pINetFmt;
+ const SwTxtINetFmt* pTxtAttr;
+ const SwTxtNode* pTxtNd;
+
+ USHORT n, nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_TXTATR_INETFMT );
+ for( n = 0; n < nMaxItems; ++n )
+ {
+ if( 0 != (pINetFmt = (SwFmtINetFmt*)pDoc->GetAttrPool().GetItem(
+ RES_TXTATR_INETFMT, n ) ) &&
+ 0 != ( pTxtAttr = pINetFmt->GetTxtINetFmt()) &&
+ 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
+ pTxtNd->GetNodes().IsDocNodes() )
+ {
+ AddLinkTarget( pINetFmt->GetValue() );
+ }
+ }
+
+ const SwFmtURL *pURL;
+ nMaxItems = pDoc->GetAttrPool().GetItemCount( RES_URL );
+ for( n = 0; n < nMaxItems; ++n )
+ {
+ if( 0 != (pURL = (SwFmtURL*)pDoc->GetAttrPool().GetItem(
+ RES_URL, n ) ) )
+ {
+ AddLinkTarget( pURL->GetURL() );
+ const ImageMap *pIMap = pURL->GetMap();
+ if( pIMap )
+ {
+ for( USHORT i=0; i<pIMap->GetIMapObjectCount(); i++ )
+ {
+ const IMapObject* pObj = pIMap->GetIMapObject( i );
+ if( pObj )
+ {
+ AddLinkTarget( pObj->GetURL() );
+ }
+ }
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------
+
+SwHTMLPosFlyFrm::SwHTMLPosFlyFrm( const SwPosFlyFrm& rPosFly,
+ const SdrObject *pSdrObj,
+ BYTE nOutMode ) :
+ pFrmFmt( &rPosFly.GetFmt() ),
+ pSdrObject( pSdrObj ),
+ pNdIdx( new SwNodeIndex( rPosFly.GetNdIndex() ) ),
+ nOrdNum( rPosFly.GetOrdNum() ),
+ nCntntIdx( 0 ),
+ nOutputMode( nOutMode )
+{
+ const SwFmtAnchor& rAnchor = rPosFly.GetFmt().GetAnchor();
+ if ((FLY_AT_CHAR == rAnchor.GetAnchorId()) &&
+ HTML_POS_INSIDE == GetOutPos() )
+ {
+ // Auto-gebundene Rahmen werden ein Zeichen weiter hinten
+ // ausgegeben, weil dann die Positionierung mit Netscape
+ // uebereinstimmt.
+ ASSERT( rAnchor.GetCntntAnchor(), "Keine Anker-Position?" );
+ if( rAnchor.GetCntntAnchor() )
+ {
+ nCntntIdx = rAnchor.GetCntntAnchor()->nContent.GetIndex();
+ sal_Int16 eHoriRel = rPosFly.GetFmt().GetHoriOrient().
+ GetRelationOrient();
+ if( text::RelOrientation::FRAME == eHoriRel || text::RelOrientation::PRINT_AREA == eHoriRel )
+ {
+ const SwCntntNode *pCNd = pNdIdx->GetNode().GetCntntNode();
+ ASSERT( pCNd, "Kein Content-Node an PaM-Position" );
+ if( pCNd && nCntntIdx < pCNd->Len() )
+ nCntntIdx++;
+ }
+ }
+ }
+}
+
+BOOL SwHTMLPosFlyFrm::operator<( const SwHTMLPosFlyFrm& rFrm ) const
+{
+ if( pNdIdx->GetIndex() == rFrm.pNdIdx->GetIndex() )
+ {
+ if( nCntntIdx == rFrm.nCntntIdx )
+ {
+ if( GetOutPos() == rFrm.GetOutPos() )
+ return nOrdNum < rFrm.nOrdNum;
+ else
+ return GetOutPos() < rFrm.GetOutPos();
+ }
+ else
+ return nCntntIdx < rFrm.nCntntIdx;
+ }
+ else
+ return pNdIdx->GetIndex() < rFrm.pNdIdx->GetIndex();
+}
+
+
diff --git a/sw/source/filter/html/htmlfly.hxx b/sw/source/filter/html/htmlfly.hxx
new file mode 100644
index 000000000000..72a2dd4ba006
--- /dev/null
+++ b/sw/source/filter/html/htmlfly.hxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _HTMLFLY_HXX
+#define _HTMLFLY_HXX
+
+#include <tools/solar.h>
+#include <tools/string.hxx>
+
+#ifndef _SVARRAY_H
+#include <svl/svarray.hxx>
+#endif
+
+class SdrObject;
+class SwFrmFmt;
+class SwNodeIndex;
+class SwPosFlyFrm;
+
+// ACHTUNG: Die Werte dieses Enumgs gehen direkt in die
+// Augabe Tabelle!!!
+enum SwHTMLFrmType
+{
+ HTML_FRMTYPE_TABLE,
+ HTML_FRMTYPE_TABLE_CAP,
+ HTML_FRMTYPE_MULTICOL,
+ HTML_FRMTYPE_EMPTY,
+ HTML_FRMTYPE_TEXT,
+ HTML_FRMTYPE_GRF,
+ HTML_FRMTYPE_PLUGIN,
+ HTML_FRMTYPE_APPLET,
+ HTML_FRMTYPE_IFRAME,
+ HTML_FRMTYPE_OLE,
+ HTML_FRMTYPE_MARQUEE,
+ HTML_FRMTYPE_CONTROL,
+ HTML_FRMTYPE_DRAW,
+ HTML_FRMTYPE_END
+};
+
+#define HTML_OUT_TBLNODE 0x00
+#define HTML_OUT_GRFNODE 0x01
+#define HTML_OUT_OLENODE 0x02
+#define HTML_OUT_DIV 0x03
+#define HTML_OUT_MULTICOL 0x04
+#define HTML_OUT_SPACER 0x05
+#define HTML_OUT_CONTROL 0x06
+#define HTML_OUT_AMARQUEE 0x07
+#define HTML_OUT_MARQUEE 0x08
+#define HTML_OUT_GRFFRM 0x09
+#define HTML_OUT_OLEGRF 0x0a
+#define HTML_OUT_SPAN 0x0b
+#define HTML_OUT_MASK 0x0f
+
+#define HTML_POS_PREFIX 0x00
+#define HTML_POS_BEFORE 0x10
+#define HTML_POS_INSIDE 0x20
+#define HTML_POS_ANY 0x30
+#define HTML_POS_MASK 0x30
+
+#define HTML_CNTNR_NONE 0x00
+#define HTML_CNTNR_SPAN 0x40
+#define HTML_CNTNR_DIV 0x80
+#define HTML_CNTNR_MASK 0xc0
+
+
+const USHORT MAX_FRMTYPES = HTML_FRMTYPE_END;
+const USHORT MAX_BROWSERS = 4;
+
+extern BYTE aHTMLOutFrmPageFlyTable[MAX_FRMTYPES][MAX_BROWSERS];
+extern BYTE aHTMLOutFrmParaFrameTable[MAX_FRMTYPES][MAX_BROWSERS];
+extern BYTE aHTMLOutFrmParaPrtAreaTable[MAX_FRMTYPES][MAX_BROWSERS];
+extern BYTE aHTMLOutFrmParaOtherTable[MAX_FRMTYPES][MAX_BROWSERS];
+extern BYTE aHTMLOutFrmAsCharTable[MAX_FRMTYPES][MAX_BROWSERS];
+
+class SwHTMLPosFlyFrm
+{
+ const SwFrmFmt *pFrmFmt; // der Rahmen
+ const SdrObject *pSdrObject; // ggf. Sdr-Objekt
+ SwNodeIndex *pNdIdx; // Node-Index
+ UINT32 nOrdNum; // Aus SwPosFlyFrm
+ xub_StrLen nCntntIdx; // seine Position im Content
+ BYTE nOutputMode; // Ausgabe-Infos
+
+public:
+
+ SwHTMLPosFlyFrm( const SwPosFlyFrm& rPosFly,
+ const SdrObject *pSdrObj, BYTE nOutMode );
+
+ BOOL operator==( const SwHTMLPosFlyFrm& ) const { return FALSE; }
+ BOOL operator<( const SwHTMLPosFlyFrm& ) const;
+
+ const SwFrmFmt& GetFmt() const { return *pFrmFmt; }
+ const SdrObject *GetSdrObject() const { return pSdrObject; }
+
+ const SwNodeIndex& GetNdIndex() const { return *pNdIdx; }
+
+ xub_StrLen GetCntntIndex() const { return nCntntIdx; }
+
+ BYTE GetOutMode() const { return nOutputMode; }
+
+ static BYTE GetOutFn( BYTE nMode ) { return nMode & HTML_OUT_MASK; }
+ static BYTE GetOutPos( BYTE nMode ) { return nMode & HTML_POS_MASK; }
+ static BYTE GetOutCntnr( BYTE nMode ) { return nMode & HTML_CNTNR_MASK; }
+
+ BYTE GetOutFn() const { return nOutputMode & HTML_OUT_MASK; }
+ BYTE GetOutPos() const { return nOutputMode & HTML_POS_MASK; }
+ BYTE GetOutCntnr() const { return nOutputMode & HTML_CNTNR_MASK; }
+};
+
+typedef SwHTMLPosFlyFrm *SwHTMLPosFlyFrmPtr;
+SV_DECL_PTRARR_SORT( SwHTMLPosFlyFrms, SwHTMLPosFlyFrmPtr, 10, 10 )
+
+
+#endif
diff --git a/sw/source/filter/html/htmlflyt.cxx b/sw/source/filter/html/htmlflyt.cxx
new file mode 100644
index 000000000000..f3b80db509e5
--- /dev/null
+++ b/sw/source/filter/html/htmlflyt.cxx
@@ -0,0 +1,516 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "htmlfly.hxx"
+
+
+#define TE(t,p,c) (BYTE)( HTML_OUT_##t | HTML_POS_##p | HTML_CNTNR_##c )
+
+BYTE aHTMLOutFrmPageFlyTable[MAX_FRMTYPES][MAX_BROWSERS] =
+{
+ {
+ // Textrahmen mit Tabelle
+ TE(TBLNODE, BEFORE, NONE), // HTML 3.2
+ TE(DIV, PREFIX, NONE), // IE 4
+ TE(DIV, PREFIX, NONE), // SW
+ TE(DIV, PREFIX, NONE) // Netscape 4!
+ },
+ {
+ // Textrahmen mit Tabelle und Ueberschrift
+ TE(TBLNODE, BEFORE, NONE), // HTML 3.2
+ TE(DIV, PREFIX, NONE), // IE 4
+ TE(DIV, PREFIX, NONE), // SW
+ TE(DIV, PREFIX, NONE) // Netscape 4
+ },
+ {
+ // spaltiger Rahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, PREFIX, NONE), // IE 4
+ TE(MULTICOL,PREFIX, NONE), // SW
+ TE(MULTICOL,PREFIX, DIV) // Netscape 4
+ },
+ {
+ // leerer Textreahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(DIV, PREFIX, NONE), // IE 4
+ TE(DIV, PREFIX, NONE), // SW
+ TE(DIV, PREFIX, NONE) // Netscape 4
+ },
+ {
+ // sonstiger Textreahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(DIV, PREFIX, NONE), // IE 4
+ TE(DIV, PREFIX, NONE), // SW
+ TE(DIV, PREFIX, NONE) // Netscape 4
+ },
+ {
+ // Grafik-Node
+ TE(GRFNODE, INSIDE, NONE), // HTML 3.2
+ TE(GRFNODE, PREFIX, NONE), // IE 4
+ TE(GRFNODE, PREFIX, NONE), // SW
+ TE(GRFNODE, PREFIX, SPAN) // Netscape 4
+ },
+ {
+ // Plugin
+ TE(OLENODE, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, PREFIX, NONE), // IE 4
+ TE(OLENODE, PREFIX, NONE), // SW
+ TE(OLENODE, PREFIX, SPAN) // Netscape 4
+ },
+ {
+ // Applet
+ TE(OLENODE, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, PREFIX, NONE), // IE 4
+ TE(OLENODE, PREFIX, NONE), // SW
+ TE(OLENODE, PREFIX, SPAN) // Netscape 4
+ },
+ {
+ // Floating-Frame
+ TE(OLEGRF, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, PREFIX, NONE), // IE 4
+ TE(OLENODE, PREFIX, NONE), // SW
+ TE(OLEGRF, PREFIX, SPAN) // Netscape 4
+ },
+ {
+ // sonstige OLE-Objekte
+ TE(OLEGRF, INSIDE, NONE), // HTML 3.2
+ TE(OLEGRF, PREFIX, NONE), // IE 4
+ TE(OLEGRF, PREFIX, NONE), // SW
+ TE(OLEGRF, PREFIX, SPAN) // Netscape 4
+ },
+ {
+ // Laufschrift
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(AMARQUEE,PREFIX, NONE), // IE 4
+ TE(AMARQUEE,PREFIX, NONE), // SW
+ TE(GRFFRM, PREFIX, SPAN) // Netscape 4
+ },
+ {
+ // Controls
+ TE(CONTROL, INSIDE, NONE), // HTML 3.2
+ TE(CONTROL, PREFIX, NONE), // IE 4
+ TE(CONTROL, PREFIX, NONE), // SW
+ // Netscape schaltet FORM bei Controls in abs.-pos. SPAN aus.
+ TE(CONTROL, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstige Zeichen-Objekte
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, PREFIX, NONE), // IE 4
+ TE(GRFFRM, PREFIX, NONE), // SW
+ TE(GRFFRM, PREFIX, SPAN) // Netscape 4
+ }
+};
+
+BYTE aHTMLOutFrmParaFrameTable[MAX_FRMTYPES][MAX_BROWSERS] =
+{
+ {
+ // Textrahmen mit Tabelle
+ TE(TBLNODE, BEFORE, NONE), // HTML 3.2
+ TE(TBLNODE, BEFORE, NONE), // IE 4
+ TE(TBLNODE, BEFORE, NONE), // SW
+ TE(TBLNODE, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // Textrahmen mit Tabelle und Ueberschrift
+ TE(TBLNODE, BEFORE, NONE), // HTML 3.2
+ TE(DIV, BEFORE, NONE), // IE 4
+ TE(DIV, BEFORE, NONE), // SW
+ TE(TBLNODE, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // spaltiger Rahmen
+ TE(GRFFRM, BEFORE, NONE), // HTML 3.2
+ TE(GRFFRM, BEFORE, NONE), // IE 4
+ TE(MULTICOL,BEFORE, NONE), // SW
+ TE(MULTICOL,BEFORE, DIV) // Netscape 4
+ },
+ {
+ // leerer Textreahmen
+ TE(GRFFRM, BEFORE, NONE), // HTML 3.2
+ TE(DIV, BEFORE, NONE), // IE 4
+ TE(SPACER, BEFORE, NONE), // SW
+ TE(SPACER, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // sonstiger Textreahmen
+ TE(GRFFRM, BEFORE, NONE), // HTML 3.2
+ TE(DIV, BEFORE, NONE), // IE 4
+ TE(DIV, BEFORE, NONE), // SW
+ TE(DIV, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // Grafik-Node
+ TE(GRFNODE, BEFORE, NONE), // HTML 3.2
+ TE(GRFNODE, BEFORE, NONE), // IE 4
+ TE(GRFNODE, BEFORE, NONE), // SW
+ TE(GRFNODE, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // Plugin
+ TE(OLENODE, BEFORE, NONE), // HTML 3.2
+ TE(OLENODE, BEFORE, NONE), // IE 4
+ TE(OLENODE, BEFORE, NONE), // SW
+ TE(OLENODE, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // Applet
+ TE(OLENODE, BEFORE, NONE), // HTML 3.2
+ TE(OLENODE, BEFORE, NONE), // IE 4
+ TE(OLENODE, BEFORE, NONE), // SW
+ TE(OLENODE, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // Floating-Frame
+ TE(OLEGRF, BEFORE, NONE), // HTML 3.2
+ TE(OLENODE, BEFORE, NONE), // IE 4
+ TE(OLENODE, BEFORE, NONE), // SW
+ TE(OLEGRF, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // sonstige OLE-Objekte
+ TE(OLEGRF, BEFORE, NONE), // HTML 3.2
+ TE(OLEGRF, BEFORE, NONE), // IE 4
+ TE(OLEGRF, BEFORE, NONE), // SW
+ TE(OLEGRF, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // Laufschrift (fuer Netscape 4 im Container, damit
+ // die LAufschrift an der richtigen Stelle erscheint
+ TE(GRFFRM, BEFORE, NONE), // HTML 3.2
+ TE(AMARQUEE,BEFORE, NONE), // IE 4
+ TE(AMARQUEE,BEFORE, NONE), // SW
+ TE(GRFFRM, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // Controls
+ TE(CONTROL, INSIDE, NONE), // HTML 3.2
+ TE(CONTROL, BEFORE, NONE), // IE 4
+ TE(CONTROL, BEFORE, NONE), // SW
+ // hier koennte man einen Container draus machen (Import fehlt)
+ TE(CONTROL, BEFORE, NONE) // Netscape 4
+ },
+ {
+ // sonstige Zeichen-Objekte
+ TE(GRFFRM, BEFORE, NONE), // HTML 3.2
+ TE(GRFFRM, BEFORE, NONE), // IE 4
+ TE(GRFFRM, BEFORE, NONE), // SW
+ TE(GRFFRM, BEFORE, NONE) // Netscape 4
+ }
+};
+
+BYTE aHTMLOutFrmParaPrtAreaTable[MAX_FRMTYPES][MAX_BROWSERS] =
+{
+ {
+ // Textrahmen mit Tabelle
+ TE(TBLNODE, INSIDE, NONE), // HTML 3.2
+ TE(TBLNODE, INSIDE, NONE), // IE 4
+ TE(TBLNODE, INSIDE, NONE), // SW
+ TE(TBLNODE, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Textrahmen mit Tabelle und Ueberschrift
+ TE(TBLNODE, INSIDE, NONE), // HTML 3.2
+ TE(SPAN, INSIDE, NONE), // IE 4
+ TE(SPAN, INSIDE, NONE), // SW
+ TE(SPAN, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // spaltiger Rahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(MULTICOL,INSIDE, NONE), // SW
+ TE(MULTICOL,INSIDE, SPAN) // Netscape 4
+ },
+ {
+ // leerer Textreahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(SPAN, INSIDE, NONE), // IE 4
+ TE(SPACER, INSIDE, NONE), // SW
+ TE(SPACER, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstiger Textreahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(SPAN, INSIDE, NONE), // IE 4
+ TE(SPAN, INSIDE, NONE), // SW
+ TE(SPAN, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Grafik-Node
+ TE(GRFNODE, INSIDE, NONE), // HTML 3.2
+ TE(GRFNODE, INSIDE, NONE), // IE 4
+ TE(GRFNODE, INSIDE, NONE), // SW
+ TE(GRFNODE, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Plugin
+ TE(OLENODE, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLENODE, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Applet
+ TE(OLENODE, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLENODE, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Floating-Frame
+ TE(OLEGRF, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLEGRF, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstige OLE-Objekte
+ TE(OLEGRF, INSIDE, NONE), // HTML 3.2
+ TE(OLEGRF, INSIDE, NONE), // IE 4
+ TE(OLEGRF, INSIDE, NONE), // SW
+ TE(OLEGRF, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Laufschrift
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(AMARQUEE,INSIDE, NONE), // IE 4
+ TE(AMARQUEE,INSIDE, NONE), // SW
+ TE(GRFFRM, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Controls
+ TE(CONTROL, INSIDE, NONE), // HTML 3.2
+ TE(CONTROL, INSIDE, NONE), // IE 4
+ TE(CONTROL, INSIDE, NONE), // SW
+ // hier koennte man einen Container draus machen (Import fehlt)
+ TE(CONTROL, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstige Zeichen-Objekte
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(GRFFRM, INSIDE, NONE), // SW
+ TE(GRFFRM, INSIDE, NONE) // Netscape 4
+ }
+};
+
+BYTE aHTMLOutFrmParaOtherTable[MAX_FRMTYPES][MAX_BROWSERS] =
+{
+ {
+ // Textrahmen mit Tabelle
+ TE(TBLNODE, BEFORE, NONE), // HTML 3.2
+ TE(SPAN, INSIDE, NONE), // IE 4
+ TE(SPAN, INSIDE, NONE), // SW
+ TE(SPAN, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Textrahmen mit Tabelle und Ueberschrift
+ TE(TBLNODE, BEFORE, NONE), // HTML 3.2
+ TE(SPAN, INSIDE, NONE), // IE 4
+ TE(SPAN, INSIDE, NONE), // SW
+ TE(SPAN, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // spaltiger Rahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(MULTICOL,INSIDE, NONE), // SW
+ TE(MULTICOL,INSIDE, SPAN) // Netscape 4
+ },
+ {
+ // leerer Textreahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(SPAN, INSIDE, NONE), // IE 4
+ TE(SPAN, INSIDE, NONE), // SW
+ TE(SPAN, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstiger Textreahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(SPAN, INSIDE, NONE), // IE 4
+ TE(SPAN, INSIDE, NONE), // SW
+ TE(SPAN, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Grafik-Node
+ TE(GRFNODE, INSIDE, NONE), // HTML 3.2
+ TE(GRFNODE, INSIDE, NONE), // IE 4
+ TE(GRFNODE, INSIDE, NONE), // SW
+ TE(GRFNODE, INSIDE, SPAN) // Netscape 4
+ },
+ {
+ // Plugin
+ TE(OLENODE, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLENODE, INSIDE, SPAN) // Netscape 4
+ },
+ {
+ // Applet
+ TE(OLENODE, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLENODE, INSIDE, SPAN) // Netscape 4
+ },
+ {
+ // Floating-Frame
+ TE(OLEGRF, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLEGRF, INSIDE, SPAN) // Netscape 4
+ },
+ {
+ // sonstige OLE-Objekte
+ TE(OLEGRF, INSIDE, NONE), // HTML 3.2
+ TE(OLEGRF, INSIDE, NONE), // IE 4
+ TE(OLEGRF, INSIDE, NONE), // SW
+ TE(OLEGRF, INSIDE, SPAN) // Netscape 4
+ },
+ {
+ // Laufschrift
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(AMARQUEE,INSIDE, NONE), // IE 4
+ TE(AMARQUEE,INSIDE, NONE), // SW
+ TE(GRFFRM, INSIDE, SPAN) // Netscape 4
+ },
+ {
+ // Controls
+ TE(CONTROL, INSIDE, NONE), // HTML 3.2
+ TE(CONTROL, INSIDE, NONE), // IE 4
+ TE(CONTROL, INSIDE, NONE), // SW
+ // Netscape schaltet FORM bei Controls in abs.-pos. SPAN aus.
+ TE(CONTROL, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstige Zeichen-Objekte
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(GRFFRM, INSIDE, NONE), // SW
+ TE(GRFFRM, INSIDE, SPAN) // Netscape 4
+ }
+};
+
+BYTE aHTMLOutFrmAsCharTable[MAX_FRMTYPES][MAX_BROWSERS] =
+{
+ {
+ // Textrahmen mit Tabelle
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(GRFFRM, INSIDE, NONE), // SW
+ TE(GRFFRM, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Textrahmen mit Tabelle und Ueberschrift
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(GRFFRM, INSIDE, NONE), // SW
+ TE(GRFFRM, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // spaltiger Rahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(MULTICOL,INSIDE, NONE), // SW
+ TE(MULTICOL,INSIDE, NONE) // Netscape 4
+ },
+ {
+ // leerer Textreahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(SPACER, INSIDE, NONE), // SW
+ TE(SPACER, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstiger Textreahmen
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(GRFFRM, INSIDE, NONE), // SW
+ TE(GRFFRM, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Grafik-Node
+ TE(GRFNODE, INSIDE, NONE), // HTML 3.2
+ TE(GRFNODE, INSIDE, NONE), // IE 4
+ TE(GRFNODE, INSIDE, NONE), // SW
+ TE(GRFNODE, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Plugin
+ TE(OLENODE, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLENODE, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Applet
+ TE(OLENODE, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLENODE, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Floating-Frame
+ TE(OLEGRF, INSIDE, NONE), // HTML 3.2
+ TE(OLENODE, INSIDE, NONE), // IE 4
+ TE(OLENODE, INSIDE, NONE), // SW
+ TE(OLEGRF, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstige OLE-Objekte
+ TE(OLEGRF, INSIDE, NONE), // HTML 3.2
+ TE(OLEGRF, INSIDE, NONE), // IE 4
+ TE(OLEGRF, INSIDE, NONE), // SW
+ TE(OLEGRF, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Laufschrift (kann immer als MARQUEE exportiert werden, weil
+ // der Inhalt an der richtigen Stelle erscheint
+ TE(MARQUEE, INSIDE, NONE), // HTML 3.2
+ TE(MARQUEE, INSIDE, NONE), // IE 4
+ TE(MARQUEE, INSIDE, NONE), // SW
+ TE(MARQUEE, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // Controls
+ TE(CONTROL, INSIDE, NONE), // HTML 3.2
+ TE(CONTROL, INSIDE, NONE), // IE 4
+ TE(CONTROL, INSIDE, NONE), // SW
+ TE(CONTROL, INSIDE, NONE) // Netscape 4
+ },
+ {
+ // sonstige Zeichen-Objekte
+ TE(GRFFRM, INSIDE, NONE), // HTML 3.2
+ TE(GRFFRM, INSIDE, NONE), // IE 4
+ TE(GRFFRM, INSIDE, NONE), // SW
+ TE(GRFFRM, INSIDE, NONE) // Netscape 4
+ }
+};
+
diff --git a/sw/source/filter/html/htmlform.cxx b/sw/source/filter/html/htmlform.cxx
new file mode 100644
index 000000000000..3067de67ce97
--- /dev/null
+++ b/sw/source/filter/html/htmlform.cxx
@@ -0,0 +1,2661 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmltokn.h>
+#include <svl/urihelper.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/fmglob.hxx>
+#include <com/sun/star/form/ListSourceType.hpp>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/form/FormSubmitEncoding.hpp>
+#include <com/sun/star/form/FormSubmitMethod.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/awt/XTextLayoutConstrains.hpp>
+#include <com/sun/star/awt/XLayoutConstrains.hpp>
+#include <com/sun/star/awt/XImageConsumer.hpp>
+#include <com/sun/star/awt/ImageStatus.hpp>
+#include <com/sun/star/form/XImageProducerSupplier.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <swtable.hxx>
+#include <fmtanchr.hxx>
+#include <htmltbl.hxx>
+#include <docsh.hxx>
+#include <viewsh.hxx>
+#include <unodraw.hxx>
+#include <unotextrange.hxx>
+#include "dcontact.hxx"
+
+#include "swcss1.hxx"
+#include "swhtml.hxx"
+#include "htmlform.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::form;
+using ::rtl::OUString;
+
+const sal_uInt16 TABINDEX_MIN = 0;
+const sal_uInt16 TABINDEX_MAX = 32767;
+
+static HTMLOptionEnum __FAR_DATA aHTMLFormMethodTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_METHOD_get, FormSubmitMethod_GET },
+ { OOO_STRING_SVTOOLS_HTML_METHOD_post, FormSubmitMethod_POST },
+ { 0, 0 }
+};
+
+static HTMLOptionEnum __FAR_DATA aHTMLFormEncTypeTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_ET_url, FormSubmitEncoding_URL },
+ { OOO_STRING_SVTOOLS_HTML_ET_multipart, FormSubmitEncoding_MULTIPART },
+ { OOO_STRING_SVTOOLS_HTML_ET_text, FormSubmitEncoding_TEXT },
+ { 0, 0 }
+};
+
+enum HTMLWordWrapMode { HTML_WM_OFF, HTML_WM_HARD, HTML_WM_SOFT };
+
+static HTMLOptionEnum __FAR_DATA aHTMLTextAreaWrapTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_WW_off, HTML_WM_OFF },
+ { OOO_STRING_SVTOOLS_HTML_WW_hard, HTML_WM_HARD },
+ { OOO_STRING_SVTOOLS_HTML_WW_soft, HTML_WM_SOFT },
+ { OOO_STRING_SVTOOLS_HTML_WW_physical,HTML_WM_HARD },
+ { OOO_STRING_SVTOOLS_HTML_WW_virtual, HTML_WM_SOFT },
+ { 0, 0 }
+};
+
+HTMLEventType __FAR_DATA aEventTypeTable[] =
+{
+ HTML_ET_ONSUBMITFORM,
+ HTML_ET_ONRESETFORM,
+ HTML_ET_ONGETFOCUS,
+ HTML_ET_ONLOSEFOCUS,
+ HTML_ET_ONCLICK,
+ HTML_ET_ONCLICK_ITEM,
+ HTML_ET_ONCHANGE,
+ HTML_ET_ONSELECT,
+ HTML_ET_END
+};
+
+const sal_Char * __FAR_DATA aEventListenerTable[] =
+{
+ "XSubmitListener",
+ "XResetListener",
+ "XFocusListener",
+ "XFocusListener",
+ "XApproveActionListener",
+ "XItemListener",
+ "XChangeListener",
+ ""
+};
+
+const sal_Char * __FAR_DATA aEventMethodTable[] =
+{
+ "approveSubmit",
+ "approveReset",
+ "focusGained",
+ "focusLost",
+ "approveAction",
+ "itemStateChanged",
+ "changed",
+ ""
+};
+
+const sal_Char * __FAR_DATA aEventSDOptionTable[] =
+{
+ OOO_STRING_SVTOOLS_HTML_O_SDonsubmit,
+ OOO_STRING_SVTOOLS_HTML_O_SDonreset,
+ OOO_STRING_SVTOOLS_HTML_O_SDonfocus,
+ OOO_STRING_SVTOOLS_HTML_O_SDonblur,
+ OOO_STRING_SVTOOLS_HTML_O_SDonclick,
+ OOO_STRING_SVTOOLS_HTML_O_SDonclick,
+ OOO_STRING_SVTOOLS_HTML_O_SDonchange,
+ 0
+};
+
+const sal_Char * __FAR_DATA aEventOptionTable[] =
+{
+ OOO_STRING_SVTOOLS_HTML_O_onsubmit,
+ OOO_STRING_SVTOOLS_HTML_O_onreset,
+ OOO_STRING_SVTOOLS_HTML_O_onfocus,
+ OOO_STRING_SVTOOLS_HTML_O_onblur,
+ OOO_STRING_SVTOOLS_HTML_O_onclick,
+ OOO_STRING_SVTOOLS_HTML_O_onclick,
+ OOO_STRING_SVTOOLS_HTML_O_onchange,
+ 0
+};
+
+/* */
+
+class SwHTMLForm_Impl
+{
+ SwDocShell *pDocSh;
+
+ SvKeyValueIterator *pHeaderAttrs;
+
+ // gecachte Interfaces
+ uno::Reference< drawing::XDrawPage > xDrawPage;
+ uno::Reference< container::XIndexContainer > xForms;
+ uno::Reference< drawing::XShapes > xShapes;
+ uno::Reference< XMultiServiceFactory > xServiceFactory;
+
+ uno::Reference< script::XEventAttacherManager > xControlEventManager;
+ uno::Reference< script::XEventAttacherManager > xFormEventManager;
+
+ // Kontext-Informationen
+ uno::Reference< container::XIndexContainer > xFormComps;
+ uno::Reference< beans::XPropertySet > xFCompPropSet;
+ uno::Reference< drawing::XShape > xShape;
+
+ String sText;
+ SvStringsDtor aStringList;
+ SvStringsDtor aValueList;
+ SvUShorts aSelectedList;
+
+public:
+
+ SwHTMLForm_Impl( SwDocShell *pDSh ) :
+ pDocSh( pDSh ),
+ pHeaderAttrs( pDSh ? pDSh->GetHeaderAttributes() : 0 )
+ {
+ ASSERT( pDocSh, "Keine DocShell, keine Controls" );
+ }
+
+ const uno::Reference< XMultiServiceFactory >& GetServiceFactory();
+ const uno::Reference< drawing::XDrawPage >& GetDrawPage();
+ const uno::Reference< drawing::XShapes >& GetShapes();
+ const uno::Reference< script::XEventAttacherManager >& GetControlEventManager();
+ const uno::Reference< script::XEventAttacherManager >& GetFormEventManager();
+ const uno::Reference< container::XIndexContainer >& GetForms();
+
+ const uno::Reference< container::XIndexContainer >& GetFormComps() const
+ {
+ return xFormComps;
+ }
+
+ void SetFormComps( const uno::Reference< container::XIndexContainer >& r )
+ {
+ xFormComps = r;
+ }
+
+ void ReleaseFormComps() { xFormComps = 0; xControlEventManager = 0; }
+
+ const uno::Reference< beans::XPropertySet >& GetFCompPropSet() const
+ {
+ return xFCompPropSet;
+ }
+
+ void SetFCompPropSet( const uno::Reference< beans::XPropertySet >& r )
+ {
+ xFCompPropSet = r;
+ }
+
+ void ReleaseFCompPropSet() { xFCompPropSet = 0; }
+
+ const uno::Reference< drawing::XShape >& GetShape() const { return xShape; }
+ void SetShape( const uno::Reference< drawing::XShape >& r ) { xShape = r; }
+ void ReleaseShape() { xShape = 0; }
+
+ String& GetText() { return sText; }
+ void EraseText() { sText = aEmptyStr; }
+
+ SvStringsDtor& GetStringList() { return aStringList; }
+ void EraseStringList()
+ {
+ aStringList.DeleteAndDestroy( 0, aStringList.Count() );
+ }
+
+ SvStringsDtor& GetValueList() { return aValueList; }
+ void EraseValueList()
+ {
+ aValueList.DeleteAndDestroy( 0, aValueList.Count() );
+ }
+
+ SvUShorts& GetSelectedList() { return aSelectedList; }
+ void EraseSelectedList()
+ {
+ aSelectedList.Remove( 0, aSelectedList.Count() );
+ }
+
+ SvKeyValueIterator *GetHeaderAttrs() const { return pHeaderAttrs; }
+};
+
+const uno::Reference< XMultiServiceFactory >& SwHTMLForm_Impl::GetServiceFactory()
+{
+ if( !xServiceFactory.is() && pDocSh )
+ {
+ xServiceFactory =
+ uno::Reference< XMultiServiceFactory >( pDocSh->GetBaseModel(),
+ UNO_QUERY );
+ ASSERT( xServiceFactory.is(),
+ "XServiceFactory nicht vom Model erhalten" );
+ }
+ return xServiceFactory;
+}
+
+
+const uno::Reference< drawing::XDrawPage >& SwHTMLForm_Impl::GetDrawPage()
+{
+ if( !xDrawPage.is() && pDocSh )
+ {
+ uno::Reference< drawing::XDrawPageSupplier > xTxtDoc( pDocSh->GetBaseModel(),
+ UNO_QUERY );
+ ASSERT( xTxtDoc.is(),
+ "drawing::XDrawPageSupplier nicht vom XModel erhalten" );
+ xDrawPage = xTxtDoc->getDrawPage();
+ ASSERT( xDrawPage.is(), "drawing::XDrawPage nicht erhalten" );
+ }
+ return xDrawPage;
+}
+
+const uno::Reference< container::XIndexContainer >& SwHTMLForm_Impl::GetForms()
+{
+ if( !xForms.is() )
+ {
+ GetDrawPage();
+ if( xDrawPage.is() )
+ {
+ uno::Reference< XFormsSupplier > xFormsSupplier( xDrawPage, UNO_QUERY );
+ ASSERT( xFormsSupplier.is(),
+ "XFormsSupplier nicht vom drawing::XDrawPage erhalten" );
+
+ uno::Reference< container::XNameContainer > xNameCont =
+ xFormsSupplier->getForms();
+ xForms = uno::Reference< container::XIndexContainer >( xNameCont,
+ UNO_QUERY );
+
+ ASSERT( xForms.is(), "XForms nicht erhalten" );
+ }
+ }
+ return xForms;
+}
+
+
+const uno::Reference< drawing::XShapes > & SwHTMLForm_Impl::GetShapes()
+{
+ if( !xShapes.is() )
+ {
+ GetDrawPage();
+ if( xDrawPage.is() )
+ {
+ xShapes = uno::Reference< drawing::XShapes >( xDrawPage, UNO_QUERY );
+ ASSERT( xShapes.is(),
+ "XShapes nicht vom drawing::XDrawPage erhalten" );
+ }
+ }
+ return xShapes;
+}
+
+const uno::Reference< script::XEventAttacherManager >&
+ SwHTMLForm_Impl::GetControlEventManager()
+{
+ if( !xControlEventManager.is() && xFormComps.is() )
+ {
+ xControlEventManager =
+ uno::Reference< script::XEventAttacherManager >( xFormComps, UNO_QUERY );
+ ASSERT( xControlEventManager.is(),
+ "uno::Reference< XEventAttacherManager > nicht von xFormComps erhalten" );
+ }
+
+ return xControlEventManager;
+}
+
+const uno::Reference< script::XEventAttacherManager >&
+ SwHTMLForm_Impl::GetFormEventManager()
+{
+ if( !xFormEventManager.is() )
+ {
+ GetForms();
+ if( xForms.is() )
+ {
+ xFormEventManager =
+ uno::Reference< script::XEventAttacherManager >( xForms, UNO_QUERY );
+ ASSERT( xFormEventManager.is(),
+ "uno::Reference< XEventAttacherManager > nicht von xForms erhalten" );
+ }
+ }
+
+ return xFormEventManager;
+}
+
+class SwHTMLImageWatcher :
+ public cppu::WeakImplHelper2< awt::XImageConsumer, XEventListener >
+{
+ uno::Reference< drawing::XShape > xShape; // das control
+ uno::Reference< XImageProducerSupplier > xSrc;
+ uno::Reference< awt::XImageConsumer > xThis; // man selbst
+ sal_Bool bSetWidth;
+ sal_Bool bSetHeight;
+
+ void clear();
+
+public:
+
+ SwHTMLImageWatcher( const uno::Reference< drawing::XShape > & rShape,
+ sal_Bool bWidth, sal_Bool bHeight );
+ ~SwHTMLImageWatcher();
+
+ // startProduction darf nicht im Konstruktor gerufen werden, weil
+ // wir und ggf. selbst zerstoeren ... Deshlab eine eigene Methode.
+ void start() { xSrc->getImageProducer()->startProduction(); }
+
+ // UNO Anbindung
+
+ // XImageConsumer
+ virtual void SAL_CALL init( sal_Int32 Width, sal_Int32 Height)
+ throw( uno::RuntimeException );
+ virtual void SAL_CALL setColorModel(
+ sal_Int16 BitCount, const uno::Sequence< sal_Int32 >& RGBAPal,
+ sal_Int32 RedMask, sal_Int32 GreenMask, sal_Int32 BlueMask,
+ sal_Int32 AlphaMask)
+ throw( uno::RuntimeException );
+ virtual void SAL_CALL setPixelsByBytes(
+ sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height,
+ const uno::Sequence< sal_Int8 >& ProducerData,
+ sal_Int32 Offset, sal_Int32 Scansize)
+ throw( uno::RuntimeException );
+ virtual void SAL_CALL setPixelsByLongs(
+ sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height,
+ const uno::Sequence< sal_Int32 >& ProducerData,
+ sal_Int32 Offset, sal_Int32 Scansize)
+ throw( uno::RuntimeException );
+ virtual void SAL_CALL complete(
+ sal_Int32 Status,
+ const uno::Reference< awt::XImageProducer > & Producer)
+ throw( uno::RuntimeException );
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& Source ) throw ( uno::RuntimeException);
+};
+
+SwHTMLImageWatcher::SwHTMLImageWatcher(
+ const uno::Reference< drawing::XShape >& rShape,
+ sal_Bool bWidth, sal_Bool bHeight ) :
+ xShape( rShape ),
+ bSetWidth( bWidth ), bSetHeight( bHeight )
+{
+ // Die Quelle des Images merken
+ uno::Reference< drawing::XControlShape > xControlShape( xShape, UNO_QUERY );
+ uno::Reference< awt::XControlModel > xControlModel(
+ xControlShape->getControl() );
+ xSrc = uno::Reference< XImageProducerSupplier >( xControlModel, UNO_QUERY );
+ ASSERT( xSrc.is(), "Kein XImageProducerSupplier" );
+
+ // Als Event-Listener am Shape anmelden, damit wir es beim dispose
+ // loslassen ko”nnen ...
+ uno::Reference< XEventListener > xEvtLstnr = (XEventListener *)this;
+ uno::Reference< XComponent > xComp( xShape, UNO_QUERY );
+ xComp->addEventListener( xEvtLstnr );
+
+ // Zum Schluss halten wir noch eine Referenz auf uns selbst, damit
+ // wir am Leben bleiben ... (eigentlich sollte das nicht neotig sein,
+ // weil wir ja noch an diversen anderen Stellen angemeldet sind)
+ xThis = (awt::XImageConsumer *)this;
+
+ // und am ImageProducer anmelden, um die Groesse zu erehalten ...
+ xSrc->getImageProducer()->addConsumer( xThis );
+}
+
+SwHTMLImageWatcher::~SwHTMLImageWatcher()
+{
+}
+
+void SwHTMLImageWatcher::clear()
+{
+ // Am Shape als Event-Listener abmelden
+ uno::Reference< XEventListener > xEvtLstnr = (XEventListener *)this;
+ uno::Reference< XComponent > xComp( xShape, UNO_QUERY );
+ xComp->removeEventListener( xEvtLstnr );
+
+ // Am ImageProducer abmelden
+ uno::Reference<awt::XImageProducer> xProd = xSrc->getImageProducer();
+ if( xProd.is() )
+ xProd->removeConsumer( xThis );
+}
+
+//------------------------------------------------------------------------------
+
+void SwHTMLImageWatcher::init( sal_Int32 Width, sal_Int32 Height )
+ throw( uno::RuntimeException )
+{
+ ASSERT( bSetWidth || bSetHeight,
+ "Breite oder Hoehe muss angepasst werden" );
+
+ // Wenn keine Breite oder Hoehe angegeben ist, ist das das init von
+ // der leeren Grafik, die angezeigt wird, bevor der Stream einer
+ // asynchron anzuzeigenden Grfik verfuegbar ist.
+ if( !Width && !Height )
+ return;
+
+ awt::Size aNewSz;
+ aNewSz.Width = Width;
+ aNewSz.Height = Height;
+ if( Application::GetDefaultDevice() )
+ {
+ Size aTmp(aNewSz.Width, aNewSz.Height);
+ aTmp = Application::GetDefaultDevice()
+ ->PixelToLogic( aTmp, MapMode( MAP_100TH_MM ) );
+ aNewSz.Width = aTmp.Width();
+ aNewSz.Height = aTmp.Height();
+ }
+
+ if( !bSetWidth || !bSetHeight )
+ {
+ awt::Size aSz( xShape->getSize() );
+ if( bSetWidth && aNewSz.Height )
+ {
+ aNewSz.Width *= aSz.Height;
+ aNewSz.Width /= aNewSz.Height;
+ aNewSz.Height = aSz.Height;
+ }
+ if( bSetHeight && aNewSz.Width )
+ {
+ aNewSz.Height *= aSz.Width;
+ aNewSz.Height /= aNewSz.Width;
+ aNewSz.Width = aSz.Width;
+ }
+ }
+ if( aNewSz.Width < MINFLY )
+ aNewSz.Width = MINFLY;
+ if( aNewSz.Height < MINFLY )
+ aNewSz.Height = MINFLY;
+
+ xShape->setSize( aNewSz );
+ if( bSetWidth )
+ {
+ // Wenn das Control in einer Tabelle verankert ist, muesen
+ // die Tabellen-Spalten neu berechnet werden
+
+ // Um an den SwXShape* zu gelangen, brauchen wir ein Interface,
+ // das auch vom SwXShape implementiert wird.
+
+ uno::Reference< beans::XPropertySet > xPropSet( xShape, UNO_QUERY );
+ uno::Reference< XUnoTunnel> xTunnel( xPropSet, UNO_QUERY );
+ SwXShape *pSwShape = xTunnel.is() ?
+ reinterpret_cast< SwXShape * >( sal::static_int_cast< sal_IntPtr>(
+ xTunnel->getSomething(SwXShape::getUnoTunnelId()) ))
+ : 0;
+
+ ASSERT( pSwShape, "Wo ist das SW-Shape?" );
+ if( pSwShape )
+ {
+ SwFrmFmt *pFrmFmt = pSwShape->GetFrmFmt();
+
+ const SwDoc *pDoc = pFrmFmt->GetDoc();
+ const SwPosition* pAPos = pFrmFmt->GetAnchor().GetCntntAnchor();
+ SwNode *pANd;
+ SwTableNode *pTblNd;
+ if( pAPos &&
+ 0 != (pANd = pDoc->GetNodes()[pAPos->nNode]) &&
+ 0 != (pTblNd = pANd->FindTableNode()) )
+ {
+ const sal_Bool bLastGrf = !pTblNd->GetTable().DecGrfsThatResize();
+ SwHTMLTableLayout *pLayout =
+ pTblNd->GetTable().GetHTMLTableLayout();
+ if( pLayout )
+ {
+ const sal_uInt16 nBrowseWidth =
+ pLayout->GetBrowseWidthByTable( *pDoc );
+
+ if ( nBrowseWidth )
+ {
+ pLayout->Resize( nBrowseWidth, sal_True, sal_True,
+ bLastGrf ? HTMLTABLE_RESIZE_NOW
+ : 500 );
+ }
+ }
+ }
+ }
+ }
+
+ // uns selbst abmelden und loeschen
+ clear();
+ uno::Reference< awt::XImageConsumer > xTmp = (awt::XImageConsumer*)this;
+ xThis = 0;
+}
+
+void SwHTMLImageWatcher::setColorModel(
+ sal_Int16, const Sequence< sal_Int32 >&, sal_Int32, sal_Int32,
+ sal_Int32, sal_Int32 )
+ throw( uno::RuntimeException )
+{
+}
+
+void SwHTMLImageWatcher::setPixelsByBytes(
+ sal_Int32, sal_Int32, sal_Int32, sal_Int32,
+ const Sequence< sal_Int8 >&, sal_Int32, sal_Int32 )
+ throw( uno::RuntimeException )
+{
+}
+
+
+void SwHTMLImageWatcher::setPixelsByLongs(
+ sal_Int32, sal_Int32, sal_Int32, sal_Int32,
+ const Sequence< sal_Int32 >&, sal_Int32, sal_Int32 )
+ throw( uno::RuntimeException )
+{
+}
+
+
+void SwHTMLImageWatcher::complete( sal_Int32 Status,
+ const uno::Reference< awt::XImageProducer >& )
+ throw( uno::RuntimeException )
+{
+ if( awt::ImageStatus::IMAGESTATUS_ERROR == Status || awt::ImageStatus::IMAGESTATUS_ABORTED == Status )
+ {
+ // uns selbst abmelden und loeschen
+ clear();
+ uno::Reference< awt::XImageConsumer > xTmp = (awt::XImageConsumer*)this;
+ xThis = 0;
+ }
+}
+
+void SwHTMLImageWatcher::disposing(const lang::EventObject& evt) throw ( uno::RuntimeException)
+{
+ uno::Reference< awt::XImageConsumer > xTmp;
+
+ // Wenn das Shape verschwindet soll muessen wir es loslassen
+ uno::Reference< drawing::XShape > xTmpShape;
+ if( evt.Source == xShape )
+ {
+ clear();
+ xTmp = (awt::XImageConsumer*)this;
+ xThis = 0;
+ }
+}
+
+void SwHTMLParser::DeleteFormImpl()
+{
+ delete pFormImpl;
+ pFormImpl = 0;
+}
+
+static void lcl_html_setFixedFontProperty(
+ const uno::Reference< beans::XPropertySet >& rPropSet )
+{
+ Font aFixedFont( OutputDevice::GetDefaultFont(
+ DEFAULTFONT_FIXED, LANGUAGE_ENGLISH_US,
+ DEFAULTFONT_FLAGS_ONLYONE ) );
+ Any aTmp;
+ aTmp <<= OUString( aFixedFont.GetName() );
+ rPropSet->setPropertyValue( OUString::createFromAscii("FontName"), aTmp );
+
+ aTmp <<= OUString( aFixedFont.GetStyleName() );
+ rPropSet->setPropertyValue( OUString::createFromAscii("FontStyleName"),
+ aTmp );
+
+ aTmp <<= (sal_Int16) aFixedFont.GetFamily();
+ rPropSet->setPropertyValue( OUString::createFromAscii("FontFamily"), aTmp );
+
+ aTmp <<= (sal_Int16) aFixedFont.GetCharSet();
+ rPropSet->setPropertyValue( OUString::createFromAscii("FontCharset"),
+ aTmp );
+
+ aTmp <<= (sal_Int16) aFixedFont.GetPitch();
+ rPropSet->setPropertyValue( OUString::createFromAscii("FontPitch"), aTmp );
+
+ float fVal(10.);
+ aTmp.setValue( &fVal, ::getCppuType(&fVal ));
+ rPropSet->setPropertyValue( OUString::createFromAscii("FontHeight"), aTmp );
+}
+
+class SwHTMLFormPendingStackData_Impl: public SwPendingStackData
+{
+ uno::Reference< drawing::XShape > xShape;
+ Size aTextSz;
+ sal_Bool bMinWidth;
+ sal_Bool bMinHeight;
+
+public:
+
+ SwHTMLFormPendingStackData_Impl(
+ const uno::Reference< drawing::XShape > & rShape, const Size& rTextSz,
+ sal_Bool bMinW, sal_Bool bMinH ) :
+ xShape( rShape ),
+ aTextSz( rTextSz ),
+ bMinWidth( bMinW ),
+ bMinHeight( bMinH )
+ {}
+
+ const uno::Reference< drawing::XShape >& GetShape() const { return xShape; }
+ const Size& GetTextSize() const { return aTextSz; }
+ sal_Bool IsMinWidth() const { return bMinWidth; }
+ sal_Bool IsMinHeight() const { return bMinHeight; }
+};
+
+void SwHTMLParser::SetPendingControlSize( int nToken )
+{
+ ASSERT( pPendStack, "Wo ist der Pending Stack?" );
+ SwHTMLFormPendingStackData_Impl *pData =
+ (SwHTMLFormPendingStackData_Impl *)pPendStack->pData;
+
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+ ASSERT( !pPendStack, "Wo kommt der Pending-Stack her?" );
+
+ SetControlSize( pData->GetShape(), pData->GetTextSize(),
+ pData->IsMinWidth(), pData->IsMinHeight(),
+ nToken );
+ delete pData;
+}
+
+void SwHTMLParser::SetControlSize( const uno::Reference< drawing::XShape >& rShape,
+ const Size& rTextSz,
+ sal_Bool bMinWidth,
+ sal_Bool bMinHeight,
+ int nToken )
+{
+ nToken = 0;
+ if( !rTextSz.Width() && !rTextSz.Height() && !bMinWidth && !bMinHeight )
+ return;
+
+ // Um an den SwXShape* zu gelangen, brauchen wir ein Interface,
+ // das auch vom SwXShape implementiert wird.
+ uno::Reference< beans::XPropertySet > xPropSet( rShape, UNO_QUERY );
+
+ ViewShell *pVSh;
+ pDoc->GetEditShell( &pVSh );
+ if( !pVSh && !nEventId )
+ {
+ // If there is no view shell by now and the doc shell is an internal
+ // one, no view shell will be created. That for, we have to do that of
+ // our own. This happens if a linked section is inserted or refreshed.
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ if( pDocSh )
+ {
+ if ( pDocSh->GetMedium() )
+ {
+ // if there is no hidden property in the MediaDescriptor it should be removed after loading
+ SFX_ITEMSET_ARG( pDocSh->GetMedium()->GetItemSet(), pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False );
+ bRemoveHidden = ( pHiddenItem == NULL || !pHiddenItem->GetValue() );
+ }
+
+ pTempViewFrame = SfxViewFrame::LoadHiddenDocument( *pDocSh, 0 );
+ CallStartAction();
+ pDoc->GetEditShell( &pVSh );
+ }
+ }
+
+ uno::Reference< XUnoTunnel> xTunnel( xPropSet, UNO_QUERY );
+ SwXShape *pSwShape = xTunnel.is() ?
+ reinterpret_cast< SwXShape *>( sal::static_int_cast< sal_IntPtr >(
+ xTunnel->getSomething(SwXShape::getUnoTunnelId()) ))
+ : 0;
+
+ ASSERT( pSwShape, "Wo ist das SW-Shape?" );
+
+ // es muss ein Draw-Format sein
+ SwFrmFmt *pFrmFmt = pSwShape->GetFrmFmt();
+ ASSERT( RES_DRAWFRMFMT == pFrmFmt->Which(), "Kein DrawFrmFmt" );
+
+ // Schauen, ob es ein SdrObject dafuer gibt
+ const SdrObject *pObj = pFrmFmt->FindSdrObject();
+ ASSERT( pObj, "SdrObject nicht gefunden" );
+ ASSERT( FmFormInventor == pObj->GetObjInventor(), "falscher Inventor" );
+
+ const SdrView* pDrawView = pVSh ? pVSh->GetDrawView() : 0;
+
+ SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, pObj );
+ uno::Reference< awt::XControl > xControl;
+ if ( pDrawView && pVSh->GetWin() )
+ xControl = pFormObj->GetUnoControl( *pDrawView, *pVSh->GetWin() );
+
+ awt::Size aSz( rShape->getSize() );
+ awt::Size aNewSz( 0, 0 );
+
+ // #i71248# ensure we got a XControl before apllying corrections
+ if(xControl.is())
+ {
+ if( bMinWidth || bMinHeight )
+ {
+ uno::Reference< awt::XLayoutConstrains > xLC( xControl, UNO_QUERY );
+ awt::Size aTmpSz( xLC->getPreferredSize() );
+ if( bMinWidth )
+ aNewSz.Width = aTmpSz.Width;
+ if( bMinHeight )
+ aNewSz.Height = aTmpSz.Height;
+ }
+ if( rTextSz.Width() || rTextSz.Height())
+ {
+ uno::Reference< awt::XTextLayoutConstrains > xLC( xControl, UNO_QUERY );
+ ASSERT( xLC.is(), "kein XTextLayoutConstrains" );
+ if( xLC.is() )
+ {
+ awt::Size aTmpSz( rTextSz.Width(), rTextSz.Height() );
+ if( -1 == rTextSz.Width() )
+ {
+ aTmpSz.Width = 0;
+ aTmpSz.Height = nSelectEntryCnt;
+ }
+ aTmpSz = xLC->getMinimumSize( static_cast< sal_Int16 >(aTmpSz.Width), static_cast< sal_Int16 >(aTmpSz.Height) );
+ if( rTextSz.Width() )
+ aNewSz.Width = aTmpSz.Width;
+ if( rTextSz.Height() )
+ aNewSz.Height = aTmpSz.Height;
+ }
+ }
+ }
+
+ if( Application::GetDefaultDevice() )
+ {
+ Size aTmpSz( aNewSz.Width, aNewSz.Height );
+ aTmpSz = Application::GetDefaultDevice()
+ ->PixelToLogic( aTmpSz, MapMode( MAP_100TH_MM ) );
+ aNewSz.Width = aTmpSz.Width();
+ aNewSz.Height = aTmpSz.Height();
+ }
+ if( aNewSz.Width )
+ {
+ if( aNewSz.Width < MINLAY )
+ aNewSz.Width = MINLAY;
+ aSz.Width = aNewSz.Width;
+ }
+ if( aNewSz.Height )
+ {
+ if( aNewSz.Height < MINLAY )
+ aNewSz.Height = MINLAY;
+ aSz.Height = aNewSz.Height;
+ }
+
+ rShape->setSize( aSz );
+}
+
+static void lcl_html_setEvents(
+ const uno::Reference< script::XEventAttacherManager > & rEvtMn,
+ sal_uInt32 nPos, const SvxMacroTableDtor& rMacroTbl,
+ const SvStringsDtor& rUnoMacroTbl,
+ const SvStringsDtor& rUnoMacroParamTbl,
+ const String& rType )
+{
+ // Erstmal muss die Anzahl der Events ermittelt werden ...
+ sal_Int32 nEvents = 0;
+ sal_uInt16 i;
+
+ for( i = 0; HTML_ET_END != aEventTypeTable[i]; i++ )
+ {
+ const SvxMacro *pMacro = rMacroTbl.Get( aEventTypeTable[i] );
+ // Solange nicht alle Events implementiert sind, enthaelt die
+ // Tabelle auch Leerstrings!
+ if( pMacro && aEventListenerTable[i] )
+ nEvents++;
+ }
+ for( i=0; i< rUnoMacroTbl.Count(); i++ )
+ {
+ const String& rStr = *rUnoMacroTbl[i];
+ xub_StrLen nIndex = 0;
+ if( !rStr.GetToken( 0, '-', nIndex ).Len() || STRING_NOTFOUND == nIndex )
+ continue;
+ if( !rStr.GetToken( 0, '-', nIndex ).Len() || STRING_NOTFOUND == nIndex )
+ continue;
+ if( nIndex < rStr.Len() )
+ nEvents++;
+ }
+
+ if( 0==nEvents )
+ return;
+
+ Sequence<script::ScriptEventDescriptor> aDescs( nEvents );
+ script::ScriptEventDescriptor* pDescs = aDescs.getArray();
+ sal_Int32 nEvent = 0;
+
+ for( i=0; HTML_ET_END != aEventTypeTable[i]; i++ )
+ {
+ const SvxMacro *pMacro = rMacroTbl.Get( aEventTypeTable[i] );
+ if( pMacro && aEventListenerTable[i] )
+ {
+ script::ScriptEventDescriptor& rDesc = pDescs[nEvent++];
+ rDesc.ListenerType =
+ OUString::createFromAscii(aEventListenerTable[i]);
+ rDesc.EventMethod = OUString::createFromAscii(aEventMethodTable[i]);
+ rDesc.ScriptType = pMacro->GetLanguage();
+ rDesc.ScriptCode = pMacro->GetMacName();
+ }
+ }
+
+ for( i=0; i< rUnoMacroTbl.Count(); i++ )
+ {
+ const String& rStr = *rUnoMacroTbl[i];
+ xub_StrLen nIndex = 0;
+ String sListener( rStr.GetToken( 0, '-', nIndex ) );
+ if( !sListener.Len() || STRING_NOTFOUND == nIndex )
+ continue;
+
+ String sMethod( rStr.GetToken( 0, '-', nIndex ) );
+ if( !sMethod.Len() || STRING_NOTFOUND == nIndex )
+ continue;
+
+ String sCode( rStr.Copy( nIndex ) );
+ if( !sCode.Len() )
+ continue;
+
+ script::ScriptEventDescriptor& rDesc = pDescs[nEvent++];
+ rDesc.ListenerType = sListener;
+ rDesc.EventMethod = sMethod;
+ rDesc.ScriptType = rType;
+ rDesc.ScriptCode = sCode;
+ rDesc.AddListenerParam = OUString();
+
+ if( rUnoMacroParamTbl.Count() )
+ {
+ String sSearch( sListener );
+ sSearch += '-';
+ sSearch += sMethod;
+ sSearch += '-';
+ xub_StrLen nLen = sSearch.Len();
+ for( sal_uInt16 j=0; j < rUnoMacroParamTbl.Count(); j++ )
+ {
+ const String& rParam = *rUnoMacroParamTbl[j];
+ if( rParam.CompareTo( sSearch, nLen ) == COMPARE_EQUAL &&
+ rParam.Len() > nLen )
+ {
+ rDesc.AddListenerParam = rParam.Copy(nLen);
+ break;
+ }
+ }
+ }
+ }
+ rEvtMn->registerScriptEvents( nPos, aDescs );
+}
+
+static void lcl_html_getEvents( const String& rOption, const String& rValue,
+ SvStringsDtor& rUnoMacroTbl,
+ SvStringsDtor& rUnoMacroParamTbl )
+{
+ if( rOption.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_O_sdevent,
+ sizeof(OOO_STRING_SVTOOLS_HTML_O_sdevent)-1 ) == COMPARE_EQUAL )
+ {
+ String *pEvent = new String( rOption.Copy(sizeof(OOO_STRING_SVTOOLS_HTML_O_sdevent)-1) );
+ *pEvent += '-';
+ *pEvent += rValue;
+ rUnoMacroTbl.Insert( pEvent, rUnoMacroTbl.Count() );
+ }
+ else if( rOption.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_O_sdaddparam,
+ sizeof(OOO_STRING_SVTOOLS_HTML_O_sdaddparam)-1 ) == COMPARE_EQUAL )
+ {
+ String *pParam =
+ new String( rOption.Copy( sizeof(OOO_STRING_SVTOOLS_HTML_O_sdaddparam)-1 ) );
+ *pParam += '-';
+ *pParam += rValue;
+ rUnoMacroParamTbl.Insert( pParam, rUnoMacroParamTbl.Count() );
+ }
+}
+
+uno::Reference< drawing::XShape > SwHTMLParser::InsertControl(
+ const uno::Reference< XFormComponent > & rFComp,
+ const uno::Reference< beans::XPropertySet > & rFCompPropSet,
+ const Size& rSize, sal_Int16 eVertOri, sal_Int16 eHoriOri,
+ SfxItemSet& rCSS1ItemSet, SvxCSS1PropertyInfo& rCSS1PropInfo,
+ const SvxMacroTableDtor& rMacroTbl, const SvStringsDtor& rUnoMacroTbl,
+ const SvStringsDtor& rUnoMacroParamTbl, sal_Bool bSetFCompPropSet,
+ sal_Bool bHidden )
+{
+ uno::Reference< drawing::XShape > xShape;
+
+ const uno::Reference< container::XIndexContainer > & rFormComps =
+ pFormImpl->GetFormComps();
+ Any aAny( &rFComp, ::getCppuType( (uno::Reference< XFormComponent>*)0 ) );
+ rFormComps->insertByIndex( rFormComps->getCount(), aAny );
+
+ if( !bHidden )
+ {
+ Any aTmp;
+ sal_uInt16 nLeftSpace = 0, nRightSpace = 0,
+ nUpperSpace = 0, nLowerSpace = 0;
+
+ const uno::Reference< XMultiServiceFactory > & rServiceFactory =
+ pFormImpl->GetServiceFactory();
+ if( !rServiceFactory.is() )
+ return xShape;
+
+ uno::Reference< XInterface > xCreate =
+ rServiceFactory ->createInstance(
+ OUString::createFromAscii("com.sun.star.drawing.ControlShape"));
+ if( !xCreate.is() )
+ return xShape;
+
+ xShape = uno::Reference< drawing::XShape >( xCreate, UNO_QUERY );
+
+ DBG_ASSERT( xShape.is(), "XShape nicht erhalten" );
+ awt::Size aTmpSz;
+ aTmpSz.Width = rSize.Width();
+ aTmpSz.Height = rSize.Height();
+ xShape->setSize( aTmpSz );
+
+ uno::Reference< beans::XPropertySet > xShapePropSet( xCreate, UNO_QUERY );
+
+ // linken/rechten Rand setzen
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_LR_SPACE, sal_True,
+ &pItem ) )
+ {
+ // Ggf. den Erstzeilen-Einzug noch plaetten
+ const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
+ SvxLRSpaceItem aLRItem( *pLRItem );
+ aLRItem.SetTxtFirstLineOfst( 0 );
+ if( rCSS1PropInfo.bLeftMargin )
+ {
+ nLeftSpace = static_cast< sal_uInt16 >(TWIP_TO_MM100( aLRItem.GetLeft() ));
+ rCSS1PropInfo.bLeftMargin = sal_False;
+ }
+ if( rCSS1PropInfo.bRightMargin )
+ {
+ nRightSpace = static_cast< sal_uInt16 >(TWIP_TO_MM100( aLRItem.GetRight() ));
+ rCSS1PropInfo.bRightMargin = sal_False;
+ }
+ rCSS1ItemSet.ClearItem( RES_LR_SPACE );
+ }
+ if( nLeftSpace || nRightSpace )
+ {
+ Any aAny2;
+ aAny2 <<= (sal_Int32)nLeftSpace;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "LeftMargin" ), aAny2 );
+
+ aAny2 <<= (sal_Int32)nRightSpace;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "RightMargin" ), aAny2 );
+ }
+
+ // oberen/unteren Rand setzen
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_UL_SPACE, sal_True,
+ &pItem ) )
+ {
+ // Ggf. den Erstzeilen-Einzug noch plaetten
+ const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
+ if( rCSS1PropInfo.bTopMargin )
+ {
+ nUpperSpace = TWIP_TO_MM100_UNSIGNED( pULItem->GetUpper() );
+ rCSS1PropInfo.bTopMargin = sal_False;
+ }
+ if( rCSS1PropInfo.bBottomMargin )
+ {
+ nLowerSpace = TWIP_TO_MM100_UNSIGNED( pULItem->GetLower() );
+ rCSS1PropInfo.bBottomMargin = sal_False;
+ }
+
+ rCSS1ItemSet.ClearItem( RES_UL_SPACE );
+ }
+ if( nUpperSpace || nLowerSpace )
+ {
+ uno::Any aAny2;
+ aAny2 <<= (sal_Int32)nUpperSpace;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "TopMargin" ), aAny2 );
+
+ aAny2 <<= (sal_Int32)nLowerSpace;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "BottomMargin" ), aAny2 );
+ }
+
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
+ rFCompPropSet->getPropertySetInfo();
+ OUString sPropName = OUString::createFromAscii( "BackgroundColor" );
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_BACKGROUND, sal_True,
+ &pItem ) &&
+ xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ const Color &rColor = ((const SvxBrushItem *)pItem)->GetColor();
+ /// OD 02.09.2002 #99657#
+ /// copy color, if color is not "no fill"/"auto fill"
+ if( rColor.GetColor() != COL_TRANSPARENT )
+ {
+ /// OD 02.09.2002 #99657#
+ /// copy complete color with transparency
+ aTmp <<= static_cast<sal_Int32>(rColor.GetColor());
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+
+ }
+
+ sPropName = OUString::createFromAscii( "TextColor" );
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_CHRATR_COLOR, sal_True,
+ &pItem ) &&
+ xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= (sal_Int32)((const SvxColorItem *)pItem)->GetValue()
+ .GetRGBColor();
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+
+ sPropName = OUString::createFromAscii( "FontHeight" );
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_CHRATR_FONTSIZE,
+ sal_True, &pItem ) &&
+ xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ float fVal = static_cast< float >(
+ (((SvxFontHeightItem *)pItem)->GetHeight()) / 20.0 );
+ aTmp.setValue( &fVal, ::getCppuType(&fVal));
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_CHRATR_FONT, sal_True,
+ &pItem ) )
+ {
+ const SvxFontItem *pFontItem = (SvxFontItem *)pItem;
+ sPropName = OUString::createFromAscii( "FontName" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= OUString( pFontItem->GetFamilyName() );
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+ sPropName = OUString::createFromAscii( "FontStyleName" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= OUString( pFontItem->GetStyleName() );
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+ sPropName = OUString::createFromAscii( "FontFamily" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= (sal_Int16)pFontItem->GetFamily() ;
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+ sPropName = OUString::createFromAscii( "FontCharset" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= (sal_Int16)pFontItem->GetCharSet() ;
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+ sPropName = OUString::createFromAscii( "FontPitch" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= (sal_Int16)pFontItem->GetPitch() ;
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+ }
+
+ sPropName = OUString::createFromAscii( "FontWeight" );
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_CHRATR_WEIGHT,
+ sal_True, &pItem ) &&
+ xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ float fVal = VCLUnoHelper::ConvertFontWeight(
+ ((SvxWeightItem *)pItem)->GetWeight() );
+ aTmp.setValue( &fVal, ::getCppuType(&fVal));
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+
+ sPropName = OUString::createFromAscii( "FontSlant" );
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_CHRATR_POSTURE,
+ sal_True, &pItem ) &&
+ xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= (sal_Int16)((SvxPostureItem *)pItem)->GetPosture();
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+
+ sPropName = OUString::createFromAscii( "FontUnderline" );
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_CHRATR_UNDERLINE,
+ sal_True, &pItem ) &&
+ xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= (sal_Int16)((SvxUnderlineItem *)pItem)->GetLineStyle();
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+
+ sPropName = OUString::createFromAscii( "FontStrikeout" );
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_CHRATR_CROSSEDOUT,
+ sal_True, &pItem ) &&
+ xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp <<= (sal_Int16)((SvxCrossedOutItem *)pItem)->GetStrikeout();
+ rFCompPropSet->setPropertyValue( sPropName, aTmp );
+ }
+
+ uno::Reference< text::XTextRange > xTxtRg;
+ sal_Int16 nAnchorType = text::TextContentAnchorType_AS_CHARACTER;
+ sal_Bool bSetPos = sal_False, bSetSurround = sal_False;
+ sal_Int32 nXPos = 0, nYPos = 0;
+ sal_Int16 nSurround = text::WrapTextMode_NONE;
+ if( SVX_CSS1_POS_ABSOLUTE == rCSS1PropInfo.ePosition &&
+ SVX_CSS1_LTYPE_TWIP == rCSS1PropInfo.eLeftType &&
+ SVX_CSS1_LTYPE_TWIP == rCSS1PropInfo.eTopType )
+ {
+ const SwStartNode *pFlySttNd =
+ pDoc->GetNodes()[pPam->GetPoint()->nNode]->FindFlyStartNode();
+
+ if( pFlySttNd )
+ {
+ nAnchorType = text::TextContentAnchorType_AT_FRAME;
+ SwPaM aPaM( *pFlySttNd );
+
+ uno::Reference< text::XText > xDummyTxtRef; // unsauber, aber laut OS geht das ...
+ xTxtRg = new SwXTextRange( aPaM, xDummyTxtRef );
+ }
+ else
+ {
+ nAnchorType = text::TextContentAnchorType_AT_PAGE;
+ }
+ nXPos = TWIP_TO_MM100( rCSS1PropInfo.nLeft ) + nLeftSpace;
+ nYPos = TWIP_TO_MM100( rCSS1PropInfo.nTop ) + nUpperSpace;
+ bSetPos = sal_True;
+
+ nSurround = text::WrapTextMode_THROUGHT;
+ bSetSurround = sal_True;
+ }
+ else if( SVX_ADJUST_LEFT == rCSS1PropInfo.eFloat ||
+ text::HoriOrientation::LEFT == eHoriOri )
+ {
+ nAnchorType = text::TextContentAnchorType_AT_PARAGRAPH;
+ nXPos = nLeftSpace;
+ nYPos = nUpperSpace;
+ bSetPos = sal_True;
+ nSurround = text::WrapTextMode_RIGHT;
+ bSetSurround = sal_True;
+ }
+ else if( text::VertOrientation::NONE != eVertOri )
+ {
+ sal_Int16 nVertOri = text::VertOrientation::NONE;
+ switch( eVertOri )
+ {
+ case text::VertOrientation::NONE:
+ nVertOri = text::VertOrientation::NONE;
+ break;
+ case text::VertOrientation::TOP:
+ nVertOri = text::VertOrientation::TOP;
+ break;
+ case text::VertOrientation::CENTER:
+ nVertOri = text::VertOrientation::CENTER;
+ break;
+ case text::VertOrientation::BOTTOM:
+ nVertOri = text::VertOrientation::BOTTOM;
+ break;
+ case text::VertOrientation::CHAR_TOP:
+ nVertOri = text::VertOrientation::CHAR_TOP;
+ break;
+ case text::VertOrientation::CHAR_CENTER:
+ nVertOri = text::VertOrientation::CHAR_CENTER;
+ break;
+ case text::VertOrientation::CHAR_BOTTOM:
+ nVertOri = text::VertOrientation::CHAR_BOTTOM;
+ break;
+ case text::VertOrientation::LINE_TOP:
+ nVertOri = text::VertOrientation::LINE_TOP;
+ break;
+ case text::VertOrientation::LINE_CENTER:
+ nVertOri = text::VertOrientation::LINE_CENTER;
+ break;
+ case text::VertOrientation::LINE_BOTTOM:
+ nVertOri = text::VertOrientation::LINE_BOTTOM;
+ break;
+ }
+ aTmp <<= (sal_Int16)nVertOri ;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "VertOrient" ), aTmp );
+ }
+
+ aTmp <<= (sal_Int16)nAnchorType ;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "AnchorType" ), aTmp );
+
+ if( text::TextContentAnchorType_AT_PAGE == nAnchorType )
+ {
+ aTmp <<= (sal_Int16) 1 ;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "AnchorPageNo" ), aTmp );
+ }
+ else
+ {
+ if( !xTxtRg.is() )
+ {
+ uno::Reference< text::XText > xDummyTxtRef; // unsauber, aber laut OS geht das ...
+ xTxtRg = new SwXTextRange( *pPam, xDummyTxtRef );
+ }
+
+ aTmp.setValue( &xTxtRg,
+ ::getCppuType((uno::Reference< text::XTextRange>*)0));
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "TextRange" ), aTmp );
+ }
+
+ if( bSetPos )
+ {
+ aTmp <<= (sal_Int16)text::HoriOrientation::NONE;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "HoriOrient" ), aTmp );
+ aTmp <<= (sal_Int32)nXPos ;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "HoriOrientPosition" ), aTmp );
+
+ aTmp <<= (sal_Int16)text::VertOrientation::NONE;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "VertOrient" ), aTmp );
+ aTmp <<= (sal_Int32)nYPos ;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "VertOrientPosition" ), aTmp );
+ }
+ if( bSetSurround )
+ {
+ aTmp <<= (sal_Int16)nSurround ;
+ xShapePropSet->setPropertyValue(
+ OUString::createFromAscii( "Surround" ), aTmp );
+ }
+
+ pFormImpl->GetShapes()->add(xShape);
+
+ // Das Control-Model am Control-Shape setzen
+ uno::Reference< drawing::XControlShape > xControlShape( xShape, UNO_QUERY );
+ uno::Reference< awt::XControlModel > xControlModel( rFComp, UNO_QUERY );
+ xControlShape->setControl( xControlModel );
+ }
+
+ // Da beim Einfuegen der Controls der Fokus gesetzt wird, werden
+ // auch schon Fokus-Events verschickt. Damit die nicht evtl. schon
+ // vorhendene JavaSCript-Eents rufen, werden die Events nachtraeglich
+ // gesetzt.
+ if( rMacroTbl.Count() || rUnoMacroTbl.Count() )
+ {
+ lcl_html_setEvents( pFormImpl->GetControlEventManager(),
+ rFormComps->getCount() - 1,
+ rMacroTbl, rUnoMacroTbl, rUnoMacroParamTbl,
+ GetScriptTypeString(pFormImpl->GetHeaderAttrs()) );
+ }
+
+ if( bSetFCompPropSet )
+ {
+ pFormImpl->SetFCompPropSet( rFCompPropSet );
+ }
+
+ return xShape;
+}
+
+void SwHTMLParser::NewForm( sal_Bool bAppend )
+{
+ // Gibt es schon eine Form?
+ if( pFormImpl && pFormImpl->GetFormComps().is() )
+ return;
+
+ if( bAppend )
+ {
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_SPACE );
+ else
+ AddParSpace();
+ }
+
+ if( !pFormImpl )
+ pFormImpl = new SwHTMLForm_Impl( pDoc->GetDocShell() );
+
+ String aAction( sBaseURL );
+ String sName, sTarget;
+ sal_uInt16 nEncType = FormSubmitEncoding_URL;
+ sal_uInt16 nMethod = FormSubmitMethod_GET;
+ SvxMacroTableDtor aMacroTbl;
+ SvStringsDtor aUnoMacroTbl;
+ SvStringsDtor aUnoMacroParamTbl;
+ SvKeyValueIterator *pHeaderAttrs = pFormImpl->GetHeaderAttrs();
+ ScriptType eDfltScriptType = GetScriptType( pHeaderAttrs );
+ const String& rDfltScriptType = GetScriptTypeString( pHeaderAttrs );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ ScriptType eScriptType2 = eDfltScriptType;
+ sal_uInt16 nEvent;
+ sal_Bool bSetEvent = sal_False;
+
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ACTION:
+ aAction = pOption->GetString();
+ break;
+ case HTML_O_METHOD:
+ nMethod = pOption->GetEnum( aHTMLFormMethodTable, nMethod );
+ break;
+ case HTML_O_ENCTYPE:
+ nEncType = pOption->GetEnum( aHTMLFormEncTypeTable, nEncType );
+ break;
+ case HTML_O_TARGET:
+ sTarget = pOption->GetString();
+ break;
+ case HTML_O_NAME:
+ sName = pOption->GetString();
+ break;
+
+ case HTML_O_SDONSUBMIT:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONSUBMIT:
+ nEvent = HTML_ET_ONSUBMITFORM;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONRESET:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONRESET:
+ nEvent = HTML_ET_ONRESETFORM;
+ bSetEvent = sal_True;
+ break;
+
+ default:
+ lcl_html_getEvents( pOption->GetTokenString(),
+ pOption->GetString(),
+ aUnoMacroTbl, aUnoMacroParamTbl );
+ break;
+ }
+
+ if( bSetEvent )
+ {
+ String sEvent( pOption->GetString() );
+ if( sEvent.Len() )
+ {
+ sEvent.ConvertLineEnd();
+ String aScriptType2;
+ if( EXTENDED_STYPE==eScriptType2 )
+ aScriptType2 = rDfltScriptType;
+ aMacroTbl.Insert( nEvent, new SvxMacro( sEvent, aScriptType2,
+ eScriptType2 ) );
+ }
+ }
+ }
+
+ const uno::Reference< XMultiServiceFactory > & rSrvcMgr =
+ pFormImpl->GetServiceFactory();
+ if( !rSrvcMgr.is() )
+ return;
+
+ uno::Reference< XInterface > xInt = rSrvcMgr->createInstance(
+ OUString::createFromAscii( "com.sun.star.form.component.Form" ) );
+ if( !xInt.is() )
+ return;
+
+ uno::Reference< XForm > xForm( xInt, UNO_QUERY );
+ DBG_ASSERT( xForm.is(), "keine Form?" );
+
+ uno::Reference< container::XIndexContainer > xFormComps( xForm, UNO_QUERY );
+ pFormImpl->SetFormComps( xFormComps );
+
+ uno::Reference< beans::XPropertySet > xFormPropSet( xForm, UNO_QUERY );
+
+ Any aTmp;
+ aTmp <<= OUString(sName);
+ xFormPropSet->setPropertyValue( OUString::createFromAscii( "Name" ), aTmp );
+
+ if( aAction.Len() )
+ {
+ aAction = URIHelper::SmartRel2Abs(INetURLObject(sBaseURL), aAction, Link(), false);
+ }
+ else
+ {
+ // Bei leerer URL das Directory nehmen
+ INetURLObject aURLObj( aPathToFile );
+ aAction = aURLObj.GetPartBeforeLastName();
+ }
+ aTmp <<= OUString(aAction);
+ xFormPropSet->setPropertyValue( OUString::createFromAscii( "TargetURL" ),
+ aTmp );
+
+ FormSubmitMethod eMethod = (FormSubmitMethod)nMethod;
+ aTmp.setValue( &eMethod, ::getCppuType((const FormSubmitMethod*)0) );
+ xFormPropSet->setPropertyValue( OUString::createFromAscii( "SubmitMethod" ),
+ aTmp );
+
+ FormSubmitEncoding eEncType = (FormSubmitEncoding)nEncType;
+ aTmp.setValue( &eEncType, ::getCppuType((const FormSubmitEncoding*)0) );
+ xFormPropSet->setPropertyValue(
+ OUString::createFromAscii( "SubmitEncoding" ), aTmp );
+
+ if( sTarget.Len() )
+ {
+ aTmp <<= OUString(sTarget);
+ xFormPropSet->setPropertyValue(
+ OUString::createFromAscii( "TargetFrame" ), aTmp );
+ }
+
+ const uno::Reference< container::XIndexContainer > & rForms =
+ pFormImpl->GetForms();
+ Any aAny( &xForm, ::getCppuType((uno::Reference< XForm>*)0) );
+ rForms->insertByIndex( rForms->getCount(), aAny );
+ if( aMacroTbl.Count() )
+ lcl_html_setEvents( pFormImpl->GetFormEventManager(),
+ rForms->getCount() - 1,
+ aMacroTbl, aUnoMacroTbl, aUnoMacroParamTbl,
+ rDfltScriptType );
+}
+
+void SwHTMLParser::EndForm( sal_Bool bAppend )
+{
+ if( pFormImpl && pFormImpl->GetFormComps().is() )
+ {
+ if( bAppend )
+ {
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_SPACE );
+ else
+ AddParSpace();
+ }
+
+ pFormImpl->ReleaseFormComps();
+ }
+}
+
+void SwHTMLParser::InsertInput()
+{
+ if( pPendStack )
+ {
+ SetPendingControlSize( HTML_INPUT );
+ return;
+ }
+
+ if( !pFormImpl || !pFormImpl->GetFormComps().is() )
+ return;
+
+ String sImgSrc, aId, aClass, aStyle, sText;
+ String sName;
+ SvxMacroTableDtor aMacroTbl;
+ SvStringsDtor aUnoMacroTbl;
+ SvStringsDtor aUnoMacroParamTbl;
+ sal_uInt16 nSize = 0;
+ sal_Int16 nMaxLen = 0;
+ sal_Int16 nChecked = STATE_NOCHECK;
+ sal_Int32 nTabIndex = TABINDEX_MAX + 1;
+ HTMLInputType eType = HTML_IT_TEXT;
+ sal_Bool bDisabled = sal_False, bValue = sal_False;
+ sal_Bool bSetGrfWidth = sal_False, bSetGrfHeight = sal_False;
+ sal_Bool bHidden = sal_False;
+ long nWidth=0, nHeight=0;
+ sal_Int16 eVertOri = text::VertOrientation::TOP;
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+ SvKeyValueIterator *pHeaderAttrs = pFormImpl->GetHeaderAttrs();
+ ScriptType eDfltScriptType = GetScriptType( pHeaderAttrs );
+ const String& rDfltScriptType = GetScriptTypeString( pHeaderAttrs );
+
+ sal_uInt16 nKeepCRLFToken = HTML_O_VALUE;
+ const HTMLOptions *pHTMLOptions = GetOptions( &nKeepCRLFToken );
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ ScriptType eScriptType2 = eDfltScriptType;
+ sal_uInt16 nEvent;
+ sal_Bool bSetEvent = sal_False;
+
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_TYPE:
+ eType = pOption->GetInputType();
+ break;
+ case HTML_O_NAME:
+ sName = pOption->GetString();
+ break;
+ case HTML_O_VALUE:
+ sText = pOption->GetString();
+ bValue = sal_True;
+ break;
+ case HTML_O_CHECKED:
+ nChecked = STATE_CHECK;
+ break;
+ case HTML_O_DISABLED:
+ bDisabled = sal_True;
+ break;
+ case HTML_O_MAXLENGTH:
+ nMaxLen = (sal_Int16)pOption->GetNumber();
+ break;
+ case HTML_O_SIZE:
+ nSize = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_SRC:
+ sImgSrc = pOption->GetString();
+ break;
+ case HTML_O_WIDTH:
+ // erstmal nur als Pixelwerte merken!
+ nWidth = pOption->GetNumber();
+ break;
+ case HTML_O_HEIGHT:
+ // erstmal nur als Pixelwerte merken!
+ nHeight = pOption->GetNumber();
+ break;
+ case HTML_O_ALIGN:
+ eVertOri =
+ pOption->GetEnum( aHTMLImgVAlignTable, eVertOri );
+ eHoriOri =
+ pOption->GetEnum( aHTMLImgHAlignTable, eHoriOri );
+ break;
+ case HTML_O_TABINDEX:
+ // erstmal nur als Pixelwerte merken!
+ nTabIndex = pOption->GetNumber();
+ break;
+
+ case HTML_O_SDONFOCUS:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONFOCUS:
+ nEvent = HTML_ET_ONGETFOCUS;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONBLUR: // eigtl. nur EDIT
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONBLUR:
+ nEvent = HTML_ET_ONLOSEFOCUS;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONCLICK:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONCLICK:
+ nEvent = HTML_ET_ONCLICK;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONCHANGE: // eigtl. nur EDIT
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONCHANGE:
+ nEvent = HTML_ET_ONCHANGE;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONSELECT: // eigtl. nur EDIT
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONSELECT:
+ nEvent = HTML_ET_ONSELECT;
+ bSetEvent = sal_True;
+ break;
+
+ default:
+ lcl_html_getEvents( pOption->GetTokenString(),
+ pOption->GetString(),
+ aUnoMacroTbl, aUnoMacroParamTbl );
+ break;
+ }
+
+ if( bSetEvent )
+ {
+ String sEvent( pOption->GetString() );
+ if( sEvent.Len() )
+ {
+ sEvent.ConvertLineEnd();
+ String aScriptType2;
+ if( EXTENDED_STYPE==eScriptType2 )
+ aScriptType2 = rDfltScriptType;
+ aMacroTbl.Insert( nEvent, new SvxMacro( sEvent, aScriptType2,
+ eScriptType2 ) );
+ }
+ }
+ }
+
+ if( HTML_IT_IMAGE==eType )
+ {
+ // Image-Controls ohne Image-URL werden ignoriert (wie bei MS)
+ if( !sImgSrc.Len() )
+ return;
+ }
+ else
+ {
+ // ALIGN fuer alle Controls auszuwerten ist keine so gute Idee,
+ // solange Absatz-gebundene Controls die Hoehe von Tabellen-Zellen
+ // nicht beeinflussen
+ // (#64110#, http://www.telekom.de/katalog-online/onlineshop.html)
+ eVertOri = text::VertOrientation::TOP;
+ eHoriOri = text::HoriOrientation::NONE;
+ }
+
+ // Defaults entsprechen HTML_IT_TEXT
+ const sal_Char *pType = "TextField";
+ sal_Bool bKeepCRLFInValue = sal_False;
+ switch( eType )
+ {
+ case HTML_IT_CHECKBOX:
+ pType = "CheckBox";
+ bKeepCRLFInValue = sal_True;
+ break;
+
+ case HTML_IT_RADIO:
+ pType = "RadioButton";
+ bKeepCRLFInValue = sal_True;
+ break;
+
+ case HTML_IT_PASSWORD:
+ bKeepCRLFInValue = sal_True;
+ break;
+
+ case HTML_IT_BUTTON:
+ bKeepCRLFInValue = sal_True;
+ case HTML_IT_SUBMIT:
+ case HTML_IT_RESET:
+ pType = "CommandButton";
+ break;
+
+ case HTML_IT_IMAGE:
+ pType = "ImageButton";
+ break;
+
+ case HTML_IT_FILE:
+ pType = "FileControl";
+ break;
+
+ case HTML_IT_HIDDEN:
+ pType = "HiddenControl";
+ bKeepCRLFInValue = sal_True;
+ break;
+ default:
+ ;
+ }
+
+ // Fuer ein par Controls mussen CR/LF noch aus dem VALUE
+ // geloescht werden.
+ if( !bKeepCRLFInValue )
+ {
+ sText.EraseAllChars( _CR );
+ sText.EraseAllChars( _LF );
+ }
+
+ const uno::Reference< XMultiServiceFactory > & rServiceFactory =
+ pFormImpl->GetServiceFactory();
+ if( !rServiceFactory.is() )
+ return;
+
+ String sServiceName(
+ OUString::createFromAscii("com.sun.star.form.component.") );
+ sServiceName.AppendAscii( pType );
+ uno::Reference< XInterface > xInt =
+ rServiceFactory->createInstance( sServiceName );
+ if( !xInt.is() )
+ return;
+
+ uno::Reference< XFormComponent > xFComp( xInt, UNO_QUERY );
+ if( !xFComp.is() )
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xFComp, UNO_QUERY );
+
+ Any aTmp;
+ aTmp <<= OUString(sName);
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Name" ), aTmp );
+
+ if( HTML_IT_HIDDEN != eType )
+ {
+ if( nTabIndex >= TABINDEX_MIN && nTabIndex <= TABINDEX_MAX )
+ {
+ aTmp <<= (sal_Int16) (sal_Int16)nTabIndex ;
+ xPropSet->setPropertyValue( OUString::createFromAscii( "TabIndex" ), aTmp );
+ }
+
+ if( bDisabled )
+ {
+ BOOL bFalse = sal_False;
+ aTmp.setValue(&bFalse, ::getBooleanCppuType() );
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Enabled" ), aTmp );
+ }
+ }
+
+ aTmp <<= OUString(sText);
+
+ Size aSz( 0, 0 ); // defaults
+ Size aTextSz( 0, 0 ); // Text-Size
+ sal_Bool bMinWidth = sal_False, bMinHeight = sal_False;
+ sal_Bool bUseSize = sal_False;
+ switch( eType )
+ {
+ case HTML_IT_CHECKBOX:
+ case HTML_IT_RADIO:
+ {
+ if( !bValue )
+ aTmp <<= OUString::createFromAscii( OOO_STRING_SVTOOLS_HTML_on );
+ xPropSet->setPropertyValue( OUString::createFromAscii( "RefValue" ),
+ aTmp );
+ aTmp <<= OUString();
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Label" ),
+ aTmp );
+ // #53559#: Beim RadioButton darf die DefaultChecked-Property
+ // erst gesetzt werden, wenn das Control angelegt und ein
+ // activateTabOrder gerufen wurde, weil es sonst noch zu der
+ // vorhergehenden Gruppe gehoert.
+ if( HTML_IT_CHECKBOX == eType )
+ {
+ aTmp <<= (sal_Int16) nChecked ;
+ xPropSet->setPropertyValue(
+ OUString::createFromAscii( "DefaultState" ), aTmp );
+ }
+
+ SvxMacro *pMacro = aMacroTbl.Get( HTML_ET_ONCLICK );
+ if( pMacro )
+ {
+ aMacroTbl.Remove( HTML_ET_ONCLICK );
+ aMacroTbl.Insert( HTML_ET_ONCLICK_ITEM, pMacro );
+ }
+ // SIZE auszuwerten duerfte hier keinen Sinn machen???
+ bMinWidth = bMinHeight = sal_True;
+ }
+ break;
+
+ case HTML_IT_IMAGE:
+ {
+ // SIZE = WIDTH
+ aSz.Width() = nSize ? nSize : nWidth;
+ aSz.Width() = nWidth;
+ aSz.Height() = nHeight;
+ if( (aSz.Width() || aSz.Height()) && Application::GetDefaultDevice() )
+ {
+ aSz = Application::GetDefaultDevice()
+ ->PixelToLogic( aSz, MapMode( MAP_100TH_MM ) );
+ }
+ FormButtonType eButtonType = FormButtonType_SUBMIT;
+ aTmp.setValue( &eButtonType,
+ ::getCppuType((const FormButtonType*)0));
+ xPropSet->setPropertyValue(
+ OUString::createFromAscii( "ButtonType" ), aTmp );
+
+ aTmp <<= (sal_Int16) 0 ;
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Border" ),
+ aTmp );
+ }
+ break;
+
+ case HTML_IT_BUTTON:
+ case HTML_IT_SUBMIT:
+ case HTML_IT_RESET:
+ {
+ FormButtonType eButtonType;
+ switch( eType )
+ {
+ case HTML_IT_BUTTON:
+ eButtonType = FormButtonType_PUSH;
+ break;
+ case HTML_IT_SUBMIT:
+ eButtonType = FormButtonType_SUBMIT;
+ if( !sText.Len() )
+ sText.AssignAscii( OOO_STRING_SVTOOLS_HTML_IT_submit );
+ break;
+ case HTML_IT_RESET:
+ eButtonType = FormButtonType_RESET;
+ if( !sText.Len() )
+ sText.AssignAscii( OOO_STRING_SVTOOLS_HTML_IT_reset );
+ break;
+ default:
+ ;
+ }
+ aTmp <<= OUString(sText);
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Label" ),
+ aTmp );
+
+ aTmp.setValue( &eButtonType,
+ ::getCppuType((const FormButtonType*)0));
+ xPropSet->setPropertyValue(
+ OUString::createFromAscii( "ButtonType" ), aTmp );
+
+ bMinWidth = bMinHeight = sal_True;
+ bUseSize = sal_True;
+ }
+ break;
+
+ case HTML_IT_PASSWORD:
+ case HTML_IT_TEXT:
+ case HTML_IT_FILE:
+ if( HTML_IT_FILE != eType )
+ {
+ // Beim File-Control wird der VALUE aus Sicherheitsgruenden ignoriert.
+ xPropSet->setPropertyValue(
+ OUString::createFromAscii( "DefaultText" ), aTmp );
+ if( nMaxLen != 0 )
+ {
+ aTmp <<= (sal_Int16) nMaxLen ;
+ xPropSet->setPropertyValue(
+ OUString::createFromAscii( "MaxTextLen" ), aTmp );
+ }
+ }
+
+ if( HTML_IT_PASSWORD == eType )
+ {
+ aTmp <<= (sal_Int16)'*' ;
+ xPropSet->setPropertyValue( OUString::createFromAscii( "EchoChar" ),
+ aTmp );
+ }
+
+ lcl_html_setFixedFontProperty( xPropSet );
+
+ if( !nSize )
+ nSize = 20;
+ aTextSz.Width() = nSize;
+ bMinHeight = sal_True;
+ break;
+
+ case HTML_IT_HIDDEN:
+ xPropSet->setPropertyValue( OUString::createFromAscii( "HiddenValue" ),
+ aTmp );
+ bHidden = sal_True;
+ break;
+ default:
+ ;
+ }
+
+ if( bUseSize && nSize>0 )
+ {
+ if( Application::GetDefaultDevice() )
+ {
+ Size aNewSz( nSize, 0 );
+ aNewSz = Application::GetDefaultDevice()
+ ->PixelToLogic( aNewSz, MapMode( MAP_100TH_MM ) );
+ aSz.Width() = aNewSz.Width();
+ ASSERT( !aTextSz.Width(), "Text-Breite ist gegeben" );
+ bMinWidth = sal_False;
+ }
+ }
+
+ SfxItemSet aCSS1ItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aCSS1PropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ {
+ ParseStyleOptions( aStyle, aId, aClass, aCSS1ItemSet, aCSS1PropInfo );
+ if( aId.Len() )
+ InsertBookmark( aId );
+ }
+
+ if( SVX_CSS1_LTYPE_TWIP== aCSS1PropInfo.eWidthType )
+ {
+ aSz.Width() = TWIP_TO_MM100( aCSS1PropInfo.nWidth );
+ aTextSz.Width() = 0;
+ bMinWidth = sal_False;
+ }
+ if( SVX_CSS1_LTYPE_TWIP== aCSS1PropInfo.eHeightType )
+ {
+ aSz.Height() = TWIP_TO_MM100( aCSS1PropInfo.nHeight );
+ aTextSz.Height() = 0;
+ bMinHeight = sal_False;
+ }
+
+ // Beim Image-Button bei nicht gegebern Groesse einen sinnvollen Default
+ // setzen
+ if( HTML_IT_IMAGE== eType )
+ {
+ if( !aSz.Width() )
+ {
+ aSz.Width() = HTML_DFLT_IMG_WIDTH;
+ bSetGrfWidth = sal_True;
+ if( pTable != 0 )
+ IncGrfsThatResizeTable();
+ }
+ if( !aSz.Height() )
+ {
+ aSz.Height() = HTML_DFLT_IMG_HEIGHT;
+ bSetGrfHeight = sal_True;
+ }
+ }
+ if( aSz.Width() < MINFLY )
+ aSz.Width() = MINFLY;
+ if( aSz.Height() < MINFLY )
+ aSz.Height() = MINFLY;
+
+ uno::Reference< drawing::XShape > xShape = InsertControl(
+ xFComp, xPropSet, aSz,
+ eVertOri, eHoriOri,
+ aCSS1ItemSet, aCSS1PropInfo,
+ aMacroTbl, aUnoMacroTbl,
+ aUnoMacroParamTbl, sal_False,
+ bHidden );
+ if( aTextSz.Width() || aTextSz.Height() || bMinWidth || bMinHeight )
+ {
+ ASSERT( !(bSetGrfWidth || bSetGrfHeight), "Grafikgroesse anpassen???" );
+ SetControlSize( xShape, aTextSz, bMinWidth, bMinHeight, HTML_INPUT );
+ }
+
+ if( HTML_IT_RADIO == eType )
+ {
+ aTmp <<= (sal_Int16) nChecked ;
+ xPropSet->setPropertyValue( OUString::createFromAscii( "DefaultState" ), aTmp );
+ }
+
+ if( HTML_IT_IMAGE == eType )
+ {
+ // Die URL erst nach dem Einfuegen setzen, weil sich der
+ // Download der Grafik erst dann am XModel anmelden kann,
+ // wenn das Control eingefuegt ist.
+ aTmp <<= OUString( URIHelper::SmartRel2Abs(INetURLObject(sBaseURL), sImgSrc, Link(), false));
+ xPropSet->setPropertyValue( OUString::createFromAscii( "ImageURL" ),
+ aTmp );
+ }
+
+ if( bSetGrfWidth || bSetGrfHeight )
+ {
+ SwHTMLImageWatcher* pWatcher =
+ new SwHTMLImageWatcher( xShape, bSetGrfWidth, bSetGrfHeight );
+ uno::Reference< awt::XImageConsumer > xCons = pWatcher;
+ pWatcher->start();
+ }
+}
+
+void SwHTMLParser::NewTextArea()
+{
+ if( pPendStack )
+ {
+ SetPendingControlSize( HTML_TEXTAREA_ON );
+ return;
+ }
+
+ ASSERT( !bTextArea, "TextArea in TextArea???" );
+ ASSERT( !pFormImpl || !pFormImpl->GetFCompPropSet().is(),
+ "TextArea in Control???" );
+
+ if( !pFormImpl || !pFormImpl->GetFormComps().is() )
+ {
+ // Spezialbehandlung fuer TextArea auch untem im Parser beenden
+ FinishTextArea();
+ return;
+ }
+
+ String aId, aClass, aStyle;
+ String sName;
+ sal_Int32 nTabIndex = TABINDEX_MAX + 1;
+ SvxMacroTableDtor aMacroTbl;
+ SvStringsDtor aUnoMacroTbl;
+ SvStringsDtor aUnoMacroParamTbl;
+ sal_uInt16 nRows = 0, nCols = 0;
+ sal_uInt16 nWrap = HTML_WM_OFF;
+ sal_Bool bDisabled = sal_False;
+ SvKeyValueIterator *pHeaderAttrs = pFormImpl->GetHeaderAttrs();
+ ScriptType eDfltScriptType = GetScriptType( pHeaderAttrs );
+ const String& rDfltScriptType = GetScriptTypeString( pHeaderAttrs );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ ScriptType eScriptType2 = eDfltScriptType;
+ sal_uInt16 nEvent;
+ sal_Bool bSetEvent = sal_False;
+
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_NAME:
+ sName = pOption->GetString();
+ break;
+ case HTML_O_DISABLED:
+ bDisabled = sal_True;
+ break;
+ case HTML_O_ROWS:
+ nRows = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_COLS:
+ nCols = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_WRAP:
+ nWrap = pOption->GetEnum( aHTMLTextAreaWrapTable, nWrap );
+ break;
+
+ case HTML_O_TABINDEX:
+ nTabIndex = pOption->GetSNumber();
+ break;
+
+ case HTML_O_SDONFOCUS:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONFOCUS:
+ nEvent = HTML_ET_ONGETFOCUS;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONBLUR:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONBLUR:
+ nEvent = HTML_ET_ONLOSEFOCUS;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONCLICK:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONCLICK:
+ nEvent = HTML_ET_ONCLICK;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONCHANGE:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONCHANGE:
+ nEvent = HTML_ET_ONCHANGE;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONSELECT:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONSELECT:
+ nEvent = HTML_ET_ONSELECT;
+ bSetEvent = sal_True;
+ break;
+
+ default:
+ lcl_html_getEvents( pOption->GetTokenString(),
+ pOption->GetString(),
+ aUnoMacroTbl, aUnoMacroParamTbl );
+ break;
+ }
+
+ if( bSetEvent )
+ {
+ String sEvent( pOption->GetString() );
+ if( sEvent.Len() )
+ {
+ sEvent.ConvertLineEnd();
+ if( EXTENDED_STYPE==eScriptType2 )
+ aScriptType = rDfltScriptType;
+ aMacroTbl.Insert( nEvent, new SvxMacro( sEvent, aScriptType,
+ eScriptType2 ) );
+ }
+ }
+ }
+
+
+ const uno::Reference< lang::XMultiServiceFactory > & rSrvcMgr =
+ pFormImpl->GetServiceFactory();
+ if( !rSrvcMgr.is() )
+ {
+ FinishTextArea();
+ return;
+ }
+ uno::Reference< uno::XInterface > xInt = rSrvcMgr->createInstance(
+ OUString::createFromAscii( "com.sun.star.form.component.TextField" ) );
+ if( !xInt.is() )
+ {
+ FinishTextArea();
+ return;
+ }
+
+ uno::Reference< XFormComponent > xFComp( xInt, UNO_QUERY );
+ DBG_ASSERT( xFComp.is(), "keine FormComponent?" );
+
+ uno::Reference< beans::XPropertySet > xPropSet( xFComp, UNO_QUERY );
+
+ Any aTmp;
+ aTmp <<= OUString(sName);
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Name" ), aTmp );
+
+ BOOL bTrue = sal_True;
+ aTmp.setValue( &bTrue, ::getBooleanCppuType() );
+ xPropSet->setPropertyValue( OUString::createFromAscii( "MultiLine" ),
+ aTmp );
+ xPropSet->setPropertyValue( OUString::createFromAscii( "VScroll" ), aTmp );
+ if( HTML_WM_OFF == nWrap )
+ xPropSet->setPropertyValue( OUString::createFromAscii( "HScroll" ),
+ aTmp );
+ if( HTML_WM_HARD == nWrap )
+ xPropSet->setPropertyValue(
+ OUString::createFromAscii( "HardLineBreaks" ), aTmp );
+
+ if( nTabIndex >= TABINDEX_MIN && nTabIndex <= TABINDEX_MAX )
+ {
+ aTmp <<= (sal_Int16)nTabIndex ;
+ xPropSet->setPropertyValue( OUString::createFromAscii( "TabIndex" ),
+ aTmp );
+ }
+
+ lcl_html_setFixedFontProperty( xPropSet );
+
+ if( bDisabled )
+ {
+ BOOL bFalse = sal_False;
+ aTmp.setValue( &bFalse, ::getBooleanCppuType() );
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Enabled" ),
+ aTmp );
+ }
+
+ ASSERT( !pFormImpl->GetText().Len(), "Text ist nicht leer!" );
+
+ if( !nCols )
+ nCols = 20;
+ if( !nRows )
+ nRows = 1;
+
+ Size aTextSz( nCols, nRows );
+
+ SfxItemSet aCSS1ItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aCSS1PropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ {
+ ParseStyleOptions( aStyle, aId, aClass, aCSS1ItemSet, aCSS1PropInfo );
+ if( aId.Len() )
+ InsertBookmark( aId );
+ }
+
+ Size aSz( MINFLY, MINFLY );
+ if( SVX_CSS1_LTYPE_TWIP== aCSS1PropInfo.eWidthType )
+ {
+ aSz.Width() = TWIP_TO_MM100( aCSS1PropInfo.nWidth );
+ aTextSz.Width() = 0;
+ }
+ if( SVX_CSS1_LTYPE_TWIP== aCSS1PropInfo.eHeightType )
+ {
+ aSz.Height() = TWIP_TO_MM100( aCSS1PropInfo.nHeight );
+ aTextSz.Height() = 0;
+ }
+ if( aSz.Width() < MINFLY )
+ aSz.Width() = MINFLY;
+ if( aSz.Height() < MINFLY )
+ aSz.Height() = MINFLY;
+
+ uno::Reference< drawing::XShape > xShape = InsertControl( xFComp, xPropSet, aSz,
+ text::VertOrientation::TOP, text::HoriOrientation::NONE,
+ aCSS1ItemSet, aCSS1PropInfo,
+ aMacroTbl, aUnoMacroTbl,
+ aUnoMacroParamTbl );
+ if( aTextSz.Width() || aTextSz.Height() )
+ SetControlSize( xShape, aTextSz, sal_False, sal_False,
+ HTML_TEXTAREA_ON );
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_TEXTAREA_ON );
+
+ // und PRE/Listing/XMP voruebergehend aussetzen
+ SplitPREListingXMP( pCntxt );
+ PushContext( pCntxt );
+
+ bTextArea = sal_True;
+ bTAIgnoreNewPara = sal_True;
+}
+
+void SwHTMLParser::EndTextArea()
+{
+ ASSERT( bTextArea, "keine TextArea oder falscher Typ" );
+ ASSERT( pFormImpl && pFormImpl->GetFCompPropSet().is(),
+ "TextArea fehlt" );
+
+ const uno::Reference< beans::XPropertySet > & rPropSet =
+ pFormImpl->GetFCompPropSet();
+
+ Any aTmp;
+ aTmp <<= OUString(pFormImpl->GetText());
+ rPropSet->setPropertyValue( OUString::createFromAscii( "DefaultText" ),
+ aTmp );
+ pFormImpl->EraseText();
+
+ pFormImpl->ReleaseFCompPropSet();
+
+ // den Kontext holen
+ _HTMLAttrContext *pCntxt = PopContext( HTML_TEXTAREA_ON );
+ if( pCntxt )
+ {
+ // und ggf. die Attribute beenden
+ EndContext( pCntxt );
+ delete pCntxt;
+ }
+
+ bTextArea = sal_False;
+}
+
+
+void SwHTMLParser::InsertTextAreaText( sal_uInt16 nToken )
+{
+ ASSERT( bTextArea, "keine TextArea oder falscher Typ" );
+ ASSERT( pFormImpl && pFormImpl->GetFCompPropSet().is(),
+ "TextArea fehlt" );
+
+ String& rText = pFormImpl->GetText();
+ switch( nToken)
+ {
+ case HTML_TEXTTOKEN:
+ rText += aToken;
+ break;
+ case HTML_NEWPARA:
+ if( !bTAIgnoreNewPara )
+ rText += '\n'; // das ist hier richtig!!!
+ break;
+ default:
+ rText += '<';
+ rText += sSaveToken;
+ if( aToken.Len() )
+ {
+ rText += ' ';
+ rText += aToken;
+ }
+ rText += '>';
+ }
+
+ bTAIgnoreNewPara = sal_False;
+}
+
+void SwHTMLParser::NewSelect()
+{
+ if( pPendStack )
+ {
+ SetPendingControlSize( HTML_SELECT_ON );
+ return;
+ }
+
+ ASSERT( !bSelect, "Select in Select???" );
+ ASSERT( !pFormImpl || !pFormImpl->GetFCompPropSet().is(),
+ "Select in Control???" );
+
+ if( !pFormImpl || !pFormImpl->GetFormComps().is() )
+ return;
+
+ String aId, aClass, aStyle;
+ String sName;
+ sal_Int32 nTabIndex = TABINDEX_MAX + 1;
+ SvxMacroTableDtor aMacroTbl;
+ SvStringsDtor aUnoMacroTbl;
+ SvStringsDtor aUnoMacroParamTbl;
+ sal_Bool bMultiple = sal_False;
+ sal_Bool bDisabled = sal_False;
+ nSelectEntryCnt = 1;
+ SvKeyValueIterator *pHeaderAttrs = pFormImpl->GetHeaderAttrs();
+ ScriptType eDfltScriptType = GetScriptType( pHeaderAttrs );
+ const String& rDfltScriptType = GetScriptTypeString( pHeaderAttrs );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ ScriptType eScriptType2 = eDfltScriptType;
+ sal_uInt16 nEvent;
+ sal_Bool bSetEvent = sal_False;
+
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_NAME:
+ sName = pOption->GetString();
+ break;
+ case HTML_O_MULTIPLE:
+ bMultiple = sal_True;
+ break;
+ case HTML_O_DISABLED:
+ bDisabled = sal_True;
+ break;
+ case HTML_O_SIZE:
+ nSelectEntryCnt = (sal_uInt16)pOption->GetNumber();
+ break;
+
+ case HTML_O_TABINDEX:
+ nTabIndex = pOption->GetSNumber();
+ break;
+
+ case HTML_O_SDONFOCUS:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONFOCUS:
+ nEvent = HTML_ET_ONGETFOCUS;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONBLUR:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONBLUR:
+ nEvent = HTML_ET_ONLOSEFOCUS;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONCLICK:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONCLICK:
+ nEvent = HTML_ET_ONCLICK;
+ bSetEvent = sal_True;
+ break;
+
+ case HTML_O_SDONCHANGE:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONCHANGE:
+ nEvent = HTML_ET_ONCHANGE;
+ bSetEvent = sal_True;
+ break;
+
+ default:
+ lcl_html_getEvents( pOption->GetTokenString(),
+ pOption->GetString(),
+ aUnoMacroTbl, aUnoMacroParamTbl );
+ break;
+ }
+
+ if( bSetEvent )
+ {
+ String sEvent( pOption->GetString() );
+ if( sEvent.Len() )
+ {
+ sEvent.ConvertLineEnd();
+ if( EXTENDED_STYPE==eScriptType2 )
+ aScriptType = rDfltScriptType;
+ aMacroTbl.Insert( nEvent, new SvxMacro( sEvent, aScriptType,
+ eScriptType2 ) );
+ }
+ }
+ }
+
+ const uno::Reference< lang::XMultiServiceFactory > & rSrvcMgr =
+ pFormImpl->GetServiceFactory();
+ if( !rSrvcMgr.is() )
+ {
+ FinishTextArea();
+ return;
+ }
+ uno::Reference< uno::XInterface > xInt = rSrvcMgr->createInstance(
+ OUString::createFromAscii( "com.sun.star.form.component.ListBox" ) );
+ if( !xInt.is() )
+ {
+ FinishTextArea();
+ return;
+ }
+
+ uno::Reference< XFormComponent > xFComp( xInt, UNO_QUERY );
+ DBG_ASSERT(xFComp.is(), "keine FormComponent?");
+
+ uno::Reference< beans::XPropertySet > xPropSet( xFComp, UNO_QUERY );
+
+ Any aTmp;
+ aTmp <<= OUString(sName);
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Name" ), aTmp );
+
+ if( nTabIndex >= TABINDEX_MIN && nTabIndex <= TABINDEX_MAX )
+ {
+ aTmp <<= (sal_Int16)nTabIndex ;
+ xPropSet->setPropertyValue( OUString::createFromAscii( "TabIndex" ),
+ aTmp );
+ }
+
+ if( bDisabled )
+ {
+ BOOL bFalse = sal_False;
+ aTmp.setValue( &bFalse, ::getBooleanCppuType() );
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Enabled" ),
+ aTmp );
+ }
+
+ Size aTextSz( 0, 0 );
+ sal_Bool bMinWidth = sal_True, bMinHeight = sal_True;
+ if( !bMultiple && 1==nSelectEntryCnt )
+ {
+ BOOL bTrue = sal_True;
+ aTmp.setValue( &bTrue, ::getBooleanCppuType() );
+ xPropSet->setPropertyValue( OUString::createFromAscii( "Dropdown" ),
+ aTmp );
+ }
+ else
+ {
+ if( nSelectEntryCnt <= 1 ) // 4 Zeilen als default
+ nSelectEntryCnt = 4;
+
+ if( bMultiple )
+ {
+ BOOL bTrue = sal_True;
+ aTmp.setValue( &bTrue, ::getBooleanCppuType() );
+ xPropSet->setPropertyValue(
+ OUString::createFromAscii( "MultiSelection" ), aTmp );
+ }
+ aTextSz.Height() = nSelectEntryCnt;
+ bMinHeight = sal_False;
+ }
+
+ SfxItemSet aCSS1ItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aCSS1PropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ {
+ ParseStyleOptions( aStyle, aId, aClass, aCSS1ItemSet, aCSS1PropInfo );
+ if( aId.Len() )
+ InsertBookmark( aId );
+ }
+
+ Size aSz( MINFLY, MINFLY );
+ bFixSelectWidth = bFixSelectHeight = sal_True;
+ if( SVX_CSS1_LTYPE_TWIP== aCSS1PropInfo.eWidthType )
+ {
+ aSz.Width() = TWIP_TO_MM100( aCSS1PropInfo.nWidth );
+ bFixSelectWidth = sal_False;
+ bMinWidth = sal_False;
+ }
+ if( SVX_CSS1_LTYPE_TWIP== aCSS1PropInfo.eHeightType )
+ {
+ aSz.Height() = TWIP_TO_MM100( aCSS1PropInfo.nHeight );
+ aTextSz.Height() = sal_False;
+ bMinHeight = sal_False;
+ }
+ if( aSz.Width() < MINFLY )
+ aSz.Width() = MINFLY;
+ if( aSz.Height() < MINFLY )
+ aSz.Height() = MINFLY;
+
+ uno::Reference< drawing::XShape > xShape = InsertControl( xFComp, xPropSet, aSz,
+ text::VertOrientation::TOP, text::HoriOrientation::NONE,
+ aCSS1ItemSet, aCSS1PropInfo,
+ aMacroTbl, aUnoMacroTbl,
+ aUnoMacroParamTbl );
+ if( bFixSelectWidth )
+ pFormImpl->SetShape( xShape );
+ if( aTextSz.Height() || bMinWidth || bMinHeight )
+ SetControlSize( xShape, aTextSz, bMinWidth, bMinHeight,
+ HTML_SELECT_ON );
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_SELECT_ON );
+
+ // und PRE/Listing/XMP voruebergehend aussetzen
+ SplitPREListingXMP( pCntxt );
+ PushContext( pCntxt );
+
+ bSelect = sal_True;
+}
+
+void SwHTMLParser::EndSelect()
+{
+ if( pPendStack )
+ {
+ SetPendingControlSize( HTML_SELECT_OFF );
+ return;
+ }
+
+ ASSERT( bSelect, "keine Select" );
+ ASSERT( pFormImpl && pFormImpl->GetFCompPropSet().is(),
+ "kein Select-Control" );
+
+ const uno::Reference< beans::XPropertySet > & rPropSet =
+ pFormImpl->GetFCompPropSet();
+
+ // die Groesse anpassen
+ Size aNewSz( MINFLY, MINFLY );
+
+ sal_uInt16 nEntryCnt = pFormImpl->GetStringList().Count();
+ if( nEntryCnt )
+ {
+ Sequence<OUString> aList( (sal_Int32)nEntryCnt );
+ Sequence<OUString> aValueList( (sal_Int32)nEntryCnt );
+ OUString *pStrings = aList.getArray();
+ OUString *pValues = aValueList.getArray();
+ sal_uInt16 i;
+
+ for( i = 0; i < nEntryCnt; i++ )
+ {
+ String sText( *pFormImpl->GetStringList()[i] );
+ sText.EraseTrailingChars();
+ pStrings[i] = sText;
+
+ sText = *pFormImpl->GetValueList()[i];
+ pValues[i] = sText;
+ }
+
+ Any aAny( &aList, ::getCppuType((uno::Sequence<OUString>*)0) );
+
+ rPropSet->setPropertyValue(
+ OUString::createFromAscii( "StringItemList" ), aAny );
+
+ aAny <<= ListSourceType_VALUELIST;
+ rPropSet->setPropertyValue(
+ OUString::createFromAscii( "ListSourceType" ), aAny );
+
+ aAny.setValue( &aValueList, ::getCppuType((uno::Sequence<OUString>*)0) );
+
+ rPropSet->setPropertyValue( OUString::createFromAscii( "ListSource" ),
+ aAny );
+
+ sal_uInt16 nSelCnt = pFormImpl->GetSelectedList().Count();
+ if( !nSelCnt && 1 == nSelectEntryCnt && nEntryCnt )
+ {
+ // In einer DropDown-Listbox sollte immer ein Eintrag selektiert
+ // sein.
+ pFormImpl->GetSelectedList().Insert( (sal_uInt16)0, (sal_uInt16)0 );
+ nSelCnt = 1;
+ }
+ Sequence<sal_Int16> aSelList( (sal_Int32)nSelCnt );
+ sal_Int16 *pSels = aSelList.getArray();
+ for( i=0; i<nSelCnt; i++ )
+ {
+ pSels[i] = (sal_Int16)pFormImpl->GetSelectedList()[i];
+ }
+ aAny.setValue( &aSelList,
+ ::getCppuType((uno::Sequence<sal_Int16>*)0) );
+
+ rPropSet->setPropertyValue(
+ OUString::createFromAscii( "DefaultSelection" ), aAny );
+
+ pFormImpl->EraseStringList();
+ pFormImpl->EraseValueList();
+ }
+
+ pFormImpl->EraseSelectedList();
+
+ if( bFixSelectWidth )
+ {
+ ASSERT( pFormImpl->GetShape().is(), "Kein Shape gemerkt" );
+ Size aTextSz( -1, 0 );
+ SetControlSize( pFormImpl->GetShape(), aTextSz, sal_False, sal_False,
+ HTML_SELECT_OFF );
+ }
+
+ pFormImpl->ReleaseFCompPropSet();
+
+ // den Kontext holen
+ _HTMLAttrContext *pCntxt = PopContext( HTML_SELECT_ON );
+ if( pCntxt )
+ {
+ // und ggf. die Attribute beenden
+ EndContext( pCntxt );
+ delete pCntxt;
+ }
+
+ bSelect = sal_False;
+}
+
+void SwHTMLParser::InsertSelectOption()
+{
+ ASSERT( bSelect, "keine Select" );
+ ASSERT( pFormImpl && pFormImpl->GetFCompPropSet().is(),
+ "kein Select-Control" );
+
+ bLBEntrySelected = sal_False;
+ String aValue;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ // erstmal weglassen!!!
+ break;
+ case HTML_O_SELECTED:
+ bLBEntrySelected = sal_True;
+ break;
+ case HTML_O_VALUE:
+ aValue = pOption->GetString();
+ if( !aValue.Len() )
+ aValue.AssignAscii( "$$$empty$$$" );
+ break;
+ }
+ }
+
+ sal_uInt16 nEntryCnt = pFormImpl->GetStringList().Count();
+ pFormImpl->GetStringList().Insert( new String( aEmptyStr ), nEntryCnt );
+ pFormImpl->GetValueList().Insert( new String( aValue ), nEntryCnt );
+ if( bLBEntrySelected )
+ pFormImpl->GetSelectedList().Insert( nEntryCnt,
+ pFormImpl->GetSelectedList().Count() );
+}
+
+void SwHTMLParser::InsertSelectText()
+{
+ ASSERT( bSelect, "keine Select" );
+ ASSERT( pFormImpl && pFormImpl->GetFCompPropSet().is(),
+ "kein Select-Control" );
+
+ sal_uInt16 nEntryCnt = pFormImpl->GetStringList().Count();
+ if( nEntryCnt )
+ {
+ String& rText = *pFormImpl->GetStringList()[nEntryCnt-1];
+
+ if( aToken.Len() && ' '==aToken.GetChar( 0 ) )
+ {
+ xub_StrLen nLen = rText.Len();
+ if( !nLen || ' '==rText.GetChar( nLen-1 ))
+ aToken.Erase( 0, 1 );
+ }
+ if( aToken.Len() )
+ rText += aToken;
+ }
+}
+
diff --git a/sw/source/filter/html/htmlform.hxx b/sw/source/filter/html/htmlform.hxx
new file mode 100644
index 000000000000..2deac9db0b5c
--- /dev/null
+++ b/sw/source/filter/html/htmlform.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _HTMLFORM_HXX
+#define _HTMLFORM_HXX
+
+
+enum HTMLEventType
+{
+ HTML_ET_ONSUBMITFORM, HTML_ET_ONRESETFORM,
+ HTML_ET_ONGETFOCUS, HTML_ET_ONLOSEFOCUS,
+ HTML_ET_ONCLICK, HTML_ET_ONCLICK_ITEM,
+ HTML_ET_ONCHANGE, HTML_ET_ONSELECT,
+ HTML_ET_END
+};
+
+extern HTMLEventType __FAR_DATA aEventTypeTable[];
+extern const sal_Char * __FAR_DATA aEventListenerTable[];
+extern const sal_Char * __FAR_DATA aEventMethodTable[];
+extern const sal_Char * __FAR_DATA aEventSDOptionTable[];
+extern const sal_Char * __FAR_DATA aEventOptionTable[];
+
+
+
+
+#endif
+
+
diff --git a/sw/source/filter/html/htmlforw.cxx b/sw/source/filter/html/htmlforw.cxx
new file mode 100644
index 000000000000..85c4e9846857
--- /dev/null
+++ b/sw/source/filter/html/htmlforw.cxx
@@ -0,0 +1,1447 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/form/FormSubmitEncoding.hpp>
+#include <com/sun/star/form/FormSubmitMethod.hpp>
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/script/XEventAttacher.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/awt/XTextLayoutConstrains.hpp>
+#include <hintids.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <svl/macitem.hxx>
+#include <tools/urlobj.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <svl/urihelper.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/fmglob.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <docsh.hxx>
+#include <fmtanchr.hxx>
+#include <docary.hxx>
+#include <viewsh.hxx>
+#include "pam.hxx"
+#include "doc.hxx"
+#include "ndtxt.hxx"
+#include "dcontact.hxx"
+#include "flypos.hxx"
+#include "wrthtml.hxx"
+#include "htmlfly.hxx"
+#include "htmlform.hxx"
+
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+/* */
+
+const sal_uInt32 HTML_FRMOPTS_CONTROL =
+ 0;
+const sal_uInt32 HTML_FRMOPTS_CONTROL_CSS1 =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SIZE |
+ HTML_FRMOPT_S_SPACE |
+ HTML_FRMOPT_BRCLEAR;
+const sal_uInt32 HTML_FRMOPTS_IMG_CONTROL =
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_BRCLEAR;
+const sal_uInt32 HTML_FRMOPTS_IMG_CONTROL_CSS1 =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SPACE;
+
+
+/* */
+
+struct HTMLControl
+{
+ // die Form, zu der das Control gehoert
+ uno::Reference< container::XIndexContainer > xFormComps;
+ ULONG nNdIdx; // der Node, in dem es verankert ist
+ xub_StrLen nCount; // wie viele Controls sind in dem Node
+
+ HTMLControl( const uno::Reference< container::XIndexContainer > & rForm,
+ sal_uInt32 nIdx );
+ ~HTMLControl();
+
+ // operatoren fuer das Sort-Array
+ sal_Bool operator==( const HTMLControl& rCtrl )
+ {
+ return nNdIdx == rCtrl.nNdIdx;
+ }
+ sal_Bool operator<( const HTMLControl& rCtrl )
+ {
+ return nNdIdx < rCtrl.nNdIdx;
+ }
+};
+
+SV_IMPL_OP_PTRARR_SORT( HTMLControls, HTMLControl* )
+
+/* */
+
+void lcl_html_outEvents( SvStream& rStrm,
+ const uno::Reference< form::XFormComponent > rFormComp,
+ sal_Bool bCfgStarBasic,
+ rtl_TextEncoding eDestEnc,
+ String *pNonConvertableChars )
+{
+ uno::Reference< container::XChild > xChild( rFormComp, uno::UNO_QUERY );
+ uno::Reference< uno::XInterface > xParentIfc = xChild->getParent();
+ ASSERT( xParentIfc.is(), "lcl_html_outEvents: no parent interface" );
+ if( !xParentIfc.is() )
+ return;
+ uno::Reference< container::XIndexAccess > xIndexAcc( xParentIfc, uno::UNO_QUERY );
+ uno::Reference< script::XEventAttacherManager > xEventManager( xParentIfc,
+ uno::UNO_QUERY );
+ if( !xIndexAcc.is() || !xEventManager.is() )
+ return;
+
+ // Und die Position des ControlModel darin suchen
+ sal_Int32 nCount = xIndexAcc->getCount(), nPos;
+ for( nPos = 0 ; nPos < nCount; nPos++ )
+ {
+ uno::Any aTmp = xIndexAcc->getByIndex(nPos);
+ ASSERT( aTmp.getValueType() ==
+ ::getCppuType( (uno::Reference<form::XFormComponent>*)0 ) ||
+ aTmp.getValueType() ==
+ ::getCppuType( (uno::Reference<form::XForm>*)0 ),
+ "lcl_html_outEvents: falsche Reflection" );
+ if( aTmp.getValueType() ==
+ ::getCppuType( (uno::Reference< form::XFormComponent >*)0) )
+
+ {
+ if( rFormComp ==
+ *(uno::Reference< form::XFormComponent > *)aTmp.getValue() )
+ break;
+ }
+ else if( aTmp.getValueType() ==
+ ::getCppuType( (uno::Reference< form::XForm>*)0) )
+ {
+ uno::Reference< form::XFormComponent > xFC(
+ *(uno::Reference< form::XForm > *)aTmp.getValue(), uno::UNO_QUERY );
+ if( rFormComp == xFC )
+ break;
+ }
+ }
+
+ if( nPos == nCount )
+ return;
+
+ uno::Sequence< script::ScriptEventDescriptor > aDescs =
+ xEventManager->getScriptEvents( nPos );
+ nCount = aDescs.getLength();
+ if( !nCount )
+ return;
+
+ const script::ScriptEventDescriptor *pDescs = aDescs.getConstArray();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ ScriptType eScriptType = EXTENDED_STYPE;
+ String aScriptType( pDescs[i].ScriptType );
+ if( aScriptType.EqualsIgnoreCaseAscii(SVX_MACRO_LANGUAGE_JAVASCRIPT) )
+ eScriptType = JAVASCRIPT;
+ else if( aScriptType.EqualsIgnoreCaseAscii(SVX_MACRO_LANGUAGE_STARBASIC ) )
+ eScriptType = STARBASIC;
+ if( JAVASCRIPT != eScriptType && !bCfgStarBasic )
+ continue;
+
+ String sListener( pDescs[i].ListenerType );
+ xub_StrLen nTok = sListener.GetTokenCount( '.' );
+ if( nTok )
+ sListener = sListener.GetToken( nTok-1, '.' );
+ String sMethod( pDescs[i].EventMethod );
+
+ const sal_Char *pOpt = 0;
+ for( sal_uInt16 j=0; aEventListenerTable[j]; j++ )
+ {
+ if( sListener.EqualsAscii( aEventListenerTable[j] ) &&
+ sMethod.EqualsAscii( aEventMethodTable[j] ) )
+ {
+ pOpt = (STARBASIC==eScriptType ? aEventSDOptionTable
+ : aEventOptionTable)[j];
+ break;
+ }
+ }
+
+ ByteString sOut( ' ' );
+ if( pOpt && (EXTENDED_STYPE != eScriptType ||
+ !pDescs[i].AddListenerParam.getLength()) )
+ sOut += pOpt;
+ else
+ (((sOut += OOO_STRING_SVTOOLS_HTML_O_sdevent)
+ += ByteString( sListener, RTL_TEXTENCODING_ASCII_US)) += '-')
+ += ByteString( sMethod, RTL_TEXTENCODING_ASCII_US);
+ sOut += "=\"";
+ rStrm << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rStrm, pDescs[i].ScriptCode, eDestEnc, pNonConvertableChars );
+ rStrm << '\"';
+ if( EXTENDED_STYPE == eScriptType &&
+ pDescs[i].AddListenerParam.getLength() )
+ {
+ (((((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_sdaddparam)
+ += ByteString( sListener, RTL_TEXTENCODING_ASCII_US)) += '-')
+ += ByteString( sMethod, RTL_TEXTENCODING_ASCII_US))
+ += "=\"";
+ rStrm << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rStrm, pDescs[i].AddListenerParam,
+ eDestEnc, pNonConvertableChars );
+ rStrm << '\"';
+ }
+ }
+}
+
+sal_Bool lcl_html_isHTMLControl( sal_Int16 nClassId )
+{
+ sal_Bool bRet = sal_False;
+
+ switch( nClassId )
+ {
+ case form::FormComponentType::TEXTFIELD:
+ case form::FormComponentType::COMMANDBUTTON:
+ case form::FormComponentType::RADIOBUTTON:
+ case form::FormComponentType::CHECKBOX:
+ case form::FormComponentType::LISTBOX:
+ case form::FormComponentType::IMAGEBUTTON:
+ case form::FormComponentType::FILECONTROL:
+ bRet = sal_True;
+ break;
+ }
+
+ return bRet;
+}
+
+sal_Bool SwHTMLWriter::HasControls() const
+{
+ sal_uInt32 nStartIdx = pCurPam->GetPoint()->nNode.GetIndex();
+ sal_uInt16 i;
+
+ // Skip all controls in front of the current paragraph
+ for( i = 0; i < aHTMLControls.Count() &&
+ aHTMLControls[i]->nNdIdx < nStartIdx; i++ )
+ ;
+
+ return i < aHTMLControls.Count() && aHTMLControls[i]->nNdIdx == nStartIdx;
+}
+
+void SwHTMLWriter::OutForm( sal_Bool bTag_On, const SwStartNode *pStartNd )
+{
+ if( bPreserveForm ) // wir sind in einer Tabelle oder einem Bereich
+ return; // ueber dem eine Form aufgespannt wurde
+
+ if( !bTag_On )
+ {
+ // die Form beenden wenn alle Controls ausgegeben wurden
+ if( pxFormComps && pxFormComps->is() &&
+ (*pxFormComps)->getCount() == nFormCntrlCnt )
+ {
+ OutForm( sal_False, *pxFormComps );
+ (*pxFormComps) = 0;
+ }
+ return;
+ }
+
+ uno::Reference< container::XIndexContainer > xNewFormComps; // die neue Form
+ sal_uInt32 nStartIdx = pStartNd ? pStartNd->GetIndex()
+ : pCurPam->GetPoint()->nNode.GetIndex();
+
+ // Ueberspringen von Controls vor dem interesanten Bereich
+ sal_uInt16 i;
+ for( i = 0; i < aHTMLControls.Count() &&
+ aHTMLControls[i]->nNdIdx < nStartIdx; i++ )
+ ;
+
+ if( !pStartNd )
+ {
+ // Check fuer einen einzelnen Node: da ist nur interessant, ob
+ // es zu dem Node ein Control gibt und zu welcher Form es gehoert
+ if( i < aHTMLControls.Count() &&
+ aHTMLControls[i]->nNdIdx == nStartIdx )
+ xNewFormComps = aHTMLControls[i]->xFormComps;
+ }
+ else
+ {
+ // wir klappern eine Tabelle/einen Bereich ab: hier interessiert uns:
+ // - ob es Controls mit unterschiedlichen Start-Nodes gibt
+ // - ob es eine Form gibt, fuer die nicht alle Controls in der
+ // Tabelle/dem Bereich liegen
+
+ uno::Reference< container::XIndexContainer > xCurrentFormComps;// die aktuelle Form in der Tabelle
+ const SwStartNode *pCurrentStNd = 0; // und der Start-Node eines Ctrls
+ xub_StrLen nCurrentCtrls = 0; // und die in ihr gefundenen Controls
+ sal_uInt32 nEndIdx = pStartNd->EndOfSectionIndex();
+ for( ; i < aHTMLControls.Count() &&
+ aHTMLControls[i]->nNdIdx <= nEndIdx; i++ )
+ {
+ const SwStartNode *pCntrlStNd =
+ pDoc->GetNodes()[aHTMLControls[i]->nNdIdx]->StartOfSectionNode();
+
+ if( xCurrentFormComps.is() )
+ {
+ // Wir befinden uns bereits in einer Form ...
+ if( xCurrentFormComps==aHTMLControls[i]->xFormComps )
+ {
+ // ... und das Control befindet sich auch darin ...
+ if( pCurrentStNd!=pCntrlStNd )
+ {
+ // ... aber es liegt in einer anderen Zelle:
+ // Dann muessen eir eine Form ueber der Tabelle
+ // aufmachen
+ xNewFormComps = xCurrentFormComps;
+ break;
+ }
+ nCurrentCtrls = nCurrentCtrls + aHTMLControls[i]->nCount;
+ }
+ else
+ {
+ // ... aber das Control liegt in einer anderen Zelle:
+ // Da tun wir so, als ob wir eine neue Form aufmachen
+ // und suchen weiter.
+ xCurrentFormComps = aHTMLControls[i]->xFormComps;
+ pCurrentStNd = pCntrlStNd;
+ nCurrentCtrls = aHTMLControls[i]->nCount;
+ }
+ }
+ else
+ {
+ // Wir befinden uns noch in keiner Form:
+ // Da tun wir mal so, als ob wie wir die Form aufmachen.
+ xCurrentFormComps = aHTMLControls[i]->xFormComps;
+ pCurrentStNd = pCntrlStNd;
+ nCurrentCtrls = aHTMLControls[i]->nCount;
+ }
+ }
+ if( !xNewFormComps.is() && xCurrentFormComps.is() &&
+ nCurrentCtrls != xCurrentFormComps->getCount() )
+ {
+ // In der Tablle/dem Bereich sollte eine Form aufgemacht werden,
+ // die nicht vollstaendig in der Tabelle liegt. Dan muessen
+ // wie die Form jetzt ebenfalls oeffen.
+ xNewFormComps = xCurrentFormComps;
+ }
+ }
+
+ if( xNewFormComps.is() &&
+ (!pxFormComps || !(xNewFormComps == *pxFormComps)) )
+ {
+ // Es soll eine Form aufgemacht werden ...
+ if( pxFormComps && pxFormComps->is() )
+ {
+ // .. es ist aber noch eine Form offen: Das ist in
+ // jedem Fall eine Fehler, aber wir schliessen die alte
+ // Form trotzdem
+ OutForm( sal_False, *pxFormComps );
+
+ //!!!nWarn = 1; // Control wird falscher Form zugeordnet
+ }
+
+ if( !pxFormComps )
+ pxFormComps = new uno::Reference< container::XIndexContainer > ;
+ *pxFormComps = xNewFormComps;
+
+ OutForm( sal_True, *pxFormComps );
+ uno::Reference< beans::XPropertySet > xTmp;
+ OutHiddenControls( *pxFormComps, xTmp );
+ }
+}
+
+void SwHTMLWriter::OutHiddenForms()
+{
+ // Ohne DrawModel kann es auch keine Controls geben. Dann darf man
+ // auch nicht per UNO auf das Dok zugreifen, weil sonst ein DrawModel
+ // angelegt wird.
+ if( !pDoc->GetDrawModel() )
+ return;
+
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ if( !pDocSh )
+ return;
+
+ uno::Reference< drawing::XDrawPageSupplier > xDPSupp( pDocSh->GetBaseModel(),
+ uno::UNO_QUERY );
+ ASSERT( xDPSupp.is(), "XTextDocument nicht vom XModel erhalten" );
+ uno::Reference< drawing::XDrawPage > xDrawPage = xDPSupp->getDrawPage();
+
+ ASSERT( xDrawPage.is(), "XDrawPage nicht erhalten" );
+ if( !xDrawPage.is() )
+ return;
+
+ uno::Reference< form::XFormsSupplier > xFormsSupplier( xDrawPage, uno::UNO_QUERY );
+ ASSERT( xFormsSupplier.is(),
+ "XFormsSupplier nicht vom XDrawPage erhalten" );
+
+ uno::Reference< container::XNameContainer > xTmp = xFormsSupplier->getForms();
+ ASSERT( xTmp.is(), "XForms nicht erhalten" );
+ uno::Reference< container::XIndexContainer > xForms( xTmp, uno::UNO_QUERY );
+ ASSERT( xForms.is(), "XForms ohne container::XIndexContainer?" );
+
+ sal_Int32 nCount = xForms->getCount();
+ for( sal_Int32 i=0; i<nCount; i++)
+ {
+ uno::Any aTmp = xForms->getByIndex( i );
+ ASSERT( aTmp.getValueType() ==
+ ::getCppuType((uno::Reference< form::XForm >*)0),
+ "OutHiddenForms: falsche Reflection" );
+ if( aTmp.getValueType() ==
+ ::getCppuType((uno::Reference< form::XForm >*)0) )
+ OutHiddenForm( *(uno::Reference< form::XForm > *)aTmp.getValue() );
+ }
+}
+
+void SwHTMLWriter::OutHiddenForm( const uno::Reference< form::XForm > & rForm )
+{
+ uno::Reference< container::XIndexContainer > xFormComps( rForm, uno::UNO_QUERY );
+ if( !xFormComps.is() )
+ return;
+
+ sal_Int32 nCount = xFormComps->getCount();
+ sal_Bool bHiddenOnly = nCount > 0, bHidden = sal_False;
+ for( sal_Int32 i=0; i<nCount; i++ )
+ {
+ uno::Any aTmp = xFormComps->getByIndex( i );
+ ASSERT( aTmp.getValueType() ==
+ ::getCppuType((uno::Reference<form::XFormComponent>*)0),
+ "OutHiddenForm: falsche Reflection" );
+ if( aTmp.getValueType() !=
+ ::getCppuType((uno::Reference<form::XFormComponent>*)0) )
+ continue;
+
+ uno::Reference< form::XFormComponent > xFormComp =
+ *(uno::Reference< form::XFormComponent > *)aTmp.getValue();
+ uno::Reference< form::XForm > xForm( xFormComp, uno::UNO_QUERY );
+ if( xForm.is() )
+ OutHiddenForm( xForm );
+
+ if( bHiddenOnly )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( xFormComp, uno::UNO_QUERY );
+ OUString sPropName = OUString::createFromAscii( "ClassId" );
+ if( xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
+ {
+ uno::Any aAny2 = xPropSet->getPropertyValue( sPropName );
+ if( aAny2.getValueType() == ::getCppuType((sal_Int16*)0) )
+ {
+ if( form::FormComponentType::HIDDENCONTROL ==
+ *(sal_Int16*)aAny2.getValue() )
+ bHidden = sal_True;
+ else if( lcl_html_isHTMLControl(
+ *(sal_Int16*)aAny2.getValue() ) )
+ bHiddenOnly = sal_False;
+ }
+ }
+ }
+ }
+
+ if( bHidden && bHiddenOnly )
+ {
+ OutForm( sal_True, xFormComps );
+ uno::Reference< beans::XPropertySet > xTmp;
+ OutHiddenControls( xFormComps, xTmp );
+ OutForm( sal_False, xFormComps );
+ }
+}
+
+void SwHTMLWriter::OutForm( sal_Bool bOn,
+ const uno::Reference< container::XIndexContainer > & rFormComps )
+{
+ nFormCntrlCnt = 0;
+
+ if( !bOn )
+ {
+ DecIndentLevel(); // Inhalt der Form einruecken
+ if( bLFPossible )
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_form, sal_False );
+ bLFPossible = sal_True;
+
+ return;
+ }
+
+ // die neue Form wird geoeffnet
+ if( bLFPossible )
+ OutNewLine();
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_form;
+
+ uno::Reference< beans::XPropertySet > xFormPropSet( rFormComps, uno::UNO_QUERY );
+
+ uno::Any aTmp = xFormPropSet->getPropertyValue(
+ OUString::createFromAscii( "Name" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), *(OUString*)aTmp.getValue(),
+ eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ aTmp = xFormPropSet->getPropertyValue(
+ OUString::createFromAscii( "TargetURL" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_action) += "=\"";
+ Strm() << sOut.GetBuffer();
+ String aURL( *(OUString*)aTmp.getValue() );
+ aURL = URIHelper::simpleNormalizedMakeRelative( GetBaseURL(), aURL);
+ HTMLOutFuncs::Out_String( Strm(), aURL, eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ aTmp = xFormPropSet->getPropertyValue(
+ OUString::createFromAscii( "SubmitMethod" ) );
+ if( aTmp.getValueType() == ::getCppuType((const form::FormSubmitMethod*)0) )
+ {
+ form::FormSubmitMethod eMethod =
+ *( form::FormSubmitMethod*)aTmp.getValue();
+ if( form::FormSubmitMethod_POST==eMethod )
+ {
+ ((((sOut += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_method) += "=\"")
+ += OOO_STRING_SVTOOLS_HTML_METHOD_post) += '\"';
+ }
+ }
+ aTmp = xFormPropSet->getPropertyValue(
+ OUString::createFromAscii( "SubmitEncoding" ) );
+ if( aTmp.getValueType()==::getCppuType((const form::FormSubmitEncoding*)0) )
+ {
+ form::FormSubmitEncoding eEncType =
+ *( form::FormSubmitEncoding*)aTmp.getValue();
+ const sal_Char *pStr = 0;
+ switch( eEncType )
+ {
+ case form::FormSubmitEncoding_MULTIPART:
+ pStr = OOO_STRING_SVTOOLS_HTML_ET_multipart;
+ break;
+ case form::FormSubmitEncoding_TEXT:
+ pStr = OOO_STRING_SVTOOLS_HTML_ET_text;
+ break;
+ default:
+ ;
+ }
+
+ if( pStr )
+ {
+ ((((sOut += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_enctype) += "=\"")
+ += pStr) += '\"';
+ }
+ }
+
+ aTmp = xFormPropSet->getPropertyValue(
+ OUString::createFromAscii( "TargetFrame" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0)&&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_target) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), *(OUString*)aTmp.getValue(),
+ eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ Strm() << sOut.GetBuffer();
+ uno::Reference< form::XFormComponent > xFormComp( rFormComps, uno::UNO_QUERY );
+ lcl_html_outEvents( Strm(), xFormComp, bCfgStarBasic, eDestEnc, &aNonConvertableCharacters );
+ Strm() << '>';
+
+ IncIndentLevel(); // Inhalt der Form einruecken
+ bLFPossible = sal_True;
+}
+
+void SwHTMLWriter::OutHiddenControls(
+ const uno::Reference< container::XIndexContainer > & rFormComps,
+ const uno::Reference< beans::XPropertySet > & rPropSet )
+{
+ sal_Int32 nCount = rFormComps->getCount();
+ sal_Int32 nPos = 0;
+ sal_Bool bDone = sal_False;
+ if( rPropSet.is() )
+ {
+ uno::Reference< form::XFormComponent > xFC( rPropSet, uno::UNO_QUERY );
+ for( nPos=0; !bDone && nPos < nCount; nPos++ )
+ {
+ uno::Any aTmp = rFormComps->getByIndex( nPos );
+ ASSERT( aTmp.getValueType() ==
+ ::getCppuType((uno::Reference< form::XFormComponent>*)0),
+ "OutHiddenControls: falsche Reflection" );
+ bDone = aTmp.getValueType() ==
+ ::getCppuType((uno::Reference< form::XFormComponent>*)0) &&
+ *(uno::Reference< form::XFormComponent > *)aTmp.getValue() ==
+ xFC;
+ }
+ }
+
+ for( ; nPos < nCount; nPos++ )
+ {
+ uno::Any aTmp = rFormComps->getByIndex( nPos );
+ ASSERT( aTmp.getValueType() ==
+ ::getCppuType((uno::Reference< form::XFormComponent>*)0),
+ "OutHiddenControls: falsche Reflection" );
+ if( aTmp.getValueType() !=
+ ::getCppuType((uno::Reference< form::XFormComponent>*)0) )
+ continue;
+ uno::Reference< form::XFormComponent > xFC =
+ *(uno::Reference< form::XFormComponent > *)aTmp.getValue();
+ uno::Reference< beans::XPropertySet > xPropSet( xFC, uno::UNO_QUERY );
+
+ OUString sPropName = OUString::createFromAscii( "ClassId" );
+ if( !xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
+ continue;
+
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() != ::getCppuType((const sal_Int16*)0) )
+ continue;
+
+ if( form::FormComponentType::HIDDENCONTROL ==
+ *(sal_Int16*) aTmp.getValue() )
+ {
+ if( bLFPossible )
+ OutNewLine( sal_True );
+ ByteString sOut( '<' );
+ ((((sOut += OOO_STRING_SVTOOLS_HTML_input) += ' ') +=
+ OOO_STRING_SVTOOLS_HTML_O_type) += '=') += OOO_STRING_SVTOOLS_HTML_IT_hidden;
+
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "Name" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ (( sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_name ) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), *(OUString*)aTmp.getValue(),
+ eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "HiddenValue" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), *(OUString*)aTmp.getValue(),
+ eDestEnc, &aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ sOut += '>';
+ Strm() << sOut.GetBuffer();
+
+ nFormCntrlCnt++;
+ }
+ else if( lcl_html_isHTMLControl( *(sal_Int16*) aTmp.getValue() ) )
+ {
+ break;
+ }
+ }
+}
+
+/* */
+
+// hier folgen die Ausgabe-Routinen, dadurch sind die form::Forms gebuendelt:
+
+const SdrObject *SwHTMLWriter::GetHTMLControl( const SwDrawFrmFmt& rFmt )
+{
+ // es muss ein Draw-Format sein
+ ASSERT( RES_DRAWFRMFMT == rFmt.Which(),
+ "GetHTMLControl nuer fuer Draw-Formate erlaubt" );
+
+ // Schauen, ob es ein SdrObject dafuer gibt
+ const SdrObject *pObj = rFmt.FindSdrObject();
+ if( !pObj || FmFormInventor != pObj->GetObjInventor() )
+ return 0;
+
+ SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, pObj );
+ uno::Reference< awt::XControlModel > xControlModel =
+ pFormObj->GetUnoControlModel();
+
+ ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
+ if( !xControlModel.is() )
+ return 0;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
+
+ OUString sPropName = OUString::createFromAscii( "ClassId" );
+ if( !xPropSet->getPropertySetInfo()->hasPropertyByName( sPropName ) )
+ return 0;
+
+ uno::Any aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0)&&
+ lcl_html_isHTMLControl( *(sal_Int16*) aTmp.getValue() ) )
+ {
+ return pObj;
+ }
+
+ return 0;
+}
+
+static void GetControlSize( const SdrObject& rSdrObj, Size& rSz,
+ SwDoc *pDoc )
+{
+ ViewShell *pVSh = 0;
+ pDoc->GetEditShell( &pVSh );
+ if( !pVSh )
+ return;
+
+ SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, &rSdrObj );
+ uno::Reference< awt::XControl > xControl;
+ SdrView* pDrawView = pVSh->GetDrawView();
+ ASSERT( pDrawView && pVSh->GetWin(), "no DrawView or window!" );
+ if ( pDrawView && pVSh->GetWin() )
+ xControl = pFormObj->GetUnoControl( *pDrawView, *pVSh->GetWin() );
+ uno::Reference< awt::XTextLayoutConstrains > xLC( xControl, uno::UNO_QUERY );
+ ASSERT( xLC.is(), "kein XTextLayoutConstrains" );
+ if( !xLC.is() )
+ return;
+
+ sal_Int16 nCols=0, nLines=0;
+ xLC->getColumnsAndLines( nCols, nLines );
+ rSz.Width() = nCols;
+ rSz.Height() = nLines;
+}
+
+Writer& OutHTML_DrawFrmFmtAsControl( Writer& rWrt,
+ const SwDrawFrmFmt& rFmt,
+ const SdrObject& rSdrObject,
+ sal_Bool bInCntnr )
+{
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, &rSdrObject );
+ uno::Reference< awt::XControlModel > xControlModel =
+ pFormObj->GetUnoControlModel();
+
+ ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
+ if( !xControlModel.is() )
+ return rWrt;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
+ xPropSet->getPropertySetInfo();
+
+//!!! if( rHTMLWrt.pForm != pVCSbxCtrl->GetVCForm() )
+//!!! rHTMLWrt.nWarn = 1; // Control wird falscher Form zugeordnet
+ rHTMLWrt.nFormCntrlCnt++;
+
+ enum Tag { TAG_INPUT, TAG_SELECT, TAG_TEXTAREA, TAG_NONE };
+ static char const * const TagNames[] = {
+ OOO_STRING_SVTOOLS_HTML_input, OOO_STRING_SVTOOLS_HTML_select,
+ OOO_STRING_SVTOOLS_HTML_textarea };
+ Tag eTag = TAG_INPUT;
+ enum Type {
+ TYPE_TEXT, TYPE_PASSWORD, TYPE_CHECKBOX, TYPE_RADIO, TYPE_FILE,
+ TYPE_SUBMIT, TYPE_IMAGE, TYPE_RESET, TYPE_BUTTON, TYPE_NONE };
+ static char const * const TypeNames[] = {
+ OOO_STRING_SVTOOLS_HTML_IT_text, OOO_STRING_SVTOOLS_HTML_IT_password,
+ OOO_STRING_SVTOOLS_HTML_IT_checkbox, OOO_STRING_SVTOOLS_HTML_IT_radio,
+ OOO_STRING_SVTOOLS_HTML_IT_file, OOO_STRING_SVTOOLS_HTML_IT_submit,
+ OOO_STRING_SVTOOLS_HTML_IT_image, OOO_STRING_SVTOOLS_HTML_IT_reset,
+ OOO_STRING_SVTOOLS_HTML_IT_button };
+ Type eType = TYPE_NONE;
+ OUString sValue;
+ ByteString sOptions;
+ sal_Bool bEmptyValue = sal_False;
+ uno::Any aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "ClassId" ) );
+ sal_Int16 nClassId = *(sal_Int16*) aTmp.getValue();
+ sal_uInt32 nFrmOpts = HTML_FRMOPTS_CONTROL;
+ switch( nClassId )
+ {
+ case form::FormComponentType::CHECKBOX:
+ case form::FormComponentType::RADIOBUTTON:
+ eType = (form::FormComponentType::CHECKBOX == nClassId
+ ? TYPE_CHECKBOX : TYPE_RADIO);
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "DefaultState" ) );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) &&
+ STATE_NOCHECK != *(sal_Int16*) aTmp.getValue() )
+ {
+ (sOptions += ' ') += OOO_STRING_SVTOOLS_HTML_O_checked;
+ }
+
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "RefValue" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) )
+
+ {
+ const OUString& rVal = *(OUString*)aTmp.getValue();
+ if( !rVal.getLength() )
+ bEmptyValue = sal_True;
+ else if( rVal.compareToAscii( OOO_STRING_SVTOOLS_HTML_on ) != 0 )
+ sValue = rVal;
+ }
+ break;
+
+ case form::FormComponentType::COMMANDBUTTON:
+ {
+ form::FormButtonType eButtonType = form::FormButtonType_PUSH;
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "ButtonType" ) );
+ if( aTmp.getValueType() ==
+ ::getCppuType((const form::FormButtonType*)0) )
+ eButtonType = *( form::FormButtonType*)aTmp.getValue();
+
+ switch( eButtonType )
+ {
+ case form::FormButtonType_RESET:
+ eType = TYPE_RESET;
+ break;
+ case form::FormButtonType_SUBMIT:
+ eType = TYPE_SUBMIT;
+ break;
+ case form::FormButtonType_PUSH:
+ default:
+ eType = TYPE_BUTTON;
+ }
+
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "Label" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ sValue = *(OUString*)aTmp.getValue();
+ }
+ }
+ break;
+
+ case form::FormComponentType::LISTBOX:
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( sal_True );
+ eTag = TAG_SELECT;
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "Dropdown" ) );
+ if( aTmp.getValueType() == ::getBooleanCppuType() &&
+ !*(sal_Bool*)aTmp.getValue() )
+ {
+ Size aSz( 0, 0 );
+ GetControlSize( rSdrObject, aSz, rWrt.pDoc );
+
+ // wieviele sind sichtbar ??
+ if( aSz.Height() )
+ (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_size ) += '=' )
+ += ByteString::CreateFromInt32( aSz.Height() );
+
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "MultiSelection" ) );
+ if( aTmp.getValueType() == ::getBooleanCppuType() &&
+ *(sal_Bool*)aTmp.getValue() )
+ {
+ (sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_multiple;
+ }
+ }
+ break;
+
+ case form::FormComponentType::TEXTFIELD:
+ {
+ Size aSz( 0, 0 );
+ GetControlSize( rSdrObject, aSz, rWrt.pDoc );
+
+ sal_Bool bMultiLine = sal_False;
+ OUString sMultiLine( OUString::createFromAscii( "MultiLine" ) );
+ if( xPropSetInfo->hasPropertyByName( sMultiLine ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sMultiLine );
+ bMultiLine = aTmp.getValueType() == ::getBooleanCppuType() &&
+ *(sal_Bool*)aTmp.getValue();
+ }
+
+ if( bMultiLine )
+ {
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( sal_True );
+ eTag = TAG_TEXTAREA;
+
+ if( aSz.Height() )
+ (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_rows ) += '=' )
+ += ByteString::CreateFromInt32( aSz.Height() );
+ if( aSz.Width() )
+ (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cols ) += '=' )
+ += ByteString::CreateFromInt32( aSz.Width() );
+
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "HScroll" ) );
+ if( aTmp.getValueType() == ::getVoidCppuType() ||
+ (aTmp.getValueType() == ::getBooleanCppuType() &&
+ !*(sal_Bool*)aTmp.getValue()) )
+ {
+ const sal_Char *pWrapStr = 0;
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "HardLineBreaks" ) );
+ pWrapStr =
+ (aTmp.getValueType() == ::getBooleanCppuType() &&
+ *(sal_Bool*)aTmp.getValue()) ? OOO_STRING_SVTOOLS_HTML_WW_hard
+ : OOO_STRING_SVTOOLS_HTML_WW_soft;
+ (((sOptions += ' ') += OOO_STRING_SVTOOLS_HTML_O_wrap) += '=') += pWrapStr;
+ }
+ }
+ else
+ {
+ eType = TYPE_TEXT;
+ OUString sEchoChar( OUString::createFromAscii( "EchoChar" ) );
+ if( xPropSetInfo->hasPropertyByName( sEchoChar ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sEchoChar );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) &&
+ *(sal_Int16*)aTmp.getValue() != 0 )
+ eType = TYPE_PASSWORD;
+ }
+
+ if( aSz.Width() )
+ (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_size ) += '=' )
+ += ByteString::CreateFromInt32( aSz.Width() );
+
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "MaxTextLen" ) );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) &&
+ *(sal_Int16*) aTmp.getValue() != 0 )
+ {
+ (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_maxlength ) += '=' )
+ += ByteString::CreateFromInt32(
+ *(sal_Int16*) aTmp.getValue() );
+ }
+
+ OUString sDefaultText( OUString::createFromAscii( "DefaultText" ) );
+ if( xPropSetInfo->hasPropertyByName( sDefaultText ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sDefaultText );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ sValue = *(OUString*)aTmp.getValue();
+ }
+ }
+ }
+ }
+ break;
+
+ case form::FormComponentType::FILECONTROL:
+ {
+ Size aSz( 0, 0 );
+ GetControlSize( rSdrObject, aSz, rWrt.pDoc );
+ eType = TYPE_FILE;
+
+ if( aSz.Width() )
+ (((sOptions += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_size ) += '=' )
+ += ByteString::CreateFromInt32( aSz.Width() );
+
+ // VALUE vim form aus Sicherheitsgruenden nicht exportieren
+ }
+ break;
+
+
+ case form::FormComponentType::IMAGEBUTTON:
+ eType = TYPE_IMAGE;
+ nFrmOpts = HTML_FRMOPTS_IMG_CONTROL;
+ break;
+
+ default: // kennt HTML nicht
+ eTag = TAG_NONE; // also ueberspringen
+ break;
+ }
+
+ if( eTag == TAG_NONE )
+ return rWrt;
+
+ ByteString sOut( '<' );
+ sOut += TagNames[eTag];
+ if( eType != TYPE_NONE )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=') +=
+ TypeNames[eType];
+
+ aTmp = xPropSet->getPropertyValue( OUString::createFromAscii( "Name" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ (( sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_name ) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), *(OUString*)aTmp.getValue(),
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ aTmp = xPropSet->getPropertyValue( OUString::createFromAscii( "Enabled" ) );
+ if( aTmp.getValueType() == ::getBooleanCppuType() &&
+ !*(sal_Bool*)aTmp.getValue() )
+ {
+ (( sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_disabled );
+ }
+
+ if( sValue.getLength() || bEmptyValue )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sValue, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ sOut += sOptions;
+
+ if( TYPE_IMAGE == eType )
+ {
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "ImageURL" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+
+ HTMLOutFuncs::Out_String( rWrt.Strm(),
+ URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), *(OUString*)aTmp.getValue()),
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ Size aTwipSz( rSdrObject.GetLogicRect().GetSize() );
+ Size aPixelSz( 0, 0 );
+ if( (aTwipSz.Width() || aTwipSz.Height()) &&
+ Application::GetDefaultDevice() )
+ {
+ aPixelSz =
+ Application::GetDefaultDevice()->LogicToPixel( aTwipSz,
+ MapMode(MAP_TWIP) );
+ if( !aPixelSz.Width() && aTwipSz.Width() )
+ aPixelSz.Width() = 1;
+ if( !aPixelSz.Height() && aTwipSz.Height() )
+ aPixelSz.Height() = 1;
+ }
+
+ if( aPixelSz.Width() )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=')
+ += ByteString::CreateFromInt32( aPixelSz.Width() );
+
+ if( aPixelSz.Height() )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
+ += ByteString::CreateFromInt32( aPixelSz.Height() );
+ }
+
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "TabIndex" ) );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) )
+ {
+ sal_Int16 nTabIndex = *(sal_Int16*) aTmp.getValue();
+ if( nTabIndex > 0 )
+ {
+ if( nTabIndex >= 32767 )
+ nTabIndex = 32767;
+
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_tabindex) += '=')
+ += ByteString::CreateFromInt32( nTabIndex );
+ }
+ }
+
+ if( sOut.Len() )
+ {
+ rWrt.Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ }
+
+ ASSERT( !bInCntnr, "Container wird fuer Controls nicht unterstuertzt" );
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_DRAW ) && !bInCntnr )
+ {
+ // Wenn Zeichen-Objekte nicht absolut positioniert werden duerfen,
+ // das entsprechende Flag loeschen.
+ nFrmOpts |= (TYPE_IMAGE == eType
+ ? HTML_FRMOPTS_IMG_CONTROL_CSS1
+ : HTML_FRMOPTS_CONTROL_CSS1);
+ }
+ ByteString aEndTags;
+ if( nFrmOpts != 0 )
+ rHTMLWrt.OutFrmFmtOptions( rFmt, aEmptyStr, aEndTags, nFrmOpts );
+
+ if( rHTMLWrt.bCfgOutStyles )
+ {
+ sal_Bool bEdit = TAG_TEXTAREA == eTag || TYPE_FILE == eType ||
+ TYPE_TEXT == eType;
+
+ SfxItemSet aItemSet( rHTMLWrt.pDoc->GetAttrPool(), RES_CHRATR_BEGIN,
+ RES_CHRATR_END );
+ OUString sPropName = OUString::createFromAscii( "BackgroundColor" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int32*)0) )
+ {
+ Color aCol(*(sal_Int32*)aTmp .getValue());
+ aItemSet.Put( SvxBrushItem( aCol, RES_CHRATR_BACKGROUND ) );
+ }
+ }
+ sPropName = OUString::createFromAscii( "TextColor" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int32*)0) )
+ {
+ Color aColor( *(sal_Int32*)aTmp .getValue() );
+ aItemSet.Put( SvxColorItem( aColor, RES_CHRATR_COLOR ) );
+ }
+ }
+ sPropName = OUString::createFromAscii( "FontHeight" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const float*)0) )
+
+ {
+ float nHeight = *(float*)aTmp.getValue();
+ if( nHeight > 0 && (!bEdit || nHeight != 10.) )
+ aItemSet.Put( SvxFontHeightItem( sal_Int16(nHeight * 20.), 100, RES_CHRATR_FONTSIZE ) );
+ }
+ }
+ sPropName = OUString::createFromAscii( "FontName" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ Font aFixedFont( OutputDevice::GetDefaultFont(
+ DEFAULTFONT_FIXED, LANGUAGE_ENGLISH_US,
+ DEFAULTFONT_FLAGS_ONLYONE ) );
+ String aFName( *(OUString*)aTmp.getValue() );
+ if( !bEdit || aFName != aFixedFont.GetName() )
+ {
+ FontFamily eFamily = FAMILY_DONTKNOW;
+ sPropName = OUString::createFromAscii( "FontFamily" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0))
+ eFamily = (FontFamily)*(sal_Int16*) aTmp.getValue();
+ }
+ SvxFontItem aItem( eFamily, aFName, aEmptyStr, PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, RES_CHRATR_FONT );
+ aItemSet.Put( aItem );
+ }
+ }
+ }
+ sPropName = OUString::createFromAscii( "FontWeight" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const float*)0) )
+ {
+ FontWeight eWeight =
+ VCLUnoHelper::ConvertFontWeight( *(float*)aTmp.getValue() );
+ if( eWeight != WEIGHT_DONTKNOW && eWeight != WEIGHT_NORMAL )
+ aItemSet.Put( SvxWeightItem( eWeight, RES_CHRATR_WEIGHT ) );
+ }
+ }
+ sPropName = OUString::createFromAscii( "FontSlant" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0))
+ {
+ FontItalic eItalic = (FontItalic)*(sal_Int16*)aTmp.getValue();
+ if( eItalic != ITALIC_DONTKNOW && eItalic != ITALIC_NONE )
+ aItemSet.Put( SvxPostureItem( eItalic, RES_CHRATR_POSTURE ) );
+ }
+ }
+ sPropName = OUString::createFromAscii( "FontUnderline" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0) )
+ {
+ FontUnderline eUnderline =
+ (FontUnderline)*(sal_Int16*)aTmp.getValue();
+ if( eUnderline != UNDERLINE_DONTKNOW &&
+ eUnderline != UNDERLINE_NONE )
+ aItemSet.Put( SvxUnderlineItem( eUnderline, RES_CHRATR_UNDERLINE ) );
+ }
+ }
+ sPropName = OUString::createFromAscii( "FontStrikeout" );
+ if( xPropSetInfo->hasPropertyByName( sPropName ) )
+ {
+ aTmp = xPropSet->getPropertyValue( sPropName );
+ if( aTmp.getValueType() == ::getCppuType((const sal_Int16*)0))
+ {
+ FontStrikeout eStrikeout =
+ (FontStrikeout)*(sal_Int16*)aTmp.getValue();
+ if( eStrikeout != STRIKEOUT_DONTKNOW &&
+ eStrikeout != STRIKEOUT_NONE )
+ aItemSet.Put( SvxCrossedOutItem( eStrikeout, RES_CHRATR_CROSSEDOUT ) );
+ }
+ }
+
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFmt, nFrmOpts, &rSdrObject,
+ &aItemSet );
+ }
+
+ uno::Reference< form::XFormComponent > xFormComp( xControlModel, uno::UNO_QUERY );
+ lcl_html_outEvents( rWrt.Strm(), xFormComp, rHTMLWrt.bCfgStarBasic,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+
+ rWrt.Strm() << '>';
+
+ if( TAG_SELECT == eTag )
+ {
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "StringItemList" ) );
+ if( aTmp.getValueType() == ::getCppuType((uno::Sequence<OUString>*)0) )
+ {
+ rHTMLWrt.IncIndentLevel(); // der Inhalt von Select darf
+ // eingerueckt werden
+ uno::Sequence<OUString> aList( *(uno::Sequence<OUString>*)aTmp.getValue() );
+ sal_Int32 nCnt = aList.getLength();
+ const OUString *pStrings = aList.getConstArray();
+
+ const OUString *pValues = 0;
+ sal_Int32 nValCnt = 0;
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "ListSource" ) );
+ uno::Sequence<OUString> aValList;
+ if( aTmp.getValueType() == ::getCppuType((uno::Sequence<OUString>*)0) )
+ {
+ aValList = *(uno::Sequence<OUString>*)aTmp.getValue();
+ nValCnt = aValList.getLength();
+ pValues = aValList.getConstArray();
+ }
+
+ uno::Any aSelTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "DefaultSelection" ) );
+ const sal_Int16 *pSels = 0;
+ sal_Int32 nSel = 0;
+ sal_Int32 nSelCnt = 0;
+ uno::Sequence<sal_Int16> aSelList;
+ if( aSelTmp.getValueType() ==::getCppuType((uno::Sequence<sal_Int16>*)0))
+ {
+ aSelList = *(uno::Sequence<sal_Int16>*)aSelTmp.getValue();
+ nSelCnt = aSelList.getLength();
+ pSels = aSelList.getConstArray();
+ }
+
+ for( sal_Int32 i = 0; i < nCnt; i++ )
+ {
+ OUString sVal;
+ sal_Bool bSelected = sal_False, bEmptyVal = sal_False;
+ if( i < nValCnt )
+ {
+ const OUString& rVal = pValues[i];
+ if( rVal.compareToAscii( "$$$empty$$$" ) == 0 )
+ bEmptyVal = sal_True;
+ else
+ sVal = rVal;
+ }
+
+ bSelected = (nSel < nSelCnt) && pSels[nSel] == i;
+ if( bSelected )
+ nSel++;
+
+ rHTMLWrt.OutNewLine(); // jede Option bekommt eine eigene Zeile
+ (sOut = '<') += OOO_STRING_SVTOOLS_HTML_option;
+ if( sVal.getLength() || bEmptyVal )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_value) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sVal,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ if( bSelected )
+ (sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_selected;
+
+ sOut += '>';
+ rWrt.Strm() << sOut.GetBuffer();
+
+ HTMLOutFuncs::Out_String( rWrt.Strm(), pStrings[i],
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ }
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_option, sal_False );
+
+ rHTMLWrt.DecIndentLevel();
+ rHTMLWrt.OutNewLine();// das </SELECT> bekommt eine eigene Zeile
+ }
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_select, sal_False );
+ }
+ else if( TAG_TEXTAREA == eTag )
+ {
+ // In TextAreas duerfen keine zusaetzlichen Spaces oder LF exportiert
+ // werden!
+ String sVal;
+ aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii( "DefaultText" ) );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0)&&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ sVal = String( *(OUString*)aTmp.getValue() );
+ }
+ if( sVal.Len() )
+ {
+ sVal.ConvertLineEnd( LINEEND_LF );
+ xub_StrLen nPos = 0;
+ while ( nPos != STRING_NOTFOUND )
+ {
+ if( nPos )
+ rWrt.Strm() << SwHTMLWriter::sNewLine;
+ String aLine = sVal.GetToken( 0, 0x0A, nPos );
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aLine,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ }
+ }
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_textarea, sal_False );
+ }
+ else if( TYPE_CHECKBOX == eType || TYPE_RADIO == eType )
+ {
+ aTmp = xPropSet->getPropertyValue( OUString::createFromAscii("Label") );
+ if( aTmp.getValueType() == ::getCppuType((const OUString*)0) &&
+ ((OUString*)aTmp.getValue())->getLength() )
+ {
+ sValue = *(OUString*)aTmp.getValue();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sValue,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << ' ';
+ }
+ }
+
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ // Controls sind nicht absatz-gebunden, deshalb kein LF mehr ausgeben!
+ rHTMLWrt.bLFPossible = sal_False;
+
+ if( rHTMLWrt.pxFormComps && rHTMLWrt.pxFormComps->is() )
+ rHTMLWrt.OutHiddenControls( *rHTMLWrt.pxFormComps, xPropSet );
+ return rWrt;
+}
+
+/* */
+
+// Ermitteln, ob eine Format zu einem Control gehoert und wenn ja
+// dessen Form zurueckgeben
+static void AddControl( HTMLControls& rControls,
+ const SdrObject *pSdrObj,
+ sal_uInt32 nNodeIdx )
+{
+ SdrUnoObj *pFormObj = PTR_CAST( SdrUnoObj, pSdrObj );
+ ASSERT( pFormObj, "Doch kein FormObj" );
+ uno::Reference< awt::XControlModel > xControlModel =
+ pFormObj->GetUnoControlModel();
+ if( !xControlModel.is() )
+ return;
+
+ uno::Reference< form::XFormComponent > xFormComp( xControlModel, uno::UNO_QUERY );
+ uno::Reference< uno::XInterface > xIfc = xFormComp->getParent();
+ uno::Reference< form::XForm > xForm(xIfc, uno::UNO_QUERY);
+
+ ASSERT( xForm.is(), "Wo ist die Form?" );
+ if( xForm.is() )
+ {
+ uno::Reference< container::XIndexContainer > xFormComps( xForm, uno::UNO_QUERY );
+ HTMLControl *pHCntrl = new HTMLControl( xFormComps, nNodeIdx );
+ if( !rControls.C40_PTR_INSERT( HTMLControl, pHCntrl ) )
+ {
+ sal_uInt16 nPos = 0;
+ if( rControls.Seek_Entry(pHCntrl,&nPos) &&
+ rControls[nPos]->xFormComps==xFormComps )
+ rControls[nPos]->nCount++;
+ delete pHCntrl;
+ }
+ }
+}
+
+
+void SwHTMLWriter::GetControls()
+{
+ // Idee: die absatz- und zeichengebundenen Controls werden erst einmal
+ // eingesammelt. Dabei wird fuer jedes Control des Absatz-Position
+ // und VCForm in einem Array gemerkt.
+ // Ueber dieses Array laesst sich dann feststellen, wo form::Forms geoeffnet
+ // und geschlossen werden muessen.
+ sal_uInt16 i;
+ if( pHTMLPosFlyFrms )
+ {
+ // die absatz-gebundenen Controls einsammeln
+ for( i=0; i<pHTMLPosFlyFrms->Count(); i++ )
+ {
+ const SwHTMLPosFlyFrm* pPosFlyFrm = pHTMLPosFlyFrms->GetObject( i );
+ if( HTML_OUT_CONTROL != pPosFlyFrm->GetOutFn() )
+ continue;
+
+ const SdrObject *pSdrObj = pPosFlyFrm->GetSdrObject();
+ ASSERT( pSdrObj, "Wo ist das SdrObject?" );
+ if( !pSdrObj )
+ continue;
+
+ AddControl( aHTMLControls, pSdrObj,
+ pPosFlyFrm->GetNdIndex().GetIndex() );
+ }
+ }
+
+ // und jetzt die in einem zeichengebundenen Rahmen
+ const SwSpzFrmFmts* pSpzFrmFmts = pDoc->GetSpzFrmFmts();
+ for( i=0; i<pSpzFrmFmts->Count(); i++ )
+ {
+ const SwFrmFmt *pFrmFmt = (*pSpzFrmFmts)[i];
+ if( RES_DRAWFRMFMT != pFrmFmt->Which() )
+ continue;
+
+ const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
+ const SwPosition *pPos = rAnchor.GetCntntAnchor();
+ if ((FLY_AS_CHAR != rAnchor.GetAnchorId()) || !pPos)
+ continue;
+
+ const SdrObject *pSdrObj =
+ SwHTMLWriter::GetHTMLControl( *(const SwDrawFrmFmt*)pFrmFmt );
+ if( !pSdrObj )
+ continue;
+
+ AddControl( aHTMLControls, pSdrObj, pPos->nNode.GetIndex() );
+ }
+}
+
+/* */
+
+HTMLControl::HTMLControl(
+ const uno::Reference< container::XIndexContainer > & rFormComps,
+ sal_uInt32 nIdx ) :
+ xFormComps( rFormComps ), nNdIdx( nIdx ), nCount( 1 )
+{}
+
+
+HTMLControl::~HTMLControl()
+{}
+
+
diff --git a/sw/source/filter/html/htmlftn.cxx b/sw/source/filter/html/htmlftn.cxx
new file mode 100644
index 000000000000..900643bbc680
--- /dev/null
+++ b/sw/source/filter/html/htmlftn.cxx
@@ -0,0 +1,621 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <svtools/htmlout.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <errhdl.hxx>
+#include <ndindex.hxx>
+#include <fmtftn.hxx>
+#include <txtftn.hxx>
+#include <ftninfo.hxx>
+#include <doc.hxx>
+#include <ndtxt.hxx>
+#include <charfmt.hxx>
+
+
+#include "swhtml.hxx"
+#include "wrthtml.hxx"
+
+typedef SwTxtFtn *SwTxtFtnPtr;
+SV_DECL_PTRARR( SwHTMLTxtFtns, SwTxtFtnPtr, 1, 1 )
+
+struct SwHTMLFootEndNote_Impl
+{
+ SwHTMLTxtFtns aTxtFtns;
+ SvStringsDtor aNames;
+
+ String sName;
+ String sContent; // Infos fuer die letzte Fussnote
+ BOOL bEndNote;
+ BOOL bFixed;
+};
+
+
+xub_StrLen lcl_html_getNextPart( String& rPart, const String& rContent,
+ xub_StrLen nPos )
+{
+ rPart = aEmptyStr;
+ xub_StrLen nLen = rContent.Len();
+ if( nPos >= nLen )
+ {
+ nPos = STRING_MAXLEN;
+ }
+ else
+ {
+ BOOL bQuoted = FALSE, bDone = FALSE;
+ for( ; nPos < nLen && !bDone; nPos++ )
+ {
+ sal_Unicode c = rContent.GetChar( nPos );
+ switch( c )
+ {
+ case '\\':
+ if( bQuoted )
+ rPart += c;
+ bQuoted = !bQuoted;
+ break;
+
+ case ';':
+ if( bQuoted )
+ rPart += c;
+ else
+ bDone = TRUE;
+ bQuoted = FALSE;
+ break;
+
+ default:
+ rPart += c;
+ bQuoted = FALSE;
+ break;
+ }
+ }
+ }
+
+ return nPos;
+}
+
+xub_StrLen lcl_html_getEndNoteInfo( SwEndNoteInfo& rInfo,
+ const String& rContent,
+ BOOL bEndNote )
+{
+ xub_StrLen nStrPos = 0;
+ for( USHORT nPart = 0; nPart < 4; nPart++ )
+ {
+ String aPart;
+ if( STRING_MAXLEN != nStrPos )
+ nStrPos = lcl_html_getNextPart( aPart, rContent, nStrPos );
+
+ switch( nPart )
+ {
+ case 0:
+ rInfo.aFmt.SetNumberingType( static_cast< sal_Int16 >(bEndNote ? SVX_NUM_ROMAN_LOWER : SVX_NUM_ARABIC));
+ if( aPart.Len() )
+ rInfo.aFmt.SetNumberingType(SwHTMLParser::GetNumType( aPart,
+ rInfo.aFmt.GetNumberingType() ));
+ break;
+
+ case 1:
+ rInfo.nFtnOffset = aPart.Len() == 0 ? 0 : (USHORT)aPart.ToInt32();
+ break;
+
+ case 2:
+ rInfo.SetPrefix( aPart );
+ break;
+
+ case 3:
+ rInfo.SetSuffix( aPart );
+ break;
+ }
+ }
+
+ return nStrPos;
+}
+
+void SwHTMLParser::FillEndNoteInfo( const String& rContent )
+{
+ SwEndNoteInfo aInfo( pDoc->GetEndNoteInfo() );
+ lcl_html_getEndNoteInfo( aInfo, rContent, TRUE );
+ pDoc->SetEndNoteInfo( aInfo );
+}
+
+void SwHTMLParser::FillFootNoteInfo( const String& rContent )
+{
+ SwFtnInfo aInfo( pDoc->GetFtnInfo() );
+
+ xub_StrLen nStrPos = lcl_html_getEndNoteInfo( aInfo, rContent, FALSE );
+
+ for( USHORT nPart = 4; nPart < 8; nPart++ )
+ {
+ String aPart;
+ if( STRING_MAXLEN != nStrPos )
+ nStrPos = lcl_html_getNextPart( aPart, rContent, nStrPos );
+
+ switch( nPart )
+ {
+ case 4:
+ aInfo.eNum = FTNNUM_DOC;
+ if( aPart.Len() )
+ {
+ switch( aPart.GetChar(0) )
+ {
+ case 'D': aInfo.eNum = FTNNUM_DOC; break;
+ case 'C': aInfo.eNum = FTNNUM_CHAPTER; break;
+ case 'P': aInfo.eNum = FTNNUM_PAGE; break;
+ }
+ }
+ break;
+
+ case 5:
+ aInfo.ePos = FTNPOS_PAGE;
+ if( aPart.Len() )
+ {
+ switch( aPart.GetChar(0) )
+ {
+ case 'C': aInfo.ePos = FTNPOS_CHAPTER; break;
+ case 'P': aInfo.ePos = FTNPOS_PAGE; break;
+ }
+ }
+ break;
+
+ case 6:
+ aInfo.aQuoVadis = aPart;
+ break;
+
+ case 7:
+ aInfo.aErgoSum = aPart;
+ break;
+ }
+ }
+
+ pDoc->SetFtnInfo( aInfo );
+}
+
+void SwHTMLParser::InsertFootEndNote( const String& rName, BOOL bEndNote,
+ BOOL bFixed )
+{
+ if( !pFootEndNoteImpl )
+ pFootEndNoteImpl = new SwHTMLFootEndNote_Impl;
+
+ pFootEndNoteImpl->sName = rName;
+ if( pFootEndNoteImpl->sName.Len() > 3 )
+ pFootEndNoteImpl->sName.Erase( pFootEndNoteImpl->sName.Len() - 3 );
+ // TODO: ToUpperAscii???
+ pFootEndNoteImpl->sName.ToUpperAscii();
+
+ pFootEndNoteImpl->bEndNote = bEndNote;
+ pFootEndNoteImpl->bFixed = bFixed;
+ pFootEndNoteImpl->sContent = aEmptyStr;
+}
+
+void SwHTMLParser::FinishFootEndNote()
+{
+ if( !pFootEndNoteImpl )
+ return;
+
+ SwFmtFtn aFtn( pFootEndNoteImpl->bEndNote );
+ if( pFootEndNoteImpl->bFixed )
+ aFtn.SetNumStr( pFootEndNoteImpl->sContent );
+
+ pDoc->InsertPoolItem( *pPam, aFtn, 0 );
+ SwTxtFtn * const pTxtFtn = static_cast<SwTxtFtn *>(
+ pPam->GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
+ pPam->GetPoint()->nContent.GetIndex() - 1, RES_TXTATR_FTN ) );
+ // In Kopf- und Fusszeilen duerfen keine Fussnoten eingefuegt werden.
+ if( pTxtFtn )
+ {
+ pFootEndNoteImpl->aTxtFtns.Insert( pTxtFtn,
+ pFootEndNoteImpl->aTxtFtns.Count() );
+
+ pFootEndNoteImpl->aNames.Insert( new String(pFootEndNoteImpl->sName),
+ pFootEndNoteImpl->aNames.Count() );
+ }
+ pFootEndNoteImpl->sName = aEmptyStr;
+ pFootEndNoteImpl->sContent = aEmptyStr;
+ pFootEndNoteImpl->bFixed = FALSE;
+}
+
+void SwHTMLParser::InsertFootEndNoteText()
+{
+ if( pFootEndNoteImpl && pFootEndNoteImpl->bFixed )
+ pFootEndNoteImpl->sContent += aToken;
+}
+
+void SwHTMLParser::DeleteFootEndNoteImpl()
+{
+ delete pFootEndNoteImpl;
+ pFootEndNoteImpl = 0;
+}
+
+SwNodeIndex *SwHTMLParser::GetFootEndNoteSection( const String& rName )
+{
+ SwNodeIndex *pStartNodeIdx = 0;
+
+ if( pFootEndNoteImpl )
+ {
+ String aName( rName );
+ // TODO: ToUpperAscii
+ aName.ToUpperAscii();
+
+ USHORT nCount = pFootEndNoteImpl->aNames.Count();
+ for( USHORT i=0; i<nCount; i++ )
+ {
+ if( *pFootEndNoteImpl->aNames[i] == aName )
+ {
+ pStartNodeIdx = pFootEndNoteImpl->aTxtFtns[i]->GetStartNode();
+ pFootEndNoteImpl->aNames.DeleteAndDestroy( i, 1 );
+ pFootEndNoteImpl->aTxtFtns.Remove( i, 1 );
+ if( !pFootEndNoteImpl->aNames.Count() )
+ {
+ delete pFootEndNoteImpl;
+ pFootEndNoteImpl = 0;
+ }
+
+ break;
+ }
+ }
+ }
+
+ return pStartNodeIdx;
+}
+
+Writer& OutHTML_SwFmtFtn( Writer& rWrt, const SfxPoolItem& rHt )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ SwFmtFtn& rFmtFtn = (SwFmtFtn&)rHt;
+ SwTxtFtn *pTxtFtn = rFmtFtn.GetTxtFtn();
+ if( !pTxtFtn )
+ return rWrt;
+
+ String sFtnName, sClass;
+ USHORT nPos;
+ if( rFmtFtn.IsEndNote() )
+ {
+ nPos = rHTMLWrt.pFootEndNotes ? rHTMLWrt.pFootEndNotes->Count() : 0;
+ ASSERT( nPos == rHTMLWrt.nFootNote + rHTMLWrt.nEndNote,
+ "OutHTML_SwFmtFtn: Position falsch" );
+ sClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_anc );
+ sFtnName.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote );
+ sFtnName += String::CreateFromInt32( (sal_Int32)(++rHTMLWrt.nEndNote) );
+ }
+ else
+ {
+ nPos = rHTMLWrt.nFootNote;
+ sClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_anc );
+ sFtnName.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote);
+ sFtnName += String::CreateFromInt32( (sal_Int32)(++rHTMLWrt.nFootNote));
+ }
+
+ if( !rHTMLWrt.pFootEndNotes )
+ rHTMLWrt.pFootEndNotes = new SwHTMLTxtFtns;
+ rHTMLWrt.pFootEndNotes->Insert( pTxtFtn, nPos );
+
+ ByteString sOut( '<' );
+ (((sOut += OOO_STRING_SVTOOLS_HTML_anchor) += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sClass, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ ((sOut = "\" ") += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sFtnName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ (((sOut = OOO_STRING_SVTOOLS_HTML_FTN_anchor) += "\" ") += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"#";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sFtnName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ (sOut = OOO_STRING_SVTOOLS_HTML_FTN_symbol)+= '\"';
+ if( rFmtFtn.GetNumStr().Len() )
+ (sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_sdfixed;
+ sOut += '>';
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_superscript, TRUE );
+
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rFmtFtn.GetViewNumStr(*rWrt.pDoc),
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_superscript, FALSE );
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_anchor, FALSE );
+
+ return rWrt;
+}
+
+void SwHTMLWriter::OutFootEndNotes()
+{
+ ASSERT( pFootEndNotes,
+ "SwHTMLWriter::OutFootEndNotes(): unnoetiger Aufruf" );
+ if( !pFootEndNotes )
+ return;
+
+#ifdef DBG_UTIL
+ USHORT nFtn = nFootNote, nEn = nEndNote;
+#endif
+ nFootNote = 0, nEndNote = 0;
+
+ for( USHORT i=0; i<pFootEndNotes->Count(); i++ )
+ {
+ SwTxtFtn *pTxtFtn = (*pFootEndNotes)[i];
+ pFmtFtn = &pTxtFtn->GetFtn();
+
+ String sFtnName, sClass;
+ if( pFmtFtn->IsEndNote() )
+ {
+ sClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote );
+ sFtnName.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote );
+ sFtnName.Append( String::CreateFromInt32((sal_Int32)(++nEndNote)) );
+ }
+ else
+ {
+ sClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote );
+ sFtnName.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote );
+ sFtnName.Append( String::CreateFromInt32((sal_Int32)(++nFootNote)));
+ }
+
+ if( bLFPossible )
+ OutNewLine();
+ ByteString sOut( '<' );
+ (((sOut += OOO_STRING_SVTOOLS_HTML_division) += ' ') += OOO_STRING_SVTOOLS_HTML_O_id) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), sFtnName, eDestEnc, &aNonConvertableCharacters );
+ Strm() << "\">";
+
+ bLFPossible = TRUE;
+ IncIndentLevel(); // Inhalt von <DIV> einruecken
+
+ ASSERT( pTxtFtn, "SwHTMLWriter::OutFootEndNotes: SwTxtFtn fehlt" );
+ SwNodeIndex *pSttNdIdx = pTxtFtn->GetStartNode();
+ ASSERT( pSttNdIdx,
+ "SwHTMLWriter::OutFootEndNotes: StartNode-Index fehlt" );
+ if( pSttNdIdx )
+ {
+ HTMLSaveData aSaveData( *this, pSttNdIdx->GetIndex()+1,
+ pSttNdIdx->GetNode().EndOfSectionIndex(), FALSE );
+ Out_SwDoc( pCurPam );
+ }
+
+ DecIndentLevel(); // Inhalt von <DIV> einruecken
+ if( bLFPossible )
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_division, FALSE );
+ bLFPossible = TRUE;
+
+ ASSERT( !pFmtFtn,
+ "SwHTMLWriter::OutFootEndNotes: Ftn wurde nicht ausgegeben" );
+ if( pFmtFtn )
+ {
+ if( pFmtFtn->IsEndNote() )
+ nEndNote++;
+ else
+ nFootNote++;
+
+ pFmtFtn = 0;
+ }
+ }
+
+#ifdef DBG_UTIL
+ ASSERT( nFtn == nFootNote,
+ "SwHTMLWriter::OutFootEndNotes: Anzahl Fussnoten stimmt nicht" );
+ ASSERT( nEn == nEndNote,
+ "SwHTMLWriter::OutFootEndNotes: Anzahl Endnoten stimmt nicht" );
+#endif
+
+ delete pFootEndNotes;
+ pFootEndNotes = 0;
+ nFootNote = nEndNote = 0;
+}
+
+String SwHTMLWriter::GetFootEndNoteSym( const SwFmtFtn& rFmtFtn )
+{
+ const SwEndNoteInfo * pInfo = 0;
+ if( rFmtFtn.GetNumStr().Len() == 0 )
+ pInfo = rFmtFtn.IsEndNote() ? &pDoc->GetEndNoteInfo()
+ : &pDoc->GetFtnInfo();
+
+ String sRet;
+ if( pInfo )
+ sRet = pInfo->GetPrefix();
+ sRet += rFmtFtn.GetViewNumStr( *pDoc );
+ if( pInfo )
+ sRet += pInfo->GetSuffix();
+
+ return sRet;
+}
+
+void SwHTMLWriter::OutFootEndNoteSym( const SwFmtFtn& rFmtFtn,
+ const String& rNum,
+ sal_uInt16 nScript )
+{
+ const SwEndNoteInfo *pInfo;
+
+ String sFtnName, sClass, sPrefix, sSuffix;
+ if( rFmtFtn.IsEndNote() )
+ {
+ sClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_sym );
+ sFtnName.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote );
+ sFtnName.Append( String::CreateFromInt32((sal_Int32)nEndNote) );
+ pInfo = &pDoc->GetEndNoteInfo();
+ }
+ else
+ {
+ sClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_sym );
+ sFtnName.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote );
+ sFtnName.Append( String::CreateFromInt32((sal_Int32)nFootNote));
+ pInfo = &pDoc->GetFtnInfo();
+ }
+
+ const SwCharFmt *pSymCharFmt = pInfo->GetCharFmt( *pDoc );
+ if( pSymCharFmt && aScriptTextStyles.Seek_Entry( (String *)&pSymCharFmt->GetName() ) )
+ {
+ switch( nScript )
+ {
+ case CSS1_OUTMODE_WESTERN:
+ sClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
+ break;
+ case CSS1_OUTMODE_CJK:
+ sClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
+ break;
+ case CSS1_OUTMODE_CTL:
+ sClass.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
+ break;
+ }
+ }
+
+ ByteString sOut( '<' );
+ (((sOut += OOO_STRING_SVTOOLS_HTML_anchor) += ' ') += OOO_STRING_SVTOOLS_HTML_O_class) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), sClass, eDestEnc, &aNonConvertableCharacters );
+ ((sOut = "\" ") += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), sFtnName, eDestEnc, &aNonConvertableCharacters );
+ (((sOut = OOO_STRING_SVTOOLS_HTML_FTN_symbol) +="\" ") += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"#";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), sFtnName, eDestEnc, &aNonConvertableCharacters );
+ (sOut = OOO_STRING_SVTOOLS_HTML_FTN_anchor) += "\">";
+ Strm() << sOut.GetBuffer();
+
+ HTMLOutFuncs::Out_String( Strm(), rNum, eDestEnc, &aNonConvertableCharacters );
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_anchor, FALSE );
+}
+
+USHORT lcl_html_fillEndNoteInfo( const SwEndNoteInfo& rInfo,
+ String *pParts,
+ BOOL bEndNote )
+{
+ USHORT nParts = 0;
+ sal_Int16 eFmt = rInfo.aFmt.GetNumberingType();
+ if( (bEndNote ? SVX_NUM_ROMAN_LOWER : SVX_NUM_ARABIC) != eFmt )
+ {
+ const sal_Char *pStr = SwHTMLWriter::GetNumFormat( eFmt );
+ if( pStr )
+ {
+ pParts[0] = String::CreateFromAscii( pStr );
+ nParts = 1;
+ }
+ }
+ if( rInfo.nFtnOffset > 0 )
+ {
+ pParts[1] = String::CreateFromInt32( (sal_Int32)rInfo.nFtnOffset );
+ nParts = 2;
+ }
+ if( rInfo.GetPrefix().Len() > 0 )
+ {
+ pParts[2] = rInfo.GetPrefix();
+ nParts = 3;
+ }
+ if( rInfo.GetSuffix().Len() > 0 )
+ {
+ pParts[3] = rInfo.GetSuffix();
+ nParts = 4;
+ }
+
+ return nParts;
+}
+
+void lcl_html_outFootEndNoteInfo( Writer& rWrt, String *pParts,
+ USHORT nParts, const sal_Char *pName )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ String aContent;
+ for( USHORT i=0; i<nParts; i++ )
+ {
+ xub_StrLen nPos = 0;
+ String aTmp( pParts[i] );
+ String aRep( String::CreateFromAscii("\\\\") );
+ while( STRING_NOTFOUND != (nPos = aTmp.SearchAndReplaceAscii( "\\",
+ aRep, nPos ) ) )
+ nPos += 2;
+ nPos = 0;
+ aRep.AssignAscii( "\\;" );
+ while( STRING_NOTFOUND != (nPos = aTmp.SearchAndReplaceAscii( ";",
+ aRep, nPos ) ) )
+ nPos += 2;
+ if( i > 0 )
+ aContent += ';';
+ aContent += aTmp;
+ }
+
+ rHTMLWrt.OutNewLine();
+ ByteString sOut( '<' );
+ (((((((sOut += OOO_STRING_SVTOOLS_HTML_meta) += ' ')
+ += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"") += pName) += "\" ")
+ += OOO_STRING_SVTOOLS_HTML_O_content) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aContent, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ rWrt.Strm() << "\">";
+}
+
+void SwHTMLWriter::OutFootEndNoteInfo()
+{
+ // Nummerntyp (1 bzw. i)
+ // Offset (0)
+ // Davor
+ // Dahinter
+ // Dok/Seite/Kap (D)
+ // Position (S)
+ // Folgeseite
+ // Beginn
+
+ {
+ const SwFtnInfo& rInfo = pDoc->GetFtnInfo();
+ String aParts[8];
+ USHORT nParts = lcl_html_fillEndNoteInfo( rInfo, aParts, FALSE );
+ if( rInfo.eNum != FTNNUM_DOC )
+ {
+ aParts[4] = rInfo.eNum == FTNNUM_CHAPTER ? 'C' : 'P';
+ nParts = 5;
+ }
+ if( rInfo.ePos != FTNPOS_PAGE)
+ {
+ aParts[5] = 'C';
+ nParts = 6;
+ }
+ if( rInfo.aQuoVadis.Len() > 0 )
+ {
+ aParts[6] = rInfo.aQuoVadis;
+ nParts = 7;
+ }
+ if( rInfo.aErgoSum.Len() > 0 )
+ {
+ aParts[7] = rInfo.aErgoSum;
+ nParts = 8;
+ }
+ if( nParts > 0 )
+ lcl_html_outFootEndNoteInfo( *this, aParts, nParts,
+ OOO_STRING_SVTOOLS_HTML_META_sdfootnote );
+ }
+
+ {
+ const SwEndNoteInfo& rInfo = pDoc->GetEndNoteInfo();
+ String aParts[4];
+ USHORT nParts = lcl_html_fillEndNoteInfo( rInfo, aParts, TRUE );
+ if( nParts > 0 )
+ lcl_html_outFootEndNoteInfo( *this, aParts, nParts,
+ OOO_STRING_SVTOOLS_HTML_META_sdendnote );
+ }
+}
+
diff --git a/sw/source/filter/html/htmlgrin.cxx b/sw/source/filter/html/htmlgrin.cxx
new file mode 100644
index 000000000000..afcb979abe6c
--- /dev/null
+++ b/sw/source/filter/html/htmlgrin.cxx
@@ -0,0 +1,1448 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <svx/svxids.hrc>
+#include <sfx2/sfx.hrc>
+#include <i18npool/mslangid.hxx>
+#include <svl/stritem.hxx>
+#include <svl/urihelper.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <sfx2/docfile.hxx>
+#include <svtools/imap.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <unotools/eventcfg.hxx>
+
+#include <fmtornt.hxx>
+#include <fmturl.hxx>
+#include <fmtanchr.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtinfmt.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtanchr.hxx>
+#include <fmtfsize.hxx>
+#include <fmtinfmt.hxx>
+#include "frmatr.hxx"
+#include "charatr.hxx"
+#include <frmfmt.hxx>
+#include <charfmt.hxx>
+#include <docary.hxx>
+#include <docsh.hxx>
+#include <pam.hxx>
+#include <doc.hxx>
+#include <ndtxt.hxx>
+#include <shellio.hxx>
+#include <poolfmt.hxx>
+#include <IMark.hxx>
+#include <ndgrf.hxx>
+#include <htmlnum.hxx>
+#include <swcss1.hxx>
+#include <swhtml.hxx>
+#include <numrule.hxx>
+#include <boost/shared_ptr.hpp>
+
+using namespace ::com::sun::star;
+
+
+HTMLOptionEnum __FAR_DATA aHTMLImgHAlignTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_AL_left, text::HoriOrientation::LEFT },
+ { OOO_STRING_SVTOOLS_HTML_AL_right, text::HoriOrientation::RIGHT },
+ { 0, 0 }
+};
+
+
+HTMLOptionEnum __FAR_DATA aHTMLImgVAlignTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_VA_top, text::VertOrientation::LINE_TOP },
+ { OOO_STRING_SVTOOLS_HTML_VA_texttop, text::VertOrientation::CHAR_TOP },
+ { OOO_STRING_SVTOOLS_HTML_VA_middle, text::VertOrientation::CENTER },
+ { OOO_STRING_SVTOOLS_HTML_AL_center, text::VertOrientation::CENTER },
+ { OOO_STRING_SVTOOLS_HTML_VA_absmiddle, text::VertOrientation::LINE_CENTER },
+ { OOO_STRING_SVTOOLS_HTML_VA_bottom, text::VertOrientation::TOP },
+ { OOO_STRING_SVTOOLS_HTML_VA_baseline, text::VertOrientation::TOP },
+ { OOO_STRING_SVTOOLS_HTML_VA_absbottom, text::VertOrientation::LINE_BOTTOM },
+ { 0, 0 }
+};
+
+SV_IMPL_PTRARR( ImageMaps, ImageMapPtr )
+
+ImageMap *SwHTMLParser::FindImageMap( const String& rName ) const
+{
+ ImageMap *pMap = 0;
+
+ ASSERT( rName.GetChar(0) != '#', "FindImageName: Name beginnt mit #!" );
+
+ if( pImageMaps )
+ {
+ for( USHORT i=0; i<pImageMaps->Count(); i++ )
+ {
+ ImageMap *pIMap = (*pImageMaps)[i];
+ if( rName.EqualsIgnoreCaseAscii( pIMap->GetName() ) )
+ {
+ pMap = pIMap;
+ break;
+ }
+ }
+ }
+ return pMap;
+}
+
+void SwHTMLParser::ConnectImageMaps()
+{
+ SwNodes& rNds = pDoc->GetNodes();
+ // auf den Start-Node der 1. Section
+ ULONG nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 1;
+ ULONG nEndIdx = rNds.GetEndOfAutotext().GetIndex();
+
+ SwGrfNode* pGrfNd;
+ while( nMissingImgMaps > 0 && nIdx < nEndIdx )
+ {
+ SwNode *pNd = rNds[nIdx + 1];
+ if( 0 != (pGrfNd = pNd->GetGrfNode()) )
+ {
+ SwFrmFmt *pFmt = pGrfNd->GetFlyFmt();
+ SwFmtURL aURL( pFmt->GetURL() );
+ const ImageMap *pIMap = aURL.GetMap();
+ if( pIMap && pIMap->GetIMapObjectCount()==0 )
+ {
+ // Die (leere) Image-Map des Nodes wird entweder
+ // durch die jetzt gefundene Image-Map ersetzt
+ // oder geloescht.
+ ImageMap *pNewIMap =
+ FindImageMap( pIMap->GetName() );
+ aURL.SetMap( pNewIMap );
+ pFmt->SetFmtAttr( aURL );
+ if( !pGrfNd->IsScaleImageMap() )
+ {
+ // die Grafikgroesse ist mitlerweile da oder dir
+ // Grafik muss nicht skaliert werden
+ pGrfNd->ScaleImageMap();
+ }
+ nMissingImgMaps--; // eine Map weniger suchen
+ }
+ }
+ nIdx = rNds[nIdx]->EndOfSectionIndex() + 1;
+ }
+}
+
+
+/* */
+
+void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri,
+ sal_Int16 eHoriOri,
+ const SfxItemSet &rCSS1ItemSet,
+ const SvxCSS1PropertyInfo &rCSS1PropInfo,
+ SfxItemSet& rFrmItemSet )
+{
+ const SfxItemSet *pCntnrItemSet = 0;
+ USHORT i = aContexts.Count();
+ while( !pCntnrItemSet && i > nContextStMin )
+ pCntnrItemSet = aContexts[--i]->GetFrmItemSet();
+
+ if( pCntnrItemSet )
+ {
+ // Wenn wir und in einem Container befinden wird die Verankerung
+ // des Containers uebernommen.
+ rFrmItemSet.Put( *pCntnrItemSet );
+ }
+ else if( pCSS1Parser->MayBePositioned( rCSS1PropInfo, TRUE ) )
+ {
+ // Wenn die Ausrichtung anhand der CSS1-Optionen gesetzt werden kann
+ // werden die benutzt.
+ SetAnchorAndAdjustment( rCSS1ItemSet, rCSS1PropInfo, rFrmItemSet );
+ }
+ else
+ {
+ // Sonst wird die Ausrichtung entsprechend der normalen HTML-Optionen
+ // gesetzt.
+ SetAnchorAndAdjustment( eVertOri, eHoriOri, rFrmItemSet );
+ }
+}
+
+void SwHTMLParser::SetAnchorAndAdjustment( sal_Int16 eVertOri,
+ sal_Int16 eHoriOri,
+ SfxItemSet& rFrmSet,
+ BOOL bDontAppend )
+{
+ BOOL bMoveBackward = FALSE;
+ SwFmtAnchor aAnchor( FLY_AS_CHAR );
+ sal_Int16 eVertRel = text::RelOrientation::FRAME;
+
+ if( text::HoriOrientation::NONE != eHoriOri )
+ {
+ // den Absatz-Einzug bestimmen
+ USHORT nLeftSpace = 0, nRightSpace = 0;
+ short nIndent = 0;
+ GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
+
+ // Horizonale Ausrichtung und Umlauf bestimmen.
+ sal_Int16 eHoriRel;
+ SwSurround eSurround;
+ switch( eHoriOri )
+ {
+ case text::HoriOrientation::LEFT:
+ eHoriRel = nLeftSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
+ eSurround = SURROUND_RIGHT;
+ break;
+ case text::HoriOrientation::RIGHT:
+ eHoriRel = nRightSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
+ eSurround = SURROUND_LEFT;
+ break;
+ case text::HoriOrientation::CENTER: // fuer Tabellen
+ eHoriRel = text::RelOrientation::FRAME;
+ eSurround = SURROUND_NONE;
+ break;
+ default:
+ eHoriRel = text::RelOrientation::FRAME;
+ eSurround = SURROUND_PARALLEL;
+ break;
+ }
+
+ // Einen neuen Absatz aufmachen, wenn der aktuelle
+ // absatzgebundene Rahmen ohne Umlauf enthaelt.
+ if( !bDontAppend && HasCurrentParaFlys( TRUE ) )
+ {
+ // Wenn der Absatz nur Grafiken enthaelt, braucht er
+ // auch keinen unteren Absatz-Abstand. Da hier auch bei
+ // Verwendung von Styles kein Abstand enstehen soll, wird
+ // hier auch geweohnlich attributiert !!!
+ USHORT nUpper=0, nLower=0;
+ GetULSpaceFromContext( nUpper, nLower );
+ InsertAttr( SvxULSpaceItem( nUpper, 0, RES_UL_SPACE ), FALSE, TRUE );
+
+ AppendTxtNode( AM_NOSPACE );
+
+ if( nUpper )
+ {
+ NewAttr( &aAttrTab.pULSpace, SvxULSpaceItem( 0, nLower, RES_UL_SPACE ) );
+ aParaAttrs.Insert( aAttrTab.pULSpace, aParaAttrs.Count() );
+ EndAttr( aAttrTab.pULSpace, 0, FALSE );
+ }
+ }
+
+ // Vertikale Ausrichtung und Verankerung bestimmen.
+ xub_StrLen nCntnt = pPam->GetPoint()->nContent.GetIndex();
+ if( nCntnt )
+ {
+ aAnchor.SetType( FLY_AT_CHAR );
+ bMoveBackward = TRUE;
+ eVertOri = text::VertOrientation::CHAR_BOTTOM;
+ eVertRel = text::RelOrientation::CHAR;
+ }
+ else
+ {
+ aAnchor.SetType( FLY_AT_PARA );
+ eVertOri = text::VertOrientation::TOP;
+ eVertRel = text::RelOrientation::PRINT_AREA;
+ }
+
+ rFrmSet.Put( SwFmtHoriOrient( 0, eHoriOri, eHoriRel) );
+
+ rFrmSet.Put( SwFmtSurround( eSurround ) );
+ }
+ rFrmSet.Put( SwFmtVertOrient( 0, eVertOri, eVertRel) );
+
+ if( bMoveBackward )
+ pPam->Move( fnMoveBackward );
+
+ aAnchor.SetAnchor( pPam->GetPoint() );
+
+ if( bMoveBackward )
+ pPam->Move( fnMoveForward );
+
+ rFrmSet.Put( aAnchor );
+}
+
+void SwHTMLParser::RegisterFlyFrm( SwFrmFmt *pFlyFmt )
+{
+ // automatisch verankerte Rahmen muessen noch um eine Position
+ // nach vorne verschoben werden.
+ if( RES_DRAWFRMFMT != pFlyFmt->Which() &&
+ (FLY_AT_PARA == pFlyFmt->GetAnchor().GetAnchorId()) &&
+ SURROUND_THROUGHT == pFlyFmt->GetSurround().GetSurround() )
+ {
+ aMoveFlyFrms.Insert( pFlyFmt, aMoveFlyFrms.Count() );
+ aMoveFlyCnts.Insert( pPam->GetPoint()->nContent.GetIndex(),
+ aMoveFlyCnts.Count() );
+ }
+}
+
+/* */
+
+void SwHTMLParser::GetDefaultScriptType( ScriptType& rType,
+ String& rTypeStr ) const
+{
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ SvKeyValueIterator* pHeaderAttrs = pDocSh ? pDocSh->GetHeaderAttributes()
+ : 0;
+ rType = GetScriptType( pHeaderAttrs );
+ rTypeStr = GetScriptTypeString( pHeaderAttrs );
+}
+
+/* */
+
+void SwHTMLParser::InsertImage()
+{
+ // und jetzt auswerten
+ String sGrfNm, sAltNm, aId, aClass, aStyle, aMap, sHTMLGrfName;
+ sal_Int16 eVertOri = text::VertOrientation::TOP;
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+ long nWidth=0, nHeight=0;
+ long nVSpace=0, nHSpace=0;
+
+ USHORT nBorder = (aAttrTab.pINetFmt ? 1 : 0);
+ BOOL bIsMap = FALSE;
+ BOOL bPrcWidth = FALSE;
+ BOOL bPrcHeight = FALSE;
+ SvxMacroItem aMacroItem(RES_FRMMACRO);
+
+ ScriptType eDfltScriptType;
+ String sDfltScriptType;
+ GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ USHORT nEvent = 0;
+ ScriptType eScriptType2 = eDfltScriptType;
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_SRC:
+ sGrfNm = pOption->GetString();
+ if( !InternalImgToPrivateURL(sGrfNm) )
+ sGrfNm = INetURLObject::GetAbsURL( sBaseURL, sGrfNm );
+ break;
+ case HTML_O_ALIGN:
+ eVertOri =
+ pOption->GetEnum( aHTMLImgVAlignTable,
+ text::VertOrientation::TOP );
+ eHoriOri =
+ pOption->GetEnum( aHTMLImgHAlignTable,
+ text::HoriOrientation::NONE );
+ break;
+ case HTML_O_WIDTH:
+ // erstmal nur als Pixelwerte merken!
+ nWidth = pOption->GetNumber();
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ if( bPrcWidth && nWidth>100 )
+ nWidth = 100;
+ break;
+ case HTML_O_HEIGHT:
+ // erstmal nur als Pixelwerte merken!
+ nHeight = pOption->GetNumber();
+ bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ if( bPrcHeight && nHeight>100 )
+ nHeight = 100;
+ break;
+ case HTML_O_VSPACE:
+ nVSpace = pOption->GetNumber();
+ break;
+ case HTML_O_HSPACE:
+ nHSpace = pOption->GetNumber();
+ break;
+ case HTML_O_ALT:
+ sAltNm = pOption->GetString();
+ break;
+ case HTML_O_BORDER:
+ nBorder = (USHORT)pOption->GetNumber();
+ break;
+ case HTML_O_ISMAP:
+ bIsMap = TRUE;
+ break;
+ case HTML_O_USEMAP:
+ aMap = pOption->GetString();
+ break;
+ case HTML_O_NAME:
+ sHTMLGrfName = pOption->GetString();
+ break;
+
+ case HTML_O_SDONLOAD:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONLOAD:
+ nEvent = SVX_EVENT_IMAGE_LOAD;
+ goto IMAGE_SETEVENT;
+
+ case HTML_O_SDONABORT:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONABORT:
+ nEvent = SVX_EVENT_IMAGE_ABORT;
+ goto IMAGE_SETEVENT;
+
+ case HTML_O_SDONERROR:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONERROR:
+ nEvent = SVX_EVENT_IMAGE_ERROR;
+ goto IMAGE_SETEVENT;
+IMAGE_SETEVENT:
+ {
+ String sTmp( pOption->GetString() );
+ if( sTmp.Len() )
+ {
+ sTmp.ConvertLineEnd();
+ String sScriptType;
+ if( EXTENDED_STYPE == eScriptType2 )
+ sScriptType = sDfltScriptType;
+ aMacroItem.SetMacro( nEvent,
+ SvxMacro( sTmp, sScriptType, eScriptType2 ));
+ }
+ }
+ break;
+ }
+ }
+
+ if( !sGrfNm.Len() )
+ return;
+
+ // Wenn wir in einer Numerierung stehen und der Absatz noch leer und
+ // nicht numeriert ist, handelt es sich vielleicht um die Grafik
+ // einer Bullet-Liste
+ if( !pPam->GetPoint()->nContent.GetIndex() &&
+ GetNumInfo().GetDepth() > 0 && GetNumInfo().GetDepth() <= MAXLEVEL &&
+ aBulletGrfs[GetNumInfo().GetDepth()-1].Len() &&
+ aBulletGrfs[GetNumInfo().GetDepth()-1]==sGrfNm )
+ {
+ SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
+
+ if( pTxtNode && ! pTxtNode->IsCountedInList())
+ {
+ ASSERT( pTxtNode->GetActualListLevel() == GetNumInfo().GetLevel(),
+ "Numerierungs-Ebene stimmt nicht" );
+
+ pTxtNode->SetCountedInList( true );
+
+ // Rule invalisieren ist noetig, weil zwischem dem einlesen
+ // des LI und der Grafik ein EndAction gerufen worden sein kann.
+ if( GetNumInfo().GetNumRule() )
+ GetNumInfo().GetNumRule()->SetInvalidRule( TRUE );
+
+ // Die Vorlage novh mal setzen. Ist noetig, damit der
+ // Erstzeilen-Einzug stimmt.
+ SetTxtCollAttrs();
+
+ return;
+ }
+ }
+
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
+
+ SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs( aFrmSet );
+
+ // Umrandung setzen
+ long nHBorderWidth = 0, nVBorderWidth = 0;
+ if( nBorder )
+ {
+ nHBorderWidth = (long)nBorder;
+ nVBorderWidth = (long)nBorder;
+ SvxCSS1Parser::PixelToTwip( nVBorderWidth, nHBorderWidth );
+
+ SvxBorderLine aHBorderLine;
+ SvxBorderLine aVBorderLine;
+
+ SvxCSS1Parser::SetBorderWidth( aHBorderLine,
+ (USHORT)nHBorderWidth, FALSE );
+ if( nHBorderWidth == nVBorderWidth )
+ aVBorderLine.SetOutWidth( aHBorderLine.GetOutWidth() );
+ else
+ SvxCSS1Parser::SetBorderWidth( aVBorderLine,
+ (USHORT)nVBorderWidth, FALSE );
+
+ // die tatsaechlich gesetzter Rahmenbreite benutzen und nicht die
+ // Wunschbreite!
+ nHBorderWidth = aHBorderLine.GetOutWidth();
+ nVBorderWidth = aVBorderLine.GetOutWidth();
+
+ if( aAttrTab.pINetFmt )
+ {
+ const String& rURL =
+ ((const SwFmtINetFmt&)aAttrTab.pINetFmt->GetItem()).GetValue();
+
+ pCSS1Parser->SetATagStyles();
+ USHORT nPoolId = static_cast< USHORT >(pDoc->IsVisitedURL( rURL )
+ ? RES_POOLCHR_INET_VISIT
+ : RES_POOLCHR_INET_NORMAL);
+ const SwCharFmt *pCharFmt = pCSS1Parser->GetCharFmtFromPool( nPoolId );
+ aHBorderLine.SetColor( pCharFmt->GetColor().GetValue() );
+ aVBorderLine.SetColor( aHBorderLine.GetColor() );
+ }
+ else
+ {
+ const SvxColorItem& rColorItem = aAttrTab.pFontColor ?
+ (const SvxColorItem &)aAttrTab.pFontColor->GetItem() :
+ (const SvxColorItem &)pDoc->GetDefault(RES_CHRATR_COLOR);
+ aHBorderLine.SetColor( rColorItem.GetValue() );
+ aVBorderLine.SetColor( aHBorderLine.GetColor() );
+ }
+
+
+ SvxBoxItem aBoxItem( RES_BOX );
+ aBoxItem.SetLine( &aHBorderLine, BOX_LINE_TOP );
+ aBoxItem.SetLine( &aHBorderLine, BOX_LINE_BOTTOM );
+ aBoxItem.SetLine( &aVBorderLine, BOX_LINE_LEFT );
+ aBoxItem.SetLine( &aVBorderLine, BOX_LINE_RIGHT );
+ aFrmSet.Put( aBoxItem );
+ }
+
+ // Ausrichtung setzen
+ SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, aFrmSet );
+
+ // Abstaende setzen
+ SetSpace( Size( nHSpace, nVSpace), aItemSet, aPropInfo, aFrmSet );
+
+ // Sonstige CSS1-Attribute Setzen
+ SetFrmFmtAttrs( aItemSet, aPropInfo, HTML_FF_BOX, aFrmSet );
+
+ Size aTwipSz( bPrcWidth ? 0 : nWidth, bPrcHeight ? 0 : nHeight );
+ if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
+ {
+ aTwipSz = Application::GetDefaultDevice()
+ ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
+ }
+
+ // CSS1-Groesse auf "normale" Groesse umrechnen
+ switch( aPropInfo.eWidthType )
+ {
+ case SVX_CSS1_LTYPE_TWIP:
+ aTwipSz.Width() = aPropInfo.nWidth;
+ nWidth = 1; // != 0
+ bPrcWidth = FALSE;
+ break;
+ case SVX_CSS1_LTYPE_PERCENTAGE:
+ aTwipSz.Width() = 0;
+ nWidth = aPropInfo.nWidth;
+ bPrcWidth = TRUE;
+ break;
+ default:
+ ;
+ }
+ switch( aPropInfo.eHeightType )
+ {
+ case SVX_CSS1_LTYPE_TWIP:
+ aTwipSz.Height() = aPropInfo.nHeight;
+ nHeight = 1; // != 0
+ bPrcHeight = FALSE;
+ break;
+ case SVX_CSS1_LTYPE_PERCENTAGE:
+ aTwipSz.Height() = 0;
+ nHeight = aPropInfo.nHeight;
+ bPrcHeight = TRUE;
+ break;
+ default:
+ ;
+ }
+
+ Size aGrfSz( 0, 0 );
+ BOOL bSetTwipSize = TRUE; // Twip-Size am Node setzen?
+ BOOL bChangeFrmSize = FALSE; // Frame-Format nachtraeglich anpassen?
+ BOOL bRequestGrfNow = FALSE;
+ BOOL bSetScaleImageMap = FALSE;
+ BYTE nPrcWidth = 0, nPrcHeight = 0;
+
+ if( !nWidth || !nHeight )
+ {
+ // Es fehlt die Breite oder die Hoehe
+ // Wenn die Grfik in einer Tabelle steht, wird sie gleich
+ // angefordert, damit sie eventuell schon da ist, bevor die
+ // Tabelle layoutet wird.
+ if( pTable!=0 && !nWidth )
+ {
+ bRequestGrfNow = TRUE;
+ IncGrfsThatResizeTable();
+ }
+
+ // Die Groesse des Rahmens wird nachtraeglich gesetzt
+ bChangeFrmSize = TRUE;
+ aGrfSz = aTwipSz;
+ if( !nWidth && !nHeight )
+ {
+ aTwipSz.Width() = HTML_DFLT_IMG_WIDTH;
+ aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT;
+ }
+ else if( nWidth )
+ {
+ // eine %-Angabe
+ if( bPrcWidth )
+ {
+ nPrcWidth = (BYTE)nWidth;
+ nPrcHeight = 255;
+ }
+ else
+ {
+ aTwipSz.Height() = HTML_DFLT_IMG_HEIGHT;
+ }
+ }
+ else if( nHeight )
+ {
+ if( bPrcHeight )
+ {
+ nPrcHeight = (BYTE)nHeight;
+ nPrcWidth = 255;
+ }
+ else
+ {
+ aTwipSz.Width() = HTML_DFLT_IMG_WIDTH;
+ }
+ }
+ }
+ else
+ {
+ // Breite und Hoehe wurden angegeben und brauchen nicht gesetzt
+ // zu werden
+ bSetTwipSize = FALSE;
+
+ if( bPrcWidth )
+ nPrcWidth = (BYTE)nWidth;
+
+ if( bPrcHeight )
+ nPrcHeight = (BYTE)nHeight;
+ }
+
+ // Image-Map setzen
+ aMap.EraseTrailingChars();
+ if( aMap.Len() )
+ {
+ // Da wir nur lokale Image-Maps kennen nehmen wireinfach alles
+ // hinter dem # als Namen
+ xub_StrLen nPos = aMap.Search( '#' );
+ String aName;
+ if ( STRING_NOTFOUND==nPos )
+ aName = aMap ;
+ else
+ aName = aMap.Copy(nPos+1);
+
+ ImageMap *pImgMap = FindImageMap( aName );
+ if( pImgMap )
+ {
+ SwFmtURL aURL; aURL.SetMap( pImgMap );//wird kopieiert
+
+ bSetScaleImageMap = !nPrcWidth || !nPrcHeight;
+ aFrmSet.Put( aURL );
+ }
+ else
+ {
+ ImageMap aEmptyImgMap( aName );
+ SwFmtURL aURL; aURL.SetMap( &aEmptyImgMap );//wird kopieiert
+ aFrmSet.Put( aURL );
+ nMissingImgMaps++; // es fehlen noch Image-Maps
+
+ // die Grafik muss beim SetTwipSize skaliert werden, wenn
+ // wir keine Groesse am Node gesetzt haben oder die Groesse
+ // nicht der Grafikgroesse entsprach.
+ bSetScaleImageMap = sal_True;
+ }
+ }
+
+ // min. Werte einhalten !!
+ if( nPrcWidth )
+ {
+ ASSERT( !aTwipSz.Width(),
+ "Wieso ist da trotz %-Angabe eine Breite gesetzt?" );
+ aTwipSz.Width() = aGrfSz.Width() ? aGrfSz.Width()
+ : HTML_DFLT_IMG_WIDTH;
+ }
+ else
+ {
+ aTwipSz.Width() += 2*nVBorderWidth;
+ if( aTwipSz.Width() < MINFLY )
+ aTwipSz.Width() = MINFLY;
+ }
+ if( nPrcHeight )
+ {
+ ASSERT( !aTwipSz.Height(),
+ "Wieso ist da trotz %-Angabe eine Hoehe gesetzt?" );
+ aTwipSz.Height() = aGrfSz.Height() ? aGrfSz.Height()
+ : HTML_DFLT_IMG_HEIGHT;
+ }
+ else
+ {
+ aTwipSz.Height() += 2*nHBorderWidth;
+ if( aTwipSz.Height() < MINFLY )
+ aTwipSz.Height() = MINFLY;
+ }
+
+ SwFmtFrmSize aFrmSize( ATT_FIX_SIZE, aTwipSz.Width(), aTwipSz.Height() );
+ aFrmSize.SetWidthPercent( nPrcWidth );
+ aFrmSize.SetHeightPercent( nPrcHeight );
+ aFrmSet.Put( aFrmSize );
+
+ Graphic aEmptyGrf;
+ aEmptyGrf.SetDefaultType();
+ SwFrmFmt *pFlyFmt = pDoc->Insert( *pPam, sGrfNm, aEmptyStr, &aEmptyGrf,
+ &aFrmSet, NULL, NULL );
+ SwGrfNode *pGrfNd = pDoc->GetNodes()[ pFlyFmt->GetCntnt().GetCntntIdx()
+ ->GetIndex()+1 ]->GetGrfNode();
+
+ if( sHTMLGrfName.Len() )
+ {
+ pFlyFmt->SetName( sHTMLGrfName );
+
+ // ggfs. eine Grafik anspringen
+ if( JUMPTO_GRAPHIC == eJumpTo && sHTMLGrfName == sJmpMark )
+ {
+ bChkJumpMark = TRUE;
+ eJumpTo = JUMPTO_NONE;
+ }
+ }
+
+ if( sAltNm.Len() )
+ pGrfNd->SetTitle( sAltNm );
+
+ if( bSetTwipSize )
+ pGrfNd->SetTwipSize( aGrfSz );
+
+ pGrfNd->SetChgTwipSize( bChangeFrmSize, bChangeFrmSize );
+
+ if( bSetScaleImageMap )
+ pGrfNd->SetScaleImageMap( TRUE );
+
+ if( aAttrTab.pINetFmt )
+ {
+ const SwFmtINetFmt &rINetFmt =
+ (const SwFmtINetFmt&)aAttrTab.pINetFmt->GetItem();
+
+ SwFmtURL aURL( pFlyFmt->GetURL() );
+
+ aURL.SetURL( rINetFmt.GetValue(), bIsMap );
+ aURL.SetTargetFrameName( rINetFmt.GetTargetFrame() );
+ aURL.SetName( rINetFmt.GetName() );
+ pFlyFmt->SetFmtAttr( aURL );
+
+ {
+ const SvxMacro *pMacro;
+ static USHORT __READONLY_DATA aEvents[] = {
+ SFX_EVENT_MOUSEOVER_OBJECT,
+ SFX_EVENT_MOUSECLICK_OBJECT,
+ SFX_EVENT_MOUSEOUT_OBJECT,
+ 0 };
+
+ for( USHORT n = 0; aEvents[ n ]; ++n )
+ if( 0 != ( pMacro = rINetFmt.GetMacro( aEvents[ n ] ) ))
+ aMacroItem.SetMacro( aEvents[ n ], *pMacro );
+ }
+
+ if ((FLY_AS_CHAR == pFlyFmt->GetAnchor().GetAnchorId()) &&
+ aAttrTab.pINetFmt->GetSttPara() ==
+ pPam->GetPoint()->nNode &&
+ aAttrTab.pINetFmt->GetSttCnt() ==
+ pPam->GetPoint()->nContent.GetIndex() - 1 )
+ {
+ // das Attribut wurde unmitellbar vor einer zeichengeb.
+ // Grafik eingefuegt, also verschieben wir es
+ aAttrTab.pINetFmt->SetStart( *pPam->GetPoint() );
+
+ // Wenn das Attribut auch ein Sprungziel ist, fuegen
+ // wir noch eine Bookmark vor der Grafik ein, weil das
+ // SwFmtURL kein Sprungziel ist.
+ if( rINetFmt.GetName().Len() )
+ {
+ pPam->Move( fnMoveBackward );
+ InsertBookmark( rINetFmt.GetName() );
+ pPam->Move( fnMoveForward );
+ }
+ }
+
+ }
+
+ if( aMacroItem.GetMacroTable().Count() )
+ pFlyFmt->SetFmtAttr( aMacroItem );
+
+ // Wenn die Grafik gleich angeforder wird, muss dies geschehen,
+ // nachdem das Format vollstaendig aufgebaut ist, weil es evtl.
+ // gleich (synchron) angepasst wird (war bug #40983#)
+ if( bRequestGrfNow )
+ {
+ pGrfNd->SwapIn();
+ }
+
+ // Ggf. Frames anlegen und Auto-gebundenen Rahmen registrieren
+ RegisterFlyFrm( pFlyFmt );
+
+ if( aId.Len() )
+ InsertBookmark( aId );
+}
+
+/* */
+
+void SwHTMLParser::InsertBodyOptions()
+{
+ pDoc->SetTxtFmtColl( *pPam,
+ pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
+
+ String aBackGround, aId, aStyle, aLang, aDir;
+ Color aBGColor, aTextColor, aLinkColor, aVLinkColor;
+ BOOL bBGColor=FALSE, bTextColor=FALSE;
+ BOOL bLinkColor=FALSE, bVLinkColor=FALSE;
+
+ ScriptType eDfltScriptType;
+ String sDfltScriptType;
+ GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ ScriptType eScriptType2 = eDfltScriptType;
+ rtl::OUString aEvent;
+ BOOL bSetEvent = FALSE;
+
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_BACKGROUND:
+ aBackGround = pOption->GetString();
+ break;
+ case HTML_O_BGCOLOR:
+ pOption->GetColor( aBGColor );
+ bBGColor = TRUE;
+ break;
+ case HTML_O_TEXT:
+ pOption->GetColor( aTextColor );
+ bTextColor = TRUE;
+ break;
+ case HTML_O_LINK:
+ pOption->GetColor( aLinkColor );
+ bLinkColor = TRUE;
+ break;
+ case HTML_O_VLINK:
+ pOption->GetColor( aVLinkColor );
+ bVLinkColor = TRUE;
+ break;
+
+ case HTML_O_SDONLOAD:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONLOAD:
+ aEvent = GlobalEventConfig::GetEventName( STR_EVENT_OPENDOC );
+ bSetEvent = TRUE;
+ break;
+
+ case HTML_O_SDONUNLOAD:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONUNLOAD:
+ aEvent = GlobalEventConfig::GetEventName( STR_EVENT_PREPARECLOSEDOC );
+ bSetEvent = TRUE;
+ break;
+
+ case HTML_O_SDONFOCUS:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONFOCUS:
+ aEvent = GlobalEventConfig::GetEventName( STR_EVENT_ACTIVATEDOC );
+ bSetEvent = TRUE;
+ break;
+
+ case HTML_O_SDONBLUR:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONBLUR:
+ aEvent = GlobalEventConfig::GetEventName( STR_EVENT_DEACTIVATEDOC );
+ bSetEvent = TRUE;
+ break;
+
+ case HTML_O_ONERROR:
+// if( bAnyStarBasic )
+// InsertBasicDocEvent( SFX_EVENT_ACTIVATEDOC,
+// pOption->GetString() );
+ break;
+
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ bTextColor = TRUE;
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+
+ if( bSetEvent )
+ {
+ const String& rEvent = pOption->GetString();
+ if( rEvent.Len() )
+ InsertBasicDocEvent( aEvent, rEvent, eScriptType2,
+ sDfltScriptType );
+ }
+ }
+
+ if( bTextColor && !pCSS1Parser->IsBodyTextSet() )
+ {
+ // Die Textfarbe wird an der Standard-Vorlage gesetzt
+ pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )
+ ->SetFmtAttr( SvxColorItem(aTextColor, RES_CHRATR_COLOR) );
+ pCSS1Parser->SetBodyTextSet();
+ }
+
+
+ // Die Item fuer die Seitenvorlage vorbereiten (Hintergrund, Umrandung)
+ // Beim BrushItem muessen schon gesetzte werte erhalten bleiben!
+ SvxBrushItem aBrushItem( pCSS1Parser->GetPageDescBackground() );
+ BOOL bSetBrush = FALSE;
+
+ if( bBGColor && !pCSS1Parser->IsBodyBGColorSet() )
+ {
+ // Hintergrundfarbe aus "BGCOLOR"
+ String aLink;
+ if( aBrushItem.GetGraphicLink() )
+ aLink = *aBrushItem.GetGraphicLink();
+ SvxGraphicPosition ePos = aBrushItem.GetGraphicPos();
+
+ aBrushItem.SetColor( aBGColor );
+
+ if( aLink.Len() )
+ {
+ aBrushItem.SetGraphicLink( aLink );
+ aBrushItem.SetGraphicPos( ePos );
+ }
+ bSetBrush = TRUE;
+ pCSS1Parser->SetBodyBGColorSet();
+ }
+
+ if( aBackGround.Len() && !pCSS1Parser->IsBodyBackgroundSet() )
+ {
+ // Hintergrundgrafik aus "BACKGROUND"
+ aBrushItem.SetGraphicLink( INetURLObject::GetAbsURL( sBaseURL, aBackGround ) );
+ aBrushItem.SetGraphicPos( GPOS_TILED );
+ bSetBrush = TRUE;
+ pCSS1Parser->SetBodyBackgroundSet();
+ }
+
+ if( aStyle.Len() || aDir.Len() )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ String aDummy;
+ ParseStyleOptions( aStyle, aDummy, aDummy, aItemSet, aPropInfo, 0, &aDir );
+
+ // Ein par Attribute muessen an der Seitenvorlage gesetzt werden,
+ // und zwar die, die nicht vererbit werden
+ pCSS1Parser->SetPageDescAttrs( bSetBrush ? &aBrushItem : 0,
+ &aItemSet );
+
+ 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 == aItemSet.GetItemState( aWhichIds[i], FALSE,
+ &pItem ) &&
+ static_cast <const SvxFontHeightItem * >(pItem)->GetProp() != 100)
+ {
+ sal_uInt32 nHeight =
+ ( aFontHeights[2] *
+ static_cast <const SvxFontHeightItem * >(pItem)->GetProp() ) / 100;
+ SvxFontHeightItem aNewItem( nHeight, 100, aWhichIds[i] );
+ aItemSet.Put( aNewItem );
+ }
+ }
+
+ // alle noch uebrigen Optionen koennen an der Standard-Vorlage
+ // gesetzt werden und gelten dann automatisch als defaults
+ pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )
+ ->SetFmtAttr( aItemSet );
+ }
+ else if( bSetBrush )
+ {
+ pCSS1Parser->SetPageDescAttrs( &aBrushItem );
+ }
+
+ if( bLinkColor && !pCSS1Parser->IsBodyLinkSet() )
+ {
+ SwCharFmt *pCharFmt =
+ pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_INET_NORMAL);
+ pCharFmt->SetFmtAttr( SvxColorItem(aLinkColor, RES_CHRATR_COLOR) );
+ pCSS1Parser->SetBodyLinkSet();
+ }
+ if( bVLinkColor && !pCSS1Parser->IsBodyVLinkSet() )
+ {
+ SwCharFmt *pCharFmt =
+ pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_INET_VISIT);
+ pCharFmt->SetFmtAttr( SvxColorItem(aVLinkColor, RES_CHRATR_COLOR) );
+ pCSS1Parser->SetBodyVLinkSet();
+ }
+ if( aLang.Len() )
+ {
+ LanguageType eLang = MsLangId::convertIsoStringToLanguage( aLang );
+ sal_uInt16 nWhich = 0;
+ if( LANGUAGE_DONTKNOW != eLang )
+ {
+ switch( SvtLanguageOptions::GetScriptTypeOfLanguage( eLang ) )
+ {
+ case SCRIPTTYPE_LATIN:
+ nWhich = RES_CHRATR_LANGUAGE;
+ break;
+ case SCRIPTTYPE_ASIAN:
+ nWhich = RES_CHRATR_CJK_LANGUAGE;
+ break;
+ case SCRIPTTYPE_COMPLEX:
+ nWhich = RES_CHRATR_CTL_LANGUAGE;
+ break;
+ }
+ if( nWhich )
+ {
+ SvxLanguageItem aLanguage( eLang, nWhich );
+ aLanguage.SetWhich( nWhich );
+ pDoc->SetDefault( aLanguage );
+ }
+ }
+ }
+
+ if( aId.Len() )
+ InsertBookmark( aId );
+}
+
+/* */
+
+void SwHTMLParser::NewAnchor()
+{
+ // den voherigen Link beenden, falls es einen gab
+ _HTMLAttrContext *pOldCntxt = PopContext( HTML_ANCHOR_ON );
+ if( pOldCntxt )
+ {
+ // und ggf. die Attribute beenden
+ EndContext( pOldCntxt );
+ delete pOldCntxt;
+ }
+
+ SvxMacroTableDtor aMacroTbl;
+ String sHRef, aName, sTarget;
+ String aId, aStyle, aClass, aLang, aDir;
+ BOOL bHasHRef = FALSE, bFixed = FALSE;
+
+ ScriptType eDfltScriptType;
+ String sDfltScriptType;
+ GetDefaultScriptType( eDfltScriptType, sDfltScriptType );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ USHORT nEvent = 0;
+ ScriptType eScriptType2 = eDfltScriptType;
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ break;
+
+ case HTML_O_HREF:
+ sHRef = pOption->GetString();
+ bHasHRef = TRUE;
+ break;
+ case HTML_O_TARGET:
+ sTarget = pOption->GetString();
+ break;
+
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_SDFIXED:
+ bFixed = TRUE;
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+
+ case HTML_O_SDONCLICK:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONCLICK:
+ nEvent = SFX_EVENT_MOUSECLICK_OBJECT;
+ goto ANCHOR_SETEVENT;
+
+ case HTML_O_SDONMOUSEOVER:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONMOUSEOVER:
+ nEvent = SFX_EVENT_MOUSEOVER_OBJECT;
+ goto ANCHOR_SETEVENT;
+
+ case HTML_O_SDONMOUSEOUT:
+ eScriptType2 = STARBASIC;
+ case HTML_O_ONMOUSEOUT:
+ nEvent = SFX_EVENT_MOUSEOUT_OBJECT;
+ goto ANCHOR_SETEVENT;
+ANCHOR_SETEVENT:
+ {
+ String sTmp( pOption->GetString() );
+ if( sTmp.Len() )
+ {
+ sTmp.ConvertLineEnd();
+ String sScriptType;
+ if( EXTENDED_STYPE == eScriptType2 )
+ sScriptType = sDfltScriptType;
+ aMacroTbl.Insert( nEvent,
+ new SvxMacro( sTmp, sScriptType, eScriptType2 ));
+ }
+ }
+ break;
+
+ }
+ }
+
+ // Sprungziele, die unseren ipmliziten Zielen entsprechen, schmeissen
+ // wir hier ganz rigoros raus.
+ if( aName.Len() )
+ {
+ String sDecoded( INetURLObject::decode( aName, INET_HEX_ESCAPE,
+ INetURLObject::DECODE_UNAMBIGUOUS,
+ RTL_TEXTENCODING_UTF8 ));
+ xub_StrLen nPos = sDecoded.SearchBackward( cMarkSeperator );
+ if( STRING_NOTFOUND != nPos )
+ {
+ String sCmp( sDecoded.Copy( nPos+1 ) );
+ sCmp.EraseAllChars();
+ if( sCmp.Len() )
+ {
+ sCmp.ToLowerAscii();
+ if( sCmp.EqualsAscii( pMarkToRegion ) ||
+ sCmp.EqualsAscii( pMarkToFrame ) ||
+ sCmp.EqualsAscii( pMarkToGraphic ) ||
+ sCmp.EqualsAscii( pMarkToOLE ) ||
+ sCmp.EqualsAscii( pMarkToTable ) ||
+ sCmp.EqualsAscii( pMarkToOutline ) ||
+ sCmp.EqualsAscii( pMarkToText ) )
+ {
+ aName.Erase();
+ }
+ }
+ }
+ }
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_ANCHOR_ON );
+
+ BOOL bEnAnchor = FALSE, bFtnAnchor = FALSE, bFtnEnSymbol = FALSE;
+ String aFtnName;
+ String aStrippedClass( aClass );
+ SwCSS1Parser::GetScriptFromClass( aStrippedClass, sal_False );
+ if( aStrippedClass.Len() >=9 && bHasHRef && sHRef.Len() > 1 &&
+ ('s' == aStrippedClass.GetChar(0) || 'S' == aStrippedClass.GetChar(0)) &&
+ ('d' == aStrippedClass.GetChar(1) || 'D' == aStrippedClass.GetChar(1)) )
+ {
+ if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_anc ) )
+ bEnAnchor = TRUE;
+ else if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_anc ) )
+ bFtnAnchor = TRUE;
+ else if( aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdendnote_sym ) ||
+ aStrippedClass.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote_sym ) )
+ bFtnEnSymbol = TRUE;
+ if( bEnAnchor || bFtnAnchor || bFtnEnSymbol )
+ {
+ aFtnName = sHRef.Copy( 1 );
+ aClass = aStrippedClass = aName = aEmptyStr;
+ bHasHRef = FALSE;
+ }
+ }
+
+ // Styles parsen
+ if( HasStyleOptions( aStyle, aId, aStrippedClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+ InsertAttrs( aItemSet, aPropInfo, pCntxt, TRUE );
+ }
+ }
+
+ if( bHasHRef )
+ {
+ if( sHRef.Len() )
+ {
+ sHRef = URIHelper::SmartRel2Abs( INetURLObject(sBaseURL), sHRef, Link(), false );
+ }
+ else
+ {
+ // Bei leerer URL das Directory nehmen
+ INetURLObject aURLObj( aPathToFile );
+ sHRef = aURLObj.GetPartBeforeLastName();
+ }
+
+ pCSS1Parser->SetATagStyles();
+ SwFmtINetFmt aINetFmt( sHRef, sTarget );
+ aINetFmt.SetName( aName );
+
+ if( aMacroTbl.Count() )
+ aINetFmt.SetMacroTbl( &aMacroTbl );
+
+ // das Default-Attribut setzen
+ InsertAttr( &aAttrTab.pINetFmt, aINetFmt, pCntxt );
+ }
+ else if( aName.Len() )
+ {
+ InsertBookmark( aName );
+ }
+
+ if( bEnAnchor || bFtnAnchor )
+ {
+ InsertFootEndNote( aFtnName, bEnAnchor, bFixed );
+ bInFootEndNoteAnchor = bCallNextToken = TRUE;
+ }
+ else if( bFtnEnSymbol )
+ {
+ bInFootEndNoteSymbol = bCallNextToken = TRUE;
+ }
+
+ // den Kontext merken
+ PushContext( pCntxt );
+}
+
+void SwHTMLParser::EndAnchor()
+{
+ if( bInFootEndNoteAnchor )
+ {
+ FinishFootEndNote();
+ bInFootEndNoteAnchor = FALSE;
+ }
+ else if( bInFootEndNoteSymbol )
+ {
+ bInFootEndNoteSymbol = FALSE;
+ }
+
+ EndTag( HTML_ANCHOR_OFF );
+}
+
+/* */
+
+void SwHTMLParser::InsertBookmark( const String& rName )
+{
+ _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(),
+ SfxStringItem( RES_FLTR_BOOKMARK, rName ));
+ aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
+}
+
+BOOL SwHTMLParser::HasCurrentParaBookmarks( BOOL bIgnoreStack ) const
+{
+ BOOL bHasMarks = FALSE;
+ ULONG nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
+
+ // first step: are there still bookmark in the attribute-stack?
+ // bookmarks are added to the end of the stack - thus we only have
+ // to check the last bookmark
+ if( !bIgnoreStack )
+ {
+ _HTMLAttr* pAttr;
+ for( USHORT i = aSetAttrTab.Count(); i; )
+ {
+ pAttr = aSetAttrTab[ --i ];
+ if( RES_FLTR_BOOKMARK == pAttr->pItem->Which() )
+ {
+ if( pAttr->GetSttParaIdx() == nNodeIdx )
+ bHasMarks = TRUE;
+ break;
+ }
+ }
+ }
+
+ if( !bHasMarks )
+ {
+ // second step: when we didnt find a bookmark, check if there is one
+ // set already
+ IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
+ for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
+ ppMark != pMarkAccess->getMarksEnd();
+ ppMark++)
+ {
+ const ::sw::mark::IMark* pBookmark = ppMark->get();
+ ULONG nBookNdIdx = pBookmark->GetMarkPos().nNode.GetIndex();
+ if( nBookNdIdx==nNodeIdx )
+ {
+ bHasMarks = TRUE;
+ break;
+ }
+ else if( nBookNdIdx > nNodeIdx )
+ break;
+ }
+ }
+
+ return bHasMarks;
+}
+
+/* */
+
+void SwHTMLParser::StripTrailingPara()
+{
+ BOOL bSetSmallFont = FALSE;
+
+ SwCntntNode* pCNd = pPam->GetCntntNode();
+ if( !pPam->GetPoint()->nContent.GetIndex() )
+ {
+ if( pCNd && pCNd->StartOfSectionIndex()+2 <
+ pCNd->EndOfSectionIndex() )
+ {
+ ULONG nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
+
+ const SwSpzFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
+
+ for( USHORT i=0; i<rFrmFmtTbl.Count(); i++ )
+ {
+ SwFrmFmt const*const pFmt = rFrmFmtTbl[i];
+ SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
+ SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
+ if (pAPos &&
+ ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
+ (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
+ pAPos->nNode == nNodeIdx )
+
+ return; // den Knoten duerfen wir nicht loeschen
+ }
+
+ SetAttr( FALSE ); // die noch offenen Attribute muessen
+ // beendet werden, bevor der Node
+ // geloescht wird, weil sonst der
+ // End-Index in die Botanik zeigt
+
+ if( pCNd->Len() && pCNd->IsTxtNode() )
+ {
+ // es wurden Felder in den Node eingefuegt, die muessen
+ // wir jetzt verschieben
+ SwTxtNode *pPrvNd = pDoc->GetNodes()[nNodeIdx-1]->GetTxtNode();
+ if( pPrvNd )
+ {
+ SwIndex aSrc( pCNd, 0 );
+ pCNd->GetTxtNode()->CutText( pPrvNd, aSrc, pCNd->Len() );
+ }
+ }
+
+ // jetz muessen wir noch eventuell vorhandene Bookmarks
+ // verschieben
+ IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
+ for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
+ ppMark != pMarkAccess->getMarksEnd();
+ ppMark++)
+ {
+ ::sw::mark::IMark* pMark = ppMark->get();
+ ULONG nBookNdIdx = pMark->GetMarkPos().nNode.GetIndex();
+ if(nBookNdIdx==nNodeIdx)
+ {
+ SwNodeIndex nNewNdIdx(pPam->GetPoint()->nNode);
+ SwCntntNode* pNd = pDoc->GetNodes().GoPrevious(&nNewNdIdx);
+ if(!pNd)
+ {
+ ASSERT(!this, "Hoppla, wo ist mein Vorgaenger-Node");
+ return;
+ }
+ // --> OD 2007-09-27 #i81002# - refactoring
+ // Do not directly manipulate member of <SwBookmark>
+ {
+ SwPosition aNewPos(*pNd);
+ aNewPos.nContent.Assign(pNd, pNd->Len());
+ const SwPaM aPaM(aNewPos);
+ pMarkAccess->repositionMark(ppMark->get(), aPaM);
+ }
+ // <--
+ }
+ else if( nBookNdIdx > nNodeIdx )
+ break;
+ }
+
+ pPam->GetPoint()->nContent.Assign( 0, 0 );
+ pPam->SetMark();
+ pPam->DeleteMark();
+ pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
+ pPam->Move( fnMoveBackward, fnGoNode );
+ }
+ else if( pCNd && pCNd->IsTxtNode() && pTable )
+ {
+ // In leeren Zellen stellen wir einen kleinen Font ein, damit die
+ // Zelle nicht hoeher wird als die Grafik bzw. so niedrig wie
+ // moeglich bleibt.
+ bSetSmallFont = TRUE;
+ }
+ }
+ else if( pCNd && pCNd->IsTxtNode() && pTable &&
+ pCNd->StartOfSectionIndex()+2 ==
+ pCNd->EndOfSectionIndex() )
+ {
+ // Wenn die Zelle nur zeichengebundene Grafiken/Rahmen enthaelt
+ // stellen wir ebenfalls einen kleinen Font ein.
+ bSetSmallFont = TRUE;
+ SwTxtNode* pTxtNd = pCNd->GetTxtNode();
+
+ xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
+ while( bSetSmallFont && nPos>0 )
+ {
+ --nPos;
+ bSetSmallFont =
+ (CH_TXTATR_BREAKWORD == pTxtNd->GetTxt().GetChar( nPos )) &&
+ (0 != pTxtNd->GetTxtAttrForCharAt( nPos, RES_TXTATR_FLYCNT ));
+ }
+ }
+
+ if( bSetSmallFont )
+ {
+ SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+ }
+}
+
diff --git a/sw/source/filter/html/htmlnum.cxx b/sw/source/filter/html/htmlnum.cxx
new file mode 100644
index 000000000000..0cf9d8d6d04c
--- /dev/null
+++ b/sw/source/filter/html/htmlnum.cxx
@@ -0,0 +1,987 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <com/sun/star/style/NumberingType.hpp>
+#include <hintids.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmlout.hxx>
+#include <svl/urihelper.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <numrule.hxx>
+#include <doc.hxx>
+#include <docary.hxx>
+#include <poolfmt.hxx>
+#include <ndtxt.hxx>
+#include <paratr.hxx>
+
+#include "htmlnum.hxx"
+#include "swcss1.hxx"
+#include "swhtml.hxx"
+#include "wrthtml.hxx"
+
+#include <SwNodeNum.hxx>
+
+using namespace ::com::sun::star;
+
+// TODO: Unicode: Are these characters the correct ones?
+#define HTML_BULLETCHAR_DISC (0xe008)
+#define HTML_BULLETCHAR_CIRCLE (0xe009)
+#define HTML_BULLETCHAR_SQUARE (0xe00b)
+
+
+// <UL TYPE=...>
+static HTMLOptionEnum __FAR_DATA aHTMLULTypeTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_ULTYPE_disc, HTML_BULLETCHAR_DISC },
+ { OOO_STRING_SVTOOLS_HTML_ULTYPE_circle, HTML_BULLETCHAR_CIRCLE },
+ { OOO_STRING_SVTOOLS_HTML_ULTYPE_square, HTML_BULLETCHAR_SQUARE },
+ { 0, 0 }
+};
+
+/* */
+
+void SwHTMLNumRuleInfo::Set( const SwTxtNode& rTxtNd )
+{
+ // --> OD 2006-06-12 #b6435904#
+ // export all numberings, except the outline numbering.
+// if( rTxtNd.GetNumRule() && ! rTxtNd.IsOutline())
+ const SwNumRule* pTxtNdNumRule( rTxtNd.GetNumRule() );
+ if ( pTxtNdNumRule &&
+ pTxtNdNumRule != rTxtNd.GetDoc()->GetOutlineNumRule() )
+ {
+ pNumRule = const_cast<SwNumRule*>(pTxtNdNumRule);
+ nDeep = static_cast< sal_uInt16 >(pNumRule ? rTxtNd.GetActualListLevel() + 1 : 0);
+ bNumbered = rTxtNd.IsCountedInList();
+ // --> OD 2008-02-27 #refactorlists#
+ // --> OD 2005-11-16 #i57919#
+ // correction of refactoring done by cws swnumtree:
+ // <bRestart> has to be set to <true>, if numbering is restarted at this
+ // text node and the start value equals <USHRT_MAX>.
+ // Start value <USHRT_MAX> indicates, that at this text node the numbering
+ // is restarted with the value given at the corresponding level.
+// bRestart = rTxtNd.IsListRestart() &&
+// GetNum() && rTxtNd.GetNum()->GetStartValue() == USHRT_MAX;
+ bRestart = rTxtNd.IsListRestart() && !rTxtNd.HasAttrListRestartValue();
+ // <--
+ }
+ // <--
+ else
+ {
+ pNumRule = 0;
+ nDeep = 0;
+ bNumbered = bRestart = sal_False;
+ }
+}
+
+/* */
+
+void SwHTMLParser::NewNumBulList( int nToken )
+{
+ SwHTMLNumRuleInfo& rInfo = GetNumInfo();
+
+ // Erstmal einen neuen Absatz aufmachen
+ sal_Bool bSpace = (rInfo.GetDepth() + nDefListDeep) == 0;
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( bSpace ? AM_SPACE : AM_NOSPACE, sal_False );
+ else if( bSpace )
+ AddParSpace();
+
+ // Die Numerierung-Ebene erhoehen
+ rInfo.IncDepth();
+ sal_uInt8 nLevel = (sal_uInt8)( (rInfo.GetDepth() <= MAXLEVEL ? rInfo.GetDepth()
+ : MAXLEVEL) - 1 );
+
+ // ggf. ein Regelwerk anlegen
+ if( !rInfo.GetNumRule() )
+ {
+ sal_uInt16 nPos = pDoc->MakeNumRule( pDoc->GetUniqueNumRuleName() );
+ rInfo.SetNumRule( pDoc->GetNumRuleTbl()[nPos] );
+ }
+
+ // das Format anpassen, falls es fuer den Level noch nicht
+ // geschehen ist!
+ sal_Bool bNewNumFmt = rInfo.GetNumRule()->GetNumFmt( nLevel ) == 0;
+ sal_Bool bChangeNumFmt = sal_False;
+
+ // das default Numerierungsformat erstellen
+ SwNumFmt aNumFmt( rInfo.GetNumRule()->Get(nLevel) );
+ rInfo.SetNodeStartValue( nLevel );
+ if( bNewNumFmt )
+ {
+ sal_uInt16 nChrFmtPoolId = 0;
+ if( HTML_ORDERLIST_ON == nToken )
+ {
+ aNumFmt.SetNumberingType(SVX_NUM_ARABIC);
+ nChrFmtPoolId = RES_POOLCHR_NUM_LEVEL;
+ }
+ else
+ {
+ // Wir setzen hier eine Zeichenvorlage, weil die UI das auch
+ // so macht. Dadurch wurd immer auch eine 9pt-Schrift
+ // eingestellt, was in Netscape nicht der Fall ist. Bisher hat
+ // das noch niemanden gestoert.
+ // --> OD 2008-06-03 #i63395#
+ // Only apply user defined default bullet font
+ if ( numfunc::IsDefBulletFontUserDefined() )
+ {
+ aNumFmt.SetBulletFont( &numfunc::GetDefBulletFont() );
+ }
+ // <--
+ aNumFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
+ aNumFmt.SetBulletChar( cBulletChar ); // das Bulletzeichen !!
+ nChrFmtPoolId = RES_POOLCHR_BUL_LEVEL;
+ }
+
+ sal_uInt16 nAbsLSpace = HTML_NUMBUL_MARGINLEFT;
+
+ short nFirstLineIndent = HTML_NUMBUL_INDENT;
+ if( nLevel > 0 )
+ {
+ const SwNumFmt& rPrevNumFmt = rInfo.GetNumRule()->Get( nLevel-1 );
+ nAbsLSpace = nAbsLSpace + rPrevNumFmt.GetAbsLSpace();
+ nFirstLineIndent = rPrevNumFmt.GetFirstLineOffset();
+ }
+ aNumFmt.SetAbsLSpace( nAbsLSpace );
+ aNumFmt.SetFirstLineOffset( nFirstLineIndent );
+ aNumFmt.SetCharFmt( pCSS1Parser->GetCharFmtFromPool(nChrFmtPoolId) );
+
+ bChangeNumFmt = sal_True;
+ }
+ else if( 1 != aNumFmt.GetStart() )
+ {
+ // Wenn die Ebene schon mal benutzt wurde, muss der Start-Wert
+ // ggf. hart am Absatz gesetzt werden.
+ rInfo.SetNodeStartValue( nLevel, 1 );
+ }
+
+ // und es ggf. durch die Optionen veraendern
+ String aId, aStyle, aClass, aBulletSrc, aLang, aDir;
+ sal_Int16 eVertOri = text::VertOrientation::NONE;
+ sal_uInt16 nWidth=USHRT_MAX, nHeight=USHRT_MAX;
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_TYPE:
+ if( bNewNumFmt && pOption->GetString().Len() )
+ {
+ switch( nToken )
+ {
+ case HTML_ORDERLIST_ON:
+ bChangeNumFmt = sal_True;
+ switch( pOption->GetString().GetChar(0) )
+ {
+ case 'A': aNumFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER); break;
+ case 'a': aNumFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER); break;
+ case 'I': aNumFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); break;
+ case 'i': aNumFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); break;
+ default: bChangeNumFmt = sal_False;
+ }
+ break;
+
+ case HTML_UNORDERLIST_ON:
+ aNumFmt.SetBulletChar( (sal_Unicode)pOption->GetEnum(
+ aHTMLULTypeTable,aNumFmt.GetBulletChar() ) );
+ bChangeNumFmt = sal_True;
+ break;
+ }
+ }
+ break;
+ case HTML_O_START:
+ {
+ sal_uInt16 nStart = (sal_uInt16)pOption->GetNumber();
+ if( bNewNumFmt )
+ {
+ aNumFmt.SetStart( nStart );
+ bChangeNumFmt = sal_True;
+ }
+ else
+ {
+ rInfo.SetNodeStartValue( nLevel, nStart );
+ }
+ }
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ case HTML_O_SRC:
+ if( bNewNumFmt )
+ {
+ aBulletSrc = pOption->GetString();
+ if( !InternalImgToPrivateURL(aBulletSrc) )
+ aBulletSrc = URIHelper::SmartRel2Abs( INetURLObject( sBaseURL ), aBulletSrc, Link(), false );
+ }
+ break;
+ case HTML_O_WIDTH:
+ nWidth = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_HEIGHT:
+ nHeight = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_ALIGN:
+ eVertOri =
+ (sal_Int16)pOption->GetEnum( aHTMLImgVAlignTable,
+ static_cast< sal_uInt16 >(eVertOri) );
+ break;
+ }
+ }
+
+ if( aBulletSrc.Len() )
+ {
+ // Eine Bullet-Liste mit Grafiken
+ aNumFmt.SetNumberingType(SVX_NUM_BITMAP);
+
+ // Die Grafik als Brush anlegen
+ SvxBrushItem aBrushItem( RES_BACKGROUND );
+ aBrushItem.SetGraphicLink( aBulletSrc );
+ aBrushItem.SetGraphicPos( GPOS_AREA );
+
+ // Die Groesse nur beachten, wenn Breite und Hoehe vorhanden sind
+ Size aTwipSz( nWidth, nHeight), *pTwipSz=0;
+ if( nWidth!=USHRT_MAX && nHeight!=USHRT_MAX )
+ {
+ aTwipSz =
+ Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
+ MapMode(MAP_TWIP) );
+ pTwipSz = &aTwipSz;
+ }
+
+ // Die Ausrichtung auch nur beachten, wenn eine Ausrichtung
+ // angegeben wurde
+ aNumFmt.SetGraphicBrush( &aBrushItem, pTwipSz,
+ text::VertOrientation::NONE!=eVertOri ? &eVertOri : 0);
+
+ // Und noch die Grafik merken, um sie in den Absaetzen nicht
+ // einzufuegen
+ aBulletGrfs[nLevel] = aBulletSrc;
+ bChangeNumFmt = sal_True;
+ }
+ else
+ aBulletGrfs[nLevel].Erase();
+
+ // den aktuellen Absatz erst einmal nicht numerieren
+ {
+ BYTE nLvl = nLevel;
+ // --> OD 2008-04-02 #refactorlists#
+// SetNoNum(&nLvl, TRUE); // #115962#
+// SetNodeNum( nLvl );
+ SetNodeNum( nLvl, false );
+ // <--
+ }
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
+
+ // Styles parsen
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ if( bNewNumFmt )
+ {
+ if( aPropInfo.bLeftMargin )
+ {
+ // Der Der Default-Einzug wurde schon eingefuegt.
+ sal_uInt16 nAbsLSpace =
+ aNumFmt.GetAbsLSpace() - HTML_NUMBUL_MARGINLEFT;
+ if( aPropInfo.nLeftMargin < 0 &&
+ nAbsLSpace < -aPropInfo.nLeftMargin )
+ nAbsLSpace = 0U;
+ else if( aPropInfo.nLeftMargin > USHRT_MAX ||
+ (long)nAbsLSpace +
+ aPropInfo.nLeftMargin > USHRT_MAX )
+ nAbsLSpace = USHRT_MAX;
+ else
+ nAbsLSpace = nAbsLSpace + (sal_uInt16)aPropInfo.nLeftMargin;
+
+ aNumFmt.SetAbsLSpace( nAbsLSpace );
+ bChangeNumFmt = sal_True;
+ }
+ if( aPropInfo.bTextIndent )
+ {
+ short nTextIndent =
+ ((const SvxLRSpaceItem &)aItemSet.Get( RES_LR_SPACE ))
+ .GetTxtFirstLineOfst();
+ aNumFmt.SetFirstLineOffset( nTextIndent );
+ bChangeNumFmt = sal_True;
+ }
+ }
+ aPropInfo.bLeftMargin = aPropInfo.bTextIndent = sal_False;
+ if( !aPropInfo.bRightMargin )
+ aItemSet.ClearItem( RES_LR_SPACE );
+
+ // --> OD 2008-06-26 #i89812#
+ // Perform change to list style before calling <DoPositioning(..)>,
+ // because <DoPositioning(..)> may open a new context and thus may
+ // clear the <SwHTMLNumRuleInfo> instance hold by local variable <rInfo>.
+ if( bChangeNumFmt )
+ {
+ rInfo.GetNumRule()->Set( nLevel, aNumFmt );
+ pDoc->ChgNumRuleFmts( *rInfo.GetNumRule() );
+ bChangeNumFmt = sal_False;
+ }
+ // <--
+
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+
+ InsertAttrs( aItemSet, aPropInfo, pCntxt );
+ }
+ }
+
+ if( bChangeNumFmt )
+ {
+ rInfo.GetNumRule()->Set( nLevel, aNumFmt );
+ pDoc->ChgNumRuleFmts( *rInfo.GetNumRule() );
+ }
+
+ PushContext( pCntxt );
+
+ // die Attribute der neuen Vorlage setzen
+ SetTxtCollAttrs( pCntxt );
+}
+
+void SwHTMLParser::EndNumBulList( int nToken )
+{
+ SwHTMLNumRuleInfo& rInfo = GetNumInfo();
+
+ // Ein neuer Absatz muss aufgemacht werden, wenn
+ // - der aktuelle nicht leer ist, also Text oder absatzgebundene Objekte
+ // enthaelt.
+ // - der aktuelle Absatz numeriert ist.
+ sal_Bool bAppend = pPam->GetPoint()->nContent.GetIndex() > 0;
+ if( !bAppend )
+ {
+ SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
+
+ bAppend = (pTxtNode && ! pTxtNode->IsOutline() && pTxtNode->IsCountedInList()) ||
+
+ HasCurrentParaFlys();
+ }
+
+ sal_Bool bSpace = (rInfo.GetDepth() + nDefListDeep) == 1;
+ if( bAppend )
+ AppendTxtNode( bSpace ? AM_SPACE : AM_NOSPACE, sal_False );
+ else if( bSpace )
+ AddParSpace();
+
+ // den aktuellen Kontext vom Stack holen
+ _HTMLAttrContext *pCntxt = nToken!=0 ? PopContext( static_cast< sal_uInt16 >(nToken & ~1) ) : 0;
+
+ // Keine Liste aufgrund eines Tokens beenden, wenn der Kontext
+ // nie angelgt wurde oder nicht beendet werden darf.
+ if( rInfo.GetDepth()>0 && (!nToken || pCntxt) )
+ {
+ rInfo.DecDepth();
+ if( !rInfo.GetDepth() ) // wars der letze Level ?
+ {
+ // Die noch nicht angepassten Formate werden jetzt noch
+ // angepasst, damit es sich besser Editieren laesst.
+ const SwNumFmt *pRefNumFmt = 0;
+ sal_Bool bChanged = sal_False;
+ for( sal_uInt16 i=0; i<MAXLEVEL; i++ )
+ {
+ const SwNumFmt *pNumFmt = rInfo.GetNumRule()->GetNumFmt(i);
+ if( pNumFmt )
+ {
+ pRefNumFmt = pNumFmt;
+ }
+ else if( pRefNumFmt )
+ {
+ SwNumFmt aNumFmt( rInfo.GetNumRule()->Get(i) );
+ aNumFmt.SetNumberingType(pRefNumFmt->GetNumberingType() != SVX_NUM_BITMAP
+ ? pRefNumFmt->GetNumberingType() : style::NumberingType::CHAR_SPECIAL);
+ if( SVX_NUM_CHAR_SPECIAL == aNumFmt.GetNumberingType() )
+ {
+ // --> OD 2008-06-03 #i63395#
+ // Only apply user defined default bullet font
+ if ( numfunc::IsDefBulletFontUserDefined() )
+ {
+ aNumFmt.SetBulletFont( &numfunc::GetDefBulletFont() );
+ }
+ // <--
+ aNumFmt.SetBulletChar( cBulletChar );
+ }
+ aNumFmt.SetAbsLSpace( (i+1) * HTML_NUMBUL_MARGINLEFT );
+ aNumFmt.SetFirstLineOffset( HTML_NUMBUL_INDENT );
+ aNumFmt.SetCharFmt( pRefNumFmt->GetCharFmt() );
+ rInfo.GetNumRule()->Set( i, aNumFmt );
+ bChanged = sal_True;
+ }
+ }
+ if( bChanged )
+ pDoc->ChgNumRuleFmts( *rInfo.GetNumRule() );
+
+ // Beim letzen Append wurde das NumRule-Item und das
+ // NodeNum-Objekt mit kopiert. Beides muessen wir noch
+ // loeschen. Das ResetAttr loescht das NodeNum-Objekt mit!
+ pPam->GetNode()->GetTxtNode()->ResetAttr( RES_PARATR_NUMRULE );
+
+ rInfo.Clear();
+ }
+ else
+ {
+ // den naechsten Absatz erstmal nicht numerieren
+ // --> OD 2008-04-02 #refactorlists#
+// SetNodeNum( rInfo.GetLevel() | NO_NUMLEVEL );
+ SetNodeNum( rInfo.GetLevel(), false );
+ // <--
+ }
+ }
+
+ // und noch Attribute beenden
+ sal_Bool bSetAttrs = sal_False;
+ if( pCntxt )
+ {
+ EndContext( pCntxt );
+ delete pCntxt;
+ bSetAttrs = sal_True;
+ }
+
+ if( nToken )
+ SetTxtCollAttrs();
+
+ if( bSetAttrs )
+ SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
+
+}
+
+/* */
+
+void SwHTMLParser::NewNumBulListItem( int nToken )
+{
+ sal_uInt8 nLevel = GetNumInfo().GetLevel();
+ String aId, aStyle, aClass, aLang, aDir;
+ sal_uInt16 nStart = HTML_LISTHEADER_ON != nToken
+ ? GetNumInfo().GetNodeStartValue( nLevel )
+ : USHRT_MAX;
+ if( USHRT_MAX != nStart )
+ GetNumInfo().SetNodeStartValue( nLevel );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_VALUE:
+ nStart = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ // einen neuen Absatz aufmachen
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_NOSPACE, sal_False );
+ bNoParSpace = sal_False; // In <LI> wird kein Abstand eingefuegt!
+
+ // --> OD 2008-04-02 #refactorlists#
+// if( HTML_LISTHEADER_ON==nToken )
+// SetNoNum(&nLevel, TRUE);
+ const bool bCountedInList( HTML_LISTHEADER_ON==nToken ? false : true );
+ // <--
+
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
+
+ String aNumRuleName;
+ if( GetNumInfo().GetNumRule() )
+ {
+ aNumRuleName = GetNumInfo().GetNumRule()->GetName();
+ }
+ else
+ {
+ aNumRuleName = pDoc->GetUniqueNumRuleName();
+ // --> OD 2008-02-11 #newlistlevelattrs#
+ SwNumRule aNumRule( aNumRuleName,
+ SvxNumberFormat::LABEL_WIDTH_AND_POSITION );
+ // <--
+ SwNumFmt aNumFmt( aNumRule.Get( 0 ) );
+ // --> OD 2008-06-03 #i63395#
+ // Only apply user defined default bullet font
+ if ( numfunc::IsDefBulletFontUserDefined() )
+ {
+ aNumFmt.SetBulletFont( &numfunc::GetDefBulletFont() );
+ }
+ // <--
+ aNumFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
+ aNumFmt.SetBulletChar( cBulletChar ); // das Bulletzeichen !!
+ aNumFmt.SetCharFmt( pCSS1Parser->GetCharFmtFromPool(RES_POOLCHR_BUL_LEVEL) );
+ aNumFmt.SetLSpace( (sal_uInt16)(-HTML_NUMBUL_INDENT) );
+ aNumFmt.SetFirstLineOffset( HTML_NUMBUL_INDENT );
+ aNumRule.Set( 0, aNumFmt );
+
+ pDoc->MakeNumRule( aNumRuleName, &aNumRule );
+
+ ASSERT( !nOpenParaToken,
+ "Jetzt geht ein offenes Absatz-Element verloren" );
+ // Wir tun so, als ob wir in einem Absatz sind. Dann wird
+ // beim naechsten Absatz wenigstens die Numerierung
+ // weggeschmissen, die nach dem naechsten AppendTxtNode uebernommen
+ // wird.
+ nOpenParaToken = static_cast< sal_uInt16 >(nToken);
+ }
+
+ SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
+ ((SwCntntNode *)pTxtNode)->SetAttr( SwNumRuleItem(aNumRuleName) );
+ pTxtNode->SetAttrListLevel(nLevel);
+ // --> OD 2005-11-14 #i57656#
+ // <IsCounted()> state of text node has to be adjusted accordingly.
+ if ( /*nLevel >= 0 &&*/ nLevel < MAXLEVEL )
+ {
+ // --> OD 2008-04-02 #refactorlists#
+ pTxtNode->SetCountedInList( bCountedInList );
+ // <--
+ }
+ // <--
+ // --> OD 2005-11-15 #i57919#
+ // correction of refactoring done by cws swnumtree
+ // - <nStart> contains the start value, if the numbering has to be restarted
+ // at this text node. Value <USHRT_MAX> indicates, that numbering isn't
+ // restarted at this text node
+ if ( nStart != USHRT_MAX )
+ {
+ pTxtNode->SetListRestart( true );
+ pTxtNode->SetAttrListRestartValue( nStart );
+ }
+ // <--
+
+ if( GetNumInfo().GetNumRule() )
+ GetNumInfo().GetNumRule()->SetInvalidRule( sal_True );
+
+ // Styles parsen
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+ InsertAttrs( aItemSet, aPropInfo, pCntxt );
+ }
+ }
+
+ PushContext( pCntxt );
+
+ // die neue Vorlage setzen
+ SetTxtCollAttrs( pCntxt );
+
+ // Laufbalkenanzeige aktualisieren
+ ShowStatline();
+}
+
+void SwHTMLParser::EndNumBulListItem( int nToken, sal_Bool bSetColl,
+ sal_Bool /*bLastPara*/ )
+{
+ // einen neuen Absatz aufmachen
+ if( !nToken && pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_NOSPACE );
+
+ // Kontext zu dem Token suchen und vom Stack holen
+ _HTMLAttrContext *pCntxt = 0;
+ sal_uInt16 nPos = aContexts.Count();
+ nToken &= ~1;
+ while( !pCntxt && nPos>nContextStMin )
+ {
+ sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
+ switch( nCntxtToken )
+ {
+ case HTML_LI_ON:
+ case HTML_LISTHEADER_ON:
+ if( !nToken || nToken == nCntxtToken )
+ {
+ pCntxt = aContexts[nPos];
+ aContexts.Remove( nPos, 1 );
+ }
+ break;
+ case HTML_ORDERLIST_ON:
+ case HTML_UNORDERLIST_ON:
+ case HTML_MENULIST_ON:
+ case HTML_DIRLIST_ON:
+ // keine LI/LH ausserhalb der aktuellen Liste betrachten
+ nPos = nContextStMin;
+ break;
+ }
+ }
+
+ // und noch Attribute beenden
+ if( pCntxt )
+ {
+ EndContext( pCntxt );
+ SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
+ delete pCntxt;
+ }
+
+ // und die bisherige Vorlage setzen
+ if( bSetColl )
+ SetTxtCollAttrs();
+}
+
+/* */
+
+// --> OD 2008-04-02 #refactorlists#
+void SwHTMLParser::SetNodeNum( sal_uInt8 nLevel, bool bCountedInList )
+{
+ SwTxtNode* pTxtNode = pPam->GetNode()->GetTxtNode();
+ ASSERT( pTxtNode, "Kein Text-Node an PaM-Position" );
+
+ ASSERT( GetNumInfo().GetNumRule(), "Kein Numerierungs-Regel" );
+ const String& rName = GetNumInfo().GetNumRule()->GetName();
+ ((SwCntntNode *)pTxtNode)->SetAttr( SwNumRuleItem(rName) );
+
+ // --> OD 2008-04-02 #refactorlists#
+// // --> OD 2005-11-14 #i57656#
+// // consider usage of NO_NUMLEVEL - see implementation of <SwTxtNode::SetLevel(..)>
+// if ( /*nLevel >= 0 &&*/ ( nLevel & NO_NUMLEVEL ) )
+// {
+// pTxtNode->SetAttrListLevel( nLevel & ~NO_NUMLEVEL );
+// pTxtNode->SetCountedInList( false );
+// }
+// else
+// {
+// pTxtNode->SetAttrListLevel( nLevel );
+// pTxtNode->SetCountedInList( true );
+// }
+ pTxtNode->SetAttrListLevel( nLevel );
+ pTxtNode->SetCountedInList( bCountedInList );
+ // <--
+
+ // NumRule invalidieren, weil sie durch ein EndAction bereits
+ // auf valid geschaltet worden sein kann.
+ GetNumInfo().GetNumRule()->SetInvalidRule( sal_False );
+}
+
+
+/* */
+
+void SwHTMLWriter::FillNextNumInfo()
+{
+ pNextNumRuleInfo = 0;
+
+ ULONG nPos = pCurPam->GetPoint()->nNode.GetIndex() + 1;
+
+ sal_Bool bTable = sal_False;
+ do
+ {
+ const SwNode* pNd = pDoc->GetNodes()[nPos];
+ if( pNd->IsTxtNode() )
+ {
+ // Der naechste wird als naechstes ausgegeben.
+ pNextNumRuleInfo = new SwHTMLNumRuleInfo( *pNd->GetTxtNode() );
+
+ // Vor einer Tabelle behalten wir erst einmal die alte Ebene bei,
+ // wenn die gleiche Numerierung hinter der Tabelle
+ // fortgesetzt wird und dort nicht von vorne numeriert
+ // wird. Die Tabelle wird ann beim Import so weit eingeruckt,
+ // wie es der Num-Ebene entspricht.
+ if( bTable &&
+ pNextNumRuleInfo->GetNumRule()==GetNumInfo().GetNumRule() &&
+ !pNextNumRuleInfo->IsRestart() )
+ {
+ pNextNumRuleInfo->SetDepth( GetNumInfo().GetDepth() );
+ }
+ }
+ else if( pNd->IsTableNode() )
+ {
+ // Eine Tabelle wird uebersprungen, also den Node
+ // hinter der Tabelle betrachten.
+ nPos = pNd->EndOfSectionIndex() + 1;
+ bTable = sal_True;
+ }
+ else
+ {
+ // In allen anderen Faellen ist die Numerierung erstmal
+ // zu Ende.
+ pNextNumRuleInfo = new SwHTMLNumRuleInfo;
+ }
+ }
+ while( !pNextNumRuleInfo );
+}
+
+void SwHTMLWriter::ClearNextNumInfo()
+{
+ delete pNextNumRuleInfo;
+ pNextNumRuleInfo = 0;
+}
+
+Writer& OutHTML_NumBulListStart( SwHTMLWriter& rWrt,
+ const SwHTMLNumRuleInfo& rInfo )
+{
+ SwHTMLNumRuleInfo& rPrevInfo = rWrt.GetNumInfo();
+ sal_Bool bSameRule = rPrevInfo.GetNumRule() == rInfo.GetNumRule();
+ if( bSameRule && rPrevInfo.GetDepth() >= rInfo.GetDepth() &&
+ !rInfo.IsRestart() )
+ {
+ return rWrt;
+ }
+
+ sal_Bool bStartValue = sal_False;
+ if( !bSameRule && rInfo.GetDepth() )
+ {
+ String aName( rInfo.GetNumRule()->GetName() );
+ if( rWrt.aNumRuleNames.Seek_Entry( &aName ) )
+ {
+ // The rule has been applied before
+ sal_Int16 eType = rInfo.GetNumRule()
+ ->Get( rInfo.GetDepth()-1 ).GetNumberingType();
+ if( SVX_NUM_CHAR_SPECIAL != eType && SVX_NUM_BITMAP != eType )
+ {
+ // If its a numbering rule, the current number should be
+ // exported as start value, but only if there are no nodes
+ // within the numbering that have a lower level
+ bStartValue = sal_True;
+ if( rInfo.GetDepth() > 1 )
+ {
+ ULONG nPos =
+ rWrt.pCurPam->GetPoint()->nNode.GetIndex() + 1;
+ do
+ {
+ const SwNode* pNd = rWrt.pDoc->GetNodes()[nPos];
+ if( pNd->IsTxtNode() )
+ {
+ const SwTxtNode *pTxtNd = pNd->GetTxtNode();
+ if( !pTxtNd->GetNumRule() )
+ {
+ // node isn't numbered => check completed
+ break;
+ }
+
+ ASSERT(! pTxtNd->IsOutline(),
+ "outline not expected");
+
+ if( pTxtNd->GetActualListLevel() + 1 <
+ rInfo.GetDepth() )
+ {
+ // node is numbered, but level is lower
+ // => check completed
+ bStartValue = sal_False;
+ break;
+ }
+ nPos++;
+ }
+ else if( pNd->IsTableNode() )
+ {
+ // skip table
+ nPos = pNd->EndOfSectionIndex() + 1;
+ }
+ else
+ {
+ // end node or sections start node -> check
+ // completed
+ break;
+ }
+ }
+ while( sal_True );
+ }
+ }
+ }
+ else
+ {
+ rWrt.aNumRuleNames.Insert( new String( aName ) );
+ }
+ }
+
+
+ DBG_ASSERT( rWrt.nLastParaToken == 0,
+ "<PRE> wurde nicht vor <OL> beendet." );
+ sal_uInt16 nPrevDepth =
+ (bSameRule && !rInfo.IsRestart()) ? rPrevInfo.GetDepth() : 0;
+
+ for( sal_uInt16 i=nPrevDepth; i<rInfo.GetDepth(); i++ )
+ {
+ rWrt.OutNewLine(); // <OL>/<UL> in eine neue Zeile
+
+ rWrt.aBulletGrfs[i].Erase();
+ ByteString sOut( '<' );
+ const SwNumFmt& rNumFmt = rInfo.GetNumRule()->Get( i );
+ sal_Int16 eType = rNumFmt.GetNumberingType();
+ if( SVX_NUM_CHAR_SPECIAL == eType )
+ {
+ // Aufzaehlungs-Liste: <OL>
+ sOut += OOO_STRING_SVTOOLS_HTML_unorderlist;
+
+ // den Typ ueber das Bullet-Zeichen bestimmen
+ const sal_Char *pStr = 0;
+ switch( rNumFmt.GetBulletChar() )
+ {
+ case HTML_BULLETCHAR_DISC:
+ pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_disc;
+ break;
+ case HTML_BULLETCHAR_CIRCLE:
+ pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_circle;
+ break;
+ case HTML_BULLETCHAR_SQUARE:
+ pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_square;
+ break;
+ }
+
+ if( pStr )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=') += pStr;
+ }
+ else if( SVX_NUM_BITMAP == eType )
+ {
+ // Aufzaehlungs-Liste: <OL>
+ sOut += OOO_STRING_SVTOOLS_HTML_unorderlist;
+ rWrt.Strm() << sOut.GetBuffer();
+ sOut.Erase();
+
+ OutHTML_BulletImage( rWrt,
+ 0,
+ rNumFmt.GetBrush(),
+ rWrt.aBulletGrfs[i],
+ rNumFmt.GetGraphicSize(),
+ rNumFmt.GetGraphicOrientation() );
+ }
+ else
+ {
+ // Numerierungs-Liste: <UL>
+ sOut += OOO_STRING_SVTOOLS_HTML_orderlist;
+
+ // den Typ ueber das Format bestimmen
+ sal_Char cType = 0;
+ switch( eType )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER: cType = 'A'; break;
+ case SVX_NUM_CHARS_LOWER_LETTER: cType = 'a'; break;
+ case SVX_NUM_ROMAN_UPPER: cType = 'I'; break;
+ case SVX_NUM_ROMAN_LOWER: cType = 'i'; break;
+ }
+ if( cType )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += '=') += cType;
+
+ sal_uInt16 nStartVal = rNumFmt.GetStart();
+ if( bStartValue && 1 == nStartVal && i == rInfo.GetDepth()-1 )
+ {
+ // --> OD 2005-11-02 #i51089 - TUNING#
+ if ( rWrt.pCurPam->GetNode()->GetTxtNode()->GetNum() )
+ {
+ nStartVal = static_cast< sal_uInt16 >( rWrt.pCurPam->GetNode()
+ ->GetTxtNode()->GetNumberVector()[i] );
+ }
+ else
+ {
+ ASSERT( false,
+ "<OutHTML_NumBulListStart(..) - text node has no number." );
+ }
+ }
+ if( nStartVal != 1 )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_start) += '=')
+ += ByteString::CreateFromInt32( nStartVal );
+ }
+ }
+
+ if( sOut.Len() )
+ rWrt.Strm() << sOut.GetBuffer();
+
+ if( rWrt.bCfgOutStyles )
+ OutCSS1_NumBulListStyleOpt( rWrt, *rInfo.GetNumRule(), (BYTE)i );
+
+ rWrt.Strm() << '>';
+
+ rWrt.IncIndentLevel(); // Inhalt von <OL> einruecken
+ }
+
+ return rWrt;
+}
+
+Writer& OutHTML_NumBulListEnd( SwHTMLWriter& rWrt,
+ const SwHTMLNumRuleInfo& rNextInfo )
+{
+ SwHTMLNumRuleInfo& rInfo = rWrt.GetNumInfo();
+ sal_Bool bSameRule = rNextInfo.GetNumRule() == rInfo.GetNumRule();
+ if( bSameRule && rNextInfo.GetDepth() >= rInfo.GetDepth() &&
+ !rNextInfo.IsRestart() )
+ {
+ return rWrt;
+ }
+
+ DBG_ASSERT( rWrt.nLastParaToken == 0,
+ "<PRE> wurde nicht vor </OL> beendet." );
+ sal_uInt16 nNextDepth =
+ (bSameRule && !rNextInfo.IsRestart()) ? rNextInfo.GetDepth() : 0;
+
+ // MIB 23.7.97: Die Schleife muss doch rueckwaerts durchlaufen
+ // werden, weil die Reihenfolge von </OL>/</UL> stimmen muss
+ for( sal_uInt16 i=rInfo.GetDepth(); i>nNextDepth; i-- )
+ {
+ rWrt.DecIndentLevel(); // Inhalt von <OL> einruecken
+ if( rWrt.bLFPossible )
+ rWrt.OutNewLine(); // </OL>/</UL> in eine neue Zeile
+
+ // es wird also eine Liste angefangen oder beendet:
+ sal_Int16 eType = rInfo.GetNumRule()->Get( i-1 ).GetNumberingType();
+ const sal_Char *pStr;
+ if( SVX_NUM_CHAR_SPECIAL == eType || SVX_NUM_BITMAP == eType)
+ pStr = OOO_STRING_SVTOOLS_HTML_unorderlist;
+ else
+ pStr = OOO_STRING_SVTOOLS_HTML_orderlist;
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, sal_False );
+ rWrt.bLFPossible = sal_True;
+ }
+
+ return rWrt;
+}
diff --git a/sw/source/filter/html/htmlnum.hxx b/sw/source/filter/html/htmlnum.hxx
new file mode 100644
index 000000000000..7f7f02bc1015
--- /dev/null
+++ b/sw/source/filter/html/htmlnum.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _HTMLNUM_HXX
+#define _HTMLNUM_HXX
+
+#include <swtypes.hxx>
+#include <string.h>
+
+#define HTML_NUMBUL_MARGINLEFT (MM50*2 + MM50/2)
+#define HTML_NUMBUL_INDENT (-MM50)
+
+class SwTxtNode;
+class SwNumRule;
+
+class SwHTMLNumRuleInfo
+{
+ sal_uInt16 aNumStarts[MAXLEVEL];
+ SwNumRule * pNumRule; // Aktuelle Numerierung
+ sal_uInt16 nDeep; // aktuelle Num-Tiefe (1, 2, 3, ...)
+ sal_Bool bRestart : 1; // Export: Numerierung neu starten
+ sal_Bool bNumbered : 1; // Export: Absatz ist numeriert
+
+public:
+
+ inline void Set( const SwHTMLNumRuleInfo& rInf );
+ void Set( const SwTxtNode& rTxtNd );
+
+ SwHTMLNumRuleInfo() :
+ pNumRule( 0 ), nDeep( 0 ),
+ bRestart( sal_False ), bNumbered( sal_False )
+ {
+ memset( &aNumStarts, 0xff, sizeof( aNumStarts ) );
+ }
+
+ SwHTMLNumRuleInfo( const SwHTMLNumRuleInfo& rInf ) :
+ pNumRule( rInf.pNumRule ), nDeep( rInf.nDeep ),
+ bRestart( rInf.bRestart ), bNumbered( rInf.bNumbered )
+ {
+ memcpy( &aNumStarts, &rInf.aNumStarts, sizeof( aNumStarts ) );
+ }
+
+ SwHTMLNumRuleInfo( const SwTxtNode& rTxtNd ) { Set( rTxtNd ); }
+ inline SwHTMLNumRuleInfo& operator=( const SwHTMLNumRuleInfo& rInf );
+
+ inline void Clear();
+
+ void SetNumRule( const SwNumRule *pRule ) { pNumRule = (SwNumRule *)pRule; }
+ SwNumRule *GetNumRule() { return pNumRule; }
+ const SwNumRule *GetNumRule() const { return pNumRule; }
+
+ void SetDepth( sal_uInt16 nDepth ) { nDeep = nDepth; }
+ sal_uInt16 GetDepth() const { return nDeep; }
+ sal_uInt16 IncDepth() { return ++nDeep; }
+ sal_uInt16 DecDepth() { return nDeep==0 ? 0 : --nDeep; }
+ inline sal_uInt8 GetLevel() const;
+
+ void SetRestart( sal_Bool bSet ) { bRestart = bSet; }
+ sal_Bool IsRestart() const { return bRestart; }
+
+ void SetNumbered( sal_Bool bSet ) { bNumbered = bSet; }
+ sal_Bool IsNumbered() const { return bNumbered; }
+
+ inline void SetNodeStartValue( sal_uInt8 nLvl, sal_uInt16 nVal=USHRT_MAX );
+ sal_uInt16 GetNodeStartValue( sal_uInt8 nLvl ) const { return aNumStarts[nLvl]; }
+};
+
+inline SwHTMLNumRuleInfo& SwHTMLNumRuleInfo::operator=(
+ const SwHTMLNumRuleInfo& rInf )
+{
+ Set( rInf );
+ return *this;
+}
+
+inline void SwHTMLNumRuleInfo::Set( const SwHTMLNumRuleInfo& rInf )
+{
+ pNumRule = rInf.pNumRule;
+ nDeep = rInf.nDeep;
+ bRestart = rInf.bRestart;
+ bNumbered = rInf.bNumbered;
+ memcpy( &aNumStarts, &rInf.aNumStarts, sizeof( aNumStarts ) );
+}
+
+inline void SwHTMLNumRuleInfo::Clear()
+{
+ pNumRule = 0;
+ nDeep = 0;
+ bRestart = bNumbered = sal_False;
+ memset( &aNumStarts, 0xff, sizeof( aNumStarts ) );
+}
+
+inline sal_uInt8 SwHTMLNumRuleInfo::GetLevel() const
+{
+ return
+ (sal_uInt8)( pNumRule!=0 && nDeep != 0
+ ? ( nDeep<=MAXLEVEL ? nDeep-1 : MAXLEVEL - 1 )
+ : 0 );
+}
+
+inline void SwHTMLNumRuleInfo::SetNodeStartValue( sal_uInt8 nLvl, sal_uInt16 nVal )
+{
+ aNumStarts[nLvl] = nVal;
+}
+
+
+#endif
+
+
diff --git a/sw/source/filter/html/htmlplug.cxx b/sw/source/filter/html/htmlplug.cxx
new file mode 100644
index 000000000000..a154592959dc
--- /dev/null
+++ b/sw/source/filter/html/htmlplug.cxx
@@ -0,0 +1,1401 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include "hintids.hxx"
+#include <svl/urihelper.hxx>
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/frmhtml.hxx>
+#include <sfx2/frmhtmlw.hxx>
+#include <vcl/wrkwin.hxx>
+#include <sot/storage.hxx>
+#include <svx/xoutbmp.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/htmltokn.h>
+#include <SwAppletImpl.hxx>
+#include <fmtornt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtanchr.hxx>
+#include <fmtcntnt.hxx>
+#include <frmfmt.hxx>
+
+#include <svl/ownlist.hxx>
+#include "pam.hxx"
+#include "doc.hxx"
+#include "ndtxt.hxx"
+#include "swerror.h"
+#include "ndole.hxx"
+#include "swtable.hxx"
+#include "swhtml.hxx"
+#include "wrthtml.hxx"
+#include "htmlfly.hxx"
+#include "swcss1.hxx"
+#include <com/sun/star/embed/XClassifiedObject.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <comphelper/embeddedobjectcontainer.hxx>
+#include <sot/clsids.hxx>
+
+using namespace com::sun::star;
+
+#define HTML_DFLT_EMBED_WIDTH ((MM50*5)/2)
+#define HTML_DFLT_EMBED_HEIGHT ((MM50*5)/2)
+
+#define HTML_DFLT_APPLET_WIDTH ((MM50*5)/2)
+#define HTML_DFLT_APPLET_HEIGHT ((MM50*5)/2)
+
+namespace {
+
+static char const sHTML_O_Hidden_False[] = "FALSE";
+
+}
+
+const ULONG HTML_FRMOPTS_EMBED_ALL =
+ HTML_FRMOPT_ALT |
+ HTML_FRMOPT_SIZE |
+ HTML_FRMOPT_NAME;
+const ULONG HTML_FRMOPTS_EMBED_CNTNR =
+ HTML_FRMOPTS_EMBED_ALL |
+ HTML_FRMOPT_ABSSIZE;
+const ULONG HTML_FRMOPTS_EMBED =
+ HTML_FRMOPTS_EMBED_ALL |
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SPACE |
+ HTML_FRMOPT_BRCLEAR |
+ HTML_FRMOPT_NAME;
+const ULONG HTML_FRMOPTS_HIDDEN_EMBED =
+ HTML_FRMOPT_ALT |
+ HTML_FRMOPT_NAME;
+
+const ULONG HTML_FRMOPTS_APPLET_ALL =
+ HTML_FRMOPT_ALT |
+ HTML_FRMOPT_SIZE;
+const ULONG HTML_FRMOPTS_APPLET_CNTNR =
+ HTML_FRMOPTS_APPLET_ALL |
+ HTML_FRMOPT_ABSSIZE;
+const ULONG HTML_FRMOPTS_APPLET =
+ HTML_FRMOPTS_APPLET_ALL |
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SPACE |
+ HTML_FRMOPT_BRCLEAR;
+
+const ULONG HTML_FRMOPTS_IFRAME_ALL =
+ HTML_FRMOPT_ALT |
+ HTML_FRMOPT_SIZE;
+const ULONG HTML_FRMOPTS_IFRAME_CNTNR =
+ HTML_FRMOPTS_IFRAME_ALL |
+ HTML_FRMOPT_ABSSIZE;
+const ULONG HTML_FRMOPTS_IFRAME =
+ HTML_FRMOPTS_IFRAME_ALL |
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SPACE |
+ HTML_FRMOPT_BORDER |
+ HTML_FRMOPT_BRCLEAR;
+
+const ULONG HTML_FRMOPTS_OLE_CSS1 =
+ HTML_FRMOPT_S_ALIGN |
+ HTML_FRMOPT_S_SPACE;
+
+/* */
+
+void SwHTMLParser::SetFixSize( const Size& rPixSize,
+ const Size& rTwipDfltSize,
+ BOOL bPrcWidth, BOOL bPrcHeight,
+ SfxItemSet& /*rCSS1ItemSet*/,
+ SvxCSS1PropertyInfo& rCSS1PropInfo,
+ SfxItemSet& rFlyItemSet )
+{
+ // absolulte Groessenangaben in Twip umrechnen
+ BYTE nPrcWidth = 0, nPrcHeight = 0;
+ Size aTwipSz( bPrcWidth || USHRT_MAX==rPixSize.Width() ? 0 : rPixSize.Width(),
+ bPrcHeight || USHRT_MAX==rPixSize.Height() ? 0 : rPixSize.Height() );
+ if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
+ {
+ aTwipSz =
+ Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
+ MapMode(MAP_TWIP) );
+ }
+
+ // die Breite bearbeiten
+ if( SVX_CSS1_LTYPE_PERCENTAGE == rCSS1PropInfo.eWidthType )
+ {
+ nPrcWidth = (BYTE)rCSS1PropInfo.nWidth;
+ aTwipSz.Width() = rTwipDfltSize.Width();
+ }
+ else if( SVX_CSS1_LTYPE_TWIP== rCSS1PropInfo.eWidthType )
+ {
+ aTwipSz.Width() = rCSS1PropInfo.nWidth;
+ }
+ else if( bPrcWidth && rPixSize.Width() )
+ {
+ nPrcWidth = (BYTE)rPixSize.Width();
+ if( nPrcWidth > 100 )
+ nPrcWidth = 100;
+
+ aTwipSz.Width() = rTwipDfltSize.Width();
+ }
+ else if( USHRT_MAX==rPixSize.Width() )
+ {
+ aTwipSz.Width() = rTwipDfltSize.Width();
+ }
+ if( aTwipSz.Width() < MINFLY )
+ {
+ aTwipSz.Width() = MINFLY;
+ }
+
+ // Hoehe bearbeiten
+ if( SVX_CSS1_LTYPE_PERCENTAGE == rCSS1PropInfo.eHeightType )
+ {
+ nPrcHeight = (BYTE)rCSS1PropInfo.nHeight;
+ aTwipSz.Height() = rTwipDfltSize.Height();
+ }
+ else if( SVX_CSS1_LTYPE_TWIP== rCSS1PropInfo.eHeightType )
+ {
+ aTwipSz.Height() = rCSS1PropInfo.nHeight;
+ }
+ else if( bPrcHeight && rPixSize.Height() )
+ {
+ nPrcHeight = (BYTE)rPixSize.Height();
+ if( nPrcHeight > 100 )
+ nPrcHeight = 100;
+
+ aTwipSz.Height() = rTwipDfltSize.Height();
+ }
+ else if( USHRT_MAX==rPixSize.Height() )
+ {
+ aTwipSz.Height() = rTwipDfltSize.Height();
+ }
+ if( aTwipSz.Height() < MINFLY )
+ {
+ aTwipSz.Height() = MINFLY;
+ }
+
+ // Size setzen
+ SwFmtFrmSize aFrmSize( ATT_FIX_SIZE, aTwipSz.Width(), aTwipSz.Height() );
+ aFrmSize.SetWidthPercent( nPrcWidth );
+ aFrmSize.SetHeightPercent( nPrcHeight );
+ rFlyItemSet.Put( aFrmSize );
+}
+
+void SwHTMLParser::SetSpace( const Size& rPixSpace,
+ SfxItemSet& rCSS1ItemSet,
+ SvxCSS1PropertyInfo& rCSS1PropInfo,
+ SfxItemSet& rFlyItemSet )
+{
+ sal_Int32 nLeftSpace = 0, nRightSpace = 0;
+ sal_uInt16 nUpperSpace = 0, nLowerSpace = 0;
+ if( (rPixSpace.Width() || rPixSpace.Height()) && Application::GetDefaultDevice() )
+ {
+ Size aTwipSpc( rPixSpace.Width(), rPixSpace.Height() );
+ aTwipSpc =
+ Application::GetDefaultDevice()->PixelToLogic( aTwipSpc,
+ MapMode(MAP_TWIP) );
+ nLeftSpace = nRightSpace = aTwipSpc.Width();
+ nUpperSpace = nLowerSpace = (USHORT)aTwipSpc.Height();
+ }
+
+ // linken/rechten Rand setzen
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_LR_SPACE, TRUE, &pItem ) )
+ {
+ // Ggf. den Erstzeilen-Einzug noch plaetten
+ const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
+ SvxLRSpaceItem aLRItem( *pLRItem );
+ aLRItem.SetTxtFirstLineOfst( 0 );
+ if( rCSS1PropInfo.bLeftMargin )
+ {
+ nLeftSpace = aLRItem.GetLeft();
+ rCSS1PropInfo.bLeftMargin = FALSE;
+ }
+ if( rCSS1PropInfo.bRightMargin )
+ {
+ nRightSpace = aLRItem.GetRight();
+ rCSS1PropInfo.bRightMargin = FALSE;
+ }
+ rCSS1ItemSet.ClearItem( RES_LR_SPACE );
+ }
+ if( nLeftSpace > 0 || nRightSpace > 0 )
+ {
+ SvxLRSpaceItem aLRItem( RES_LR_SPACE );
+ aLRItem.SetLeft( nLeftSpace > 0 ? nLeftSpace : 0 );
+ aLRItem.SetRight( nRightSpace > 0 ? nRightSpace : 0 );
+ rFlyItemSet.Put( aLRItem );
+ if( nLeftSpace )
+ {
+ const SwFmtHoriOrient& rHoriOri =
+ (const SwFmtHoriOrient&)rFlyItemSet.Get( RES_HORI_ORIENT );
+ if( text::HoriOrientation::NONE == rHoriOri.GetHoriOrient() )
+ {
+ SwFmtHoriOrient aHoriOri( rHoriOri );
+ aHoriOri.SetPos( aHoriOri.GetPos() + nLeftSpace );
+ rFlyItemSet.Put( aHoriOri );
+ }
+ }
+ }
+
+ // oberen/unteren Rand setzen
+ if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_UL_SPACE, TRUE, &pItem ) )
+ {
+ // Ggf. den Erstzeilen-Einzug noch plaetten
+ const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
+ if( rCSS1PropInfo.bTopMargin )
+ {
+ nUpperSpace = pULItem->GetUpper();
+ rCSS1PropInfo.bTopMargin = FALSE;
+ }
+ if( rCSS1PropInfo.bBottomMargin )
+ {
+ nLowerSpace = pULItem->GetLower();
+ rCSS1PropInfo.bBottomMargin = FALSE;
+ }
+ rCSS1ItemSet.ClearItem( RES_UL_SPACE );
+ }
+ if( nUpperSpace || nLowerSpace )
+ {
+ SvxULSpaceItem aULItem( RES_UL_SPACE );
+ aULItem.SetUpper( nUpperSpace );
+ aULItem.SetLower( nLowerSpace );
+ rFlyItemSet.Put( aULItem );
+ if( nUpperSpace )
+ {
+ const SwFmtVertOrient& rVertOri =
+ (const SwFmtVertOrient&)rFlyItemSet.Get( RES_VERT_ORIENT );
+ if( text::VertOrientation::NONE == rVertOri.GetVertOrient() )
+ {
+ SwFmtVertOrient aVertOri( rVertOri );
+ aVertOri.SetPos( aVertOri.GetPos() + nUpperSpace );
+ rFlyItemSet.Put( aVertOri );
+ }
+ }
+ }
+}
+
+/* */
+
+void SwHTMLParser::InsertEmbed()
+{
+ String aURL, aType, aName, aAlt, aId, aStyle, aClass;
+ Size aSize( USHRT_MAX, USHRT_MAX );
+ Size aSpace( USHRT_MAX, USHRT_MAX );
+ BOOL bPrcWidth = FALSE, bPrcHeight = FALSE, bHidden = FALSE;
+ sal_Int16 eVertOri = text::VertOrientation::NONE;
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+ SvCommandList aCmdLst;
+ const HTMLOptions *pHTMLOptions = GetOptions();
+
+ // Die Optionen werden vorwaerts gelesen, weil die Plugins sie in
+ // dieser Reihenfolge erwarten. Trotzdem darf immer nur der erste
+ // Wert einer Option beruecksichtigt werden.
+ USHORT nArrLen = pHTMLOptions->Count();
+ for( USHORT i=0; i<nArrLen; i++ )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ break;
+ case HTML_O_SRC:
+ if( !aURL.Len() )
+ aURL = pOption->GetString();
+ break;
+ case HTML_O_ALT:
+ aAlt = pOption->GetString();
+ break;
+ case HTML_O_TYPE:
+ if( !aType.Len() )
+ aType = pOption->GetString();
+ break;
+ case HTML_O_ALIGN:
+ if( eVertOri==text::VertOrientation::NONE && eHoriOri==text::HoriOrientation::NONE )
+ {
+ eVertOri = pOption->GetEnum( aHTMLImgVAlignTable, eVertOri );
+ eHoriOri = pOption->GetEnum( aHTMLImgHAlignTable, eHoriOri );
+ }
+ break;
+ case HTML_O_WIDTH:
+ if( USHRT_MAX==aSize.Width() )
+ {
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Width() = (long)pOption->GetNumber();
+ }
+ break;
+ case HTML_O_HEIGHT:
+ if( USHRT_MAX==aSize.Height() )
+ {
+ bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Height() = (long)pOption->GetNumber();
+ }
+ break;
+ case HTML_O_HSPACE:
+ if( USHRT_MAX==aSpace.Width() )
+ aSpace.Width() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_VSPACE:
+ if( USHRT_MAX==aSpace.Height() )
+ aSpace.Height() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_UNKNOWN:
+ if( pOption->GetTokenString().EqualsIgnoreCaseAscii( OOO_STRING_SW_HTML_O_Hidden ) )
+ bHidden =
+ !pOption->GetString().EqualsIgnoreCaseAscii( sHTML_O_Hidden_False );
+ break;
+ }
+
+ // Es werden alle Parameter an das Plugin weitergereicht
+ aCmdLst.Append( pOption->GetTokenString(), pOption->GetString() );
+ }
+
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
+
+ // Die Default-Werte umsetzen (ausser Hoehe/Breite, das macht schon
+ // SetFrmSize() fuer uns)
+ if( eVertOri==text::VertOrientation::NONE && eHoriOri==text::HoriOrientation::NONE )
+ eVertOri = text::VertOrientation::TOP;
+ if( USHRT_MAX==aSpace.Width() )
+ aSpace.Width() = 0;
+ if( USHRT_MAX==aSpace.Height() )
+ aSpace.Height() = 0;
+ if( bHidden )
+ {
+ // Size (0,0) wird in SetFrmSize auf (MINFLY, MINFLY) umgebogen
+ aSize.Width() = 0; aSize.Height() = 0;
+ aSpace.Width() = 0; aSpace.Height() = 0;
+ bPrcWidth = bPrcHeight = FALSE;
+ }
+
+ // die URL aufbereiten
+ INetURLObject aURLObj;
+ bool bHasURL = aURL.Len() &&
+ aURLObj.SetURL(
+ URIHelper::SmartRel2Abs(
+ INetURLObject(sBaseURL), aURL,
+ URIHelper::GetMaybeFileHdl()) );
+
+ // #109761# do not insert plugin if it has neither URL nor type
+ bool bHasType = aType.Len() != 0;
+ if( !bHasURL && !bHasType )
+ return;
+
+ // das Plugin anlegen
+ comphelper::EmbeddedObjectContainer aCnt;
+ ::rtl::OUString aObjName;
+ uno::Reference < embed::XEmbeddedObject > xObj = aCnt.CreateEmbeddedObject( SvGlobalName( SO3_PLUGIN_CLASSID ).GetByteSequence(), aObjName );
+ if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
+ {
+ uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ if( bHasURL )
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("PluginURL"),
+ uno::makeAny( ::rtl::OUString( aURL ) ) );
+ if( bHasType )
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("PluginMimeType"),
+ uno::makeAny( ::rtl::OUString( aType ) ) );
+
+ uno::Sequence < beans::PropertyValue > aProps;
+ aCmdLst.FillSequence( aProps );
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("PluginCommands"), uno::makeAny( aProps ) );
+
+ // TODO/LATER: EnableSetModified?!
+ //pPlugin->EnableSetModified( TRUE );
+ }
+ }
+
+ SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs( aFrmSet );
+
+ // den Anker setzen
+ if( !bHidden )
+ {
+ SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, aFrmSet );
+ }
+ else
+ {
+ SwFmtAnchor aAnchor( FLY_AT_PARA );
+ aAnchor.SetAnchor( pPam->GetPoint() );
+ aFrmSet.Put( aAnchor );
+ aFrmSet.Put( SwFmtHoriOrient( 0, text::HoriOrientation::LEFT, text::RelOrientation::FRAME) );
+ aFrmSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
+ aFrmSet.Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::PRINT_AREA ) );
+ }
+
+ // und noch die Groesse des Rahmens
+ Size aDfltSz( HTML_DFLT_EMBED_WIDTH, HTML_DFLT_EMBED_HEIGHT );
+ SetFixSize( aSize, aDfltSz, bPrcWidth, bPrcHeight, aItemSet, aPropInfo,
+ aFrmSet );
+ SetSpace( aSpace, aItemSet, aPropInfo, aFrmSet );
+
+ // und in das Dok einfuegen
+ SwFrmFmt* pFlyFmt =
+ pDoc->Insert( *pPam, ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), &aFrmSet, NULL, NULL );
+
+ // Namen am FrmFmt setzen
+ if( aName.Len() )
+ pFlyFmt->SetName( aName );
+
+ // den alternativen Text setzen
+ SwNoTxtNode *pNoTxtNd =
+ pDoc->GetNodes()[ pFlyFmt->GetCntnt().GetCntntIdx()
+ ->GetIndex()+1 ]->GetNoTxtNode();
+ pNoTxtNd->SetTitle( aAlt );
+
+ // Ggf Frames anlegen und auto-geb. Rahmen registrieren
+ if( !bHidden )
+ {
+ // HIDDEN-Plugins sollen absatzgebunden bleiben. Da RegisterFlyFrm
+ // absatzgebundene Rahmen mit DUrchlauf in am Zeichen gebundene
+ // Rahmen umwandelt, muessen die Frames hier von Hand angelegt werden.
+ RegisterFlyFrm( pFlyFmt );
+ }
+}
+
+/* */
+
+#ifdef SOLAR_JAVA
+void SwHTMLParser::NewObject()
+{
+ String aClassID, aName, aStandBy, aId, aStyle, aClass;
+ Size aSize( USHRT_MAX, USHRT_MAX );
+ Size aSpace( 0, 0 );
+ sal_Int16 eVertOri = text::VertOrientation::TOP;
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+
+ sal_Bool bPrcWidth = sal_False, bPrcHeight = sal_False,
+ bDeclare = sal_False;
+ // Eine neue Command-List anlegen
+ if( pAppletImpl )
+ delete pAppletImpl;
+ pAppletImpl = new SwApplet_Impl( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_DECLARE:
+ bDeclare = sal_True;
+ break;
+ case HTML_O_CLASSID:
+ aClassID = pOption->GetString();
+ break;
+ case HTML_O_CODEBASE:
+ break;
+ case HTML_O_DATA:
+ break;
+ case HTML_O_TYPE:
+ break;
+ case HTML_O_CODETYPE:
+ break;
+ case HTML_O_ARCHIVE:
+ case HTML_O_UNKNOWN:
+ break;
+ case HTML_O_STANDBY:
+ aStandBy = pOption->GetString();
+ break;
+ case HTML_O_WIDTH:
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Width() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_HEIGHT:
+ bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Height() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_ALIGN:
+ eVertOri = pOption->GetEnum( aHTMLImgVAlignTable, eVertOri );
+ eHoriOri = pOption->GetEnum( aHTMLImgHAlignTable, eHoriOri );
+ break;
+ case HTML_O_USEMAP:
+ break;
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ break;
+ case HTML_O_HSPACE:
+ aSpace.Width() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_VSPACE:
+ aSpace.Height() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_BORDER:
+ break;
+
+ case HTML_O_SDONCLICK:
+ case HTML_O_ONCLICK:
+ case HTML_O_SDONMOUSEOVER:
+ case HTML_O_ONMOUSEOVER:
+ case HTML_O_SDONMOUSEOUT:
+ case HTML_O_ONMOUSEOUT:
+ break;
+ }
+ // Es werden alle Parameter auch an das Applet weitergereicht
+ pAppletImpl->AppendParam( pOption->GetTokenString(),
+ pOption->GetString() );
+
+ }
+
+ // Objects that are declared only are not evaluated. Moreover, only
+ // Java applets are supported.
+ sal_Bool bIsApplet = sal_False;;
+
+ if( !bDeclare && aClassID.Len() == 42 &&
+ aClassID.EqualsAscii( "clsid:", 0, 6 ) )
+ {
+ aClassID.Erase( 0, 6 );
+ SvGlobalName aCID;
+ if( aCID.MakeId( aClassID ) )
+ {
+ SvGlobalName aJavaCID( 0x8AD9C840UL, 0x044EU, 0x11D1U, 0xB3U, 0xE9U,
+ 0x00U, 0x80U, 0x5FU, 0x49U, 0x9DU, 0x93U );
+
+ bIsApplet = aJavaCID == aCID;
+ }
+ }
+
+ if( !bIsApplet )
+ {
+ delete pAppletImpl;
+ pAppletImpl = 0;
+ return;
+ }
+
+ pAppletImpl->SetAltText( aStandBy );
+
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
+
+ SfxItemSet& rFrmSet = pAppletImpl->GetItemSet();
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs( rFrmSet );
+
+ // den Anker und die Ausrichtung setzen
+ SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, rFrmSet );
+
+ // und noch die Groesse des Rahmens
+ Size aDfltSz( HTML_DFLT_APPLET_WIDTH, HTML_DFLT_APPLET_HEIGHT );
+ SetFixSize( aSize, aDfltSz, bPrcWidth, bPrcHeight, aItemSet, aPropInfo,
+ rFrmSet );
+ SetSpace( aSpace, aItemSet, aPropInfo, rFrmSet );
+}
+#endif
+
+void SwHTMLParser::EndObject()
+{
+#ifdef SOLAR_JAVA
+ if( !pAppletImpl )
+ return;
+ if( pAppletImpl->CreateApplet( sBaseURL ) )
+ {
+ pAppletImpl->FinishApplet();
+
+ // und in das Dok einfuegen
+ SwFrmFmt* pFlyFmt =
+ pDoc->Insert( *pPam,
+ ::svt::EmbeddedObjectRef( pAppletImpl->GetApplet(), embed::Aspects::MSOLE_CONTENT ),
+ &pAppletImpl->GetItemSet(),
+ NULL,
+ NULL );
+
+ // den alternativen Namen setzen
+ SwNoTxtNode *pNoTxtNd =
+ pDoc->GetNodes()[ pFlyFmt->GetCntnt().GetCntntIdx()
+ ->GetIndex()+1 ]->GetNoTxtNode();
+ pNoTxtNd->SetTitle( pAppletImpl->GetAltText() );
+
+ // Ggf Frames anlegen und auto-geb. Rahmen registrieren
+ RegisterFlyFrm( pFlyFmt );
+
+ delete pAppletImpl;
+ pAppletImpl = 0;
+ }
+#endif
+}
+
+#ifdef SOLAR_JAVA
+void SwHTMLParser::InsertApplet()
+{
+ String aCodeBase, aCode, aName, aAlt, aId, aStyle, aClass;
+ Size aSize( USHRT_MAX, USHRT_MAX );
+ Size aSpace( 0, 0 );
+ BOOL bPrcWidth = FALSE, bPrcHeight = FALSE, bMayScript = FALSE;
+ sal_Int16 eVertOri = text::VertOrientation::TOP;
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+
+ // Eine neue Command-List anlegen
+ if( pAppletImpl )
+ delete pAppletImpl;
+ pAppletImpl = new SwApplet_Impl( pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_CODEBASE:
+ aCodeBase = pOption->GetString();
+ break;
+ case HTML_O_CODE:
+ aCode = pOption->GetString();
+ break;
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ break;
+ case HTML_O_ALT:
+ aAlt = pOption->GetString();
+ break;
+ case HTML_O_ALIGN:
+ eVertOri = pOption->GetEnum( aHTMLImgVAlignTable, eVertOri );
+ eHoriOri = pOption->GetEnum( aHTMLImgHAlignTable, eHoriOri );
+ break;
+ case HTML_O_WIDTH:
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Width() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_HEIGHT:
+ bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Height() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_HSPACE:
+ aSpace.Width() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_VSPACE:
+ aSpace.Height() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_MAYSCRIPT:
+ bMayScript = TRUE;
+ break;
+ }
+
+ // Es werden alle Parameter auch an das Applet weitergereicht
+ pAppletImpl->AppendParam( pOption->GetTokenString(),
+ pOption->GetString() );
+ }
+
+ if( !aCode.Len() )
+ {
+ delete pAppletImpl;
+ pAppletImpl = 0;
+ return;
+ }
+
+ if ( aCodeBase.Len() )
+ aCodeBase = INetURLObject::GetAbsURL( sBaseURL, aCodeBase );
+ pAppletImpl->CreateApplet( aCode, aName, bMayScript, aCodeBase, sBaseURL );//, aAlt );
+ pAppletImpl->SetAltText( aAlt );
+
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
+
+ SfxItemSet& rFrmSet = pAppletImpl->GetItemSet();
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs( rFrmSet );
+
+ // den Anker und die Ausrichtung setzen
+ SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, rFrmSet );
+
+ // und noch die Groesse des Rahmens
+ Size aDfltSz( HTML_DFLT_APPLET_WIDTH, HTML_DFLT_APPLET_HEIGHT );
+ SetFixSize( aSize, aDfltSz, bPrcWidth, bPrcHeight, aItemSet, aPropInfo,
+ rFrmSet );
+ SetSpace( aSpace, aItemSet, aPropInfo, rFrmSet );
+}
+#endif
+
+void SwHTMLParser::EndApplet()
+{
+#ifdef SOLAR_JAVA
+ if( !pAppletImpl )
+ return;
+
+ pAppletImpl->FinishApplet();
+
+ // und in das Dok einfuegen
+ SwFrmFmt* pFlyFmt =
+ pDoc->Insert( *pPam,
+ ::svt::EmbeddedObjectRef( pAppletImpl->GetApplet(), embed::Aspects::MSOLE_CONTENT ),
+ &pAppletImpl->GetItemSet(),
+ NULL,
+ NULL );
+
+ // den alternativen Namen setzen
+ SwNoTxtNode *pNoTxtNd =
+ pDoc->GetNodes()[ pFlyFmt->GetCntnt().GetCntntIdx()
+ ->GetIndex()+1 ]->GetNoTxtNode();
+ pNoTxtNd->SetTitle( pAppletImpl->GetAltText() );
+
+ // Ggf Frames anlegen und auto-geb. Rahmen registrieren
+ RegisterFlyFrm( pFlyFmt );
+
+ delete pAppletImpl;
+ pAppletImpl = 0;
+#endif
+}
+
+void SwHTMLParser::InsertParam()
+{
+#ifdef SOLAR_JAVA
+ if( !pAppletImpl )
+ return;
+
+ String aName, aValue;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ break;
+ case HTML_O_VALUE:
+ aValue = pOption->GetString();
+ break;
+ }
+ }
+
+ if( !aName.Len() )
+ return;
+
+ pAppletImpl->AppendParam( aName, aValue );
+#endif
+}
+
+
+/* */
+
+void SwHTMLParser::InsertFloatingFrame()
+{
+ String aAlt, aId, aStyle, aClass;
+ Size aSize( USHRT_MAX, USHRT_MAX );
+ Size aSpace( 0, 0 );
+ BOOL bPrcWidth = FALSE, bPrcHeight = FALSE;
+ sal_Int16 eVertOri = text::VertOrientation::TOP;
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+
+ // Erstmal die Optionen f?r das Writer-Frame-Format holen
+ USHORT nArrLen = pHTMLOptions->Count();
+ for ( USHORT i=0; i<nArrLen; i++ )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_ALT:
+ aAlt = pOption->GetString();
+ break;
+ case HTML_O_ALIGN:
+ eVertOri = pOption->GetEnum( aHTMLImgVAlignTable, eVertOri );
+ eHoriOri = pOption->GetEnum( aHTMLImgHAlignTable, eHoriOri );
+ break;
+ case HTML_O_WIDTH:
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Width() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_HEIGHT:
+ bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Height() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_HSPACE:
+ aSpace.Width() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_VSPACE:
+ aSpace.Height() = (long)pOption->GetNumber();
+ break;
+ }
+ }
+
+ // und jetzt die fuer den SfxFrame
+ SfxFrameDescriptor aFrameDesc;
+
+ SfxFrameHTMLParser::ParseFrameOptions( &aFrameDesc, pHTMLOptions, sBaseURL );
+
+ // den Floating-Frame anlegen
+ comphelper::EmbeddedObjectContainer aCnt;
+ ::rtl::OUString aObjName;
+ uno::Reference < embed::XEmbeddedObject > xObj = aCnt.CreateEmbeddedObject( SvGlobalName( SO3_IFRAME_CLASSID ).GetByteSequence(), aObjName );
+
+ //pFrame->EnableSetModified( FALSE );
+ try
+ {
+ // TODO/MBA: testing
+ if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
+ {
+ uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ ::rtl::OUString aName = aFrameDesc.GetName();
+ ScrollingMode eScroll = aFrameDesc.GetScrollingMode();
+ sal_Bool bHasBorder = aFrameDesc.HasFrameBorder();
+ Size aMargin = aFrameDesc.GetMargin();
+
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("FrameURL"), uno::makeAny( ::rtl::OUString( aFrameDesc.GetURL().GetMainURL( INetURLObject::NO_DECODE ) ) ) );
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("FrameName"), uno::makeAny( aName ) );
+
+ if ( eScroll == ScrollingAuto )
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("FrameIsAutoScroll"),
+ uno::makeAny( sal_True ) );
+ else
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("FrameIsScrollingMode"),
+ uno::makeAny( (sal_Bool) ( eScroll == ScrollingYes) ) );
+
+ //if ( aFrmDescr.IsFrameBorderSet() )
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("FrameIsBorder"),
+ uno::makeAny( bHasBorder ) );
+ /*else
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("FrameIsAutoBorder"),
+ uno::makeAny( sal_True ) );*/
+
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("FrameMarginWidth"),
+ uno::makeAny( sal_Int32( aMargin.Width() ) ) );
+
+ xSet->setPropertyValue( ::rtl::OUString::createFromAscii("FrameMarginHeight"),
+ uno::makeAny( sal_Int32( aMargin.Height() ) ) );
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ //pFrame->EnableSetModified( TRUE );
+
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo );
+
+ // den Itemset holen
+ SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs( aFrmSet );
+
+ // den Anker und die Ausrichtung setzen
+ SetAnchorAndAdjustment( eVertOri, eHoriOri, aItemSet, aPropInfo, aFrmSet );
+
+ // und noch die Groesse des Rahmens
+ Size aDfltSz( HTML_DFLT_APPLET_WIDTH, HTML_DFLT_APPLET_HEIGHT );
+ SetFixSize( aSize, aDfltSz, bPrcWidth, bPrcHeight, aItemSet, aPropInfo,
+ aFrmSet );
+ SetSpace( aSpace, aItemSet, aPropInfo, aFrmSet );
+
+ // und in das Dok einfuegen
+ SwFrmFmt* pFlyFmt =
+ pDoc->Insert( *pPam, ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ), &aFrmSet, NULL, NULL );
+
+ // den alternativen Namen setzen
+ SwNoTxtNode *pNoTxtNd =
+ pDoc->GetNodes()[ pFlyFmt->GetCntnt().GetCntntIdx()
+ ->GetIndex()+1 ]->GetNoTxtNode();
+ pNoTxtNd->SetTitle( aAlt );
+
+ // Ggf Frames anlegen und auto-geb. Rahmen registrieren
+ RegisterFlyFrm( pFlyFmt );
+
+ bInFloatingFrame = TRUE;
+}
+
+/* */
+
+/*
+#define SWHTML_OPTTYPE_IGNORE 0
+#define SWHTML_OPTTYPE_TAG 1
+#define SWHTML_OPTTYPE_PARAM 2
+
+
+static USHORT GetOptionType( const String& rName, BOOL bApplet )
+{
+ USHORT nType = bApplet ? SWHTML_OPTTYPE_PARAM : SWHTML_OPTTYPE_TAG;
+
+ switch( rName.GetChar(0) )
+ {
+ case 'A':
+ case 'a':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_align ) ||
+ rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_alt ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ else if( bApplet &&
+ (rName.EqualsIgnoreCaseAscii( sHTML_O_archive ) ||
+ rName.EqualsIgnoreCaseAscii( sHTML_O_Archives )) )
+ nType = SWHTML_OPTTYPE_TAG;
+ break;
+ case 'C':
+ case 'c':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_class ) ||
+ (bApplet && (rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_code ) ||
+ rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_codebase ))) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'H':
+ case 'h':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_height ) ||
+ rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_hspace ) ||
+ (!bApplet && rName.EqualsIgnoreCaseAscii( OOO_STRING_SW_HTML_O_Hidden )) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'I':
+ case 'i':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_id ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'M':
+ case 'm':
+ if( bApplet && rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_mayscript ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'N':
+ case 'n':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_name ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'O':
+ case 'o':
+ if( bApplet && rName.EqualsIgnoreCaseAscii( sHTML_O_Object ) )
+ nType = SWHTML_OPTTYPE_TAG;
+ break;
+ case 'S':
+ case 's':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_style ) ||
+ (!bApplet && rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_src )) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'T':
+ case 't':
+ if( !bApplet && rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_type ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'V':
+ case 'v':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_vspace ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ case 'W':
+ case 'w':
+ if( rName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_O_width ) )
+ nType = SWHTML_OPTTYPE_IGNORE;
+ break;
+ }
+
+ return nType;
+}
+*/
+
+USHORT SwHTMLWriter::GuessOLENodeFrmType( const SwNode& rNode )
+{
+ SwOLEObj& rObj = ((SwOLENode*)rNode.GetOLENode())->GetOLEObj();
+
+ SwHTMLFrmType eType = HTML_FRMTYPE_OLE;
+
+ uno::Reference < embed::XClassifiedObject > xClass ( rObj.GetOleRef(), uno::UNO_QUERY );
+ SvGlobalName aClass( xClass->getClassID() );
+ if( aClass == SvGlobalName( SO3_PLUGIN_CLASSID ) )
+ {
+ eType = HTML_FRMTYPE_PLUGIN;
+ }
+ else if( aClass == SvGlobalName( SO3_IFRAME_CLASSID ) )
+ {
+ eType = HTML_FRMTYPE_IFRAME;
+ }
+#ifdef SOLAR_JAVA
+ else if( aClass == SvGlobalName( SO3_APPLET_CLASSID ) )
+ {
+ eType = HTML_FRMTYPE_APPLET;
+ }
+#endif
+
+ return static_cast< USHORT >(eType);
+}
+
+Writer& OutHTML_FrmFmtOLENode( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ BOOL bInCntnr )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
+ SwOLENode *pOLENd = rHTMLWrt.pDoc->GetNodes()[ nStt ]->GetOLENode();
+
+ ASSERT( pOLENd, "OLE-Node erwartet" );
+ if( !pOLENd )
+ return rWrt;
+
+ SwOLEObj &rObj = pOLENd->GetOLEObj();
+
+ uno::Reference < embed::XEmbeddedObject > xObj( rObj.GetOleRef() );
+ if ( !svt::EmbeddedObjectRef::TryRunningState( xObj ) )
+ return rWrt;
+
+ uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
+ BOOL bHiddenEmbed = FALSE;
+
+ if( !xSet.is() )
+ {
+ DBG_ERROR("Unknown Object" );
+ return rWrt;
+ }
+
+ ByteString aEndTags;
+ ULONG nFrmOpts;
+
+ // wenn meoglich vor dem "Objekt" einen Zeilen-Umbruch ausgeben
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine( TRUE );
+
+ if( rFrmFmt.GetName().Len() )
+ rHTMLWrt.OutImplicitMark( rFrmFmt.GetName(),
+ pMarkToOLE );
+ uno::Any aAny;
+ SvGlobalName aGlobName( xObj->getClassID() );
+ ByteString sOut('<');
+ if( aGlobName == SvGlobalName( SO3_PLUGIN_CLASSID ) )
+ {
+ // erstmal das Plug-spezifische
+ sOut += OOO_STRING_SVTOOLS_HTML_embed;
+
+ ::rtl::OUString aStr;
+ String aURL;
+ aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("PluginURL" ) );
+ if( (aAny >>= aStr) && aStr.getLength() )
+ {
+ aURL = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(),
+ aStr);
+ }
+
+ if( aURL.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_src) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aURL, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ ::rtl::OUString aType;
+ aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("PluginMimeType" ) );
+ if( (aAny >>= aType) && aType.getLength() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aType, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ if ((FLY_AT_PARA == rFrmFmt.GetAnchor().GetAnchorId()) &&
+ SURROUND_THROUGHT == rFrmFmt.GetSurround().GetSurround() )
+ {
+ // Das Plugin ist HIDDEN
+ (sOut += ' ') += OOO_STRING_SW_HTML_O_Hidden;
+ nFrmOpts = HTML_FRMOPTS_HIDDEN_EMBED;
+ bHiddenEmbed = TRUE;
+ }
+ else
+ {
+ nFrmOpts = bInCntnr ? HTML_FRMOPTS_EMBED_CNTNR
+ : HTML_FRMOPTS_EMBED;
+ }
+ }
+ else if( aGlobName == SvGlobalName( SO3_APPLET_CLASSID ) )
+ {
+ // oder das Applet-Spezifische
+
+ sOut += OOO_STRING_SVTOOLS_HTML_applet;
+
+ // CODEBASE
+ ::rtl::OUString aCd;
+ aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("AppletCodeBase" ) );
+ if( (aAny >>= aCd) && aCd.getLength() )
+ {
+ String sCodeBase( URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), aCd) );
+ if( sCodeBase.Len() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_codebase) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), sCodeBase, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+ }
+
+ // CODE
+ ::rtl::OUString aClass;
+ aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("AppletCode" ) );
+ aAny >>= aClass;
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_code) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aClass, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+
+ // NAME
+ ::rtl::OUString aAppletName;
+ aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("AppletName" ) );
+ aAny >>= aAppletName;
+ if( aAppletName.getLength() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), aAppletName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ sal_Bool bScript = sal_False;
+ aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("AppletIsScript" ) );
+ aAny >>= bScript;
+ if( bScript )
+ (sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_mayscript;
+
+ nFrmOpts = bInCntnr ? HTML_FRMOPTS_APPLET_CNTNR
+ : HTML_FRMOPTS_APPLET;
+ }
+ else
+ {
+ // oder das Flating-Frame spezifische
+
+ sOut += OOO_STRING_SVTOOLS_HTML_iframe;
+ rWrt.Strm() << sOut.GetBuffer();
+
+ SfxFrameHTMLWriter::Out_FrameDescriptor( rWrt.Strm(), rWrt.GetBaseURL(),
+ xSet,
+ rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ sOut.Erase();
+
+ nFrmOpts = bInCntnr ? HTML_FRMOPTS_IFRAME_CNTNR
+ : HTML_FRMOPTS_IFRAME;
+ }
+
+ rWrt.Strm() << sOut.GetBuffer();
+
+ // ALT, WIDTH, HEIGHT, HSPACE, VSPACE, ALIGN
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bHiddenEmbed )
+ nFrmOpts |= HTML_FRMOPTS_OLE_CSS1;
+ rHTMLWrt.OutFrmFmtOptions( rFrmFmt, pOLENd->GetTitle(),
+ aEndTags, nFrmOpts );
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_FLY ) && !bHiddenEmbed )
+ rHTMLWrt.OutCSS1_FrmFmtOptions( rFrmFmt, nFrmOpts );
+
+ if( aGlobName == SvGlobalName( SO3_APPLET_CLASSID ) )
+ {
+ // fuer Applets die Parameter als eigene Tags ausgeben
+ // und ein </APPLET> schreiben
+
+ uno::Sequence < beans::PropertyValue > aProps;
+ aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("AppletCommands" ) );
+ aAny >>= aProps;
+
+ SvCommandList aCommands;
+ aCommands.FillFromSequence( aProps );
+ SvULongs aParams;
+ ULONG i = aCommands.Count();
+ while( i > 0 )
+ {
+ const SvCommand& rCommand = aCommands[ --i ];
+ const String& rName = rCommand.GetCommand();
+ USHORT nType = SwApplet_Impl::GetOptionType( rName, TRUE );
+ if( SWHTML_OPTTYPE_TAG == nType )
+ {
+ const String& rValue = rCommand.GetArgument();
+ rWrt.Strm() << ' ';
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ rWrt.Strm() << "=\"";
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rValue, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << '\"';
+ }
+ else if( SWHTML_OPTTYPE_PARAM == nType )
+ {
+ aParams.Insert( i, aParams.Count() );
+ }
+ }
+
+ rHTMLWrt.Strm() << '>';
+
+ rHTMLWrt.IncIndentLevel(); // Inhalt von Applet einruecken
+
+ USHORT ii = aParams.Count();
+ while( ii > 0 )
+ {
+ const SvCommand& rCommand = aCommands[ aParams[--ii] ];
+ const String& rName = rCommand.GetCommand();
+ const String& rValue = rCommand.GetArgument();
+ rHTMLWrt.OutNewLine();
+ ((((sOut = '<') += OOO_STRING_SVTOOLS_HTML_param) += ' ') += OOO_STRING_SVTOOLS_HTML_O_name)
+ += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ ((sOut = "\" ") += OOO_STRING_SVTOOLS_HTML_O_value) += "=\"";
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rValue, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << "\">";
+ }
+
+ rHTMLWrt.DecIndentLevel(); // Inhalt von Applet einruecken
+ if( aCommands.Count() )
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_applet, FALSE );
+ }
+ else
+ if( aGlobName == SvGlobalName( SO3_PLUGIN_CLASSID ) )
+ {
+ // fuer Plugins die Paramater als Optionen schreiben
+
+ uno::Sequence < beans::PropertyValue > aProps;
+ aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("PluginCommands" ) );
+ aAny >>= aProps;
+
+ SvCommandList aCommands;
+ aCommands.FillFromSequence( aProps );
+ for( ULONG i=0; i<aCommands.Count(); i++ )
+ {
+ const SvCommand& rCommand = aCommands[ i ];
+ const String& rName = rCommand.GetCommand();
+
+ if( SwApplet_Impl::GetOptionType( rName, FALSE ) == SWHTML_OPTTYPE_TAG )
+ {
+ const String& rValue = rCommand.GetArgument();
+ rWrt.Strm() << ' ';
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ rWrt.Strm() << "=\"";
+ HTMLOutFuncs::Out_String( rWrt.Strm(), rValue, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters ) << '\"';
+ }
+ }
+ rHTMLWrt.Strm() << '>';
+ }
+ else
+ {
+ // und fuer Floating-Frames einfach noch ein </IFRAME>
+ // ausgeben
+
+ rHTMLWrt.Strm() << '>';
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_iframe, FALSE );
+ }
+
+ if( aEndTags.Len() )
+ rWrt.Strm() << aEndTags.GetBuffer();
+
+ return rWrt;
+}
+
+Writer& OutHTML_FrmFmtOLENodeGrf( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ BOOL bInCntnr )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ const SwFmtCntnt& rFlyCntnt = rFrmFmt.GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
+ SwOLENode *pOLENd = rHTMLWrt.pDoc->GetNodes()[ nStt ]->GetOLENode();
+
+ ASSERT( pOLENd, "OLE-Node erwartet" );
+ if( !pOLENd )
+ return rWrt;
+
+ // Inhalt des Nodes als Grafik speichern
+ //uno::Reference < embed::XEmbeddedObject > xObj = pOLENd->GetOLEObj().GetOleRef();
+ //GDIMetaFile aPic;
+ //if( xObj.is() && xRef->GetGDIMetaFile( aPic ).GetActionCount() )
+ {
+ //Graphic aGrf( aPic );
+ Graphic aGrf( *pOLENd->GetGraphic() );
+ String aGrfNm;
+ const String* pTempFileName = rHTMLWrt.GetOrigFileName();
+ if(pTempFileName)
+ aGrfNm = *pTempFileName;
+
+ USHORT nErr = XOutBitmap::WriteGraphic( aGrf, aGrfNm,
+ String::CreateFromAscii("JPG"),
+ (XOUTBMP_USE_GIF_IF_POSSIBLE |
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE) );
+ if( nErr ) // fehlerhaft, da ist nichts auszugeben
+ {
+ rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ return rWrt;
+ }
+ aGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject(rWrt.GetBaseURL()), aGrfNm,
+ URIHelper::GetMaybeFileHdl() );
+ ULONG nFlags = bInCntnr ? HTML_FRMOPTS_GENIMG_CNTNR
+ : HTML_FRMOPTS_GENIMG;
+ OutHTML_Image( rWrt, rFrmFmt, aGrfNm,
+ pOLENd->GetTitle(), pOLENd->GetTwipSize(),
+ nFlags, pMarkToOLE );
+ }
+
+ return rWrt;
+}
+
+
diff --git a/sw/source/filter/html/htmlsect.cxx b/sw/source/filter/html/htmlsect.cxx
new file mode 100644
index 000000000000..ac2f348532e8
--- /dev/null
+++ b/sw/source/filter/html/htmlsect.cxx
@@ -0,0 +1,862 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <rtl/uri.hxx>
+
+#include <svl/urihelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <sfx2/linkmgr.hxx>
+
+#include "hintids.hxx"
+#include <fmtornt.hxx>
+#include <fmthdft.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtclds.hxx>
+#include <fmtanchr.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtflcnt.hxx>
+#include "frmatr.hxx"
+#include "doc.hxx"
+#include "pam.hxx"
+#include "ndtxt.hxx"
+#include "shellio.hxx"
+#include "section.hxx"
+#include "poolfmt.hxx"
+#include "pagedesc.hxx"
+#include "swtable.hxx"
+#include "viewsh.hxx"
+#include "swcss1.hxx"
+#include "swhtml.hxx"
+
+#define CONTEXT_FLAGS_MULTICOL (HTML_CNTXT_STRIP_PARA | \
+ HTML_CNTXT_KEEP_NUMRULE | \
+ HTML_CNTXT_KEEP_ATTRS)
+//#define CONTEXT_FLAGS_HDRFTR (HTML_CNTXT_STRIP_PARA|HTML_CNTXT_PROTECT_STACK)
+#define CONTEXT_FLAGS_HDRFTR (CONTEXT_FLAGS_MULTICOL)
+#define CONTEXT_FLAGS_FTN (CONTEXT_FLAGS_MULTICOL)
+
+
+using namespace ::com::sun::star;
+
+
+/* */
+
+void SwHTMLParser::NewDivision( int nToken )
+{
+ String aId, aHRef, aStyle, aClass, aLang, aDir;
+ SvxAdjust eAdjust = HTML_CENTER_ON==nToken ? SVX_ADJUST_CENTER
+ : SVX_ADJUST_END;
+
+ sal_Bool bHeader=sal_False, bFooter=sal_False;
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_ALIGN:
+ if( HTML_DIVISION_ON==nToken )
+ eAdjust = (SvxAdjust)pOption->GetEnum( aHTMLPAlignTable,
+ static_cast< sal_uInt16 >(eAdjust) );
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ case HTML_O_HREF:
+ aHRef = pOption->GetString();
+ break;
+ case HTML_O_TYPE:
+ {
+ const String& rType = pOption->GetString();
+ if( rType.EqualsIgnoreCaseAscii( "HEADER" ) )
+ bHeader = sal_True;
+ else if( rType.EqualsIgnoreCaseAscii( "FOOTER" ) )
+ bFooter = sal_True;
+ }
+ }
+ }
+
+ sal_Bool bAppended = sal_False;
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ {
+ AppendTxtNode( bHeader||bFooter||aId.Len()||aHRef.Len() ? AM_NORMAL
+ : AM_NOSPACE );
+ bAppended = sal_True;
+ }
+
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
+
+ sal_Bool bStyleParsed = sal_False, bPositioned = sal_False;
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ bStyleParsed = ParseStyleOptions( aStyle, aId, aClass,
+ aItemSet, aPropInfo, &aLang, &aDir );
+ if( bStyleParsed )
+ {
+ bPositioned = HTML_DIVISION_ON == nToken && aClass.Len() &&
+ CreateContainer( aClass, aItemSet, aPropInfo,
+ pCntxt );
+ if( !bPositioned )
+ bPositioned = DoPositioning( aItemSet, aPropInfo, pCntxt );
+ }
+ }
+
+ if( !bPositioned && (bHeader || bFooter) && IsNewDoc() )
+ {
+ SwPageDesc *pPageDesc = pCSS1Parser->GetMasterPageDesc();
+ SwFrmFmt& rPageFmt = pPageDesc->GetMaster();
+
+ SwFrmFmt *pHdFtFmt;
+ sal_Bool bNew = sal_False;
+ sal_uInt16 nFlags = CONTEXT_FLAGS_HDRFTR;
+ if( bHeader )
+ {
+ pHdFtFmt = (SwFrmFmt*)rPageFmt.GetHeader().GetHeaderFmt();
+ if( !pHdFtFmt )
+ {
+ // noch keine Header, dann erzeuge einen.
+ rPageFmt.SetFmtAttr( SwFmtHeader( sal_True ));
+ pHdFtFmt = (SwFrmFmt*)rPageFmt.GetHeader().GetHeaderFmt();
+ bNew = sal_True;
+ }
+ nFlags |= HTML_CNTXT_HEADER_DIST;
+ }
+ else
+ {
+ pHdFtFmt = (SwFrmFmt*)rPageFmt.GetFooter().GetFooterFmt();
+ if( !pHdFtFmt )
+ {
+ // noch keine Footer, dann erzeuge einen.
+ rPageFmt.SetFmtAttr( SwFmtFooter( sal_True ));
+ pHdFtFmt = (SwFrmFmt*)rPageFmt.GetFooter().GetFooterFmt();
+ bNew = sal_True;
+ }
+ nFlags |= HTML_CNTXT_FOOTER_DIST;
+ }
+
+ const SwFmtCntnt& rFlyCntnt = pHdFtFmt->GetCntnt();
+ const SwNodeIndex& rCntntStIdx = *rFlyCntnt.GetCntntIdx();
+ SwCntntNode *pCNd;
+
+ if( bNew )
+ {
+ pCNd = pDoc->GetNodes()[rCntntStIdx.GetIndex()+1]
+ ->GetCntntNode();
+ }
+ else
+ {
+ // Einen neuen Node zu Beginn der Section anlegen
+ SwNodeIndex aSttIdx( rCntntStIdx, 1 );
+ pCNd = pDoc->GetNodes().MakeTxtNode( aSttIdx,
+ pCSS1Parser->GetTxtCollFromPool(RES_POOLCOLL_TEXT));
+
+ // Den bisherigen Inhalt der Section loeschen
+ SwPaM aDelPam( aSttIdx );
+ aDelPam.SetMark();
+
+ const SwStartNode *pStNd =
+ (const SwStartNode *)pDoc->GetNodes()[rCntntStIdx];
+ aDelPam.GetPoint()->nNode = pStNd->EndOfSectionIndex() - 1;
+
+ pDoc->DelFullPara( aDelPam );
+
+ // Die Seitenvorlage aktualisieren
+ for( sal_uInt16 i=0; i < pDoc->GetPageDescCnt(); i++ )
+ {
+ if( RES_POOLPAGE_HTML==const_cast<const SwDoc *>(pDoc)
+ ->GetPageDesc(i).GetPoolFmtId() )
+ {
+ pDoc->ChgPageDesc( i, *pPageDesc );
+ break;
+ }
+ }
+ }
+
+ SwPosition aNewPos( SwNodeIndex( rCntntStIdx, 1 ), SwIndex( pCNd, 0 ) );
+ SaveDocContext( pCntxt, nFlags, &aNewPos );
+ }
+ else if( !bPositioned && aId.Len() > 9 &&
+ ('s' == aId.GetChar(0) || 'S' == aId.GetChar(0) ) &&
+ ('d' == aId.GetChar(1) || 'D' == aId.GetChar(1) ) )
+ {
+ sal_Bool bEndNote = sal_False, bFootNote = sal_False;
+ if( aId.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_sdendnote, 9 ) == COMPARE_EQUAL )
+ bEndNote = sal_True;
+ else if( aId.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote, 10 ) == COMPARE_EQUAL )
+ bFootNote = sal_True;
+ if( bFootNote || bEndNote )
+ {
+ SwNodeIndex *pStartNdIdx = GetFootEndNoteSection( aId );
+ if( pStartNdIdx )
+ {
+ SwCntntNode *pCNd =
+ pDoc->GetNodes()[pStartNdIdx->GetIndex()+1]->GetCntntNode();
+ SwNodeIndex aTmpSwNodeIndex = SwNodeIndex(*pCNd);
+ SwPosition aNewPos( aTmpSwNodeIndex, SwIndex( pCNd, 0 ) );
+ SaveDocContext( pCntxt, CONTEXT_FLAGS_FTN, &aNewPos );
+ aId = aPropInfo.aId = aEmptyStr;
+ }
+ }
+ }
+
+ // Bereiche fuegen wir in Rahmen nur dann ein, wenn der Bereich gelinkt ist.
+ if( (aId.Len() && !bPositioned) || aHRef.Len() )
+ {
+ // Bereich einfuegen (muss vor dem Setzten von Attributen erfolgen,
+ // weil die Section vor der PaM-Position eingefuegt.
+
+ // wenn wir im ersten Node einer Section stehen, wir die neue
+ // Section nicht in der aktuellen, sondern vor der aktuellen
+ // Section eingefuegt. Deshalb muessen wir dann einen Node
+ // einfuegen. UND IN LOESCHEN!!!
+ if( !bAppended )
+ {
+ SwNodeIndex aPrvNdIdx( pPam->GetPoint()->nNode, -1 );
+ if( (pDoc->GetNodes()[aPrvNdIdx])->IsSectionNode() )
+ {
+ AppendTxtNode();
+ bAppended = sal_True;
+ }
+ }
+ _HTMLAttrs *pPostIts = bAppended ? 0 : new _HTMLAttrs;
+ SetAttr( sal_True, sal_True, pPostIts );
+
+ // Namen der Section eindeutig machen
+ String aName( pDoc->GetUniqueSectionName( aId.Len() ? &aId : 0 ) );
+
+ if( aHRef.Len() )
+ {
+ sal_Unicode cDelim = 255U;
+ String aURL;
+ xub_StrLen nPos = aHRef.SearchBackward( cDelim );
+ xub_StrLen nPos2 = STRING_NOTFOUND;
+ if( STRING_NOTFOUND != nPos )
+ {
+ nPos2 = aHRef.SearchBackward( cDelim, nPos );
+ if( STRING_NOTFOUND != nPos2 )
+ {
+ xub_StrLen nTmp = nPos;
+ nPos = nPos2;
+ nPos2 = nTmp;
+ }
+ }
+ if( STRING_NOTFOUND == nPos )
+ {
+ aURL = URIHelper::SmartRel2Abs(INetURLObject( sBaseURL ), aHRef, Link(), false);
+ }
+ else
+ {
+ aURL = URIHelper::SmartRel2Abs(INetURLObject( sBaseURL ), aHRef.Copy( 0, nPos ), Link(), false );
+ aURL += sfx2::cTokenSeperator;
+ if( STRING_NOTFOUND == nPos2 )
+ {
+ aURL += aHRef.Copy( nPos+1 );
+ }
+ else
+ {
+ aURL += aHRef.Copy( nPos+1, nPos2 - (nPos+1) );
+ aURL += sfx2::cTokenSeperator;
+ aURL += String(rtl::Uri::decode( aHRef.Copy( nPos2+1 ),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_ISO_8859_1 ));
+ }
+ }
+ aHRef = aURL;
+ }
+
+ SwSectionData aSection( (aHRef.Len()) ? FILE_LINK_SECTION
+ : CONTENT_SECTION, aName );
+ if( aHRef.Len() )
+ {
+ aSection.SetLinkFileName( aHRef );
+ aSection.SetProtectFlag(true);
+ }
+
+ SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs(aFrmItemSet );
+
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET == aItemSet.GetItemState( RES_BACKGROUND, sal_False,
+ &pItem ) )
+ {
+ aFrmItemSet.Put( *pItem );
+ aItemSet.ClearItem( RES_BACKGROUND );
+ }
+ if( SFX_ITEM_SET == aItemSet.GetItemState( RES_FRAMEDIR, sal_False,
+ &pItem ) )
+ {
+ aFrmItemSet.Put( *pItem );
+ aItemSet.ClearItem( RES_FRAMEDIR );
+ }
+
+ pDoc->InsertSwSection( *pPam, aSection, 0, &aFrmItemSet, false );
+
+ // ggfs. einen Bereich anspringen
+ if( JUMPTO_REGION == eJumpTo && aName == sJmpMark )
+ {
+ bChkJumpMark = sal_True;
+ eJumpTo = JUMPTO_NONE;
+ }
+
+ SwTxtNode* pOldTxtNd =
+ bAppended ? 0 : pDoc->GetNodes()[pPam->GetPoint()->nNode]
+ ->GetTxtNode();
+
+ pPam->Move( fnMoveBackward );
+
+ // PageDesc- und SwFmtBreak Attribute vom aktuellen Node in den
+ // (ersten) Node des Bereich verschieben.
+ if( pOldTxtNd )
+ MovePageDescAttrs( pOldTxtNd, pPam->GetPoint()->nNode.GetIndex(),
+ sal_True );
+
+ if( pPostIts )
+ {
+ // noch vorhandene PostIts in den ersten Absatz
+ // der Tabelle setzen
+ InsertAttrs( *pPostIts );
+ delete pPostIts;
+ pPostIts = 0;
+ }
+
+ pCntxt->SetSpansSection( sal_True );
+
+ // keine text::Bookmarks mit dem gleichen Namen wie Bereiche einfuegen
+ if( aPropInfo.aId.Len() && aPropInfo.aId==aName )
+ aPropInfo.aId.Erase();
+ }
+ else
+ {
+ pCntxt->SetAppendMode( AM_NOSPACE );
+ }
+
+ if( SVX_ADJUST_END != eAdjust )
+ {
+ InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eAdjust, RES_PARATR_ADJUST), pCntxt );
+ }
+
+ // Style parsen
+ if( bStyleParsed )
+ InsertAttrs( aItemSet, aPropInfo, pCntxt, sal_True );
+
+ PushContext( pCntxt );
+}
+
+void SwHTMLParser::EndDivision( int /*nToken*/ )
+{
+ // Stack-Eintrag zu dem Token suchen (weil wir noch den Div-Stack
+ // haben unterscheiden wir erst einmal nicht zwischen DIV und CENTER
+ _HTMLAttrContext *pCntxt = 0;
+ sal_uInt16 nPos = aContexts.Count();
+ while( !pCntxt && nPos>nContextStMin )
+ {
+ switch( aContexts[--nPos]->GetToken() )
+ {
+ case HTML_CENTER_ON:
+ case HTML_DIVISION_ON:
+ pCntxt = aContexts[nPos];
+ aContexts.Remove( nPos, 1 );
+ break;
+ }
+ }
+
+ if( pCntxt )
+ {
+ // Attribute beenden
+ EndContext( pCntxt );
+ SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
+
+ delete pCntxt;
+ }
+}
+
+void SwHTMLParser::FixHeaderFooterDistance( sal_Bool bHeader,
+ const SwPosition *pOldPos )
+{
+ SwPageDesc *pPageDesc = pCSS1Parser->GetMasterPageDesc();
+ SwFrmFmt& rPageFmt = pPageDesc->GetMaster();
+
+ SwFrmFmt *pHdFtFmt =
+ bHeader ? (SwFrmFmt*)rPageFmt.GetHeader().GetHeaderFmt()
+ : (SwFrmFmt*)rPageFmt.GetFooter().GetFooterFmt();
+ ASSERT( pHdFtFmt, "Doch keine Kopf- oder Fusszeile" );
+
+ const SwFmtCntnt& rFlyCntnt = pHdFtFmt->GetCntnt();
+ const SwNodeIndex& rCntntStIdx = *rFlyCntnt.GetCntntIdx();
+
+ ULONG nPrvNxtIdx;
+ if( bHeader )
+ {
+ nPrvNxtIdx = pDoc->GetNodes()[rCntntStIdx]->EndOfSectionIndex()-1;
+ }
+ else
+ {
+ nPrvNxtIdx = pOldPos->nNode.GetIndex() - 1;
+ }
+
+ sal_uInt16 nSpace = 0;
+ SwTxtNode *pTxtNode = pDoc->GetNodes()[nPrvNxtIdx]->GetTxtNode();
+ if( pTxtNode )
+ {
+ const SvxULSpaceItem& rULSpace =
+ ((const SvxULSpaceItem&)pTxtNode
+ ->SwCntntNode::GetAttr( RES_UL_SPACE ));
+
+ // Der untere Absatz-Abstand wird zum Abstand zur
+ // Kopf- oder Fusszeile
+ nSpace = rULSpace.GetLower();
+
+ // und anschliessend auf einen vernuenftigen Wert
+ // gesetzt
+ const SvxULSpaceItem& rCollULSpace =
+ pTxtNode->GetAnyFmtColl().GetULSpace();
+ if( rCollULSpace.GetUpper() == rULSpace.GetUpper() )
+ pTxtNode->ResetAttr( RES_UL_SPACE );
+ else
+ pTxtNode->SetAttr(
+ SvxULSpaceItem( rULSpace.GetUpper(),
+ rCollULSpace.GetLower(), RES_UL_SPACE ) );
+ }
+
+ if( bHeader )
+ {
+ nPrvNxtIdx = pOldPos->nNode.GetIndex();
+ }
+ else
+ {
+ nPrvNxtIdx = rCntntStIdx.GetIndex() + 1;
+ }
+
+ pTxtNode = pDoc->GetNodes()[nPrvNxtIdx]
+ ->GetTxtNode();
+ if( pTxtNode )
+ {
+ const SvxULSpaceItem& rULSpace =
+ ((const SvxULSpaceItem&)pTxtNode
+ ->SwCntntNode::GetAttr( RES_UL_SPACE ));
+
+ // Der obere Absatz-Abstand wird zum Abstand zur
+ // Kopf- oder Fusszeile, wenn er groesser ist als
+ // der untere vom Absatz davor
+ if( rULSpace.GetUpper() > nSpace )
+ nSpace = rULSpace.GetUpper();
+
+ // und anschliessend auf einen vernuenftigen Wert gesetzt
+ const SvxULSpaceItem& rCollULSpace =
+ pTxtNode->GetAnyFmtColl().GetULSpace();
+ if( rCollULSpace.GetLower() == rULSpace.GetLower() )
+ pTxtNode->ResetAttr( RES_UL_SPACE );
+ else
+ pTxtNode->SetAttr(
+ SvxULSpaceItem( rCollULSpace.GetUpper(),
+ rULSpace.GetLower(), RES_UL_SPACE ) );
+ }
+
+ SvxULSpaceItem aULSpace( RES_UL_SPACE );
+ if( bHeader )
+ aULSpace.SetLower( nSpace );
+ else
+ aULSpace.SetUpper( nSpace );
+
+ pHdFtFmt->SetFmtAttr( aULSpace );
+}
+
+sal_Bool SwHTMLParser::EndSection( sal_Bool bLFStripped )
+{
+ SwEndNode *pEndNd = pDoc->GetNodes()[pPam->GetPoint()->nNode.GetIndex()+1]
+ ->GetEndNode();
+ if( pEndNd && pEndNd->StartOfSectionNode()->IsSectionNode() )
+ {
+ // den Bereich beenden
+ if( !bLFStripped )
+ StripTrailingPara();
+ pPam->Move( fnMoveForward );
+ return sal_True;
+ }
+
+ ASSERT( !this, "Falsche PaM Position Beenden eines Bereichs" );
+
+ return sal_False;
+}
+
+sal_Bool SwHTMLParser::EndSections( sal_Bool bLFStripped )
+{
+ sal_Bool bSectionClosed = sal_False;
+ sal_uInt16 nPos = aContexts.Count();
+ while( nPos>nContextStMin )
+ {
+ _HTMLAttrContext *pCntxt = aContexts[--nPos];
+ if( pCntxt->GetSpansSection() && EndSection( bLFStripped ) )
+ {
+ bSectionClosed = sal_True;
+ pCntxt->SetSpansSection( sal_False );
+ bLFStripped = sal_False;
+ }
+ }
+
+ return bSectionClosed;
+}
+
+/* */
+
+void SwHTMLParser::NewMultiCol()
+{
+ String aId, aStyle, aClass, aLang, aDir;
+ long nWidth = 100;
+ sal_uInt16 nCols = 0, nGutter = 10;
+ sal_Bool bPrcWidth = sal_True;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ sal_uInt16 i;
+
+ for( i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ case HTML_O_COLS:
+ nCols = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_WIDTH:
+ nWidth = pOption->GetNumber();
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ if( bPrcWidth && nWidth>100 )
+ nWidth = 100;
+ break;
+ case HTML_O_GUTTER:
+ nGutter = (sal_uInt16)pOption->GetNumber();
+ break;
+
+ }
+ }
+
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_MULTICOL_ON );
+
+ //.is the multicol elememt contained in a container? That may be the
+ // case for 5.0 documents.
+ sal_Bool bInCntnr = sal_False;
+ i = aContexts.Count();
+ while( !bInCntnr && i > nContextStMin )
+ bInCntnr = 0 != aContexts[--i]->GetFrmItemSet();
+
+ // Parse style sheets, but don't position anything by now.
+ sal_Bool bStyleParsed = sal_False;
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ bStyleParsed = ParseStyleOptions( aStyle, aId, aClass,
+ aItemSet, aPropInfo, &aLang, &aDir );
+
+ // Calculate width.
+ sal_uInt8 nPrcWidth = bPrcWidth ? (sal_uInt8)nWidth : 0;
+ sal_uInt16 nTwipWidth = 0;
+ if( !bPrcWidth && nWidth && Application::GetDefaultDevice() )
+ {
+ nTwipWidth = (sal_uInt16)Application::GetDefaultDevice()
+ ->PixelToLogic( Size(nWidth, 0),
+ MapMode(MAP_TWIP) ).Width();
+ }
+
+ if( !nPrcWidth && nTwipWidth < MINFLY )
+ nTwipWidth = MINFLY;
+
+ // Do positioning.
+ sal_Bool bPositioned = sal_False;
+ if( bInCntnr || pCSS1Parser->MayBePositioned( aPropInfo, sal_True ) )
+ {
+ SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs(aFrmItemSet );
+
+ SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE, aItemSet, aPropInfo,
+ aFrmItemSet );
+
+ // The width is either the WIDTH attribute's value or contained
+ // in some style option.
+ SetVarSize( aItemSet, aPropInfo, aFrmItemSet, nTwipWidth, nPrcWidth );
+
+ SetSpace( Size(0,0), aItemSet, aPropInfo, aFrmItemSet );
+
+ // Set some other frame attributes. If the background is set, its
+ // it will be cleared here. That for, it won't be set at the section,
+ // too.
+ SetFrmFmtAttrs( aItemSet, aPropInfo,
+ HTML_FF_BOX|HTML_FF_BACKGROUND|HTML_FF_PADDING|HTML_FF_DIRECTION,
+ aFrmItemSet );
+
+ // Insert fly frame. If the are columns, the fly frame's name is not
+ // the sections name but a generated one.
+ String aFlyName( aEmptyStr );
+ if( nCols < 2 )
+ {
+ aFlyName = aId;
+ aPropInfo.aId.Erase();
+ }
+
+ InsertFlyFrame( aFrmItemSet, pCntxt, aFlyName, CONTEXT_FLAGS_ABSPOS );
+
+ pCntxt->SetPopStack( sal_True );
+ bPositioned = sal_True;
+ }
+
+ sal_Bool bAppended = sal_False;
+ if( !bPositioned )
+ {
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ {
+ AppendTxtNode( AM_SPACE );
+ bAppended = sal_True;
+ }
+ else
+ {
+ AddParSpace();
+ }
+ }
+
+ // If there are less then 2 columns, no section is inserted.
+ if( nCols >= 2 )
+ {
+ if( !bAppended )
+ {
+ // If the pam is at the start of a section, a additional text
+ // node must be inserted. Otherwise, the new section will be
+ // inserted in front of the old one.
+ SwNodeIndex aPrvNdIdx( pPam->GetPoint()->nNode, -1 );
+ if( (pDoc->GetNodes()[aPrvNdIdx])->IsSectionNode() )
+ {
+ AppendTxtNode();
+ bAppended = sal_True;
+ }
+ }
+ _HTMLAttrs *pPostIts = bAppended ? 0 : new _HTMLAttrs;
+ SetAttr( sal_True, sal_True, pPostIts );
+
+ // Make section name unique.
+ String aName( pDoc->GetUniqueSectionName( aId.Len() ? &aId : 0 ) );
+ SwSectionData aSection( CONTENT_SECTION, aName );
+
+ SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs(aFrmItemSet );
+
+ if( nGutter && Application::GetDefaultDevice() )
+ {
+ nGutter = (sal_uInt16)Application::GetDefaultDevice()
+ ->PixelToLogic( Size(nGutter, 0),
+ MapMode(MAP_TWIP) ).Width();
+ }
+
+ SwFmtCol aFmtCol;
+#ifndef WIDTH_SUPPORTED_BY_SECTIONS
+ nPrcWidth = 100;
+#endif
+
+ aFmtCol.Init( nCols, nGutter, nPrcWidth ? USHRT_MAX : nTwipWidth );
+ aFrmItemSet.Put( aFmtCol );
+
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET == aItemSet.GetItemState( RES_BACKGROUND, sal_False,
+ &pItem ) )
+ {
+ aFrmItemSet.Put( *pItem );
+ aItemSet.ClearItem( RES_BACKGROUND );
+ }
+ if( SFX_ITEM_SET == aItemSet.GetItemState( RES_FRAMEDIR, sal_False,
+ &pItem ) )
+ {
+ aFrmItemSet.Put( *pItem );
+ aItemSet.ClearItem( RES_FRAMEDIR );
+ }
+ pDoc->InsertSwSection( *pPam, aSection, 0, &aFrmItemSet, false );
+
+ // Jump to section, if this is requested.
+ if( JUMPTO_REGION == eJumpTo && aName == sJmpMark )
+ {
+ bChkJumpMark = sal_True;
+ eJumpTo = JUMPTO_NONE;
+ }
+
+ SwTxtNode* pOldTxtNd =
+ bAppended ? 0 : pDoc->GetNodes()[pPam->GetPoint()->nNode]
+ ->GetTxtNode();
+
+ pPam->Move( fnMoveBackward );
+
+ // Move PageDesc and SwFmtBreak attributes of the current node
+ // to the section's first node.
+ if( pOldTxtNd )
+ MovePageDescAttrs( pOldTxtNd, pPam->GetPoint()->nNode.GetIndex(),
+ sal_True );
+
+ if( pPostIts )
+ {
+ // Move pending PostIts into the section.
+ InsertAttrs( *pPostIts );
+ delete pPostIts;
+ pPostIts = 0;
+ }
+
+ pCntxt->SetSpansSection( sal_True );
+
+ // Insert a bookmark if its name differs from the section's name only.
+ if( aPropInfo.aId.Len() && aPropInfo.aId==aName )
+ aPropInfo.aId.Erase();
+ }
+
+ // Additional attributes must be set as hard ones.
+ if( bStyleParsed )
+ InsertAttrs( aItemSet, aPropInfo, pCntxt, sal_True );
+
+ PushContext( pCntxt );
+}
+
+/* */
+
+void SwHTMLParser::InsertFlyFrame( const SfxItemSet& rItemSet,
+ _HTMLAttrContext *pCntxt,
+ const String& rName,
+ sal_uInt16 nFlags )
+{
+ RndStdIds eAnchorId =
+ ((const SwFmtAnchor&)rItemSet.Get( RES_ANCHOR )).GetAnchorId();
+
+ // Den Rahmen anlegen
+ SwFlyFrmFmt* pFlyFmt = pDoc->MakeFlySection( eAnchorId, pPam->GetPoint(),
+ &rItemSet );
+ // Ggf. den Namen setzen
+ if( rName.Len() )
+ pFlyFmt->SetName( rName );
+
+ RegisterFlyFrm( pFlyFmt );
+
+ const SwFmtCntnt& rFlyCntnt = pFlyFmt->GetCntnt();
+ const SwNodeIndex& rFlyCntIdx = *rFlyCntnt.GetCntntIdx();
+ SwCntntNode *pCNd = pDoc->GetNodes()[rFlyCntIdx.GetIndex()+1]
+ ->GetCntntNode();
+
+ SwPosition aNewPos( SwNodeIndex( rFlyCntIdx, 1 ), SwIndex( pCNd, 0 ) );
+ SaveDocContext( pCntxt, nFlags, &aNewPos );
+}
+
+
+/* */
+
+void SwHTMLParser::MovePageDescAttrs( SwNode *pSrcNd,
+ ULONG nDestIdx,
+ sal_Bool bFmtBreak )
+{
+ SwCntntNode* pDestCntntNd =
+ pDoc->GetNodes()[nDestIdx]->GetCntntNode();
+
+ ASSERT( pDestCntntNd, "Wieso ist das Ziel kein Content-Node?" );
+
+ if( pSrcNd->IsCntntNode() )
+ {
+ SwCntntNode* pSrcCntntNd = pSrcNd->GetCntntNode();
+
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pSrcCntntNd->GetSwAttrSet()
+ .GetItemState( RES_PAGEDESC, sal_False, &pItem ) &&
+ ((SwFmtPageDesc *)pItem)->GetPageDesc() )
+ {
+ pDestCntntNd->SetAttr( *pItem );
+ pSrcCntntNd->ResetAttr( RES_PAGEDESC );
+ }
+ if( SFX_ITEM_SET == pSrcCntntNd->GetSwAttrSet()
+ .GetItemState( RES_BREAK, sal_False, &pItem ) )
+ {
+ switch( ((SvxFmtBreakItem *)pItem)->GetBreak() )
+ {
+ case SVX_BREAK_PAGE_BEFORE:
+ case SVX_BREAK_PAGE_AFTER:
+ case SVX_BREAK_PAGE_BOTH:
+ if( bFmtBreak )
+ pDestCntntNd->SetAttr( *pItem );
+ pSrcCntntNd->ResetAttr( RES_BREAK );
+ default:
+ ;
+ }
+ }
+ }
+ else if( pSrcNd->IsTableNode() )
+ {
+ SwFrmFmt *pFrmFmt = pSrcNd->GetTableNode()->GetTable().GetFrmFmt();
+
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pFrmFmt->GetAttrSet().
+ GetItemState( RES_PAGEDESC, sal_False, &pItem ) )
+ {
+ pDestCntntNd->SetAttr( *pItem );
+ pFrmFmt->ResetFmtAttr( RES_PAGEDESC );
+ }
+ }
+}
+
diff --git a/sw/source/filter/html/htmltab.cxx b/sw/source/filter/html/htmltab.cxx
new file mode 100644
index 000000000000..df9f43fafa41
--- /dev/null
+++ b/sw/source/filter/html/htmltab.cxx
@@ -0,0 +1,5600 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+//#define TEST_RESIZE
+
+
+#include "hintids.hxx"
+#include <vcl/svapp.hxx>
+#ifndef _WRKWIN_HXX //autogen
+#include <vcl/wrkwin.hxx>
+#endif
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <svl/urihelper.hxx>
+
+
+#include <fmtornt.hxx>
+#include <frmfmt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtanchr.hxx>
+#include <fmtlsplt.hxx>
+#include "frmatr.hxx"
+#include "pam.hxx"
+#include "doc.hxx"
+#include "ndtxt.hxx"
+#include "shellio.hxx"
+#include "poolfmt.hxx"
+#include "swtable.hxx"
+#include "cellatr.hxx"
+#ifdef TEST_RESIZE
+#include "viewsh.hxx"
+#endif
+#include "htmltbl.hxx"
+#include "swtblfmt.hxx"
+#include "htmlnum.hxx"
+#include "swhtml.hxx"
+#include "swcss1.hxx"
+#include <numrule.hxx>
+
+#define NETSCAPE_DFLT_BORDER 1
+#define NETSCAPE_DFLT_CELLPADDING 1
+#define NETSCAPE_DFLT_CELLSPACING 2
+
+//#define FIX56334
+
+using namespace ::com::sun::star;
+
+
+static HTMLOptionEnum __FAR_DATA aHTMLTblVAlignTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_VA_top, text::VertOrientation::NONE },
+ { OOO_STRING_SVTOOLS_HTML_VA_middle, text::VertOrientation::CENTER },
+ { OOO_STRING_SVTOOLS_HTML_VA_bottom, text::VertOrientation::BOTTOM },
+ { 0, 0 }
+};
+
+
+/* */
+
+// Die Optionen eines Table-Tags
+
+struct HTMLTableOptions
+{
+ sal_uInt16 nCols;
+ sal_uInt16 nWidth;
+ sal_uInt16 nHeight;
+ sal_uInt16 nCellPadding;
+ sal_uInt16 nCellSpacing;
+ sal_uInt16 nBorder;
+ sal_uInt16 nHSpace;
+ sal_uInt16 nVSpace;
+
+ SvxAdjust eAdjust;
+ sal_Int16 eVertOri;
+ HTMLTableFrame eFrame;
+ HTMLTableRules eRules;
+
+ sal_Bool bPrcWidth : 1;
+ sal_Bool bTableAdjust : 1;
+ sal_Bool bBGColor : 1;
+
+ Color aBorderColor;
+ Color aBGColor;
+
+ String aBGImage, aStyle, aId, aClass, aDir;
+
+ HTMLTableOptions( const HTMLOptions *pOptions, SvxAdjust eParentAdjust );
+};
+
+/* */
+
+class _HTMLTableContext
+{
+ SwHTMLNumRuleInfo aNumRuleInfo; // Vor der Tabelle gueltige Numerierung
+
+ SwTableNode *pTblNd; // der Tabellen-Node
+ SwFrmFmt *pFrmFmt; // der Fly frame::Frame, in dem die Tabelle steht
+ SwPosition *pPos; // die Position hinter der Tabelle
+
+ sal_uInt16 nContextStAttrMin;
+ sal_uInt16 nContextStMin;
+
+ sal_Bool bRestartPRE : 1;
+ sal_Bool bRestartXMP : 1;
+ sal_Bool bRestartListing : 1;
+
+public:
+
+ _HTMLAttrTable aAttrTab; // und die Attribute
+
+ _HTMLTableContext( SwPosition *pPs, sal_uInt16 nCntxtStMin,
+ sal_uInt16 nCntxtStAttrMin ) :
+ pTblNd( 0 ),
+ pFrmFmt( 0 ),
+ pPos( pPs ),
+ nContextStAttrMin( nCntxtStAttrMin ),
+ nContextStMin( nCntxtStMin ),
+ bRestartPRE( sal_False ),
+ bRestartXMP( sal_False ),
+ bRestartListing( sal_False )
+ {
+ memset( &aAttrTab, 0, sizeof( _HTMLAttrTable ));
+ }
+
+ ~_HTMLTableContext();
+
+ void SetNumInfo( const SwHTMLNumRuleInfo& rInf ) { aNumRuleInfo.Set(rInf); }
+ const SwHTMLNumRuleInfo& GetNumInfo() const { return aNumRuleInfo; };
+
+ void SavePREListingXMP( SwHTMLParser& rParser );
+ void RestorePREListingXMP( SwHTMLParser& rParser );
+
+ SwPosition *GetPos() const { return pPos; }
+
+ void SetTableNode( SwTableNode *pNd ) { pTblNd = pNd; }
+ SwTableNode *GetTableNode() const { return pTblNd; }
+
+ void SetFrmFmt( SwFrmFmt *pFmt ) { pFrmFmt = pFmt; }
+ SwFrmFmt *GetFrmFmt() const { return pFrmFmt; }
+
+ sal_uInt16 GetContextStMin() const { return nContextStMin; }
+ sal_uInt16 GetContextStAttrMin() const { return nContextStAttrMin; }
+};
+
+/* */
+
+// der Inhalt einer Zelle ist eine verkettete Liste mit SwStartNodes und
+// HTMLTables.
+
+class HTMLTableCnts
+{
+ HTMLTableCnts *pNext; // der naechste Inhalt
+
+ // von den beiden naechsten Pointern darf nur einer gesetzt sein!
+ const SwStartNode *pStartNode; // ein Abastz
+ HTMLTable *pTable; // eine Tabelle
+
+ SwHTMLTableLayoutCnts* pLayoutInfo;
+
+ sal_Bool bNoBreak;
+
+ void InitCtor();
+
+public:
+
+ HTMLTableCnts( const SwStartNode* pStNd );
+ HTMLTableCnts( HTMLTable* pTab );
+
+ ~HTMLTableCnts(); // nur in ~HTMLTableCell erlaubt
+
+ // Ermitteln des SwStartNode bzw. der HTMLTable
+ const SwStartNode *GetStartNode() const { return pStartNode; }
+ const HTMLTable *GetTable() const { return pTable; }
+ HTMLTable *GetTable() { return pTable; }
+
+ // hinzufuegen eines neuen Knotens am Listenende
+ void Add( HTMLTableCnts* pNewCnts );
+
+ // Ermitteln des naechsten Knotens
+ const HTMLTableCnts *Next() const { return pNext; }
+ HTMLTableCnts *Next() { return pNext; }
+
+ inline void SetTableBox( SwTableBox *pBox );
+
+ void SetNoBreak() { bNoBreak = sal_True; }
+
+ SwHTMLTableLayoutCnts *CreateLayoutInfo();
+};
+
+/* */
+
+// Eine Zelle der HTML-Tabelle
+
+class HTMLTableCell
+{
+ // !!!ACHTUNG!!!!! Fuer jeden neuen Pointer muss die SetProtected-
+ // Methode (und natuerlich der Destruktor) bearbeitet werden.
+ HTMLTableCnts *pContents; // der Inhalt der Zelle
+ SvxBrushItem *pBGBrush; // Hintergrund der Zelle
+ // !!!ACHTUNG!!!!!
+
+ sal_uInt32 nNumFmt;
+ sal_uInt16 nRowSpan; // ROWSPAN der Zelle
+ sal_uInt16 nColSpan; // COLSPAN der Zelle
+ sal_uInt16 nWidth; // WIDTH der Zelle
+ double nValue;
+ sal_Int16 eVertOri; // vertikale Ausrichtung der Zelle
+ sal_Bool bProtected : 1; // Zelle darf nicht belegt werden
+ sal_Bool bRelWidth : 1; // nWidth ist %-Angabe
+ sal_Bool bHasNumFmt : 1;
+ sal_Bool bHasValue : 1;
+ sal_Bool bNoWrap : 1;
+ sal_Bool mbCovered : 1;
+
+public:
+
+ HTMLTableCell(); // neue Zellen sind immer leer
+
+ ~HTMLTableCell(); // nur in ~HTMLTableRow erlaubt
+
+ // Belegen einer nicht-leeren Zelle
+ void Set( HTMLTableCnts *pCnts, sal_uInt16 nRSpan, sal_uInt16 nCSpan,
+ sal_Int16 eVertOri, SvxBrushItem *pBGBrush,
+ sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
+ sal_Bool bHasValue, double nValue, sal_Bool bNoWrap, sal_Bool bCovered );
+
+ // Schuetzen einer leeren 1x1-Zelle
+ void SetProtected();
+
+ // Setzen/Ermitteln des Inhalts einer Zelle
+ void SetContents( HTMLTableCnts *pCnts ) { pContents = pCnts; }
+ const HTMLTableCnts *GetContents() const { return pContents; }
+ HTMLTableCnts *GetContents() { return pContents; }
+
+ // ROWSPAN/COLSPAN der Zelle Setzen/Ermitteln
+ void SetRowSpan( sal_uInt16 nRSpan ) { nRowSpan = nRSpan; }
+ sal_uInt16 GetRowSpan() const { return nRowSpan; }
+
+ void SetColSpan( sal_uInt16 nCSpan ) { nColSpan = nCSpan; }
+ sal_uInt16 GetColSpan() const { return nColSpan; }
+
+ inline void SetWidth( sal_uInt16 nWidth, sal_Bool bRelWidth );
+
+ const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
+
+ inline sal_Bool GetNumFmt( sal_uInt32& rNumFmt ) const;
+ inline sal_Bool GetValue( double& rValue ) const;
+
+ sal_Int16 GetVertOri() const { return eVertOri; }
+
+ // Ist die Zelle belegt oder geschuetzt?
+ sal_Bool IsUsed() const { return pContents!=0 || bProtected; }
+
+ SwHTMLTableLayoutCell *CreateLayoutInfo();
+
+ sal_Bool IsCovered() const { return mbCovered; }
+};
+
+/* */
+
+// Eine Zeile der HTML-Tabelle
+
+typedef HTMLTableCell* HTMLTableCellPtr;
+SV_DECL_PTRARR_DEL(HTMLTableCells,HTMLTableCellPtr,5,5)
+
+class HTMLTableRow
+{
+ HTMLTableCells *pCells; // die Zellen der Zeile
+
+ sal_Bool bIsEndOfGroup : 1;
+ sal_Bool bSplitable : 1;
+
+ sal_uInt16 nHeight; // Optionen von <TR>/<TD>
+ sal_uInt16 nEmptyRows; // wieviele Leere Zeilen folgen
+
+ SvxAdjust eAdjust;
+ sal_Int16 eVertOri;
+ SvxBrushItem *pBGBrush; // Hintergrund der Zelle aus STYLE
+
+public:
+
+ sal_Bool bBottomBorder; // kommt hinter der Zeile eine Linie?
+
+ HTMLTableRow( sal_uInt16 nCells=0 ); // die Zellen der Zeile sind leer
+
+ ~HTMLTableRow();
+
+ inline void SetHeight( sal_uInt16 nHeight );
+ sal_uInt16 GetHeight() const { return nHeight; }
+
+ // Ermitteln einer Zelle
+ inline HTMLTableCell *GetCell( sal_uInt16 nCell ) const;
+ inline const HTMLTableCells *GetCells() const { return pCells; }
+
+
+ inline void SetAdjust( SvxAdjust eAdj ) { eAdjust = eAdj; }
+ inline SvxAdjust GetAdjust() const { return eAdjust; }
+
+ inline void SetVertOri( sal_Int16 eV) { eVertOri = eV; }
+ inline sal_Int16 GetVertOri() const { return eVertOri; }
+
+ void SetBGBrush( SvxBrushItem *pBrush ) { pBGBrush = pBrush; }
+ const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
+
+ inline void SetEndOfGroup() { bIsEndOfGroup = sal_True; }
+ inline sal_Bool IsEndOfGroup() const { return bIsEndOfGroup; }
+
+ void IncEmptyRows() { nEmptyRows++; }
+ sal_uInt16 GetEmptyRows() const { return nEmptyRows; }
+
+ // Expandieren einer Zeile durch hinzufuegen leerer Zellen
+ void Expand( sal_uInt16 nCells, sal_Bool bOneCell=sal_False );
+
+ // Verkuerzen einer Zeile durch loesen von leeren Zellen
+ void Shrink( sal_uInt16 nCells );
+
+ void SetSplitable( sal_Bool bSet ) { bSplitable = bSet; }
+ sal_Bool IsSplitable() const { return bSplitable; }
+};
+
+/* */
+
+// Eine Spalte der HTML-Tabelle
+
+class HTMLTableColumn
+{
+ sal_Bool bIsEndOfGroup;
+
+ sal_uInt16 nWidth; // Optionen von <COL>
+ sal_Bool bRelWidth;
+
+ SvxAdjust eAdjust;
+ sal_Int16 eVertOri;
+
+ SwFrmFmt *aFrmFmts[6];
+
+ inline sal_uInt16 GetFrmFmtIdx( sal_Bool bBorderLine,
+ sal_Int16 eVertOri ) const;
+
+public:
+
+ sal_Bool bLeftBorder; // kommt vor der Spalte eine Linie
+
+ HTMLTableColumn();
+
+ inline void SetWidth( sal_uInt16 nWidth, sal_Bool bRelWidth);
+
+ inline void SetAdjust( SvxAdjust eAdj ) { eAdjust = eAdj; }
+ inline SvxAdjust GetAdjust() const { return eAdjust; }
+
+ inline void SetVertOri( sal_Int16 eV) { eVertOri = eV; }
+ inline sal_Int16 GetVertOri() const { return eVertOri; }
+
+ inline void SetEndOfGroup() { bIsEndOfGroup = sal_True; }
+ inline sal_Bool IsEndOfGroup() const { return bIsEndOfGroup; }
+
+ inline void SetFrmFmt( SwFrmFmt *pFmt, sal_Bool bBorderLine,
+ sal_Int16 eVertOri );
+ inline SwFrmFmt *GetFrmFmt( sal_Bool bBorderLine,
+ sal_Int16 eVertOri ) const;
+
+ SwHTMLTableLayoutColumn *CreateLayoutInfo();
+};
+
+/* */
+
+// eine HTML-Tabelle
+
+typedef HTMLTableRow* HTMLTableRowPtr;
+SV_DECL_PTRARR_DEL(HTMLTableRows,HTMLTableRowPtr,5,5)
+
+typedef HTMLTableColumn* HTMLTableColumnPtr;
+SV_DECL_PTRARR_DEL(HTMLTableColumns,HTMLTableColumnPtr,5,5)
+
+SV_DECL_PTRARR(SdrObjects,SdrObject *,1,1)
+
+class HTMLTable
+{
+ String aId;
+ String aStyle;
+ String aClass;
+ String aDir;
+
+ SdrObjects *pResizeDrawObjs;// SDR-Objekte
+ SvUShorts *pDrawObjPrcWidths; // Spalte des Zeichen-Objekts und dessen
+ // relative Breite
+
+ HTMLTableRows *pRows; // die Zeilen der Tabelle
+ HTMLTableColumns *pColumns; // die Spalten der Tabelle
+
+ sal_uInt16 nRows; // Anzahl Zeilen
+ sal_uInt16 nCols; // Anzahl Spalten
+ sal_uInt16 nFilledCols; // Anzahl tatsaechlich gefuellter Spalten
+
+ sal_uInt16 nCurRow; // aktuelle Zeile
+ sal_uInt16 nCurCol; // aktuelle Spalte
+
+ sal_uInt16 nLeftMargin; // Abstand zum linken Rand (aus Absatz)
+ sal_uInt16 nRightMargin; // Abstand zum rechten Rand (aus Absatz)
+
+ sal_uInt16 nCellPadding; // Abstand Umrandung zum Text
+ sal_uInt16 nCellSpacing; // Abstand zwischen zwei Zellen
+ sal_uInt16 nHSpace;
+ sal_uInt16 nVSpace;
+
+ sal_uInt16 nBoxes; // Wievele Boxen enthaelt die Tabelle
+
+ const SwStartNode *pPrevStNd; // der Table-Node oder der Start-Node
+ // der vorhergehenden Section
+ const SwTable *pSwTable; // die SW-Tabelle (nur auf dem Top-Level)
+ SwTableBox *pBox1; // die TableBox, die beim Erstellen
+ // der Top-Level-Tabelle angelegt wird
+
+ SwTableBoxFmt *pBoxFmt; // das frame::Frame-Format einer SwTableBox
+ SwTableLineFmt *pLineFmt; // das frame::Frame-Format einer SwTableLine
+ SwTableLineFmt *pLineFrmFmtNoHeight;
+ SvxBrushItem *pBGBrush; // Hintergrund der Tabelle
+ SvxBrushItem *pInhBGBrush; // "geerbter" Hintergrund der Tabelle
+ const SwStartNode *pCaptionStartNode; // Start-Node der Tabellen-Ueberschrift
+
+ SvxBorderLine aTopBorderLine; // die Linie fuer die Umrandung
+ SvxBorderLine aBottomBorderLine;// die Linie fuer die Umrandung
+ SvxBorderLine aLeftBorderLine; // die Linie fuer die Umrandung
+ SvxBorderLine aRightBorderLine; // die Linie fuer die Umrandung
+ SvxBorderLine aBorderLine; // die Linie fuer die Umrandung
+ SvxBorderLine aInhLeftBorderLine; // die Linie fuer die Umrandung
+ SvxBorderLine aInhRightBorderLine; // die Linie fuer die Umrandung
+ sal_Bool bTopBorder; // besitzt die Tabelle oben eine Linie
+ sal_Bool bRightBorder; // besitzt die Tabelle rechts eine Linie
+ sal_Bool bTopAlwd; // duerfen die Raender gesetzt werden?
+ sal_Bool bRightAlwd;
+ sal_Bool bFillerTopBorder; // bekommt eine linke/rechter Filler-
+ sal_Bool bFillerBottomBorder; // Zelle eine obere/untere Umrandung?
+ sal_Bool bInhLeftBorder;
+ sal_Bool bInhRightBorder;
+ sal_Bool bBordersSet; // die Umrandung wurde bereits gesetzt
+ sal_Bool bForceFrame;
+ sal_Bool bTableAdjustOfTag; // stammt nTableAdjust aus <TABLE>?
+ sal_uInt32 nHeadlineRepeat; // repeating rows
+ sal_Bool bIsParentHead;
+ sal_Bool bHasParentSection;
+ sal_Bool bMakeTopSubTable;
+ sal_Bool bHasToFly;
+ sal_Bool bFixedCols;
+ sal_Bool bColSpec; // Gab es COL(GROUP)-Elemente?
+ sal_Bool bPrcWidth; // Breite ist eine %-Angabe
+
+ SwHTMLParser *pParser; // der aktuelle Parser
+ HTMLTable *pTopTable; // die Tabelle auf dem Top-Level
+ HTMLTableCnts *pParentContents;
+
+ _HTMLTableContext *pContext; // der Kontext der Tabelle
+
+ SwHTMLTableLayout *pLayoutInfo;
+
+
+ // die folgenden Parameter stammen aus der dem <TABLE>-Tag
+ sal_uInt16 nWidth; // die Breite der Tabelle
+ sal_uInt16 nHeight; // absolute Hoehe der Tabelle
+ SvxAdjust eTableAdjust; // drawing::Alignment der Tabelle
+ sal_Int16 eVertOri; // Default vertikale Ausr. der Zellen
+ sal_uInt16 nBorder; // Breite der auesseren Umrandung
+ HTMLTableFrame eFrame; // Rahmen um die Tabelle
+ HTMLTableRules eRules; // Ramhen in der Tabelle
+ sal_Bool bTopCaption; // Ueberschrift ueber der Tabelle
+
+ void InitCtor( const HTMLTableOptions *pOptions );
+
+ // Korigieren des Row-Spans fuer alle Zellen oberhalb der
+ // angegeben Zelle und der Zelle selbst, fuer die den anegebenen
+ // Inhalt besitzen. Die angegeben Zelle bekommt den Row-Span 1
+ void FixRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, const HTMLTableCnts *pCnts );
+
+ // Schuetzen der angegeben Zelle und den darunterliegenden
+ void ProtectRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, sal_uInt16 nRowSpan );
+
+ // Suchen des SwStartNodes der logisch vorhergehenden Box
+ // bei nRow==nCell==USHRT_MAX wird der allerletzte Start-Node
+ // der Tabelle zurueckgegeben
+ const SwStartNode* GetPrevBoxStartNode( sal_uInt16 nRow, sal_uInt16 nCell ) const;
+
+ sal_uInt16 GetTopCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
+ sal_Bool bSwBorders=sal_True ) const;
+ sal_uInt16 GetBottomCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
+ sal_Bool bSwBorders=sal_True ) const;
+
+ // Anpassen des frame::Frame-Formates einer Box
+ void FixFrameFmt( SwTableBox *pBox, sal_uInt16 nRow, sal_uInt16 nCol,
+ sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
+ sal_Bool bFirstPara=sal_True, sal_Bool bLastPara=sal_True ) const;
+ void FixFillerFrameFmt( SwTableBox *pBox, sal_Bool bRight ) const;
+
+ // den Inhalt (Lines/Boxen) eine Tabelle erstellen
+ void _MakeTable( SwTableBox *pUpper=0 );
+
+ // Anlegen einer neuen SwTableBox, die einen SwStartNode enthaelt
+ SwTableBox *NewTableBox( const SwStartNode *pStNd,
+ SwTableLine *pUpper ) const;
+
+ // Erstellen einer SwTableLine aus den Zellen des Rechtecks
+ // (nTopRow/nLeftCol) inklusive bis (nBottomRow/nRightRow) exklusive
+ SwTableLine *MakeTableLine( SwTableBox *pUpper,
+ sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
+ sal_uInt16 nBottomRow, sal_uInt16 nRightCol );
+
+ // Erstellen einer SwTableBox aus dem Inhalt einer Zelle
+ SwTableBox *MakeTableBox( SwTableLine *pUpper,
+ HTMLTableCnts *pCnts,
+ sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
+ sal_uInt16 nBootomRow, sal_uInt16 nRightCol );
+
+ // der Autolayout-Algorithmus
+
+ // Setzen der Umrandung anhand der Vorgaben der Parent-Tabelle
+ void InheritBorders( const HTMLTable *pParent,
+ sal_uInt16 nRow, sal_uInt16 nCol,
+ sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
+ sal_Bool bFirstPara, sal_Bool bLastPara );
+
+ // Linke und rechte Umrandung der umgebenen Tabelle erben
+ void InheritVertBorders( const HTMLTable *pParent,
+ sal_uInt16 nCol, sal_uInt16 nColSpan );
+
+
+ // Setzen der Umrandung anhand der Benutzervorgaben
+ void SetBorders();
+
+ // wurde die Umrandung der Tabelle schon gesetzt
+ sal_Bool BordersSet() const { return bBordersSet; }
+
+ const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
+ const SvxBrushItem *GetInhBGBrush() const { return pInhBGBrush; }
+
+ sal_uInt16 GetBorderWidth( const SvxBorderLine& rBLine,
+ sal_Bool bWithDistance=sal_False ) const;
+
+public:
+
+ sal_Bool bFirstCell; // wurde schon eine Zelle angelegt?
+
+ HTMLTable( SwHTMLParser* pPars, HTMLTable *pTopTab,
+ sal_Bool bParHead, sal_Bool bHasParentSec,
+ sal_Bool bTopTbl, sal_Bool bHasToFly,
+ const HTMLTableOptions *pOptions );
+
+ ~HTMLTable();
+
+ // Ermitteln einer Zelle
+ inline HTMLTableCell *GetCell( sal_uInt16 nRow, sal_uInt16 nCell ) const;
+
+ // Ueberschrift setzen/ermitteln
+ inline void SetCaption( const SwStartNode *pStNd, sal_Bool bTop );
+ const SwStartNode *GetCaptionStartNode() const { return pCaptionStartNode; }
+ sal_Bool IsTopCaption() const { return bTopCaption; }
+
+ SvxAdjust GetTableAdjust( sal_Bool bAny ) const
+ {
+ return (bTableAdjustOfTag || bAny) ? eTableAdjust : SVX_ADJUST_END;
+ }
+ sal_Int16 GetVertOri() const { return eVertOri; }
+
+ sal_uInt16 GetHSpace() const { return nHSpace; }
+ sal_uInt16 GetVSpace() const { return nVSpace; }
+
+ sal_Bool HasPrcWidth() const { return bPrcWidth; }
+ sal_uInt8 GetPrcWidth() const { return bPrcWidth ? (sal_uInt8)nWidth : 0; }
+
+ sal_uInt16 GetMinWidth() const
+ {
+ sal_uInt32 nMin = pLayoutInfo->GetMin();
+ return nMin < USHRT_MAX ? (sal_uInt16)nMin : USHRT_MAX;
+ }
+
+ // von Zeilen oder Spalten geerbtes drawing::Alignment holen
+ SvxAdjust GetInheritedAdjust() const;
+ sal_Int16 GetInheritedVertOri() const;
+
+ // Einfuegen einer Zelle an der aktuellen Position
+ void InsertCell( HTMLTableCnts *pCnts, sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
+ sal_uInt16 nWidth, sal_Bool bRelWidth, sal_uInt16 nHeight,
+ sal_Int16 eVertOri, SvxBrushItem *pBGBrush,
+ sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
+ sal_Bool bHasValue, double nValue, sal_Bool bNoWrap );
+
+ // Start/Ende einer neuen Zeile bekanntgeben
+ void OpenRow( SvxAdjust eAdjust, sal_Int16 eVertOri,
+ SvxBrushItem *pBGBrush );
+ void CloseRow( sal_Bool bEmpty );
+
+ // Ende einer neuen Section bekanntgeben
+ inline void CloseSection( sal_Bool bHead );
+
+ // Ende einer Spalten-Gruppe bekanntgeben
+ inline void CloseColGroup( sal_uInt16 nSpan, sal_uInt16 nWidth, sal_Bool bRelWidth,
+ SvxAdjust eAdjust, sal_Int16 eVertOri );
+
+ // Einfuegen einer Spalte
+ void InsertCol( sal_uInt16 nSpan, sal_uInt16 nWidth, sal_Bool bRelWidth,
+ SvxAdjust eAdjust, sal_Int16 eVertOri );
+
+ // Beenden einer Tab-Definition (MUSS fuer ALLE Tabs aufgerufen werden)
+ void CloseTable();
+
+ // SwTable konstruieren (inkl. der Child-Tabellen)
+ void MakeTable( SwTableBox *pUpper, sal_uInt16 nAbsAvail,
+ sal_uInt16 nRelAvail=0, sal_uInt16 nAbsLeftSpace=0,
+ sal_uInt16 nAbsRightSpace=0, sal_uInt16 nInhAbsSpace=0 );
+
+ inline sal_Bool IsNewDoc() const { return pParser->IsNewDoc(); }
+
+ void SetHasParentSection( sal_Bool bSet ) { bHasParentSection = bSet; }
+ sal_Bool HasParentSection() const { return bHasParentSection; }
+
+ void SetParentContents( HTMLTableCnts *pCnts ) { pParentContents = pCnts; }
+ HTMLTableCnts *GetParentContents() const { return pParentContents; }
+
+ void MakeParentContents();
+
+ sal_Bool GetIsParentHeader() const { return bIsParentHead; }
+
+ sal_Bool IsMakeTopSubTable() const { return bMakeTopSubTable; }
+ void SetHasToFly() { bHasToFly=sal_True; }
+ sal_Bool HasToFly() const { return bHasToFly; }
+
+ void SetTable( const SwStartNode *pStNd, _HTMLTableContext *pCntxt,
+ sal_uInt16 nLeft, sal_uInt16 nRight,
+ const SwTable *pSwTab=0, sal_Bool bFrcFrame=sal_False );
+
+ _HTMLTableContext *GetContext() const { return pContext; }
+
+ SwHTMLTableLayout *CreateLayoutInfo();
+
+ sal_Bool HasColTags() const { return bColSpec; }
+
+ sal_uInt16 IncGrfsThatResize() { return pSwTable ? ((SwTable *)pSwTable)->IncGrfsThatResize() : 0; }
+
+ void RegisterDrawObject( SdrObject *pObj, sal_uInt8 nPrcWidth );
+
+ const SwTable *GetSwTable() const { return pSwTable; }
+
+ void SetBGBrush( const SvxBrushItem& rBrush ) { delete pBGBrush; pBGBrush = new SvxBrushItem( rBrush ); }
+
+ const String& GetId() const { return aId; }
+ const String& GetClass() const { return aClass; }
+ const String& GetStyle() const { return aStyle; }
+ const String& GetDirection() const { return aDir; }
+
+ void IncBoxCount() { nBoxes++; }
+ sal_Bool IsOverflowing() const { return nBoxes > 64000; }
+};
+
+SV_IMPL_PTRARR(HTMLTableCells,HTMLTableCellPtr)
+SV_IMPL_PTRARR(HTMLTableRows,HTMLTableRowPtr)
+SV_IMPL_PTRARR(HTMLTableColumns,HTMLTableColumnPtr)
+
+/* */
+
+
+void HTMLTableCnts::InitCtor()
+{
+ pNext = 0;
+ pLayoutInfo = 0;
+
+ bNoBreak = sal_False;
+}
+
+HTMLTableCnts::HTMLTableCnts( const SwStartNode* pStNd ):
+ pStartNode(pStNd), pTable(0)
+{
+ InitCtor();
+}
+
+HTMLTableCnts::HTMLTableCnts( HTMLTable* pTab ):
+ pStartNode(0), pTable(pTab)
+{
+ InitCtor();
+}
+
+HTMLTableCnts::~HTMLTableCnts()
+{
+ delete pTable; // die Tabellen brauchen wir nicht mehr
+ delete pNext;
+}
+
+void HTMLTableCnts::Add( HTMLTableCnts* pNewCnts )
+{
+ HTMLTableCnts *pCnts = this;
+
+ while( pCnts->pNext )
+ pCnts = pCnts->pNext;
+
+ pCnts->pNext = pNewCnts;
+}
+
+inline void HTMLTableCnts::SetTableBox( SwTableBox *pBox )
+{
+ ASSERT( pLayoutInfo, "Da sit noch keine Layout-Info" );
+ if( pLayoutInfo )
+ pLayoutInfo->SetTableBox( pBox );
+}
+
+SwHTMLTableLayoutCnts *HTMLTableCnts::CreateLayoutInfo()
+{
+ if( !pLayoutInfo )
+ {
+ SwHTMLTableLayoutCnts *pNextInfo = pNext ? pNext->CreateLayoutInfo() : 0;
+ SwHTMLTableLayout *pTableInfo = pTable ? pTable->CreateLayoutInfo() : 0;
+
+ pLayoutInfo = new SwHTMLTableLayoutCnts( pStartNode, pTableInfo,
+ bNoBreak, pNextInfo );
+ }
+
+ return pLayoutInfo;
+}
+
+/* */
+
+HTMLTableCell::HTMLTableCell():
+ pContents(0),
+ pBGBrush(0),
+ nNumFmt(0),
+ nRowSpan(1),
+ nColSpan(1),
+ nWidth( 0 ),
+ nValue(0),
+ eVertOri( text::VertOrientation::NONE ),
+ bProtected(sal_False),
+ bRelWidth( sal_False ),
+ bHasNumFmt(sal_False),
+ bHasValue(sal_False),
+ mbCovered(sal_False)
+{}
+
+HTMLTableCell::~HTMLTableCell()
+{
+ // der Inhalt ist in mehrere Zellen eingetragen, darf aber nur einmal
+ // geloescht werden
+ if( 1==nRowSpan && 1==nColSpan )
+ {
+ delete pContents;
+ delete pBGBrush;
+ }
+}
+
+void HTMLTableCell::Set( HTMLTableCnts *pCnts, sal_uInt16 nRSpan, sal_uInt16 nCSpan,
+ sal_Int16 eVert, SvxBrushItem *pBrush,
+ sal_Bool bHasNF, sal_uInt32 nNF, sal_Bool bHasV, double nVal,
+ sal_Bool bNWrap, sal_Bool bCovered )
+{
+ pContents = pCnts;
+ nRowSpan = nRSpan;
+ nColSpan = nCSpan;
+ bProtected = sal_False;
+ eVertOri = eVert;
+ pBGBrush = pBrush;
+
+ bHasNumFmt = bHasNF;
+ bHasValue = bHasV;
+ nNumFmt = nNF;
+ nValue = nVal;
+
+ bNoWrap = bNWrap;
+ mbCovered = bCovered;
+}
+
+inline void HTMLTableCell::SetWidth( sal_uInt16 nWdth, sal_Bool bRelWdth )
+{
+ nWidth = nWdth;
+ bRelWidth = bRelWdth;
+}
+
+void HTMLTableCell::SetProtected()
+{
+ // Die Inhalte dieser Zelle mussen nich irgenwo anders verankert
+ // sein, weil sie nicht geloescht werden!!!
+
+ // Inhalt loeschen
+ pContents = 0;
+
+ // Hintergrundfarbe kopieren.
+ if( pBGBrush )
+ pBGBrush = new SvxBrushItem( *pBGBrush );
+
+ nRowSpan = 1;
+ nColSpan = 1;
+ bProtected = sal_True;
+}
+
+inline sal_Bool HTMLTableCell::GetNumFmt( sal_uInt32& rNumFmt ) const
+{
+ rNumFmt = nNumFmt;
+ return bHasNumFmt;
+}
+
+inline sal_Bool HTMLTableCell::GetValue( double& rValue ) const
+{
+ rValue = nValue;
+ return bHasValue;
+}
+
+SwHTMLTableLayoutCell *HTMLTableCell::CreateLayoutInfo()
+{
+ SwHTMLTableLayoutCnts *pCntInfo = pContents ? pContents->CreateLayoutInfo() : 0;
+
+ return new SwHTMLTableLayoutCell( pCntInfo, nRowSpan, nColSpan, nWidth,
+ bRelWidth, bNoWrap );
+}
+
+/* */
+
+HTMLTableRow::HTMLTableRow( sal_uInt16 nCells ):
+ pCells(new HTMLTableCells),
+ bIsEndOfGroup(sal_False),
+ bSplitable( sal_False ),
+ nHeight(0),
+ nEmptyRows(0),
+ eAdjust(SVX_ADJUST_END),
+ eVertOri(text::VertOrientation::TOP),
+ pBGBrush(0),
+ bBottomBorder(sal_False)
+{
+ for( sal_uInt16 i=0; i<nCells; i++ )
+ {
+ pCells->Insert( new HTMLTableCell, pCells->Count() );
+ }
+
+ ASSERT( nCells==pCells->Count(),
+ "Zellenzahl in neuer HTML-Tabellenzeile stimmt nicht" );
+}
+
+HTMLTableRow::~HTMLTableRow()
+{
+ delete pCells;
+ delete pBGBrush;
+}
+
+inline void HTMLTableRow::SetHeight( sal_uInt16 nHght )
+{
+ if( nHght > nHeight )
+ nHeight = nHght;
+}
+
+inline HTMLTableCell *HTMLTableRow::GetCell( sal_uInt16 nCell ) const
+{
+ ASSERT( nCell<pCells->Count(),
+ "ungueltiger Zellen-Index in HTML-Tabellenzeile" );
+ return (*pCells)[nCell];
+}
+
+void HTMLTableRow::Expand( sal_uInt16 nCells, sal_Bool bOneCell )
+{
+ // die Zeile wird mit einer einzigen Zelle aufgefuellt, wenn
+ // bOneCell gesetzt ist. Das geht, nur fuer Zeilen, in die keine
+ // Zellen mehr eingefuegt werden!
+
+ sal_uInt16 nColSpan = nCells-pCells->Count();
+ for( sal_uInt16 i=pCells->Count(); i<nCells; i++ )
+ {
+ HTMLTableCell *pCell = new HTMLTableCell;
+ if( bOneCell )
+ pCell->SetColSpan( nColSpan );
+
+ pCells->Insert( pCell, pCells->Count() );
+ nColSpan--;
+ }
+
+ ASSERT( nCells==pCells->Count(),
+ "Zellenzahl in expandierter HTML-Tabellenzeile stimmt nicht" );
+}
+
+void HTMLTableRow::Shrink( sal_uInt16 nCells )
+{
+ ASSERT( nCells < pCells->Count(), "Anzahl Zellen falsch" );
+
+#ifdef DBG_UTIL
+ sal_uInt16 nEnd = pCells->Count();
+#endif
+ // The colspan of empty cells at the end has to be fixed to the new
+ // number of cells.
+ sal_uInt16 i=nCells;
+ while( i )
+ {
+ HTMLTableCell *pCell = (*pCells)[--i];
+ if( !pCell->GetContents() )
+ {
+ ASSERT( pCell->GetColSpan() == nEnd - i,
+ "invalid col span for empty cell at row end" );
+ pCell->SetColSpan( nCells-i);
+ }
+ else
+ break;
+ }
+#ifdef DBG_UTIL
+ for( i=nCells; i<nEnd; i++ )
+ {
+ HTMLTableCell *pCell = (*pCells)[i];
+ ASSERT( pCell->GetRowSpan() == 1,
+ "RowSpan von zu loesender Zelle ist falsch" );
+ ASSERT( pCell->GetColSpan() == nEnd - i,
+ "ColSpan von zu loesender Zelle ist falsch" );
+ ASSERT( !pCell->GetContents(), "Zu loeschende Zelle hat Inhalt" );
+ }
+#endif
+
+ pCells->DeleteAndDestroy( nCells, pCells->Count()-nCells );
+}
+
+/* */
+
+HTMLTableColumn::HTMLTableColumn():
+ bIsEndOfGroup(sal_False),
+ nWidth(0), bRelWidth(sal_False),
+ eAdjust(SVX_ADJUST_END), eVertOri(text::VertOrientation::TOP),
+ bLeftBorder(sal_False)
+{
+ for( sal_uInt16 i=0; i<6; i++ )
+ aFrmFmts[i] = 0;
+}
+
+inline void HTMLTableColumn::SetWidth( sal_uInt16 nWdth, sal_Bool bRelWdth )
+{
+ if( bRelWidth==bRelWdth )
+ {
+ if( nWdth > nWidth )
+ nWidth = nWdth;
+ }
+ else
+ nWidth = nWdth;
+ bRelWidth = bRelWdth;
+}
+
+inline SwHTMLTableLayoutColumn *HTMLTableColumn::CreateLayoutInfo()
+{
+ return new SwHTMLTableLayoutColumn( nWidth, bRelWidth, bLeftBorder );
+}
+
+inline sal_uInt16 HTMLTableColumn::GetFrmFmtIdx( sal_Bool bBorderLine,
+ sal_Int16 eVertOrient ) const
+{
+ ASSERT( text::VertOrientation::TOP != eVertOrient, "Top ist nicht erlaubt" );
+ sal_uInt16 n = bBorderLine ? 3 : 0;
+ switch( eVertOrient )
+ {
+ case text::VertOrientation::CENTER: n+=1; break;
+ case text::VertOrientation::BOTTOM: n+=2; break;
+ default:
+ ;
+ }
+ return n;
+}
+
+inline void HTMLTableColumn::SetFrmFmt( SwFrmFmt *pFmt, sal_Bool bBorderLine,
+ sal_Int16 eVertOrient )
+{
+ aFrmFmts[GetFrmFmtIdx(bBorderLine,eVertOrient)] = pFmt;
+}
+
+inline SwFrmFmt *HTMLTableColumn::GetFrmFmt( sal_Bool bBorderLine,
+ sal_Int16 eVertOrient ) const
+{
+ return aFrmFmts[GetFrmFmtIdx(bBorderLine,eVertOrient)];
+}
+
+/* */
+
+
+void HTMLTable::InitCtor( const HTMLTableOptions *pOptions )
+{
+ pResizeDrawObjs = 0;
+ pDrawObjPrcWidths = 0;
+
+ pRows = new HTMLTableRows;
+ pColumns = new HTMLTableColumns;
+ nRows = 0;
+ nCurRow = 0; nCurCol = 0;
+
+ pBox1 = 0;
+ pBoxFmt = 0; pLineFmt = 0;
+ pLineFrmFmtNoHeight = 0;
+ pInhBGBrush = 0;
+
+ pPrevStNd = 0;
+ pSwTable = 0;
+
+ bTopBorder = sal_False; bRightBorder = sal_False;
+ bTopAlwd = sal_True; bRightAlwd = sal_True;
+ bFillerTopBorder = sal_False; bFillerBottomBorder = sal_False;
+ bInhLeftBorder = sal_False; bInhRightBorder = sal_False;
+ bBordersSet = sal_False;
+ bForceFrame = sal_False;
+ nHeadlineRepeat = 0;
+
+ nLeftMargin = 0;
+ nRightMargin = 0;
+
+ const Color& rBorderColor = pOptions->aBorderColor;
+
+ long nBorderOpt = (long)pOptions->nBorder;
+ long nPWidth = nBorderOpt==USHRT_MAX ? NETSCAPE_DFLT_BORDER
+ : nBorderOpt;
+ long nPHeight = nBorderOpt==USHRT_MAX ? 0 : nBorderOpt;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+
+ // nBorder gibt die Breite der Umrandung an, wie sie in die
+ // Breitenberechnung in Netscape einfliesst. Wenn pOption->nBorder
+ // == USHRT_MAX, wurde keine BORDER-Option angegeben. Trotzdem fliesst
+ // eine 1 Pixel breite Umrandung in die Breitenberechnung mit ein.
+ nBorder = (sal_uInt16)nPWidth;
+ if( nBorderOpt==USHRT_MAX )
+ nPWidth = 0;
+
+ // HACK: ein Pixel-breite Linien sollen zur Haarlinie werden, wenn
+ // wir mit doppelter Umrandung arbeiten
+ if( pOptions->nCellSpacing!=0 && nBorderOpt==1 )
+ {
+ nPWidth = 1;
+ nPHeight = 1;
+ }
+
+ SvxCSS1Parser::SetBorderWidth( aTopBorderLine, (sal_uInt16)nPHeight,
+ pOptions->nCellSpacing!=0, sal_True );
+ aTopBorderLine.SetColor( rBorderColor );
+ aBottomBorderLine = aTopBorderLine;
+
+ if( nPWidth == nPHeight )
+ {
+ aLeftBorderLine = aTopBorderLine;
+ }
+ else
+ {
+ SvxCSS1Parser::SetBorderWidth( aLeftBorderLine, (sal_uInt16)nPWidth,
+ pOptions->nCellSpacing!=0, sal_True );
+ aLeftBorderLine.SetColor( rBorderColor );
+ }
+ aRightBorderLine = aLeftBorderLine;
+
+ if( pOptions->nCellSpacing != 0 )
+ {
+ aBorderLine.SetOutWidth( DEF_DOUBLE_LINE7_OUT );
+ aBorderLine.SetInWidth( DEF_DOUBLE_LINE7_IN );
+ aBorderLine.SetDistance( DEF_DOUBLE_LINE7_DIST );
+ }
+ else
+ {
+ aBorderLine.SetOutWidth( DEF_LINE_WIDTH_1 );
+ }
+ aBorderLine.SetColor( rBorderColor );
+
+ if( nCellPadding )
+ {
+ if( nCellPadding==USHRT_MAX )
+ nCellPadding = MIN_BORDER_DIST; // default
+ else
+ {
+ nCellPadding = pParser->ToTwips( nCellPadding );
+ if( nCellPadding<MIN_BORDER_DIST )
+ nCellPadding = MIN_BORDER_DIST;
+ }
+ }
+ if( nCellSpacing )
+ {
+ if( nCellSpacing==USHRT_MAX )
+ nCellSpacing = NETSCAPE_DFLT_CELLSPACING;
+ nCellSpacing = pParser->ToTwips( nCellSpacing );
+ }
+
+ nPWidth = pOptions->nHSpace;
+ nPHeight = pOptions->nVSpace;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ nHSpace = (sal_uInt16)nPWidth;
+ nVSpace = (sal_uInt16)nPHeight;
+
+ bColSpec = sal_False;
+
+ pBGBrush = pParser->CreateBrushItem(
+ pOptions->bBGColor ? &(pOptions->aBGColor) : 0,
+ pOptions->aBGImage, aEmptyStr, aEmptyStr, aEmptyStr );
+
+ pContext = 0;
+ pParentContents = 0;
+
+ aId = pOptions->aId;
+ aClass = pOptions->aClass;
+ aStyle = pOptions->aStyle;
+ aDir = pOptions->aDir;
+}
+
+HTMLTable::HTMLTable( SwHTMLParser* pPars, HTMLTable *pTopTab,
+ sal_Bool bParHead,
+ sal_Bool bHasParentSec, sal_Bool bTopTbl, sal_Bool bHasToFlw,
+ const HTMLTableOptions *pOptions ) :
+ nCols( pOptions->nCols ),
+ nFilledCols( 0 ),
+ nCellPadding( pOptions->nCellPadding ),
+ nCellSpacing( pOptions->nCellSpacing ),
+ nBoxes( 1 ),
+ pCaptionStartNode( 0 ),
+ bTableAdjustOfTag( pTopTab ? sal_False : pOptions->bTableAdjust ),
+ bIsParentHead( bParHead ),
+ bHasParentSection( bHasParentSec ),
+ bMakeTopSubTable( bTopTbl ),
+ bHasToFly( bHasToFlw ),
+ bFixedCols( pOptions->nCols>0 ),
+ bPrcWidth( pOptions->bPrcWidth ),
+ pParser( pPars ),
+ pTopTable( pTopTab ? pTopTab : this ),
+ pLayoutInfo( 0 ),
+ nWidth( pOptions->nWidth ),
+ nHeight( pTopTab ? 0 : pOptions->nHeight ),
+ eTableAdjust( pOptions->eAdjust ),
+ eVertOri( pOptions->eVertOri ),
+ eFrame( pOptions->eFrame ),
+ eRules( pOptions->eRules ),
+ bTopCaption( sal_False ),
+ bFirstCell( !pTopTab )
+{
+ InitCtor( pOptions );
+
+ for( sal_uInt16 i=0; i<nCols; i++ )
+ pColumns->Insert( new HTMLTableColumn, pColumns->Count() );
+}
+
+
+HTMLTable::~HTMLTable()
+{
+ delete pResizeDrawObjs;
+ delete pDrawObjPrcWidths;
+
+ delete pRows;
+ delete pColumns;
+ delete pBGBrush;
+ delete pInhBGBrush;
+
+ delete pContext;
+
+ // pLayoutInfo wurde entweder bereits geloescht oder muss aber es
+ // in den Besitz der SwTable uebergegangen.
+}
+
+SwHTMLTableLayout *HTMLTable::CreateLayoutInfo()
+{
+ sal_uInt16 nW = bPrcWidth ? nWidth : pParser->ToTwips( nWidth );
+
+ sal_uInt16 nBorderWidth = GetBorderWidth( aBorderLine, sal_True );
+ sal_uInt16 nLeftBorderWidth =
+ ((*pColumns)[0])->bLeftBorder ? GetBorderWidth( aLeftBorderLine, sal_True ) : 0;
+ sal_uInt16 nRightBorderWidth =
+ bRightBorder ? GetBorderWidth( aRightBorderLine, sal_True ) : 0;
+ sal_uInt16 nInhLeftBorderWidth = 0;
+ sal_uInt16 nInhRightBorderWidth = 0;
+
+ pLayoutInfo = new SwHTMLTableLayout(
+ pSwTable,
+ nRows, nCols, bFixedCols, bColSpec,
+ nW, bPrcWidth, nBorder, nCellPadding,
+ nCellSpacing, eTableAdjust,
+ nLeftMargin, nRightMargin,
+ nBorderWidth, nLeftBorderWidth, nRightBorderWidth,
+ nInhLeftBorderWidth, nInhRightBorderWidth );
+
+ sal_Bool bExportable = sal_True;
+ sal_uInt16 i;
+ for( i=0; i<nRows; i++ )
+ {
+ HTMLTableRow *pRow = (*pRows)[i];
+ for( sal_uInt16 j=0; j<nCols; j++ )
+ {
+ SwHTMLTableLayoutCell *pLayoutCell =
+ pRow->GetCell(j)->CreateLayoutInfo();
+
+ pLayoutInfo->SetCell( pLayoutCell, i, j );
+
+ if( bExportable )
+ {
+ SwHTMLTableLayoutCnts *pLayoutCnts =
+ pLayoutCell->GetContents();
+ bExportable = !pLayoutCnts ||
+ ( pLayoutCnts->GetStartNode() &&
+ !pLayoutCnts->GetNext() );
+ }
+ }
+ }
+
+ pLayoutInfo->SetExportable( bExportable );
+
+ for( i=0; i<nCols; i++ )
+ pLayoutInfo->SetColumn( ((*pColumns)[i])->CreateLayoutInfo(), i );
+
+ return pLayoutInfo;
+}
+
+inline void HTMLTable::SetCaption( const SwStartNode *pStNd, sal_Bool bTop )
+{
+ pCaptionStartNode = pStNd;
+ bTopCaption = bTop;
+}
+
+void HTMLTable::FixRowSpan( sal_uInt16 nRow, sal_uInt16 nCol,
+ const HTMLTableCnts *pCnts )
+{
+ sal_uInt16 nRowSpan=1;
+ HTMLTableCell *pCell;
+ while( ( pCell=GetCell(nRow,nCol), pCell->GetContents()==pCnts ) )
+ {
+ pCell->SetRowSpan( nRowSpan );
+ if( pLayoutInfo )
+ pLayoutInfo->GetCell(nRow,nCol)->SetRowSpan( nRowSpan );
+
+ if( !nRow ) break;
+ nRowSpan++; nRow--;
+ }
+}
+
+void HTMLTable::ProtectRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, sal_uInt16 nRowSpan )
+{
+ for( sal_uInt16 i=0; i<nRowSpan; i++ )
+ {
+ GetCell(nRow+i,nCol)->SetProtected();
+ if( pLayoutInfo )
+ pLayoutInfo->GetCell(nRow+i,nCol)->SetProtected();
+ }
+}
+
+
+// Suchen des SwStartNodes der letzten belegten Vorgaengerbox
+const SwStartNode* HTMLTable::GetPrevBoxStartNode( sal_uInt16 nRow, sal_uInt16 nCol ) const
+{
+ const HTMLTableCnts *pPrevCnts = 0;
+
+ if( 0==nRow )
+ {
+ // immer die Vorgaenger-Zelle
+ if( nCol>0 )
+ pPrevCnts = GetCell( 0, nCol-1 )->GetContents();
+ else
+ return pPrevStNd;
+ }
+ else if( USHRT_MAX==nRow && USHRT_MAX==nCol )
+ // der Contents der letzten Zelle
+ pPrevCnts = GetCell( nRows-1, nCols-1 )->GetContents();
+ else
+ {
+ sal_uInt16 i;
+ HTMLTableRow *pPrevRow = (*pRows)[nRow-1];
+
+ // evtl. eine Zelle in der aktuellen Zeile
+ i = nCol;
+ while( i )
+ {
+ i--;
+ if( 1 == pPrevRow->GetCell(i)->GetRowSpan() )
+ {
+ pPrevCnts = GetCell(nRow,i)->GetContents();
+ break;
+ }
+ }
+
+ // sonst die letzte gefuellte Zelle der Zeile davor suchen
+ if( !pPrevCnts )
+ {
+ i = nCols;
+ while( !pPrevCnts && i )
+ {
+ i--;
+ pPrevCnts = pPrevRow->GetCell(i)->GetContents();
+ }
+ }
+ }
+ ASSERT( pPrevCnts, "keine gefuellte Vorgaenger-Zelle gefunden" );
+ if( !pPrevCnts )
+ {
+ pPrevCnts = GetCell(0,0)->GetContents();
+ if( !pPrevCnts )
+ return pPrevStNd;
+ }
+
+ while( pPrevCnts->Next() )
+ pPrevCnts = pPrevCnts->Next();
+
+ return ( pPrevCnts->GetStartNode() ? pPrevCnts->GetStartNode()
+ : pPrevCnts->GetTable()->GetPrevBoxStartNode( USHRT_MAX, USHRT_MAX ) );
+}
+
+
+static sal_Bool IsBoxEmpty( const SwTableBox *pBox )
+{
+ const SwStartNode *pSttNd = pBox->GetSttNd();
+ if( pSttNd &&
+ pSttNd->GetIndex() + 2 == pSttNd->EndOfSectionIndex() )
+ {
+ const SwCntntNode *pCNd =
+ pSttNd->GetNodes()[pSttNd->GetIndex()+1]->GetCntntNode();
+ if( pCNd && !pCNd->Len() )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_uInt16 HTMLTable::GetTopCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
+ sal_Bool bSwBorders ) const
+{
+ sal_uInt16 nSpace = nCellPadding;
+
+ if( nRow == 0 )
+ {
+ nSpace += nBorder + nCellSpacing;
+ if( bSwBorders )
+ {
+ sal_uInt16 nTopBorderWidth =
+ GetBorderWidth( aTopBorderLine, sal_True );
+ if( nSpace < nTopBorderWidth )
+ nSpace = nTopBorderWidth;
+ }
+ }
+ else if( bSwBorders && ((*pRows)[nRow+nRowSpan-1])->bBottomBorder &&
+ nSpace < MIN_BORDER_DIST )
+ {
+ ASSERT( !nCellPadding, "GetTopCellSpace: CELLPADDING!=0" );
+ // Wenn die Gegenueberliegende Seite umrandet ist muessen
+ // wir zumindest den minimalen Abstand zum Inhalt
+ // beruecksichtigen. (Koennte man zusaetzlich auch an
+ // nCellPadding festmachen.)
+ nSpace = MIN_BORDER_DIST;
+ }
+
+ return nSpace;
+}
+
+sal_uInt16 HTMLTable::GetBottomCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
+ sal_Bool bSwBorders ) const
+{
+ sal_uInt16 nSpace = nCellSpacing + nCellPadding;
+
+ if( nRow+nRowSpan == nRows )
+ {
+ nSpace = nSpace + nBorder;
+
+ if( bSwBorders )
+ {
+ sal_uInt16 nBottomBorderWidth =
+ GetBorderWidth( aBottomBorderLine, sal_True );
+ if( nSpace < nBottomBorderWidth )
+ nSpace = nBottomBorderWidth;
+ }
+ }
+ else if( bSwBorders )
+ {
+ if( ((*pRows)[nRow+nRowSpan+1])->bBottomBorder )
+ {
+ sal_uInt16 nBorderWidth = GetBorderWidth( aBorderLine, sal_True );
+ if( nSpace < nBorderWidth )
+ nSpace = nBorderWidth;
+ }
+ else if( nRow==0 && bTopBorder && nSpace < MIN_BORDER_DIST )
+ {
+ ASSERT( GetBorderWidth( aTopBorderLine, sal_True ) > 0,
+ "GetBottomCellSpace: |aTopLine| == 0" );
+ ASSERT( !nCellPadding, "GetBottomCellSpace: CELLPADDING!=0" );
+ // Wenn die Gegenueberliegende Seite umrandet ist muessen
+ // wir zumindest den minimalen Abstand zum Inhalt
+ // beruecksichtigen. (Koennte man zusaetzlich auch an
+ // nCellPadding festmachen.)
+ nSpace = MIN_BORDER_DIST;
+ }
+ }
+
+ return nSpace;
+}
+
+void HTMLTable::FixFrameFmt( SwTableBox *pBox,
+ sal_uInt16 nRow, sal_uInt16 nCol,
+ sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
+ sal_Bool bFirstPara, sal_Bool bLastPara ) const
+{
+ SwFrmFmt *pFrmFmt = 0; // frame::Frame-Format
+ sal_Int16 eVOri = text::VertOrientation::NONE;
+ const SvxBrushItem *pBGBrushItem = 0; // Hintergrund
+ sal_Bool bTopLine = sal_False, bBottomLine = sal_False, bLastBottomLine = sal_False;
+ sal_Bool bReUsable = sal_False; // Format nochmals verwendbar?
+ sal_uInt16 nEmptyRows = 0;
+ sal_Bool bHasNumFmt = sal_False;
+ sal_Bool bHasValue = sal_False;
+ sal_uInt32 nNumFmt = 0;
+ double nValue = 0.0;
+
+ HTMLTableColumn *pColumn = (*pColumns)[nCol];
+
+ if( pBox->GetSttNd() )
+ {
+ // die Hintergrundfarbe/-grafik bestimmen
+ const HTMLTableCell *pCell = GetCell( nRow, nCol );
+ pBGBrushItem = pCell->GetBGBrush();
+ if( !pBGBrushItem )
+ {
+ // Wenn die Zelle ueber mehrere Zeilen geht muss ein evtl.
+ // an der Zeile gesetzter Hintergrund an die Zelle uebernommen
+ // werden.
+#ifndef FIX56334
+ // Wenn es sich um eine Tabelle in der Tabelle handelt und
+ // die Zelle ueber die gesamte Heoehe der Tabelle geht muss
+ // ebenfalls der Hintergrund der Zeile uebernommen werden, weil
+ // die Line von der GC (zu Recht) wegoptimiert wird.
+ if( nRowSpan > 1 || (this != pTopTable && nRowSpan==nRows) )
+#else
+ if( nRowSpan > 1 )
+#endif
+ {
+ pBGBrushItem = ((*pRows)[nRow])->GetBGBrush();
+ if( !pBGBrushItem && this != pTopTable )
+ {
+ pBGBrushItem = GetBGBrush();
+ if( !pBGBrushItem )
+ pBGBrushItem = GetInhBGBrush();
+ }
+ }
+ }
+
+ bTopLine = 0==nRow && bTopBorder && bFirstPara;
+ if( ((*pRows)[nRow+nRowSpan-1])->bBottomBorder && bLastPara )
+ {
+ nEmptyRows = ((*pRows)[nRow+nRowSpan-1])->GetEmptyRows();
+ if( nRow+nRowSpan == nRows )
+ bLastBottomLine = sal_True;
+ else
+ bBottomLine = sal_True;
+ }
+
+ eVOri = pCell->GetVertOri();
+ bHasNumFmt = pCell->GetNumFmt( nNumFmt );
+ if( bHasNumFmt )
+ bHasValue = pCell->GetValue( nValue );
+
+ if( nColSpan==1 && !bTopLine && !bLastBottomLine && !nEmptyRows &&
+ !pBGBrushItem && !bHasNumFmt )
+ {
+ pFrmFmt = pColumn->GetFrmFmt( bBottomLine, eVOri );
+ bReUsable = !pFrmFmt;
+ }
+ }
+
+ if( !pFrmFmt )
+ {
+ pFrmFmt = pBox->ClaimFrmFmt();
+
+ // die Breite der Box berechnen
+ SwTwips nFrmWidth = (SwTwips)pLayoutInfo->GetColumn(nCol)
+ ->GetRelColWidth();
+ for( sal_uInt16 i=1; i<nColSpan; i++ )
+ nFrmWidth += (SwTwips)pLayoutInfo->GetColumn(nCol+i)
+ ->GetRelColWidth();
+
+ // die Umrandung nur an Edit-Boxen setzen (bei der oberen und unteren
+ // Umrandung muss beruecks. werden, ob es sich um den ersten oder
+ // letzen Absatz der Zelle handelt)
+ if( pBox->GetSttNd() )
+ {
+ sal_Bool bSet = (nCellPadding > 0);
+
+ SvxBoxItem aBoxItem( RES_BOX );
+ long nInnerFrmWidth = nFrmWidth;
+
+ if( bTopLine )
+ {
+ aBoxItem.SetLine( &aTopBorderLine, BOX_LINE_TOP );
+ bSet = sal_True;
+ }
+ if( bLastBottomLine )
+ {
+ aBoxItem.SetLine( &aBottomBorderLine, BOX_LINE_BOTTOM );
+ bSet = sal_True;
+ }
+ else if( bBottomLine )
+ {
+ if( nEmptyRows && !aBorderLine.GetInWidth() )
+ {
+ // Leere Zeilen koennen zur Zeit nur dann ueber
+ // dicke Linien simuliert werden, wenn die Linie
+ // einfach ist.
+ SvxBorderLine aThickBorderLine( aBorderLine );
+
+ sal_uInt16 nBorderWidth = aBorderLine.GetOutWidth();
+ nBorderWidth *= (nEmptyRows + 1);
+ SvxCSS1Parser::SetBorderWidth( aThickBorderLine,
+ nBorderWidth, sal_False );
+ aBoxItem.SetLine( &aThickBorderLine, BOX_LINE_BOTTOM );
+ }
+ else
+ {
+ aBoxItem.SetLine( &aBorderLine, BOX_LINE_BOTTOM );
+ }
+ bSet = sal_True;
+ }
+ if( ((*pColumns)[nCol])->bLeftBorder )
+ {
+ const SvxBorderLine& rBorderLine =
+ 0==nCol ? aLeftBorderLine : aBorderLine;
+ aBoxItem.SetLine( &rBorderLine, BOX_LINE_LEFT );
+ nInnerFrmWidth -= GetBorderWidth( rBorderLine );
+ bSet = sal_True;
+ }
+ if( nCol+nColSpan == nCols && bRightBorder )
+ {
+ aBoxItem.SetLine( &aRightBorderLine, BOX_LINE_RIGHT );
+ nInnerFrmWidth -= GetBorderWidth( aRightBorderLine );
+ bSet = sal_True;
+ }
+
+ if( bSet )
+ {
+ // fix #30588#: BorderDist nicht mehr Bestandteil
+ // einer Zelle mit fixer Breite
+ sal_uInt16 nBDist = static_cast< sal_uInt16 >(
+ (2*nCellPadding <= nInnerFrmWidth) ? nCellPadding
+ : (nInnerFrmWidth / 2) );
+ // wir setzen das Item nur, wenn es eine Umrandung gibt
+ // oder eine sheet::Border-Distanz vorgegeben ist. Fehlt letztere,
+ // dann gibt es eine Umrandung, und wir muessen die Distanz
+ // setzen
+ aBoxItem.SetDistance( nBDist ? nBDist : MIN_BORDER_DIST );
+ pFrmFmt->SetFmtAttr( aBoxItem );
+ }
+ else
+ pFrmFmt->ResetFmtAttr( RES_BOX );
+
+ if( pBGBrushItem )
+ {
+ pFrmFmt->SetFmtAttr( *pBGBrushItem );
+ }
+ else
+ pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
+
+ // fix #41003#: Format nur setzten, wenn es auch einen Value
+ // gibt oder die Box leer ist.
+ if( bHasNumFmt && (bHasValue || IsBoxEmpty(pBox)) )
+ {
+ sal_Bool bLock = pFrmFmt->GetDoc()->GetNumberFormatter()
+ ->IsTextFormat( nNumFmt );
+ SfxItemSet aItemSet( *pFrmFmt->GetAttrSet().GetPool(),
+ RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
+ SvxAdjust eAdjust = SVX_ADJUST_END;
+ SwCntntNode *pCNd = 0;
+ if( !bLock )
+ {
+ const SwStartNode *pSttNd = pBox->GetSttNd();
+ pCNd = pSttNd->GetNodes()[pSttNd->GetIndex()+1]
+ ->GetCntntNode();
+ const SfxPoolItem *pItem;
+ if( pCNd && pCNd->HasSwAttrSet() &&
+ SFX_ITEM_SET==pCNd->GetpSwAttrSet()->GetItemState(
+ RES_PARATR_ADJUST, sal_False, &pItem ) )
+ {
+ eAdjust = ((const SvxAdjustItem *)pItem)
+ ->GetAdjust();
+ }
+ }
+ aItemSet.Put( SwTblBoxNumFormat(nNumFmt) );
+ if( bHasValue )
+ aItemSet.Put( SwTblBoxValue(nValue) );
+
+ if( bLock )
+ pFrmFmt->LockModify();
+ pFrmFmt->SetFmtAttr( aItemSet );
+ if( bLock )
+ pFrmFmt->UnlockModify();
+ else if( pCNd && SVX_ADJUST_END != eAdjust )
+ {
+ SvxAdjustItem aAdjItem( eAdjust, RES_PARATR_ADJUST );
+ pCNd->SetAttr( aAdjItem );
+ }
+ }
+ else
+ pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
+
+ ASSERT( eVOri != text::VertOrientation::TOP, "text::VertOrientation::TOP ist nicht erlaubt!" );
+ if( text::VertOrientation::NONE != eVOri )
+ {
+ pFrmFmt->SetFmtAttr( SwFmtVertOrient( 0, eVOri ) );
+ }
+ else
+ pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
+
+ if( bReUsable )
+ pColumn->SetFrmFmt( pFrmFmt, bBottomLine, eVOri );
+ }
+ else
+ {
+ pFrmFmt->ResetFmtAttr( RES_BOX );
+ pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
+ pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
+ pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
+ }
+ }
+ else
+ {
+ ASSERT( pBox->GetSttNd() ||
+ SFX_ITEM_SET!=pFrmFmt->GetAttrSet().GetItemState(
+ RES_VERT_ORIENT, sal_False ),
+ "Box ohne Inhalt hat vertikale Ausrichtung" );
+ pBox->ChgFrmFmt( (SwTableBoxFmt*)pFrmFmt );
+ }
+
+}
+
+void HTMLTable::FixFillerFrameFmt( SwTableBox *pBox, sal_Bool bRight ) const
+{
+ SwFrmFmt *pFrmFmt = pBox->ClaimFrmFmt();
+
+ if( bFillerTopBorder || bFillerBottomBorder ||
+ (!bRight && bInhLeftBorder) || (bRight && bInhRightBorder) )
+ {
+ SvxBoxItem aBoxItem( RES_BOX );
+ if( bFillerTopBorder )
+ aBoxItem.SetLine( &aTopBorderLine, BOX_LINE_TOP );
+ if( bFillerBottomBorder )
+ aBoxItem.SetLine( &aBottomBorderLine, BOX_LINE_BOTTOM );
+ if( !bRight && bInhLeftBorder )
+ aBoxItem.SetLine( &aInhLeftBorderLine, BOX_LINE_LEFT );
+ if( bRight && bInhRightBorder )
+ aBoxItem.SetLine( &aInhRightBorderLine, BOX_LINE_RIGHT );
+ aBoxItem.SetDistance( MIN_BORDER_DIST );
+ pFrmFmt->SetFmtAttr( aBoxItem );
+ }
+ else
+ {
+ pFrmFmt->ResetFmtAttr( RES_BOX );
+ }
+
+ if( GetInhBGBrush() )
+ pFrmFmt->SetFmtAttr( *GetInhBGBrush() );
+ else
+ pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
+
+ pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
+ pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
+}
+
+SwTableBox *HTMLTable::NewTableBox( const SwStartNode *pStNd,
+ SwTableLine *pUpper ) const
+{
+ SwTableBox *pBox;
+
+ if( pTopTable->pBox1 &&
+ pTopTable->pBox1->GetSttNd() == pStNd )
+ {
+ // wenn der StartNode dem StartNode der initial angelegten Box
+ // entspricht nehmen wir diese Box
+ pBox = pTopTable->pBox1;
+ pBox->SetUpper( pUpper );
+ pTopTable->pBox1 = 0;
+ }
+ else
+ pBox = new SwTableBox( pBoxFmt, *pStNd, pUpper );
+
+ return pBox;
+}
+
+
+static void ResetLineFrmFmtAttrs( SwFrmFmt *pFrmFmt )
+{
+ pFrmFmt->ResetFmtAttr( RES_FRM_SIZE );
+ pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
+ ASSERT( SFX_ITEM_SET!=pFrmFmt->GetAttrSet().GetItemState(
+ RES_VERT_ORIENT, sal_False ),
+ "Zeile hat vertikale Ausrichtung" );
+}
+
+// !!! kann noch vereinfacht werden
+SwTableLine *HTMLTable::MakeTableLine( SwTableBox *pUpper,
+ sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
+ sal_uInt16 nBottomRow, sal_uInt16 nRightCol )
+{
+ SwTableLine *pLine;
+ if( this==pTopTable && !pUpper && 0==nTopRow )
+ pLine = (pSwTable->GetTabLines())[0];
+ else
+ pLine = new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
+ : pLineFmt,
+ 0, pUpper );
+
+ HTMLTableRow *pTopRow = (*pRows)[nTopRow];
+ sal_uInt16 nRowHeight = pTopRow->GetHeight();
+ const SvxBrushItem *pBGBrushItem = 0;
+#ifndef FIX56334
+ if( this == pTopTable || nTopRow>0 || nBottomRow<nRows )
+ {
+ // An der Line eine Frabe zu setzen macht keinen Sinn, wenn sie
+ // die auesserste und gleichzeitig einzige Zeile einer Tabelle in
+ // der Tabelle ist.
+#endif
+ pBGBrushItem = pTopRow->GetBGBrush();
+
+ if( !pBGBrushItem && this != pTopTable )
+ {
+ // Ein an einer Tabellen in der Tabelle gesetzter Hintergrund
+ // wird an den Rows gesetzt. Das gilt auch fuer den Hintergrund
+ // der Zelle, in dem die Tabelle vorkommt.
+ pBGBrushItem = GetBGBrush();
+ if( !pBGBrushItem )
+ pBGBrushItem = GetInhBGBrush();
+ }
+#ifndef FIX56334
+ }
+#endif
+ if( nTopRow==nBottomRow-1 && (nRowHeight || pBGBrushItem) )
+ {
+ SwTableLineFmt *pFrmFmt = (SwTableLineFmt*)pLine->ClaimFrmFmt();
+ ResetLineFrmFmtAttrs( pFrmFmt );
+
+ if( nRowHeight )
+ {
+ // Tabellenhoehe einstellen. Da es sich um eine
+ // Mindesthoehe handelt, kann sie genauso wie in
+ // Netscape berechnet werden, also ohne Beruecksichtigung
+ // der tatsaechlichen Umrandungsbreite.
+ nRowHeight += GetTopCellSpace( nTopRow, 1, sal_False ) +
+ GetBottomCellSpace( nTopRow, 1, sal_False );
+
+ pFrmFmt->SetFmtAttr( SwFmtFrmSize( ATT_MIN_SIZE, 0, nRowHeight ) );
+ }
+
+ if( pBGBrushItem )
+ {
+ pFrmFmt->SetFmtAttr( *pBGBrushItem );
+ }
+
+ }
+ else if( !pLineFrmFmtNoHeight )
+ {
+ // sonst muessen wir die Hoehe aus dem Attribut entfernen
+ // und koennen uns das Format merken
+ pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
+
+ ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
+ }
+
+
+ SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+
+ sal_uInt16 nStartCol = nLeftCol;
+ while( nStartCol<nRightCol )
+ {
+ sal_uInt16 nCol = nStartCol;
+ sal_uInt16 nSplitCol = nRightCol;
+ sal_Bool bSplitted = sal_False;
+ while( !bSplitted )
+ {
+ ASSERT( nCol < nRightCol, "Zu weit gelaufen" );
+
+ HTMLTableCell *pCell = GetCell(nTopRow,nCol);
+ const sal_Bool bSplit = 1 == pCell->GetColSpan();
+
+#ifdef DBG_UTIL
+ if( nCol == nRightCol-1 )
+ {
+ ASSERT( bSplit, "Split-Flag falsch" );
+ }
+#endif
+ if( bSplit )
+ {
+ SwTableBox* pBox = 0;
+ HTMLTableCell *pCell2 = GetCell( nTopRow, nStartCol );
+ if( pCell2->GetColSpan() == (nCol+1-nStartCol) )
+ {
+ // Die HTML-Tabellen-Zellen bilden genau eine Box.
+ // Dann muss hinter der Box gesplittet werden
+ nSplitCol = nCol + 1;
+
+ long nBoxRowSpan = pCell2->GetRowSpan();
+ if ( !pCell2->GetContents() || pCell2->IsCovered() )
+ {
+ if ( pCell2->IsCovered() )
+ nBoxRowSpan = -1 * nBoxRowSpan;
+
+ const SwStartNode* pPrevStartNd =
+ GetPrevBoxStartNode( nTopRow, nStartCol );
+ HTMLTableCnts *pCnts = new HTMLTableCnts(
+ pParser->InsertTableSection(pPrevStartNd) );
+ SwHTMLTableLayoutCnts *pCntsLayoutInfo =
+ pCnts->CreateLayoutInfo();
+
+ pCell2->SetContents( pCnts );
+ SwHTMLTableLayoutCell *pCurrCell = pLayoutInfo->GetCell( nTopRow, nStartCol );
+ pCurrCell->SetContents( pCntsLayoutInfo );
+ if( nBoxRowSpan < 0 )
+ pCurrCell->SetRowSpan( 0 );
+
+ // ggf. COLSPAN beachten
+ for( sal_uInt16 j=nStartCol+1; j<nSplitCol; j++ )
+ {
+ GetCell(nTopRow,j)->SetContents( pCnts );
+ pLayoutInfo->GetCell( nTopRow, j )
+ ->SetContents( pCntsLayoutInfo );
+ }
+ }
+
+ pBox = MakeTableBox( pLine, pCell2->GetContents(),
+ nTopRow, nStartCol,
+ nBottomRow, nSplitCol );
+
+ if ( 1 != nBoxRowSpan )
+ pBox->setRowSpan( nBoxRowSpan );
+
+ bSplitted = sal_True;
+ }
+
+ ASSERT( pBox, "Colspan trouble" )
+
+ if( pBox )
+ rBoxes.C40_INSERT( SwTableBox, pBox, rBoxes.Count() );
+ }
+ nCol++;
+ }
+ nStartCol = nSplitCol;
+ }
+
+ return pLine;
+}
+
+SwTableBox *HTMLTable::MakeTableBox( SwTableLine *pUpper,
+ HTMLTableCnts *pCnts,
+ sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
+ sal_uInt16 nBottomRow, sal_uInt16 nRightCol )
+{
+ SwTableBox *pBox;
+ sal_uInt16 nColSpan = nRightCol - nLeftCol;
+ sal_uInt16 nRowSpan = nBottomRow - nTopRow;
+
+ if( !pCnts->Next() )
+ {
+ // nur eine Inhalts-Section
+ if( pCnts->GetStartNode() )
+ {
+ // und die ist keine Tabelle
+ pBox = NewTableBox( pCnts->GetStartNode(), pUpper );
+ pCnts->SetTableBox( pBox );
+ }
+ else
+ {
+ pCnts->GetTable()->InheritVertBorders( this, nLeftCol,
+ nRightCol-nLeftCol );
+ // und die ist eine Tabelle: dann bauen wir eine neue
+ // Box und fuegen die Zeilen der Tabelle in die Zeilen
+ // der Box ein
+ pBox = new SwTableBox( pBoxFmt, 0, pUpper );
+ sal_uInt16 nAbs, nRel;
+ pLayoutInfo->GetAvail( nLeftCol, nColSpan, nAbs, nRel );
+ sal_uInt16 nLSpace = pLayoutInfo->GetLeftCellSpace( nLeftCol, nColSpan );
+ sal_uInt16 nRSpace = pLayoutInfo->GetRightCellSpace( nLeftCol, nColSpan );
+ sal_uInt16 nInhSpace = pLayoutInfo->GetInhCellSpace( nLeftCol, nColSpan );
+ pCnts->GetTable()->MakeTable( pBox, nAbs, nRel, nLSpace, nRSpace,
+ nInhSpace );
+ }
+ }
+ else
+ {
+ // mehrere Inhalts Sections: dann brauchen wir eine Box mit Zeilen
+ pBox = new SwTableBox( pBoxFmt, 0, pUpper );
+ SwTableLines& rLines = pBox->GetTabLines();
+ sal_Bool bFirstPara = sal_True;
+
+ while( pCnts )
+ {
+ if( pCnts->GetStartNode() )
+ {
+ // normale Absaetze werden zu einer Box in einer Zeile
+ SwTableLine *pLine =
+ new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
+ : pLineFmt, 0, pBox );
+ if( !pLineFrmFmtNoHeight )
+ {
+ // Wenn es noch kein Line-Format ohne Hoehe gibt, koennen
+ // wir uns dieses her als soleches merken
+ pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
+
+ ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
+ }
+
+ SwTableBox* pCntBox = NewTableBox( pCnts->GetStartNode(),
+ pLine );
+ pCnts->SetTableBox( pCntBox );
+ FixFrameFmt( pCntBox, nTopRow, nLeftCol, nRowSpan, nColSpan,
+ bFirstPara, 0==pCnts->Next() );
+ pLine->GetTabBoxes().C40_INSERT( SwTableBox, pCntBox,
+ pLine->GetTabBoxes().Count() );
+
+ rLines.C40_INSERT( SwTableLine, pLine, rLines.Count() );
+ }
+ else
+ {
+ pCnts->GetTable()->InheritVertBorders( this, nLeftCol,
+ nRightCol-nLeftCol );
+ // Tabellen werden direkt eingetragen
+ sal_uInt16 nAbs, nRel;
+ pLayoutInfo->GetAvail( nLeftCol, nColSpan, nAbs, nRel );
+ sal_uInt16 nLSpace = pLayoutInfo->GetLeftCellSpace( nLeftCol,
+ nColSpan );
+ sal_uInt16 nRSpace = pLayoutInfo->GetRightCellSpace( nLeftCol,
+ nColSpan );
+ sal_uInt16 nInhSpace = pLayoutInfo->GetInhCellSpace( nLeftCol, nColSpan );
+ pCnts->GetTable()->MakeTable( pBox, nAbs, nRel, nLSpace,
+ nRSpace, nInhSpace );
+ }
+
+ pCnts = pCnts->Next();
+ bFirstPara = sal_False;
+ }
+ }
+
+ FixFrameFmt( pBox, nTopRow, nLeftCol, nRowSpan, nColSpan );
+
+ return pBox;
+}
+
+void HTMLTable::InheritBorders( const HTMLTable *pParent,
+ sal_uInt16 nRow, sal_uInt16 nCol,
+ sal_uInt16 nRowSpan, sal_uInt16 /*nColSpan*/,
+ sal_Bool bFirstPara, sal_Bool bLastPara )
+{
+ ASSERT( nRows>0 && nCols>0 && nCurRow==nRows,
+ "Wurde CloseTable nicht aufgerufen?" );
+
+ // Die Child-Tabelle muss einen Rahmen bekommen, wenn die umgebende
+ // Zelle einen Rand an der betreffenden Seite besitzt.
+ // Der obere bzw. untere Rand wird nur gesetzt, wenn die Tabelle
+ // ale erster bzw. letzter Absatz in der Zelle vorkommt. Ansonsten
+ // Fuer den linken/rechten Rand kann noch nicht entschieden werden,
+ // ob eine Umrandung der Tabelle noetig/moeglich ist, weil das davon
+ // abhaengt, ob "Filler"-Zellen eingefuegt werden. Hier werden deshalb
+ // erstmal nur Informationen gesammelt
+ //
+ if( 0==nRow && pParent->bTopBorder && bFirstPara )
+ {
+ bTopBorder = sal_True;
+ bFillerTopBorder = sal_True; // auch Filler bekommt eine Umrandung
+ aTopBorderLine = pParent->aTopBorderLine;
+ }
+ if( ((*pParent->pRows)[nRow+nRowSpan-1])->bBottomBorder && bLastPara )
+ {
+ ((*pRows)[nRows-1])->bBottomBorder = sal_True;
+ bFillerBottomBorder = sal_True; // auch Filler bekommt eine Umrandung
+ aBottomBorderLine =
+ nRow+nRowSpan==pParent->nRows ? pParent->aBottomBorderLine
+ : pParent->aBorderLine;
+ }
+
+
+ // Die Child Tabelle darf keinen oberen oder linken Rahmen bekommen,
+ // wenn der bereits durch die umgebende Tabelle gesetzt ist.
+ // Sie darf jedoch immer einen oberen Rand bekommen, wenn die Tabelle
+ // nicht der erste Absatz in der Zelle ist.
+ bTopAlwd = ( !bFirstPara || (pParent->bTopAlwd &&
+ (0==nRow || !((*pParent->pRows)[nRow-1])->bBottomBorder)) );
+
+ // die Child-Tabelle muss die Farbe der Zelle erben, in der sie
+ // vorkommt, wenn sie keine eigene besitzt
+ const SvxBrushItem *pInhBG = pParent->GetCell(nRow,nCol)->GetBGBrush();
+ if( !pInhBG && pParent != pTopTable &&
+ pParent->GetCell(nRow,nCol)->GetRowSpan() == pParent->nRows )
+ {
+ // die ganze umgebende Tabelle ist eine Tabelle in der Tabelle
+ // und besteht nur aus einer Line, die bei der GC (zu Recht)
+ // wegoptimiert wird. Deshalb muss der Hintergrund der Line in
+ // diese Tabelle uebernommen werden.
+ pInhBG = ((*pParent->pRows)[nRow])->GetBGBrush();
+ if( !pInhBG )
+ pInhBG = pParent->GetBGBrush();
+ if( !pInhBG )
+ pInhBG = pParent->GetInhBGBrush();
+ }
+ if( pInhBG )
+ pInhBGBrush = new SvxBrushItem( *pInhBG );
+}
+
+void HTMLTable::InheritVertBorders( const HTMLTable *pParent,
+ sal_uInt16 nCol, sal_uInt16 nColSpan )
+{
+ sal_uInt16 nInhLeftBorderWidth = 0;
+ sal_uInt16 nInhRightBorderWidth = 0;
+
+ if( nCol+nColSpan==pParent->nCols && pParent->bRightBorder )
+ {
+ bInhRightBorder = sal_True; // erstmal nur merken
+ aInhRightBorderLine = pParent->aRightBorderLine;
+ nInhRightBorderWidth =
+ GetBorderWidth( aInhRightBorderLine, sal_True ) + MIN_BORDER_DIST;
+ }
+
+ if( ((*pParent->pColumns)[nCol])->bLeftBorder )
+ {
+ bInhLeftBorder = sal_True; // erstmal nur merken
+ aInhLeftBorderLine = 0==nCol ? pParent->aLeftBorderLine
+ : pParent->aBorderLine;
+ nInhLeftBorderWidth =
+ GetBorderWidth( aInhLeftBorderLine, sal_True ) + MIN_BORDER_DIST;
+ }
+
+ if( !bInhLeftBorder && (bFillerTopBorder || bFillerBottomBorder) )
+ nInhLeftBorderWidth = 2 * MIN_BORDER_DIST;
+ if( !bInhRightBorder && (bFillerTopBorder || bFillerBottomBorder) )
+ nInhRightBorderWidth = 2 * MIN_BORDER_DIST;
+ pLayoutInfo->SetInhBorderWidths( nInhLeftBorderWidth,
+ nInhRightBorderWidth );
+
+ bRightAlwd = ( pParent->bRightAlwd &&
+ (nCol+nColSpan==pParent->nCols ||
+ !((*pParent->pColumns)[nCol+nColSpan])->bLeftBorder) );
+}
+
+void HTMLTable::SetBorders()
+{
+ sal_uInt16 i;
+ for( i=1; i<nCols; i++ )
+ if( HTML_TR_ALL==eRules || HTML_TR_COLS==eRules ||
+ ((HTML_TR_ROWS==eRules || HTML_TR_GROUPS==eRules) &&
+ ((*pColumns)[i-1])->IsEndOfGroup()) )
+ ((*pColumns)[i])->bLeftBorder = sal_True;
+
+ for( i=0; i<nRows-1; i++ )
+ if( HTML_TR_ALL==eRules || HTML_TR_ROWS==eRules ||
+ ((HTML_TR_COLS==eRules || HTML_TR_GROUPS==eRules) &&
+ ((*pRows)[i])->IsEndOfGroup()) )
+ ((*pRows)[i])->bBottomBorder = sal_True;
+
+ if( bTopAlwd && (HTML_TF_ABOVE==eFrame || HTML_TF_HSIDES==eFrame ||
+ HTML_TF_BOX==eFrame) )
+ bTopBorder = sal_True;
+ if( HTML_TF_BELOW==eFrame || HTML_TF_HSIDES==eFrame ||
+ HTML_TF_BOX==eFrame )
+ ((*pRows)[nRows-1])->bBottomBorder = sal_True;
+ if( /*bRightAlwd &&*/ (HTML_TF_RHS==eFrame || HTML_TF_VSIDES==eFrame ||
+ HTML_TF_BOX==eFrame) )
+ bRightBorder = sal_True;
+ if( HTML_TF_LHS==eFrame || HTML_TF_VSIDES==eFrame || HTML_TF_BOX==eFrame )
+ ((*pColumns)[0])->bLeftBorder = sal_True;
+
+ for( i=0; i<nRows; i++ )
+ {
+ HTMLTableRow *pRow = (*pRows)[i];
+ for( sal_uInt16 j=0; j<nCols; j++ )
+ {
+ HTMLTableCell *pCell = pRow->GetCell(j);
+ if( pCell->GetContents() )
+ {
+ HTMLTableCnts *pCnts = pCell->GetContents();
+ sal_Bool bFirstPara = sal_True;
+ while( pCnts )
+ {
+ HTMLTable *pTable = pCnts->GetTable();
+ if( pTable && !pTable->BordersSet() )
+ {
+ pTable->InheritBorders( this, i, j,
+ pCell->GetRowSpan(),
+ pCell->GetColSpan(),
+ bFirstPara,
+ 0==pCnts->Next() );
+ pTable->SetBorders();
+ }
+ bFirstPara = sal_False;
+ pCnts = pCnts->Next();
+ }
+ }
+ }
+ }
+
+ bBordersSet = sal_True;
+}
+
+sal_uInt16 HTMLTable::GetBorderWidth( const SvxBorderLine& rBLine,
+ sal_Bool bWithDistance ) const
+{
+ sal_uInt16 nBorderWidth = rBLine.GetOutWidth() + rBLine.GetInWidth() +
+ rBLine.GetDistance();
+ if( bWithDistance )
+ {
+ if( nCellPadding )
+ nBorderWidth = nBorderWidth + nCellPadding;
+ else if( nBorderWidth )
+ nBorderWidth = nBorderWidth + MIN_BORDER_DIST;
+ }
+
+ return nBorderWidth;
+}
+
+inline HTMLTableCell *HTMLTable::GetCell( sal_uInt16 nRow,
+ sal_uInt16 nCell ) const
+{
+ ASSERT( nRow<pRows->Count(),
+ "ungueltiger Zeilen-Index in HTML-Tabelle" );
+ return ((*pRows)[nRow])->GetCell( nCell );
+}
+
+
+
+SvxAdjust HTMLTable::GetInheritedAdjust() const
+{
+ SvxAdjust eAdjust = (nCurCol<nCols ? ((*pColumns)[nCurCol])->GetAdjust()
+ : SVX_ADJUST_END );
+ if( SVX_ADJUST_END==eAdjust )
+ eAdjust = ((*pRows)[nCurRow])->GetAdjust();
+
+ return eAdjust;
+}
+
+sal_Int16 HTMLTable::GetInheritedVertOri() const
+{
+ // text::VertOrientation::TOP ist der default!
+ sal_Int16 eVOri = ((*pRows)[nCurRow])->GetVertOri();
+ if( text::VertOrientation::TOP==eVOri && nCurCol<nCols )
+ eVOri = ((*pColumns)[nCurCol])->GetVertOri();
+ if( text::VertOrientation::TOP==eVOri )
+ eVOri = eVertOri;
+
+ ASSERT( eVertOri != text::VertOrientation::TOP, "text::VertOrientation::TOP ist nicht erlaubt!" );
+ return eVOri;
+}
+
+void HTMLTable::InsertCell( HTMLTableCnts *pCnts,
+ sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
+ sal_uInt16 nCellWidth, sal_Bool bRelWidth, sal_uInt16 nCellHeight,
+ sal_Int16 eVertOrient, SvxBrushItem *pBGBrushItem,
+ sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
+ sal_Bool bHasValue, double nValue, sal_Bool bNoWrap )
+{
+ if( !nRowSpan || (sal_uInt32)nCurRow + nRowSpan > USHRT_MAX )
+ nRowSpan = 1;
+
+ if( !nColSpan || (sal_uInt32)nCurCol + nColSpan > USHRT_MAX )
+ nColSpan = 1;
+
+ sal_uInt16 nColsReq = nCurCol + nColSpan; // benoetigte Spalten
+ sal_uInt16 nRowsReq = nCurRow + nRowSpan; // benoetigte Zeilen
+ sal_uInt16 i, j;
+
+ // falls wir mehr Spalten benoetigen als wir zur Zeit haben,
+ // muessen wir in allen Zeilen noch Zellen hinzufuegen
+ if( nCols < nColsReq )
+ {
+ for( i=nCols; i<nColsReq; i++ )
+ pColumns->Insert( new HTMLTableColumn, pColumns->Count() );
+ for( i=0; i<nRows; i++ )
+ ((*pRows)[i])->Expand( nColsReq, i<nCurRow );
+ nCols = nColsReq;
+ ASSERT( pColumns->Count()==nCols,
+ "Anzahl der Spalten nach Expandieren stimmt nicht" );
+ }
+ if( nColsReq > nFilledCols )
+ nFilledCols = nColsReq;
+
+ // falls wir mehr Zeilen benoetigen als wir zur Zeit haben,
+ // muessen wir noch neue Zeilen hinzufuegen
+ if( nRows < nRowsReq )
+ {
+ for( i=nRows; i<nRowsReq; i++ )
+ pRows->Insert( new HTMLTableRow(nCols), pRows->Count() );
+ nRows = nRowsReq;
+ ASSERT( nRows==pRows->Count(), "Zeilenzahl in Insert stimmt nicht" );
+ }
+
+ // Testen, ob eine Ueberschneidung vorliegt und diese
+ // gegebenfalls beseitigen
+ sal_uInt16 nSpanedCols = 0;
+ if( nCurRow>0 )
+ {
+ HTMLTableRow *pCurRow = (*pRows)[nCurRow];
+ for( i=nCurCol; i<nColsReq; i++ )
+ {
+ HTMLTableCell *pCell = pCurRow->GetCell(i);
+ if( pCell->GetContents() )
+ {
+ // Der Inhalt reicht von einer weiter oben stehenden Zelle
+ // hier herein. Inhalt und Farbe der Zelle sind deshalb in
+ // jedem Fall noch dort verankert und koennen deshalb
+ // ueberschrieben werden bzw. von ProtectRowSpan geloescht
+ // (Inhalt) oder kopiert (Farbe) werden.
+ nSpanedCols = i + pCell->GetColSpan();
+ FixRowSpan( nCurRow-1, i, pCell->GetContents() );
+ if( pCell->GetRowSpan() > nRowSpan )
+ ProtectRowSpan( nRowsReq, i,
+ pCell->GetRowSpan()-nRowSpan );
+ }
+ }
+ for( i=nColsReq; i<nSpanedCols; i++ )
+ {
+ // Auch diese Inhalte sind in jedem Fall nich in der Zeile
+ // darueber verankert.
+ HTMLTableCell *pCell = pCurRow->GetCell(i);
+ FixRowSpan( nCurRow-1, i, pCell->GetContents() );
+ ProtectRowSpan( nCurRow, i, pCell->GetRowSpan() );
+ }
+ }
+
+ // Fill the cells
+ for( i=nColSpan; i>0; i-- )
+ {
+ for( j=nRowSpan; j>0; j-- )
+ {
+ const bool bCovered = i != nColSpan || j != nRowSpan;
+ GetCell( nRowsReq-j, nColsReq-i )
+ ->Set( pCnts, j, i, eVertOrient, pBGBrushItem,
+ bHasNumFmt, nNumFmt, bHasValue, nValue, bNoWrap, bCovered );
+ }
+ }
+
+ Size aTwipSz( bRelWidth ? 0 : nCellWidth, nCellHeight );
+ if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
+ {
+ aTwipSz = Application::GetDefaultDevice()
+ ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
+ }
+
+ // die Breite nur in die erste Zelle setzen!
+ if( nCellWidth )
+ {
+ sal_uInt16 nTmp = bRelWidth ? nCellWidth : (sal_uInt16)aTwipSz.Width();
+ GetCell( nCurRow, nCurCol )->SetWidth( nTmp, bRelWidth );
+ }
+
+ // Ausserdem noch die Hoehe merken
+ if( nCellHeight && 1==nRowSpan )
+ {
+ if( nCellHeight < MINLAY )
+ nCellHeight = MINLAY;
+ ((*pRows)[nCurRow])->SetHeight( (sal_uInt16)aTwipSz.Height() );
+ }
+
+ // den Spaltenzaehler hinter die neuen Zellen setzen
+ nCurCol = nColsReq;
+ if( nSpanedCols > nCurCol )
+ nCurCol = nSpanedCols;
+
+ // und die naechste freie Zelle suchen
+ while( nCurCol<nCols && GetCell(nCurRow,nCurCol)->IsUsed() )
+ nCurCol++;
+}
+
+inline void HTMLTable::CloseSection( sal_Bool bHead )
+{
+ // die vorhergende Section beenden, falls es schon eine Zeile gibt
+ ASSERT( nCurRow<=nRows, "ungeultige aktuelle Zeile" );
+ if( nCurRow>0 && nCurRow<=nRows )
+ ((*pRows)[nCurRow-1])->SetEndOfGroup();
+ if( bHead /*&& nCurRow==1*/ )
+// bHeadlineRepeat = sal_True;
+ nHeadlineRepeat = nCurRow;
+}
+
+void HTMLTable::OpenRow( SvxAdjust eAdjust, sal_Int16 eVertOrient,
+ SvxBrushItem *pBGBrushItem )
+{
+ sal_uInt16 nRowsReq = nCurRow+1; // Anzahl benoetigter Zeilen;
+
+ // die naechste Zeile anlegen, falls sie nicht schon da ist
+ if( nRows<nRowsReq )
+ {
+ for( sal_uInt16 i=nRows; i<nRowsReq; i++ )
+ pRows->Insert( new HTMLTableRow(nCols), pRows->Count() );
+ nRows = nRowsReq;
+ ASSERT( nRows==pRows->Count(),
+ "Zeilenzahl in OpenRow stimmt nicht" );
+ }
+
+ HTMLTableRow *pCurRow = ((*pRows)[nCurRow]);
+ pCurRow->SetAdjust( eAdjust );
+ pCurRow->SetVertOri( eVertOrient );
+ if( pBGBrushItem )
+ ((*pRows)[nCurRow])->SetBGBrush( pBGBrushItem );
+
+ // den Spaltenzaehler wieder an den Anfang setzen
+ nCurCol=0;
+
+ // und die naechste freie Zelle suchen
+ while( nCurCol<nCols && GetCell(nCurRow,nCurCol)->IsUsed() )
+ nCurCol++;
+}
+
+void HTMLTable::CloseRow( sal_Bool bEmpty )
+{
+ ASSERT( nCurRow<nRows, "aktulle Zeile hinter dem Tabellenende" );
+
+ // leere Zellen bekommen einfach einen etwas dickeren unteren Rand!
+ if( bEmpty )
+ {
+ if( nCurRow > 0 )
+ ((*pRows)[nCurRow-1])->IncEmptyRows();
+ return;
+ }
+
+ HTMLTableRow *pRow = (*pRows)[nCurRow];
+
+ // den COLSPAN aller leeren Zellen am Zeilenende so anpassen, dass
+ // eine Zelle daraus wird. Das kann man hier machen (und auf keinen
+ // Fall frueher), weill jetzt keine Zellen mehr in die Zeile eingefuegt
+ // werden.
+ sal_uInt16 i=nCols;
+ while( i )
+ {
+ HTMLTableCell *pCell = pRow->GetCell(--i);
+ if( !pCell->GetContents() )
+ {
+ sal_uInt16 nColSpan = nCols-i;
+ if( nColSpan > 1 )
+ pCell->SetColSpan( nColSpan );
+ }
+ else
+ break;
+ }
+
+
+ nCurRow++;
+}
+
+inline void HTMLTable::CloseColGroup( sal_uInt16 nSpan, sal_uInt16 _nWidth,
+ sal_Bool bRelWidth, SvxAdjust eAdjust,
+ sal_Int16 eVertOrient )
+{
+ if( nSpan )
+ InsertCol( nSpan, _nWidth, bRelWidth, eAdjust, eVertOrient );
+
+ ASSERT( nCurCol<=nCols, "ungueltige Spalte" );
+ if( nCurCol>0 && nCurCol<=nCols )
+ ((*pColumns)[nCurCol-1])->SetEndOfGroup();
+}
+
+void HTMLTable::InsertCol( sal_uInt16 nSpan, sal_uInt16 nColWidth, sal_Bool bRelWidth,
+ SvxAdjust eAdjust, sal_Int16 eVertOrient )
+{
+ // --> OD, MIB 2004-11-08 #i35143# - no columns, if rows already exist.
+ if ( nRows > 0 )
+ return;
+ // <--
+
+ sal_uInt16 i;
+
+ if( !nSpan )
+ nSpan = 1;
+
+ sal_uInt16 nColsReq = nCurCol + nSpan; // benoetigte Spalten
+
+ if( nCols < nColsReq )
+ {
+ for( i=nCols; i<nColsReq; i++ )
+ pColumns->Insert( new HTMLTableColumn, pColumns->Count() );
+ nCols = nColsReq;
+ }
+
+ Size aTwipSz( bRelWidth ? 0 : nColWidth, 0 );
+ if( aTwipSz.Width() && Application::GetDefaultDevice() )
+ {
+ aTwipSz = Application::GetDefaultDevice()
+ ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
+ }
+
+ for( i=nCurCol; i<nColsReq; i++ )
+ {
+ HTMLTableColumn *pCol = (*pColumns)[i];
+ sal_uInt16 nTmp = bRelWidth ? nColWidth : (sal_uInt16)aTwipSz.Width();
+ pCol->SetWidth( nTmp, bRelWidth );
+ pCol->SetAdjust( eAdjust );
+ pCol->SetVertOri( eVertOrient );
+ }
+
+ bColSpec = sal_True;
+
+ nCurCol = nColsReq;
+}
+
+
+void HTMLTable::CloseTable()
+{
+ sal_uInt16 i;
+
+ // Die Anzahl der Tabellenzeilen richtet sich nur nach den
+ // <TR>-Elementen (d.h. nach nCurRow). Durch ROWSPAN aufgespannte
+ // Zeilen hinter Zeile nCurRow muessen wir deshalb loeschen
+ // und vor allem aber den ROWSPAN in den darueberliegenden Zeilen
+ // anpassen.
+ if( nRows>nCurRow )
+ {
+ HTMLTableRow *pPrevRow = (*pRows)[nCurRow-1];
+ HTMLTableCell *pCell;
+ for( i=0; i<nCols; i++ )
+ if( ( pCell=pPrevRow->GetCell(i), pCell->GetRowSpan() > 1 ) )
+ {
+ FixRowSpan( nCurRow-1, i, pCell->GetContents() );
+ ProtectRowSpan( nCurRow, i, (*pRows)[nCurRow]->GetCell(i)->GetRowSpan() );
+ }
+ for( i=nRows-1; i>=nCurRow; i-- )
+ pRows->DeleteAndDestroy(i);
+ nRows = nCurRow;
+ }
+
+ // falls die Tabelle keine Spalte hat, muessen wir eine hinzufuegen
+ if( 0==nCols )
+ {
+ pColumns->Insert( new HTMLTableColumn, pColumns->Count() );
+ for( i=0; i<nRows; i++ )
+ ((*pRows)[i])->Expand(1);
+ nCols = 1;
+ nFilledCols = 1;
+ }
+
+ // falls die Tabelle keine Zeile hat, muessen wir eine hinzufuegen
+ if( 0==nRows )
+ {
+ pRows->Insert( new HTMLTableRow(nCols), pRows->Count() );
+ nRows = 1;
+ nCurRow = 1;
+ }
+
+ if( nFilledCols < nCols )
+ {
+ pColumns->DeleteAndDestroy( nFilledCols, nCols-nFilledCols );
+ for( i=0; i<nRows; i++ )
+ ((*pRows)[i])->Shrink( nFilledCols );
+ nCols = nFilledCols;
+ }
+}
+
+void HTMLTable::_MakeTable( SwTableBox *pBox )
+{
+ SwTableLines& rLines = (pBox ? pBox->GetTabLines()
+ : ((SwTable *)pSwTable)->GetTabLines() );
+
+ // jetzt geht's richtig los ...
+
+ for( sal_uInt16 i=0; i<nRows; i++ )
+ {
+ SwTableLine *pLine = MakeTableLine( pBox, i, 0, i+1, nCols );
+ if( pBox || i > 0 )
+ rLines.C40_INSERT( SwTableLine, pLine, rLines.Count() );
+ }
+}
+
+/* Wie werden Tabellen ausgerichtet?
+
+erste Zeile: ohne Absatz-Einzuege
+zweite Zeile: mit Absatz-Einzuegen
+
+ALIGN= LEFT RIGHT CENTER -
+-------------------------------------------------------------------------
+xxx bei Tabellen mit WIDTH=nn% ist die Prozent-Angabe von Bedeutung:
+xxx nn = 100 text::HoriOrientation::FULL text::HoriOrientation::FULL text::HoriOrientation::FULL text::HoriOrientation::FULL %
+xxx text::HoriOrientation::NONE text::HoriOrientation::NONE text::HoriOrientation::NONE % text::HoriOrientation::NONE %
+xxx nn < 100 Rahmen F Rahmen F text::HoriOrientation::CENTER % text::HoriOrientation::LEFT %
+xxx Rahmen F Rahmen F text::HoriOrientation::CENTER % text::HoriOrientation::NONE %
+
+bei Tabellen mit WIDTH=nn% ist die Prozent-Angabe von Bedeutung:
+nn = 100 text::HoriOrientation::LEFT text::HoriOrientation::RIGHT text::HoriOrientation::CENTER % text::HoriOrientation::LEFT %
+ text::HoriOrientation::LEFT_AND text::HoriOrientation::RIGHT text::HoriOrientation::CENTER % text::HoriOrientation::LEFT_AND %
+nn < 100 Rahmen F Rahmen F text::HoriOrientation::CENTER % text::HoriOrientation::LEFT %
+ Rahmen F Rahmen F text::HoriOrientation::CENTER % text::HoriOrientation::NONE %
+
+sonst die berechnete Breite w
+w = avail* text::HoriOrientation::LEFT text::HoriOrientation::RIGHT text::HoriOrientation::CENTER text::HoriOrientation::LEFT
+ HORI_LEDT_AND text::HoriOrientation::RIGHT text::HoriOrientation::CENTER text::HoriOrientation::LEFT_AND
+w < avail Rahmen L Rahmen L text::HoriOrientation::CENTER text::HoriOrientation::LEFT
+ Rahmen L Rahmen L text::HoriOrientation::CENTER text::HoriOrientation::NONE
+
+xxx *) wenn fuer die Tabelle keine Groesse angegeben wurde, wird immer
+xxx text::HoriOrientation::FULL genommen
+
+*/
+
+void HTMLTable::MakeTable( SwTableBox *pBox, sal_uInt16 nAbsAvail,
+ sal_uInt16 nRelAvail, sal_uInt16 nAbsLeftSpace,
+ sal_uInt16 nAbsRightSpace, sal_uInt16 nInhAbsSpace )
+{
+ ASSERT( nRows>0 && nCols>0 && nCurRow==nRows,
+ "Wurde CloseTable nicht aufgerufen?" );
+
+ ASSERT( (pLayoutInfo==0) == (this==pTopTable),
+ "Top-Tabelle hat keine Layout-Info oder umgekehrt" );
+
+ if( this==pTopTable )
+ {
+ // Umrandung der Tabelle und aller in ihr enthaltenen berechnen
+ SetBorders();
+
+ // Schritt 1: Die benoetigten Layout-Strukturen werden angelegt
+ // (inklusive Tabellen in Tabellen).
+ CreateLayoutInfo();
+
+ // Schritt 2: Die minimalen und maximalen Spaltenbreiten werden
+ // berechnet (inklusive Tabellen in Tabellen). Da wir noch keine
+ // Boxen haben, arabeiten wir noch auf den Start-Nodes.
+ pLayoutInfo->AutoLayoutPass1();
+ }
+
+ // Schritt 3: Die tatsaechlichen Spaltenbreiten dieser Tabelle werden
+ // berechnet (nicht von Tabellen in Tabellen). Dies muss jetzt schon
+ // sein, damit wir entscheiden koennen ob Filler-Zellen benoetigt werden
+ // oder nicht (deshalb war auch Pass1 schon noetig).
+ pLayoutInfo->AutoLayoutPass2( nAbsAvail, nRelAvail, nAbsLeftSpace,
+ nAbsRightSpace, nInhAbsSpace );
+
+ if( this!=pTopTable )
+ {
+ // die linke und rechte Umrandung der Tabelle kann jetzt entgueltig
+ // festgelegt werden
+ if( pLayoutInfo->GetRelRightFill() == 0 )
+ {
+ if( !bRightBorder )
+ {
+ // linke Umrandung von auesserer Tabelle uebernehmen
+ if( bInhRightBorder )
+ {
+ bRightBorder = sal_True;
+ aRightBorderLine = aInhRightBorderLine;
+ }
+ }
+ else
+ {
+ // Umrandung nur setzen, wenn es erlaubt ist
+ bRightBorder = bRightAlwd;
+ }
+ }
+
+ if( pLayoutInfo->GetRelLeftFill() == 0 &&
+ !((*pColumns)[0])->bLeftBorder &&
+ bInhLeftBorder )
+ {
+ // ggf. rechte Umrandung von auesserer Tabelle uebernehmen
+ ((*pColumns)[0])->bLeftBorder = sal_True;
+ aLeftBorderLine = aInhLeftBorderLine;
+ }
+ }
+
+ // Fuer die Top-Table muss die Ausrichtung gesetzt werden
+ if( this==pTopTable )
+ {
+ sal_Int16 eHoriOri;
+ if( bForceFrame )
+ {
+ // Die Tabelle soll in einen Rahmen und ist auch schmaler
+ // als der verfuegbare Platz und nicht 100% breit.
+ // Dann kommt sie in einen Rahmen
+ eHoriOri = bPrcWidth ? text::HoriOrientation::FULL : text::HoriOrientation::LEFT;
+ }
+ else switch( eTableAdjust )
+ {
+ // Die Tabelle passt entweder auf die Seite, soll aber in keinen
+ // Rahmen oder sie ist Breiter als die Seite und soll deshalb
+ // in keinen Rahmen
+
+ case SVX_ADJUST_RIGHT:
+ // in rechtsbuendigen Tabellen kann nicht auf den rechten
+ // Rand Ruecksicht genommen werden
+ eHoriOri = text::HoriOrientation::RIGHT;
+ break;
+ case SVX_ADJUST_CENTER:
+ // zentrierte Tabellen nehmen keine Ruecksicht auf Raender!
+ eHoriOri = text::HoriOrientation::CENTER;
+ break;
+ case SVX_ADJUST_LEFT:
+ default:
+ // linksbuendige Tabellen nehmen nur auf den linken Rand
+ // Ruecksicht
+ eHoriOri = nLeftMargin ? text::HoriOrientation::LEFT_AND_WIDTH : text::HoriOrientation::LEFT;
+ break;
+ }
+
+ // das Tabellenform holen und anpassen
+ SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
+ pFrmFmt->SetFmtAttr( SwFmtHoriOrient(0,eHoriOri) );
+ if( text::HoriOrientation::LEFT_AND_WIDTH==eHoriOri )
+ {
+ ASSERT( nLeftMargin || nRightMargin,
+ "Da gibt's wohl noch Reste von relativen Breiten" );
+
+ // The right margin will be ignored anyway.
+ SvxLRSpaceItem aLRItem( pSwTable->GetFrmFmt()->GetLRSpace() );
+ aLRItem.SetLeft( nLeftMargin );
+ aLRItem.SetRight( nRightMargin );
+ pFrmFmt->SetFmtAttr( aLRItem );
+ }
+
+ if( bPrcWidth && text::HoriOrientation::FULL!=eHoriOri )
+ {
+ pFrmFmt->LockModify();
+ SwFmtFrmSize aFrmSize( pFrmFmt->GetFrmSize() );
+ aFrmSize.SetWidthPercent( (sal_uInt8)nWidth );
+ pFrmFmt->SetFmtAttr( aFrmSize );
+ pFrmFmt->UnlockModify();
+ }
+ }
+
+ // die Default Line- und Box-Formate holen
+ if( this==pTopTable )
+ {
+ // die erste Box merken und aus der ersten Zeile ausketten
+ SwTableLine *pLine1 = (pSwTable->GetTabLines())[0];
+ pBox1 = (pLine1->GetTabBoxes())[0];
+ pLine1->GetTabBoxes().Remove(0);
+
+ pLineFmt = (SwTableLineFmt*)pLine1->GetFrmFmt();
+ pBoxFmt = (SwTableBoxFmt*)pBox1->GetFrmFmt();
+ }
+ else
+ {
+ pLineFmt = (SwTableLineFmt*)pTopTable->pLineFmt;
+ pBoxFmt = (SwTableBoxFmt*)pTopTable->pBoxFmt;
+ }
+
+ // ggf. muessen fuer Tabellen in Tabellen "Filler"-Zellen eingefuegt
+ // werden
+ if( this != pTopTable &&
+ ( pLayoutInfo->GetRelLeftFill() > 0 ||
+ pLayoutInfo->GetRelRightFill() > 0 ) )
+ {
+ ASSERT( pBox, "kein TableBox fuer Tabelle in Tabelle" );
+
+ SwTableLines& rLines = pBox->GetTabLines();
+
+ // dazu brauchen wir erstmal ein eine neue Table-Line in der Box
+ SwTableLine *pLine =
+ new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
+ : pLineFmt, 0, pBox );
+ rLines.C40_INSERT( SwTableLine, pLine, rLines.Count() );
+
+ // Sicherstellen, dass wie ein Format ohne Hoehe erwischt haben
+ if( !pLineFrmFmtNoHeight )
+ {
+ // sonst muessen wir die Hoehe aus dem Attribut entfernen
+ // und koennen uns das Format merken
+ pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
+
+ ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
+ }
+
+ SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ SwTableBox *pNewBox;
+
+ // ggf. links eine Zelle einfuegen
+ if( pLayoutInfo->GetRelLeftFill() > 0 )
+ {
+ // pPrevStNd ist der Vorgaenger-Start-Node der Tabelle. Den
+ // "Filler"-Node fuegen wir einfach dahinter ein ...
+ pPrevStNd = pParser->InsertTableSection( pPrevStNd );
+
+ pNewBox = NewTableBox( pPrevStNd, pLine );
+ rBoxes.C40_INSERT( SwTableBox, pNewBox, rBoxes.Count() );
+ FixFillerFrameFmt( pNewBox, sal_False );
+ pLayoutInfo->SetLeftFillerBox( pNewBox );
+ }
+
+ // jetzt die Tabelle bearbeiten
+ pNewBox = new SwTableBox( pBoxFmt, 0, pLine );
+ rBoxes.C40_INSERT( SwTableBox, pNewBox, rBoxes.Count() );
+
+ SwFrmFmt *pFrmFmt = pNewBox->ClaimFrmFmt();
+ pFrmFmt->ResetFmtAttr( RES_BOX );
+ pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
+ pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
+ pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
+
+
+ _MakeTable( pNewBox );
+
+ // und noch ggf. rechts eine Zelle einfuegen
+ if( pLayoutInfo->GetRelRightFill() > 0 )
+ {
+ const SwStartNode *pStNd =
+ GetPrevBoxStartNode( USHRT_MAX, USHRT_MAX );
+ pStNd = pParser->InsertTableSection( pStNd );
+
+ pNewBox = NewTableBox( pStNd, pLine );
+ rBoxes.C40_INSERT( SwTableBox, pNewBox, rBoxes.Count() );
+
+ FixFillerFrameFmt( pNewBox, sal_True );
+ pLayoutInfo->SetRightFillerBox( pNewBox );
+ }
+ }
+ else
+ {
+ _MakeTable( pBox );
+ }
+
+ // zum Schluss fuehren wir noch eine Garbage-Collection fuer die
+ // Top-Level-Tabelle durch
+ if( this==pTopTable )
+ {
+ if( 1==nRows && nHeight && 1==pSwTable->GetTabLines().Count() )
+ {
+ // Hoehe einer einzeiligen Tabelle als Mindesthoehe der
+ // Zeile setzen. (War mal fixe Hoehe, aber das gibt manchmal
+ // Probleme (fix #34972#) und ist auch nicht Netscape 4.0
+ // konform
+ nHeight = pParser->ToTwips( nHeight );
+ if( nHeight < MINLAY )
+ nHeight = MINLAY;
+
+ (pSwTable->GetTabLines())[0]->ClaimFrmFmt();
+ (pSwTable->GetTabLines())[0]->GetFrmFmt()
+ ->SetFmtAttr( SwFmtFrmSize( ATT_MIN_SIZE, 0, nHeight ) );
+ }
+
+ if( GetBGBrush() )
+ pSwTable->GetFrmFmt()->SetFmtAttr( *GetBGBrush() );
+
+ ((SwTable *)pSwTable)->SetRowsToRepeat( static_cast< USHORT >(nHeadlineRepeat) );
+ ((SwTable *)pSwTable)->GCLines();
+
+ sal_Bool bIsInFlyFrame = pContext && pContext->GetFrmFmt();
+ if( bIsInFlyFrame && !nWidth )
+ {
+ SvxAdjust eTblAdjust = GetTableAdjust(sal_False);
+ if( eTblAdjust != SVX_ADJUST_LEFT &&
+ eTblAdjust != SVX_ADJUST_RIGHT )
+ {
+ // Wenn eine Tabelle ohne Breitenangabe nicht links oder
+ // rechts umflossen werden soll, dann stacken wir sie
+ // in einem Rahmen mit 100%-Breite, damit ihre Groesse
+ // angepasst wird. Der Rahmen darf nicht angepasst werden.
+ ASSERT( HasToFly(), "Warum ist die Tabelle in einem Rahmen?" );
+ sal_uInt32 nMin = pLayoutInfo->GetMin();
+ if( nMin > USHRT_MAX )
+ nMin = USHRT_MAX;
+ SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, (SwTwips)nMin, MINLAY );
+ aFlyFrmSize.SetWidthPercent( 100 );
+ pContext->GetFrmFmt()->SetFmtAttr( aFlyFrmSize );
+ bIsInFlyFrame = sal_False;
+ }
+ else
+ {
+ // Links und rechts ausgerichtete Tabellen ohne Breite
+ // duerfen leider nicht in der Breite angepasst werden, denn
+ // sie wuerden nur schrumpfen aber nie wachsen.
+ pLayoutInfo->SetMustNotRecalc( sal_True );
+ if( pContext->GetFrmFmt()->GetAnchor().GetCntntAnchor()
+ ->nNode.GetNode().FindTableNode() )
+ {
+ sal_uInt32 nMax = pLayoutInfo->GetMax();
+ if( nMax > USHRT_MAX )
+ nMax = USHRT_MAX;
+ SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, (SwTwips)nMax, MINLAY );
+ pContext->GetFrmFmt()->SetFmtAttr( aFlyFrmSize );
+ bIsInFlyFrame = sal_False;
+ }
+ else
+ {
+ pLayoutInfo->SetMustNotResize( sal_True );
+ }
+ }
+ }
+ pLayoutInfo->SetMayBeInFlyFrame( bIsInFlyFrame );
+
+ // Nur Tabellen mit relativer Breite oder ohne Breite muessen
+ // angepasst werden.
+ pLayoutInfo->SetMustResize( bPrcWidth || !nWidth );
+
+ pLayoutInfo->SetWidths();
+
+ ((SwTable *)pSwTable)->SetHTMLTableLayout( pLayoutInfo );
+
+ if( pResizeDrawObjs )
+ {
+ sal_uInt16 nCount = pResizeDrawObjs->Count();
+ for( sal_uInt16 i=0; i<nCount; i++ )
+ {
+ SdrObject *pObj = (*pResizeDrawObjs)[i];
+ sal_uInt16 nRow = (*pDrawObjPrcWidths)[3*i];
+ sal_uInt16 nCol = (*pDrawObjPrcWidths)[3*i+1];
+ sal_uInt8 nPrcWidth = (sal_uInt8)(*pDrawObjPrcWidths)[3*i+2];
+
+ SwHTMLTableLayoutCell *pLayoutCell =
+ pLayoutInfo->GetCell( nRow, nCol );
+ sal_uInt16 nColSpan = pLayoutCell->GetColSpan();
+
+ sal_uInt16 nWidth2, nDummy;
+ pLayoutInfo->GetAvail( nCol, nColSpan, nWidth2, nDummy );
+ nWidth2 = nWidth2 - pLayoutInfo->GetLeftCellSpace( nCol, nColSpan );
+ nWidth2 = nWidth2 - pLayoutInfo->GetRightCellSpace( nCol, nColSpan );
+ nWidth2 = static_cast< sal_uInt16 >(((long)nWidth * nPrcWidth) / 100);
+
+ pParser->ResizeDrawObject( pObj, nWidth2 );
+ }
+ }
+ }
+}
+
+void HTMLTable::SetTable( const SwStartNode *pStNd, _HTMLTableContext *pCntxt,
+ sal_uInt16 nLeft, sal_uInt16 nRight,
+ const SwTable *pSwTab, sal_Bool bFrcFrame )
+{
+ pPrevStNd = pStNd;
+ pSwTable = pSwTab;
+ pContext = pCntxt;
+
+ nLeftMargin = nLeft;
+ nRightMargin = nRight;
+
+ bForceFrame = bFrcFrame;
+}
+
+void HTMLTable::RegisterDrawObject( SdrObject *pObj, sal_uInt8 nPrcWidth )
+{
+ if( !pResizeDrawObjs )
+ pResizeDrawObjs = new SdrObjects;
+ pResizeDrawObjs->C40_INSERT( SdrObject, pObj, pResizeDrawObjs->Count() );
+
+ if( !pDrawObjPrcWidths )
+ pDrawObjPrcWidths = new SvUShorts;
+ pDrawObjPrcWidths->Insert( nCurRow, pDrawObjPrcWidths->Count() );
+ pDrawObjPrcWidths->Insert( nCurCol, pDrawObjPrcWidths->Count() );
+ pDrawObjPrcWidths->Insert( (sal_uInt16)nPrcWidth, pDrawObjPrcWidths->Count() );
+}
+
+void HTMLTable::MakeParentContents()
+{
+ if( !GetContext() && !HasParentSection() )
+ {
+ SetParentContents(
+ pParser->InsertTableContents( GetIsParentHeader() ) );
+
+ SetHasParentSection( sal_True );
+ }
+}
+
+_HTMLTableContext::~_HTMLTableContext()
+{
+ delete pPos;
+}
+
+void _HTMLTableContext::SavePREListingXMP( SwHTMLParser& rParser )
+{
+ bRestartPRE = rParser.IsReadPRE();
+ bRestartXMP = rParser.IsReadXMP();
+ bRestartListing = rParser.IsReadListing();
+ rParser.FinishPREListingXMP();
+}
+
+void _HTMLTableContext::RestorePREListingXMP( SwHTMLParser& rParser )
+{
+ rParser.FinishPREListingXMP();
+
+ if( bRestartPRE )
+ rParser.StartPRE();
+
+ if( bRestartXMP )
+ rParser.StartXMP();
+
+ if( bRestartListing )
+ rParser.StartListing();
+}
+
+/* */
+
+const SwStartNode *SwHTMLParser::InsertTableSection
+ ( const SwStartNode *pPrevStNd )
+{
+ ASSERT( pPrevStNd, "Start-Node ist NULL" );
+
+ pCSS1Parser->SetTDTagStyles();
+ SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TABLE );
+
+ const SwStartNode *pStNd;
+ if( pTable && pTable->bFirstCell )
+ {
+ SwNode *pNd = pDoc->GetNodes()[pPam->GetPoint()->nNode];
+ pNd->GetTxtNode()->ChgFmtColl( pColl );
+ pStNd = pNd->FindTableBoxStartNode();
+ pTable->bFirstCell = sal_False;
+ }
+ else
+ {
+ const SwNode* pNd;
+ if( pPrevStNd->IsTableNode() )
+ pNd = pPrevStNd;
+ else
+ pNd = pPrevStNd->EndOfSectionNode();
+ SwNodeIndex nIdx( *pNd, 1 );
+ pStNd = pDoc->GetNodes().MakeTextSection( nIdx, SwTableBoxStartNode,
+ pColl );
+ pTable->IncBoxCount();
+ }
+
+ SwCntntNode *pCNd = pDoc->GetNodes()[pStNd->GetIndex()+1] ->GetCntntNode();
+ SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+
+ return pStNd;
+}
+
+const SwStartNode *SwHTMLParser::InsertTableSection( sal_uInt16 nPoolId )
+{
+ switch( nPoolId )
+ {
+ case RES_POOLCOLL_TABLE_HDLN:
+ pCSS1Parser->SetTHTagStyles();
+ break;
+ case RES_POOLCOLL_TABLE:
+ pCSS1Parser->SetTDTagStyles();
+ break;
+ }
+
+ SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( nPoolId );
+
+ SwNode *pNd = pDoc->GetNodes()[pPam->GetPoint()->nNode];
+ const SwStartNode *pStNd;
+ if( pTable && pTable->bFirstCell )
+ {
+ pNd->GetTxtNode()->ChgFmtColl( pColl );
+ pTable->bFirstCell = sal_False;
+ pStNd = pNd->FindTableBoxStartNode();
+ }
+ else
+ {
+ SwTableNode *pTblNd = pNd->FindTableNode();
+ if( pTblNd->GetTable().GetHTMLTableLayout() )
+ { // if there is already a HTMTableLayout, this table is already finished
+ // and we have to look for the right table in the environment
+ SwTableNode *pOutTbl = pTblNd;
+ do {
+ pTblNd = pOutTbl;
+ pOutTbl = pOutTbl->StartOfSectionNode()->FindTableNode();
+ } while( pOutTbl && pTblNd->GetTable().GetHTMLTableLayout() );
+ }
+ SwNodeIndex aIdx( *pTblNd->EndOfSectionNode() );
+ pStNd = pDoc->GetNodes().MakeTextSection( aIdx, SwTableBoxStartNode,
+ pColl );
+
+ pPam->GetPoint()->nNode = pStNd->GetIndex() + 1;
+ SwTxtNode *pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
+ pPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
+ pTable->IncBoxCount();
+ }
+
+ return pStNd;
+}
+
+SwStartNode *SwHTMLParser::InsertTempTableCaptionSection()
+{
+ SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TEXT );
+ SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
+ rIdx = pDoc->GetNodes().GetEndOfExtras();
+ SwStartNode *pStNd = pDoc->GetNodes().MakeTextSection( rIdx,
+ SwNormalStartNode, pColl );
+
+ rIdx = pStNd->GetIndex() + 1;
+ pPam->GetPoint()->nContent.Assign( rIdx.GetNode().GetTxtNode(), 0 );
+
+ return pStNd;
+}
+
+
+xub_StrLen SwHTMLParser::StripTrailingLF()
+{
+ xub_StrLen nStripped = 0;
+
+ xub_StrLen nLen = pPam->GetPoint()->nContent.GetIndex();
+ if( nLen )
+ {
+ SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
+ // vorsicht, wenn Kommentare nicht uebrlesen werden!!!
+ if( pTxtNd )
+ {
+ xub_StrLen nPos = nLen;
+ xub_StrLen nLFCount = 0;
+ while( nPos && '\x0a' == (pTxtNd->GetTxt()).GetChar(--nPos) )
+ nLFCount++;
+
+ if( nLFCount )
+ {
+// MIB 6.6.97: Warum sollte man bei leeren Absaetzen nur ein LF loeschen?
+// Das stimmt doch irgendwi nicht ...
+// if( nLFCount == nLen )
+// {
+// // nur Lfs, dann nur ein LF loeschen
+// nLFCount = 1;
+// }
+// else if( nLFCount > 2 )
+ if( nLFCount > 2 )
+ {
+ // Bei Netscape entspricht ein Absatz-Ende zwei LFs
+ // (mit einem kommt man in die naechste Zeile, das
+ // zweite erzeugt eine Leerzeile) Diesen Abstand
+ // erreichen wie aber schon mit dem unteren
+ // Absatz-Abstand. Wenn nach den <BR> ein neuer
+ // Absatz aufgemacht wird, wird das Maximum des Abstands,
+ // der sich aus den BR und dem P ergibt genommen.
+ // Deshalb muessen wir 2 bzw. alle bei weniger
+ // als zweien loeschen
+ nLFCount = 2;
+ }
+
+ nPos = nLen - nLFCount;
+ SwIndex nIdx( pTxtNd, nPos );
+ pTxtNd->EraseText( nIdx, nLFCount );
+ nStripped = nLFCount;
+ }
+ }
+ }
+
+ return nStripped;
+}
+
+SvxBrushItem* SwHTMLParser::CreateBrushItem( const Color *pColor,
+ const String& rImageURL,
+ const String& rStyle,
+ const String& rId,
+ const String& rClass )
+{
+ SvxBrushItem *pBrushItem = 0;
+
+ if( rStyle.Len() || rId.Len() || rClass.Len() )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), RES_BACKGROUND,
+ RES_BACKGROUND );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( rClass.Len() )
+ {
+ String aClass( rClass );
+ SwCSS1Parser::GetScriptFromClass( aClass );
+ SvxCSS1MapEntry *pClass = pCSS1Parser->GetClass( aClass );
+ if( pClass )
+ aItemSet.Put( pClass->GetItemSet() );
+ }
+
+ if( rId.Len() )
+ {
+ SvxCSS1MapEntry *pId = pCSS1Parser->GetId( rId );
+ if( pId )
+ aItemSet.Put( pId->GetItemSet() );
+ }
+
+ pCSS1Parser->ParseStyleOption( rStyle, aItemSet, aPropInfo );
+ const SfxPoolItem *pItem = 0;
+ if( SFX_ITEM_SET == aItemSet.GetItemState( RES_BACKGROUND, sal_False,
+ &pItem ) )
+ {
+ pBrushItem = new SvxBrushItem( *((const SvxBrushItem *)pItem) );
+ }
+ }
+
+ if( !pBrushItem && (pColor || rImageURL.Len()) )
+ {
+ pBrushItem = new SvxBrushItem(RES_BACKGROUND);
+
+ if( pColor )
+ pBrushItem->SetColor(*pColor);
+
+ if( rImageURL.Len() )
+ {
+ pBrushItem->SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject(sBaseURL), rImageURL, Link(), false) );
+ pBrushItem->SetGraphicPos( GPOS_TILED );
+ }
+ }
+
+ return pBrushItem;
+}
+
+/* */
+
+class _SectionSaveStruct : public SwPendingStackData
+{
+ sal_uInt16 nBaseFontStMinSave, nFontStMinSave, nFontStHeadStartSave;
+ sal_uInt16 nDefListDeepSave, nContextStMinSave, nContextStAttrMinSave;
+
+public:
+
+ HTMLTable *pTable;
+
+ _SectionSaveStruct( SwHTMLParser& rParser );
+ virtual ~_SectionSaveStruct();
+
+ sal_uInt16 GetContextStAttrMin() const { return nContextStAttrMinSave; }
+
+ void Restore( SwHTMLParser& rParser );
+};
+
+_SectionSaveStruct::_SectionSaveStruct( SwHTMLParser& rParser ) :
+ nBaseFontStMinSave(0), nFontStMinSave(0), nFontStHeadStartSave(0),
+ nDefListDeepSave(0), nContextStMinSave(0), nContextStAttrMinSave(0),
+ pTable( 0 )
+{
+ // Font-Stacks einfrieren
+ nBaseFontStMinSave = rParser.nBaseFontStMin;
+ rParser.nBaseFontStMin = rParser.aBaseFontStack.Count();
+
+ nFontStMinSave = rParser.nFontStMin;
+ nFontStHeadStartSave = rParser.nFontStHeadStart;
+ rParser.nFontStMin = rParser.aFontStack.Count();
+
+ // Kontext-Stack einfrieren
+ nContextStMinSave = rParser.nContextStMin;
+ nContextStAttrMinSave = rParser.nContextStAttrMin;
+ rParser.nContextStMin = rParser.aContexts.Count();
+ rParser.nContextStAttrMin = rParser.nContextStMin;
+
+ // und noch ein par Zaehler retten
+ nDefListDeepSave = rParser.nDefListDeep;
+ rParser.nDefListDeep = 0;
+}
+
+_SectionSaveStruct::~_SectionSaveStruct()
+{}
+
+void _SectionSaveStruct::Restore( SwHTMLParser& rParser )
+{
+ // Font-Stacks wieder auftauen
+ sal_uInt16 nMin = rParser.nBaseFontStMin;
+ if( rParser.aBaseFontStack.Count() > nMin )
+ rParser.aBaseFontStack.Remove( nMin,
+ rParser.aBaseFontStack.Count() - nMin );
+ rParser.nBaseFontStMin = nBaseFontStMinSave;
+
+
+ nMin = rParser.nFontStMin;
+ if( rParser.aFontStack.Count() > nMin )
+ rParser.aFontStack.Remove( nMin,
+ rParser.aFontStack.Count() - nMin );
+ rParser.nFontStMin = nFontStMinSave;
+ rParser.nFontStHeadStart = nFontStHeadStartSave;
+
+ // Der Kontext-Stack muss schon aufgeraeumt sein!
+ ASSERT( rParser.aContexts.Count() == rParser.nContextStMin &&
+ rParser.aContexts.Count() == rParser.nContextStAttrMin,
+ "Der Kontext-Stack wurde nicht aufgeraeumt" );
+ rParser.nContextStMin = nContextStMinSave;
+ rParser.nContextStAttrMin = nContextStAttrMinSave;
+
+ // und noch ein par Zaehler rekonstruieren
+ rParser.nDefListDeep = nDefListDeepSave;
+
+ // und ein par Flags zuruecksetzen
+ rParser.bNoParSpace = sal_False;
+ rParser.nOpenParaToken = 0;
+
+ if( rParser.aParaAttrs.Count() )
+ rParser.aParaAttrs.Remove( 0, rParser.aParaAttrs.Count() );
+}
+
+/* */
+
+class _CellSaveStruct : public _SectionSaveStruct
+{
+ String aStyle, aId, aClass, aLang, aDir;
+ String aBGImage;
+ Color aBGColor;
+
+ HTMLTableCnts* pCnts; // Liste aller Inhalte
+ HTMLTableCnts* pCurrCnts; // der aktuelle Inhalt oder 0
+ SwNodeIndex *pNoBreakEndParaIdx;// Absatz-Index eines </NOBR>
+
+ double nValue;
+
+ sal_uInt32 nNumFmt;
+
+ sal_uInt16 nRowSpan, nColSpan, nWidth, nHeight;
+ xub_StrLen nNoBreakEndCntntPos; // Zeichen-Index eines </NOBR>
+
+ SvxAdjust eAdjust;
+ sal_Int16 eVertOri;
+
+ sal_Bool bHead : 1;
+ sal_Bool bPrcWidth : 1;
+ sal_Bool bHasNumFmt : 1;
+ sal_Bool bHasValue : 1;
+ sal_Bool bBGColor : 1;
+ sal_Bool bNoWrap : 1; // NOWRAP-Option
+ sal_Bool bNoBreak : 1; // NOBREAK-Tag
+
+public:
+
+ _CellSaveStruct( SwHTMLParser& rParser, HTMLTable *pCurTable, sal_Bool bHd,
+ sal_Bool bReadOpt );
+
+ virtual ~_CellSaveStruct();
+
+ void AddContents( HTMLTableCnts *pNewCnts );
+ HTMLTableCnts *GetFirstContents() { return pCnts; }
+
+ void ClearIsInSection() { pCurrCnts = 0; }
+ sal_Bool IsInSection() const { return pCurrCnts!=0; }
+ HTMLTableCnts *GetCurrContents() const { return pCurrCnts; }
+
+ void InsertCell( SwHTMLParser& rParser, HTMLTable *pCurTable );
+
+ sal_Bool IsHeaderCell() const { return bHead; }
+
+ void StartNoBreak( const SwPosition& rPos );
+ void EndNoBreak( const SwPosition& rPos );
+ void CheckNoBreak( const SwPosition& rPos, SwDoc *pDoc );
+};
+
+
+_CellSaveStruct::_CellSaveStruct( SwHTMLParser& rParser, HTMLTable *pCurTable,
+ sal_Bool bHd, sal_Bool bReadOpt ) :
+ _SectionSaveStruct( rParser ),
+ pCnts( 0 ),
+ pCurrCnts( 0 ),
+ pNoBreakEndParaIdx( 0 ),
+ nValue( 0.0 ),
+ nNumFmt( 0 ),
+ nRowSpan( 1 ),
+ nColSpan( 1 ),
+ nWidth( 0 ),
+ nHeight( 0 ),
+ nNoBreakEndCntntPos( 0 ),
+ eAdjust( pCurTable->GetInheritedAdjust() ),
+ eVertOri( pCurTable->GetInheritedVertOri() ),
+ bHead( bHd ),
+ bPrcWidth( sal_False ),
+ bHasNumFmt( sal_False ),
+ bHasValue( sal_False ),
+ bBGColor( sal_False ),
+ bNoWrap( sal_False ),
+ bNoBreak( sal_False )
+{
+ String aNumFmt, aValue;
+
+ if( bReadOpt )
+ {
+ const HTMLOptions *pOptions = rParser.GetOptions();
+ for( sal_uInt16 i = pOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_COLSPAN:
+ nColSpan = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_ROWSPAN:
+ nRowSpan = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_ALIGN:
+ eAdjust = (SvxAdjust)pOption->GetEnum(
+ aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
+ break;
+ case HTML_O_VALIGN:
+ eVertOri = pOption->GetEnum(
+ aHTMLTblVAlignTable, eVertOri );
+ break;
+ case HTML_O_WIDTH:
+ nWidth = (sal_uInt16)pOption->GetNumber(); // nur fuer Netscape
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ if( bPrcWidth && nWidth>100 )
+ nWidth = 100;
+ break;
+ case HTML_O_HEIGHT:
+ nHeight = (sal_uInt16)pOption->GetNumber(); // nur fuer Netscape
+ if( pOption->GetString().Search('%') != STRING_NOTFOUND)
+ nHeight = 0; // keine %-Angaben beruecksichtigen
+ break;
+ case HTML_O_BGCOLOR:
+ // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netscape
+ // ignorieren, bei allen anderen Tags *wirklich* nicht.
+ if( pOption->GetString().Len() )
+ {
+ pOption->GetColor( aBGColor );
+ bBGColor = sal_True;
+ }
+ break;
+ case HTML_O_BACKGROUND:
+ aBGImage = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ case HTML_O_SDNUM:
+ aNumFmt = pOption->GetString();
+ bHasNumFmt = sal_True;
+ break;
+ case HTML_O_SDVAL:
+ bHasValue = sal_True;
+ aValue = pOption->GetString();
+ break;
+ case HTML_O_NOWRAP:
+ bNoWrap = sal_True;
+ break;
+ }
+ }
+
+ if( aId.Len() )
+ rParser.InsertBookmark( aId );
+ }
+
+ if( bHasNumFmt )
+ {
+ LanguageType eLang;
+ nValue = rParser.GetTableDataOptionsValNum(
+ nNumFmt, eLang, aValue, aNumFmt,
+ *rParser.pDoc->GetNumberFormatter() );
+ }
+
+ // einen neuen Kontext anlegen, aber das drawing::Alignment-Attribut
+ // nicht dort verankern, weil es noch ger keine Section gibt, in der
+ // es gibt.
+ sal_uInt16 nToken, nColl;
+ if( bHead )
+ {
+ nToken = HTML_TABLEHEADER_ON;
+ nColl = RES_POOLCOLL_TABLE_HDLN;
+ }
+ else
+ {
+ nToken = HTML_TABLEDATA_ON;
+ nColl = RES_POOLCOLL_TABLE;
+ }
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( nToken, nColl, aEmptyStr, sal_True );
+ if( SVX_ADJUST_END != eAdjust )
+ rParser.InsertAttr( &rParser.aAttrTab.pAdjust, SvxAdjustItem(eAdjust, RES_PARATR_ADJUST),
+ pCntxt );
+
+ if( rParser.HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( rParser.pDoc->GetAttrPool(),
+ rParser.pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( rParser.ParseStyleOptions( aStyle, aId, aClass, aItemSet,
+ aPropInfo, &aLang, &aDir ) )
+ rParser.InsertAttrs( aItemSet, aPropInfo, pCntxt );
+ }
+
+ rParser.SplitPREListingXMP( pCntxt );
+
+ rParser.PushContext( pCntxt );
+}
+
+_CellSaveStruct::~_CellSaveStruct()
+{
+ delete pNoBreakEndParaIdx;
+}
+
+void _CellSaveStruct::AddContents( HTMLTableCnts *pNewCnts )
+{
+ if( pCnts )
+ pCnts->Add( pNewCnts );
+ else
+ pCnts = pNewCnts;
+
+ pCurrCnts = pNewCnts;
+}
+
+void _CellSaveStruct::InsertCell( SwHTMLParser& rParser,
+ HTMLTable *pCurTable )
+{
+#ifdef DBG_UTIL
+ // Die Attribute muessen schon beim Auefrauemen des Kontext-Stacks
+ // entfernt worden sein, sonst ist etwas schiefgelaufen. Das
+ // Checken wir mal eben ...
+ // MIB 8.1.98: Wenn ausserhalb einer Zelle Attribute geoeffnet
+ // wurden stehen diese noch in der Attribut-Tabelle und werden erst
+ // ganz zum Schluss durch die CleanContext-Aufrufe in BuildTable
+ // geloescht. Damit es in diesem Fall keine Asserts gibt findet dann
+ // keine Ueberpruefung statt. Erkennen tut man diesen Fall an
+ // nContextStAttrMin: Der gemerkte Wert nContextStAttrMinSave ist der
+ // Wert, den nContextStAttrMin beim Start der Tabelle hatte. Und
+ // der aktuelle Wert von nContextStAttrMin entspricht der Anzahl der
+ // Kontexte, die beim Start der Zelle vorgefunden wurden. Sind beide
+ // Werte unterschiedlich, wurden ausserhalb der Zelle Kontexte
+ // angelegt und wir ueberpruefen nichts.
+
+ if( rParser.nContextStAttrMin == GetContextStAttrMin() )
+ {
+ _HTMLAttr** pTbl = (_HTMLAttr**)&rParser.aAttrTab;
+
+ for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
+ nCnt--; ++pTbl )
+ {
+ ASSERT( !*pTbl, "Die Attribut-Tabelle ist nicht leer" );
+ }
+ }
+#endif
+
+ // jetzt muessen wir noch die Zelle an der aktuellen Position einfuegen
+ SvxBrushItem *pBrushItem =
+ rParser.CreateBrushItem( bBGColor ? &aBGColor : 0, aBGImage,
+ aStyle, aId, aClass );
+ pCurTable->InsertCell( pCnts, nRowSpan, nColSpan, nWidth,
+ bPrcWidth, nHeight, eVertOri, pBrushItem,
+ bHasNumFmt, nNumFmt, bHasValue, nValue,
+ bNoWrap );
+ Restore( rParser );
+}
+
+void _CellSaveStruct::StartNoBreak( const SwPosition& rPos )
+{
+ if( !pCnts ||
+ (!rPos.nContent.GetIndex() && pCurrCnts==pCnts &&
+ pCnts->GetStartNode() &&
+ pCnts->GetStartNode()->GetIndex() + 1 ==
+ rPos.nNode.GetIndex()) )
+ {
+ bNoBreak = sal_True;
+ }
+}
+
+void _CellSaveStruct::EndNoBreak( const SwPosition& rPos )
+{
+ if( bNoBreak )
+ {
+ delete pNoBreakEndParaIdx;
+ pNoBreakEndParaIdx = new SwNodeIndex( rPos.nNode );
+ nNoBreakEndCntntPos = rPos.nContent.GetIndex();
+ bNoBreak = sal_False;
+ }
+}
+
+void _CellSaveStruct::CheckNoBreak( const SwPosition& rPos, SwDoc *pDoc )
+{
+ if( pCnts && pCurrCnts==pCnts )
+ {
+ if( bNoBreak )
+ {
+ // <NOBR> wurde nicht beendet
+ pCnts->SetNoBreak();
+ }
+ else if( pNoBreakEndParaIdx &&
+ pNoBreakEndParaIdx->GetIndex() == rPos.nNode.GetIndex() )
+ {
+ if( nNoBreakEndCntntPos == rPos.nContent.GetIndex() )
+ {
+ // <NOBR> wurde unmittelbar vor dem Zellen-Ende beendet
+ pCnts->SetNoBreak();
+ }
+ else if( nNoBreakEndCntntPos + 1 == rPos.nContent.GetIndex() )
+ {
+ const SwTxtNode *pTxtNd =
+ pDoc->GetNodes()[rPos.nNode]->GetTxtNode();
+ if( pTxtNd )
+ {
+ sal_Unicode cLast =
+ pTxtNd->GetTxt().GetChar(nNoBreakEndCntntPos);
+ if( ' '==cLast || '\x0a'==cLast )
+ {
+ // Zwischem dem </NOBR> und dem Zellen-Ende gibt es nur
+ // ein Blank oder einen Zeilenumbruch.
+ pCnts->SetNoBreak();
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+HTMLTableCnts *SwHTMLParser::InsertTableContents(
+ sal_Bool bHead )
+{
+ // eine neue Section anlegen, der PaM steht dann darin
+ const SwStartNode *pStNd =
+ InsertTableSection( static_cast< USHORT >(bHead ? RES_POOLCOLL_TABLE_HDLN
+ : RES_POOLCOLL_TABLE) );
+
+ if( GetNumInfo().GetNumRule() )
+ {
+ // 1. Absatz auf nicht numeriert setzen
+ BYTE nLvl = GetNumInfo().GetLevel();
+ // --> OD 2008-04-02 #refactorlists#
+// SetNoNum(&nLvl, TRUE);
+// SetNodeNum( nLvl);
+ SetNodeNum( nLvl, false );
+ }
+
+ // Attributierungs-Anfang neu setzen
+ const SwNodeIndex& rSttPara = pPam->GetPoint()->nNode;
+ xub_StrLen nSttCnt = pPam->GetPoint()->nContent.GetIndex();
+
+ _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
+ for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
+ nCnt--; ++pTbl )
+ {
+
+ _HTMLAttr *pAttr = *pTbl;
+ while( pAttr )
+ {
+ ASSERT( !pAttr->GetPrev(), "Attribut hat Previous-Liste" );
+ pAttr->nSttPara = rSttPara;
+ pAttr->nEndPara = rSttPara;
+ pAttr->nSttCntnt = nSttCnt;
+ pAttr->nEndCntnt = nSttCnt;
+
+ pAttr = pAttr->GetNext();
+ }
+ }
+
+ return new HTMLTableCnts( pStNd );
+}
+
+sal_uInt16 SwHTMLParser::IncGrfsThatResizeTable()
+{
+ return pTable ? pTable->IncGrfsThatResize() : 0;
+}
+
+void SwHTMLParser::RegisterDrawObjectToTable( HTMLTable *pCurTable,
+ SdrObject *pObj, sal_uInt8 nPrcWidth )
+{
+ pCurTable->RegisterDrawObject( pObj, nPrcWidth );
+}
+
+void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, sal_Bool bReadOptions,
+ sal_Bool bHead )
+{
+ if( !IsParserWorking() && !pPendStack )
+ return;
+
+ _CellSaveStruct* pSaveStruct;
+
+ int nToken = 0;
+ sal_Bool bPending = sal_False;
+ if( pPendStack )
+ {
+ pSaveStruct = (_CellSaveStruct*)pPendStack->pData;
+
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+ nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
+ bPending = SVPAR_ERROR == eState && pPendStack != 0;
+
+ SaveState( nToken );
+ }
+ else
+ {
+ // <TH> bzw. <TD> wurde bereits gelesen
+ if( pTable->IsOverflowing() )
+ {
+ SaveState( 0 );
+ return;
+ }
+
+ if( !pCurTable->GetContext() )
+ {
+ sal_Bool bTopTable = pTable==pCurTable;
+
+ // die Tabelle besitzt noch keinen Inhalt, d.h. die eigentliche
+ // Tabelle muss erst noch angelegt werden
+
+ static sal_uInt16 aWhichIds[] =
+ {
+ RES_PARATR_SPLIT, RES_PARATR_SPLIT,
+ RES_PAGEDESC, RES_PAGEDESC,
+ RES_BREAK, RES_BREAK,
+ RES_BACKGROUND, RES_BACKGROUND,
+ RES_KEEP, RES_KEEP,
+ RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT,
+ RES_FRAMEDIR, RES_FRAMEDIR,
+ 0
+ };
+
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), aWhichIds );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ sal_Bool bStyleParsed = ParseStyleOptions( pCurTable->GetStyle(),
+ pCurTable->GetId(),
+ pCurTable->GetClass(),
+ aItemSet, aPropInfo,
+ 0, &pCurTable->GetDirection() );
+ const SfxPoolItem *pItem = 0;
+ if( bStyleParsed )
+ {
+ if( SFX_ITEM_SET == aItemSet.GetItemState(
+ RES_BACKGROUND, sal_False, &pItem ) )
+ {
+ pCurTable->SetBGBrush( *(const SvxBrushItem *)pItem );
+ aItemSet.ClearItem( RES_BACKGROUND );
+ }
+ if( SFX_ITEM_SET == aItemSet.GetItemState(
+ RES_PARATR_SPLIT, sal_False, &pItem ) )
+ {
+ aItemSet.Put(
+ SwFmtLayoutSplit( ((const SvxFmtSplitItem *)pItem)
+ ->GetValue() ) );
+ aItemSet.ClearItem( RES_PARATR_SPLIT );
+ }
+ }
+
+ // Den linken/rechten Absatzeinzug ermitteln
+ sal_uInt16 nLeftSpace = 0;
+ sal_uInt16 nRightSpace = 0;
+ short nIndent;
+ GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
+
+ // die aktuelle Position an die wir irgendwann zurueckkehren
+ SwPosition *pSavePos = 0;
+ sal_Bool bForceFrame = sal_False;
+ sal_Bool bAppended = sal_False;
+ sal_Bool bParentLFStripped = sal_False;
+ if( bTopTable )
+ {
+ SvxAdjust eTblAdjust = pTable->GetTableAdjust(sal_False);
+
+ // Wenn die Tabelle links oder rechts ausgerivchtet ist,
+ // oder in einen Rahmen soll, dann kommt sie auch in einen
+ // solchen.
+ bForceFrame = eTblAdjust == SVX_ADJUST_LEFT ||
+ eTblAdjust == SVX_ADJUST_RIGHT ||
+ pCurTable->HasToFly();
+
+ // Entweder kommt die Tabelle in keinen Rahmen und befindet
+ // sich in keinem Rahmen (wird also durch Zellen simuliert),
+ // oder es gibt bereits Inhalt an der entsprechenden Stelle.
+ ASSERT( !bForceFrame || pCurTable->HasParentSection(),
+ "Tabelle im Rahmen hat keine Umgebung!" );
+// SCHOEN WAER'S, aber wie bekommen den Inhalt nicht zurueck
+// in die umgebende Zelle
+// if( bForceFrame && !pCurTable->HasParentSection() )
+// {
+// pCurTable->SetParentContents(
+// InsertTableContents( sal_False, SVX_ADJUST_END ) );
+// pCurTable->SetHasParentSection( sal_True );
+// }
+
+ sal_Bool bAppend = sal_False;
+ if( bForceFrame )
+ {
+ // Wenn die Tabelle in einen Rahmen kommt, muss
+ // nur ein neuer Absatz aufgemacht werden, wenn
+ // der Absatz Rahmen ohne Umlauf enthaelt.
+ bAppend = HasCurrentParaFlys(sal_True);
+ }
+ else
+ {
+ // Sonst muss ein neuer Absatz aufgemacht werden,
+ // wenn der Absatz nicht leer ist, oder Rahmen
+ // oder text::Bookmarks enthaelt.
+ bAppend =
+ pPam->GetPoint()->nContent.GetIndex() ||
+ HasCurrentParaFlys() ||
+ HasCurrentParaBookmarks();
+ }
+ if( bAppend )
+ {
+ if( !pPam->GetPoint()->nContent.GetIndex() )
+ {
+ pDoc->SetTxtFmtColl( *pPam,
+ pCSS1Parser->GetTxtCollFromPool(RES_POOLCOLL_STANDARD) );
+ SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
+
+ _HTMLAttr* pTmp =
+ new _HTMLAttr( *pPam->GetPoint(), aFontHeight );
+ aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
+
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ pTmp = new _HTMLAttr( *pPam->GetPoint(), aFontHeight );
+ aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
+
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ pTmp = new _HTMLAttr( *pPam->GetPoint(), aFontHeight );
+ aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
+
+ pTmp = new _HTMLAttr( *pPam->GetPoint(),
+ SvxULSpaceItem( 0, 0, RES_UL_SPACE ) );
+ aSetAttrTab.Insert( pTmp, 0 ); // ja, 0, weil schon
+ // vom Tabellenende vorher
+ // was gesetzt sein kann.
+ }
+ AppendTxtNode( AM_NOSPACE );
+ bAppended = sal_True;
+ }
+ else if( aParaAttrs.Count() )
+ {
+ if( !bForceFrame )
+ {
+ // Der Absatz wird gleich hinter die Tabelle
+ // verschoben. Deshalb entfernen wir alle harten
+ // Attribute des Absatzes
+
+ for( sal_uInt16 i=0; i<aParaAttrs.Count(); i++ )
+ aParaAttrs[i]->Invalidate();
+ }
+
+ aParaAttrs.Remove( 0, aParaAttrs.Count() );
+ }
+
+ pSavePos = new SwPosition( *pPam->GetPoint() );
+ }
+ else if( pCurTable->HasParentSection() )
+ {
+ bParentLFStripped = StripTrailingLF() > 0;
+
+ // Absaetze bzw. ueberschriften beeenden
+ nOpenParaToken = 0;
+ nFontStHeadStart = nFontStMin;
+
+ // die harten Attribute an diesem Absatz werden nie mehr ungueltig
+ if( aParaAttrs.Count() )
+ aParaAttrs.Remove( 0, aParaAttrs.Count() );
+ }
+
+ // einen Tabellen Kontext anlegen
+ _HTMLTableContext *pTCntxt =
+ new _HTMLTableContext( pSavePos, nContextStMin,
+ nContextStAttrMin );
+
+ // alle noch offenen Attribute beenden und hinter der Tabelle
+ // neu aufspannen
+ _HTMLAttrs *pPostIts = 0;
+ if( !bForceFrame && (bTopTable || pCurTable->HasParentSection()) )
+ {
+ SplitAttrTab( pTCntxt->aAttrTab, bTopTable );
+ // Wenn wir einen schon vorhandenen Absatz verwenden, duerfen
+ // in den keine PostIts eingefuegt werden, weil der Absatz
+ // ja hinter die Tabelle wandert. Sie werden deshalb in den
+ // ersten Absatz der Tabelle verschoben.
+ // Bei Tabellen in Tabellen duerfen ebenfalls keine PostIts
+ // in einen noch leeren Absatz eingefuegt werden, weil
+ // der sonat nicht geloescht wird.
+ if( (bTopTable && !bAppended) ||
+ (!bTopTable && !bParentLFStripped &&
+ !pPam->GetPoint()->nContent.GetIndex()) )
+ pPostIts = new _HTMLAttrs;
+ SetAttr( bTopTable, bTopTable, pPostIts );
+ }
+ else
+ {
+ SaveAttrTab( pTCntxt->aAttrTab );
+ if( bTopTable && !bAppended )
+ {
+ pPostIts = new _HTMLAttrs;
+ SetAttr( sal_True, sal_True, pPostIts );
+ }
+ }
+ bNoParSpace = sal_False;
+
+ // Aktuelle Numerierung retten und auschalten.
+ pTCntxt->SetNumInfo( GetNumInfo() );
+ GetNumInfo().Clear();
+ pTCntxt->SavePREListingXMP( *this );
+
+ if( bTopTable )
+ {
+ if( bForceFrame )
+ {
+ // Die Tabelle soll in einen Rahmen geschaufelt werden.
+
+ SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !pCurTable->IsNewDoc() )
+ Reader::ResetFrmFmtAttrs( aFrmSet );
+
+ SwSurround eSurround = SURROUND_NONE;
+ sal_Int16 eHori;
+
+ switch( pCurTable->GetTableAdjust(sal_True) )
+ {
+ case SVX_ADJUST_RIGHT:
+ eHori = text::HoriOrientation::RIGHT;
+ eSurround = SURROUND_LEFT;
+ break;
+ case SVX_ADJUST_CENTER:
+ eHori = text::HoriOrientation::CENTER;
+ break;
+ case SVX_ADJUST_LEFT:
+ eSurround = SURROUND_RIGHT;
+ default:
+ eHori = text::HoriOrientation::LEFT;
+ break;
+ }
+ SetAnchorAndAdjustment( text::VertOrientation::NONE, eHori, aFrmSet,
+ sal_True );
+ aFrmSet.Put( SwFmtSurround(eSurround) );
+
+ SwFmtFrmSize aFrmSize( ATT_VAR_SIZE, 20*MM50, MINLAY );
+ aFrmSize.SetWidthPercent( 100 );
+ aFrmSet.Put( aFrmSize );
+
+ sal_uInt16 nSpace = pCurTable->GetHSpace();
+ if( nSpace )
+ aFrmSet.Put( SvxLRSpaceItem(nSpace,nSpace, 0, 0, RES_LR_SPACE) );
+ nSpace = pCurTable->GetVSpace();
+ if( nSpace )
+ aFrmSet.Put( SvxULSpaceItem(nSpace,nSpace, RES_UL_SPACE) );
+
+ RndStdIds eAnchorId = ((const SwFmtAnchor&)aFrmSet.
+ Get( RES_ANCHOR )).
+ GetAnchorId();
+ SwFrmFmt *pFrmFmt = pDoc->MakeFlySection(
+ eAnchorId, pPam->GetPoint(), &aFrmSet );
+
+ pTCntxt->SetFrmFmt( pFrmFmt );
+ const SwFmtCntnt& rFlyCntnt = pFrmFmt->GetCntnt();
+ pPam->GetPoint()->nNode = *rFlyCntnt.GetCntntIdx();
+ SwCntntNode *pCNd =
+ pDoc->GetNodes().GoNext( &(pPam->GetPoint()->nNode) );
+ pPam->GetPoint()->nContent.Assign( pCNd, 0 );
+
+ // automatisch verankerte Rahmen muessen noch um
+ // eine Position nach vorne verschoben werden.
+ //if( FLY_AUTO_CNTNT==eAnchorId )
+ // aMoveFlyFrms.C40_INSERT( SwFrmFmt, pFrmFmt,
+ // aMoveFlyFrms.Count() );
+ }
+
+ // eine SwTable mit einer Box anlegen und den PaM in den
+ // Inhalt der Box-Section bewegen (der Ausrichtungs-Parameter
+ // ist erstmal nur ein Dummy und wird spaeter noch richtig
+ // gesetzt)
+ ASSERT( !pPam->GetPoint()->nContent.GetIndex(),
+ "Der Absatz hinter der Tabelle ist nicht leer!" );
+ const SwTable* pSwTable = pDoc->InsertTable(
+ SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
+ *pPam->GetPoint(), 1, 1, text::HoriOrientation::LEFT );
+
+ if( bForceFrame )
+ {
+ SwNodeIndex aDstIdx( pPam->GetPoint()->nNode );
+ pPam->Move( fnMoveBackward );
+ pDoc->GetNodes().Delete( aDstIdx );
+ }
+ else
+ {
+ if( bStyleParsed )
+ {
+ pCSS1Parser->SetFmtBreak( aItemSet, aPropInfo );
+ pSwTable->GetFrmFmt()->SetFmtAttr( aItemSet );
+ }
+ pPam->Move( fnMoveBackward );
+ }
+
+ const SwNode *pNd = pDoc->GetNodes()[pPam->GetPoint()->nNode];
+ if( !bAppended && !bForceFrame )
+ {
+ SwTxtNode* pOldTxtNd =
+ pDoc->GetNodes()[pSavePos->nNode]->GetTxtNode();
+ ASSERT( pOldTxtNd, "Wieso stehen wir in keinem Txt-Node?" );
+ SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
+
+ const SfxPoolItem* pItem2;
+ if( SFX_ITEM_SET == pOldTxtNd->GetSwAttrSet()
+ .GetItemState( RES_PAGEDESC, sal_False, &pItem2 ) &&
+ ((SwFmtPageDesc *)pItem2)->GetPageDesc() )
+ {
+ pFrmFmt->SetFmtAttr( *pItem2 );
+ pOldTxtNd->ResetAttr( RES_PAGEDESC );
+ }
+ if( SFX_ITEM_SET == pOldTxtNd->GetSwAttrSet()
+ .GetItemState( RES_BREAK, sal_True, &pItem2 ) )
+ {
+ switch( ((SvxFmtBreakItem *)pItem2)->GetBreak() )
+ {
+ case SVX_BREAK_PAGE_BEFORE:
+ case SVX_BREAK_PAGE_AFTER:
+ case SVX_BREAK_PAGE_BOTH:
+ pFrmFmt->SetFmtAttr( *pItem2 );
+ pOldTxtNd->ResetAttr( RES_BREAK );
+ default:
+ ;
+ }
+ }
+ }
+
+ if( !bAppended && pPostIts )
+ {
+ // noch vorhandene PostIts in den ersten Absatz
+ // der Tabelle setzen
+ InsertAttrs( *pPostIts );
+ delete pPostIts;
+ pPostIts = 0;
+ }
+
+ pTCntxt->SetTableNode( (SwTableNode *)pNd->FindTableNode() );
+
+ pCurTable->SetTable( pTCntxt->GetTableNode(), pTCntxt,
+ nLeftSpace, nRightSpace,
+ pSwTable, bForceFrame );
+
+ ASSERT( !pPostIts, "ubenutzte PostIts" );
+ }
+ else
+ {
+ // noch offene Bereiche muessen noch entfernt werden
+ if( EndSections( bParentLFStripped ) )
+ bParentLFStripped = sal_False;
+
+ if( pCurTable->HasParentSection() )
+ {
+ // dannach entfernen wir ein ggf. zu viel vorhandenen
+ // leeren Absatz, aber nur, wenn er schon vor dem
+ // entfernen von LFs leer war
+ if( !bParentLFStripped )
+ StripTrailingPara();
+
+ if( pPostIts )
+ {
+ // noch vorhandene PostIts an das Ende des jetzt
+ // aktuellen Absatzes schieben
+ InsertAttrs( *pPostIts );
+ delete pPostIts;
+ pPostIts = 0;
+ }
+ }
+
+ const SwNode *pNd = pDoc->GetNodes()[pPam->GetPoint()->nNode];
+ const SwStartNode *pStNd = (pTable->bFirstCell ? pNd->FindTableNode()
+ : pNd->FindTableBoxStartNode() );
+
+ pCurTable->SetTable( pStNd, pTCntxt, nLeftSpace, nRightSpace );
+ }
+
+ // Den Kontext-Stack einfrieren, denn es koennen auch mal
+ // irgendwo ausserhalb von Zellen Attribute gesetzt werden.
+ // Darf nicht frueher passieren, weil eventuell noch im
+ // Stack gesucht wird!!!
+ nContextStMin = aContexts.Count();
+ nContextStAttrMin = nContextStMin;
+ }
+
+ pSaveStruct = new _CellSaveStruct( *this, pCurTable, bHead,
+ bReadOptions );
+
+ // ist beim ersten GetNextToken schon pending, muss bei
+ // wiederaufsetzen auf jedenfall neu gelesen werden!
+ SaveState( 0 );
+ }
+
+ if( !nToken )
+ nToken = GetNextToken(); // Token nach <TABLE>
+
+ sal_Bool bDone = sal_False;
+ while( (IsParserWorking() && !bDone) || bPending )
+ {
+ SaveState( nToken );
+
+ nToken = FilterToken( nToken );
+
+ ASSERT( pPendStack || !bCallNextToken || pSaveStruct->IsInSection(),
+ "Wo ist die Section gebieben?" );
+ if( !pPendStack && bCallNextToken && pSaveStruct->IsInSection() )
+ {
+ // NextToken direkt aufrufen (z.B. um den Inhalt von
+ // Floating-Frames oder Applets zu ignorieren)
+ NextToken( nToken );
+ }
+ else switch( nToken )
+ {
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ case HTML_TABLEROW_ON:
+ case HTML_TABLEROW_OFF:
+ case HTML_THEAD_ON:
+ case HTML_THEAD_OFF:
+ case HTML_TFOOT_ON:
+ case HTML_TFOOT_OFF:
+ case HTML_TBODY_ON:
+ case HTML_TBODY_OFF:
+ case HTML_TABLE_OFF:
+ SkipToken(-1);
+ case HTML_TABLEHEADER_OFF:
+ case HTML_TABLEDATA_OFF:
+ bDone = sal_True;
+ break;
+ case HTML_TABLE_ON:
+ {
+ sal_Bool bTopTable = sal_False;
+ sal_Bool bHasToFly = sal_False;
+ SvxAdjust eTabAdjust = SVX_ADJUST_END;
+ if( !pPendStack )
+ {
+ // nur wenn eine neue Tabelle aufgemacht wird, aber
+ // nicht wenn nach einem Pending in der Tabelle
+ // weitergelesen wird!
+ pSaveStruct->pTable = pTable;
+
+ // HACK: Eine Section fuer eine Tabelle anlegen, die
+ // in einen Rahmen kommt.
+ if( !pSaveStruct->IsInSection() )
+ {
+ // Diese Schleife muss vorwartes sein, weil die
+ // erste Option immer gewinnt.
+ sal_Bool bNeedsSection = sal_False;
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i=0; i<pHTMLOptions->Count(); i++ )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[i];
+ if( HTML_O_ALIGN==pOption->GetToken() )
+ {
+ SvxAdjust eAdjust =
+ (SvxAdjust)pOption->GetEnum(
+ aHTMLPAlignTable, SVX_ADJUST_END );
+ bNeedsSection = SVX_ADJUST_LEFT == eAdjust ||
+ SVX_ADJUST_RIGHT == eAdjust;
+ break;
+ }
+ }
+ if( bNeedsSection )
+ {
+ pSaveStruct->AddContents(
+ InsertTableContents(bHead ) );
+ }
+ }
+ else
+ {
+ // Wenn wir mitlerweile in einem Rahmen stehen
+ // koennen wir erneut eine echte Tabelle aufmachen.
+ // Wir erkennen das daran, dass wir keinen
+ // Tabellen-Node mehr finden.
+ bTopTable = pDoc->GetNodes()[pPam->GetPoint()->nNode]
+ ->FindTableNode() == 0;
+
+ // Wenn im aktuellen Absatz Flys verankert sind,
+ // muss die neue Tabelle in einen Rahmen.
+ bHasToFly = HasCurrentParaFlys(sal_False,sal_True);
+ }
+
+ // in der Zelle kann sich ein Bereich befinden!
+ eTabAdjust = aAttrTab.pAdjust
+ ? ((const SvxAdjustItem&)aAttrTab.pAdjust->GetItem()).
+ GetAdjust()
+ : SVX_ADJUST_END;
+ }
+
+ HTMLTable *pSubTable = BuildTable( eTabAdjust,
+ bHead,
+ pSaveStruct->IsInSection(),
+ bTopTable, bHasToFly );
+ if( SVPAR_PENDING != GetStatus() )
+ {
+ // nur wenn die Tabelle wirklich zu Ende ist!
+ if( pSubTable )
+ {
+ ASSERT( pSubTable->GetTableAdjust(sal_False)!= SVX_ADJUST_LEFT &&
+ pSubTable->GetTableAdjust(sal_False)!= SVX_ADJUST_RIGHT,
+ "links oder rechts ausgerichtete Tabellen gehoehren in Rahmen" );
+
+
+ HTMLTableCnts *pParentContents =
+ pSubTable->GetParentContents();
+ if( pParentContents )
+ {
+ ASSERT( !pSaveStruct->IsInSection(),
+ "Wo ist die Section geblieben" );
+
+ // Wenn jetzt keine Tabelle kommt haben wir eine
+ // Section
+ pSaveStruct->AddContents( pParentContents );
+ }
+
+ const SwStartNode *pCapStNd =
+ pSubTable->GetCaptionStartNode();
+
+ if( pSubTable->GetContext() )
+ {
+ ASSERT( !pSubTable->GetContext()->GetFrmFmt(),
+ "Tabelle steht im Rahmen" );
+
+ if( pCapStNd && pSubTable->IsTopCaption() )
+ {
+ pSaveStruct->AddContents(
+ new HTMLTableCnts(pCapStNd) );
+ }
+
+ pSaveStruct->AddContents(
+ new HTMLTableCnts(pSubTable) );
+
+ if( pCapStNd && !pSubTable->IsTopCaption() )
+ {
+ pSaveStruct->AddContents(
+ new HTMLTableCnts(pCapStNd) );
+ }
+
+ // Jetzt haben wir keine Section mehr
+ pSaveStruct->ClearIsInSection();
+ }
+ else if( pCapStNd )
+ {
+ // Da wir diese Sction nicht mehr loeschen
+ // koennen (sie koeente zur erster Box
+ // gehoeren), fuegen wir sie ein.
+ pSaveStruct->AddContents(
+ new HTMLTableCnts(pCapStNd) );
+
+ // Jetzt haben wir keine Section mehr
+ pSaveStruct->ClearIsInSection();
+ }
+ }
+
+ pTable = pSaveStruct->pTable;
+ }
+ }
+ break;
+
+ case HTML_NOBR_ON:
+ // HACK fuer MS: Steht das <NOBR> zu beginn der Zelle?
+ pSaveStruct->StartNoBreak( *pPam->GetPoint() );
+ break;
+
+ case HTML_NOBR_OFF:
+ pSaveStruct->EndNoBreak( *pPam->GetPoint() );
+ break;
+
+ case HTML_COMMENT:
+ // Mit Kommentar-Feldern werden Spaces nicht mehr geloescht
+ // ausserdem wollen wir fuer einen Kommentar keine neue Zelle
+ // anlegen !!!
+ NextToken( nToken );
+ break;
+
+ case HTML_MARQUEE_ON:
+ if( !pSaveStruct->IsInSection() )
+ {
+ // eine neue Section anlegen, der PaM steht dann darin
+ pSaveStruct->AddContents(
+ InsertTableContents( bHead ) );
+ }
+ bCallNextToken = sal_True;
+ NewMarquee( pCurTable );
+ break;
+
+ case HTML_TEXTTOKEN:
+ // keine Section fuer einen leeren String anlegen
+ if( !pSaveStruct->IsInSection() && 1==aToken.Len() &&
+ ' '==aToken.GetChar(0) )
+ break;
+ default:
+ if( !pSaveStruct->IsInSection() )
+ {
+ // eine neue Section anlegen, der PaM steht dann darin
+ pSaveStruct->AddContents(
+ InsertTableContents( bHead ) );
+ }
+
+ if( IsParserWorking() || bPending )
+ NextToken( nToken );
+ break;
+ }
+
+ ASSERT( !bPending || !pPendStack,
+ "SwHTMLParser::BuildTableCell: Es gibt wieder einen Pend-Stack" );
+ bPending = sal_False;
+ if( IsParserWorking() )
+ SaveState( 0 );
+
+ if( !bDone )
+ nToken = GetNextToken();
+ }
+
+ if( SVPAR_PENDING == GetStatus() )
+ {
+ pPendStack = new SwPendingStack( bHead ? HTML_TABLEHEADER_ON
+ : HTML_TABLEDATA_ON, pPendStack );
+ pPendStack->pData = pSaveStruct;
+
+ return;
+ }
+
+ // Falls der Inhalt der Zelle leer war, muessen wir noch einen
+ // leeren Inhalt anlegen. Ausserdem legen wir einen leeren Inhalt
+ // an, wenn die Zelle mit einer Tabelle aufgehoert hat und keine
+ // COL-Tags hatte (sonst wurde sie wahrscheinlich von uns exportiert,
+ // und dann wollen wir natuerlich keinen zusaetzlichen Absatz haben).
+ if( !pSaveStruct->GetFirstContents() ||
+ (!pSaveStruct->IsInSection() && !pCurTable->HasColTags()) )
+ {
+ ASSERT( pSaveStruct->GetFirstContents() ||
+ !pSaveStruct->IsInSection(),
+ "Section oder nicht, das ist hier die Frage" );
+ const SwStartNode *pStNd =
+ InsertTableSection( static_cast< USHORT >(pSaveStruct->IsHeaderCell()
+ ? RES_POOLCOLL_TABLE_HDLN
+ : RES_POOLCOLL_TABLE ));
+ const SwEndNode *pEndNd = pStNd->EndOfSectionNode();
+ SwCntntNode *pCNd = pDoc->GetNodes()[pEndNd->GetIndex()-1] ->GetCntntNode();
+ SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ pCNd->SetAttr( aFontHeight );
+
+ pSaveStruct->AddContents( new HTMLTableCnts(pStNd) );
+ pSaveStruct->ClearIsInSection();
+ }
+
+ if( pSaveStruct->IsInSection() )
+ {
+ pSaveStruct->CheckNoBreak( *pPam->GetPoint(), pDoc );
+
+ // Alle noch offenen Kontexte beenden. Wir nehmen hier
+ // AttrMin, weil nContxtStMin evtl. veraendert wurde.
+ // Da es durch EndContext wieder restauriert wird, geht das.
+ while( aContexts.Count() > nContextStAttrMin+1 )
+ {
+ _HTMLAttrContext *pCntxt = PopContext();
+ EndContext( pCntxt );
+ delete pCntxt;
+ }
+
+ // LFs am Absatz-Ende entfernen
+ if( StripTrailingLF()==0 && !pPam->GetPoint()->nContent.GetIndex() )
+ StripTrailingPara();
+
+ // falls fuer die Zelle eine Ausrichtung gesetzt wurde, muessen
+ // wir die beenden
+ _HTMLAttrContext *pCntxt = PopContext();
+ EndContext( pCntxt );
+ delete pCntxt;
+ }
+ else
+ {
+ // Alle noch offenen Kontexte beenden
+ while( aContexts.Count() > nContextStAttrMin )
+ {
+ _HTMLAttrContext *pCntxt = PopContext();
+ ClearContext( pCntxt );
+ delete pCntxt;
+ }
+ }
+
+ // auch eine Numerierung muss beendet werden
+ GetNumInfo().Clear();
+
+ SetAttr( sal_False );
+
+ pSaveStruct->InsertCell( *this, pCurTable );
+
+ // wir stehen jetzt (wahrschenlich) vor <TH>, <TD>, <TR> oder </TABLE>
+ delete pSaveStruct;
+}
+
+
+class _RowSaveStruct : public SwPendingStackData
+{
+public:
+ SvxAdjust eAdjust;
+ sal_Int16 eVertOri;
+ sal_Bool bHasCells;
+
+ _RowSaveStruct() :
+ eAdjust( SVX_ADJUST_END ), eVertOri( text::VertOrientation::TOP ), bHasCells( sal_False )
+ {}
+};
+
+
+void SwHTMLParser::BuildTableRow( HTMLTable *pCurTable, sal_Bool bReadOptions,
+ SvxAdjust eGrpAdjust,
+ sal_Int16 eGrpVertOri )
+{
+ // <TR> wurde bereist gelesen
+
+ if( !IsParserWorking() && !pPendStack )
+ return;
+
+ int nToken = 0;
+ _RowSaveStruct* pSaveStruct;
+
+ sal_Bool bPending = sal_False;
+ if( pPendStack )
+ {
+ pSaveStruct = (_RowSaveStruct*)pPendStack->pData;
+
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+ nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
+ bPending = SVPAR_ERROR == eState && pPendStack != 0;
+
+ SaveState( nToken );
+ }
+ else
+ {
+ SvxAdjust eAdjust = eGrpAdjust;
+ sal_Int16 eVertOri = eGrpVertOri;
+ Color aBGColor;
+ String aBGImage, aStyle, aId, aClass;
+ sal_Bool bBGColor = sal_False;
+ pSaveStruct = new _RowSaveStruct;
+
+ if( bReadOptions )
+ {
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_ALIGN:
+ eAdjust = (SvxAdjust)pOption->GetEnum(
+ aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
+ break;
+ case HTML_O_VALIGN:
+ eVertOri = pOption->GetEnum(
+ aHTMLTblVAlignTable, eVertOri );
+ break;
+ case HTML_O_BGCOLOR:
+ // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netsc.
+ // ignorieren, bei allen anderen Tags *wirklich* nicht.
+ if( pOption->GetString().Len() )
+ {
+ pOption->GetColor( aBGColor );
+ bBGColor = sal_True;
+ }
+ break;
+ case HTML_O_BACKGROUND:
+ aBGImage = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass= pOption->GetString();
+ break;
+ }
+ }
+ }
+
+ if( aId.Len() )
+ InsertBookmark( aId );
+
+ SvxBrushItem *pBrushItem =
+ CreateBrushItem( bBGColor ? &aBGColor : 0, aBGImage, aStyle,
+ aId, aClass );
+ pCurTable->OpenRow( eAdjust, eVertOri, pBrushItem );
+ // ist beim ersten GetNextToken schon pending, muss bei
+ // wiederaufsetzen auf jedenfall neu gelesen werden!
+ SaveState( 0 );
+ }
+
+ if( !nToken )
+ nToken = GetNextToken(); // naechstes Token
+
+ sal_Bool bDone = sal_False;
+ while( (IsParserWorking() && !bDone) || bPending )
+ {
+ SaveState( nToken );
+
+ nToken = FilterToken( nToken );
+
+ ASSERT( pPendStack || !bCallNextToken ||
+ pCurTable->GetContext() || pCurTable->HasParentSection(),
+ "Wo ist die Section gebieben?" );
+ if( !pPendStack && bCallNextToken &&
+ (pCurTable->GetContext() || pCurTable->HasParentSection()) )
+ {
+ // NextToken direkt aufrufen (z.B. um den Inhalt von
+ // Floating-Frames oder Applets zu ignorieren)
+ NextToken( nToken );
+ }
+ else switch( nToken )
+ {
+ case HTML_TABLE_ON:
+ if( !pCurTable->GetContext() )
+ {
+ SkipToken( -1 );
+ bDone = sal_True;
+ }
+// else
+// {
+// NextToken( nToken );
+// }
+ break;
+ case HTML_TABLEROW_ON:
+ case HTML_THEAD_ON:
+ case HTML_THEAD_OFF:
+ case HTML_TBODY_ON:
+ case HTML_TBODY_OFF:
+ case HTML_TFOOT_ON:
+ case HTML_TFOOT_OFF:
+ case HTML_TABLE_OFF:
+ SkipToken( -1 );
+ case HTML_TABLEROW_OFF:
+ bDone = sal_True;
+ break;
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ BuildTableCell( pCurTable, sal_True, HTML_TABLEHEADER_ON==nToken );
+ if( SVPAR_PENDING != GetStatus() )
+ {
+ pSaveStruct->bHasCells = sal_True;
+ bDone = pTable->IsOverflowing();
+ }
+ break;
+ case HTML_CAPTION_ON:
+ BuildTableCaption( pCurTable );
+ bDone = pTable->IsOverflowing();
+ break;
+ case HTML_CAPTION_OFF:
+ case HTML_TABLEHEADER_OFF:
+ case HTML_TABLEDATA_OFF:
+ case HTML_COLGROUP_ON:
+ case HTML_COLGROUP_OFF:
+ case HTML_COL_ON:
+ case HTML_COL_OFF:
+ // wo keine Zelle anfing kann auch keine aufhoehren, oder?
+ // und die ganzen anderen Tokens haben hier auch nicht zu
+ // suchen und machen nur die Tabelle kaputt
+ break;
+ case HTML_MULTICOL_ON:
+ // spaltige Rahmen koennen wir hier leider nicht einguegen
+ break;
+ case HTML_FORM_ON:
+ NewForm( sal_False ); // keinen neuen Absatz aufmachen!
+ break;
+ case HTML_FORM_OFF:
+ EndForm( sal_False ); // keinen neuen Absatz aufmachen!
+ break;
+ case HTML_COMMENT:
+ NextToken( nToken );
+ break;
+ case HTML_MAP_ON:
+ // eine Image-Map fuegt nichts ein, deshalb koennen wir sie
+ // problemlos auch ohne Zelle parsen
+ NextToken( nToken );
+ break;
+ case HTML_TEXTTOKEN:
+ if( (pCurTable->GetContext() ||
+ !pCurTable->HasParentSection()) &&
+ 1==aToken.Len() && ' '==aToken.GetChar(0) )
+ break;
+ default:
+ pCurTable->MakeParentContents();
+ NextToken( nToken );
+ break;
+ }
+
+ ASSERT( !bPending || !pPendStack,
+ "SwHTMLParser::BuildTableRow: Es gibt wieder einen Pend-Stack" );
+ bPending = sal_False;
+ if( IsParserWorking() )
+ SaveState( 0 );
+
+ if( !bDone )
+ nToken = GetNextToken();
+ }
+
+ if( SVPAR_PENDING == GetStatus() )
+ {
+ pPendStack = new SwPendingStack( HTML_TABLEROW_ON, pPendStack );
+ pPendStack->pData = pSaveStruct;
+ }
+ else
+ {
+ pCurTable->CloseRow( !pSaveStruct->bHasCells );
+ delete pSaveStruct;
+ }
+
+ // wir stehen jetzt (wahrscheinlich) vor <TR> oder </TABLE>
+}
+
+void SwHTMLParser::BuildTableSection( HTMLTable *pCurTable,
+ sal_Bool bReadOptions,
+ sal_Bool bHead )
+{
+ // <THEAD>, <TBODY> bzw. <TFOOT> wurde bereits gelesen
+ if( !IsParserWorking() && !pPendStack )
+ return;
+
+ int nToken = 0;
+ sal_Bool bPending = sal_False;
+ _RowSaveStruct* pSaveStruct;
+
+ if( pPendStack )
+ {
+ pSaveStruct = (_RowSaveStruct*)pPendStack->pData;
+
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+ nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
+ bPending = SVPAR_ERROR == eState && pPendStack != 0;
+
+ SaveState( nToken );
+ }
+ else
+ {
+ pSaveStruct = new _RowSaveStruct;
+
+ if( bReadOptions )
+ {
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ InsertBookmark( pOption->GetString() );
+ break;
+ case HTML_O_ALIGN:
+ pSaveStruct->eAdjust =
+ (SvxAdjust)pOption->GetEnum( aHTMLPAlignTable,
+ static_cast< sal_uInt16 >(pSaveStruct->eAdjust) );
+ break;
+ case HTML_O_VALIGN:
+ pSaveStruct->eVertOri =
+ pOption->GetEnum( aHTMLTblVAlignTable,
+ pSaveStruct->eVertOri );
+ break;
+ }
+ }
+ }
+
+ // ist beim ersten GetNextToken schon pending, muss bei
+ // wiederaufsetzen auf jedenfall neu gelesen werden!
+ SaveState( 0 );
+ }
+
+ if( !nToken )
+ nToken = GetNextToken(); // naechstes Token
+
+ sal_Bool bDone = sal_False;
+ while( (IsParserWorking() && !bDone) || bPending )
+ {
+ SaveState( nToken );
+
+ nToken = FilterToken( nToken );
+
+ ASSERT( pPendStack || !bCallNextToken ||
+ pCurTable->GetContext() || pCurTable->HasParentSection(),
+ "Wo ist die Section gebieben?" );
+ if( !pPendStack && bCallNextToken &&
+ (pCurTable->GetContext() || pCurTable->HasParentSection()) )
+ {
+ // NextToken direkt aufrufen (z.B. um den Inhalt von
+ // Floating-Frames oder Applets zu ignorieren)
+ NextToken( nToken );
+ }
+ else switch( nToken )
+ {
+ case HTML_TABLE_ON:
+ if( !pCurTable->GetContext() )
+ {
+ SkipToken( -1 );
+ bDone = sal_True;
+ }
+// else
+// {
+// NextToken( nToken );
+// }
+ break;
+ case HTML_THEAD_ON:
+ case HTML_TFOOT_ON:
+ case HTML_TBODY_ON:
+ case HTML_TABLE_OFF:
+ SkipToken( -1 );
+ case HTML_THEAD_OFF:
+ case HTML_TBODY_OFF:
+ case HTML_TFOOT_OFF:
+ bDone = sal_True;
+ break;
+ case HTML_CAPTION_ON:
+ BuildTableCaption( pCurTable );
+ bDone = pTable->IsOverflowing();
+ break;
+ case HTML_CAPTION_OFF:
+ break;
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ SkipToken( -1 );
+ BuildTableRow( pCurTable, sal_False, pSaveStruct->eAdjust,
+ pSaveStruct->eVertOri );
+ bDone = pTable->IsOverflowing();
+ break;
+ case HTML_TABLEROW_ON:
+ BuildTableRow( pCurTable, sal_True, pSaveStruct->eAdjust,
+ pSaveStruct->eVertOri );
+ bDone = pTable->IsOverflowing();
+ break;
+ case HTML_MULTICOL_ON:
+ // spaltige Rahmen koennen wir hier leider nicht einguegen
+ break;
+ case HTML_FORM_ON:
+ NewForm( sal_False ); // keinen neuen Absatz aufmachen!
+ break;
+ case HTML_FORM_OFF:
+ EndForm( sal_False ); // keinen neuen Absatz aufmachen!
+ break;
+ case HTML_TEXTTOKEN:
+ // Blank-Strings sind Folge von CR+LF und kein Text
+ if( (pCurTable->GetContext() ||
+ !pCurTable->HasParentSection()) &&
+ 1==aToken.Len() && ' '==aToken.GetChar(0) )
+ break;
+ default:
+ pCurTable->MakeParentContents();
+ NextToken( nToken );
+ }
+
+ ASSERT( !bPending || !pPendStack,
+ "SwHTMLParser::BuildTableSection: Es gibt wieder einen Pend-Stack" );
+ bPending = sal_False;
+ if( IsParserWorking() )
+ SaveState( 0 );
+
+ if( !bDone )
+ nToken = GetNextToken();
+ }
+
+ if( SVPAR_PENDING == GetStatus() )
+ {
+ pPendStack = new SwPendingStack( bHead ? HTML_THEAD_ON
+ : HTML_TBODY_ON, pPendStack );
+ pPendStack->pData = pSaveStruct;
+ }
+ else
+ {
+ pCurTable->CloseSection( bHead );
+ delete pSaveStruct;
+ }
+
+ // wir stehen jetzt (wahrscheinlich) vor <TBODY>,... oder </TABLE>
+}
+
+struct _TblColGrpSaveStruct : public SwPendingStackData
+{
+ sal_uInt16 nColGrpSpan;
+ sal_uInt16 nColGrpWidth;
+ sal_Bool bRelColGrpWidth;
+ SvxAdjust eColGrpAdjust;
+ sal_Int16 eColGrpVertOri;
+
+ inline _TblColGrpSaveStruct();
+
+
+ inline void CloseColGroup( HTMLTable *pTable );
+};
+
+inline _TblColGrpSaveStruct::_TblColGrpSaveStruct() :
+ nColGrpSpan( 1 ), nColGrpWidth( 0 ),
+ bRelColGrpWidth( sal_False ), eColGrpAdjust( SVX_ADJUST_END ),
+ eColGrpVertOri( text::VertOrientation::TOP )
+{}
+
+
+inline void _TblColGrpSaveStruct::CloseColGroup( HTMLTable *pTable )
+{
+ pTable->CloseColGroup( nColGrpSpan, nColGrpWidth,
+ bRelColGrpWidth, eColGrpAdjust, eColGrpVertOri );
+}
+
+void SwHTMLParser::BuildTableColGroup( HTMLTable *pCurTable,
+ sal_Bool bReadOptions )
+{
+ // <COLGROUP> wurde bereits gelesen, wenn bReadOptions
+
+ if( !IsParserWorking() && !pPendStack )
+ return;
+
+ int nToken = 0;
+ sal_Bool bPending = sal_False;
+ _TblColGrpSaveStruct* pSaveStruct;
+
+ if( pPendStack )
+ {
+ pSaveStruct = (_TblColGrpSaveStruct*)pPendStack->pData;
+
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+ nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
+ bPending = SVPAR_ERROR == eState && pPendStack != 0;
+
+ SaveState( nToken );
+ }
+ else
+ {
+
+ pSaveStruct = new _TblColGrpSaveStruct;
+ if( bReadOptions )
+ {
+ const HTMLOptions *pColGrpOptions = GetOptions();
+ for( sal_uInt16 i = pColGrpOptions->Count(); i; )
+ {
+ const HTMLOption *pColGrpOption = (*pColGrpOptions)[--i];
+ switch( pColGrpOption->GetToken() )
+ {
+ case HTML_O_ID:
+ InsertBookmark( pColGrpOption->GetString() );
+ break;
+ case HTML_O_SPAN:
+ pSaveStruct->nColGrpSpan = (sal_uInt16)pColGrpOption->GetNumber();
+ break;
+ case HTML_O_WIDTH:
+ pSaveStruct->nColGrpWidth = (sal_uInt16)pColGrpOption->GetNumber();
+ pSaveStruct->bRelColGrpWidth =
+ (pColGrpOption->GetString().Search('*') != STRING_NOTFOUND);
+ break;
+ case HTML_O_ALIGN:
+ pSaveStruct->eColGrpAdjust =
+ (SvxAdjust)pColGrpOption->GetEnum( aHTMLPAlignTable,
+ static_cast< sal_uInt16 >(pSaveStruct->eColGrpAdjust) );
+ break;
+ case HTML_O_VALIGN:
+ pSaveStruct->eColGrpVertOri =
+ pColGrpOption->GetEnum( aHTMLTblVAlignTable,
+ pSaveStruct->eColGrpVertOri );
+ break;
+ }
+ }
+ }
+ // ist beim ersten GetNextToken schon pending, muss bei
+ // wiederaufsetzen auf jedenfall neu gelesen werden!
+ SaveState( 0 );
+ }
+
+ if( !nToken )
+ nToken = GetNextToken(); // naechstes Token
+
+ sal_Bool bDone = sal_False;
+ while( (IsParserWorking() && !bDone) || bPending )
+ {
+ SaveState( nToken );
+
+ nToken = FilterToken( nToken );
+
+ ASSERT( pPendStack || !bCallNextToken ||
+ pCurTable->GetContext() || pCurTable->HasParentSection(),
+ "Wo ist die Section gebieben?" );
+ if( !pPendStack && bCallNextToken &&
+ (pCurTable->GetContext() || pCurTable->HasParentSection()) )
+ {
+ // NextToken direkt aufrufen (z.B. um den Inhalt von
+ // Floating-Frames oder Applets zu ignorieren)
+ NextToken( nToken );
+ }
+ else switch( nToken )
+ {
+ case HTML_TABLE_ON:
+ if( !pCurTable->GetContext() )
+ {
+ SkipToken( -1 );
+ bDone = sal_True;
+ }
+// else
+// {
+// NextToken( nToken );
+// }
+ break;
+ case HTML_COLGROUP_ON:
+ case HTML_THEAD_ON:
+ case HTML_TFOOT_ON:
+ case HTML_TBODY_ON:
+ case HTML_TABLEROW_ON:
+ case HTML_TABLE_OFF:
+ SkipToken( -1 );
+ case HTML_COLGROUP_OFF:
+ bDone = sal_True;
+ break;
+ case HTML_COL_ON:
+ {
+ sal_uInt16 nColSpan = 1;
+ sal_uInt16 nColWidth = pSaveStruct->nColGrpWidth;
+ sal_Bool bRelColWidth = pSaveStruct->bRelColGrpWidth;
+ SvxAdjust eColAdjust = pSaveStruct->eColGrpAdjust;
+ sal_Int16 eColVertOri = pSaveStruct->eColGrpVertOri;
+
+ const HTMLOptions *pColOptions = GetOptions();
+ for( sal_uInt16 i = pColOptions->Count(); i; )
+ {
+ const HTMLOption *pColOption = (*pColOptions)[--i];
+ switch( pColOption->GetToken() )
+ {
+ case HTML_O_ID:
+ InsertBookmark( pColOption->GetString() );
+ break;
+ case HTML_O_SPAN:
+ nColSpan = (sal_uInt16)pColOption->GetNumber();
+ break;
+ case HTML_O_WIDTH:
+ nColWidth = (sal_uInt16)pColOption->GetNumber();
+ bRelColWidth =
+ (pColOption->GetString().Search('*') != STRING_NOTFOUND);
+ break;
+ case HTML_O_ALIGN:
+ eColAdjust =
+ (SvxAdjust)pColOption->GetEnum( aHTMLPAlignTable,
+ static_cast< sal_uInt16 >(eColAdjust) );
+ break;
+ case HTML_O_VALIGN:
+ eColVertOri =
+ pColOption->GetEnum( aHTMLTblVAlignTable,
+ eColVertOri );
+ break;
+ }
+ }
+ pCurTable->InsertCol( nColSpan, nColWidth, bRelColWidth,
+ eColAdjust, eColVertOri );
+
+ // die Angaben in <COLGRP> sollen ignoriert werden, wenn
+ // <COL>-Elemente existieren
+ pSaveStruct->nColGrpSpan = 0;
+ }
+ break;
+ case HTML_COL_OFF:
+ break; // Ignorieren
+ case HTML_MULTICOL_ON:
+ // spaltige Rahmen koennen wir hier leider nicht einguegen
+ break;
+ case HTML_TEXTTOKEN:
+ if( (pCurTable->GetContext() ||
+ !pCurTable->HasParentSection()) &&
+ 1==aToken.Len() && ' '==aToken.GetChar(0) )
+ break;
+ default:
+ pCurTable->MakeParentContents();
+ NextToken( nToken );
+ }
+
+ ASSERT( !bPending || !pPendStack,
+ "SwHTMLParser::BuildTableColGrp: Es gibt wieder einen Pend-Stack" );
+ bPending = sal_False;
+ if( IsParserWorking() )
+ SaveState( 0 );
+
+ if( !bDone )
+ nToken = GetNextToken();
+ }
+
+ if( SVPAR_PENDING == GetStatus() )
+ {
+ pPendStack = new SwPendingStack( HTML_COL_ON, pPendStack );
+ pPendStack->pData = pSaveStruct;
+ }
+ else
+ {
+ pSaveStruct->CloseColGroup( pCurTable );
+ delete pSaveStruct;
+ }
+}
+
+class _CaptionSaveStruct : public _SectionSaveStruct
+{
+ SwPosition aSavePos;
+ SwHTMLNumRuleInfo aNumRuleInfo; // gueltige Numerierung
+
+public:
+
+ _HTMLAttrTable aAttrTab; // und die Attribute
+
+ _CaptionSaveStruct( SwHTMLParser& rParser, const SwPosition& rPos ) :
+ _SectionSaveStruct( rParser ), aSavePos( rPos )
+ {
+ rParser.SaveAttrTab( aAttrTab );
+
+ // Die aktuelle Numerierung wurde gerettet und muss nur
+ // noch beendet werden.
+ aNumRuleInfo.Set( rParser.GetNumInfo() );
+ rParser.GetNumInfo().Clear();
+ }
+
+ const SwPosition& GetPos() const { return aSavePos; }
+
+ void RestoreAll( SwHTMLParser& rParser )
+ {
+ // Die alten Stack wiederherstellen
+ Restore( rParser );
+
+ // Die alte Attribut-Tabelle wiederherstellen
+ rParser.RestoreAttrTab( aAttrTab );
+
+ // Die alte Numerierung wieder aufspannen
+ rParser.GetNumInfo().Set( aNumRuleInfo );
+ }
+
+ virtual ~_CaptionSaveStruct();
+};
+
+_CaptionSaveStruct::~_CaptionSaveStruct()
+{}
+
+void SwHTMLParser::BuildTableCaption( HTMLTable *pCurTable )
+{
+ // <CAPTION> wurde bereits gelesen
+
+ if( !IsParserWorking() && !pPendStack )
+ return;
+
+ int nToken = 0;
+ _CaptionSaveStruct* pSaveStruct;
+
+ if( pPendStack )
+ {
+ pSaveStruct = (_CaptionSaveStruct*)pPendStack->pData;
+
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+ nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
+ ASSERT( !pPendStack, "Wo kommt hier ein Pending-Stack her?" );
+
+ SaveState( nToken );
+ }
+ else
+ {
+ if( pTable->IsOverflowing() )
+ {
+ SaveState( 0 );
+ return;
+ }
+
+ sal_Bool bTop = sal_True;
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for ( sal_uInt16 i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ if( HTML_O_ALIGN == pOption->GetToken() )
+ {
+ if( pOption->GetString().EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_VA_bottom))
+ bTop = sal_False;
+ }
+ }
+
+ // Alte PaM-Position retten.
+ pSaveStruct = new _CaptionSaveStruct( *this, *pPam->GetPoint() );
+
+ // Eine Text-Section im Icons-Bereich als Container fuer die
+ // Ueberschrift anlegen und PaM dort reinstellen.
+ const SwStartNode *pStNd;
+ if( pTable == pCurTable )
+ pStNd = InsertTempTableCaptionSection();
+ else
+ pStNd = InsertTableSection( RES_POOLCOLL_TEXT );
+
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_CAPTION_ON );
+
+ // Tabellen-Ueberschriften sind immer zentriert.
+ NewAttr( &aAttrTab.pAdjust, SvxAdjustItem(SVX_ADJUST_CENTER, RES_PARATR_ADJUST) );
+
+ _HTMLAttrs &rAttrs = pCntxt->GetAttrs();
+ rAttrs.Insert( aAttrTab.pAdjust, rAttrs.Count() );
+
+ PushContext( pCntxt );
+
+ // StartNode der Section an der Tabelle merken.
+ pCurTable->SetCaption( pStNd, bTop );
+
+ // ist beim ersten GetNextToken schon pending, muss bei
+ // wiederaufsetzen auf jedenfall neu gelesen werden!
+ SaveState( 0 );
+ }
+
+ if( !nToken )
+ nToken = GetNextToken(); // naechstes Token
+
+ // </CAPTION> wird laut DTD benoetigt
+ sal_Bool bDone = sal_False;
+ while( IsParserWorking() && !bDone )
+ {
+ SaveState( nToken );
+
+ nToken = FilterToken( nToken );
+
+ switch( nToken )
+ {
+ case HTML_TABLE_ON:
+ if( !pPendStack )
+ {
+ pSaveStruct->pTable = pTable;
+ sal_Bool bHasToFly = pSaveStruct->pTable!=pCurTable;
+ BuildTable( pCurTable->GetTableAdjust( sal_True ),
+ sal_False, sal_True, sal_True, bHasToFly );
+ }
+ else
+ {
+ BuildTable( SVX_ADJUST_END );
+ }
+ if( SVPAR_PENDING != GetStatus() )
+ {
+ pTable = pSaveStruct->pTable;
+ }
+ break;
+ case HTML_TABLE_OFF:
+ case HTML_COLGROUP_ON:
+ case HTML_THEAD_ON:
+ case HTML_TFOOT_ON:
+ case HTML_TBODY_ON:
+ case HTML_TABLEROW_ON:
+ SkipToken( -1 );
+ bDone = sal_True;
+ break;
+
+ case HTML_CAPTION_OFF:
+ bDone = sal_True;
+ break;
+ default:
+ int nNxtToken = nToken;
+ if( pPendStack )
+ {
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+
+ ASSERT( !pTmp, "weiter kann es nicht gehen!" );
+ nNxtToken = 0; // neu lesen
+ }
+
+ if( IsParserWorking() )
+ NextToken( nToken );
+ break;
+ }
+
+ if( IsParserWorking() )
+ SaveState( 0 );
+
+ if( !bDone )
+ nToken = GetNextToken();
+ }
+
+ if( SVPAR_PENDING==GetStatus() )
+ {
+ pPendStack = new SwPendingStack( HTML_CAPTION_ON, pPendStack );
+ pPendStack->pData = pSaveStruct;
+ return;
+ }
+
+ // Alle noch offenen Kontexte beenden
+ while( aContexts.Count() > nContextStAttrMin+1 )
+ {
+ _HTMLAttrContext *pCntxt = PopContext();
+ EndContext( pCntxt );
+ delete pCntxt;
+ }
+
+ // LF am Absatz-Ende entfernen
+ sal_Bool bLFStripped = StripTrailingLF() > 0;
+
+ if( pTable==pCurTable )
+ {
+ // Beim spaeteren verschieben der Beschriftung vor oder hinter
+ // die Tabelle wird der letzte Absatz nicht mitverschoben.
+ // Deshalb muss sich am Ende der Section immer ein leerer
+ // Absatz befinden.
+ if( pPam->GetPoint()->nContent.GetIndex() || bLFStripped )
+ AppendTxtNode( AM_NOSPACE );
+ }
+ else
+ {
+ // LFs am Absatz-Ende entfernen
+ if( !pPam->GetPoint()->nContent.GetIndex() && !bLFStripped )
+ StripTrailingPara();
+ }
+
+ // falls fuer die Zelle eine Ausrichtung gesetzt wurde, muessen
+ // wir die beenden
+ _HTMLAttrContext *pCntxt = PopContext();
+ EndContext( pCntxt );
+ delete pCntxt;
+
+ SetAttr( sal_False );
+
+ // Stacks und Attribut-Tabelle wiederherstellen
+ pSaveStruct->RestoreAll( *this );
+
+ // PaM wiederherstellen.
+ *pPam->GetPoint() = pSaveStruct->GetPos();
+
+ delete pSaveStruct;
+}
+
+class _TblSaveStruct : public SwPendingStackData
+{
+public:
+ HTMLTable *pCurTable;
+
+ _TblSaveStruct( HTMLTable *pCurTbl ) :
+ pCurTable( pCurTbl )
+ {}
+
+ virtual ~_TblSaveStruct();
+
+ // Aufbau der Tabelle anstossen und die Tabelle ggf. in einen
+ // Rahmen packen. Wenn sal_True zurueckgegeben wird muss noch ein
+ // Absatz eingefuegt werden!
+ void MakeTable( sal_uInt16 nWidth, SwPosition& rPos, SwDoc *pDoc );
+};
+
+_TblSaveStruct::~_TblSaveStruct()
+{}
+
+
+void _TblSaveStruct::MakeTable( sal_uInt16 nWidth, SwPosition& rPos, SwDoc *pDoc )
+{
+ pCurTable->MakeTable( 0, nWidth );
+
+ _HTMLTableContext *pTCntxt = pCurTable->GetContext();
+ ASSERT( pTCntxt, "Wo ist der Tabellen-Kontext" );
+
+ SwTableNode *pTblNd = pTCntxt->GetTableNode();
+ ASSERT( pTblNd, "Wo ist der Tabellen-Node" );
+
+ if( pDoc->GetRootFrm() && pTblNd )
+ {
+ // Existiert schon ein Layout, dann muss an dieser Tabelle die
+ // BoxFrames neu erzeugt werden.
+
+ if( pTCntxt->GetFrmFmt() )
+ {
+ pTCntxt->GetFrmFmt()->DelFrms();
+ pTblNd->DelFrms();
+ pTCntxt->GetFrmFmt()->MakeFrms();
+ }
+ else
+ {
+ pTblNd->DelFrms();
+ SwNodeIndex aIdx( *pTblNd->EndOfSectionNode(), 1 );
+ ASSERT( aIdx.GetIndex() <= pTCntxt->GetPos()->nNode.GetIndex(),
+ "unerwarteter Node fuer das Tabellen-Layout" );
+ pTblNd->MakeFrms( &aIdx );
+ }
+ }
+
+ rPos = *pTCntxt->GetPos();
+}
+
+
+HTMLTableOptions::HTMLTableOptions( const HTMLOptions *pOptions,
+ SvxAdjust eParentAdjust ) :
+ nCols( 0 ),
+ nWidth( 0 ), nHeight( 0 ),
+ nCellPadding( USHRT_MAX ), nCellSpacing( USHRT_MAX ),
+ nBorder( USHRT_MAX ),
+ nHSpace( 0 ), nVSpace( 0 ),
+ eAdjust( eParentAdjust ), eVertOri( text::VertOrientation::CENTER ),
+ eFrame( HTML_TF_VOID ), eRules( HTML_TR_NONE ),
+ bPrcWidth( sal_False ),
+ bTableAdjust( sal_False ),
+ bBGColor( sal_False ),
+ aBorderColor( COL_GRAY )
+{
+ sal_Bool bBorderColor = sal_False;
+ sal_Bool bHasFrame = sal_False, bHasRules = sal_False;
+
+ for( sal_uInt16 i = pOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_COLS:
+ nCols = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_WIDTH:
+ nWidth = (sal_uInt16)pOption->GetNumber();
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ if( bPrcWidth && nWidth>100 )
+ nWidth = 100;
+ break;
+ case HTML_O_HEIGHT:
+ nHeight = (sal_uInt16)pOption->GetNumber();
+ if( pOption->GetString().Search('%') != STRING_NOTFOUND )
+ nHeight = 0; // keine %-Anagben benutzen!!!
+ break;
+ case HTML_O_CELLPADDING:
+ nCellPadding = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_CELLSPACING:
+ nCellSpacing = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_ALIGN:
+ {
+ sal_uInt16 nAdjust = static_cast< sal_uInt16 >(eAdjust);
+ if( pOption->GetEnum( nAdjust, aHTMLPAlignTable ) )
+ {
+ eAdjust = (SvxAdjust)nAdjust;
+ bTableAdjust = sal_True;
+ }
+ }
+ break;
+ case HTML_O_VALIGN:
+ eVertOri = pOption->GetEnum( aHTMLTblVAlignTable, eVertOri );
+ break;
+ case HTML_O_BORDER:
+ // BORDER und BORDER=BORDER wie BORDER=1 behandeln
+ if( pOption->GetString().Len() &&
+ !pOption->GetString().EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_O_border) )
+ nBorder = (sal_uInt16)pOption->GetNumber();
+ else
+ nBorder = 1;
+
+ if( !bHasFrame )
+ eFrame = ( nBorder ? HTML_TF_BOX : HTML_TF_VOID );
+ if( !bHasRules )
+ eRules = ( nBorder ? HTML_TR_ALL : HTML_TR_NONE );
+ break;
+ case HTML_O_FRAME:
+ eFrame = pOption->GetTableFrame();
+ bHasFrame = sal_True;
+ break;
+ case HTML_O_RULES:
+ eRules = pOption->GetTableRules();
+ bHasRules = sal_True;
+ break;
+ case HTML_O_BGCOLOR:
+ // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netscape
+ // ignorieren, bei allen anderen Tags *wirklich* nicht.
+ if( pOption->GetString().Len() )
+ {
+ pOption->GetColor( aBGColor );
+ bBGColor = sal_True;
+ }
+ break;
+ case HTML_O_BACKGROUND:
+ aBGImage = pOption->GetString();
+ break;
+ case HTML_O_BORDERCOLOR:
+ pOption->GetColor( aBorderColor );
+ bBorderColor = sal_True;
+ break;
+ case HTML_O_BORDERCOLORDARK:
+ if( !bBorderColor )
+ pOption->GetColor( aBorderColor );
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ case HTML_O_HSPACE:
+ nHSpace = (sal_uInt16)pOption->GetNumber();
+ break;
+ case HTML_O_VSPACE:
+ nVSpace = (sal_uInt16)pOption->GetNumber();
+ break;
+ }
+ }
+
+ if( nCols && !nWidth )
+ {
+ nWidth = 100;
+ bPrcWidth = sal_True;
+ }
+
+ // Wenn BORDER=0 oder kein BORDER gegeben ist, daan darf es auch
+ // keine Umrandung geben
+ if( 0==nBorder || USHRT_MAX==nBorder )
+ {
+ eFrame = HTML_TF_VOID;
+ eRules = HTML_TR_NONE;
+ }
+}
+
+
+HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust,
+ sal_Bool bIsParentHead,
+ sal_Bool bHasParentSection,
+ sal_Bool bMakeTopSubTable,
+ sal_Bool bHasToFly )
+{
+ if( !IsParserWorking() && !pPendStack )
+ return 0;
+
+ int nToken = 0;
+ sal_Bool bPending = sal_False;
+ _TblSaveStruct* pSaveStruct;
+
+ if( pPendStack )
+ {
+ pSaveStruct = (_TblSaveStruct*)pPendStack->pData;
+
+ SwPendingStack* pTmp = pPendStack->pNext;
+ delete pPendStack;
+ pPendStack = pTmp;
+ nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
+ bPending = SVPAR_ERROR == eState && pPendStack != 0;
+
+ SaveState( nToken );
+ }
+ else
+ {
+ pTable = 0;
+ HTMLTableOptions *pTblOptions =
+ new HTMLTableOptions( GetOptions(), eParentAdjust );
+
+ if( pTblOptions->aId.Len() )
+ InsertBookmark( pTblOptions->aId );
+
+ HTMLTable *pCurTable = new HTMLTable( this, pTable,
+ bIsParentHead,
+ bHasParentSection,
+ bMakeTopSubTable,
+ bHasToFly,
+ pTblOptions );
+ if( !pTable )
+ pTable = pCurTable;
+
+ pSaveStruct = new _TblSaveStruct( pCurTable );
+
+ delete pTblOptions;
+
+ // ist beim ersten GetNextToken schon pending, muss bei
+ // wiederaufsetzen auf jedenfall neu gelesen werden!
+ SaveState( 0 );
+ }
+
+ HTMLTable *pCurTable = pSaveStruct->pCurTable;
+
+ // </TABLE> wird laut DTD benoetigt
+ if( !nToken )
+ nToken = GetNextToken(); // naechstes Token
+
+ sal_Bool bDone = sal_False;
+ while( (IsParserWorking() && !bDone) || bPending )
+ {
+ SaveState( nToken );
+
+ nToken = FilterToken( nToken );
+
+ ASSERT( pPendStack || !bCallNextToken ||
+ pCurTable->GetContext() || pCurTable->HasParentSection(),
+ "Wo ist die Section gebieben?" );
+ if( !pPendStack && bCallNextToken &&
+ (pCurTable->GetContext() || pCurTable->HasParentSection()) )
+ {
+ // NextToken direkt aufrufen (z.B. um den Inhalt von
+ // Floating-Frames oder Applets zu ignorieren)
+ NextToken( nToken );
+ }
+ else switch( nToken )
+ {
+ case HTML_TABLE_ON:
+ if( !pCurTable->GetContext() )
+ {
+ // Wenn noch keine Tabelle eingefuegt wurde,
+ // die naechste Tabelle lesen
+ SkipToken( -1 );
+ bDone = sal_True;
+ }
+// else
+// {
+// NextToken( nToken );
+// }
+ break;
+ case HTML_TABLE_OFF:
+ bDone = sal_True;
+ break;
+ case HTML_CAPTION_ON:
+ BuildTableCaption( pCurTable );
+ bDone = pTable->IsOverflowing();
+ break;
+ case HTML_COL_ON:
+ SkipToken( -1 );
+ BuildTableColGroup( pCurTable, sal_False );
+ break;
+ case HTML_COLGROUP_ON:
+ BuildTableColGroup( pCurTable, sal_True );
+ break;
+ case HTML_TABLEROW_ON:
+ case HTML_TABLEHEADER_ON:
+ case HTML_TABLEDATA_ON:
+ SkipToken( -1 );
+ BuildTableSection( pCurTable, sal_False, sal_False );
+ bDone = pTable->IsOverflowing();
+ break;
+ case HTML_THEAD_ON:
+ case HTML_TFOOT_ON:
+ case HTML_TBODY_ON:
+ BuildTableSection( pCurTable, sal_True, HTML_THEAD_ON==nToken );
+ bDone = pTable->IsOverflowing();
+ break;
+ case HTML_MULTICOL_ON:
+ // spaltige Rahmen koennen wir hier leider nicht einguegen
+ break;
+ case HTML_FORM_ON:
+ NewForm( sal_False ); // keinen neuen Absatz aufmachen!
+ break;
+ case HTML_FORM_OFF:
+ EndForm( sal_False ); // keinen neuen Absatz aufmachen!
+ break;
+ case HTML_TEXTTOKEN:
+ // Blank-Strings sind u. U. eine Folge von CR+LF und kein Text
+ if( (pCurTable->GetContext() ||
+ !pCurTable->HasParentSection()) &&
+ 1==aToken.Len() && ' '==aToken.GetChar(0) )
+ break;
+ default:
+ pCurTable->MakeParentContents();
+ NextToken( nToken );
+ break;
+ }
+
+ ASSERT( !bPending || !pPendStack,
+ "SwHTMLParser::BuildTable: Es gibt wieder einen Pend-Stack" );
+ bPending = sal_False;
+ if( IsParserWorking() )
+ SaveState( 0 );
+
+ if( !bDone )
+ nToken = GetNextToken();
+ }
+
+ if( SVPAR_PENDING == GetStatus() )
+ {
+ pPendStack = new SwPendingStack( HTML_TABLE_ON, pPendStack );
+ pPendStack->pData = pSaveStruct;
+ return 0;
+ }
+
+ _HTMLTableContext *pTCntxt = pCurTable->GetContext();
+ if( pTCntxt )
+ {
+ // Die Tabelle wurde auch angelegt
+
+ // Tabellen-Struktur anpassen
+ pCurTable->CloseTable();
+
+ // ausserhalb von Zellen begonnene Kontexte beenden
+ // muss vor(!) dem Umsetzten der Attribut Tabelle existieren,
+ // weil die aktuelle danach nicht mehr existiert
+ while( aContexts.Count() > nContextStAttrMin )
+ {
+ _HTMLAttrContext *pCntxt = PopContext();
+ ClearContext( pCntxt );
+ delete pCntxt;
+ }
+
+ nContextStMin = pTCntxt->GetContextStMin();
+ nContextStAttrMin = pTCntxt->GetContextStAttrMin();
+
+ if( pTable==pCurTable )
+ {
+ // Tabellen-Beschriftung setzen
+ const SwStartNode *pCapStNd = pTable->GetCaptionStartNode();
+ if( pCapStNd )
+ {
+ // Der letzte Absatz der Section wird nie mitkopiert. Deshalb
+ // muss die Section mindestens zwei Absaetze enthalten.
+
+ if( pCapStNd->EndOfSectionIndex() - pCapStNd->GetIndex() > 2 )
+ {
+ // Start-Node und letzten Absatz nicht mitkopieren.
+ SwNodeRange aSrcRg( *pCapStNd, 1,
+ *pCapStNd->EndOfSectionNode(), -1 );
+
+ sal_Bool bTop = pTable->IsTopCaption();
+ SwStartNode *pTblStNd = pTCntxt->GetTableNode();
+
+ ASSERT( pTblStNd, "Wo ist der Tabellen-Node" );
+ ASSERT( pTblStNd==pPam->GetNode()->FindTableNode(),
+ "Stehen wir in der falschen Tabelle?" );
+
+ SwNode* pNd;
+ if( bTop )
+ pNd = pTblStNd;
+ else
+ pNd = pTblStNd->EndOfSectionNode();
+ SwNodeIndex aDstIdx( *pNd, bTop ? 0 : 1 );
+
+ pDoc->MoveNodeRange( aSrcRg, aDstIdx,
+ IDocumentContentOperations::DOC_MOVEDEFAULT );
+
+ // Wenn die Caption vor der Tabelle eingefuegt wurde muss
+ // eine an der Tabelle gestzte Seitenvorlage noch in den
+ // ersten Absatz der Ueberschrift verschoben werden.
+ // Ausserdem muessen alle gemerkten Indizes, die auf den
+ // Tabellen-Node zeigen noch verschoben werden.
+ if( bTop )
+ {
+ MovePageDescAttrs( pTblStNd, aSrcRg.aStart.GetIndex(),
+ sal_False );
+ }
+ }
+
+ // Die Section wird jetzt nicht mehr gebraucht.
+ pPam->SetMark();
+ pPam->DeleteMark();
+ pDoc->DeleteSection( (SwStartNode *)pCapStNd );
+ pTable->SetCaption( 0, sal_False );
+ }
+
+ // SwTable aufbereiten
+ sal_uInt16 nBrowseWidth = (sal_uInt16)GetCurrentBrowseWidth();
+ pSaveStruct->MakeTable( nBrowseWidth, *pPam->GetPoint(), pDoc );
+
+#ifdef TEST_RESIZE
+ const SwTable *pSwTable = pTable->GetSwTable();
+ SwHTMLTableLayout *pLayoutInfo =
+ pSwTable ? ((SwTable *)pSwTable)->GetHTMLTableLayout() : 0;
+ if( pLayoutInfo )
+ {
+ ViewShell *pVSh = CheckActionViewShell();
+ if( pVSh )
+ {
+ CallEndAction( sal_False, sal_False );
+ CallStartAction( pVSh, sal_False );
+
+ sal_uInt16 nNewBrwoseWidth =
+ (sal_uInt16)GetCurrentBrowseWidth();
+ if( nBrowseWidth != nNewBrowseWidth )
+ pLayoutInfo->Resize( nNewBrowseWidth );
+ }
+ }
+#endif
+ }
+
+ GetNumInfo().Set( pTCntxt->GetNumInfo() );
+ pTCntxt->RestorePREListingXMP( *this );
+ RestoreAttrTab( pTCntxt->aAttrTab );
+
+ if( pTable==pCurTable )
+ {
+ // oberen Absatz-Abstand einstellen
+ bUpperSpace = sal_True;
+ SetTxtCollAttrs();
+
+ nParaCnt = nParaCnt - Min(nParaCnt, pTCntxt->GetTableNode()->GetTable().GetTabSortBoxes().Count());
+
+ // ggfs. eine Tabelle anspringen
+ if( JUMPTO_TABLE == eJumpTo && pTable->GetSwTable() &&
+ pTable->GetSwTable()->GetFrmFmt()->GetName() == sJmpMark )
+ {
+ bChkJumpMark = sal_True;
+ eJumpTo = JUMPTO_NONE;
+ }
+
+ // fix #37886#: Wenn Import abgebrochen wurde kein erneutes Show
+ // aufrufen, weil die ViewShell schon geloescht wurde!
+ // fix #41669#: Genuegt nicht. Auch im ACCEPTING_STATE darf
+ // kein Show aufgerufen werden, weil sonst waehrend des
+ // Reschedules der Parser zerstoert wird, wenn noch ein
+ // DataAvailable-Link kommt. Deshalb: Nur im WORKING-State.
+ if( !nParaCnt && SVPAR_WORKING == GetStatus() )
+ Show();
+ }
+ }
+ else if( pTable==pCurTable )
+ {
+ // Es wurde gar keine Tabelle gelesen.
+
+ // Dann muss eine evtl gelesene Beschriftung noch geloescht werden.
+ const SwStartNode *pCapStNd = pCurTable->GetCaptionStartNode();
+ if( pCapStNd )
+ {
+ pPam->SetMark();
+ pPam->DeleteMark();
+ pDoc->DeleteSection( (SwStartNode *)pCapStNd );
+ pCurTable->SetCaption( 0, sal_False );
+ }
+ }
+
+ if( pTable == pCurTable )
+ {
+ delete pSaveStruct->pCurTable;
+ pSaveStruct->pCurTable = 0;
+ pTable = 0;
+ }
+
+ HTMLTable* pRetTbl = pSaveStruct->pCurTable;
+ delete pSaveStruct;
+
+ return pRetTbl;
+}
+
+
diff --git a/sw/source/filter/html/htmltabw.cxx b/sw/source/filter/html/htmltabw.cxx
new file mode 100644
index 000000000000..43b83557a149
--- /dev/null
+++ b/sw/source/filter/html/htmltabw.cxx
@@ -0,0 +1,1265 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <vcl/svapp.hxx>
+#include <svtools/htmlout.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#ifndef _WRKWIN_HXX //autogen
+#include <vcl/wrkwin.hxx>
+#endif
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XImageProducerSupplier.hpp>
+#include <com/sun/star/form/XFormController.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <fmtornt.hxx>
+#include <frmfmt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtsrnd.hxx>
+#include <frmatr.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <ndtxt.hxx>
+#include <swrect.hxx>
+#include <cellatr.hxx>
+#include <poolfmt.hxx>
+#include <swtable.hxx>
+#include <htmltbl.hxx>
+#include <htmlnum.hxx>
+#include <wrthtml.hxx>
+#include <wrtswtbl.hxx>
+#ifdef DBG_UTIL
+#ifndef _VIEWSH_HXX
+#include <viewsh.hxx>
+#endif
+#include <viewopt.hxx>
+#endif
+
+//#define MAX_DEPTH (USHRT_MAX)
+#define MAX_DEPTH (3)
+
+using namespace ::com::sun::star;
+
+
+class SwHTMLWrtTable : public SwWriteTable
+{
+ void Pixelize( sal_uInt16& rValue );
+ void PixelizeBorders();
+
+ void OutTableCell( SwHTMLWriter& rWrt, const SwWriteTableCell *pCell,
+ sal_Bool bOutVAlign ) const;
+
+ void OutTableCells( SwHTMLWriter& rWrt,
+ const SwWriteTableCells& rCells,
+ const SvxBrushItem *pBrushItem ) const;
+
+ virtual sal_Bool ShouldExpandSub( const SwTableBox *pBox,
+ sal_Bool bExpandedBefore, sal_uInt16 nDepth ) const;
+
+ static sal_Bool HasTabBackground( const SwTableLine& rLine,
+ sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight );
+ static sal_Bool HasTabBackground( const SwTableBox& rBox,
+ sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight );
+
+public:
+ SwHTMLWrtTable( const SwTableLines& rLines, long nWidth, sal_uInt16 nBWidth,
+ sal_Bool bRel, USHORT nNumOfRowsToRepeat,
+ sal_uInt16 nLeftSub=0, sal_uInt16 nRightSub=0 );
+ SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo );
+
+ void Write( SwHTMLWriter& rWrt, sal_Int16 eAlign=text::HoriOrientation::NONE,
+ sal_Bool bTHead=sal_False, const SwFrmFmt *pFrmFmt=0,
+ const String *pCaption=0, sal_Bool bTopCaption=sal_False,
+ sal_uInt16 nHSpace=0, sal_uInt16 nVSpace=0 ) const;
+};
+
+
+SwHTMLWrtTable::SwHTMLWrtTable( const SwTableLines& rLines, long nWidth,
+ sal_uInt16 nBWidth, sal_Bool bRel, USHORT nNumOfRowsToRepeat,
+ sal_uInt16 nLSub, sal_uInt16 nRSub )
+ : SwWriteTable( rLines, nWidth, nBWidth, bRel, MAX_DEPTH, nLSub, nRSub, nNumOfRowsToRepeat )
+{
+ PixelizeBorders();
+}
+
+SwHTMLWrtTable::SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo )
+ : SwWriteTable( pLayoutInfo )
+{
+ // Einige Twip-Werte an Pixel-Grenzen anpassen
+ if( bCollectBorderWidth )
+ PixelizeBorders();
+}
+
+void SwHTMLWrtTable::Pixelize( sal_uInt16& rValue )
+{
+ if( rValue && Application::GetDefaultDevice() )
+ {
+ Size aSz( rValue, 0 );
+ aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode(MAP_TWIP) );
+ if( !aSz.Width() )
+ aSz.Width() = 1;
+ aSz = Application::GetDefaultDevice()->PixelToLogic( aSz, MapMode(MAP_TWIP) );
+ rValue = (sal_uInt16)aSz.Width();
+ }
+}
+
+void SwHTMLWrtTable::PixelizeBorders()
+{
+ Pixelize( nBorder );
+ Pixelize( nCellSpacing );
+ Pixelize( nCellPadding );
+}
+
+sal_Bool SwHTMLWrtTable::HasTabBackground( const SwTableBox& rBox,
+ sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight )
+{
+ ASSERT( bTop || bBottom || bLeft || bRight,
+ "HasTabBackground: darf nicht aufgerufen werden" );
+
+ sal_Bool bRet = sal_False;
+ if( rBox.GetSttNd() )
+ {
+ const SvxBrushItem& rBrushItem =
+ rBox.GetFrmFmt()->GetBackground();
+
+ /// OD 02.09.2002 #99657#
+ /// The table box has a background, if its background color is not "no fill"/
+ /// "auto fill" or it has a background graphic.
+ bRet = rBrushItem.GetColor() != COL_TRANSPARENT ||
+ rBrushItem.GetGraphicLink() || rBrushItem.GetGraphic();
+ }
+ else
+ {
+ const SwTableLines& rLines = rBox.GetTabLines();
+ sal_uInt16 nCount = rLines.Count();
+ sal_Bool bLeftRight = bLeft || bRight;
+ for( sal_uInt16 i=0; !bRet && i<nCount; i++ )
+ {
+ sal_Bool bT = bTop && 0 == i;
+ sal_Bool bB = bBottom && nCount-1 == i;
+ if( bT || bB || bLeftRight )
+ bRet = HasTabBackground( *rLines[i], bT, bB, bLeft, bRight);
+ }
+ }
+
+ return bRet;
+}
+
+sal_Bool SwHTMLWrtTable::HasTabBackground( const SwTableLine& rLine,
+ sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight )
+{
+ ASSERT( bTop || bBottom || bLeft || bRight,
+ "HasTabBackground: darf nicht aufgerufen werden" );
+
+ sal_Bool bRet = sal_False;
+ const SvxBrushItem& rBrushItem = rLine.GetFrmFmt()->GetBackground();
+ /// OD 02.09.2002 #99657#
+ /// The table line has a background, if its background color is not "no fill"/
+ /// "auto fill" or it has a background graphic.
+ bRet = rBrushItem.GetColor() != COL_TRANSPARENT ||
+ rBrushItem.GetGraphicLink() || rBrushItem.GetGraphic();
+
+ if( !bRet )
+ {
+ const SwTableBoxes& rBoxes = rLine.GetTabBoxes();
+ sal_uInt16 nCount = rBoxes.Count();
+ sal_Bool bTopBottom = bTop || bBottom;
+ for( sal_uInt16 i=0; !bRet && i<nCount; i++ )
+ {
+ sal_Bool bL = bLeft && 0 == i;
+ sal_Bool bR = bRight && nCount-1 == i;
+ if( bTopBottom || bL || bR )
+ bRet = HasTabBackground( *rBoxes[i], bTop, bBottom, bL, bR );
+ }
+ }
+
+ return bRet;
+}
+
+sal_Bool lcl_WrtHTMLTbl_HasTabBorders( const SwTableLine*& rpLine, void* pPara );
+
+sal_Bool lcl_WrtHTMLTbl_HasTabBorders( const SwTableBox*& rpBox, void* pPara )
+{
+ sal_Bool *pBorders = (sal_Bool *)pPara;
+ if( *pBorders )
+ return sal_False;
+
+ if( !rpBox->GetSttNd() )
+ {
+ ((SwTableBox *)rpBox)->GetTabLines().ForEach(
+ &lcl_WrtHTMLTbl_HasTabBorders, pPara );
+ }
+ else
+ {
+ const SvxBoxItem& rBoxItem =
+ (const SvxBoxItem&)rpBox->GetFrmFmt()->GetFmtAttr( RES_BOX );
+
+ *pBorders = rBoxItem.GetTop() || rBoxItem.GetBottom() ||
+ rBoxItem.GetLeft() || rBoxItem.GetRight();
+ }
+
+ return !*pBorders;
+}
+
+sal_Bool lcl_WrtHTMLTbl_HasTabBorders( const SwTableLine*& rpLine, void* pPara )
+{
+ sal_Bool *pBorders = (sal_Bool *)pPara;
+ if( *pBorders )
+ return sal_False;
+
+ ((SwTableLine *)rpLine)->GetTabBoxes().ForEach(
+ &lcl_WrtHTMLTbl_HasTabBorders, pPara );
+ return !*pBorders;
+}
+
+
+sal_Bool SwHTMLWrtTable::ShouldExpandSub( const SwTableBox *pBox,
+ sal_Bool bExpandedBefore,
+ sal_uInt16 nDepth ) const
+{
+ sal_Bool bExpand = !pBox->GetSttNd() && nDepth>0;
+ if( bExpand && bExpandedBefore )
+ {
+ // MIB 30.6.97: Wenn schon eine Box expandiert wurde, wird eine
+ // weitere nur expandiert, wenn sie Umrandungen besitzt.
+ sal_Bool bBorders = sal_False;
+ lcl_WrtHTMLTbl_HasTabBorders( pBox, &bBorders );
+ if( !bBorders )
+ bBorders = HasTabBackground( *pBox, sal_True, sal_True, sal_True, sal_True );
+ bExpand = bBorders;
+ }
+
+ return bExpand;
+}
+
+
+// Eine Box als einzelne Zelle schreiben
+void SwHTMLWrtTable::OutTableCell( SwHTMLWriter& rWrt,
+ const SwWriteTableCell *pCell,
+ sal_Bool bOutVAlign ) const
+{
+ const SwTableBox *pBox = pCell->GetBox();
+ sal_uInt16 nRow = pCell->GetRow();
+ sal_uInt16 nCol = pCell->GetCol();
+ sal_uInt16 nRowSpan = pCell->GetRowSpan();
+ sal_uInt16 nColSpan = pCell->GetColSpan();
+
+ if ( !nRowSpan )
+ return;
+
+ SwWriteTableCol *pCol = aCols[nCol];
+
+// sal_Bool bOutWidth = nColSpan>1 || pCol->GetOutWidth();
+ sal_Bool bOutWidth = sal_True; //nColSpan==1 && pCol->GetOutWidth();
+
+ const SwStartNode* pSttNd = pBox->GetSttNd();
+ sal_Bool bHead = sal_False;
+ if( pSttNd )
+ {
+ ULONG nNdPos = pSttNd->GetIndex()+1;
+
+ // Art der Zelle (TD/TH) bestimmen
+ SwNode* pNd;
+ while( !( pNd = rWrt.pDoc->GetNodes()[nNdPos])->IsEndNode() )
+ {
+ if( pNd->IsTxtNode() )
+ {
+ // nur Absaetzte betrachten, an denen man was erkennt
+ // Das ist der Fall, wenn die Vorlage eine der Tabellen-Vorlagen
+ // ist oder von einer der beiden abgelitten ist.
+ const SwFmt *pFmt = &((SwTxtNode*)pNd)->GetAnyFmtColl();
+ sal_uInt16 nPoolId = pFmt->GetPoolFmtId();
+ while( !pFmt->IsDefault() &&
+ RES_POOLCOLL_TABLE_HDLN!=nPoolId &&
+ RES_POOLCOLL_TABLE!=nPoolId )
+ {
+ pFmt = pFmt->DerivedFrom();
+ nPoolId = pFmt->GetPoolFmtId();
+ }
+
+ if( !pFmt->IsDefault() )
+ {
+ bHead = (RES_POOLCOLL_TABLE_HDLN==nPoolId);
+ break;
+ }
+ }
+ nNdPos++;
+ }
+ }
+
+ rWrt.OutNewLine(); // <TH>/<TD> in neue Zeile
+ ByteString sOut( '<' );
+ sOut += (bHead ? OOO_STRING_SVTOOLS_HTML_tableheader : OOO_STRING_SVTOOLS_HTML_tabledata );
+
+ // ROW- und COLSPAN ausgeben
+ if( nRowSpan>1 )
+ (((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_rowspan ) += '=')
+ += ByteString::CreateFromInt32( nRowSpan );
+ if( nColSpan > 1 )
+ (((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_colspan ) += '=')
+ += ByteString::CreateFromInt32( nColSpan );
+
+#ifndef PURE_HTML
+ long nWidth = 0;
+ sal_uInt16 nPrcWidth = USHRT_MAX;
+ if( bOutWidth )
+ {
+ if( bLayoutExport )
+ {
+ if( pCell->HasPrcWidthOpt() )
+ {
+ nPrcWidth = pCell->GetWidthOpt();
+ }
+ else
+ {
+ nWidth = pCell->GetWidthOpt();
+ if( !nWidth )
+ bOutWidth = sal_False;
+ }
+ }
+ else
+ {
+ if( HasRelWidths() )
+ nPrcWidth = (sal_uInt16)GetPrcWidth(nCol,nColSpan);
+ else
+ nWidth = GetAbsWidth( nCol, nColSpan );
+ }
+ }
+
+ long nHeight = pCell->GetHeight() > 0
+ ? GetAbsHeight( pCell->GetHeight(), nRow, nRowSpan )
+ : 0;
+ Size aPixelSz( nWidth, nHeight );
+
+ // WIDTH ausgeben (Grrr: nur fuer Netscape)
+ if( (aPixelSz.Width() || aPixelSz.Height()) && Application::GetDefaultDevice() )
+ {
+ Size aOldSz( aPixelSz );
+ aPixelSz = Application::GetDefaultDevice()->LogicToPixel( aPixelSz,
+ MapMode(MAP_TWIP) );
+ if( aOldSz.Width() && !aPixelSz.Width() )
+ aPixelSz.Width() = 1;
+ if( aOldSz.Height() && !aPixelSz.Height() )
+ aPixelSz.Height() = 1;
+ }
+
+ // WIDTH ausgeben: Aus Layout oder berechnet
+ if( bOutWidth )
+ {
+ ((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_width ) += '=';
+ if( nPrcWidth != USHRT_MAX )
+ (sOut += ByteString::CreateFromInt32(nPrcWidth)) += '%';
+ else
+ sOut += ByteString::CreateFromInt32(aPixelSz.Width());
+ if( !bLayoutExport && nColSpan==1 )
+ pCol->SetOutWidth( sal_False );
+ }
+
+ if( nHeight )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
+ += ByteString::CreateFromInt32(aPixelSz.Height());
+ }
+#endif
+
+ const SfxItemSet& rItemSet = pBox->GetFrmFmt()->GetAttrSet();
+ const SfxPoolItem *pItem;
+
+ // ALIGN wird jetzt nur noch an den Absaetzen ausgegeben
+
+ // VALIGN ausgeben
+ if( bOutVAlign )
+ {
+ sal_Int16 eVertOri = pCell->GetVertOri();
+ if( text::VertOrientation::TOP==eVertOri || text::VertOrientation::BOTTOM==eVertOri )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_valign) += '=')
+ += (text::VertOrientation::TOP==eVertOri ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom);
+ }
+ }
+
+ rWrt.Strm() << sOut.GetBuffer();
+ sOut.Erase();
+
+ rWrt.bTxtAttr = sal_False;
+ rWrt.bOutOpts = sal_True;
+ const SvxBrushItem *pBrushItem = 0;
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
+ {
+ pBrushItem = (const SvxBrushItem *)pItem;
+ }
+ if( !pBrushItem )
+ pBrushItem = pCell->GetBackground();
+
+ if( pBrushItem )
+ {
+ // Hintergrund ausgeben
+ String aDummy;
+ rWrt.OutBackground( pBrushItem, aDummy, sal_False );
+
+ if( rWrt.bCfgOutStyles )
+ OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
+ }
+
+ sal_uInt32 nNumFmt = 0;
+ double nValue = 0.0;
+ sal_Bool bNumFmt = sal_False, bValue = sal_False;
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem ) )
+ {
+ nNumFmt = ((const SwTblBoxNumFormat *)pItem)->GetValue();
+ bNumFmt = sal_True;
+ }
+ if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOXATR_VALUE, sal_False, &pItem ) )
+ {
+ nValue = ((const SwTblBoxValue *)pItem)->GetValue();
+ bValue = sal_True;
+ if( !bNumFmt )
+ nNumFmt = pBox->GetFrmFmt()->GetTblBoxNumFmt().GetValue();
+ }
+
+ if( bNumFmt || bValue )
+ sOut = HTMLOutFuncs::CreateTableDataOptionsValNum( sOut,
+ bValue, nValue, nNumFmt, *rWrt.pDoc->GetNumberFormatter(),
+ rWrt.eDestEnc, &rWrt.aNonConvertableCharacters );
+ sOut += '>';
+ rWrt.Strm() << sOut.GetBuffer();
+ rWrt.bLFPossible = sal_True;
+
+ rWrt.IncIndentLevel(); // den Inhalt von <TD>...</TD> einruecken
+
+ if( pSttNd )
+ {
+ HTMLSaveData aSaveData( rWrt, pSttNd->GetIndex()+1,
+ pSttNd->EndOfSectionIndex() );
+ rWrt.Out_SwDoc( rWrt.pCurPam );
+ }
+ else
+ {
+ sal_uInt16 nTWidth, nBWidth, nLSub, nRSub;
+ if( HasRelWidths() )
+ {
+ nTWidth = 100;
+ nBWidth = GetRawWidth( nCol, nColSpan );
+ nLSub = 0;
+ nRSub = 0;
+ }
+ else
+ {
+ nTWidth = GetAbsWidth( nCol, nColSpan );
+ nBWidth = nTWidth;
+ nLSub = GetLeftSpace( nCol );
+ nRSub = GetRightSpace( nCol, nColSpan );
+ }
+
+ SwHTMLWrtTable aTableWrt( pBox->GetTabLines(), nTWidth,
+ nBWidth, HasRelWidths(), nLSub, nRSub );
+ aTableWrt.Write( rWrt );
+ }
+
+ rWrt.DecIndentLevel(); // den Inhalt von <TD>...</TD> einruecken
+
+ if( rWrt.bLFPossible )
+ rWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), bHead ? OOO_STRING_SVTOOLS_HTML_tableheader
+ : OOO_STRING_SVTOOLS_HTML_tabledata,
+ sal_False );
+ rWrt.bLFPossible = sal_True;
+}
+
+
+// Eine Line als Zeilen ausgeben
+void SwHTMLWrtTable::OutTableCells( SwHTMLWriter& rWrt,
+ const SwWriteTableCells& rCells,
+ const SvxBrushItem *pBrushItem ) const
+{
+ // Wenn die Zeile mehr als eine Zelle nethaelt und alle Zellen
+ // die gleiche Ausrichtung besitzen, das VALIGN an der Zeile statt der
+ // Zelle ausgeben
+ sal_Int16 eRowVertOri = text::VertOrientation::NONE;
+ if( rCells.Count() > 1 )
+ {
+ for( sal_uInt16 nCell = 0; nCell<rCells.Count(); nCell++ )
+ {
+ sal_Int16 eCellVertOri = rCells[nCell]->GetVertOri();
+ if( 0==nCell )
+ {
+ eRowVertOri = eCellVertOri;
+ }
+ else if( eRowVertOri != eCellVertOri )
+ {
+ eRowVertOri = text::VertOrientation::NONE;
+ break;
+ }
+ }
+ }
+
+ rWrt.OutNewLine(); // <TR> in neuer Zeile
+ rWrt.Strm() << '<' << OOO_STRING_SVTOOLS_HTML_tablerow;
+ if( pBrushItem )
+ {
+ String aDummy;
+ rWrt.OutBackground( pBrushItem, aDummy, sal_False );
+
+ rWrt.bTxtAttr = sal_False;
+ rWrt.bOutOpts = sal_True;
+ if( rWrt.bCfgOutStyles )
+ OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
+ }
+
+ if( text::VertOrientation::TOP==eRowVertOri || text::VertOrientation::BOTTOM==eRowVertOri )
+ {
+ ByteString sOut( ' ' );
+ ((sOut += OOO_STRING_SVTOOLS_HTML_O_valign) += '=')
+ += (text::VertOrientation::TOP==eRowVertOri ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom);
+ rWrt.Strm() << sOut.GetBuffer();
+ }
+
+ rWrt.Strm() << '>';
+
+ rWrt.IncIndentLevel(); // Inhalt von <TR>...</TR> einruecken
+
+ for( sal_uInt16 nCell = 0; nCell<rCells.Count(); nCell++ )
+ OutTableCell( rWrt, rCells[nCell], text::VertOrientation::NONE==eRowVertOri );
+
+ rWrt.DecIndentLevel(); // Inhalt von <TR>...</TR> einruecken
+
+ rWrt.OutNewLine(); // </TR> in neuer Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow, sal_False );
+}
+
+
+
+void SwHTMLWrtTable::Write( SwHTMLWriter& rWrt, sal_Int16 eAlign,
+ sal_Bool bTHead, const SwFrmFmt *pFrmFmt,
+ const String *pCaption, sal_Bool bTopCaption,
+ sal_uInt16 nHSpace, sal_uInt16 nVSpace ) const
+{
+ sal_uInt16 nRow;
+
+ // Wert fuer FRAME bestimmen
+ sal_uInt16 nFrameMask = 15;
+ if( !(aRows[0])->bTopBorder )
+ nFrameMask &= ~1;
+ if( !(aRows[aRows.Count()-1])->bBottomBorder )
+ nFrameMask &= ~2;
+ if( !(aCols[0])->bLeftBorder )
+ nFrameMask &= ~4;
+ if( !(aCols[aCols.Count()-1])->bRightBorder )
+ nFrameMask &= ~8;
+
+ // Wert fur RULES bestimmen
+ sal_Bool bRowsHaveBorder = sal_False;
+ sal_Bool bRowsHaveBorderOnly = sal_True;
+ SwWriteTableRow *pRow = aRows[0];
+ for( nRow=1; nRow < aRows.Count(); nRow++ )
+ {
+ SwWriteTableRow *pNextRow = aRows[nRow];
+ sal_Bool bBorder = ( pRow->bBottomBorder || pNextRow->bTopBorder );
+ bRowsHaveBorder |= bBorder;
+ bRowsHaveBorderOnly &= bBorder;
+
+ sal_uInt16 nBorder2 = pRow->bBottomBorder ? pRow->nBottomBorder : USHRT_MAX;
+ if( pNextRow->bTopBorder && pNextRow->nTopBorder < nBorder2 )
+ nBorder2 = pNextRow->nTopBorder;
+
+ pRow->bBottomBorder = bBorder;
+ pRow->nBottomBorder = nBorder2;
+
+ pNextRow->bTopBorder = bBorder;
+ pNextRow->nTopBorder = nBorder2;
+
+ pRow = pNextRow;
+ }
+
+ sal_Bool bColsHaveBorder = sal_False;
+ sal_Bool bColsHaveBorderOnly = sal_True;
+ SwWriteTableCol *pCol = aCols[0];
+ sal_uInt16 nCol;
+ for( nCol=1; nCol<aCols.Count(); nCol++ )
+ {
+ SwWriteTableCol *pNextCol = aCols[nCol];
+ sal_Bool bBorder = ( pCol->bRightBorder || pNextCol->bLeftBorder );
+ bColsHaveBorder |= bBorder;
+ bColsHaveBorderOnly &= bBorder;
+ pCol->bRightBorder = bBorder;
+ pNextCol->bLeftBorder = bBorder;
+ pCol = pNextCol;
+ }
+
+
+ // vorhergende Aufzaehlung etc. beenden
+ rWrt.ChangeParaToken( 0 );
+
+ if( rWrt.bLFPossible )
+ rWrt.OutNewLine(); // <TABLE> in neue Zeile
+ ByteString sOut( '<' );
+ sOut += OOO_STRING_SVTOOLS_HTML_table;
+
+ sal_uInt16 nOldDirection = rWrt.nDirection;
+ if( pFrmFmt )
+ rWrt.nDirection = rWrt.GetHTMLDirection( pFrmFmt->GetAttrSet() );
+ if( rWrt.bOutFlyFrame || nOldDirection != rWrt.nDirection )
+ {
+ rWrt.Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ rWrt.OutDirection( rWrt.nDirection );
+ }
+
+ // COLS ausgeben: Nur bei Export ueber Layout, wenn es beim Import
+ // vorhanden war.
+ if( bColsOption )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=')
+ += ByteString::CreateFromInt32( aCols.Count() );
+
+ // ALIGN= ausgeben
+ if( text::HoriOrientation::RIGHT == eAlign )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align ) += '=') += OOO_STRING_SVTOOLS_HTML_AL_right;
+ else if( text::HoriOrientation::CENTER == eAlign )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align ) += '=') += OOO_STRING_SVTOOLS_HTML_AL_center;
+ else if( text::HoriOrientation::LEFT == eAlign )
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align ) += '=') += OOO_STRING_SVTOOLS_HTML_AL_left;
+
+ // WIDTH ausgeben: Stammt aus Layout oder ist berechnet
+ if( nTabWidth )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width ) += '=';
+ if( HasRelWidths() )
+ (sOut += ByteString::CreateFromInt32( nTabWidth )) += '%';
+ else if( Application::GetDefaultDevice() )
+ {
+ long nPixWidth = Application::GetDefaultDevice()->LogicToPixel(
+ Size(nTabWidth,0), MapMode(MAP_TWIP) ).Width();
+ if( !nPixWidth )
+ nPixWidth = 1;
+
+ sOut += ByteString::CreateFromInt32( nPixWidth );
+ }
+ else
+ {
+ ASSERT( Application::GetDefaultDevice(), "kein Application-Window!?" );
+ sOut += "100%";
+ }
+ }
+
+ if( (nHSpace || nVSpace) && Application::GetDefaultDevice())
+ {
+ Size aPixelSpc =
+ Application::GetDefaultDevice()->LogicToPixel( Size(nHSpace,nVSpace),
+ MapMode(MAP_TWIP) );
+ if( !aPixelSpc.Width() && nHSpace )
+ aPixelSpc.Width() = 1;
+ if( !aPixelSpc.Height() && nVSpace )
+ aPixelSpc.Height() = 1;
+
+ if( aPixelSpc.Width() )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_hspace) += '=')
+ += ByteString::CreateFromInt32( aPixelSpc.Width() );
+ }
+
+ if( aPixelSpc.Height() )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_vspace) += '=')
+ += ByteString::CreateFromInt32( aPixelSpc.Height() );
+ }
+ }
+
+ // BORDER ausgeben, aber nur wenn wir die Umrandung selbst berechnet
+ // haben oder die Umrandung 0 ist oder es irgendwelche Umrandungen gibt.
+ // Anderenfalls enthaelt nBorder naemlich nur die Breite der Umrandung,
+ // die genutzt wird, wenn gar kein sheet::Border angegeben ist.
+ sal_Bool bHasAnyBorders = nFrameMask || bColsHaveBorder || bRowsHaveBorder;
+ if( bCollectBorderWidth || nBorder==0 || bHasAnyBorders )
+ (((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_border ) += '=')
+ += ByteString::CreateFromInt32( rWrt.ToPixel( nBorder ) );
+
+ // BORDERCOLOR ausgeben
+
+ if( (sal_uInt32)-1 != nBorderColor && rWrt.bCfgOutStyles && bHasAnyBorders )
+ {
+ ((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_bordercolor ) += '=';
+ rWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_Color( rWrt.Strm(), nBorderColor, rWrt.eDestEnc );
+ sOut.Erase();
+ }
+
+ // CELLPADDING ausgeben: Stammt aus Layout oder ist berechnet
+ (((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellpadding ) += '=')
+ += ByteString::CreateFromInt32( rWrt.ToPixel( nCellPadding ) );
+
+ // CELLSPACING ausgeben: Stammt aus Layout oder ist berechnet
+ (((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_cellspacing ) += '=')
+ += ByteString::CreateFromInt32( rWrt.ToPixel( nCellSpacing ) );
+
+ // FRAME/RULES ausgeben (nur sinnvoll, wenn border!=0)
+ if( nBorder!=0 && (bCollectBorderWidth || bHasAnyBorders) )
+ {
+ const sal_Char *pFrame = 0;
+ switch( nFrameMask )
+ {
+ case 0: pFrame = OOO_STRING_SVTOOLS_HTML_TF_void ;break;
+ case 1: pFrame = OOO_STRING_SVTOOLS_HTML_TF_above ;break;
+ case 2: pFrame = OOO_STRING_SVTOOLS_HTML_TF_below ;break;
+ case 3: pFrame = OOO_STRING_SVTOOLS_HTML_TF_hsides ;break;
+ case 4: pFrame = OOO_STRING_SVTOOLS_HTML_TF_lhs ;break;
+ case 8: pFrame = OOO_STRING_SVTOOLS_HTML_TF_rhs ;break;
+ case 12: pFrame = OOO_STRING_SVTOOLS_HTML_TF_vsides ;break;
+ //FRAME=BOX ist der default wenn BORDER>0
+ //case 15:
+ //default: pFrame = OOO_STRING_SVTOOLS_HTML_TF_box ;break; // geht nicht
+ };
+ if( pFrame )
+ (((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_frame ) += '=') += pFrame;
+
+ const sal_Char *pRules = 0;
+ if( aCols.Count() > 1 && aRows.Count() > 1 )
+ {
+ if( !bColsHaveBorder )
+ {
+ if( !bRowsHaveBorder )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_none;
+ else if( bRowsHaveBorderOnly )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_rows;
+ else
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
+ }
+ else if( bColsHaveBorderOnly )
+ {
+ if( !bRowsHaveBorder || !bRowsHaveBorderOnly )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_cols;
+ }
+ else
+ {
+ if( !bRowsHaveBorder )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
+ else if( bRowsHaveBorderOnly )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_rows;
+ else
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
+ }
+ }
+ else if( aRows.Count() > 1 )
+ {
+ if( !bRowsHaveBorder )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_none;
+ else if( !bRowsHaveBorderOnly )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
+ }
+ else if( aCols.Count() > 1 )
+ {
+ if( !bColsHaveBorder )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_none;
+ else if( !bColsHaveBorderOnly )
+ pRules = OOO_STRING_SVTOOLS_HTML_TR_groups;
+ }
+
+ if( pRules )
+ (((sOut += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_rules ) += '=') += pRules;
+ }
+ rWrt.Strm() << sOut.GetBuffer();
+
+ // Hintergrund ausgeben
+ if( pFrmFmt )
+ {
+ String aDummy;
+ rWrt.OutBackground( pFrmFmt->GetAttrSet(), aDummy, sal_False );
+
+ if( rWrt.bCfgOutStyles && pFrmFmt )
+ rWrt.OutCSS1_TableFrmFmtOptions( *pFrmFmt );
+ }
+
+ sOut = '>';
+ rWrt.Strm() << sOut.GetBuffer();
+
+ rWrt.IncIndentLevel(); // Inhalte von Table einruecken
+
+ // Ueberschrift ausgeben
+ if( pCaption && pCaption->Len() )
+ {
+ rWrt.OutNewLine(); // <CAPTION> in neue Zeile
+ ByteString sOutStr( OOO_STRING_SVTOOLS_HTML_caption );
+ (((sOutStr += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=')
+ += (bTopCaption ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom);
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOutStr.GetBuffer(), sal_True );
+ HTMLOutFuncs::Out_String( rWrt.Strm(), *pCaption, rWrt.eDestEnc, &rWrt.aNonConvertableCharacters );
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_caption, sal_False );
+ }
+
+ sal_uInt16 nCols = aCols.Count();
+
+ // <COLGRP>/<COL> ausgeben: Bei Export ueber Layout nur wenn beim
+ // Import welche da waren, sonst immer.
+ sal_Bool bColGroups = (bColsHaveBorder && !bColsHaveBorderOnly);
+ if( bColTags )
+ {
+ if( bColGroups )
+ {
+ rWrt.OutNewLine(); // <COLGRP> in neue Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup, sal_True );
+
+ rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
+ }
+
+ for( nCol=0; nCol<nCols; nCol++ )
+ {
+ rWrt.OutNewLine(); // <COL> in neue Zeile
+
+ const SwWriteTableCol *pColumn = aCols[nCol];
+
+ ByteString sOutStr( '<' );
+ sOutStr += OOO_STRING_SVTOOLS_HTML_col;
+
+ sal_uInt16 nWidth;
+ sal_Bool bRel;
+ if( bLayoutExport )
+ {
+ bRel = pColumn->HasRelWidthOpt();
+ nWidth = pColumn->GetWidthOpt();
+ }
+ else
+ {
+ bRel = HasRelWidths();
+ nWidth = bRel ? GetRelWidth(nCol,1) : GetAbsWidth(nCol,1);
+ }
+
+ ((sOutStr += ' ' ) += OOO_STRING_SVTOOLS_HTML_O_width ) += '=';
+ if( bRel )
+ {
+ (sOutStr += ByteString::CreateFromInt32( nWidth ) ) += '*';
+ }
+ else
+ {
+ sOutStr += ByteString::CreateFromInt32( rWrt.ToPixel( nWidth ) );
+ }
+ sOutStr += '>';
+ rWrt.Strm() << sOutStr.GetBuffer();
+
+ if( bColGroups && pColumn->bRightBorder && nCol<nCols-1 )
+ {
+ rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
+ rWrt.OutNewLine(); // </COLGRP> in neue Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
+ sal_False );
+ rWrt.OutNewLine(); // <COLGRP> in neue Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
+ sal_True );
+ rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
+ }
+ }
+ if( bColGroups )
+ {
+ rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
+
+ rWrt.OutNewLine(); // </COLGRP> in neue Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
+ sal_False );
+ }
+ }
+
+ // die Lines als Tabellenzeilen rausschreiben
+
+ // <TBODY> ausgeben?
+ sal_Bool bTSections = (bRowsHaveBorder && !bRowsHaveBorderOnly);
+ sal_Bool bTBody = bTSections;
+
+ // Wenn Sections ausgegeben werden muessen darf ein THEAD um die erste
+ // Zeile nur ausgegeben werden, wenn unter der Zeile eine Linie ist
+ if( bTHead &&
+ (bTSections || bColGroups) &&
+ nHeadEndRow<aRows.Count()-1 && !aRows[nHeadEndRow]->bBottomBorder )
+ bTHead = sal_False;
+
+ // <TBODY> aus ausgeben, wenn <THEAD> ausgegeben wird.
+ bTSections |= bTHead;
+
+ if( bTSections )
+ {
+ rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
+ bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_True );
+
+ rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
+ }
+
+ for( nRow = 0; nRow < aRows.Count(); nRow++ )
+ {
+ const SwWriteTableRow *pRow2 = aRows[nRow];
+
+ OutTableCells( rWrt, pRow2->GetCells(), pRow2->GetBackground() );
+ if( !nCellSpacing && nRow < aRows.Count()-1 && pRow2->bBottomBorder &&
+ pRow2->nBottomBorder > DEF_LINE_WIDTH_1 )
+ {
+ sal_uInt16 nCnt = (pRow2->nBottomBorder / DEF_LINE_WIDTH_1) - 1;
+ for( ; nCnt; nCnt-- )
+ {
+ rWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
+ sal_True );
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
+ sal_False );
+ }
+ }
+ if( ( (bTHead && nRow==nHeadEndRow) ||
+ (bTBody && pRow2->bBottomBorder) ) &&
+ nRow < aRows.Count()-1 )
+ {
+ rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
+ rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
+ bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_False );
+ rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
+
+ if( bTHead && nRow==nHeadEndRow )
+ bTHead = sal_False;
+
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
+ bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_True );
+ rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
+ }
+ }
+
+ if( bTSections )
+ {
+ rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
+
+ rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
+ bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_False );
+ }
+
+ rWrt.DecIndentLevel(); // Inhalt von <TABLE> einr.
+
+ rWrt.OutNewLine(); // </TABLE> in neue Zeile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_table, sal_False );
+
+ rWrt.nDirection = nOldDirection;
+}
+
+Writer& OutHTML_SwTblNode( Writer& rWrt, SwTableNode & rNode,
+ const SwFrmFmt *pFlyFrmFmt,
+ const String *pCaption, sal_Bool bTopCaption )
+{
+
+ SwTable& rTbl = rNode.GetTable();
+
+ SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
+ rHTMLWrt.bOutTable = sal_True;
+
+ // die horizontale Ausrichtung des Rahmens hat (falls vorhanden)
+ // Prioritaet. NONE bedeutet, dass keine horizontale
+ // Ausrichtung geschrieben wird.
+ sal_Int16 eFlyHoriOri = text::HoriOrientation::NONE;
+ SwSurround eSurround = SURROUND_NONE;
+ sal_uInt8 nFlyPrcWidth = 0;
+ long nFlyWidth = 0;
+ sal_uInt16 nFlyHSpace = 0;
+ sal_uInt16 nFlyVSpace = 0;
+ if( pFlyFrmFmt )
+ {
+ eSurround = pFlyFrmFmt->GetSurround().GetSurround();
+ const SwFmtFrmSize& rFrmSize = pFlyFrmFmt->GetFrmSize();
+ nFlyPrcWidth = rFrmSize.GetWidthPercent();
+ nFlyWidth = rFrmSize.GetSize().Width();
+
+ eFlyHoriOri = pFlyFrmFmt->GetHoriOrient().GetHoriOrient();
+ if( text::HoriOrientation::NONE == eFlyHoriOri )
+ eFlyHoriOri = text::HoriOrientation::LEFT;
+
+ const SvxLRSpaceItem& rLRSpace = pFlyFrmFmt->GetLRSpace();
+ nFlyHSpace = static_cast< sal_uInt16 >((rLRSpace.GetLeft() + rLRSpace.GetRight()) / 2);
+
+ const SvxULSpaceItem& rULSpace = pFlyFrmFmt->GetULSpace();
+ nFlyVSpace = (rULSpace.GetUpper() + rULSpace.GetLower()) / 2;
+ }
+
+ // ggf. eine FORM oeffnen
+ sal_Bool bPreserveForm = sal_False;
+ if( !rHTMLWrt.bPreserveForm )
+ {
+ rHTMLWrt.OutForm( sal_True, &rNode );
+ bPreserveForm = (rHTMLWrt.pxFormComps && rHTMLWrt.pxFormComps->is() );
+ rHTMLWrt.bPreserveForm = bPreserveForm;
+ }
+
+ SwFrmFmt *pFmt = rTbl.GetFrmFmt();
+
+ const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
+ long nWidth = rFrmSize.GetSize().Width();
+ sal_uInt8 nPrcWidth = rFrmSize.GetWidthPercent();
+ sal_uInt16 nBaseWidth = (sal_uInt16)nWidth;
+
+ sal_Int16 eTabHoriOri = pFmt->GetHoriOrient().GetHoriOrient();
+
+ // text::HoriOrientation::NONE und text::HoriOrientation::FULL Tabellen benoetigen relative Breiten
+ sal_uInt16 nNewDefListLvl = 0;
+ sal_Bool bRelWidths = sal_False;
+ sal_Bool bCheckDefList = sal_False;
+ switch( eTabHoriOri )
+ {
+ case text::HoriOrientation::FULL:
+ // Tabellen mit automatischer Ausrichtung werden zu Tabellen
+ // mit 100%-Breite
+ bRelWidths = sal_True;
+ nWidth = 100;
+ eTabHoriOri = text::HoriOrientation::LEFT;
+ break;
+ case text::HoriOrientation::NONE:
+ {
+ const SvxLRSpaceItem& aLRItem = pFmt->GetLRSpace();
+ if( aLRItem.GetRight() )
+ {
+ // Die Tabellenbreite wird anhand des linken und rechten
+ // Abstandes bestimmt. Deshalb versuchen wir die
+ // tatsaechliche Breite der Tabelle zu bestimmen. Wenn
+ // das nicht geht, machen wir eine 100% breite Tabelle
+ // draus.
+ nWidth = pFmt->FindLayoutRect(sal_True).Width();
+ if( !nWidth )
+ {
+ bRelWidths = sal_True;
+ nWidth = 100;
+ }
+
+ }
+ else if( nPrcWidth )
+ {
+ // Ohne rechten Rand bleibt die %-Breite erhalten
+ nWidth = nPrcWidth;
+ bRelWidths = sal_True;
+ }
+ else
+ {
+ // Ohne rechten Rand bleibt auch eine absolute Breite erhalten
+ // Wir versuchen aber trotzdem ueber das Layout die
+ // tatsachliche Breite zu ermitteln.
+ long nRealWidth = pFmt->FindLayoutRect(sal_True).Width();
+ if( nRealWidth )
+ nWidth = nRealWidth;
+ }
+ bCheckDefList = sal_True;
+ }
+ break;
+ case text::HoriOrientation::LEFT_AND_WIDTH:
+ eTabHoriOri = text::HoriOrientation::LEFT;
+ bCheckDefList = sal_True;
+ // no break
+ default:
+ // In allen anderen Faellen kann eine absolute oder relative
+ // Breite direkt uebernommen werden.
+ if( nPrcWidth )
+ {
+ bRelWidths = sal_True;
+ nWidth = nPrcWidth;
+ }
+ break;
+ }
+
+ if( bCheckDefList )
+ {
+ ASSERT( !rHTMLWrt.GetNumInfo().GetNumRule() ||
+ rHTMLWrt.GetNextNumInfo(),
+ "NumInfo fuer naechsten Absatz fehlt!" );
+ const SvxLRSpaceItem& aLRItem = pFmt->GetLRSpace();
+ if( aLRItem.GetLeft() > 0 && rHTMLWrt.nDefListMargin > 0 &&
+ ( !rHTMLWrt.GetNumInfo().GetNumRule() ||
+ ( rHTMLWrt.GetNextNumInfo() &&
+ (rHTMLWrt.GetNextNumInfo()->IsRestart() ||
+ rHTMLWrt.GetNumInfo().GetNumRule() !=
+ rHTMLWrt.GetNextNumInfo()->GetNumRule()) ) ) )
+ {
+ // Wenn der Absatz vor der Tabelle nicht numeriert ist oder
+ // der Absatz nach der Tabelle mit einer anderen oder
+ // (gar keiner) Regel numeriert ist, koennen wir
+ // die Einrueckung ueber eine DL regeln. Sonst behalten wir
+ // die Einrueckung der Numerierung bei.
+ nNewDefListLvl = static_cast< sal_uInt16 >(
+ (aLRItem.GetLeft() + (rHTMLWrt.nDefListMargin/2)) /
+ rHTMLWrt.nDefListMargin );
+ }
+ }
+
+ if( !pFlyFrmFmt && nNewDefListLvl != rHTMLWrt.nDefListLvl )
+ rHTMLWrt.OutAndSetDefList( nNewDefListLvl );
+
+ if( nNewDefListLvl )
+ {
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_dd );
+ }
+
+ // eFlyHoriOri und eTabHoriOri besitzen nun nur noch die Werte
+ // LEFT/CENTER und RIGHT!
+ if( eFlyHoriOri!=text::HoriOrientation::NONE )
+ {
+ eTabHoriOri = eFlyHoriOri;
+ // MIB 4.7.97: Wenn die Tabelle eine relative Breite besitzt,
+ // dann richtet sich ihre Breite nach der des Rahmens, also
+ // exportieren wir dessen Breite. Bei fixer Breite ist die Breite
+ // der Tabelle massgeblich. Wer Tabellen mit relativer Breite <100%
+ // in Rahmen steckt, ist selber schuld wenn nix Gutes bei rauskommt.
+ if( bRelWidths )
+ {
+ nWidth = nFlyPrcWidth ? nFlyPrcWidth : nFlyWidth;
+ bRelWidths = nFlyPrcWidth > 0;
+ }
+ }
+
+ sal_Int16 eDivHoriOri = text::HoriOrientation::NONE;
+ switch( eTabHoriOri )
+ {
+ case text::HoriOrientation::LEFT:
+ // Wenn eine linksbuendigeTabelle keinen rechtsseiigen Durchlauf
+ // hat, brauchen wir auch kein ALIGN=LEFT in der Tabelle.
+ if( eSurround==SURROUND_NONE || eSurround==SURROUND_LEFT )
+ eTabHoriOri = text::HoriOrientation::NONE;
+ break;
+ case text::HoriOrientation::RIGHT:
+ // Aehnliches gilt fuer rechtsbuendigeTabelle, hier nehmen wir
+ // stattdessen ein <DIV ALIGN=RIGHT>.
+ if( eSurround==SURROUND_NONE || eSurround==SURROUND_RIGHT )
+ {
+ eDivHoriOri = text::HoriOrientation::RIGHT;
+ eTabHoriOri = text::HoriOrientation::NONE;
+ }
+ break;
+ case text::HoriOrientation::CENTER:
+ // ALIGN=CENTER versteht so gut wie keiner, deshalb verzichten wir
+ // daruf und nehmen ein <CENTER>.
+ eDivHoriOri = text::HoriOrientation::CENTER;
+ eTabHoriOri = text::HoriOrientation::NONE;
+ break;
+ default:
+ ;
+ }
+ if( text::HoriOrientation::NONE==eTabHoriOri )
+ nFlyHSpace = nFlyVSpace = 0;
+
+ if( pFmt->GetName().Len() )
+ rHTMLWrt.OutImplicitMark( pFmt->GetName(), pMarkToTable );
+
+ if( text::HoriOrientation::NONE!=eDivHoriOri )
+ {
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine(); // <CENTER> in neuer Zeile
+ if( text::HoriOrientation::CENTER==eDivHoriOri )
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_center, sal_True );
+ else
+ {
+ ByteString sOut( OOO_STRING_SVTOOLS_HTML_division );
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_align) += '=') += OOO_STRING_SVTOOLS_HTML_AL_right;
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.GetBuffer(),
+ sal_True );
+ }
+ rHTMLWrt.IncIndentLevel(); // Inhalt von <CENTER> einruecken
+ rHTMLWrt.bLFPossible = sal_True;
+ }
+
+ // Wenn die Tabelle in keinem Rahmen ist kann man immer ein LF ausgeben.
+ if( text::HoriOrientation::NONE==eTabHoriOri )
+ rHTMLWrt.bLFPossible = sal_True;
+
+ const SwHTMLTableLayout *pLayout = rTbl.GetHTMLTableLayout();
+
+#ifdef DBG_UTIL
+ ViewShell *pSh;
+ rWrt.pDoc->GetEditShell( &pSh );
+ if ( pSh && pSh->GetViewOptions()->IsTest1() )
+ pLayout = 0;
+#endif
+
+ if( pLayout && pLayout->IsExportable() )
+ {
+ SwHTMLWrtTable aTableWrt( pLayout );
+ aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTbl.GetRowsToRepeat() > 0,
+ pFmt, pCaption, bTopCaption,
+ nFlyHSpace, nFlyVSpace );
+ }
+ else
+ {
+ SwHTMLWrtTable aTableWrt( rTbl.GetTabLines(), nWidth,
+ nBaseWidth, bRelWidths, rTbl.GetRowsToRepeat() );
+ aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTbl.GetRowsToRepeat() > 0,
+ pFmt, pCaption, bTopCaption,
+ nFlyHSpace, nFlyVSpace );
+ }
+
+ // Wenn die Tabelle in keinem Rahmen war kann man immer ein LF ausgeben.
+ if( text::HoriOrientation::NONE==eTabHoriOri )
+ rHTMLWrt.bLFPossible = sal_True;
+
+ if( text::HoriOrientation::NONE!=eDivHoriOri )
+ {
+ rHTMLWrt.DecIndentLevel(); // Inhalt von <CENTER> einruecken
+ rHTMLWrt.OutNewLine(); // </CENTER> in neue Teile
+ HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
+ text::HoriOrientation::CENTER==eDivHoriOri ? OOO_STRING_SVTOOLS_HTML_center
+ : OOO_STRING_SVTOOLS_HTML_division, sal_False );
+ rHTMLWrt.bLFPossible = sal_True;
+ }
+
+ // Pam hinter die Tabelle verschieben
+ rHTMLWrt.pCurPam->GetPoint()->nNode = *rNode.EndOfSectionNode();
+
+ if( bPreserveForm )
+ {
+ rHTMLWrt.bPreserveForm = sal_False;
+ rHTMLWrt.OutForm( sal_False );
+ }
+
+ rHTMLWrt.bOutTable = sal_False;
+
+ if( rHTMLWrt.GetNextNumInfo() &&
+ !rHTMLWrt.GetNextNumInfo()->IsRestart() &&
+ rHTMLWrt.GetNextNumInfo()->GetNumRule() ==
+ rHTMLWrt.GetNumInfo().GetNumRule() )
+ {
+ // Wenn der Absatz hinter der Tabelle mit der gleichen Regel
+ // numeriert ist wie der Absatz vor der Tabelle, dann steht in
+ // der NumInfo des naechsten Absatzes noch die Ebene des Absatzes
+ // vor der Tabelle. Es muss deshalb die NumInfo noch einmal geholt
+ // werden um ggf. die Num-Liste noch zu beenden.
+ rHTMLWrt.ClearNextNumInfo();
+ rHTMLWrt.FillNextNumInfo();
+ OutHTML_NumBulListEnd( rHTMLWrt, *rHTMLWrt.GetNextNumInfo() );
+ }
+ return rWrt;
+}
+
+
diff --git a/sw/source/filter/html/htmlvsh.hxx b/sw/source/filter/html/htmlvsh.hxx
new file mode 100644
index 000000000000..18e0129fd0a3
--- /dev/null
+++ b/sw/source/filter/html/htmlvsh.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _HTMLVSH_HXX
+#define _HTMLVSH_HXX
+
+#include <calbck.hxx>
+class ViewShell;
+
+
+class SwHTMLViewShellClient : public SwClient
+{
+ virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew );
+
+public:
+
+ SwHTMLViewShellClient( ViewShell *pVSh );
+
+ virtual ~SwHTMLViewShellClient();
+
+ void Register( ViewShell *pVsh );
+ void DeRegister();
+
+ /*inline*/ ViewShell *GetViewShell(); // im swhtml.cxx
+};
+
+
+
+#endif
+
+
diff --git a/sw/source/filter/html/makefile.mk b/sw/source/filter/html/makefile.mk
new file mode 100644
index 000000000000..b99cc6789424
--- /dev/null
+++ b/sw/source/filter/html/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=html
+
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : $(PRJ)$/inc$/swpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/inc$/sw.mk
+
+.IF "$(mydebug)" != ""
+CDEFS=$(CDEFS) -Dmydebug
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/css1atr.obj \
+ $(SLO)$/css1kywd.obj \
+ $(SLO)$/htmlatr.obj \
+ $(SLO)$/htmlbas.obj \
+ $(SLO)$/htmlcss1.obj \
+ $(SLO)$/htmlctxt.obj \
+ $(SLO)$/htmldraw.obj \
+ $(SLO)$/htmlfld.obj \
+ $(SLO)$/htmlfldw.obj \
+ $(SLO)$/htmlfly.obj \
+ $(SLO)$/htmlflyt.obj \
+ $(SLO)$/htmlform.obj \
+ $(SLO)$/htmlforw.obj \
+ $(SLO)$/htmlftn.obj \
+ $(SLO)$/htmlgrin.obj \
+ $(SLO)$/htmlnum.obj \
+ $(SLO)$/htmlplug.obj \
+ $(SLO)$/htmlsect.obj \
+ $(SLO)$/htmltab.obj \
+ $(SLO)$/htmltabw.obj \
+ $(SLO)$/parcss1.obj \
+ $(SLO)$/svxcss1.obj \
+ $(SLO)$/swhtml.obj \
+ $(SLO)$/wrthtml.obj \
+ $(SLO)$/SwAppletImpl.obj \
+
+EXCEPTIONSFILES = \
+ $(SLO)$/htmlfld.obj \
+ $(SLO)$/htmlplug.obj \
+ $(SLO)$/htmlsect.obj \
+ $(SLO)$/swhtml.obj \
+ $(SLO)$/wrthtml.obj
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sw/source/filter/html/parcss1.cxx b/sw/source/filter/html/parcss1.cxx
new file mode 100644
index 000000000000..8d6aadfc41e2
--- /dev/null
+++ b/sw/source/filter/html/parcss1.cxx
@@ -0,0 +1,1426 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <rtl/ustrbuf.hxx>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/htmltokn.h>
+
+#include "css1kywd.hxx"
+#include "parcss1.hxx"
+
+
+// Loop-Check: Um Endlos-Schleifen zu vermeiden, wird in jeder
+// Schalife geprueft, ob ein Fortschritt in der Eingabe-Position
+// stattgefunden hat
+#define LOOP_CHECK
+
+#ifdef LOOP_CHECK
+
+#define LOOP_CHECK_DECL \
+ xub_StrLen nOldInPos = STRING_MAXLEN;
+#define LOOP_CHECK_RESTART \
+ nOldInPos = STRING_MAXLEN;
+#define LOOP_CHECK_CHECK( where ) \
+ DBG_ASSERT( nOldInPos!=nInPos || cNextCh==(sal_Unicode)EOF, where ); \
+ if( nOldInPos==nInPos && cNextCh!=(sal_Unicode)EOF ) \
+ break; \
+ else \
+ nOldInPos = nInPos;
+
+#else
+
+#define LOOP_CHECK_DECL
+#define LOOP_CHECK_RESTART
+#define LOOP_CHECK_CHECK( where )
+
+#endif
+
+
+
+const sal_Int32 MAX_LEN = 1024;
+
+/* */
+
+void CSS1Parser::InitRead( const String& rIn )
+{
+ nlLineNr = 0;
+ nlLinePos = 0;
+
+ bWhiteSpace = TRUE; // Wenn noch nichts gelesen wurde ist das wie WS
+ bEOF = FALSE;
+ eState = CSS1_PAR_WORKING;
+ nValue = 0.;
+
+ aIn = rIn;
+ nInPos = 0;
+ cNextCh = GetNextChar();
+ nToken = GetNextToken();
+}
+
+sal_Unicode CSS1Parser::GetNextChar()
+{
+ if( nInPos >= aIn.Len() )
+ {
+ bEOF = TRUE;
+ return (sal_Unicode)EOF;
+ }
+
+ sal_Unicode c = aIn.GetChar( nInPos );
+ nInPos++;
+
+ if( c == '\n' )
+ {
+ IncLineNr();
+ SetLinePos( 1L );
+ }
+ else
+ IncLinePos();
+
+ return c;
+}
+
+/* */
+
+// Diese Funktion realisiert den in
+//
+// http://www.w3.orh/pub/WWW/TR/WD-css1.html
+// bzw. http://www.w3.orh/pub/WWW/TR/WD-css1-960220.html
+//
+// beschriebenen Scanner fuer CSS1. Es handelt sich um eine direkte
+// Umsetzung der dort beschriebenen Lex-Grammatik
+//
+CSS1Token CSS1Parser::GetNextToken()
+{
+ CSS1Token nRet = CSS1_NULL;
+ aToken.Erase();
+
+ do {
+ // Merken, ob davor White-Space gelesen wurde
+ BOOL bPrevWhiteSpace = bWhiteSpace;
+ bWhiteSpace = FALSE;
+
+ BOOL bNextCh = TRUE;
+ switch( cNextCh )
+ {
+ case '/': // COMMENT | '/'
+ {
+ cNextCh = GetNextChar();
+ if( '*' == cNextCh )
+ {
+ // COMMENT
+ cNextCh = GetNextChar();
+
+ BOOL bAsterix = FALSE;
+ while( !(bAsterix && '/'==cNextCh) && !IsEOF() )
+ {
+ bAsterix = ('*'==cNextCh);
+ cNextCh = GetNextChar();
+ }
+ }
+ else
+ {
+ // '/'
+ bNextCh = FALSE;
+ nRet = CSS1_SLASH;
+ }
+ }
+ break;
+
+ case '@': // '@import' | '@XXX'
+ {
+ cNextCh = GetNextChar();
+ if( ('A' <= cNextCh && cNextCh <= 'Z') ||
+ ('a' <= cNextCh && cNextCh <= 'z') )
+ {
+ // den naechsten Identifer scannen
+ ::rtl::OUStringBuffer sTmpBuffer( 32L );
+ do {
+ sTmpBuffer.append( cNextCh );
+ cNextCh = GetNextChar();
+ } while( ('A' <= cNextCh && cNextCh <= 'Z') ||
+ ('a' <= cNextCh && cNextCh <= 'z') ||
+ ('0' <= cNextCh && cNextCh <= '9') ||
+ '-'==cNextCh && !IsEOF() );
+
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ // und schauen, ob wir ihn kennen
+ switch( aToken.GetChar(0) )
+ {
+ case 'i':
+ case 'I':
+ if( aToken.EqualsIgnoreCaseAscii(sCSS1_import) )
+ nRet = CSS1_IMPORT_SYM;
+ break;
+// /Feature: PrintExt
+ case 'p':
+ case 'P':
+ if( aToken.EqualsIgnoreCaseAscii(sCSS1_page) )
+ nRet = CSS1_PAGE_SYM;
+ break;
+// /Feature: PrintExt
+ }
+
+ // Fehlerbehandlung: '@ident' und alles bis
+ // zu einem Semikolon der dem Ende des folgenden
+ // Blocks ignorieren
+ if( CSS1_NULL==nRet )
+ {
+ aToken.Erase();
+ USHORT nBlockLvl = 0;
+ sal_Unicode cQuoteCh = 0;
+ BOOL bDone = FALSE, bEscape = FALSE;
+ while( !bDone && !IsEOF() )
+ {
+ BOOL bOldEscape = bEscape;
+ bEscape = FALSE;
+ switch( cNextCh )
+ {
+ case '{':
+ if( !cQuoteCh && !bOldEscape )
+ nBlockLvl++;;
+ break;
+ case ';':
+ if( !cQuoteCh && !bOldEscape )
+ bDone = nBlockLvl==0;
+ break;
+ case '}':
+ if( !cQuoteCh && !bOldEscape )
+ bDone = --nBlockLvl==0;
+ break;
+ case '\"':
+ case '\'':
+ if( !bOldEscape )
+ {
+ if( cQuoteCh )
+ {
+ if( cQuoteCh == cNextCh )
+ cQuoteCh = 0;
+ }
+ else
+ {
+ cQuoteCh = cNextCh;
+ }
+ }
+ break;
+ case '\\':
+ if( !bOldEscape )
+ bEscape = TRUE;
+ break;
+ }
+ cNextCh = GetNextChar();
+ }
+ }
+
+ bNextCh = FALSE;
+ }
+ }
+ break;
+
+ case '!': // '!' 'legal' | '!' 'important' | syntax error
+ {
+ // White Space ueberlesen
+ cNextCh = GetNextChar();
+ while( ( ' ' == cNextCh ||
+ (cNextCh >= 0x09 && cNextCh <= 0x0d) ) && !IsEOF() )
+ {
+ bWhiteSpace = TRUE;
+ cNextCh = GetNextChar();
+ }
+
+ if( 'i'==cNextCh || 'I'==cNextCh)
+ {
+ // den naechsten Identifer scannen
+ ::rtl::OUStringBuffer sTmpBuffer( 32L );
+ do {
+ sTmpBuffer.append( cNextCh );
+ cNextCh = GetNextChar();
+ } while( ('A' <= cNextCh && cNextCh <= 'Z') ||
+ ('a' <= cNextCh && cNextCh <= 'z') ||
+ ('0' <= cNextCh && cNextCh <= '9') ||
+ '-' == cNextCh && !IsEOF() );
+
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ if( ('i'==aToken.GetChar(0) || 'I'==aToken.GetChar(0)) &&
+ aToken.EqualsIgnoreCaseAscii(sCSS1_important) )
+ {
+ // '!' 'important'
+ nRet = CSS1_IMPORTANT_SYM;
+ }
+ else
+ {
+ // Fehlerbehandlung: '!' ignorieren, IDENT nicht
+ nRet = CSS1_IDENT;
+ }
+
+ bWhiteSpace = FALSE;
+ bNextCh = FALSE;
+ }
+ else
+ {
+ // Fehlerbehandlung: '!' ignorieren
+ bNextCh = FALSE;
+ }
+ }
+ break;
+
+ case '\"':
+ case '\'': // STRING
+ {
+ // \... geht noch nicht!!!
+ sal_Unicode cQuoteChar = cNextCh;
+ cNextCh = GetNextChar();
+
+ ::rtl::OUStringBuffer sTmpBuffer( MAX_LEN );
+ do {
+ sTmpBuffer.append( cNextCh );
+ cNextCh = GetNextChar();
+ } while( cQuoteChar != cNextCh && !IsEOF() );
+
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ nRet = CSS1_STRING;
+ }
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': // NUMBER | PERCENTAGE | LENGTH
+ {
+ // die aktuelle Position retten
+ xub_StrLen nInPosSave = nInPos;
+ sal_Unicode cNextChSave = cNextCh;
+ sal_uInt32 nlLineNrSave = nlLineNr;
+ sal_uInt32 nlLinePosSave = nlLinePos;
+ BOOL bEOFSave = bEOF;
+
+ // erstmal versuchen eine Hex-Zahl zu scannen
+ ::rtl::OUStringBuffer sTmpBuffer( 16 );
+ do {
+ sTmpBuffer.append( cNextCh );
+ cNextCh = GetNextChar();
+ } while( sTmpBuffer.getLength() < 7 &&
+ ( ('0'<=cNextCh && '9'>=cNextCh) ||
+ ('A'<=cNextCh && 'F'>=cNextCh) ||
+ ('a'<=cNextCh && 'f'>=cNextCh) ) &&
+ !IsEOF() );
+
+ if( sTmpBuffer.getLength()==6 )
+ {
+ // wir haben eine hexadezimale Farbe gefunden
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ nRet = CSS1_HEXCOLOR;
+ bNextCh = FALSE;
+
+ break;
+ }
+
+ // sonst versuchen wir es mit einer Zahl
+ nInPos = nInPosSave;
+ cNextCh = cNextChSave;
+ nlLineNr = nlLineNrSave;
+ nlLinePos = nlLinePosSave;
+ bEOF = bEOFSave;
+
+ // erstmal die Zahl scannen
+ sTmpBuffer.setLength( 0L );
+ do {
+ sTmpBuffer.append( cNextCh );
+ cNextCh = GetNextChar();
+ } while( (('0'<=cNextCh && '9'>=cNextCh) || '.'==cNextCh) &&
+ !IsEOF() );
+
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ nValue = aToken.ToDouble();
+
+ // White Space ueberlesen
+ while( ( ' ' == cNextCh ||
+ (cNextCh >= 0x09 && cNextCh <= 0x0d) ) && !IsEOF() )
+ {
+ bWhiteSpace = TRUE;
+ cNextCh = GetNextChar();
+ }
+
+ // und nun Schauen, ob es eine Einheit gibt
+ switch( cNextCh )
+ {
+ case '%': // PERCENTAGE
+ bWhiteSpace = FALSE;
+ nRet = CSS1_PERCENTAGE;
+ break;
+
+ case 'c':
+ case 'C': // LENGTH cm | LENGTH IDENT
+ case 'e':
+ case 'E': // LENGTH (em | ex) | LENGTH IDENT
+ case 'i':
+ case 'I': // LENGTH inch | LENGTH IDENT
+ case 'p':
+ case 'P': // LENGTH (pt | px | pc) | LENGTH IDENT
+ case 'm':
+ case 'M': // LENGTH mm | LENGTH IDENT
+ {
+ // die aktuelle Position retten
+ xub_StrLen nInPosOld = nInPos;
+ sal_Unicode cNextChOld = cNextCh;
+ ULONG nlLineNrOld = nlLineNr;
+ ULONG nlLinePosOld = nlLinePos;
+ BOOL bEOFOld = bEOF;
+
+ // den naechsten Identifer scannen
+ String aIdent;
+ ::rtl::OUStringBuffer sTmpBuffer2( 64L );
+ do {
+ sTmpBuffer2.append( cNextCh );
+ cNextCh = GetNextChar();
+ } while( ( ('A' <= cNextCh && cNextCh <= 'Z') ||
+ ('a' <= cNextCh && cNextCh <= 'z') ||
+ ('0' <= cNextCh && cNextCh <= '9') ||
+ '-'==cNextCh) && !IsEOF() );
+
+ aIdent += String(sTmpBuffer2.makeStringAndClear());
+
+ // Ist es eine Einheit?
+ const sal_Char *pCmp1 = 0, *pCmp2 = 0, *pCmp3 = 0;
+ double nScale1 = 1., nScale2 = 1., nScale3 = 1.;
+ CSS1Token nToken1 = CSS1_LENGTH,
+ nToken2 = CSS1_LENGTH,
+ nToken3 = CSS1_LENGTH;
+ switch( aIdent.GetChar(0) )
+ {
+ case 'c':
+ case 'C':
+ pCmp1 = sCSS1_UNIT_cm;
+ nScale1 = (72.*20.)/2.54; // twip
+ break;
+ case 'e':
+ case 'E':
+ pCmp1 = sCSS1_UNIT_em;
+ nToken1 = CSS1_EMS;
+
+ pCmp2 = sCSS1_UNIT_ex;
+ nToken2 = CSS1_EMX;
+ break;
+ case 'i':
+ case 'I':
+ pCmp1 = sCSS1_UNIT_inch;
+ nScale1 = 72.*20.; // twip
+ break;
+ case 'm':
+ case 'M':
+ pCmp1 = sCSS1_UNIT_mm;
+ nScale1 = (72.*20.)/25.4; // twip
+ break;
+ case 'p':
+ case 'P':
+ pCmp1 = sCSS1_UNIT_pt;
+ nScale1 = 20.; // twip
+
+ pCmp2 = sCSS1_UNIT_pc;
+ nScale2 = 12.*20.; // twip
+
+ pCmp3 = sCSS1_UNIT_px;
+ nToken3 = CSS1_PIXLENGTH;
+ break;
+ }
+
+ double nScale = 0.0;
+ DBG_ASSERT( pCmp1, "Wo kommt das erste Zeichen her?" );
+ if( aIdent.EqualsIgnoreCaseAscii(pCmp1) )
+ {
+ nScale = nScale1;
+ nRet = nToken1;
+ }
+ else if( pCmp2 &&
+ aIdent.EqualsIgnoreCaseAscii(pCmp2) )
+ {
+ nScale = nScale2;
+ nRet = nToken2;
+ }
+ else if( pCmp3 &&
+ aIdent.EqualsIgnoreCaseAscii(pCmp3) )
+ {
+ nScale = nScale3;
+ nRet = nToken3;
+ }
+ else
+ {
+ nRet = CSS1_NUMBER;
+ }
+
+ if( CSS1_LENGTH==nRet && nScale!=1.0 )
+ nValue *= nScale;
+
+ if( nRet == CSS1_NUMBER )
+ {
+ nInPos = nInPosOld;
+ cNextCh = cNextChOld;
+ nlLineNr = nlLineNrOld;
+ nlLinePos = nlLinePosOld;
+ bEOF = bEOFOld;
+ }
+ else
+ {
+ bWhiteSpace = FALSE;
+ }
+ bNextCh = FALSE;
+ }
+ break;
+ default: // NUMBER IDENT
+ bNextCh = FALSE;
+ nRet = CSS1_NUMBER;
+ break;
+ }
+ }
+ break;
+
+ case ':': // ':'
+ // link/visited/active abfangen !!!
+ nRet = CSS1_COLON;
+ break;
+
+ case '.': // DOT_W_WS | DOT_WO_WS
+ nRet = bPrevWhiteSpace ? CSS1_DOT_W_WS : CSS1_DOT_WO_WS;
+ break;
+
+ // case '/': siehe oben
+
+ case '+': // '+'
+ nRet = CSS1_PLUS;
+ break;
+
+ case '-': // '-'
+ nRet = CSS1_MINUS;
+ break;
+
+ case '{': // '{'
+ nRet = CSS1_OBRACE;
+ break;
+
+ case '}': // '}'
+ nRet = CSS1_CBRACE;
+ break;
+
+ case ';': // ';'
+ nRet = CSS1_SEMICOLON;
+ break;
+
+ case ',': // ','
+ nRet = CSS1_COMMA;
+ break;
+
+ case '#': // '#'
+ cNextCh = GetNextChar();
+ if( ('0'<=cNextCh && '9'>=cNextCh) ||
+ ('a'<=cNextCh && 'f'>=cNextCh) ||
+ ('A'<=cNextCh && 'F'>=cNextCh) )
+ {
+ // die aktuelle Position retten
+ xub_StrLen nInPosSave = nInPos;
+ sal_Unicode cNextChSave = cNextCh;
+ ULONG nlLineNrSave = nlLineNr;
+ ULONG nlLinePosSave = nlLinePos;
+ BOOL bEOFSave = bEOF;
+
+ // erstmal versuchen eine Hex-Zahl zu scannen
+ ::rtl::OUStringBuffer sTmpBuffer( 6L );
+ do {
+ sTmpBuffer.append( cNextCh );
+ cNextCh = GetNextChar();
+ } while( sTmpBuffer.getLength() < 7 &&
+ ( ('0'<=cNextCh && '9'>=cNextCh) ||
+ ('A'<=cNextCh && 'F'>=cNextCh) ||
+ ('a'<=cNextCh && 'f'>=cNextCh) ) &&
+ !IsEOF() );
+
+ if( sTmpBuffer.getLength()==6 || sTmpBuffer.getLength()==3 )
+ {
+ // wir haben eine hexadezimale Farbe gefunden
+ aToken += String(sTmpBuffer.makeStringAndClear());
+ nRet = CSS1_HEXCOLOR;
+ bNextCh = FALSE;
+
+ break;
+ }
+
+ // sonst versuchen wir es mit einer Zahl
+ nInPos = nInPosSave;
+ cNextCh = cNextChSave;
+ nlLineNr = nlLineNrSave;
+ nlLinePos = nlLinePosSave;
+ bEOF = bEOFSave;
+ }
+
+ nRet = CSS1_HASH;
+ bNextCh = FALSE;
+ break;
+
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n': // White-Space
+ bWhiteSpace = TRUE;
+ break;
+
+ case (sal_Unicode)EOF:
+ if( IsEOF() )
+ {
+ eState = CSS1_PAR_ACCEPTED;
+ bNextCh = FALSE;
+ break;
+ }
+ // kein break;
+
+ default: // IDENT | syntax error
+ // TODO IsAlpha
+ if( ('A' <= cNextCh && cNextCh <= 'Z') ||
+ ('a' <= cNextCh && cNextCh <= 'z') )
+ {
+ // IDENT
+
+ BOOL bHexColor = TRUE;
+
+ // den naechsten Identifer scannen
+ ::rtl::OUStringBuffer sTmpBuffer( 64L );
+ do {
+ sTmpBuffer.append( cNextCh );
+ if( bHexColor )
+ {
+ bHexColor = sTmpBuffer.getLength()<7 &&
+ ( ('0'<=cNextCh && '9'>=cNextCh) ||
+ ('A'<=cNextCh && 'F'>=cNextCh) ||
+ ('a'<=cNextCh && 'f'>=cNextCh) );
+ }
+ cNextCh = GetNextChar();
+ // TODO: AlphaNumeric
+ } while( ( ('0'<=cNextCh && '9'>=cNextCh) ||
+ ('A'<=cNextCh && 'Z'>=cNextCh) ||
+ ('a'<=cNextCh && 'z'>=cNextCh) ||
+ '-'==cNextCh ) &&
+ !IsEOF() );
+
+ aToken += String(sTmpBuffer.makeStringAndClear());
+
+ if( bHexColor && sTmpBuffer.getLength()==6 )
+ {
+ bNextCh = FALSE;
+ nRet = CSS1_HEXCOLOR;
+
+ break;
+ }
+ if( '('==cNextCh &&
+ ( (('u'==aToken.GetChar(0) || 'U'==aToken.GetChar(0)) &&
+ aToken.EqualsIgnoreCaseAscii(sCSS1_url)) ||
+ (('r'==aToken.GetChar(0) || 'R'==aToken.GetChar(0)) &&
+ aToken.EqualsIgnoreCaseAscii(sCSS1_rgb)) ) )
+ {
+ USHORT nNestCnt = 0;
+ ::rtl::OUStringBuffer sTmpBuffer2( 64L );
+ do {
+ sTmpBuffer2.append( cNextCh );
+ switch( cNextCh )
+ {
+ case '(': nNestCnt++; break;
+ case ')': nNestCnt--; break;
+ }
+ cNextCh = GetNextChar();
+ } while( (nNestCnt>1 || ')'!=cNextCh) && !IsEOF() );
+ sTmpBuffer2.append( cNextCh );
+ aToken += String(sTmpBuffer2.makeStringAndClear());
+ bNextCh = TRUE;
+ nRet = 'u'==aToken.GetChar(0) || 'U'==aToken.GetChar(0)
+ ? CSS1_URL
+ : CSS1_RGB;
+ }
+ else
+ {
+ bNextCh = FALSE;
+ nRet = CSS1_IDENT;
+ }
+ }
+ // Fehlerbehandlung: Zeichen ignorieren
+ break;
+ }
+ if( bNextCh )
+ cNextCh = GetNextChar();
+
+ } while( CSS1_NULL==nRet && IsParserWorking() );
+
+ return nRet;
+}
+
+
+/* */
+
+
+// Dies folegenden Funktionen realisieren den in
+//
+// http://www.w3.orh/pub/WWW/TR/WD-css1.html
+// bzw. http://www.w3.orh/pub/WWW/TR/WD-css1-960220.html
+//
+// beschriebenen Parser fuer CSS1. Es handelt sich um eine direkte
+// Umsetzung der dort beschriebenen Grammatik
+
+// stylesheet
+// : import* rule*
+//
+// import
+// : IMPORT_SYM url
+//
+// url
+// : STRING
+//
+void CSS1Parser::ParseStyleSheet()
+{
+ LOOP_CHECK_DECL
+
+ // import*
+ BOOL bDone = FALSE;
+ while( !bDone && IsParserWorking() )
+ {
+ LOOP_CHECK_CHECK( "Endlos-Schleife in ParseStyleSheet()/import *" )
+
+ switch( nToken )
+ {
+ case CSS1_IMPORT_SYM:
+ // IMPORT_SYM url
+ // url ueberspringen wir ungeprueft
+ nToken = GetNextToken();
+ break;
+ case CSS1_IDENT: // Look-Aheads
+ case CSS1_DOT_W_WS:
+ case CSS1_HASH:
+// /Feature: PrintExt
+ case CSS1_PAGE_SYM:
+// /Feature: PrintExt
+ // rule
+ bDone = TRUE;
+ break;
+ default:
+ // Fehlerbehandlung: ueberlesen
+ break;
+ }
+
+ if( !bDone )
+ nToken = GetNextToken();
+ }
+
+ LOOP_CHECK_RESTART
+
+ // rule *
+ while( IsParserWorking() )
+ {
+ LOOP_CHECK_CHECK( "Endlos-Schleife in ParseStyleSheet()/rule *" )
+
+ switch( nToken )
+ {
+ case CSS1_IDENT: // Look-Aheads
+ case CSS1_DOT_W_WS:
+ case CSS1_HASH:
+// /Feature: PrintExt
+ case CSS1_PAGE_SYM:
+// /Feature: PrintExt
+ // rule
+ ParseRule();
+ break;
+ default:
+ // Fehlerbehandlung: ueberlesen
+ nToken = GetNextToken();
+ break;
+ }
+ }
+}
+
+// rule
+// : selector [ ',' selector ]*
+// '{' declaration [ ';' declaration ]* '}'
+//
+void CSS1Parser::ParseRule()
+{
+ // selector
+ CSS1Selector *pSelector = ParseSelector();
+ if( !pSelector )
+ return;
+
+ // Selektor verarbeiten
+ if( SelectorParsed( pSelector, TRUE ) )
+ delete pSelector;
+
+ LOOP_CHECK_DECL
+
+ // [ ',' selector ]*
+ while( CSS1_COMMA==nToken && IsParserWorking() )
+ {
+ LOOP_CHECK_CHECK( "Endlos-Schleife in ParseRule()/selector *" )
+
+ // ',' ueberelesen
+ nToken = GetNextToken();
+
+ // selector
+ pSelector = ParseSelector();
+ if( !pSelector )
+ return;
+
+ // Selektor verarbeiten
+ if( SelectorParsed( pSelector, FALSE ) )
+ delete pSelector;
+ }
+
+ // '{'
+ if( CSS1_OBRACE != nToken )
+ return;
+ nToken = GetNextToken();
+
+ // declaration
+ String aProperty;
+ CSS1Expression *pExpr = ParseDeclaration( aProperty );
+ if( !pExpr )
+ return;
+
+ // expression verarbeiten
+ if( DeclarationParsed( aProperty, pExpr ) )
+ delete pExpr;
+
+ LOOP_CHECK_RESTART
+
+ // [ ';' declaration ]*
+ while( CSS1_SEMICOLON==nToken && IsParserWorking() )
+ {
+ LOOP_CHECK_CHECK( "Endlos-Schleife in ParseRule()/declaration *" )
+
+ // ';'
+ nToken = GetNextToken();
+
+ // declaration
+ if( CSS1_IDENT == nToken )
+ {
+ CSS1Expression *pExp = ParseDeclaration( aProperty );
+ if( pExp )
+ {
+ // expression verarbeiten
+ if( DeclarationParsed( aProperty, pExp ) )
+ delete pExp;
+ }
+ }
+ }
+
+ // '}'
+ if( CSS1_CBRACE == nToken )
+ nToken = GetNextToken();
+}
+
+// selector
+// : simple_selector+ [ ':' pseudo_element ]?
+//
+// simple_selector
+// : element_name [ DOT_WO_WS class ]?
+// | DOT_W_WS class
+// | id_selector
+//
+// element_name
+// : IDENT
+//
+// class
+// : IDENT
+//
+// id_selector
+// : '#' IDENT
+//
+// pseude_element
+// : IDENT
+//
+CSS1Selector *CSS1Parser::ParseSelector()
+{
+ CSS1Selector *pRoot = 0, *pLast = 0;
+
+ BOOL bDone = FALSE;
+ CSS1Selector *pNew = 0;
+
+ LOOP_CHECK_DECL
+
+ // simple_selector+
+ while( !bDone && IsParserWorking() )
+ {
+ LOOP_CHECK_CHECK( "Endlos-Schleife in ParseSelector()" )
+
+ BOOL bNextToken = TRUE;
+
+ switch( nToken )
+ {
+ case CSS1_IDENT:
+ {
+ // element_name [ DOT_WO_WS class ]?
+
+ // element_name
+ String aElement = aToken;
+ CSS1SelectorType eType = CSS1_SELTYPE_ELEMENT;
+ nToken = GetNextToken();
+
+ if( CSS1_DOT_WO_WS == nToken )
+ {
+ // DOT_WO_WS
+ nToken = GetNextToken();
+
+ // class
+ if( CSS1_IDENT == nToken )
+ {
+ (aElement += '.') += aToken;
+ eType = CSS1_SELTYPE_ELEM_CLASS;
+ }
+ else
+ {
+ // class fehlt
+ return pRoot;
+ }
+ }
+ else
+ {
+ // das war jetzt ein Look-Ahead
+ bNextToken = FALSE;
+ }
+ pNew = new CSS1Selector( eType, aElement );
+ }
+ break;
+ case CSS1_DOT_W_WS:
+ // DOT_W_WS class
+
+ // DOT_W_WS
+ nToken = GetNextToken();
+
+ if( CSS1_IDENT==nToken )
+ {
+ // class
+ pNew = new CSS1Selector( CSS1_SELTYPE_CLASS, aToken );
+ }
+ else
+ {
+ // class fehlt
+ return pRoot;
+ }
+ break;
+ case CSS1_HASH:
+ // '#' id_selector
+
+ // '#'
+ nToken = GetNextToken();
+
+ if( CSS1_IDENT==nToken )
+ {
+ // id_selector
+ pNew = new CSS1Selector( CSS1_SELTYPE_ID, aToken );
+ }
+ else
+ {
+ // id_selector fehlt
+ return pRoot;
+ }
+ break;
+
+// /Feature: PrintExt
+ case CSS1_PAGE_SYM:
+ {
+ // @page
+ pNew = new CSS1Selector( CSS1_SELTYPE_PAGE, aToken );
+ }
+ break;
+// /Feature: PrintExt
+
+ default:
+ // wir wissen nicht was kommt, also aufhoehren
+ bDone = TRUE;
+ break;
+ }
+
+ // falls ein Selektor angelegt wurd, ihn speichern
+ if( pNew )
+ {
+ DBG_ASSERT( (pRoot!=0) == (pLast!=0),
+ "Root-Selektor, aber kein Last" );
+ if( pLast )
+ pLast->SetNext( pNew );
+ else
+ pRoot = pNew;
+
+ pLast = pNew;
+ pNew = 0;
+ }
+
+ if( bNextToken && !bDone )
+ nToken = GetNextToken();
+ }
+
+ if( !pRoot )
+ {
+ // simple_selector fehlt
+ return pRoot;
+ }
+
+ // [ ':' pseudo_element ]?
+ if( CSS1_COLON==nToken && IsParserWorking() )
+ {
+ // ':' pseudo element
+ nToken = GetNextToken();
+ if( CSS1_IDENT==nToken )
+ {
+ pLast->SetNext( new CSS1Selector(CSS1_SELTYPE_PSEUDO,aToken) );
+ nToken = GetNextToken();
+ }
+ else
+ {
+ // pseudo_element fehlt
+ return pRoot;
+ }
+ }
+
+ return pRoot;
+}
+
+// declaration
+// : property ':' expr prio?
+// | /* empty */
+//
+// expression
+// : term [ operator term ]*
+//
+// term
+// : unary_operator?
+// [ NUMBER | STRING | PERCENTAGE | LENGTH | EMS | EXS | IDENT |
+// HEXCOLOR | URL | RGB ]
+//
+// operator
+// : '/' | ',' | /* empty */
+//
+// unary_operator
+// : '-' | '+'
+//
+// property
+// : ident
+//
+// das Vorzeichen wird nur fuer numerische Werte (ausser PERCENTAGE)
+// beruecksichtigt und wird auf nValue angewendet!
+CSS1Expression *CSS1Parser::ParseDeclaration( String& rProperty )
+{
+ CSS1Expression *pRoot = 0, *pLast = 0;
+
+ // property
+ if( CSS1_IDENT != nToken )
+ {
+ // property fehlt
+ return pRoot;
+ }
+ rProperty = aToken;
+
+ nToken = GetNextToken();
+
+
+ // ':'
+ if( CSS1_COLON != nToken )
+ {
+ // ':' fehlt
+ return pRoot;
+ }
+ nToken = GetNextToken();
+
+ // term [operator term]*
+ // hier sind wir sehr lax, was die Syntax angeht, sollte aber kein
+ // Problem sein
+ BOOL bDone = FALSE;
+ sal_Unicode cSign = 0, cOp = 0;
+ CSS1Expression *pNew = 0;
+
+ LOOP_CHECK_DECL
+
+ while( !bDone && IsParserWorking() )
+ {
+ LOOP_CHECK_CHECK( "Endlos-Schleife in ParseDeclaration()" )
+
+ switch( nToken )
+ {
+ case CSS1_MINUS:
+ cSign = '-';
+ break;
+
+ case CSS1_PLUS:
+ cSign = '+';
+ break;
+
+ case CSS1_NUMBER:
+ case CSS1_LENGTH:
+ case CSS1_PIXLENGTH:
+ case CSS1_EMS:
+ case CSS1_EMX:
+ if( '-'==cSign )
+ nValue = -nValue;
+ case CSS1_STRING:
+ case CSS1_PERCENTAGE:
+ case CSS1_IDENT:
+ case CSS1_URL:
+ case CSS1_RGB:
+ case CSS1_HEXCOLOR:
+ pNew = new CSS1Expression( nToken, aToken, nValue, cOp );
+ nValue = 0; // sonst landet das auch im naechsten Ident
+ cSign = 0;
+ cOp = 0;
+ break;
+
+ case CSS1_SLASH:
+ cOp = '/';
+ cSign = 0;
+ break;
+
+ case CSS1_COMMA:
+ cOp = ',';
+ cSign = 0;
+ break;
+
+ default:
+ bDone = TRUE;
+ break;
+ }
+
+ // falls ein Expression angelegt wurde, diesen speichern
+ if( pNew )
+ {
+ DBG_ASSERT( (pRoot!=0) == (pLast!=0),
+ "Root-Selektor, aber kein Last" );
+ if( pLast )
+ pLast->SetNext( pNew );
+ else
+ pRoot = pNew;
+
+ pLast = pNew;
+ pNew = 0;
+ }
+
+ if( !bDone )
+ nToken = GetNextToken();
+ }
+
+ if( !pRoot )
+ {
+ // term fehlt
+ return pRoot;
+ }
+
+ // prio?
+ if( CSS1_IMPORTANT_SYM==nToken )
+ {
+ // IMPORTANT_SYM
+ nToken = GetNextToken();
+ }
+
+ return pRoot;
+}
+
+/* */
+
+CSS1Parser::CSS1Parser()
+{
+}
+
+CSS1Parser::~CSS1Parser()
+{
+}
+
+/* */
+
+BOOL CSS1Parser::ParseStyleSheet( const String& rIn )
+{
+ String aTmp( rIn );
+
+ sal_Unicode c;
+ while( aTmp.Len() &&
+ ( ' '==(c=aTmp.GetChar(0)) || '\t'==c || '\r'==c || '\n'==c ) )
+ aTmp.Erase( 0, 1 );
+
+ while( aTmp.Len() && ( ' '==(c=aTmp.GetChar( aTmp.Len()-1))
+ || '\t'==c || '\r'==c || '\n'==c ) )
+ aTmp.Erase( aTmp.Len()-1 );
+
+ // SGML-Kommentare entfernen
+ if( aTmp.Len() >= 4 &&
+ aTmp.CompareToAscii("<!--",4) == COMPARE_EQUAL )
+ aTmp.Erase( 0, 4 );
+
+ if( aTmp.Len() >=3 &&
+ aTmp.Copy(aTmp.Len()-3).CompareToAscii("-->") == COMPARE_EQUAL )
+ aTmp.Erase( aTmp.Len()-3 );
+
+ if( !aTmp.Len() )
+ return TRUE;
+
+ InitRead( aTmp );
+
+ ParseStyleSheet();
+
+ return TRUE;
+}
+
+
+BOOL CSS1Parser::ParseStyleOption( const String& rIn )
+{
+ if( !rIn.Len() )
+ return TRUE;
+
+ InitRead( rIn );
+
+ String aProperty;
+ CSS1Expression *pExpr = ParseDeclaration( aProperty );
+ if( !pExpr )
+ {
+ return FALSE;
+ }
+
+ // expression verarbeiten
+ if( DeclarationParsed( aProperty, pExpr ) )
+ delete pExpr;
+
+ LOOP_CHECK_DECL
+
+ // [ ';' declaration ]*
+ while( CSS1_SEMICOLON==nToken && IsParserWorking() )
+ {
+ LOOP_CHECK_CHECK( "Endlos-Schleife in ParseStyleOption()" )
+
+ nToken = GetNextToken();
+ if( CSS1_IDENT==nToken )
+ {
+ CSS1Expression *pExp = ParseDeclaration( aProperty );
+ if( pExp )
+ {
+ // expression verarbeiten
+ if( DeclarationParsed( aProperty, pExp ) )
+ delete pExp;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+BOOL CSS1Parser::SelectorParsed( const CSS1Selector * /* pSelector */, BOOL /*bFirst*/ )
+{
+ // Selektor loeschen
+ return TRUE;
+}
+
+BOOL CSS1Parser::DeclarationParsed( const String& /*rProperty*/,
+ const CSS1Expression * /* pExpr */ )
+{
+ // Deklaration loeschen
+ return TRUE;
+}
+
+
+/* */
+
+CSS1Selector::~CSS1Selector()
+{
+ delete pNext;
+}
+
+/* */
+
+CSS1Expression::~CSS1Expression()
+{
+ delete pNext;
+}
+
+BOOL CSS1Expression::GetURL( String& rURL ) const
+{
+ DBG_ASSERT( CSS1_URL==eType, "CSS1-Ausruck ist keine Farbe URL" );
+
+ DBG_ASSERT( aValue.CompareIgnoreCaseToAscii( sCSS1_url, 3 ) ==
+ COMPARE_EQUAL &&
+ aValue.Len() > 5 &&
+ '(' == aValue.GetChar(3) &&
+ ')' == aValue.GetChar(aValue.Len()-1),
+ "keine gueltiges URL(...)" );
+
+ BOOL bRet = FALSE;
+
+ if( aValue.Len() > 5 )
+ {
+ rURL = aValue.Copy( 4, aValue.Len()-5 );
+ rURL.EraseTrailingChars();
+ rURL.EraseLeadingChars();
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+BOOL CSS1Expression::GetColor( Color &rColor ) const
+{
+ DBG_ASSERT( CSS1_IDENT==eType || CSS1_RGB==eType ||
+ CSS1_HEXCOLOR==eType || CSS1_STRING==eType,
+ "CSS1-Ausruck kann keine Farbe sein" );
+
+ BOOL bRet = FALSE;
+ ULONG nColor = ULONG_MAX;
+
+ switch( eType )
+ {
+ case CSS1_RGB:
+ {
+ BYTE aColors[3] = { 0, 0, 0 };
+
+ DBG_ASSERT( aValue.CompareIgnoreCaseToAscii( sCSS1_rgb, 3 )
+ == COMPARE_EQUAL &&
+ aValue.Len() > 5 &&
+ '(' == aValue.GetChar( 3 ) &&
+ ')' == aValue.GetChar( aValue.Len()-1),
+ "keine gueltiges RGB(...)" );
+
+ String aColorStr( aValue.Copy( 4, aValue.Len()-1 ) );
+
+ xub_StrLen nPos = 0;
+ USHORT nCol = 0;
+
+ while( nCol < 3 && nPos < aColorStr.Len() )
+ {
+ sal_Unicode c;
+ while( nPos < aColorStr.Len() &&
+ ((c=aColorStr.GetChar(nPos)) == ' ' || c == '\t' ||
+ c == '\n' || c== '\r' ) )
+ nPos++;
+
+ xub_StrLen nEnd = aColorStr.Search( ',', nPos );
+ String aNumber;
+ if( STRING_NOTFOUND==nEnd )
+ {
+ aNumber = aColorStr.Copy(nPos);
+ nPos = aColorStr.Len();
+ }
+ else
+ {
+ aNumber = aColorStr.Copy( nPos, nEnd-nPos );
+ nPos = nEnd+1;
+ }
+
+ USHORT nNumber = (USHORT)aNumber.ToInt32();
+ if( aNumber.Search('%') != STRING_NOTFOUND )
+ {
+ if( nNumber > 100 )
+ nNumber = 100;
+ nNumber *= 255;
+ nNumber /= 100;
+ }
+ else if( nNumber > 255 )
+ nNumber = 255;
+
+ aColors[nCol] = (BYTE)nNumber;
+ nCol ++;
+ }
+
+ rColor.SetRed( aColors[0] );
+ rColor.SetGreen( aColors[1] );
+ rColor.SetBlue( aColors[2] );
+
+ bRet = TRUE; // etwas anderes als eine Farbe kann es nicht sein
+ }
+ break;
+
+ case CSS1_IDENT:
+ case CSS1_STRING:
+ {
+ String aTmp( aValue );
+ aTmp.ToUpperAscii();
+ nColor = GetHTMLColor( aTmp );
+ bRet = nColor != ULONG_MAX;
+ }
+ if( bRet || CSS1_STRING != eType || !aValue.Len() ||
+ aValue.GetChar( 0 )!='#' )
+ break;
+
+ case CSS1_HEXCOLOR:
+ {
+ // HACK fuer MS-IE: DIe Farbe kann auch in einem String stehen
+ xub_StrLen nOffset = CSS1_STRING==eType ? 1 : 0;
+ BOOL bDouble = aValue.Len()-nOffset == 3;
+ xub_StrLen i = nOffset, nEnd = (bDouble ? 3 : 6) + nOffset;
+
+ nColor = 0;
+ for( ; i<nEnd; i++ )
+ {
+ sal_Unicode c = (i<aValue.Len() ? aValue.GetChar(i)
+ : '0' );
+ if( c >= '0' && c <= '9' )
+ c -= 48;
+ else if( c >= 'A' && c <= 'F' )
+ c -= 55;
+ else if( c >= 'a' && c <= 'f' )
+ c -= 87;
+ else
+ c = 16;
+
+ nColor *= 16;
+ if( c<16 )
+ nColor += c;
+ if( bDouble )
+ {
+ nColor *= 16;
+ if( c<16 )
+ nColor += c;
+ }
+ }
+ // bRet = i==6;
+ bRet = TRUE;
+ }
+ break;
+ default:
+ ;
+ }
+
+
+ if( bRet && nColor!=ULONG_MAX )
+ {
+ rColor.SetRed( (BYTE)((nColor & 0x00ff0000UL) >> 16) );
+ rColor.SetGreen( (BYTE)((nColor & 0x0000ff00UL) >> 8) );
+ rColor.SetBlue( (BYTE)(nColor & 0x000000ffUL) );
+ }
+
+ return bRet;
+}
+
diff --git a/sw/source/filter/html/parcss1.hxx b/sw/source/filter/html/parcss1.hxx
new file mode 100644
index 000000000000..7d85f05e4a7f
--- /dev/null
+++ b/sw/source/filter/html/parcss1.hxx
@@ -0,0 +1,307 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _PARCSS1_HXX
+#define _PARCSS1_HXX
+
+#include <tools/string.hxx>
+
+class Color;
+
+/* */
+
+// Die Tokens des CSS1-Parsers
+enum CSS1Token
+{
+ CSS1_NULL,
+ CSS1_UNKOWN,
+
+ CSS1_IDENT,
+ CSS1_STRING,
+ CSS1_NUMBER,
+ CSS1_PERCENTAGE,
+ CSS1_LENGTH, // eine absolute Groesse in 1/100 MM
+ CSS1_PIXLENGTH, // eine Pixel-Groesse
+ CSS1_EMS,
+ CSS1_EMX,
+ CSS1_HEXCOLOR,
+
+ CSS1_DOT_W_WS,
+ CSS1_DOT_WO_WS,
+ CSS1_COLON,
+ CSS1_SLASH,
+ CSS1_PLUS,
+ CSS1_MINUS,
+ CSS1_OBRACE,
+ CSS1_CBRACE,
+ CSS1_SEMICOLON,
+ CSS1_COMMA,
+ CSS1_HASH,
+
+ CSS1_IMPORT_SYM,
+// Feature: PrintExt
+ CSS1_PAGE_SYM,
+// /Feature: PrintExt
+
+ CSS1_IMPORTANT_SYM,
+
+ CSS1_URL,
+ CSS1_RGB
+};
+
+
+// die Zustaende des Parsers
+enum CSS1ParserState
+{
+ CSS1_PAR_ACCEPTED = 0,
+ CSS1_PAR_WORKING,
+ CSS1_PAR_ERROR
+};
+
+
+/* */
+
+enum CSS1SelectorType
+{
+ CSS1_SELTYPE_ELEMENT,
+ CSS1_SELTYPE_ELEM_CLASS,
+ CSS1_SELTYPE_CLASS,
+ CSS1_SELTYPE_ID,
+ CSS1_SELTYPE_PSEUDO,
+// Feature: PrintExt
+ CSS1_SELTYPE_PAGE
+// /Feature: PrintExt
+
+};
+
+// Die folegende Klasse beschreibt einen Simple-Selector, also
+// - einen HTML-Element-Namen
+// - einen HTML-Element-Namen mit Klasse (durch '.' getrennt)
+// - eine Klasse (ohne Punkt)
+// - eine mit ID=xxx gesetzte ID aus einem HTML-Dokument
+// oder
+// - ein Pseudo-Element
+//
+// Die Simple-Sektoren werden in einer Liste zu vollstaendigen
+// Selektoren verkettet
+class CSS1Selector
+{
+ CSS1SelectorType eType; // Art des Selektors
+ String aSelector; // der Selektor selbst
+ CSS1Selector *pNext; // die naechste Komponente
+
+public:
+
+ CSS1Selector( CSS1SelectorType eTyp, const String &rSel )
+ : eType(eTyp), aSelector( rSel ), pNext( 0 )
+ {}
+
+ ~CSS1Selector();
+
+ CSS1SelectorType GetType() const { return eType; }
+ const String& GetString() const { return aSelector; }
+
+ void SetNext( CSS1Selector *pNxt ) { pNext = pNxt; }
+ const CSS1Selector *GetNext() const { return pNext; }
+};
+
+
+/* */
+
+// Die folegende Klasse beschreibt einen Teil-Ausdruck einer
+// CSS1-Deklaration sie besteht aus
+//
+// - dem Typ des Ausdrucks (entspricht dem Token)
+// - dem eigentlichen Wert als String und ggf. double
+// der double-Wert enthaelt das Vorzeichen fuer NUMBER und LENGTH
+// - und dem Operator, mit dem er mit dem *Vorganger*-Ausdruck
+// verknuepft ist.
+//
+struct CSS1Expression
+{
+ sal_Unicode cOp; // Art der Verkuepfung mit dem Vorgaenger
+ CSS1Token eType; // der Typ des Wertes
+ String aValue; // und sein Wert als String
+ double nValue; // und als Zahl (TWIPs fuer LENGTH)
+ CSS1Expression *pNext; // die naechste Komponente
+
+public:
+
+ CSS1Expression( CSS1Token eTyp, const String &rVal,
+ double nVal, sal_Unicode cO = 0 )
+ : cOp(cO), eType(eTyp), aValue(rVal), nValue(nVal), pNext(0)
+ {}
+
+ ~CSS1Expression();
+
+ inline void Set( CSS1Token eTyp, const String &rVal, double nVal,
+ sal_Unicode cO = 0 );
+
+ CSS1Token GetType() const { return eType; }
+ const String& GetString() const { return aValue; }
+ double GetNumber() const { return nValue; }
+ inline sal_uInt32 GetULength() const;
+ inline sal_Int32 GetSLength() const;
+ sal_Unicode GetOp() const { return cOp; }
+
+
+ sal_Bool GetURL( String& rURL ) const;
+ sal_Bool GetColor( Color &rRGB ) const;
+
+ void SetNext( CSS1Expression *pNxt ) { pNext = pNxt; }
+ const CSS1Expression *GetNext() const { return pNext; }
+};
+
+inline void CSS1Expression::Set( CSS1Token eTyp, const String &rVal,
+ double nVal, sal_Unicode cO )
+{
+ cOp = cO; eType = eTyp; aValue = rVal; nValue = nVal; pNext = 0;
+}
+
+inline sal_uInt32 CSS1Expression::GetULength() const
+{
+ return nValue < 0. ? 0UL : (sal_uInt32)(nValue + .5);
+}
+
+inline sal_Int32 CSS1Expression::GetSLength() const
+{
+ return (sal_Int32)(nValue + (nValue < 0. ? -.5 : .5 ));
+}
+
+/* */
+
+// Diese Klasse parst den Inhalt eines Style-Elements oder eine Style-Option
+// und bereitet ihn ein wenig auf.
+//
+// Das Ergebnis des Parsers wird durch die Mehtoden SelectorParsed()
+// und DeclarationParsed() an abgeleitete Parser uebergeben. Bsp:
+//
+// H1, H2 { font-weight: bold; text-align: right }
+// | | | |
+// | | | DeclP( 'text-align', 'right' )
+// | | DeclP( 'font-weight', 'bold' )
+// | SelP( 'H2', sal_False )
+// SelP( 'H1', sal_True )
+//
+class CSS1Parser
+{
+ sal_Bool bWhiteSpace : 1; // White-Space gelesen?
+ sal_Bool bEOF : 1; // Ende des "Files" ?
+
+ sal_Unicode cNextCh; // naechstes Zeichen
+
+ xub_StrLen nInPos; // aktuelle Position im Input-String
+
+ sal_uInt32 nlLineNr; // akt. Zeilen Nummer
+ sal_uInt32 nlLinePos; // akt. Spalten Nummer
+
+ double nValue; // der Wert des Tokens als Zahl
+
+ CSS1ParserState eState; // der akteulle Zustand der Parsers
+ CSS1Token nToken; // das aktuelle Token
+
+ String aIn; // der zu parsende String
+ String aToken; // das Token als String
+
+ // Parsen vorbereiten
+ void InitRead( const String& rIn );
+
+ // das naechste Zeichen holen
+ sal_Unicode GetNextChar();
+
+ // das naechste Token holen
+ CSS1Token GetNextToken();
+
+ // arbeitet der Parser noch?
+ sal_Bool IsParserWorking() const { return CSS1_PAR_WORKING == eState; }
+
+ sal_Bool IsEOF() const { return bEOF; }
+
+ sal_uInt32 IncLineNr() { return ++nlLineNr; }
+ sal_uInt32 IncLinePos() { return ++nlLinePos; }
+ inline sal_uInt32 SetLineNr( sal_uInt32 nlNum ); // inline unten
+ inline sal_uInt32 SetLinePos( sal_uInt32 nlPos ); // inline unten
+
+ // Parsen von Teilen der Grammatik
+ void ParseRule();
+ CSS1Selector *ParseSelector();
+ CSS1Expression *ParseDeclaration( String& rProperty );
+
+protected:
+
+ void ParseStyleSheet();
+
+ // Den Inhalt eines HTML-Style-Elements parsen.
+ // Fuer jeden Selektor und jede Deklaration wird
+ // SelectorParsed() bzw. DeclarationParsed() aufgerufen.
+ sal_Bool ParseStyleSheet( const String& rIn );
+
+ // Den Inhalt einer HTML-Style-Option parsen.
+ // F�r jede Deklaration wird DeclarationParsed() aufgerufen.
+ sal_Bool ParseStyleOption( const String& rIn );
+
+ // Diese Methode wird aufgerufen, wenn ein Selektor geparsed wurde
+ // Wenn 'bFirst' gesetzt ist, beginnt mit dem Selektor eine neue
+ // Deklaration. Wird sal_True zurueckgegeben, wird der Selektor
+ // geloscht, sonst nicht.
+ // Die Implementierung dieser Methode gibt nur sal_True zuruck.
+ virtual sal_Bool SelectorParsed( const CSS1Selector *pSelector,
+ sal_Bool bFirst );
+
+ // Diese Methode wird fuer jede geparsete Property aufgerufen. Wird
+ // sal_True zurueckgegeben wird der Selektor geloscht, sonst nicht.
+ // Die Implementierung dieser Methode gibt nur sal_True zuruck.
+ virtual sal_Bool DeclarationParsed( const String& rProperty,
+ const CSS1Expression *pExpr );
+
+public:
+
+ CSS1Parser();
+ virtual ~CSS1Parser();
+
+ inline sal_uInt32 GetLineNr() const { return nlLineNr; }
+ inline sal_uInt32 GetLinePos() const { return nlLinePos; }
+};
+
+inline sal_uInt32 CSS1Parser::SetLineNr( sal_uInt32 nlNum )
+{
+ sal_uInt32 nlOld = nlLineNr;
+ nlLineNr = nlNum;
+ return nlOld;
+}
+
+inline sal_uInt32 CSS1Parser::SetLinePos( sal_uInt32 nlPos )
+{
+ sal_uInt32 nlOld = nlLinePos;
+ nlLinePos = nlPos;
+ return nlOld;
+}
+
+
+#endif
+
+
diff --git a/sw/source/filter/html/svxcss1.cxx b/sw/source/filter/html/svxcss1.cxx
new file mode 100644
index 000000000000..f1dd5631eca4
--- /dev/null
+++ b/sw/source/filter/html/svxcss1.cxx
@@ -0,0 +1,3311 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <stdlib.h>
+
+#ifndef _SVX_SVXIDS_HRC
+#include <svx/svxids.hrc>
+#endif
+#include <i18npool/mslangid.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svl/urihelper.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svl/itempool.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/orphitem.hxx>
+#include <svtools/svparser.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+#include "css1kywd.hxx"
+#include "svxcss1.hxx"
+
+// die Funktionen zum Parsen einer CSS1-Property sind von folgendem Typ:
+typedef void (*FnParseCSS1Prop)( const CSS1Expression *pExpr,
+ SfxItemSet& rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser );
+
+SV_IMPL_PTRARR( CSS1Selectors, CSS1Selector* )
+
+
+/* */
+
+static CSS1PropertyEnum __READONLY_DATA aFontSizeTable[] =
+{
+ { sCSS1_PV_xx_small, 0 },
+ { sCSS1_PV_x_small, 1 },
+ { sCSS1_PV_small, 2 },
+ { sCSS1_PV_medium, 3 },
+ { sCSS1_PV_large, 4 },
+ { sCSS1_PV_x_large, 5 },
+ { sCSS1_PV_xx_large, 6 },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aFontFamilyTable[] =
+{
+ { sCSS1_PV_serif, FAMILY_ROMAN },
+ { sCSS1_PV_sans_serif, FAMILY_SWISS },
+ { sCSS1_PV_cursive, FAMILY_SCRIPT },
+ { sCSS1_PV_fantasy, FAMILY_DECORATIVE },
+ { sCSS1_PV_monospace, FAMILY_MODERN },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aFontWeightTable[] =
+{
+ { sCSS1_PV_extra_light, WEIGHT_NORMAL }, // WEIGHT_ULTRALIGHT (OBS)
+ { sCSS1_PV_light, WEIGHT_NORMAL }, // WEIGHT_LIGHT (OBSOLETE)
+ { sCSS1_PV_demi_light, WEIGHT_NORMAL }, // WEIGHT_SEMILIGHT (OBS)
+ { sCSS1_PV_medium, WEIGHT_NORMAL }, // WEIGHT_MEDIUM (OBS)
+ { sCSS1_PV_normal, WEIGHT_NORMAL }, // WEIGHT_MEDIUM
+ { sCSS1_PV_demi_bold, WEIGHT_NORMAL }, // WEIGHT_SEMIBOLD (OBS)
+ { sCSS1_PV_bold, WEIGHT_BOLD }, // WEIGHT_BOLD (OBSOLETE)
+ { sCSS1_PV_extra_bold, WEIGHT_BOLD }, // WEIGHT_ULTRABOLD (OBS)
+ { sCSS1_PV_bolder, WEIGHT_BOLD },
+ { sCSS1_PV_lighter, WEIGHT_NORMAL },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aFontStyleTable[] =
+{
+ { sCSS1_PV_normal, ITALIC_NONE },
+ { sCSS1_PV_italic, ITALIC_NORMAL },
+ { sCSS1_PV_oblique, ITALIC_NORMAL },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aFontVariantTable[] =
+{
+ { sCSS1_PV_normal, SVX_CASEMAP_NOT_MAPPED },
+ { sCSS1_PV_small_caps, SVX_CASEMAP_KAPITAELCHEN },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aDirectionTable[] =
+{
+ { sCSS1_PV_ltr, FRMDIR_HORI_LEFT_TOP },
+ { sCSS1_PV_rtl, FRMDIR_HORI_RIGHT_TOP },
+ { sCSS1_PV_inherit, FRMDIR_ENVIRONMENT },
+ { 0, 0 }
+};
+
+/* */
+
+static CSS1PropertyEnum __READONLY_DATA aBGRepeatTable[] =
+{
+ { sCSS1_PV_repeat, GPOS_TILED },
+ { sCSS1_PV_repeat_x, GPOS_TILED },
+ { sCSS1_PV_repeat_y, GPOS_TILED },
+ { sCSS1_PV_no_repeat, GPOS_NONE },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aBGHoriPosTable[] =
+{
+ { sCSS1_PV_left, GPOS_LT },
+ { sCSS1_PV_center, GPOS_MT },
+ { sCSS1_PV_right, GPOS_RT },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aBGVertPosTable[] =
+{
+ { sCSS1_PV_top, GPOS_LT },
+ { sCSS1_PV_middle, GPOS_LM },
+ { sCSS1_PV_bottom, GPOS_LB },
+ { 0, 0 }
+};
+
+/* */
+
+static CSS1PropertyEnum __READONLY_DATA aTextAlignTable[] =
+{
+ { sCSS1_PV_left, SVX_ADJUST_LEFT },
+ { sCSS1_PV_center, SVX_ADJUST_CENTER },
+ { sCSS1_PV_right, SVX_ADJUST_RIGHT },
+ { sCSS1_PV_justify, SVX_ADJUST_BLOCK },
+ { 0, 0 }
+};
+
+/* */
+
+static CSS1PropertyEnum __READONLY_DATA aBorderWidthTable[] =
+{
+ { sCSS1_PV_thin, 0 }, // DEF_LINE_WIDTH_0 / DEF_DOUBLE_LINE0
+ { sCSS1_PV_medium, 1 }, // DEF_LINE_WIDTH_1 / DEF_DOUBLE_LINE1
+ { sCSS1_PV_thick, 2 }, // DEF_LINE_WIDTH_2 / DEF_DOUBLE_LINE2
+ { 0, 0 }
+};
+
+enum CSS1BorderStyle { CSS1_BS_NONE, CSS1_BS_SINGLE, CSS1_BS_DOUBLE };
+
+static CSS1PropertyEnum __READONLY_DATA aBorderStyleTable[] =
+{
+ { sCSS1_PV_none, CSS1_BS_NONE },
+ { sCSS1_PV_dotted, CSS1_BS_SINGLE },
+ { sCSS1_PV_dashed, CSS1_BS_SINGLE },
+ { sCSS1_PV_solid, CSS1_BS_SINGLE },
+ { sCSS1_PV_double, CSS1_BS_DOUBLE },
+ { sCSS1_PV_groove, CSS1_BS_SINGLE },
+ { sCSS1_PV_ridge, CSS1_BS_SINGLE },
+ { sCSS1_PV_inset, CSS1_BS_SINGLE },
+ { sCSS1_PV_outset, CSS1_BS_SINGLE },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aFloatTable[] =
+{
+ { sCSS1_PV_left, SVX_ADJUST_LEFT },
+ { sCSS1_PV_right, SVX_ADJUST_RIGHT },
+ { sCSS1_PV_none, SVX_ADJUST_END },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aPositionTable[] =
+{
+ { sCSS1_PV_absolute, SVX_CSS1_POS_ABSOLUTE },
+ { sCSS1_PV_relative, SVX_CSS1_POS_RELATIVE },
+ { sCSS1_PV_static, SVX_CSS1_POS_STATIC },
+ { 0, 0 }
+};
+
+// Feature: PrintExt
+static CSS1PropertyEnum __READONLY_DATA aSizeTable[] =
+{
+ { sCSS1_PV_auto, SVX_CSS1_STYPE_AUTO },
+ { sCSS1_PV_landscape, SVX_CSS1_STYPE_LANDSCAPE },
+ { sCSS1_PV_portrait, SVX_CSS1_STYPE_PORTRAIT },
+ { 0, 0 }
+};
+
+static CSS1PropertyEnum __READONLY_DATA aPageBreakTable[] =
+{
+ { sCSS1_PV_auto, SVX_CSS1_PBREAK_AUTO },
+ { sCSS1_PV_always, SVX_CSS1_PBREAK_ALWAYS },
+ { sCSS1_PV_avoid, SVX_CSS1_PBREAK_AVOID },
+ { sCSS1_PV_left, SVX_CSS1_PBREAK_LEFT },
+ { sCSS1_PV_right, SVX_CSS1_PBREAK_RIGHT },
+ { 0, 0 }
+};
+
+// /Feature: PrintExt
+
+/* */
+
+// Ein Eintrag besteht aus vier USHORTs. Der erste ist die Gesamtbreite,
+// die anderen sind die 3 Einzelbreiten
+
+#define SBORDER_ENTRY( n ) \
+ DEF_LINE_WIDTH_##n, DEF_LINE_WIDTH_##n, 0, 0
+
+#define DBORDER_ENTRY( n ) \
+ DEF_DOUBLE_LINE##n##_OUT + DEF_DOUBLE_LINE##n##_IN + \
+ DEF_DOUBLE_LINE##n##_DIST, \
+ DEF_DOUBLE_LINE##n##_OUT, \
+ DEF_DOUBLE_LINE##n##_IN, \
+ DEF_DOUBLE_LINE##n##_DIST
+
+#define TDBORDER_ENTRY( n ) \
+ DEF_DOUBLE_LINE##n##_OUT, \
+ DEF_DOUBLE_LINE##n##_OUT, \
+ DEF_DOUBLE_LINE##n##_IN, \
+ DEF_DOUBLE_LINE##n##_DIST
+
+
+static USHORT __READONLY_DATA aSBorderWidths[] =
+{
+ SBORDER_ENTRY( 0 ), SBORDER_ENTRY( 1 ), SBORDER_ENTRY( 2 ),
+ SBORDER_ENTRY( 3 ), SBORDER_ENTRY( 4 )
+};
+
+static USHORT __READONLY_DATA aDBorderWidths[] =
+{
+ DBORDER_ENTRY( 0 ),
+ DBORDER_ENTRY( 7 ),
+ DBORDER_ENTRY( 1 ),
+ DBORDER_ENTRY( 8 ),
+ DBORDER_ENTRY( 4 ),
+ DBORDER_ENTRY( 9 ),
+ DBORDER_ENTRY( 3 ),
+ DBORDER_ENTRY( 10 ),
+ DBORDER_ENTRY( 2 ),
+ DBORDER_ENTRY( 5 )
+};
+
+static USHORT __READONLY_DATA aTDBorderWidths[] =
+{
+ TDBORDER_ENTRY( 7 ), TDBORDER_ENTRY( 8 ), TDBORDER_ENTRY( 9 ),
+ TDBORDER_ENTRY( 10 )
+};
+
+#undef SBORDER_ENTRY
+#undef DBORDER_ENTRY
+
+/* */
+
+struct SvxCSS1ItemIds
+{
+ USHORT nFont;
+ USHORT nFontCJK;
+ USHORT nFontCTL;
+ USHORT nPosture;
+ USHORT nPostureCJK;
+ USHORT nPostureCTL;
+ USHORT nWeight;
+ USHORT nWeightCJK;
+ USHORT nWeightCTL;
+ USHORT nFontHeight;
+ USHORT nFontHeightCJK;
+ USHORT nFontHeightCTL;
+ USHORT nUnderline;
+ USHORT nOverline;
+ USHORT nCrossedOut;
+ USHORT nColor;
+ USHORT nKerning;
+ USHORT nCaseMap;
+ USHORT nBlink;
+
+ USHORT nLineSpacing;
+ USHORT nAdjust;
+ USHORT nWidows;
+ USHORT nOrphans;
+ USHORT nFmtSplit;
+
+ USHORT nLRSpace;
+ USHORT nULSpace;
+ USHORT nBox;
+ USHORT nBrush;
+
+ USHORT nLanguage;
+ USHORT nLanguageCJK;
+ USHORT nLanguageCTL;
+ USHORT nDirection;
+};
+
+
+static SvxCSS1ItemIds aItemIds;
+
+
+/* */
+
+struct SvxCSS1BorderInfo
+{
+ Color aColor;
+ USHORT nAbsWidth;
+ USHORT nNamedWidth;
+ CSS1BorderStyle eStyle;
+
+ SvxCSS1BorderInfo() :
+ aColor( COL_BLACK ), nAbsWidth( USHRT_MAX ),
+ nNamedWidth( USHRT_MAX ), eStyle( CSS1_BS_NONE )
+ {}
+
+ SvxCSS1BorderInfo( const SvxCSS1BorderInfo& rInfo ) :
+ aColor( rInfo.aColor ), nAbsWidth( rInfo.nAbsWidth ),
+ nNamedWidth( rInfo.nNamedWidth ), eStyle( rInfo.eStyle )
+ {}
+
+ void SetBorderLine( USHORT nLine, SvxBoxItem &rBoxItem ) const;
+};
+
+void SvxCSS1BorderInfo::SetBorderLine( USHORT nLine, SvxBoxItem &rBoxItem ) const
+{
+ if( CSS1_BS_NONE==eStyle || nAbsWidth==0 ||
+ (nAbsWidth==USHRT_MAX && nNamedWidth==USHRT_MAX) )
+ {
+ rBoxItem.SetLine( 0, nLine );
+ return;
+ }
+
+ SvxBorderLine aBorderLine( &aColor );
+
+ // Linien-Stil doppelt oder einfach?
+ BOOL bDouble = eStyle == CSS1_BS_DOUBLE;
+
+ // benannte Breite umrechnenen, wenn keine absolute gegeben ist
+ if( nAbsWidth==USHRT_MAX )
+ {
+ const USHORT *aWidths = bDouble ? aDBorderWidths : aSBorderWidths;
+ USHORT nNWidth = nNamedWidth * 4;
+ aBorderLine.SetOutWidth( aWidths[nNWidth+1] );
+ aBorderLine.SetInWidth( aWidths[nNWidth+2] );
+ aBorderLine.SetDistance( aWidths[nNWidth+3] );
+ }
+ else
+ {
+ SvxCSS1Parser::SetBorderWidth( aBorderLine, nAbsWidth, bDouble );
+ }
+
+ rBoxItem.SetLine( &aBorderLine, nLine );
+}
+
+
+/* */
+
+SvxCSS1PropertyInfo::SvxCSS1PropertyInfo()
+{
+ for( USHORT i=0; i<4; i++ )
+ aBorderInfos[i] = 0;
+
+ Clear();
+}
+
+SvxCSS1PropertyInfo::SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo& rProp ) :
+ aId( rProp.aId ),
+ bTopMargin( rProp.bTopMargin ),
+ bBottomMargin( rProp.bBottomMargin ),
+ bLeftMargin( rProp.bLeftMargin ),
+ bRightMargin( rProp.bRightMargin ),
+ bTextIndent( rProp.bTextIndent ),
+ eFloat( rProp.eFloat ),
+ ePosition( rProp.ePosition ),
+ nTopBorderDistance( rProp.nTopBorderDistance ),
+ nBottomBorderDistance( rProp.nBottomBorderDistance ),
+ nLeftBorderDistance( rProp.nLeftBorderDistance ),
+ nRightBorderDistance( rProp.nRightBorderDistance ),
+ nLeft( rProp.nLeft ),
+ nTop( rProp.nTop ),
+ nWidth( rProp.nWidth ),
+ nHeight( rProp.nHeight ),
+ nLeftMargin( rProp.nLeftMargin ),
+ nRightMargin( rProp.nRightMargin ),
+ eLeftType( rProp.eLeftType ),
+ eTopType( rProp.eTopType ),
+ eWidthType( rProp.eWidthType ),
+ eHeightType( rProp.eHeightType ),
+// Feature: PrintExt
+ eSizeType( rProp.eSizeType ),
+ ePageBreakBefore( rProp.ePageBreakBefore ),
+ ePageBreakAfter( rProp.ePageBreakAfter )
+// /Feature: PrintExt
+{
+ for( USHORT i=0; i<4; i++ )
+ aBorderInfos[i] = rProp.aBorderInfos[i]
+ ? new SvxCSS1BorderInfo( *rProp.aBorderInfos[i] )
+ : 0;
+}
+
+SvxCSS1PropertyInfo::~SvxCSS1PropertyInfo()
+{
+ DestroyBorderInfos();
+}
+
+void SvxCSS1PropertyInfo::DestroyBorderInfos()
+{
+ for( USHORT i=0; i<4; i++ )
+ {
+ delete aBorderInfos[i];
+ aBorderInfos[i] = 0;
+ }
+}
+
+void SvxCSS1PropertyInfo::Clear()
+{
+ aId.Erase();
+ bTopMargin = bBottomMargin = FALSE;
+ bLeftMargin = bRightMargin = bTextIndent = FALSE;
+ nLeftMargin = nRightMargin = 0;
+ eFloat = SVX_ADJUST_END;
+
+ ePosition = SVX_CSS1_POS_NONE;
+ nTopBorderDistance = nBottomBorderDistance =
+ nLeftBorderDistance = nRightBorderDistance = USHRT_MAX;
+ nLeft = nTop = nWidth = nHeight = 0;
+ eLeftType = eTopType = eWidthType = eHeightType = SVX_CSS1_LTYPE_NONE;
+
+// Feature: PrintExt
+ eSizeType = SVX_CSS1_STYPE_NONE;
+ ePageBreakBefore = SVX_CSS1_PBREAK_NONE;
+ ePageBreakAfter = SVX_CSS1_PBREAK_NONE;
+
+ DestroyBorderInfos();
+}
+
+void SvxCSS1PropertyInfo::Merge( const SvxCSS1PropertyInfo& rProp )
+{
+ if( rProp.bTopMargin )
+ bTopMargin = TRUE;
+ if( rProp.bBottomMargin )
+ bBottomMargin = TRUE;
+
+ if( rProp.bLeftMargin )
+ {
+ bLeftMargin = TRUE;
+ nLeftMargin = rProp.nLeftMargin;
+ }
+ if( rProp.bRightMargin )
+ {
+ bRightMargin = TRUE;
+ nRightMargin = rProp.nRightMargin;
+ }
+ if( rProp.bTextIndent )
+ bTextIndent = TRUE;
+
+ for( USHORT i=0; i<4; i++ )
+ {
+ if( rProp.aBorderInfos[i] )
+ {
+ if( aBorderInfos[i] )
+ delete aBorderInfos[i];
+
+ aBorderInfos[i] = new SvxCSS1BorderInfo( *rProp.aBorderInfos[i] );
+ }
+ }
+
+ if( USHRT_MAX != rProp.nTopBorderDistance )
+ nTopBorderDistance = rProp.nTopBorderDistance;
+ if( USHRT_MAX != rProp.nBottomBorderDistance )
+ nBottomBorderDistance = rProp.nBottomBorderDistance;
+ if( USHRT_MAX != rProp.nLeftBorderDistance )
+ nLeftBorderDistance = rProp.nLeftBorderDistance;
+ if( USHRT_MAX != rProp.nRightBorderDistance )
+ nRightBorderDistance = rProp.nRightBorderDistance;
+
+ if( rProp.eFloat != SVX_ADJUST_END )
+ eFloat = rProp.eFloat;
+
+ if( rProp.ePosition != SVX_CSS1_POS_NONE )
+ ePosition = rProp.ePosition;
+
+// Feature: PrintExt
+ if( rProp.eSizeType != SVX_CSS1_STYPE_NONE )
+ {
+ eSizeType = rProp.eSizeType;
+ nWidth = rProp.nWidth;
+ nHeight = rProp.nHeight;
+ }
+
+ if( rProp.ePageBreakBefore != SVX_CSS1_PBREAK_NONE )
+ ePageBreakBefore = rProp.ePageBreakBefore;
+
+ if( rProp.ePageBreakAfter != SVX_CSS1_PBREAK_NONE )
+ ePageBreakAfter = rProp.ePageBreakAfter;
+
+// /Feature: PrintExt
+
+ if( rProp.eLeftType != SVX_CSS1_LTYPE_NONE )
+ {
+ eLeftType = rProp.eLeftType;
+ nLeft = rProp.nLeft;
+ }
+
+ if( rProp.eTopType != SVX_CSS1_LTYPE_NONE )
+ {
+ eTopType = rProp.eTopType;
+ nTop = rProp.nTop;
+ }
+
+ if( rProp.eWidthType != SVX_CSS1_LTYPE_NONE )
+ {
+ eWidthType = rProp.eWidthType;
+ nWidth = rProp.nWidth;
+ }
+
+ if( rProp.eHeightType != SVX_CSS1_LTYPE_NONE )
+ {
+ eHeightType = rProp.eHeightType;
+ nHeight = rProp.nHeight;
+ }
+}
+
+SvxCSS1BorderInfo *SvxCSS1PropertyInfo::GetBorderInfo( USHORT nLine, BOOL bCreate )
+{
+ USHORT nPos = 0;
+ switch( nLine )
+ {
+ case BOX_LINE_TOP: nPos = 0; break;
+ case BOX_LINE_BOTTOM: nPos = 1; break;
+ case BOX_LINE_LEFT: nPos = 2; break;
+ case BOX_LINE_RIGHT: nPos = 3; break;
+ }
+
+ if( !aBorderInfos[nPos] && bCreate )
+ aBorderInfos[nPos] = new SvxCSS1BorderInfo;
+
+ return aBorderInfos[nPos];
+}
+
+void SvxCSS1PropertyInfo::CopyBorderInfo( USHORT nSrcLine, USHORT nDstLine,
+ USHORT nWhat )
+{
+ SvxCSS1BorderInfo *pSrcInfo = GetBorderInfo( nSrcLine, FALSE );
+ if( !pSrcInfo )
+ return;
+
+ SvxCSS1BorderInfo *pDstInfo = GetBorderInfo( nDstLine );
+ if( (nWhat & SVX_CSS1_BORDERINFO_WIDTH) != 0 )
+ {
+ pDstInfo->nAbsWidth = pSrcInfo->nAbsWidth;
+ pDstInfo->nNamedWidth = pSrcInfo->nNamedWidth;
+ }
+
+ if( (nWhat & SVX_CSS1_BORDERINFO_COLOR) != 0 )
+ pDstInfo->aColor = pSrcInfo->aColor;
+
+ if( (nWhat & SVX_CSS1_BORDERINFO_STYLE) != 0 )
+ pDstInfo->eStyle = pSrcInfo->eStyle;
+}
+
+void SvxCSS1PropertyInfo::CopyBorderInfo( USHORT nCount, USHORT nWhat )
+{
+ if( nCount==0 )
+ {
+ CopyBorderInfo( BOX_LINE_BOTTOM, BOX_LINE_TOP, nWhat );
+ CopyBorderInfo( BOX_LINE_TOP, BOX_LINE_LEFT, nWhat );
+ }
+ if( nCount<=1 )
+ {
+ CopyBorderInfo( BOX_LINE_LEFT, BOX_LINE_RIGHT, nWhat );
+ }
+}
+
+void SvxCSS1PropertyInfo::SetBoxItem( SfxItemSet& rItemSet,
+ USHORT nMinBorderDist,
+ const SvxBoxItem *pDfltItem,
+ BOOL bTable )
+{
+ BOOL bChg = nTopBorderDistance != USHRT_MAX ||
+ nBottomBorderDistance != USHRT_MAX ||
+ nLeftBorderDistance != USHRT_MAX ||
+ nRightBorderDistance != USHRT_MAX;
+ USHORT i;
+
+ for( i = 0; !bChg && i < 4; i++ )
+ bChg = aBorderInfos[i]!=0;
+
+ if( !bChg )
+ return;
+
+ SvxBoxItem aBoxItem( aItemIds.nBox );
+ if( pDfltItem )
+ aBoxItem = *pDfltItem;
+
+ SvxCSS1BorderInfo *pInfo = GetBorderInfo( BOX_LINE_TOP, FALSE );
+ if( pInfo )
+ pInfo->SetBorderLine( BOX_LINE_TOP, aBoxItem );
+
+ pInfo = GetBorderInfo( BOX_LINE_BOTTOM, FALSE );
+ if( pInfo )
+ pInfo->SetBorderLine( BOX_LINE_BOTTOM, aBoxItem );
+
+ pInfo = GetBorderInfo( BOX_LINE_LEFT, FALSE );
+ if( pInfo )
+ pInfo->SetBorderLine( BOX_LINE_LEFT, aBoxItem );
+
+ pInfo = GetBorderInfo( BOX_LINE_RIGHT, FALSE );
+ if( pInfo )
+ pInfo->SetBorderLine( BOX_LINE_RIGHT, aBoxItem );
+
+ for( i=0; i<4; i++ )
+ {
+ USHORT nLine = BOX_LINE_TOP, nDist = 0;
+ switch( i )
+ {
+ case 0: nLine = BOX_LINE_TOP;
+ nDist = nTopBorderDistance;
+ nTopBorderDistance = USHRT_MAX;
+ break;
+ case 1: nLine = BOX_LINE_BOTTOM;
+ nDist = nBottomBorderDistance;
+ nBottomBorderDistance = USHRT_MAX;
+ break;
+ case 2: nLine = BOX_LINE_LEFT;
+ nDist = nLeftBorderDistance;
+ nLeftBorderDistance = USHRT_MAX;
+ break;
+ case 3: nLine = BOX_LINE_RIGHT;
+ nDist = nRightBorderDistance;
+ nRightBorderDistance = USHRT_MAX;
+ break;
+ }
+
+ if( aBoxItem.GetLine( nLine ) )
+ {
+ if( USHRT_MAX == nDist )
+ nDist = aBoxItem.GetDistance( nLine );
+
+ if( nDist < nMinBorderDist )
+ nDist = nMinBorderDist;
+ }
+ else
+ {
+ if( USHRT_MAX == nDist )
+ nDist = aBoxItem.GetDistance( nLine );
+
+ if( !bTable )
+ nDist = 0U;
+ else if( nDist && nDist < nMinBorderDist )
+ nDist = nMinBorderDist;
+ }
+
+ aBoxItem.SetDistance( nDist, nLine );
+ }
+
+ rItemSet.Put( aBoxItem );
+
+ DestroyBorderInfos();
+}
+
+
+/* */
+
+SvxCSS1MapEntry::SvxCSS1MapEntry( const String& rKey, const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp ) :
+ aKey( rKey ),
+ aItemSet( rItemSet ),
+ aPropInfo( rProp )
+{
+ // TODO: ToUpperAscii
+ aKey.ToUpperAscii();
+}
+
+#if defined( ICC ) || defined( BLC )
+BOOL operator==( const SvxCSS1MapEntry& rE1, const SvxCSS1MapEntry& rE2 )
+{
+ return rE1.aKey==rE2.aKey;
+}
+
+BOOL operator<( const SvxCSS1MapEntry& rE1, const SvxCSS1MapEntry& rE2 )
+{
+ return rE1.aKey<rE2.aKey;
+}
+#endif
+
+SV_IMPL_OP_PTRARR_SORT( SvxCSS1Map, SvxCSS1MapEntryPtr )
+
+/* */
+
+BOOL SvxCSS1Parser::StyleParsed( const CSS1Selector * /*pSelector*/,
+ SfxItemSet& /*rItemSet*/,
+ SvxCSS1PropertyInfo& /*rPropInfo*/ )
+{
+ // wie man sieht passiert hier gar nichts
+ return TRUE;
+}
+
+BOOL SvxCSS1Parser::SelectorParsed( const CSS1Selector *pSelector,
+ BOOL bFirst )
+{
+ if( bFirst )
+ {
+ DBG_ASSERT( pSheetItemSet, "Wo ist der Item-Set fuer Style-Sheets?" );
+
+ // Dieses ist der erste Selektor einer Rule, also muessen
+ // die bisher geparsten Items auf die Styles verteilt werden
+// pSheetPropInfo->CreateBoxItem( *pSheetItemSet, GetDfltBorderDist() );
+ for( USHORT i=0; i<aSelectors.Count(); i++ )
+ {
+ StyleParsed( aSelectors[i], *pSheetItemSet, *pSheetPropInfo );
+ }
+ pSheetItemSet->ClearItem();
+ pSheetPropInfo->Clear();
+
+ // und die naechste Rule vorbereiten
+ if( aSelectors.Count() )
+ aSelectors.DeleteAndDestroy( 0, aSelectors.Count() );
+ }
+
+ aSelectors.C40_INSERT( CSS1Selector, pSelector, aSelectors.Count() );
+
+ return FALSE; // den Selektor haben wir gespeichert. Loeschen toedlich!
+}
+
+
+BOOL SvxCSS1Parser::DeclarationParsed( const String& rProperty,
+ const CSS1Expression *pExpr )
+{
+ DBG_ASSERT( pExpr, "DeclarationParsed() ohne Expression" );
+
+ if( !pExpr )
+ return TRUE;
+
+ ParseProperty( rProperty, pExpr );
+
+ return TRUE; // die Deklaration brauchen wir nicht mehr. Loeschen!
+}
+
+/* */
+
+SvxCSS1Parser::SvxCSS1Parser( SfxItemPool& rPool, const String& rBaseURL, USHORT nMinFixLineSp,
+ USHORT *pWhichIds, USHORT nWhichIds ) :
+ CSS1Parser(),
+ sBaseURL( rBaseURL ),
+ pSheetItemSet(0),
+ pItemSet(0),
+ pSearchEntry( 0 ),
+ nMinFixLineSpace( nMinFixLineSp ),
+ eDfltEnc( RTL_TEXTENCODING_DONTKNOW ),
+ nScriptFlags( CSS1_SCRIPT_ALL ),
+ bIgnoreFontFamily( FALSE )
+{
+ // Item-Ids auch initialisieren
+ aItemIds.nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, FALSE );
+ aItemIds.nFontCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, FALSE );
+ aItemIds.nFontCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, FALSE );
+ aItemIds.nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, FALSE );
+ aItemIds.nPostureCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, FALSE );
+ aItemIds.nPostureCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, FALSE );
+ aItemIds.nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, FALSE );
+ aItemIds.nWeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, FALSE );
+ aItemIds.nWeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, FALSE );
+ aItemIds.nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, FALSE );
+ aItemIds.nFontHeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, FALSE );
+ aItemIds.nFontHeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, FALSE );
+ aItemIds.nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, FALSE );
+ aItemIds.nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, FALSE );
+ aItemIds.nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, FALSE );
+ aItemIds.nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, FALSE );
+ aItemIds.nKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, FALSE );
+ aItemIds.nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, FALSE );
+ aItemIds.nBlink = rPool.GetTrueWhich( SID_ATTR_FLASH, FALSE );
+
+ aItemIds.nLineSpacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, FALSE );
+ aItemIds.nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, FALSE );
+ aItemIds.nWidows = rPool.GetTrueWhich( SID_ATTR_PARA_WIDOWS, FALSE );
+ aItemIds.nOrphans = rPool.GetTrueWhich( SID_ATTR_PARA_ORPHANS, FALSE );
+ aItemIds.nFmtSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, FALSE );
+
+ aItemIds.nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, FALSE );
+ aItemIds.nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, FALSE );
+ aItemIds.nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, FALSE );
+ aItemIds.nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, FALSE );
+
+ aItemIds.nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, FALSE );
+ aItemIds.nLanguageCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, FALSE );
+ aItemIds.nLanguageCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, FALSE );
+ aItemIds.nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, FALSE );
+
+ aWhichMap.Insert( (USHORT)0, (USHORT)0 );
+ SvParser::BuildWhichTbl( aWhichMap, (USHORT *)&aItemIds,
+ sizeof(aItemIds) / sizeof(USHORT) );
+ if( pWhichIds && nWhichIds )
+ SvParser::BuildWhichTbl( aWhichMap, pWhichIds, nWhichIds );
+
+ pSheetItemSet = new SfxItemSet( rPool, aWhichMap.GetData() );
+ pSheetPropInfo = new SvxCSS1PropertyInfo;
+ pSearchEntry = new SvxCSS1MapEntry( rPool, aWhichMap.GetData() );
+}
+
+SvxCSS1Parser::~SvxCSS1Parser()
+{
+ delete pSheetItemSet;
+ delete pSheetPropInfo;
+ delete pSearchEntry;
+}
+
+
+/* */
+
+BOOL SvxCSS1Parser::ParseStyleSheet( const String& rIn )
+{
+ pItemSet = pSheetItemSet;
+ pPropInfo = pSheetPropInfo;
+
+ BOOL bSuccess = CSS1Parser::ParseStyleSheet( rIn );
+
+ // die bisher geparsten Items auf die Styles verteilt werden
+// pSheetPropInfo->CreateBoxItem( *pSheetItemSet, GetDfltBorderDist() );
+ for( USHORT i=0; i<aSelectors.Count(); i++ )
+ {
+ StyleParsed( aSelectors[i], *pSheetItemSet, *pSheetPropInfo );
+ }
+
+ // und etwas aufrauemen
+ if( aSelectors.Count() )
+ aSelectors.DeleteAndDestroy( 0, aSelectors.Count() );
+ pSheetItemSet->ClearItem();
+ pSheetPropInfo->Clear();
+
+ pItemSet = 0;
+ pPropInfo = 0;
+
+ return bSuccess;
+}
+
+BOOL SvxCSS1Parser::ParseStyleOption( const String& rIn,
+ SfxItemSet& rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo )
+{
+ pItemSet = &rItemSet;
+ pPropInfo = &rPropInfo;
+
+ BOOL bSuccess = CSS1Parser::ParseStyleOption( rIn );
+ rItemSet.ClearItem( aItemIds.nDirection );
+// pPropInfo->CreateBoxItem( *pItemSet, GetDfltBorderDist() );
+
+ pItemSet = 0;
+ pPropInfo = 0;
+
+ return bSuccess;
+}
+
+/* */
+
+BOOL SvxCSS1Parser::GetEnum( const CSS1PropertyEnum *pPropTable,
+ const String &rValue, USHORT& rEnum )
+{
+ String aValue( rValue );
+ aValue.ToLowerAscii();
+ while( pPropTable->pName )
+ {
+ if( !rValue.EqualsIgnoreCaseAscii( pPropTable->pName ) )
+ pPropTable++;
+ else
+ break;
+ }
+
+ if( pPropTable->pName )
+ rEnum = pPropTable->nEnum;
+
+ return (pPropTable->pName != 0);
+}
+
+void SvxCSS1Parser::PixelToTwip( long &rWidth, long &rHeight )
+{
+ if( Application::GetDefaultDevice() )
+ {
+ Size aTwipSz( rWidth, rHeight );
+ aTwipSz = Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
+ MapMode(MAP_TWIP) );
+
+ rWidth = aTwipSz.Width();
+ rHeight = aTwipSz.Height();
+ }
+}
+
+void SvxCSS1Parser::SetBorderWidth( SvxBorderLine& aBorderLine, USHORT nWidth,
+ BOOL bDouble, BOOL bTable )
+{
+ const USHORT *aWidths;
+ USHORT nSize;
+ if( !bDouble )
+ {
+ aWidths = aSBorderWidths;
+ nSize = sizeof( aSBorderWidths );
+ }
+ else if( bTable )
+ {
+ aWidths = aTDBorderWidths;
+ nSize = sizeof( aTDBorderWidths );
+ }
+ else
+ {
+ aWidths = aDBorderWidths;
+ nSize = sizeof( aDBorderWidths );
+ }
+
+ USHORT i = (nSize / sizeof(USHORT)) - 4;
+ while( i>0 &&
+ nWidth <= ((aWidths[i] + aWidths[i-4]) / 2) )
+ {
+ DBG_ASSERT( aWidths[i] > aWidths[i-4],
+ "Linienbreiten sind nicht sortiert!" );
+ i -= 4;
+ }
+
+ aBorderLine.SetOutWidth( aWidths[i+1] );
+ aBorderLine.SetInWidth( aWidths[i+2] );
+ aBorderLine.SetDistance( aWidths[i+3] );
+}
+
+sal_uInt32 SvxCSS1Parser::GetFontHeight( USHORT nSize ) const
+{
+ USHORT nHeight;
+
+ switch( nSize )
+ {
+ case 0: nHeight = 8*20; break;
+ case 1: nHeight = 10*20; break;
+ case 2: nHeight = 11*20; break;
+ case 3: nHeight = 12*20; break;
+ case 4: nHeight = 17*20; break;
+ case 5: nHeight = 20*20; break;
+ case 6:
+ default: nHeight = 32*20; break;
+ }
+
+ return nHeight;
+}
+
+const FontList *SvxCSS1Parser::GetFontList() const
+{
+ return 0;
+}
+
+SvxCSS1MapEntry *SvxCSS1Parser::GetMapEntry( const String& rKey,
+ const SvxCSS1Map& rMap ) const
+{
+ pSearchEntry->SetKey( rKey );
+
+ SvxCSS1MapEntry *pRet = 0;
+ USHORT nPos;
+ if( rMap.Seek_Entry( pSearchEntry, &nPos ) )
+ pRet = rMap[nPos];
+
+ return pRet;
+}
+
+void SvxCSS1Parser::InsertMapEntry( const String& rKey,
+ const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp,
+ SvxCSS1Map& rMap )
+{
+ SvxCSS1MapEntry *pEntry = GetMapEntry( rKey, rMap );
+ if( pEntry )
+ {
+ MergeStyles( rItemSet, rProp,
+ pEntry->GetItemSet(), pEntry->GetPropertyInfo(), TRUE );
+ }
+ else
+ {
+ rMap.Insert( new SvxCSS1MapEntry( rKey, rItemSet, rProp ) );
+ }
+}
+
+
+void SvxCSS1Parser::MergeStyles( const SfxItemSet& rSrcSet,
+ const SvxCSS1PropertyInfo& rSrcInfo,
+ SfxItemSet& rTargetSet,
+ SvxCSS1PropertyInfo& rTargetInfo,
+ BOOL bSmart )
+{
+ if( !bSmart )
+ {
+ rTargetSet.Put( rSrcSet );
+ }
+ else
+ {
+ SvxLRSpaceItem aLRSpace( (const SvxLRSpaceItem&)rTargetSet.Get(aItemIds.nLRSpace) );
+ SvxULSpaceItem aULSpace( (const SvxULSpaceItem&)rTargetSet.Get(aItemIds.nULSpace) );
+ SvxBoxItem aBox( (const SvxBoxItem&)rTargetSet.Get(aItemIds.nBox) );
+
+ rTargetSet.Put( rSrcSet );
+
+ if( rSrcInfo.bLeftMargin || rSrcInfo.bRightMargin ||
+ rSrcInfo.bTextIndent )
+ {
+ const SvxLRSpaceItem& rNewLRSpace =
+ (const SvxLRSpaceItem&)rSrcSet.Get( aItemIds.nLRSpace );
+
+ if( rSrcInfo.bLeftMargin )
+ aLRSpace.SetLeft( rNewLRSpace.GetLeft() );
+ if( rSrcInfo.bRightMargin )
+ aLRSpace.SetRight( rNewLRSpace.GetRight() );
+ if( rSrcInfo.bTextIndent )
+ aLRSpace.SetTxtFirstLineOfst( rNewLRSpace.GetTxtFirstLineOfst() );
+
+ rTargetSet.Put( aLRSpace );
+ }
+
+ if( rSrcInfo.bTopMargin || rSrcInfo.bBottomMargin )
+ {
+ const SvxULSpaceItem& rNewULSpace =
+ (const SvxULSpaceItem&)rSrcSet.Get( aItemIds.nULSpace );
+
+ if( rSrcInfo.bTopMargin )
+ aULSpace.SetUpper( rNewULSpace.GetUpper() );
+ if( rSrcInfo.bBottomMargin )
+ aULSpace.SetLower( rNewULSpace.GetLower() );
+
+ rTargetSet.Put( aULSpace );
+ }
+ }
+
+ rTargetInfo.Merge( rSrcInfo );
+}
+
+void SvxCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
+{
+ eDfltEnc = eEnc;
+}
+
+/* */
+
+static void ParseCSS1_font_size( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& rParser )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ ULONG nHeight = 0;
+ USHORT nPropHeight = 100;
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ nHeight = pExpr->GetULength();
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ long nPWidth = 0;
+ long nPHeight = (long)pExpr->GetNumber();
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ nHeight = (ULONG)nPHeight;
+ }
+ break;
+//#ifdef PERCENTAGE_POSSIBLE
+ case CSS1_PERCENTAGE:
+ // nur fuer Drop-Caps!
+ nPropHeight = (USHORT)pExpr->GetNumber();
+ break;
+//#endif
+ case CSS1_IDENT:
+ {
+ USHORT nSize;
+#ifdef PERCENTAGE_POSSIBLE
+ const String& rValue = pExpr->GetString();
+#endif
+ if( SvxCSS1Parser::GetEnum( aFontSizeTable, pExpr->GetString(),
+ nSize ) )
+ {
+ nHeight = rParser.GetFontHeight( nSize );
+ }
+#ifdef PERCENTAGE_POSSIBLE
+ else if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_larger ) )
+ {
+ nPropHeight = 150;
+ }
+ else if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_smaller ) )
+ {
+ nPropHeight = 67;
+ }
+#endif
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ if( nHeight || nPropHeight!=100 )
+ {
+ SvxFontHeightItem aFontHeight( nHeight, nPropHeight,
+ aItemIds.nFontHeight );
+ if( rParser.IsSetWesternProps() )
+ rItemSet.Put( aFontHeight );
+ if( rParser.IsSetCJKProps() )
+ {
+ aFontHeight.SetWhich( aItemIds.nFontHeightCJK );
+ rItemSet.Put( aFontHeight );
+ }
+ if( rParser.IsSetCTLProps() )
+ {
+ aFontHeight.SetWhich( aItemIds.nFontHeightCTL );
+ rItemSet.Put( aFontHeight );
+ }
+ }
+}
+
+/* */
+
+
+static void ParseCSS1_font_family( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& rParser )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ String aName, aStyleName, aDfltName;
+ FontFamily eFamily = FAMILY_DONTKNOW;
+ FontPitch ePitch = PITCH_DONTKNOW;
+ rtl_TextEncoding eEnc = rParser.GetDfltEncoding();
+ const FontList *pFList = rParser.GetFontList();
+ BOOL bFirst = TRUE;
+ BOOL bFound = FALSE;
+ while( pExpr && (bFirst || ','==pExpr->GetOp() || !pExpr->GetOp()) )
+ {
+ CSS1Token eType = pExpr->GetType();
+ if( CSS1_IDENT==eType || CSS1_STRING==eType )
+ {
+ String aIdent( pExpr->GetString() );
+
+ if( CSS1_IDENT==eType )
+ {
+ // Alle nachfolgenden id's sammeln und mit einem
+ // Space getrennt hintendranhaengen
+ const CSS1Expression *pNext = pExpr->GetNext();
+ while( pNext && !pNext->GetOp() &&
+ CSS1_IDENT==pNext->GetType() )
+ {
+ (aIdent += ' ') += pNext->GetString();
+ pExpr = pNext;
+ pNext = pExpr->GetNext();
+ }
+ }
+ if( aIdent.Len() )
+ {
+ if( !bFound && pFList )
+ {
+ sal_Handle hFont = pFList->GetFirstFontInfo( aIdent );
+ if( 0 != hFont )
+ {
+ const FontInfo& rFInfo = pFList->GetFontInfo( hFont );
+ if( RTL_TEXTENCODING_DONTKNOW != rFInfo.GetCharSet() )
+ {
+ bFound = TRUE;
+ if( RTL_TEXTENCODING_SYMBOL == rFInfo.GetCharSet() )
+ eEnc = RTL_TEXTENCODING_SYMBOL;
+ }
+ }
+ }
+ if( !bFirst )
+ aName += ';';
+ aName += aIdent;
+ }
+ }
+
+ pExpr = pExpr->GetNext();
+ bFirst = FALSE;
+ }
+
+ if( aName.Len() && !rParser.IsIgnoreFontFamily() )
+ {
+ SvxFontItem aFont( eFamily, aName, aStyleName, ePitch,
+ eEnc, aItemIds.nFont );
+ if( rParser.IsSetWesternProps() )
+ rItemSet.Put( aFont );
+ if( rParser.IsSetCJKProps() )
+ {
+ aFont.SetWhich( aItemIds.nFontCJK );
+ rItemSet.Put( aFont );
+ }
+ if( rParser.IsSetCTLProps() )
+ {
+ aFont.SetWhich( aItemIds.nFontCTL );
+ rItemSet.Put( aFont );
+ }
+ }
+}
+
+/* */
+
+static void ParseCSS1_font_weight( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& rParser )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_IDENT:
+ case CSS1_STRING: // MS-IE, was sonst
+ {
+ USHORT nWeight;
+ if( SvxCSS1Parser::GetEnum( aFontWeightTable, pExpr->GetString(),
+ nWeight ) )
+ {
+ SvxWeightItem aWeight( (FontWeight)nWeight, aItemIds.nWeight );
+ if( rParser.IsSetWesternProps() )
+ rItemSet.Put( aWeight );
+ if( rParser.IsSetCJKProps() )
+ {
+ aWeight.SetWhich( aItemIds.nWeightCJK );
+ rItemSet.Put( aWeight );
+ }
+ if( rParser.IsSetCTLProps() )
+ {
+ aWeight.SetWhich( aItemIds.nWeightCTL );
+ rItemSet.Put( aWeight );
+ }
+ }
+ }
+ break;
+ case CSS1_NUMBER:
+ {
+ USHORT nWeight = (USHORT)pExpr->GetNumber();
+ SvxWeightItem aWeight( nWeight>400 ? WEIGHT_BOLD : WEIGHT_NORMAL,
+ aItemIds.nWeight );
+ if( rParser.IsSetWesternProps() )
+ rItemSet.Put( aWeight );
+ if( rParser.IsSetCJKProps() )
+ {
+ aWeight.SetWhich( aItemIds.nWeightCJK );
+ rItemSet.Put( aWeight );
+ }
+ if( rParser.IsSetCTLProps() )
+ {
+ aWeight.SetWhich( aItemIds.nWeightCTL );
+ rItemSet.Put( aWeight );
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+}
+
+/* */
+
+static void ParseCSS1_font_style( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& rParser )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ BOOL bPosture = FALSE;
+ BOOL bCaseMap = FALSE;
+ FontItalic eItalic = ITALIC_NONE;
+ SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
+
+ // normal | italic || small-caps | oblique || small-caps | small-caps
+ // (wobei nor noch normal | italic und oblique zulaessig sind
+
+ // der Wert kann zwei Werte enthalten!
+ for( USHORT i=0; pExpr && i<2; i++ )
+ {
+ // Auch hier hinterlaesst MS-IEs Parser seine Spuren
+ if( (CSS1_IDENT==pExpr->GetType() || CSS1_STRING==pExpr->GetType()) &&
+ !pExpr->GetOp() )
+ {
+ const String& rValue = pExpr->GetString();
+ // erstmal pruefen, ob es ein Italic-Wert oder 'normal' ist
+ USHORT nItalic;
+ if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nItalic ) )
+ {
+ eItalic = (FontItalic)nItalic;
+ if( !bCaseMap && ITALIC_NONE==eItalic )
+ {
+ // fuer 'normal' muessen wir auch die case-map aussch.
+ eCaseMap = SVX_CASEMAP_NOT_MAPPED;
+ bCaseMap = TRUE;
+ }
+ bPosture = TRUE;
+ }
+ else if( !bCaseMap &&
+ rValue.EqualsIgnoreCaseAscii(sCSS1_PV_small_caps) )
+ {
+ eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
+ bCaseMap = TRUE;
+ }
+ }
+
+ // den naechsten Ausdruck holen
+ pExpr = pExpr->GetNext();
+ }
+
+ if( bPosture )
+ {
+ SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
+ if( rParser.IsSetWesternProps() )
+ rItemSet.Put( aPosture );
+ if( rParser.IsSetCJKProps() )
+ {
+ aPosture.SetWhich( aItemIds.nPostureCJK );
+ rItemSet.Put( aPosture );
+ }
+ if( rParser.IsSetCTLProps() )
+ {
+ aPosture.SetWhich( aItemIds.nPostureCTL );
+ rItemSet.Put( aPosture );
+ }
+ }
+
+ if( bCaseMap )
+ rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
+}
+
+/* */
+
+static void ParseCSS1_font_variant( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ // normal | small-caps
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_IDENT:
+ {
+ USHORT nCaseMap;
+ if( SvxCSS1Parser::GetEnum( aFontVariantTable, pExpr->GetString(),
+ nCaseMap ) )
+ {
+ rItemSet.Put( SvxCaseMapItem( (SvxCaseMap)nCaseMap,
+ aItemIds.nCaseMap ) );
+ }
+ }
+ default:
+ ;
+ }
+}
+
+/* */
+
+static void ParseCSS1_color( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_IDENT:
+ case CSS1_RGB:
+ case CSS1_HEXCOLOR:
+ case CSS1_STRING: // Wegen MS-IE
+ {
+ Color aColor;
+ if( pExpr->GetColor( aColor ) )
+ rItemSet.Put( SvxColorItem( aColor, aItemIds.nColor ) );
+ }
+ break;
+ default:
+ ;
+ }
+}
+
+static void ParseCSS1_direction( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ sal_uInt16 nDir;
+ switch( pExpr->GetType() )
+ {
+ case CSS1_IDENT:
+ case CSS1_STRING:
+ if( SvxCSS1Parser::GetEnum( aDirectionTable, pExpr->GetString(),
+ nDir ) )
+ {
+ rItemSet.Put( SvxFrameDirectionItem(
+ static_cast < SvxFrameDirection >( nDir ),
+ aItemIds.nDirection ) );
+ }
+ break;
+ default:
+ ;
+ }
+}
+
+/* */
+
+static void MergeHori( SvxGraphicPosition& ePos, SvxGraphicPosition eHori )
+{
+ DBG_ASSERT( GPOS_LT==eHori || GPOS_MT==eHori || GPOS_RT==eHori,
+ "vertikale Position nicht oben" );
+
+ switch( ePos )
+ {
+ case GPOS_LT:
+ case GPOS_MT:
+ case GPOS_RT:
+ ePos = eHori;
+ break;
+
+ case GPOS_LM:
+ case GPOS_MM:
+ case GPOS_RM:
+ ePos = GPOS_LT==eHori ? GPOS_LM : (GPOS_MT==eHori ? GPOS_MM : GPOS_RM);
+ break;
+
+ case GPOS_LB:
+ case GPOS_MB:
+ case GPOS_RB:
+ ePos = GPOS_LT==eHori ? GPOS_LB : (GPOS_MT==eHori ? GPOS_MB : GPOS_RB);
+ break;
+
+ default:
+ ;
+ }
+}
+
+static void MergeVert( SvxGraphicPosition& ePos, SvxGraphicPosition eVert )
+{
+ DBG_ASSERT( GPOS_LT==eVert || GPOS_LM==eVert || GPOS_LB==eVert,
+ "horizontale Position nicht links" );
+
+ switch( ePos )
+ {
+ case GPOS_LT:
+ case GPOS_LM:
+ case GPOS_LB:
+ ePos = eVert;
+ break;
+
+ case GPOS_MT:
+ case GPOS_MM:
+ case GPOS_MB:
+ ePos = GPOS_LT==eVert ? GPOS_MT : (GPOS_LM==eVert ? GPOS_MM : GPOS_MB);
+ break;
+
+ case GPOS_RT:
+ case GPOS_RM:
+ case GPOS_RB:
+ ePos = GPOS_LT==eVert ? GPOS_RT : (GPOS_LM==eVert ? GPOS_RM : GPOS_RB);
+ break;
+
+ default:
+ ;
+ }
+}
+
+static void ParseCSS1_background( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& rParser )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ Color aColor;
+ String aURL;
+
+ BOOL bColor = FALSE, bTransparent = FALSE;
+ SvxGraphicPosition eRepeat = GPOS_TILED;
+ SvxGraphicPosition ePos = GPOS_LT;
+ BOOL bHori = FALSE, bVert = FALSE;
+
+ while( pExpr && !pExpr->GetOp() )
+ {
+ switch( pExpr->GetType() )
+ {
+ case CSS1_URL:
+ pExpr->GetURL( aURL );
+ break;
+
+ case CSS1_RGB:
+ bColor = pExpr->GetColor( aColor );
+ break;
+
+ case CSS1_LENGTH:
+ case CSS1_PIXLENGTH:
+ {
+ // da wir keine absolute Positionierung koennen,
+ // unterscheiden wir nur zwischen 0 und !0. Deshalb
+ // koennen Pixel auch wie alle anderen Einheiten behandelt
+ // werden.
+
+ ULONG nLength = (ULONG)pExpr->GetNumber();
+ if( !bHori )
+ {
+ ePos = nLength ? GPOS_MM : GPOS_LT;
+ bHori = TRUE;
+ }
+ else if( !bVert )
+ {
+ MergeVert( ePos, (nLength ? GPOS_LM : GPOS_LT) );
+ bVert = TRUE;
+ }
+ }
+ break;
+
+ case CSS1_PERCENTAGE:
+ {
+ // die %-Angabe wird auf den enum abgebildet
+
+ USHORT nPerc = (USHORT)pExpr->GetNumber();
+ if( !bHori )
+ {
+ ePos = nPerc < 25 ? GPOS_LT
+ : (nPerc < 75 ? GPOS_MM
+ : GPOS_RB);
+ }
+ else if( !bVert )
+ {
+ SvxGraphicPosition eVert =
+ nPerc < 25 ? GPOS_LT: (nPerc < 75 ? GPOS_LM
+ : GPOS_LB);
+ MergeVert( ePos, eVert );
+ }
+ }
+ break;
+
+ case CSS1_IDENT:
+ case CSS1_HEXCOLOR:
+ case CSS1_STRING: // Wegen MS-IE
+ {
+ USHORT nEnum;
+ const String &rValue = pExpr->GetString();
+ if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_transparent ) )
+ {
+ bTransparent = TRUE;
+ }
+ if( SvxCSS1Parser::GetEnum( aBGRepeatTable, rValue, nEnum ) )
+ {
+ eRepeat = (SvxGraphicPosition)nEnum;
+ }
+ else if( SvxCSS1Parser::GetEnum( aBGHoriPosTable, rValue, nEnum ) )
+ {
+ // <position>, horizontal
+ MergeHori( ePos, (SvxGraphicPosition)nEnum );
+ }
+ else if( SvxCSS1Parser::GetEnum( aBGVertPosTable, rValue, nEnum ) )
+ {
+ // <position>, vertikal
+ MergeVert( ePos, (SvxGraphicPosition)nEnum );
+ }
+ else if( !bColor )
+ {
+ // <color>
+ bColor = pExpr->GetColor( aColor );
+ }
+ // <scroll> kennen wir nicht
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ pExpr = pExpr->GetNext();
+ }
+
+ // transparent schlaegt alles
+ if( bTransparent )
+ {
+ bColor = FALSE;
+ aURL.Erase();
+ }
+
+ // repeat hat prio gegenueber einer Position
+ if( GPOS_NONE == eRepeat )
+ eRepeat = ePos;
+
+ if( bTransparent || bColor || aURL.Len() )
+ {
+ SvxBrushItem aBrushItem( aItemIds.nBrush );
+
+ if( bTransparent )
+ aBrushItem.SetColor( Color(COL_TRANSPARENT));
+ else if( bColor )
+ aBrushItem.SetColor( aColor );
+
+ if( aURL.Len() )
+ {
+ aBrushItem.SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject( rParser.GetBaseURL()), aURL, Link(), false ) );
+ aBrushItem.SetGraphicPos( eRepeat );
+ }
+
+ rItemSet.Put( aBrushItem );
+ }
+}
+
+static void ParseCSS1_background_color( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ Color aColor;
+
+ BOOL bColor = FALSE, bTransparent = FALSE;
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_RGB:
+ bColor = pExpr->GetColor( aColor );
+ break;
+ case CSS1_IDENT:
+ case CSS1_HEXCOLOR:
+ case CSS1_STRING: // Wegen MS-IE
+ if( pExpr->GetString().EqualsIgnoreCaseAscii( sCSS1_PV_transparent ) )
+ {
+ bTransparent = TRUE;
+ }
+ else
+ {
+ // <color>
+ bColor = pExpr->GetColor( aColor );
+ }
+ break;
+ default:
+ ;
+ }
+
+ if( bTransparent || bColor )
+ {
+ SvxBrushItem aBrushItem( aItemIds.nBrush );
+
+ if( bTransparent )
+ aBrushItem.SetColor( Color(COL_TRANSPARENT) );
+ else if( bColor )
+ aBrushItem.SetColor( aColor);
+
+ rItemSet.Put( aBrushItem );
+ }
+}
+
+/* */
+
+static void ParseCSS1_line_height( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& rParser )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ USHORT nHeight = 0;
+ BYTE nPropHeight = 0;
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ nHeight = (USHORT)pExpr->GetULength();
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ long nPWidth = 0;
+ long nPHeight = (long)pExpr->GetNumber();
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ nHeight = (USHORT)nPHeight;
+ }
+ break;
+ case CSS1_PERCENTAGE:
+ {
+ USHORT nPHeight = (USHORT)pExpr->GetNumber();
+ nPropHeight = nPHeight <= 200 ? (BYTE)nPHeight : 200;
+ }
+ break;
+ case CSS1_NUMBER:
+ {
+ USHORT nPHeight = (USHORT)(pExpr->GetNumber() * 100);
+ nPropHeight = nPHeight <= 200 ? (BYTE)nPHeight : 200;
+ }
+ break;
+ default:
+ ;
+ }
+
+ if( nHeight )
+ {
+ if( nHeight < rParser.GetMinFixLineSpace() )
+ nHeight = rParser.GetMinFixLineSpace();
+ SvxLineSpacingItem aLSItem( nHeight, aItemIds.nLineSpacing );
+ aLSItem.SetLineHeight( nHeight );
+ // --> OD 2006-07-26 #138463#
+ // interpret <line-height> attribute as minimum line height
+ aLSItem.GetLineSpaceRule() = SVX_LINE_SPACE_MIN;
+ // <--
+ aLSItem.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
+ rItemSet.Put( aLSItem );
+ }
+ else if( nPropHeight )
+ {
+ SvxLineSpacingItem aLSItem( nPropHeight, aItemIds.nLineSpacing );
+ aLSItem.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
+ if( 100 == nPropHeight )
+ aLSItem.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
+ else
+ aLSItem.SetPropLineSpace( nPropHeight );
+ rItemSet.Put( aLSItem );
+ }
+
+}
+
+/* */
+
+static void ParseCSS1_font( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ FontItalic eItalic = ITALIC_NONE;
+ SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
+ FontWeight eWeight = WEIGHT_NORMAL;
+
+ // [ <font-style> || <font-variant> || <font-weight> ] ?
+ while( pExpr && !pExpr->GetOp() &&
+ (CSS1_IDENT==pExpr->GetType() ||
+ CSS1_STRING==pExpr->GetType() ||
+ CSS1_NUMBER==pExpr->GetType()) )
+ {
+ if( CSS1_IDENT==pExpr->GetType() ||
+ CSS1_STRING==pExpr->GetType() )
+ {
+ const String& rValue = pExpr->GetString();
+
+ USHORT nEnum;
+
+ if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nEnum ) )
+ {
+ eItalic = (FontItalic)nEnum;
+ }
+ else if( SvxCSS1Parser::GetEnum( aFontVariantTable, rValue, nEnum ) )
+ {
+ eCaseMap = (SvxCaseMap)nEnum;
+ }
+ else if( SvxCSS1Parser::GetEnum( aFontWeightTable, rValue, nEnum ) )
+ {
+ eWeight = (FontWeight)nEnum;
+ }
+ }
+ else
+ {
+ eWeight = (USHORT)pExpr->GetNumber() > 400 ? WEIGHT_BOLD
+ : WEIGHT_NORMAL;
+ }
+
+ pExpr = pExpr->GetNext();
+ }
+
+ if( !pExpr || pExpr->GetOp() )
+ return;
+
+ // Da "font" alle Werte zurecksetzt, fuer die nichts angegeben ist,
+ // tun wir das hier.
+ SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
+ if( rParser.IsSetWesternProps() )
+ rItemSet.Put( aPosture );
+ if( rParser.IsSetCJKProps() )
+ {
+ aPosture.SetWhich( aItemIds.nPostureCJK );
+ rItemSet.Put( aPosture );
+ }
+ if( rParser.IsSetCTLProps() )
+ {
+ aPosture.SetWhich( aItemIds.nPostureCTL );
+ rItemSet.Put( aPosture );
+ }
+
+ rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
+
+ SvxWeightItem aWeight( eWeight, aItemIds.nWeight );
+ if( rParser.IsSetWesternProps() )
+ rItemSet.Put( aWeight );
+ if( rParser.IsSetCJKProps() )
+ {
+ aWeight.SetWhich( aItemIds.nWeightCJK );
+ rItemSet.Put( aWeight );
+ }
+ if( rParser.IsSetCTLProps() )
+ {
+ aWeight.SetWhich( aItemIds.nWeightCTL );
+ rItemSet.Put( aWeight );
+ }
+
+
+ // font-size
+ CSS1Expression aExpr( pExpr->GetType(), pExpr->GetString(),
+ pExpr->GetNumber() );
+ ParseCSS1_font_size( &aExpr, rItemSet, rPropInfo, rParser );
+ pExpr = pExpr->GetNext();
+
+ if( !pExpr )
+ return;
+
+ // [ '/' line-height ]?
+ if( '/' == pExpr->GetOp() )
+ {
+ // '/' line-height
+ aExpr.Set( pExpr->GetType(), pExpr->GetString(), pExpr->GetNumber() );
+ ParseCSS1_line_height( &aExpr, rItemSet, rPropInfo, rParser );
+
+ pExpr = pExpr->GetNext();
+ }
+
+ if( !pExpr || pExpr->GetOp() )
+ return;
+
+ // font-family
+ ParseCSS1_font_family( pExpr, rItemSet, rPropInfo, rParser );
+}
+
+/* */
+
+static void ParseCSS1_letter_spacing( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ rItemSet.Put( SvxKerningItem( (short)pExpr->GetSLength(),
+ aItemIds.nKerning ) );
+ break;
+
+ case CSS1_PIXLENGTH:
+ {
+ long nPWidth = (long)pExpr->GetNumber();
+ long nPHeight = 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ rItemSet.Put( SvxKerningItem( (short)nPWidth, aItemIds.nKerning ) );
+ }
+ break;
+
+ case CSS1_NUMBER:
+ if( pExpr->GetNumber() == 0 )
+ {
+ // eigentlich unnoetig, aber wir sind ja tollerant
+ rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
+ }
+ break;
+
+ case CSS1_IDENT:
+ case CSS1_STRING: // Vorschtshalber auch MS-IE
+ if( pExpr->GetString().EqualsIgnoreCaseAscii(sCSS1_PV_normal) )
+ {
+ rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
+ }
+ break;
+ default:
+ ;
+ }
+}
+
+/* */
+
+static void ParseCSS1_text_decoration( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ BOOL bUnderline = FALSE;
+ BOOL bOverline = FALSE;
+ BOOL bCrossedOut = FALSE;
+ BOOL bBlink = FALSE;
+ BOOL bBlinkOn = FALSE;
+ FontUnderline eUnderline = UNDERLINE_NONE;
+ FontUnderline eOverline = UNDERLINE_NONE;
+ FontStrikeout eCrossedOut = STRIKEOUT_NONE;
+
+ // der Wert kann zwei Werte enthalten! Und MS-IE auch Strings
+ while( pExpr && (pExpr->GetType() == CSS1_IDENT ||
+ pExpr->GetType() == CSS1_STRING) && !pExpr->GetOp() )
+ {
+ String aValue = pExpr->GetString();
+ aValue.ToLowerAscii();
+ BOOL bKnown = FALSE;
+
+ switch( aValue.GetChar( 0 ) )
+ {
+ case 'n':
+ if( aValue.EqualsAscii( sCSS1_PV_none ) )
+ {
+ bUnderline = TRUE;
+ eUnderline = UNDERLINE_NONE;
+
+ bOverline = TRUE;
+ eOverline = UNDERLINE_NONE;
+
+ bCrossedOut = TRUE;
+ eCrossedOut = STRIKEOUT_NONE;
+
+ bBlink = TRUE;
+ bBlinkOn = FALSE;
+
+ bKnown = TRUE;
+ }
+ break;
+
+ case 'u':
+ if( aValue.EqualsAscii( sCSS1_PV_underline ) )
+ {
+ bUnderline = TRUE;
+ eUnderline = UNDERLINE_SINGLE;
+
+ bKnown = TRUE;
+ }
+ break;
+
+ case 'o':
+ if( aValue.EqualsAscii( sCSS1_PV_overline ) )
+ {
+ bOverline = TRUE;
+ eOverline = UNDERLINE_SINGLE;
+
+ bKnown = TRUE;
+ }
+ break;
+
+ case 'l':
+ if( aValue.EqualsAscii( sCSS1_PV_line_through ) )
+ {
+ bCrossedOut = TRUE;
+ eCrossedOut = STRIKEOUT_SINGLE;
+
+ bKnown = TRUE;
+ }
+ break;
+
+ case 'b':
+ if( aValue.EqualsAscii( sCSS1_PV_blink ) )
+ {
+ bBlink = TRUE;
+ bBlinkOn = TRUE;
+
+ bKnown = TRUE;
+ }
+ break;
+ }
+
+ if( !bKnown )
+ {
+ bUnderline = TRUE;
+ eUnderline = UNDERLINE_SINGLE;
+ }
+
+ pExpr = pExpr->GetNext();
+ }
+
+ if( bUnderline )
+ rItemSet.Put( SvxUnderlineItem( eUnderline, aItemIds.nUnderline ) );
+
+ if( bOverline )
+ rItemSet.Put( SvxOverlineItem( eOverline, aItemIds.nOverline ) );
+
+ if( bCrossedOut )
+ rItemSet.Put( SvxCrossedOutItem( eCrossedOut, aItemIds.nCrossedOut ) );
+
+ if( bBlink )
+ rItemSet.Put( SvxBlinkItem( bBlinkOn, aItemIds.nBlink ) );
+}
+
+/* */
+
+static void ParseCSS1_text_align( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ if( CSS1_IDENT==pExpr->GetType() ||
+ CSS1_STRING==pExpr->GetType() ) // MS-IE, mal wieder
+ {
+ USHORT nAdjust;
+ if( SvxCSS1Parser::GetEnum( aTextAlignTable, pExpr->GetString(),
+ nAdjust ) )
+ {
+ rItemSet.Put( SvxAdjustItem( (SvxAdjust)nAdjust,
+ aItemIds.nAdjust ) );
+ }
+ }
+}
+
+/* */
+
+static void ParseCSS1_text_indent( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ short nIndent = 0;
+ BOOL bSet = FALSE;
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ nIndent = (short)pExpr->GetSLength();
+ bSet = TRUE;
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ long nPWidth = (long)pExpr->GetNumber();
+ long nPHeight = 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ nIndent = (short)nPWidth;
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PERCENTAGE:
+ // koennen wir nicht
+ break;
+ default:
+ ;
+ }
+
+ if( bSet )
+ {
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, FALSE,
+ &pItem ) )
+ {
+ SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
+ aLRItem.SetTxtFirstLineOfst( nIndent );
+ rItemSet.Put( aLRItem );
+ }
+ else
+ {
+ SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
+ aLRItem.SetTxtFirstLineOfst( nIndent );
+ rItemSet.Put( aLRItem );
+ }
+ rPropInfo.bTextIndent = TRUE;
+ }
+}
+
+/* */
+
+static void ParseCSS1_margin_left( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ long nLeft = 0;
+ BOOL bSet = FALSE;
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ {
+ nLeft = pExpr->GetSLength();
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ nLeft = (long)pExpr->GetNumber();
+ long nPHeight = 0;
+ SvxCSS1Parser::PixelToTwip( nLeft, nPHeight );
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PERCENTAGE:
+ // koennen wir nicht
+ break;
+ default:
+ ;
+ }
+
+ if( bSet )
+ {
+ rPropInfo.nLeftMargin = nLeft;
+ if( nLeft < 0 )
+ nLeft = 0;
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, FALSE,
+ &pItem ) )
+ {
+ SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
+ aLRItem.SetTxtLeft( (USHORT)nLeft );
+ rItemSet.Put( aLRItem );
+ }
+ else
+ {
+ SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
+ aLRItem.SetTxtLeft( (USHORT)nLeft );
+ rItemSet.Put( aLRItem );
+ }
+ rPropInfo.bLeftMargin = TRUE;
+ }
+}
+
+/* */
+
+static void ParseCSS1_margin_right( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ long nRight = 0;
+ BOOL bSet = FALSE;
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ {
+ nRight = pExpr->GetSLength();
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ nRight = (long)pExpr->GetNumber();
+ long nPHeight = 0;
+ SvxCSS1Parser::PixelToTwip( nRight, nPHeight );
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PERCENTAGE:
+ // koennen wir nicht
+ break;
+ default:
+ ;
+ }
+
+ if( bSet )
+ {
+ rPropInfo.nRightMargin = nRight;
+ if( nRight < 0 )
+ nRight = 0;
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, FALSE,
+ &pItem ) )
+ {
+ SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
+ aLRItem.SetRight( (USHORT)nRight );
+ rItemSet.Put( aLRItem );
+ }
+ else
+ {
+ SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
+ aLRItem.SetRight( (USHORT)nRight );
+ rItemSet.Put( aLRItem );
+ }
+ rPropInfo.bRightMargin = TRUE;
+ }
+}
+
+/* */
+
+static void ParseCSS1_margin_top( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ USHORT nUpper = 0;
+ BOOL bSet = FALSE;
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ {
+ long nTmp = pExpr->GetSLength();
+ if( nTmp < 0 )
+ nTmp = 0;
+ nUpper = (USHORT)nTmp;
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ long nPWidth = 0;
+ long nPHeight = (long)pExpr->GetNumber();
+ if( nPHeight < 0 )
+ nPHeight = 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ nUpper = (USHORT)nPHeight;
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PERCENTAGE:
+ // koennen wir nicht
+ break;
+ default:
+ ;
+ }
+
+ if( bSet )
+ {
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, FALSE,
+ &pItem ) )
+ {
+ SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
+ aULItem.SetUpper( nUpper );
+ rItemSet.Put( aULItem );
+ }
+ else
+ {
+ SvxULSpaceItem aULItem( aItemIds.nULSpace );
+ aULItem.SetUpper( nUpper );
+ rItemSet.Put( aULItem );
+ }
+ rPropInfo.bTopMargin = TRUE;
+ }
+}
+
+/* */
+
+static void ParseCSS1_margin_bottom( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ USHORT nLower = 0;
+ BOOL bSet = FALSE;
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ {
+ long nTmp = pExpr->GetSLength();
+ if( nTmp < 0 )
+ nTmp = 0;
+ nLower = (USHORT)nTmp;
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ long nPWidth = 0;
+ long nPHeight = (long)pExpr->GetNumber();
+ if( nPHeight < 0 )
+ nPHeight = 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ nLower = (USHORT)nPHeight;
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PERCENTAGE:
+ // koennen wir nicht
+ break;
+ default:
+ ;
+ }
+
+ if( bSet )
+ {
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, FALSE,
+ &pItem ) )
+ {
+ SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
+ aULItem.SetLower( nLower );
+ rItemSet.Put( aULItem );
+ }
+ else
+ {
+ SvxULSpaceItem aULItem( aItemIds.nULSpace );
+ aULItem.SetLower( nLower );
+ rItemSet.Put( aULItem );
+ }
+ rPropInfo.bBottomMargin = TRUE;
+ }
+}
+
+/* */
+
+static void ParseCSS1_margin( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ long nMargins[4] = { 0, 0, 0, 0 };
+ BOOL bSetMargins[4] = { FALSE, FALSE, FALSE, FALSE };
+
+ for( USHORT i=0; pExpr && i<4 && !pExpr->GetOp(); i++ )
+ {
+ BOOL bSetThis = FALSE;
+ long nMargin = 0;
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ {
+ nMargin = pExpr->GetSLength();
+ bSetThis = TRUE;
+ }
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ long nPWidth = 0;
+ nMargin = (long)pExpr->GetNumber();
+ SvxCSS1Parser::PixelToTwip( nPWidth, nMargin );
+ bSetThis = TRUE;
+ }
+ break;
+ case CSS1_PERCENTAGE:
+ // koennen wir nicht
+ break;
+ default:
+ ;
+ }
+
+ if( bSetThis )
+ {
+ // 0 = top
+ // 1 = right
+ // 2 = bottom
+ // 3 = left
+ switch( i )
+ {
+ case 0:
+ nMargins[0] = nMargins[1] =nMargins[2] = nMargins[3] = nMargin;
+ bSetMargins[0] = bSetMargins[1] =
+ bSetMargins[2] = bSetMargins[3] = TRUE;
+ break;
+ case 1:
+ nMargins[1] = nMargins[3] = nMargin; // right + left
+ bSetMargins[1] = bSetMargins[3] = TRUE;
+ break;
+ case 2:
+ nMargins[2] = nMargin; // bottom
+ bSetMargins[2] = TRUE;
+ break;
+ case 3:
+ nMargins[3] = nMargin; // left
+ bSetMargins[3] = TRUE;
+ break;
+ }
+ }
+ pExpr = pExpr->GetNext();
+ }
+
+ if( bSetMargins[3] || bSetMargins[1] )
+ {
+ if( bSetMargins[3] )
+ {
+ rPropInfo.bLeftMargin = TRUE;
+ rPropInfo.nLeftMargin = nMargins[3];
+ if( nMargins[3] < 0 )
+ nMargins[3] = 0;
+ }
+ if( bSetMargins[1] )
+ {
+ rPropInfo.bRightMargin = TRUE;
+ rPropInfo.nRightMargin = nMargins[1];
+ if( nMargins[1] < 0 )
+ nMargins[1] = 0;
+ }
+
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, FALSE,
+ &pItem ) )
+ {
+ SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
+ if( bSetMargins[3] )
+ aLRItem.SetLeft( (USHORT)nMargins[3] );
+ if( bSetMargins[1] )
+ aLRItem.SetRight( (USHORT)nMargins[1] );
+ rItemSet.Put( aLRItem );
+ }
+ else
+ {
+ SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
+ if( bSetMargins[3] )
+ aLRItem.SetLeft( (USHORT)nMargins[3] );
+ if( bSetMargins[1] )
+ aLRItem.SetRight( (USHORT)nMargins[1] );
+ rItemSet.Put( aLRItem );
+ }
+ }
+
+ if( bSetMargins[0] || bSetMargins[2] )
+ {
+ if( nMargins[0] < 0 )
+ nMargins[0] = 0;
+ if( nMargins[2] < 0 )
+ nMargins[2] = 0;
+
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, FALSE,
+ &pItem ) )
+ {
+ SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
+ if( bSetMargins[0] )
+ aULItem.SetUpper( (USHORT)nMargins[0] );
+ if( bSetMargins[2] )
+ aULItem.SetLower( (USHORT)nMargins[2] );
+ rItemSet.Put( aULItem );
+ }
+ else
+ {
+ SvxULSpaceItem aULItem( aItemIds.nULSpace );
+ if( bSetMargins[0] )
+ aULItem.SetUpper( (USHORT)nMargins[0] );
+ if( bSetMargins[2] )
+ aULItem.SetLower( (USHORT)nMargins[2] );
+ rItemSet.Put( aULItem );
+ }
+
+ rPropInfo.bTopMargin |= bSetMargins[0];
+ rPropInfo.bBottomMargin |= bSetMargins[2];
+ }
+}
+
+/* */
+
+static BOOL ParseCSS1_padding_xxx( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/,
+ USHORT nWhichLine )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ BOOL bSet = FALSE;
+ USHORT nDist = 0;
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_LENGTH:
+ {
+ long nTmp = pExpr->GetSLength();
+ if( nTmp < 0 )
+ nTmp = 0;
+ else if( nTmp > USHRT_MAX-1 )
+ nTmp = USHRT_MAX-1;
+ nDist = (USHORT)nTmp;
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PIXLENGTH:
+ {
+ long nPWidth = (long)pExpr->GetNumber();
+ long nPHeight = 0;
+ if( nPWidth < 0 )
+ nPWidth = 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ if( nPWidth > USHRT_MAX-1 )
+ nPWidth = USHRT_MAX-1;
+ nDist = (USHORT)nPWidth;
+ bSet = TRUE;
+ }
+ break;
+ case CSS1_PERCENTAGE:
+ // koennen wir nicht
+ break;
+ default:
+ ;
+ }
+
+ if( bSet )
+ {
+ switch( nWhichLine )
+ {
+ case BOX_LINE_TOP: rPropInfo.nTopBorderDistance = nDist; break;
+ case BOX_LINE_BOTTOM: rPropInfo.nBottomBorderDistance = nDist;break;
+ case BOX_LINE_LEFT: rPropInfo.nLeftBorderDistance = nDist; break;
+ case BOX_LINE_RIGHT: rPropInfo.nRightBorderDistance = nDist; break;
+ }
+ }
+
+ return bSet;
+}
+
+/* */
+
+static void ParseCSS1_padding_top( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP );
+}
+
+static void ParseCSS1_padding_bottom( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
+ BOX_LINE_BOTTOM );
+}
+
+static void ParseCSS1_padding_left( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT );
+}
+
+static void ParseCSS1_padding_right( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
+ BOX_LINE_RIGHT );
+}
+
+static void ParseCSS1_padding( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ USHORT n=0;
+ while( n<4 && pExpr && !pExpr->GetOp() )
+ {
+ USHORT nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
+ if( ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
+ nLine ) )
+ {
+ if( n==0 )
+ {
+ rPropInfo.nTopBorderDistance = rPropInfo.nBottomBorderDistance;
+ rPropInfo.nLeftBorderDistance = rPropInfo.nTopBorderDistance;
+ }
+ if( n <= 1 )
+ rPropInfo.nRightBorderDistance = rPropInfo.nLeftBorderDistance;
+ }
+
+ pExpr = pExpr->GetNext();
+ n++;
+ }
+}
+
+/* */
+
+static void ParseCSS1_border_xxx( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/,
+ USHORT nWhichLine, BOOL bAll )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ USHORT nWidth = USHRT_MAX; // die Linien-Dicke
+ USHORT nNWidth = 1; // benannte Linien-Dicke (und default)
+ CSS1BorderStyle eStyle = CSS1_BS_NONE; // Linien-Style
+ Color aColor;
+ BOOL bColor = FALSE;
+
+ while( pExpr && !pExpr->GetOp() )
+ {
+ switch( pExpr->GetType() )
+ {
+ case CSS1_RGB:
+ case CSS1_HEXCOLOR:
+ if( pExpr->GetColor( aColor ) )
+ bColor = TRUE;
+ break;
+
+ case CSS1_IDENT:
+ {
+ const String& rValue = pExpr->GetString();
+ USHORT nValue;
+ if( SvxCSS1Parser::GetEnum( aBorderWidthTable, rValue, nValue ) )
+ {
+ nNWidth = nValue;
+ }
+ else if( SvxCSS1Parser::GetEnum( aBorderStyleTable, rValue, nValue ) )
+ {
+ eStyle = (CSS1BorderStyle)nValue;
+ }
+ else if( pExpr->GetColor( aColor ) )
+ {
+ bColor = TRUE;
+ }
+ }
+ break;
+
+ case CSS1_LENGTH:
+ nWidth = (USHORT)pExpr->GetULength();
+ break;
+
+ case CSS1_PIXLENGTH:
+ {
+ BOOL bHori = nWhichLine == BOX_LINE_TOP ||
+ nWhichLine == BOX_LINE_BOTTOM;
+ // Ein Pixel wird zur Haarlinie (ist huebscher)
+ long nWidthL = (long)pExpr->GetNumber();
+ if( nWidthL > 1 )
+ {
+ long nPWidth = bHori ? 0 : nWidthL;
+ long nPHeight = bHori ? nWidthL : 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ nWidth = (USHORT)(bHori ? nPHeight : nPWidth);
+ }
+ else
+ nWidth = 1;
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ pExpr = pExpr->GetNext();
+ }
+
+ for( USHORT i=0; i<4; i++ )
+ {
+ USHORT nLine = 0;
+ switch( i )
+ {
+ case 0: nLine = BOX_LINE_TOP; break;
+ case 1: nLine = BOX_LINE_BOTTOM; break;
+ case 2: nLine = BOX_LINE_LEFT; break;
+ case 3: nLine = BOX_LINE_RIGHT; break;
+ }
+
+ if( bAll || nLine == nWhichLine )
+ {
+ SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nLine );
+ pInfo->eStyle = eStyle;
+ pInfo->nAbsWidth = nWidth;
+ pInfo->nNamedWidth = nNWidth;
+ if( bColor )
+ pInfo->aColor = aColor;
+ }
+ }
+}
+
+static void ParseCSS1_border_xxx_width( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/,
+ USHORT nWhichLine )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ USHORT nWidth = USHRT_MAX; // die Linien-Dicke
+ USHORT nNWidth = 1; // benannte Linien-Dicke (und default)
+
+ switch( pExpr->GetType() )
+ {
+ case CSS1_IDENT:
+ {
+ USHORT nValue;
+ if( SvxCSS1Parser::GetEnum( aBorderWidthTable, pExpr->GetString(), nValue ) )
+ {
+ nNWidth = nValue;
+ }
+ }
+ break;
+
+ case CSS1_LENGTH:
+ nWidth = (USHORT)pExpr->GetULength();
+ break;
+
+ case CSS1_PIXLENGTH:
+ {
+ BOOL bHori = nWhichLine == BOX_LINE_TOP ||
+ nWhichLine == BOX_LINE_BOTTOM;
+ long nWidthL = (long)pExpr->GetNumber();
+ long nPWidth = bHori ? 0 : nWidthL;
+ long nPHeight = bHori ? nWidthL : 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ nWidth = (USHORT)(bHori ? nPHeight : nPWidth);
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nWhichLine );
+ pInfo->nAbsWidth = nWidth;
+ pInfo->nNamedWidth = nNWidth;
+}
+
+/* */
+
+static void ParseCSS1_border_top_width( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP );
+}
+
+static void ParseCSS1_border_right_width( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_RIGHT );
+}
+
+static void ParseCSS1_border_bottom_width( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_BOTTOM );
+}
+
+static void ParseCSS1_border_left_width( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT );
+}
+
+static void ParseCSS1_border_width( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ USHORT n=0;
+ while( n<4 && pExpr && !pExpr->GetOp() )
+ {
+ USHORT nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
+ ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, nLine );
+ rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_WIDTH );
+
+ pExpr = pExpr->GetNext();
+ n++;
+ }
+}
+
+static void ParseCSS1_border_color( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ USHORT n=0;
+ while( n<4 && pExpr && !pExpr->GetOp() )
+ {
+ USHORT nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
+ Color aColor;
+ switch( pExpr->GetType() )
+ {
+ case CSS1_RGB:
+ case CSS1_HEXCOLOR:
+ case CSS1_IDENT:
+ if( pExpr->GetColor( aColor ) )
+ rPropInfo.GetBorderInfo( nLine )->aColor = aColor;
+ break;
+ default:
+ ;
+ }
+ rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_COLOR );
+
+ pExpr = pExpr->GetNext();
+ n++;
+ }
+}
+
+static void ParseCSS1_border_style( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ USHORT n=0;
+ while( n<4 && pExpr && !pExpr->GetOp() )
+ {
+ USHORT nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
+ USHORT nValue;
+ if( CSS1_IDENT==pExpr->GetType() &&
+ SvxCSS1Parser::GetEnum( aBorderStyleTable, pExpr->GetString(),
+ nValue ) )
+ {
+ rPropInfo.GetBorderInfo( nLine )->eStyle = (CSS1BorderStyle)nValue;
+ }
+ rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_STYLE );
+
+ pExpr = pExpr->GetNext();
+ n++;
+ }
+}
+
+
+static void ParseCSS1_border_top( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP, FALSE );
+}
+
+static void ParseCSS1_border_right( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_RIGHT, FALSE );
+}
+
+static void ParseCSS1_border_bottom( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_BOTTOM, FALSE );
+}
+
+static void ParseCSS1_border_left( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT, FALSE );
+}
+
+static void ParseCSS1_border( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& rParser )
+{
+ ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, 0, TRUE );
+}
+
+/* */
+
+static void ParseCSS1_float( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ if( CSS1_IDENT==pExpr->GetType() )
+ {
+ USHORT nFloat;
+ if( SvxCSS1Parser::GetEnum( aFloatTable, pExpr->GetString(), nFloat ) )
+ rPropInfo.eFloat = (SvxAdjust)nFloat;
+ }
+}
+
+
+/* */
+
+static void ParseCSS1_position( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ DBG_ASSERT( pExpr, "kein Ausdruck" );
+
+ if( CSS1_IDENT==pExpr->GetType() )
+ {
+ USHORT nPos;
+ if( SvxCSS1Parser::GetEnum( aPositionTable, pExpr->GetString(), nPos ) )
+ rPropInfo.ePosition = (SvxCSS1Position)nPos;
+ }
+}
+
+/* */
+
+static void ParseCSS1_length( const CSS1Expression *pExpr,
+ long& rLength,
+ SvxCSS1LengthType& rLengthType,
+ BOOL bHori )
+{
+ switch( pExpr->GetType() )
+ {
+ case CSS1_IDENT:
+ if( pExpr->GetString().EqualsIgnoreCaseAscii( sCSS1_PV_auto ) )
+ {
+ rLength = 0;
+ rLengthType = SVX_CSS1_LTYPE_AUTO;
+ }
+ break;
+
+ case CSS1_LENGTH:
+ rLength = pExpr->GetSLength();
+ rLengthType = SVX_CSS1_LTYPE_TWIP;
+ break;
+
+ case CSS1_PIXLENGTH:
+ case CSS1_NUMBER: // wegen Netscape und IE
+ {
+ long nWidthL = (long)pExpr->GetNumber();
+ long nPWidth = bHori ? 0 : nWidthL;
+ long nPHeight = bHori ? nWidthL : 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ rLength = (bHori ? nPHeight : nPWidth);
+ rLengthType = SVX_CSS1_LTYPE_TWIP;
+ }
+ break;
+
+ case CSS1_PERCENTAGE:
+ rLength = (long)pExpr->GetNumber();
+ if( rLength > 100 )
+ rLength = 100;
+ rLengthType = SVX_CSS1_LTYPE_PERCENTAGE;
+ break;
+
+ default:
+ ;
+ }
+}
+
+/* */
+
+static void ParseCSS1_width( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ ParseCSS1_length( pExpr, rPropInfo.nWidth, rPropInfo.eWidthType, TRUE );
+}
+
+static void ParseCSS1_height( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ ParseCSS1_length( pExpr, rPropInfo.nHeight, rPropInfo.eHeightType, FALSE );
+}
+
+static void ParseCSS1_left( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ ParseCSS1_length( pExpr, rPropInfo.nLeft, rPropInfo.eLeftType, TRUE );
+}
+
+static void ParseCSS1_top( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ ParseCSS1_length( pExpr, rPropInfo.nTop, rPropInfo.eTopType, FALSE );
+}
+
+/* */
+
+// Feature: PrintExt
+static void ParseCSS1_size( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ USHORT n=0;
+ while( n<2 && pExpr && !pExpr->GetOp() )
+ {
+ switch( pExpr->GetType() )
+ {
+ case CSS1_IDENT:
+ {
+ USHORT nValue;
+ if( SvxCSS1Parser::GetEnum( aSizeTable, pExpr->GetString(),
+ nValue ) )
+ {
+ rPropInfo.eSizeType = (SvxCSS1SizeType)nValue;
+ }
+ }
+ break;
+
+ case CSS1_LENGTH:
+ rPropInfo.nHeight = pExpr->GetSLength();
+ if( n==0 )
+ rPropInfo.nWidth = rPropInfo.nHeight;
+ rPropInfo.eSizeType = SVX_CSS1_STYPE_TWIP;
+ break;
+
+ case CSS1_PIXLENGTH:
+ {
+ long nPHeight = (long)pExpr->GetNumber();
+ long nPWidth = n==0 ? nPHeight : 0;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ rPropInfo.nHeight = nPHeight;
+ if( n==0 )
+ rPropInfo.nWidth = nPWidth;
+ rPropInfo.eSizeType = SVX_CSS1_STYPE_TWIP;
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ pExpr = pExpr->GetNext();
+ n++;
+ }
+}
+
+// /Feature: PrintExt
+
+/* */
+
+// Feature: PrintExt
+
+static void ParseCSS1_page_break_xxx( const CSS1Expression *pExpr,
+ SvxCSS1PageBreak& rPBreak )
+{
+ if( CSS1_IDENT == pExpr->GetType() )
+ {
+ USHORT nValue;
+ if( SvxCSS1Parser::GetEnum( aPageBreakTable, pExpr->GetString(),
+ nValue ) )
+ {
+ rPBreak = (SvxCSS1PageBreak)nValue;
+ }
+ }
+}
+
+static void ParseCSS1_page_break_before( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ ParseCSS1_page_break_xxx( pExpr, rPropInfo.ePageBreakBefore );
+}
+
+static void ParseCSS1_page_break_after( const CSS1Expression *pExpr,
+ SfxItemSet & /*rItemSet*/,
+ SvxCSS1PropertyInfo& rPropInfo,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ ParseCSS1_page_break_xxx( pExpr, rPropInfo.ePageBreakAfter );
+}
+
+static void ParseCSS1_page_break_inside( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ SvxCSS1PageBreak eBreak(SVX_CSS1_PBREAK_NONE);
+ ParseCSS1_page_break_xxx( pExpr, eBreak );
+
+ BOOL bSetSplit = FALSE, bSplit = TRUE;
+ switch( eBreak )
+ {
+ case SVX_CSS1_PBREAK_AUTO:
+ bSetSplit = TRUE;
+ break;
+ case SVX_CSS1_PBREAK_AVOID:
+ bSplit = FALSE;
+ bSetSplit = TRUE;
+ break;
+ default:
+ ;
+ }
+
+ if( bSetSplit )
+ rItemSet.Put( SvxFmtSplitItem( bSplit, aItemIds.nFmtSplit ) );
+}
+
+static void ParseCSS1_widows( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ if( CSS1_NUMBER == pExpr->GetType() )
+ {
+ BYTE nVal = pExpr->GetNumber() <= 255
+ ? (BYTE)pExpr->GetNumber()
+ : 255;
+ SvxWidowsItem aWidowsItem( nVal, aItemIds.nWidows );
+ rItemSet.Put( aWidowsItem );
+ }
+}
+
+static void ParseCSS1_orphans( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& /*rParser*/ )
+{
+ if( CSS1_NUMBER == pExpr->GetType() )
+ {
+ BYTE nVal = pExpr->GetNumber() <= 255
+ ? (BYTE)pExpr->GetNumber()
+ : 255;
+ SvxOrphansItem aOrphansItem( nVal, aItemIds.nOrphans );
+ rItemSet.Put( aOrphansItem );
+ }
+}
+// /Feature: PrintExt
+
+static void ParseCSS1_so_language( const CSS1Expression *pExpr,
+ SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo& /*rPropInfo*/,
+ const SvxCSS1Parser& rParser )
+{
+ if( CSS1_IDENT == pExpr->GetType() ||
+ CSS1_STRING == pExpr->GetType() )
+ {
+ LanguageType eLang = MsLangId::convertIsoStringToLanguage( pExpr->GetString() );
+ if( LANGUAGE_DONTKNOW != eLang )
+ {
+ SvxLanguageItem aLang( eLang, aItemIds.nLanguage );
+ if( rParser.IsSetWesternProps() )
+ rItemSet.Put( aLang );
+ if( rParser.IsSetCJKProps() )
+ {
+ aLang.SetWhich( aItemIds.nLanguageCJK );
+ rItemSet.Put( aLang );
+ }
+ if( rParser.IsSetCTLProps() )
+ {
+ aLang.SetWhich( aItemIds.nLanguageCTL );
+ rItemSet.Put( aLang );
+ }
+ }
+ }
+}
+
+/* */
+
+// die Zuordung Property zu parsender Funktion
+struct CSS1PropEntry
+{
+ union
+ {
+ const sal_Char *sName;
+ String *pName;
+ };
+ FnParseCSS1Prop pFunc;
+};
+
+#define CSS1_PROP_ENTRY(p) \
+ { { sCSS1_P_##p }, ParseCSS1_##p }
+
+
+// die Tabelle mit den Zuordnungen
+static CSS1PropEntry __FAR_DATA aCSS1PropFnTab[] =
+{
+ CSS1_PROP_ENTRY(background),
+ CSS1_PROP_ENTRY(background_color),
+ CSS1_PROP_ENTRY(border_top_width),
+ CSS1_PROP_ENTRY(border_right_width),
+ CSS1_PROP_ENTRY(border_bottom_width),
+ CSS1_PROP_ENTRY(border_left_width),
+ CSS1_PROP_ENTRY(border_width),
+ CSS1_PROP_ENTRY(border_color),
+ CSS1_PROP_ENTRY(border_style),
+ CSS1_PROP_ENTRY(border_top),
+ CSS1_PROP_ENTRY(border_right),
+ CSS1_PROP_ENTRY(border_bottom),
+ CSS1_PROP_ENTRY(border_left),
+ CSS1_PROP_ENTRY(border),
+ CSS1_PROP_ENTRY(color),
+ CSS1_PROP_ENTRY(direction),
+ CSS1_PROP_ENTRY(float),
+ CSS1_PROP_ENTRY(font_size),
+ CSS1_PROP_ENTRY(font_family),
+ CSS1_PROP_ENTRY(font_style),
+ CSS1_PROP_ENTRY(font_variant),
+ CSS1_PROP_ENTRY(font_weight),
+ CSS1_PROP_ENTRY(letter_spacing),
+ CSS1_PROP_ENTRY(line_height),
+ CSS1_PROP_ENTRY(font),
+ CSS1_PROP_ENTRY(text_align),
+ CSS1_PROP_ENTRY(text_decoration),
+ CSS1_PROP_ENTRY(text_indent),
+ CSS1_PROP_ENTRY(margin_left),
+ CSS1_PROP_ENTRY(margin_right),
+ CSS1_PROP_ENTRY(margin_top),
+ CSS1_PROP_ENTRY(margin_bottom),
+ CSS1_PROP_ENTRY(margin),
+ CSS1_PROP_ENTRY(padding_top),
+ CSS1_PROP_ENTRY(padding_bottom),
+ CSS1_PROP_ENTRY(padding_left),
+ CSS1_PROP_ENTRY(padding_right),
+ CSS1_PROP_ENTRY(padding),
+ CSS1_PROP_ENTRY(position),
+ CSS1_PROP_ENTRY(left),
+ CSS1_PROP_ENTRY(top),
+ CSS1_PROP_ENTRY(width),
+ CSS1_PROP_ENTRY(height),
+// Feature: PrintExt
+ CSS1_PROP_ENTRY(size),
+ CSS1_PROP_ENTRY(page_break_before),
+ CSS1_PROP_ENTRY(page_break_after),
+ CSS1_PROP_ENTRY(page_break_inside),
+ CSS1_PROP_ENTRY(widows),
+ CSS1_PROP_ENTRY(orphans),
+// /Feature: PrintExt
+ CSS1_PROP_ENTRY(so_language)
+};
+
+/* */
+
+static int __FAR_DATA bSortedPropFns = FALSE;
+
+extern "C"
+{
+static int
+#if defined( WNT )
+ __cdecl
+#endif
+#if defined( ICC )
+ _Optlink
+#endif
+ CSS1PropEntryCompare( const void *pFirst, const void *pSecond)
+{
+ int nRet;
+ if( ((CSS1PropEntry*)pFirst)->pFunc )
+ {
+ if( ((CSS1PropEntry*)pSecond)->pFunc )
+ nRet = strcmp( ((CSS1PropEntry*)pFirst)->sName ,
+ ((CSS1PropEntry*)pSecond)->sName );
+ else
+ nRet = -1 * ((CSS1PropEntry*)pSecond)->pName->CompareToAscii(
+ ((CSS1PropEntry*)pFirst)->sName );
+ }
+ else
+ {
+ if( ((CSS1PropEntry*)pSecond)->pFunc )
+ nRet = ((CSS1PropEntry*)pFirst)->pName->CompareToAscii(
+ ((CSS1PropEntry*)pSecond)->sName );
+ else
+ nRet = ((CSS1PropEntry*)pFirst)->pName->CompareTo(
+ *((CSS1PropEntry*)pSecond)->pName );
+ }
+
+ return nRet;
+}
+}
+
+void SvxCSS1Parser::ParseProperty( const String& rProperty,
+ const CSS1Expression *pExpr )
+{
+ DBG_ASSERT( pItemSet, "DeclarationParsed() ohne ItemSet" );
+
+ if( !bSortedPropFns )
+ {
+ qsort( (void*) aCSS1PropFnTab,
+ sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
+ sizeof( CSS1PropEntry ),
+ CSS1PropEntryCompare );
+ bSortedPropFns = TRUE;
+ }
+
+ String aTmp( rProperty );
+ aTmp.ToLowerAscii();
+
+ CSS1PropEntry aSrch;
+ aSrch.pName = &aTmp;
+ aSrch.pFunc = 0;
+
+ void* pFound;
+ if( 0 != ( pFound = bsearch( (char *) &aSrch,
+ (void*) aCSS1PropFnTab,
+ sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
+ sizeof( CSS1PropEntry ),
+ CSS1PropEntryCompare )))
+ {
+ (((CSS1PropEntry*)pFound)->pFunc)( pExpr, *pItemSet, *pPropInfo, *this );
+ }
+}
diff --git a/sw/source/filter/html/svxcss1.hxx b/sw/source/filter/html/svxcss1.hxx
new file mode 100644
index 000000000000..e5f706334538
--- /dev/null
+++ b/sw/source/filter/html/svxcss1.hxx
@@ -0,0 +1,435 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _SVXCSS1_HXX
+#define _SVXCSS1_HXX
+
+#include <tools/string.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/svxenum.hxx>
+
+#ifndef _SVSTDARR_HXX
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#endif
+#include <rtl/textenc.h>
+#include "parcss1.hxx"
+
+class SfxItemPool;
+class SvxBoxItem;
+class FontList;
+
+/* */
+
+enum SvxCSS1Position
+{
+ SVX_CSS1_POS_NONE, // nichts angegeben
+ SVX_CSS1_POS_STATIC, // normal
+ SVX_CSS1_POS_ABSOLUTE, // absolut
+ SVX_CSS1_POS_RELATIVE, // relativ
+ SVX_CSS1_POS_END
+};
+
+
+enum SvxCSS1LengthType
+{
+ SVX_CSS1_LTYPE_NONE, // nichts angegeben
+ SVX_CSS1_LTYPE_AUTO, // automatisch
+ SVX_CSS1_LTYPE_TWIP, // twip
+ SVX_CSS1_LTYPE_PERCENTAGE, // %-Angabe
+ SVX_CSS1_LTYPE_END
+};
+
+// Feature: PrintExt
+enum SvxCSS1SizeType
+{
+ SVX_CSS1_STYPE_NONE, // nichts angegeben
+ SVX_CSS1_STYPE_AUTO, // automatisch
+ SVX_CSS1_STYPE_TWIP, // twip
+ SVX_CSS1_STYPE_LANDSCAPE, // Landscape
+ SVX_CSS1_STYPE_PORTRAIT, // Landscape
+ SVX_CSS1_STYPE_END
+};
+
+enum SvxCSS1PageBreak
+{
+ SVX_CSS1_PBREAK_NONE, // nichts angegeben
+ SVX_CSS1_PBREAK_AUTO, // automatisch
+ SVX_CSS1_PBREAK_ALWAYS, // immer
+ SVX_CSS1_PBREAK_AVOID, // nie
+ SVX_CSS1_PBREAK_LEFT, // naechste Seite ist eine linke
+ SVX_CSS1_PBREAK_RIGHT, // naechste Seite ist eine rechte
+ SVX_CSS1_PBREAK_END
+};
+
+// /Feature: PrintExt
+
+#define CSS1_SCRIPT_WESTERN 0x01
+#define CSS1_SCRIPT_CJK 0x02
+#define CSS1_SCRIPT_CTL 0x04
+#define CSS1_SCRIPT_ALL 0x07
+
+/* */
+
+struct CSS1PropertyEnum
+{
+ const sal_Char *pName; // Wert einer Property
+ sal_uInt16 nEnum; // und der dazugehoerige Wert eines Enums
+};
+
+
+/* */
+
+class SvxBorderLine;
+
+SV_DECL_PTRARR_DEL( CSS1Selectors, CSS1Selector*, 1, 1 )
+
+#define SVX_CSS1_BORDERINFO_WIDTH 1
+#define SVX_CSS1_BORDERINFO_COLOR 2
+#define SVX_CSS1_BORDERINFO_STYLE 4
+
+struct SvxCSS1BorderInfo;
+class SvxCSS1PropertyInfo
+{
+ SvxCSS1BorderInfo *aBorderInfos[4];
+
+ void DestroyBorderInfos();
+
+public:
+
+ String aId; // ID fuer Bookmarks, Rahmen etc.
+
+ sal_Bool bTopMargin : 1;
+ sal_Bool bBottomMargin : 1;
+
+ sal_Bool bLeftMargin : 1;
+ sal_Bool bRightMargin : 1;
+ sal_Bool bTextIndent : 1;
+
+ SvxAdjust eFloat;
+
+ SvxCSS1Position ePosition;
+
+ sal_uInt16 nTopBorderDistance;
+ sal_uInt16 nBottomBorderDistance;
+ sal_uInt16 nLeftBorderDistance;
+ sal_uInt16 nRightBorderDistance;
+
+ long nLeft, nTop;
+ long nWidth, nHeight;
+ long nLeftMargin, nRightMargin;
+
+ SvxCSS1LengthType eLeftType, eTopType;
+ SvxCSS1LengthType eWidthType, eHeightType;
+
+// Feature: PrintExt
+ SvxCSS1SizeType eSizeType;
+
+ SvxCSS1PageBreak ePageBreakBefore;
+ SvxCSS1PageBreak ePageBreakAfter;
+// /Feature: PrintExt
+
+ SvxCSS1PropertyInfo();
+ SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo& rProp );
+ ~SvxCSS1PropertyInfo();
+
+ void Merge( const SvxCSS1PropertyInfo& rProp );
+
+ void Clear();
+
+ SvxCSS1BorderInfo *GetBorderInfo( sal_uInt16 nLine, sal_Bool bCreate=sal_True );
+ void CopyBorderInfo( sal_uInt16 nSrcLine, sal_uInt16 nDstLine, sal_uInt16 nWhat );
+ void CopyBorderInfo( sal_uInt16 nCount, sal_uInt16 nWhat );
+
+ void SetBoxItem( SfxItemSet& rItemSet, sal_uInt16 nMinBorderDist,
+ const SvxBoxItem* pDflt=0, sal_Bool bTable = sal_False );
+
+};
+
+class SvxCSS1MapEntry
+{
+ String aKey;
+ SfxItemSet aItemSet;
+ SvxCSS1PropertyInfo aPropInfo;
+
+public:
+
+ SvxCSS1MapEntry( SfxItemPool& rPool, const sal_uInt16 *pWhichMap ) :
+ aItemSet( rPool, pWhichMap )
+ {}
+
+ SvxCSS1MapEntry( const String& rKey, const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp );
+
+
+ const SfxItemSet& GetItemSet() const { return aItemSet; }
+ SfxItemSet& GetItemSet() { return aItemSet; }
+
+ const SvxCSS1PropertyInfo& GetPropertyInfo() const { return aPropInfo; }
+ SvxCSS1PropertyInfo& GetPropertyInfo() { return aPropInfo; }
+
+ const String& GetKey() const { return aKey; }
+ // TODO: ToUpperAscii -> ???
+ void SetKey( const String& rKey ) { aKey = rKey; aKey.ToUpperAscii(); }
+
+ friend sal_Bool operator==( const SvxCSS1MapEntry& rE1,
+ const SvxCSS1MapEntry& rE2 );
+ friend sal_Bool operator<( const SvxCSS1MapEntry& rE1,
+ const SvxCSS1MapEntry& rE2 );
+};
+
+typedef SvxCSS1MapEntry *SvxCSS1MapEntryPtr;
+SV_DECL_PTRARR_SORT_DEL( SvxCSS1Map, SvxCSS1MapEntryPtr, 5, 5 )
+
+
+#if !defined( ICC ) && !defined( BLC )
+inline sal_Bool operator==( const SvxCSS1MapEntry& rE1, const SvxCSS1MapEntry& rE2 )
+{
+ return rE1.aKey==rE2.aKey;
+}
+
+inline sal_Bool operator<( const SvxCSS1MapEntry& rE1, const SvxCSS1MapEntry& rE2 )
+{
+ return rE1.aKey<rE2.aKey;
+}
+#endif
+
+// Diese Klasse bereitet den Output des CSS1-Parsers auf,
+// indem die CSS1-Properties in SvxItem(Set)s umgewandelt werden.
+// Ausserdem werden die Selektoren samt zugehoeriger Item-Set
+// gespeichert.
+// Ein abgeleiteter Parser kann dies fuer einzelne Selektoren unterdruecken,
+// indem er die Methode StyleParsed ueberlaed.
+
+class SvxCSS1Parser : public CSS1Parser
+{
+ CSS1Selectors aSelectors; // Liste der "offenen" Selectoren
+
+ SvxCSS1Map aIds;
+ SvxCSS1Map aClasses;
+ SvxCSS1Map aPages;
+ SvxCSS1Map aTags;
+
+ String sBaseURL;
+
+ SfxItemSet *pSheetItemSet; // der Item-Set fuer Style-Sheets
+ SfxItemSet *pItemSet; // der aktuelle Item-Set
+ SvxCSS1MapEntry *pSearchEntry;
+
+ SvxCSS1PropertyInfo *pSheetPropInfo;
+ SvxCSS1PropertyInfo *pPropInfo;
+
+ sal_uInt16 nMinFixLineSpace; // Mindest-Abstand fuer festen Zeilenabstand
+
+ rtl_TextEncoding eDfltEnc;
+ sal_uInt16 nScriptFlags;
+
+ sal_Bool bIgnoreFontFamily;
+
+ void ParseProperty( const String& rProperty,
+ const CSS1Expression *pExpr );
+
+ SvUShorts aWhichMap; // Which-Map des Parser
+
+ using CSS1Parser::ParseStyleOption;
+
+protected:
+
+ using CSS1Parser::ParseStyleSheet;
+
+ // Diese Methode wird fuer jeden Selektor mit dem zugehoerigen
+ // Item-Set aufgerufen. Fuer einen Selektor koennen mehrere
+ // Aufrufe erfolgen.
+ // wenn sal_True zuruckgegeben wird, wird der Item-Set bzw. der
+ // Selektor nicht mehr gespeichert!
+ // Der ItemSet darf entsprechend modifiziert werden!
+ // Die Implementierung dieser Methode gibt sal_False zurueck.
+ virtual sal_Bool StyleParsed( const CSS1Selector *pSelector,
+ SfxItemSet& rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo );
+
+ // Diese Methode wird aufgerufen, wenn ein Selektor geparst wurde
+ // Wenn bFirst gesetzt ist, wird der Inhalt von aItemSet in alle
+ // zuletzt angelegten Styles kopiert.
+ // Diese Methode sollte in abgleiteten Parsern nicht mehr
+ // ueberladen werden!
+ virtual sal_Bool SelectorParsed( const CSS1Selector *pSelector,
+ sal_Bool bFirst );
+
+ // Diese Methode wird fuer jede geparste Property aufgerufen
+ // sie fuegt das Item in den ItemSet 'pItemSet' ein
+ // Sie sollte in abgeleiteten Parsern nicht mehr ueberladen werden!
+ virtual sal_Bool DeclarationParsed( const String& rProperty,
+ const CSS1Expression *pExpr );
+
+public:
+
+
+ SvxCSS1Parser( SfxItemPool& rPool,
+ const String& rBaseURL,
+ sal_uInt16 nMinFixLineSp,
+ sal_uInt16 *pWhichIds=0, sal_uInt16 nWhichIds=0 );
+ virtual ~SvxCSS1Parser();
+
+ sal_Bool IsIgnoreFontFamily() const { return bIgnoreFontFamily; }
+ void SetIgnoreFontFamily( sal_Bool bSet ) { bIgnoreFontFamily = bSet; }
+
+ // Parsen eines Style-Sheets. Fuer jeden gefundenen Selektor
+ // wird StyleParsed mit dem entsprechenem Item-Set aufgerufen
+ virtual sal_Bool ParseStyleSheet( const String& rIn );
+
+ // Parsen einer Style-Option. Hier wird einfach nur der Item-Set
+ // gefuellt.
+ sal_Bool ParseStyleOption( const String& rIn, SfxItemSet& rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo );
+
+ // Umwandeln eines Strings in den Wert eines Enums
+ static sal_Bool GetEnum( const CSS1PropertyEnum *pPropTable,
+ const String& rValue, sal_uInt16 &rEnum );
+
+ // Pixel in Twips wandeln
+ static void PixelToTwip( long &nWidth, long &nHeight );
+
+ // Die Breite einer Umrandung einstellen
+ static void SetBorderWidth( SvxBorderLine& aBorderLine, sal_uInt16 nWidth,
+ sal_Bool bDouble, sal_Bool bTable=sal_False );
+
+ // Die Font-Hoehe fuer eine bestimmte Font-Groesse (0-6) ermitteln
+ virtual sal_uInt32 GetFontHeight( sal_uInt16 nSize ) const;
+
+ virtual const FontList *GetFontList() const;
+
+ const sal_uInt16 *GetWhichMap() const { return aWhichMap.GetData(); }
+
+ SvxCSS1MapEntry *GetMapEntry( const String& rKey,
+ const SvxCSS1Map& rMap ) const;
+
+ void InsertMapEntry( const String& rKey, const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp, SvxCSS1Map& rMap );
+
+ void InsertId( const String& rId, const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp );
+
+ inline SvxCSS1MapEntry *GetId( const String& rId ) const;
+
+ void InsertClass( const String& rClass, const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp );
+
+ inline SvxCSS1MapEntry *GetClass( const String& rClass ) const;
+
+ inline void InsertPage( const String& rPage, sal_Bool bPseudo,
+ const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp );
+
+ inline SvxCSS1MapEntry *GetPage( const String& rPage, sal_Bool bPseudo ) const;
+
+ inline SvxCSS1MapEntry *GetPage( sal_uInt16 i ) const { return aPages[i]; }
+ sal_uInt16 GetPageCount() const { return aPages.Count(); }
+
+ void InsertTag( const String& rTag, const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp );
+
+ inline SvxCSS1MapEntry *GetTag( const String& rTag ) const;
+
+ void MergeStyles( const SfxItemSet& rSrcSet,
+ const SvxCSS1PropertyInfo& rSrcInfo,
+ SfxItemSet& rTargetSet,
+ SvxCSS1PropertyInfo& rTargetInfo,
+ sal_Bool bSmart );
+
+ sal_uInt16 GetMinFixLineSpace() const { return nMinFixLineSpace; }
+
+ virtual void SetDfltEncoding( rtl_TextEncoding eEnc );
+ rtl_TextEncoding GetDfltEncoding() const { return eDfltEnc; }
+
+ sal_Bool IsSetWesternProps() const { return (nScriptFlags & CSS1_SCRIPT_WESTERN) != 0; }
+ sal_Bool IsSetCJKProps() const { return (nScriptFlags & CSS1_SCRIPT_CJK) != 0; }
+ sal_Bool IsSetCTLProps() const { return (nScriptFlags & CSS1_SCRIPT_CTL) != 0; }
+
+ const String& GetBaseURL() const { return sBaseURL;}
+
+};
+
+inline void SvxCSS1Parser::InsertId( const String& rId,
+ const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp )
+{
+ InsertMapEntry( rId, rItemSet, rProp, aIds );
+}
+
+inline SvxCSS1MapEntry *SvxCSS1Parser::GetId( const String& rId ) const
+{
+ return GetMapEntry( rId, aIds );
+}
+
+inline void SvxCSS1Parser::InsertClass( const String& rClass,
+ const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp )
+{
+ InsertMapEntry( rClass, rItemSet, rProp, aClasses );
+}
+
+inline SvxCSS1MapEntry *SvxCSS1Parser::GetClass( const String& rClass ) const
+{
+ return GetMapEntry( rClass, aClasses );
+}
+
+inline void SvxCSS1Parser::InsertPage( const String& rPage,
+ sal_Bool bPseudo,
+ const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp )
+{
+ String aKey( rPage );
+ if( bPseudo )
+ aKey.Insert( ':', 0 );
+ InsertMapEntry( aKey, rItemSet, rProp, aPages );
+}
+
+inline SvxCSS1MapEntry *SvxCSS1Parser::GetPage( const String& rPage,
+ sal_Bool bPseudo ) const
+{
+ String aKey( rPage );
+ if( bPseudo )
+ aKey.Insert( ':', 0 );
+ return GetMapEntry( aKey, aPages );
+}
+
+inline void SvxCSS1Parser::InsertTag( const String& rTag,
+ const SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rProp )
+{
+ InsertMapEntry( rTag, rItemSet, rProp, aTags );
+}
+
+inline SvxCSS1MapEntry *SvxCSS1Parser::GetTag( const String& rTag ) const
+{
+ return GetMapEntry( rTag, aTags );
+}
+
+
+#endif
+
+
diff --git a/sw/source/filter/html/swcss1.hxx b/sw/source/filter/html/swcss1.hxx
new file mode 100644
index 000000000000..09d16753db82
--- /dev/null
+++ b/sw/source/filter/html/swcss1.hxx
@@ -0,0 +1,227 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef _SWCSS1_HXX
+#define _SWCSS1_HXX
+
+#include "poolfmt.hxx"
+
+#include "svxcss1.hxx"
+
+class SwDoc;
+class SwFmt;
+class SwCharFmt;
+class SwTxtFmtColl;
+class SvxBrushItem;
+class SwFmtDrop;
+class SwPageDesc;
+
+// Dieser Header seiht zwar harmlos aus, included aber eben doch
+// ganz unauffaellig das ein oder andere! Andererseits wird diese
+// Klasse recht selten benoetigt. Deshalb ein eigener Header.
+
+
+class SwCSS1Parser : public SvxCSS1Parser
+{
+ SwDoc *pDoc;
+
+ ULONG aFontHeights[7];
+
+ USHORT nDropCapCnt;
+
+ BOOL bIsNewDoc : 1;
+
+ BOOL bBodyBGColorSet : 1;
+ BOOL bBodyBackgroundSet : 1;
+ BOOL bBodyTextSet : 1;
+ BOOL bBodyLinkSet : 1;
+ BOOL bBodyVLinkSet : 1;
+
+ BOOL bSetFirstPageDesc : 1;
+ BOOL bSetRightPageDesc : 1;
+
+ BOOL bTableHeaderTxtCollSet : 1;
+ BOOL bTableTxtCollSet : 1;
+
+ BOOL bLinkCharFmtsSet : 1;
+
+ // die Vorlagen fuer DL anlegen
+ SwTxtFmtColl* GetDefListTxtFmtColl( USHORT nCollId, USHORT nDeep );
+
+ const SwPageDesc* GetPageDesc( USHORT nPoolId, BOOL bCreate );
+
+ void SetTableTxtColl( BOOL bHeader );
+ void SetLinkCharFmts();
+
+protected:
+ virtual BOOL StyleParsed( const CSS1Selector *pSelector,
+ SfxItemSet& rItemSet,
+ SvxCSS1PropertyInfo& rPropInfo );
+
+ using CSS1Parser::ParseStyleSheet;
+
+public:
+ SwCSS1Parser( SwDoc *pDoc, sal_uInt32 aFHeight[7], const String& rBaseURL, BOOL bNewDoc );
+ virtual ~SwCSS1Parser();
+
+ virtual BOOL ParseStyleSheet( const String& rIn );
+
+ // Die Font-Hoehe fuer eine bestimmte Font-Groesse (0-6) ermitteln
+ virtual sal_uInt32 GetFontHeight( USHORT nSize ) const;
+
+ // Die aktuelle Font-Liste holen (auch 0 ist erlaubt)
+ virtual const FontList *GetFontList() const;
+
+ // das Zeichen-Format zu einem Token und einer ggf leeren Klasse
+ // ermitteln
+ SwCharFmt* GetChrFmt( USHORT nToken, const String& rClass ) const;
+
+ // eine TextFmtColl zu einer Pool-Id ermitteln
+ SwTxtFmtColl *GetTxtFmtColl( USHORT nTxtColl, const String& rClass );
+
+ // This methods do the same as the one of SwDoc, but change the
+ // encoding if required.
+ SwTxtFmtColl *GetTxtCollFromPool( USHORT nPoolId ) const;
+ SwCharFmt *GetCharFmtFromPool( USHORT nPoolId ) const;
+
+ // Die linke oder rechte Seiten-Vorlage holen. In Dokumenten mit nur
+ // einer Vorlage gibt es nur eine rechtee Seite.
+ // Ansonsten ist die rechte Seite die HTML-Poolvorlage und die linke
+ // eine Benutzter-Vorlage, die on-demand angelegt wird, wenn
+ // bCreate gesetzt ist.
+ SwPageDesc* GetMasterPageDesc();
+ inline const SwPageDesc* GetFirstPageDesc( BOOL bCreate=FALSE );
+ inline const SwPageDesc* GetRightPageDesc( BOOL bCreate=FALSE );
+ inline const SwPageDesc* GetLeftPageDesc( BOOL bCreate=FALSE );
+
+ // Attribute an der HTML-Seitenvorlage setzen (gesetzte Attribute
+ // werden aus dem Item-Set geloescht ). Wird fuer's BODY-Tag
+ // aufgerufen.
+ void SetPageDescAttrs( const SvxBrushItem *pBrush,
+ SfxItemSet *pItemSet=0 );
+
+ void ChgPageDesc( const SwPageDesc *pPageDesc,
+ const SwPageDesc& rNewPageDesc );
+
+ // Wird fuer @page aufgerufen.
+ void SetPageDescAttrs( const SwPageDesc *pPageDesc, SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rPropInfo );
+
+ // Fuellen eines DropCap-Attributs
+ void FillDropCap( SwFmtDrop& rDrop, SfxItemSet& rItemSet,
+ const String *pName=0 );
+
+ BOOL SetFmtBreak( SfxItemSet& rItemSet,
+ const SvxCSS1PropertyInfo& rPropInfo );
+
+
+ static void AddClassName( String& rFmtName, const String& rClass );
+
+ static inline void AddFirstLetterExt( String& rFmtName );
+
+ static BOOL MayBePositioned( const SvxCSS1PropertyInfo& rPropInfo,
+ BOOL bAutoWidth=FALSE );
+
+ static sal_uInt16 GetScriptFromClass( String& rClass,
+ sal_Bool bSubClassOnly = sal_True );
+
+ BOOL IsBodyBGColorSet() const { return bBodyBGColorSet; }
+ BOOL IsBodyBackgroundSet() const { return bBodyBackgroundSet; }
+ BOOL IsBodyTextSet() const { return bBodyTextSet; }
+ BOOL IsBodyLinkSet() const { return bBodyLinkSet; }
+ BOOL IsBodyVLinkSet() const { return bBodyVLinkSet; }
+
+ BOOL IsSetFirstPageDesc() const { return bSetFirstPageDesc; }
+ BOOL IsSetRightPageDesc() const { return bSetRightPageDesc; }
+
+ void SetBodyBGColorSet() { bBodyBGColorSet = TRUE; }
+ void SetBodyBackgroundSet() { bBodyBackgroundSet = TRUE; }
+ void SetBodyTextSet() { bBodyTextSet = TRUE; }
+ void SetBodyLinkSet() { bBodyLinkSet = TRUE; }
+ void SetBodyVLinkSet() { bBodyVLinkSet = TRUE; }
+
+ const SvxBrushItem& GetPageDescBackground() const;
+
+ inline void SetTHTagStyles();
+ inline void SetTDTagStyles();
+ inline void SetATagStyles();
+ inline void SetDelayedStyles();
+
+ virtual void SetDfltEncoding( rtl_TextEncoding eEnc );
+};
+
+
+inline void SwCSS1Parser::AddFirstLetterExt( String& rFmtName )
+{
+ rFmtName.AppendAscii( ".FL", 3 ); // first letter
+}
+
+inline const SwPageDesc* SwCSS1Parser::GetFirstPageDesc( BOOL bCreate )
+{
+ return GetPageDesc( RES_POOLPAGE_FIRST, bCreate );
+}
+
+inline const SwPageDesc* SwCSS1Parser::GetRightPageDesc( BOOL bCreate )
+{
+ return GetPageDesc( RES_POOLPAGE_RIGHT, bCreate );
+}
+
+inline const SwPageDesc* SwCSS1Parser::GetLeftPageDesc( BOOL bCreate )
+{
+ return GetPageDesc( RES_POOLPAGE_LEFT, bCreate );
+}
+
+inline void SwCSS1Parser::SetTHTagStyles()
+{
+ if( !bTableHeaderTxtCollSet )
+ SetTableTxtColl( TRUE );
+}
+
+inline void SwCSS1Parser::SetTDTagStyles()
+{
+ if( !bTableTxtCollSet )
+ SetTableTxtColl( FALSE );
+}
+
+
+inline void SwCSS1Parser::SetATagStyles()
+{
+ if( !bLinkCharFmtsSet )
+ SetLinkCharFmts();
+}
+
+inline void SwCSS1Parser::SetDelayedStyles()
+{
+ SetTHTagStyles();
+ SetTDTagStyles();
+ SetATagStyles();
+}
+
+
+#endif
+
+
diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx
new file mode 100644
index 000000000000..fba6a477757d
--- /dev/null
+++ b/sw/source/filter/html/swhtml.cxx
@@ -0,0 +1,5521 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <sfx2/sfx.hrc>
+#include <svx/svxids.hrc>
+#ifdef DBG_UTIL
+#include <stdlib.h>
+#endif
+#include <hintids.hxx>
+
+#define _SVSTDARR_STRINGS
+#include <svl/svstdarr.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/imap.hxx>
+#include <svtools/htmltokn.h>
+#include <svtools/htmlkywd.hxx>
+#include <svtools/ctrltool.hxx>
+#include <unotools/pathoptions.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/docfile.hxx>
+
+#include <svtools/htmlcfg.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/protitem.hxx>
+#include <editeng/flstitem.hxx>
+
+
+#include <frmatr.hxx>
+#include <charatr.hxx>
+#include <fmtfld.hxx>
+#include <fmtpdsc.hxx>
+#include <txtfld.hxx>
+#include <fmtanchr.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtfsize.hxx>
+#include <fmtclds.hxx>
+#include <fchrfmt.hxx>
+#include <fmtinfmt.hxx>
+#include <docary.hxx>
+#include <docstat.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <ndtxt.hxx>
+#include <mdiexp.hxx> // ...Percent()
+#include <expfld.hxx>
+#include <poolfmt.hxx>
+#include <pagedesc.hxx>
+#include <IMark.hxx> // fuer SwBookmark ...
+#include <docsh.hxx>
+#include <editsh.hxx> // fuer Start/EndAction
+#include <docufld.hxx>
+#include <swcss1.hxx>
+#include <htmlvsh.hxx>
+#include <fltini.hxx>
+#include <htmltbl.hxx>
+#include <htmlnum.hxx>
+#include <swhtml.hxx>
+#include <linkenum.hxx>
+#include <breakit.hxx>
+#include <SwAppletImpl.hxx>
+
+#include <sfx2/viewfrm.hxx>
+
+#ifndef _STATSTR_HRC
+#include <statstr.hrc> // ResId fuer Statusleiste
+#endif
+#include <swerror.h>
+
+#define FONTSIZE_MASK 7
+#define FONTCOLOR_MASK (1<<15)
+#define FONT_MASK (1<<14)
+
+#define HTML_ESC_PROP 80
+#define HTML_ESC_SUPER DFLT_ESC_SUPER
+#define HTML_ESC_SUB DFLT_ESC_SUB
+
+#define HTML_SPTYPE_NONE 0
+#define HTML_SPTYPE_BLOCK 1
+#define HTML_SPTYPE_HORI 2
+#define HTML_SPTYPE_VERT 3
+
+#ifndef TOOLS_CONSTASCII_STRINGPARAM
+#define TOOLS_CONSTASCII_STRINGPARAM( constAsciiStr ) constAsciiStr, sizeof( constAsciiStr )-1
+#endif
+
+using namespace ::com::sun::star;
+
+// <P ALIGN=xxx>, <Hn ALIGN=xxx>, <TD ALIGN=xxx> usw.
+HTMLOptionEnum __FAR_DATA aHTMLPAlignTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_AL_left, SVX_ADJUST_LEFT },
+ { OOO_STRING_SVTOOLS_HTML_AL_center, SVX_ADJUST_CENTER },
+ { OOO_STRING_SVTOOLS_HTML_AL_middle, SVX_ADJUST_CENTER }, // Netscape
+ { OOO_STRING_SVTOOLS_HTML_AL_right, SVX_ADJUST_RIGHT },
+ { OOO_STRING_SVTOOLS_HTML_AL_justify, SVX_ADJUST_BLOCK },
+ { OOO_STRING_SVTOOLS_HTML_AL_char, SVX_ADJUST_LEFT },
+ { 0, 0 }
+};
+
+// <SPACER TYPE=...>
+static HTMLOptionEnum __FAR_DATA aHTMLSpacerTypeTable[] =
+{
+ { OOO_STRING_SVTOOLS_HTML_SPTYPE_block, HTML_SPTYPE_BLOCK },
+ { OOO_STRING_SVTOOLS_HTML_SPTYPE_horizontal, HTML_SPTYPE_HORI },
+ { OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical, HTML_SPTYPE_VERT },
+ { 0, 0 }
+};
+
+SV_IMPL_PTRARR( _HTMLAttrs, _HTMLAttrPtr )
+
+HTMLReader::HTMLReader()
+{
+ bTmplBrowseMode = TRUE;
+}
+
+String HTMLReader::GetTemplateName() const
+{
+ String sTemplate(
+ String::CreateFromAscii(TOOLS_CONSTASCII_STRINGPARAM("internal")) );
+ sTemplate += INET_PATH_TOKEN;
+ sTemplate.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("html") );
+ String sTemplateWithoutExt( sTemplate );
+#ifndef MAC_WITHOUT_EXT
+ // --> OD 2005-01-26 - first search for OpenDocument Writer/Web template
+ sTemplate.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(".oth") );
+ // <--
+#endif
+
+ SvtPathOptions aPathOpt;
+ // OpenDocument Writer/Web template (extension .oth)
+ BOOL bSet = aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE );
+
+#ifndef MAC_WITHOUT_EXT
+ if( !bSet )
+ {
+ // 6.0 (extension .stw)
+ sTemplate = sTemplateWithoutExt;
+ // --> OD 2005-01-26 - no OpenDocument Writer/Web template found.
+ // search for OpenOffice.org Writer/Web template
+ sTemplate.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(".stw") );
+ // <--
+ bSet = aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE );
+ }
+#endif
+
+ if( !bSet )
+ {
+ sTemplate.Erase();
+ ASSERT( !this,
+ "Die html.vor befindet sich nicht mehr im definierten Directory!");
+ }
+
+ return sTemplate;
+}
+
+int HTMLReader::SetStrmStgPtr()
+{
+ ASSERT( pMedium, "Wo ist das Medium??" );
+
+ if( pMedium->IsRemote() || !pMedium->IsStorage() )
+ {
+ pStrm = pMedium->GetInStream();
+ return TRUE;
+ }
+ return FALSE;
+
+}
+
+ // Aufruf fuer die allg. Reader-Schnittstelle
+ULONG HTMLReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String & rName )
+{
+ if( !pStrm )
+ {
+ ASSERT( pStrm, "HTML-Read ohne Stream" );
+ return ERR_SWG_READ_ERROR;
+ }
+
+ if( !bInsertMode )
+ {
+ Reader::SetNoOutlineNum( rDoc );
+ Reader::ResetFrmFmts( rDoc );
+
+ // Die HTML-Seitenvorlage setzen, wenn des kein HTML-Dokument ist,
+ // sonst ist sie schon gesetzt.
+ if( !rDoc.get(IDocumentSettingAccess::HTML_MODE) )
+ {
+ rDoc.InsertPoolItem( rPam, SwFmtPageDesc(
+ rDoc.GetPageDescFromPool( RES_POOLPAGE_HTML, false )), 0 );
+ }
+ }
+
+ // damit keiner das Doc klaut!
+ rDoc.acquire();
+ ULONG nRet = 0;
+ SvParserRef xParser = new SwHTMLParser( &rDoc, rPam, *pStrm,
+ rName, rBaseURL, !bInsertMode, pMedium,
+ IsReadUTF8(),
+ bIgnoreHTMLComments );
+
+ SvParserState eState = xParser->CallParser();
+
+ if( SVPAR_PENDING == eState )
+ pStrm->ResetError();
+ else if( SVPAR_ACCEPTED != eState )
+ {
+ String sErr( String::CreateFromInt32((sal_Int32)xParser->GetLineNr()));
+ sErr += ',';
+ sErr += String::CreateFromInt32((sal_Int32)xParser->GetLinePos());
+
+ // den Stream als Fehlernummer Transporter benutzen
+ nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
+ ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
+ }
+
+
+ return nRet;
+}
+
+
+/* */
+
+SwHTMLParser::SwHTMLParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
+ const String& rPath,
+ const String& rBaseURL,
+ int bReadNewDoc,
+ SfxMedium* pMed, BOOL bReadUTF8,
+ sal_Bool bNoHTMLComments )
+ : SfxHTMLParser( rIn, static_cast< BOOL >(bReadNewDoc), pMed ),
+ SwClient( 0 ),
+ aPathToFile( rPath ),
+ sBaseURL( rBaseURL ),
+ pAppletImpl( 0 ),
+ pCSS1Parser( 0 ),
+ pNumRuleInfo( new SwHTMLNumRuleInfo ),
+ pPendStack( 0 ),
+ pDoc( pD ),
+ pActionViewShell( 0 ),
+ pSttNdIdx( 0 ),
+ pTable(0),
+ pFormImpl( 0 ),
+ pMarquee( 0 ),
+ pField( 0 ),
+ pImageMap( 0 ),
+ pImageMaps( 0 ),
+ pFootEndNoteImpl( 0 ),
+ nScriptStartLineNr( 0 ),
+ nBaseFontStMin( 0 ),
+ nFontStMin( 0 ),
+ nDefListDeep( 0 ),
+ nFontStHeadStart( 0 ),
+ nSBModuleCnt( 0 ),
+ nMissingImgMaps( 0 ),
+ nParaCnt( 5 ),
+ // --> OD 2007-10-26 #i83625#
+ nContextStMin( 0 ),
+ nContextStAttrMin( 0 ),
+ // <--
+ nOpenParaToken( 0 ),
+ eJumpTo( JUMPTO_NONE ),
+#ifdef DBG_UTIL
+ nContinue( 0 ),
+#endif
+ eParaAdjust( SVX_ADJUST_END ),
+ bDocInitalized( FALSE ),
+ bSetModEnabled( FALSE ),
+ bInFloatingFrame( FALSE ),
+ bInField( FALSE ),
+ bCallNextToken( FALSE ),
+ bIgnoreRawData( FALSE ),
+ bNoParSpace( FALSE ),
+ bInNoEmbed( FALSE ),
+ bInTitle( FALSE ),
+ bUpdateDocStat( FALSE ),
+ bFixSelectWidth( FALSE ),
+ bFixSelectHeight( FALSE ),
+ bTextArea( FALSE ),
+ bSelect( FALSE ),
+ bInFootEndNoteAnchor( FALSE ),
+ bInFootEndNoteSymbol( FALSE ),
+// bIgnoreHTMLComments( bNoHTMLComments )
+ bIgnoreHTMLComments( bNoHTMLComments ),
+ bRemoveHidden( FALSE ),
+ pTempViewFrame(0)
+{
+ nEventId = 0;
+ bUpperSpace = bViewCreated = bChkJumpMark =
+ bSetCrsr = FALSE;
+
+ eScriptLang = HTML_SL_UNKNOWN;
+ bAnyStarBasic = TRUE;
+
+ pPam = new SwPaM( *rCrsr.GetPoint() );
+ memset( &aAttrTab, 0, sizeof( _HTMLAttrTable ));
+
+ // Die Font-Groessen 1-7 aus der INI-Datei lesen
+ SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
+ aFontHeights[0] = pHtmlOptions->GetFontSize( 0 ) * 20;
+ aFontHeights[1] = pHtmlOptions->GetFontSize( 1 ) * 20;
+ aFontHeights[2] = pHtmlOptions->GetFontSize( 2 ) * 20;
+ aFontHeights[3] = pHtmlOptions->GetFontSize( 3 ) * 20;
+ aFontHeights[4] = pHtmlOptions->GetFontSize( 4 ) * 20;
+ aFontHeights[5] = pHtmlOptions->GetFontSize( 5 ) * 20;
+ aFontHeights[6] = pHtmlOptions->GetFontSize( 6 ) * 20;
+
+ bKeepUnknown = pHtmlOptions->IsImportUnknown();
+
+ if(bReadNewDoc)
+ {
+ SvxFontHeightItem aFontHeight(aFontHeights[2], 100, RES_CHRATR_FONTSIZE);
+ pDoc->SetDefault( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ pDoc->SetDefault( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ pDoc->SetDefault( aFontHeight );
+ }
+
+ // Waehrend des Imports in den HTML-Modus schalten, damit die
+ // richrigen Vorlagen angelegt werden
+ bOldIsHTMLMode = pDoc->get(IDocumentSettingAccess::HTML_MODE);
+ pDoc->set(IDocumentSettingAccess::HTML_MODE, true);
+
+ pCSS1Parser = new SwCSS1Parser( pDoc, aFontHeights, sBaseURL, IsNewDoc() );
+ pCSS1Parser->SetIgnoreFontFamily( pHtmlOptions->IsIgnoreFontFamily() );
+
+ if( bReadUTF8 )
+ {
+ SetSrcEncoding( RTL_TEXTENCODING_UTF8 );
+ }
+ else
+ {
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ SvKeyValueIterator *pHeaderAttrs =
+ pDocSh->GetHeaderAttributes();
+ if( pHeaderAttrs )
+ SetEncodingByHTTPHeader( pHeaderAttrs );
+ }
+ pCSS1Parser->SetDfltEncoding( gsl_getSystemTextEncoding() );
+
+ // Timer nur bei ganz normalen Dokumenten aufsetzen!
+ SwDocShell* pDocSh = pDoc->GetDocShell();
+ if( pDocSh )
+ {
+ bViewCreated = TRUE; // nicht, synchron laden
+
+ // es ist ein Sprungziel vorgegeben.
+
+ if( pMed )
+ {
+ sJmpMark = pMed->GetURLObject().GetMark();
+ if( sJmpMark.Len() )
+ {
+ eJumpTo = JUMPTO_MARK;
+ String sCmp;
+ xub_StrLen nLastPos, nPos = 0;
+ while( STRING_NOTFOUND != ( nLastPos =
+ sJmpMark.Search( cMarkSeperator, nPos + 1 )) )
+ nPos = nLastPos;
+
+ if( nPos && ( sCmp = sJmpMark.Copy( nPos + 1 ) ).
+ EraseAllChars().Len() )
+ {
+ sCmp.ToLowerAscii();
+ if( sCmp.EqualsAscii( pMarkToRegion ) )
+ eJumpTo = JUMPTO_REGION;
+ else if( sCmp.EqualsAscii( pMarkToTable ) )
+ eJumpTo = JUMPTO_TABLE;
+ else if( sCmp.EqualsAscii( pMarkToGraphic ) )
+ eJumpTo = JUMPTO_GRAPHIC;
+ else if( sCmp.EqualsAscii( pMarkToOutline ) ||
+ sCmp.EqualsAscii( pMarkToText ) ||
+ sCmp.EqualsAscii( pMarkToFrame ) )
+ eJumpTo = JUMPTO_NONE; // das ist nichts gueltiges!
+ else
+ // ansonsten ist das ein normaler (Book)Mark
+ nPos = STRING_LEN;
+ }
+ else
+ nPos = STRING_LEN;
+
+ sJmpMark.Erase( nPos );
+ if( !sJmpMark.Len() )
+ eJumpTo = JUMPTO_NONE;
+ }
+ }
+ }
+}
+
+__EXPORT SwHTMLParser::~SwHTMLParser()
+{
+#ifdef DBG_UTIL
+ ASSERT( !nContinue, "DTOR im Continue - Das geht schief!!!" );
+#endif
+ BOOL bAsync = pDoc->IsInLoadAsynchron();
+ pDoc->SetInLoadAsynchron( FALSE );
+ pDoc->set(IDocumentSettingAccess::HTML_MODE, bOldIsHTMLMode);
+
+ if( pDoc->GetDocShell() && nEventId )
+ Application::RemoveUserEvent( nEventId );
+
+ // das DocumentDetected kann ggfs. die DocShells loeschen, darum nochmals
+ // abfragen
+ if( pDoc->GetDocShell() )
+ {
+ // Gelinkte Bereiche updaten
+ USHORT nLinkMode = pDoc->getLinkUpdateMode( true );
+ if( nLinkMode != NEVER && bAsync &&
+ SFX_CREATE_MODE_INTERNAL!=pDoc->GetDocShell()->GetCreateMode() )
+ pDoc->GetLinkManager().UpdateAllLinks( nLinkMode == MANUAL,
+ TRUE, FALSE );
+
+ if ( pDoc->GetDocShell()->IsLoading() )
+ {
+ // --> OD 2006-11-07 #i59688#
+ pDoc->GetDocShell()->LoadingFinished();
+ }
+ }
+
+ delete pSttNdIdx;
+
+ if( aSetAttrTab.Count() )
+ {
+ ASSERT( !aSetAttrTab.Count(),"Es stehen noch Attribute auf dem Stack" );
+ aSetAttrTab.DeleteAndDestroy( 0, aSetAttrTab.Count() );
+ }
+
+ delete pPam;
+ delete pCSS1Parser;
+ delete pNumRuleInfo;
+ DeleteFormImpl();
+ DeleteFootEndNoteImpl();
+
+ ASSERT( !pTable, "Es existiert noch eine offene Tabelle" );
+ delete pImageMaps;
+ //delete pTable;
+
+ ASSERT( !pPendStack,
+ "SwHTMLParser::~SwHTMLParser: Hier sollte es keinen Pending-Stack mehr geben" );
+ while( pPendStack )
+ {
+ SwPendingStack* pTmp = pPendStack;
+ pPendStack = pPendStack->pNext;
+ delete pTmp->pData;
+ delete pTmp;
+ }
+
+ if( !pDoc->release() )
+ {
+ // keiner will mehr das Doc haben, also weg damit
+ delete pDoc;
+ pDoc = NULL;
+ }
+
+ if ( pTempViewFrame )
+ {
+ pTempViewFrame->DoClose();
+
+ // the temporary view frame is hidden, so the hidden flag might need to be removed
+ if ( bRemoveHidden && pDoc && pDoc->GetDocShell() && pDoc->GetDocShell()->GetMedium() )
+ pDoc->GetDocShell()->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN );
+ }
+}
+
+IMPL_LINK( SwHTMLParser, AsyncCallback, void*, /*pVoid*/ )
+{
+ nEventId=0;
+
+ // --> FME 2005-08-18 #i47907# If the document has already been destructed,
+ // the parser should be aware of this:
+ if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
+ || 1 == pDoc->getReferenceCount() )
+ {
+ // wurde der Import vom SFX abgebrochen?
+ eState = SVPAR_ERROR;
+ }
+ // <--
+
+ GetAsynchCallLink().Call(0);
+ return 0;
+}
+
+SvParserState __EXPORT SwHTMLParser::CallParser()
+{
+ // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt!
+ pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() );
+ if( !IsNewDoc() ) // in ein Dokument einfuegen ?
+ {
+ const SwPosition* pPos = pPam->GetPoint();
+
+ pDoc->SplitNode( *pPos, false );
+
+ *pSttNdIdx = pPos->nNode.GetIndex()-1;
+ pDoc->SplitNode( *pPos, false );
+
+ SwPaM aInsertionRangePam( *pPos );
+
+ pPam->Move( fnMoveBackward );
+
+ // #106634# split any redline over the insertion point
+ aInsertionRangePam.SetMark();
+ *aInsertionRangePam.GetPoint() = *pPam->GetPoint();
+ aInsertionRangePam.Move( fnMoveBackward );
+ pDoc->SplitRedline( aInsertionRangePam );
+
+ pDoc->SetTxtFmtColl( *pPam,
+ pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD ));
+ }
+
+ if( GetMedium() )
+ {
+ if( !bViewCreated )
+ {
+ nEventId = Application::PostUserEvent( LINK( this, SwHTMLParser, AsyncCallback ), 0 );
+ }
+ else
+ {
+ bViewCreated = TRUE;
+ nEventId = 0;
+ }
+ }
+
+ // Laufbalken anzeigen
+ else if( !GetMedium() || !GetMedium()->IsRemote() )
+ {
+ rInput.Seek(STREAM_SEEK_TO_END);
+ rInput.ResetError();
+ ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(),
+ pDoc->GetDocShell() );
+ rInput.Seek(STREAM_SEEK_TO_BEGIN);
+ rInput.ResetError();
+ }
+
+ SwPageDesc& rDesc = pDoc->_GetPageDesc( 0 );
+ rDesc.Add( this );
+
+ SvParserState eRet = HTMLParser::CallParser();
+ return eRet;
+}
+
+void __EXPORT SwHTMLParser::Continue( int nToken )
+{
+#ifdef DBG_UTIL
+ ASSERT( !nContinue, "Continue im Continue - Das sollte doch nicht sein, oder?" );
+ nContinue++;
+#endif
+
+ // Wenn der Import (vom SFX) abgebrochen wurde, wird ein Fehler
+ // gesetzt aber trotzdem noch weiter gemacht, damit vernuenftig
+ // aufgeraeumt wird.
+ ASSERT( SVPAR_ERROR!=eState,
+ "SwHTMLParser::Continue: bereits ein Fehler gesetzt" );
+ if( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
+ eState = SVPAR_ERROR;
+
+ // Die ViewShell vom Dokument holen, merken und als aktuelle setzen.
+ ViewShell *pInitVSh = CallStartAction();
+
+ if( SVPAR_ERROR != eState && GetMedium() && !bViewCreated )
+ {
+ // Beim ersten Aufruf erstmal returnen, Doc anzeigen
+ // und auf Timer Callback warten.
+ // An dieser Stelle wurde im CallParser gerade mal ein Zeichen
+ // gelesen und ein SaveState(0) gerufen.
+ eState = SVPAR_PENDING;
+ bViewCreated = TRUE;
+ pDoc->SetInLoadAsynchron( TRUE );
+
+#ifdef DBG_UTIL
+ nContinue--;
+#endif
+
+ return;
+ }
+
+ bSetModEnabled = FALSE;
+ if( pDoc->GetDocShell() &&
+ 0 != (bSetModEnabled = pDoc->GetDocShell()->IsEnableSetModified()) )
+ {
+ pDoc->GetDocShell()->EnableSetModified( FALSE );
+ }
+
+ // waehrend des einlesens kein OLE-Modified rufen
+ Link aOLELink( pDoc->GetOle2Link() );
+ pDoc->SetOle2Link( Link() );
+
+ BOOL bModified = pDoc->IsModified();
+ BOOL bWasUndo = pDoc->DoesUndo();
+ pDoc->DoUndo( FALSE );
+
+ // Wenn der Import abgebrochen wird, kein Continue mehr rufen.
+ // Falls ein Pending-Stack existiert aber durch einen Aufruf
+ // von NextToken dafuer sorgen, dass der Pending-Stack noch
+ // beendet wird.
+ if( SVPAR_ERROR == eState )
+ {
+ ASSERT( !pPendStack || pPendStack->nToken,
+ "SwHTMLParser::Continue: Pending-Stack ohne Token" );
+ if( pPendStack && pPendStack->nToken )
+ NextToken( pPendStack->nToken );
+ ASSERT( !pPendStack,
+ "SwHTMLParser::Continue: Es gibt wieder einen Pend-Stack" );
+ }
+ else
+ {
+ HTMLParser::Continue( pPendStack ? pPendStack->nToken : nToken );
+ }
+
+ // Laufbalken wieder abschalten
+ EndProgress( pDoc->GetDocShell() );
+
+ BOOL bLFStripped = FALSE;
+ if( SVPAR_PENDING != GetStatus() )
+ {
+ // noch die letzten Attribute setzen
+ {
+ if( aScriptSource.Len() )
+ {
+ SwScriptFieldType *pType =
+ (SwScriptFieldType*)pDoc->GetSysFldType( RES_SCRIPTFLD );
+
+ SwScriptField aFld( pType, aScriptType, aScriptSource,
+ FALSE );
+ InsertAttr( SwFmtFld( aFld ) );
+ }
+
+ if( pAppletImpl )
+ {
+ if( pAppletImpl->GetApplet().is() )
+ EndApplet();
+ else
+ EndObject();
+ }
+
+ // ggf. ein noch vorhandes LF hinter dem letzen Absatz entfernen
+ if( IsNewDoc() )
+ bLFStripped = StripTrailingLF() > 0;
+
+ // noch offene Nummerierungen beenden.
+ while( GetNumInfo().GetNumRule() )
+ EndNumBulList();
+
+ ASSERT( !nContextStMin, "Es gibt geschuetzte Kontexte" );
+ nContextStMin = 0;
+ while( aContexts.Count() )
+ {
+ _HTMLAttrContext *pCntxt = PopContext();
+ if( pCntxt )
+ {
+ EndContext( pCntxt );
+ delete pCntxt;
+ }
+ }
+
+ if( aParaAttrs.Count() )
+ aParaAttrs.Remove( 0, aParaAttrs.Count() );
+
+ SetAttr( FALSE );
+
+ // Noch die erst verzoegert gesetzten Styles setzen
+ pCSS1Parser->SetDelayedStyles();
+ }
+
+ // den Start wieder korrigieren
+ if( !IsNewDoc() && pSttNdIdx->GetIndex() )
+ {
+ SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode();
+ SwNodeIndex aNxtIdx( *pSttNdIdx );
+ if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx ))
+ {
+ xub_StrLen nStt = pTxtNode->GetTxt().Len();
+ // wenn der Cursor noch in dem Node steht, dann setze in an das Ende
+ if( pPam->GetPoint()->nNode == aNxtIdx )
+ {
+ pPam->GetPoint()->nNode = *pSttNdIdx;
+ pPam->GetPoint()->nContent.Assign( pTxtNode, nStt );
+ }
+
+#ifdef DBG_UTIL
+// !!! sollte nicht moeglich sein, oder ??
+ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( TRUE ).nNode.GetIndex(),
+ "Pam.Bound1 steht noch im Node" );
+ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( FALSE ).nNode.GetIndex(),
+ "Pam.Bound2 steht noch im Node" );
+
+if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( TRUE ).nNode.GetIndex() )
+{
+ xub_StrLen nCntPos = pPam->GetBound( TRUE ).nContent.GetIndex();
+ pPam->GetBound( TRUE ).nContent.Assign( pTxtNode,
+ pTxtNode->GetTxt().Len() + nCntPos );
+}
+if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( FALSE ).nNode.GetIndex() )
+{
+ xub_StrLen nCntPos = pPam->GetBound( FALSE ).nContent.GetIndex();
+ pPam->GetBound( FALSE ).nContent.Assign( pTxtNode,
+ pTxtNode->GetTxt().Len() + nCntPos );
+}
+#endif
+ // Zeichen Attribute beibehalten!
+ SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode();
+ if( pTxtNode->GetTxt().Len() )
+ pDelNd->FmtToTxtAttr( pTxtNode );
+ else
+ pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() );
+ pTxtNode->JoinNext();
+ }
+ }
+ }
+
+ if( SVPAR_ACCEPTED == eState )
+ {
+ if( nMissingImgMaps )
+ {
+ // es fehlen noch ein paar Image-Map zuordungen.
+ // vielleicht sind die Image-Maps ja jetzt da?
+ ConnectImageMaps();
+ }
+
+ // jetzt noch den letzten ueberfluessigen Absatz loeschen
+ SwPosition* pPos = pPam->GetPoint();
+ if( !pPos->nContent.GetIndex() && !bLFStripped )
+ {
+ SwTxtNode* pAktNd;
+ ULONG nNodeIdx = pPos->nNode.GetIndex();
+
+ BOOL bHasFlysOrMarks =
+ HasCurrentParaFlys() || HasCurrentParaBookmarks( TRUE );
+
+ if( IsNewDoc() )
+ {
+ const SwNode *pPrev = pDoc->GetNodes()[nNodeIdx -1];
+ if( !pPam->GetPoint()->nContent.GetIndex() &&
+ ( pPrev->IsCntntNode() ||
+ (pPrev->IsEndNode() &&
+ pPrev->StartOfSectionNode()->IsSectionNode()) ) )
+ {
+ SwCntntNode* pCNd = pPam->GetCntntNode();
+ if( pCNd && pCNd->StartOfSectionIndex()+2 <
+ pCNd->EndOfSectionIndex() && !bHasFlysOrMarks )
+ {
+ ViewShell *pVSh = CheckActionViewShell();
+ SwCrsrShell *pCrsrSh = pVSh && pVSh->ISA(SwCrsrShell)
+ ? static_cast < SwCrsrShell * >( pVSh )
+ : 0;
+ if( pCrsrSh &&
+ pCrsrSh->GetCrsr()->GetPoint()
+ ->nNode.GetIndex() == nNodeIdx )
+ {
+ pCrsrSh->MovePara(fnParaPrev, fnParaEnd );
+ pCrsrSh->SetMark();
+ pCrsrSh->ClearMark();
+ }
+ pPam->GetBound(TRUE).nContent.Assign( 0, 0 );
+ pPam->GetBound(FALSE).nContent.Assign( 0, 0 );
+ pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
+ }
+ }
+ }
+ else if( 0 != ( pAktNd = pDoc->GetNodes()[ nNodeIdx ]->GetTxtNode()) && !bHasFlysOrMarks )
+ {
+ if( pAktNd->CanJoinNext( &pPos->nNode ))
+ {
+ SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode();
+ pPos->nContent.Assign( pNextNd, 0 );
+ pPam->SetMark(); pPam->DeleteMark();
+ pNextNd->JoinPrev();
+ }
+ else if( !pAktNd->GetTxt().Len() )
+ {
+ pPos->nContent.Assign( 0, 0 );
+ pPam->SetMark(); pPam->DeleteMark();
+ pDoc->GetNodes().Delete( pPos->nNode, 1 );
+ pPam->Move( fnMoveBackward );
+ }
+ }
+ }
+
+ // nun noch das SplitNode vom Anfang aufheben
+ else if( !IsNewDoc() )
+ {
+ if( pPos->nContent.GetIndex() ) // dann gabs am Ende kein <P>,
+ pPam->Move( fnMoveForward, fnGoNode ); // als zum naechsten Node
+ SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode();
+ SwNodeIndex aPrvIdx( pPos->nNode );
+ if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) &&
+ *pSttNdIdx <= aPrvIdx )
+ {
+ // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor
+ // usw. sind im pTxtNode angemeldet, so dass der bestehen
+ // bleiben MUSS.
+
+ // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die
+ // Absatzattribute und die Vorlage uebernehmen!
+ SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode();
+ pTxtNode->ChgFmtColl( pPrev->GetTxtColl() );
+ pTxtNode->FmtToTxtAttr( pPrev );
+ pTxtNode->ResetAllAttr();
+
+ if( pPrev->HasSwAttrSet() )
+ pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() );
+
+ if( &pPam->GetBound(TRUE).nNode.GetNode() == pPrev )
+ pPam->GetBound(TRUE).nContent.Assign( pTxtNode, 0 );
+ if( &pPam->GetBound(FALSE).nNode.GetNode() == pPrev )
+ pPam->GetBound(FALSE).nContent.Assign( pTxtNode, 0 );
+
+ pTxtNode->JoinPrev();
+ }
+ }
+
+ // und noch die DocumentInfo aufbereiten
+ if( IsNewDoc() )
+ {
+ SwDocShell *pDocShell(pDoc->GetDocShell());
+ DBG_ASSERT(pDocShell, "no SwDocShell");
+ if (pDocShell) {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xDPS->getDocumentProperties());
+ DBG_ASSERT(xDocProps.is(), "DocumentProperties is null");
+ if ( xDocProps.is() && (xDocProps->getAutoloadSecs() > 0) &&
+ xDocProps->getAutoloadURL().equalsAscii("") )
+ {
+ xDocProps->setAutoloadURL(aPathToFile);
+ }
+ }
+ }
+
+ if( bUpdateDocStat )
+ {
+ SwDocStat aStat( pDoc->GetDocStat() );
+ pDoc->UpdateDocStat( aStat );
+ }
+ }
+
+ if( SVPAR_PENDING != GetStatus() )
+ delete pSttNdIdx, pSttNdIdx = 0;
+
+ // sollte der Parser der Letzte sein, der das Doc haelt, dann braucht
+ // man hier auch nichts mehr tun, Doc wird gleich zerstoert!
+ if( 1 < pDoc->getReferenceCount() )
+ {
+ if( bWasUndo )
+ {
+ pDoc->DelAllUndoObj();
+ pDoc->DoUndo( TRUE );
+ }
+ else if( !pInitVSh )
+ {
+ // Wenn zu Beginn des Continue keine Shell vorhanden war,
+ // kann trotzdem mitlerweile eine angelegt worden sein.
+ // In dieses Fall stimmt das bWasUndo-Flag nicht und
+ // wir muessen das Undo noch anschalten.
+ ViewShell *pTmpVSh = CheckActionViewShell();
+ if( pTmpVSh )
+ pDoc->DoUndo( TRUE );
+ }
+
+ pDoc->SetOle2Link( aOLELink );
+ if( !bModified )
+ pDoc->ResetModified();
+ if( bSetModEnabled && pDoc->GetDocShell() )
+ {
+ pDoc->GetDocShell()->EnableSetModified( TRUE );
+ bSetModEnabled = FALSE; // this is unnecessary here
+ }
+ }
+
+
+ // Wenn die Dokuemnt-ViewShell noch existiert und eine Action
+ // offen ist (muss bei Abbruch nicht sein), die Action beenden,
+ // uns von der Shell abmelden und schliesslich die alte Shell
+ // wieder rekonstruieren.
+ CallEndAction( TRUE );
+
+#ifdef DBG_UTIL
+ nContinue--;
+#endif
+}
+
+void SwHTMLParser::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
+{
+ switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 )
+ {
+ case RES_OBJECTDYING:
+ if( ((SwPtrMsgPoolItem *)pOld)->pObject == pRegisteredIn )
+ {
+ // dann uns selbst beenden
+ pRegisteredIn->Remove( this );
+ ReleaseRef(); // ansonsten sind wir fertig!
+ }
+ break;
+ }
+}
+
+void SwHTMLParser::DocumentDetected()
+{
+ ASSERT( !bDocInitalized, "DocumentDetected mehrfach aufgerufen" );
+ bDocInitalized = TRUE;
+ if( IsNewDoc() )
+ {
+ if( IsInHeader() )
+ FinishHeader( TRUE );
+
+ CallEndAction( TRUE, TRUE );
+
+ pDoc->DoUndo( FALSE );
+ // Durch das DocumentDetected wurde im allgemeinen eine
+ // ViewShell angelegt. Es kann aber auch sein, dass sie
+ // erst spaeter angelegt wird, naemlich dann, wenn die UI
+ // gecaptured ist.
+ CallStartAction();
+ }
+}
+
+// wird fuer jedes Token gerufen, das in CallParser erkannt wird
+void __EXPORT SwHTMLParser::NextToken( int nToken )
+{
+ if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
+ || 1 == pDoc->getReferenceCount() )
+ {
+ // wurde der Import vom SFX abgebrochen? Wenn ein Pending-Stack
+ // existiert den noch aufraumen
+ eState = SVPAR_ERROR;
+ ASSERT( !pPendStack || pPendStack->nToken,
+ "SwHTMLParser::NextToken: Pending-Stack ohne Token" );
+ if( 1 == pDoc->getReferenceCount() || !pPendStack )
+ return ;
+ }
+
+#ifdef DBG_UTIL
+ if( pPendStack )
+ {
+ switch( nToken )
+ {
+ // Tabellen werden ueber rekusive Methodenaufrufe gelesen
+ case HTML_TABLE_ON:
+ // Bei CSS-Deklarationen muss evtl. noch auf das
+ // Ende eines File-Downloads gewartet werden.
+ case HTML_LINK:
+ // Bei Controls muss evtl. noch die Groesse gesetzt werden.
+ case HTML_INPUT:
+ case HTML_TEXTAREA_ON:
+ case HTML_SELECT_ON:
+ case HTML_SELECT_OFF:
+ break;
+ default:
+ ASSERT( !pPendStack, "Unbekanntes Token fuer Pending-Stack" );
+ break;
+ }
+ }
+#endif
+
+ // Die folgeneden Spezialfaelle muessen vor der Filter-Detection behandelt
+ // werden, denn der Inhalt des Titels, etc. wird auch in Netcape nicht
+ // zur Filter-Detection herangezogen.
+ if( !pPendStack )
+ {
+ if( bInTitle )
+ {
+ switch( nToken )
+ {
+ case HTML_TITLE_OFF:
+ if( IsNewDoc() && sTitle.Len() )
+ {
+ if( pDoc->GetDocShell() ) {
+ uno::Reference<document::XDocumentPropertiesSupplier>
+ xDPS(pDoc->GetDocShell()->GetModel(),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xDPS->getDocumentProperties());
+ DBG_ASSERT(xDocProps.is(), "no DocumentProperties");
+ if (xDocProps.is()) {
+ xDocProps->setTitle(sTitle);
+ }
+
+ pDoc->GetDocShell()->SetTitle( sTitle );
+ }
+ }
+ bInTitle = FALSE;
+ sTitle.Erase();
+ break;
+
+ case HTML_NONBREAKSPACE:
+ sTitle += ' ';
+ break;
+
+ case HTML_SOFTHYPH:
+ sTitle += '-';
+ break;
+
+ case HTML_TEXTTOKEN:
+ sTitle += aToken;
+ break;
+
+ default:
+ sTitle += '<';
+ if( (HTML_TOKEN_ONOFF & nToken) && (1 & nToken) )
+ sTitle += '/';
+ sTitle += sSaveToken;
+ if( aToken.Len() )
+ {
+ sTitle += ' ';
+ sTitle += aToken;
+ }
+ sTitle += '>';
+ break;
+ }
+
+ return;
+ }
+ }
+
+ // Wenn wir noch nicht wissen, was fuer ein Dokument wir vor uns haben,
+ // versuchen wir das erstmal rauszufinden. Das muss fuer Controls in
+ // Fall vor dem Einfuegen des Controls passieren, weil beim Einfuegen
+ // bereits eine View benoetigt wird.
+ if( !bDocInitalized )
+ DocumentDetected();
+
+ BOOL bGetIDOption = FALSE, bInsertUnknown = FALSE;
+ BOOL bUpperSpaceSave = bUpperSpace;
+ bUpperSpace = FALSE;
+
+ // Die folgenden Speziallfaelle muessen oder koennen nach der
+ // Filter-Detection erfolgen.
+ if( !pPendStack )
+ {
+ if( bInFloatingFrame )
+ {
+ // <SCRIPT> wird hier (von uns) ignoriert, weil es auch in
+ // Applets ignoriert wird!
+ if( HTML_IFRAME_OFF == nToken )
+ {
+ bCallNextToken = FALSE;
+ EndFloatingFrame();
+ }
+
+ return;
+ }
+ else if( bInNoEmbed )
+ {
+ switch( nToken )
+ {
+ case HTML_NOEMBED_OFF:
+ aContents.ConvertLineEnd();
+ InsertComment( aContents, OOO_STRING_SVTOOLS_HTML_noembed );
+ aContents.Erase();
+ bCallNextToken = FALSE;
+ bInNoEmbed = FALSE;
+ break;
+
+ case HTML_RAWDATA:
+ InsertCommentText( OOO_STRING_SVTOOLS_HTML_noembed );
+ break;
+
+ default:
+ ASSERT( !this, "SwHTMLParser::NextToken: ungueltiges Tag" );
+ break;
+ }
+
+ return;
+ }
+ else if( pAppletImpl )
+ {
+ // in einem Applet interessieren uns (erstmal) nur <PARAM>-Tags
+ // und das </APPLET>.
+ // <SCRIPT> wird hier (von Netscape) ignoriert!
+
+ switch( nToken )
+ {
+ case HTML_APPLET_OFF:
+ bCallNextToken = FALSE;
+ EndApplet();
+ break;
+ case HTML_OBJECT_OFF:
+ bCallNextToken = FALSE;
+ EndObject();
+ break;
+
+ case HTML_PARAM:
+ InsertParam();
+ break;
+ }
+
+ return;
+ }
+ else if( bTextArea )
+ {
+ // in einer TextArea wird alles bis zum </TEXTAREA> als Text
+ // eingefuegt
+ // <SCRIPT> wird hier (von Netscape) ignoriert!
+
+ switch( nToken )
+ {
+ case HTML_TEXTAREA_OFF:
+ bCallNextToken = FALSE;
+ EndTextArea();
+ break;
+
+ default:
+ InsertTextAreaText( static_cast< sal_uInt16 >(nToken) );
+ break;
+ }
+
+ return;
+ }
+ else if( bSelect )
+ {
+ // MUSS nach bNoScript kommen!
+ switch( nToken )
+ {
+ case HTML_SELECT_OFF:
+ bCallNextToken = FALSE;
+ EndSelect();
+ return;
+
+ case HTML_OPTION:
+ InsertSelectOption();
+ return;
+
+ case HTML_TEXTTOKEN:
+ InsertSelectText();
+ return;
+
+ case HTML_INPUT:
+ case HTML_SCRIPT_ON:
+ case HTML_SCRIPT_OFF:
+ case HTML_NOSCRIPT_ON:
+ case HTML_NOSCRIPT_OFF:
+ case HTML_RAWDATA:
+ // im normalen switch bahandeln
+ break;
+
+ default:
+ // ignorieren
+ return;
+ }
+ }
+ else if( pMarquee )
+ {
+ // in einer TextArea wird alles bis zum </TEXTAREA> als Text
+ // eingefuegt
+ // Die <SCRIPT>-Tags werden vom MS-IE ignoriert, von uns das
+ // geasmte Script
+ switch( nToken )
+ {
+ case HTML_MARQUEE_OFF:
+ bCallNextToken = FALSE;
+ EndMarquee();
+ break;
+
+ case HTML_TEXTTOKEN:
+ InsertMarqueeText();
+ break;
+ }
+
+ return;
+ }
+ else if( bInField )
+ {
+ switch( nToken )
+ {
+ case HTML_SDFIELD_OFF:
+ bCallNextToken = FALSE;
+ EndField();
+ break;
+
+ case HTML_TEXTTOKEN:
+ InsertFieldText();
+ break;
+ }
+
+ return;
+ }
+ else if( bInFootEndNoteAnchor || bInFootEndNoteSymbol )
+ {
+ switch( nToken )
+ {
+ case HTML_ANCHOR_OFF:
+ EndAnchor();
+ bCallNextToken = FALSE;
+ break;
+
+ case HTML_TEXTTOKEN:
+ InsertFootEndNoteText();
+ break;
+ }
+ return;
+ }
+ else if( aUnknownToken.Len() )
+ {
+ // Unbekannte Token im Header werden nur durch ein passendes
+ // End-Token, </HEAD> oder <BODY> wieder beendet. Darin wird Text
+ // ignoriert.
+ switch( nToken )
+ {
+ case HTML_UNKNOWNCONTROL_OFF:
+ if( aUnknownToken.CompareTo(sSaveToken) != COMPARE_EQUAL )
+ return;
+ case HTML_FRAMESET_ON:
+ case HTML_HEAD_OFF:
+ case HTML_BODY_ON:
+ case HTML_IMAGE: // Warum auch immer Netscape das tut.
+ aUnknownToken.Erase();
+ break;
+ case HTML_TEXTTOKEN:
+ return;
+ default:
+ break;
+ }
+ }
+ }
+
+ switch( nToken )
+ {
+ case HTML_BODY_ON:
+ if( aStyleSource.Len() )
+ {
+ pCSS1Parser->ParseStyleSheet( aStyleSource );
+ aStyleSource.Erase();
+ }
+ if( IsNewDoc() )
+ {
+ InsertBodyOptions();
+ // Falls es eine Vorlage fuer die erste oder rechte Seite gibt,
+ // setzen wir die hier.
+ const SwPageDesc *pPageDesc = 0;
+ if( pCSS1Parser->IsSetFirstPageDesc() )
+ pPageDesc = pCSS1Parser->GetFirstPageDesc();
+ else if( pCSS1Parser->IsSetRightPageDesc() )
+ pPageDesc = pCSS1Parser->GetRightPageDesc();
+
+ if( pPageDesc )
+ {
+ pDoc->InsertPoolItem( *pPam, SwFmtPageDesc( pPageDesc ), 0 );
+ }
+ }
+ break;
+
+ case HTML_LINK:
+ InsertLink();
+ break;
+
+ case HTML_BASE:
+ {
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[ --i ];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_HREF:
+ sBaseURL = pOption->GetString();
+ break;
+ case HTML_O_TARGET:
+ if( IsNewDoc() )
+ {
+ SwDocShell *pDocShell(pDoc->GetDocShell());
+ DBG_ASSERT(pDocShell, "no SwDocShell");
+ if (pDocShell) {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties>
+ xDocProps(xDPS->getDocumentProperties());
+ DBG_ASSERT(xDocProps.is(),"no DocumentProperties");
+ if (xDocProps.is()) {
+ xDocProps->setDefaultTarget(
+ pOption->GetString());
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ break;
+
+ case HTML_META:
+ {
+ SvKeyValueIterator *pHTTPHeader = 0;
+ if( IsNewDoc() )
+ {
+ SwDocShell *pDocSh = pDoc->GetDocShell();
+ if( pDocSh )
+ pHTTPHeader = pDocSh->GetHeaderAttributes();
+ }
+ SwDocShell *pDocShell(pDoc->GetDocShell());
+ DBG_ASSERT(pDocShell, "no SwDocShell");
+ if (pDocShell)
+ {
+ uno::Reference<document::XDocumentProperties> xDocProps;
+ if (IsNewDoc())
+ {
+ const uno::Reference<document::XDocumentPropertiesSupplier>
+ xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ xDocProps = xDPS->getDocumentProperties();
+ DBG_ASSERT(xDocProps.is(), "DocumentProperties is null");
+ }
+ ParseMetaOptions( xDocProps, pHTTPHeader );
+ }
+ }
+ break;
+
+ case HTML_TITLE_ON:
+ bInTitle = TRUE;
+ break;
+
+ case HTML_SCRIPT_ON:
+ NewScript();
+ break;
+
+ case HTML_SCRIPT_OFF:
+ EndScript();
+ break;
+
+ case HTML_NOSCRIPT_ON:
+ case HTML_NOSCRIPT_OFF:
+ bInsertUnknown = TRUE;
+ break;
+
+ case HTML_STYLE_ON:
+ NewStyle();
+ break;
+
+ case HTML_STYLE_OFF:
+ EndStyle();
+ break;
+
+ case HTML_RAWDATA:
+ if( !bIgnoreRawData )
+ {
+ if( IsReadScript() )
+ {
+ AddScriptSource();
+ }
+ else if( IsReadStyle() )
+ {
+ if( aStyleSource.Len() )
+ aStyleSource += '\n';
+ aStyleSource += aToken;
+ }
+ }
+ break;
+
+ case HTML_OBJECT_ON:
+#ifdef SOLAR_JAVA
+ NewObject();
+ bCallNextToken = pAppletImpl!=0 && pTable!=0;
+#endif
+ break;
+
+ case HTML_APPLET_ON:
+#ifdef SOLAR_JAVA
+ InsertApplet();
+ bCallNextToken = pAppletImpl!=0 && pTable!=0;
+#endif
+ break;
+
+ case HTML_IFRAME_ON:
+ InsertFloatingFrame();
+ bCallNextToken = bInFloatingFrame && pTable!=0;
+ break;
+
+ case HTML_LINEBREAK:
+ if( !IsReadPRE() )
+ {
+ InsertLineBreak();
+ break;
+ }
+ else
+ bGetIDOption = TRUE;
+ // <BR>s in <PRE> aehneln echten LFs, deshalb kein break
+
+ case HTML_NEWPARA:
+ // CR in PRE/LISTING/XMP
+ {
+ if( HTML_NEWPARA==nToken ||
+ pPam->GetPoint()->nContent.GetIndex() )
+ {
+ AppendTxtNode(); // lf gibts hier nicht, deshalb unkritisch
+ SetTxtCollAttrs();
+ }
+ // Laufbalkenanzeige
+ if( !GetMedium() || !GetMedium()->IsRemote() )
+ ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
+ }
+ break;
+
+ case HTML_NONBREAKSPACE:
+ pDoc->InsertString( *pPam, CHAR_HARDBLANK );
+ break;
+
+ case HTML_SOFTHYPH:
+ pDoc->InsertString( *pPam, CHAR_SOFTHYPHEN );
+ break;
+
+ case HTML_LINEFEEDCHAR:
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode();
+ if( !pTable && !pDoc->IsInHeaderFooter( pPam->GetPoint()->nNode ) )
+ {
+ NewAttr( &aAttrTab.pBreak, SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK) );
+ EndAttr( aAttrTab.pBreak, 0, FALSE );
+ }
+ break;
+
+ case HTML_TEXTTOKEN:
+ // dann fuege den String ein, ohne das Attribute am Ende
+ // aufgespannt werden.
+ if( aToken.Len() && ' '==aToken.GetChar(0) && !IsReadPRE() )
+ {
+ xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
+ if( nPos )
+ {
+ const String& rText =
+ pDoc->GetNodes()[ pPam->GetPoint()->nNode ]->GetTxtNode()
+ ->GetTxt();
+ sal_Unicode cLast = rText.GetChar(--nPos);
+ if( ' ' == cLast || '\x0a' == cLast)
+ aToken.Erase(0,1);
+ }
+ else
+ aToken.Erase(0,1);
+
+ if( !aToken.Len() )
+ {
+ bUpperSpace = bUpperSpaceSave;
+ break;
+ }
+ }
+
+ if( aToken.Len() )
+ {
+ if( !bDocInitalized )
+ DocumentDetected();
+ pDoc->InsertString( *pPam, aToken );
+
+ // wenn es noch vorlaefige Absatz-Attribute gibt, der Absatz aber
+ // nicht leer ist, dann sind die Absatz-Attribute entgueltig.
+ if( aParaAttrs.Count() )
+ aParaAttrs.Remove( 0, aParaAttrs.Count() );
+
+ SetAttr();
+ }
+ break;
+
+ case HTML_HORZRULE:
+ InsertHorzRule();
+ break;
+
+ case HTML_IMAGE:
+ InsertImage();
+ // sollte der Parser der Letzte sein, der das Doc haelt, dann kann
+ // man hier abbrechen und einen Fehler setzen.
+ if( 1 == pDoc->getReferenceCount() )
+ {
+ eState = SVPAR_ERROR;
+ }
+ break;
+
+ case HTML_SPACER:
+ InsertSpacer();
+ break;
+
+ case HTML_EMBED:
+ InsertEmbed();
+ break;
+
+ case HTML_NOEMBED_ON:
+ bInNoEmbed = TRUE;
+ bCallNextToken = pTable!=0;
+ ReadRawData( OOO_STRING_SVTOOLS_HTML_noembed );
+ break;
+
+ case HTML_DEFLIST_ON:
+ if( nOpenParaToken )
+ EndPara();
+ NewDefList();
+ break;
+ case HTML_DEFLIST_OFF:
+ if( nOpenParaToken )
+ EndPara();
+ EndDefListItem( 0, FALSE, 1==nDefListDeep );
+ EndDefList();
+ break;
+
+ case HTML_DD_ON:
+ case HTML_DT_ON:
+ if( nOpenParaToken )
+ EndPara();
+ EndDefListItem( 0, FALSE );// <DD>/<DT> beenden und keine Vorl. setzen
+ NewDefListItem( nToken );
+ break;
+
+ case HTML_DD_OFF:
+ case HTML_DT_OFF:
+ // siehe HTML_LI_OFF
+ // eigentlich muesste man ein DD/DT jetzt beenden. Da aber sowhl
+ // Netscape als auch Microsoft das nicht tun, machen wir das eben
+ // auch nicht.
+ EndDefListItem( nToken, FALSE );
+ break;
+
+ // Bereiche
+ case HTML_DIVISION_ON:
+ case HTML_CENTER_ON:
+ if( nOpenParaToken )
+ {
+ if( IsReadPRE() )
+ nOpenParaToken = 0;
+ else
+ EndPara();
+ }
+ NewDivision( nToken );
+ break;
+
+ case HTML_DIVISION_OFF:
+ case HTML_CENTER_OFF:
+ if( nOpenParaToken )
+ {
+ if( IsReadPRE() )
+ nOpenParaToken = 0;
+ else
+ EndPara();
+ }
+ EndDivision( nToken );
+ break;
+
+ case HTML_MULTICOL_ON:
+ if( nOpenParaToken )
+ EndPara();
+ NewMultiCol();
+ break;
+
+ case HTML_MULTICOL_OFF:
+ if( nOpenParaToken )
+ EndPara();
+ EndTag( HTML_MULTICOL_ON );
+ break;
+
+ case HTML_MARQUEE_ON:
+ NewMarquee();
+ bCallNextToken = pMarquee!=0 && pTable!=0;
+ break;
+
+ case HTML_FORM_ON:
+ NewForm();
+ break;
+ case HTML_FORM_OFF:
+ EndForm();
+ break;
+
+ // Vorlagen:
+ case HTML_PARABREAK_ON:
+ if( nOpenParaToken )
+ EndPara( TRUE );
+ NewPara();
+ break;
+
+ case HTML_PARABREAK_OFF:
+ EndPara( TRUE );
+ break;
+
+ case HTML_ADDRESS_ON:
+ if( nOpenParaToken )
+ EndPara();
+ NewTxtFmtColl( HTML_ADDRESS_ON, RES_POOLCOLL_SENDADRESS );
+ break;
+
+ case HTML_ADDRESS_OFF:
+ if( nOpenParaToken )
+ EndPara();
+ EndTxtFmtColl( HTML_ADDRESS_OFF );
+ break;
+
+ case HTML_BLOCKQUOTE_ON:
+ case HTML_BLOCKQUOTE30_ON:
+ if( nOpenParaToken )
+ EndPara();
+ NewTxtFmtColl( HTML_BLOCKQUOTE_ON, RES_POOLCOLL_HTML_BLOCKQUOTE );
+ break;
+
+ case HTML_BLOCKQUOTE_OFF:
+ case HTML_BLOCKQUOTE30_OFF:
+ if( nOpenParaToken )
+ EndPara();
+ EndTxtFmtColl( HTML_BLOCKQUOTE_ON );
+ break;
+
+ case HTML_PREFORMTXT_ON:
+ case HTML_LISTING_ON:
+ case HTML_XMP_ON:
+ if( nOpenParaToken )
+ EndPara();
+ NewTxtFmtColl( nToken, RES_POOLCOLL_HTML_PRE );
+ break;
+
+ case HTML_PREFORMTXT_OFF:
+ bNoParSpace = TRUE; // der letzte PRE-Absatz muss einen Zeilenabstand bekommen
+ EndTxtFmtColl( HTML_PREFORMTXT_OFF );
+ break;
+
+ case HTML_LISTING_OFF:
+ case HTML_XMP_OFF:
+ EndTxtFmtColl( nToken );
+ break;
+
+ case HTML_HEAD1_ON:
+ case HTML_HEAD2_ON:
+ case HTML_HEAD3_ON:
+ case HTML_HEAD4_ON:
+ case HTML_HEAD5_ON:
+ case HTML_HEAD6_ON:
+ if( nOpenParaToken )
+ {
+ if( IsReadPRE() )
+ nOpenParaToken = 0;
+ else
+ EndPara();
+ }
+ NewHeading( nToken );
+ break;
+
+ case HTML_HEAD1_OFF:
+ case HTML_HEAD2_OFF:
+ case HTML_HEAD3_OFF:
+ case HTML_HEAD4_OFF:
+ case HTML_HEAD5_OFF:
+ case HTML_HEAD6_OFF:
+ EndHeading();
+ break;
+
+ case HTML_TABLE_ON:
+ if( pPendStack )
+ BuildTable( SVX_ADJUST_END );
+ else
+ {
+ if( nOpenParaToken )
+ EndPara();
+ ASSERT( !pTable, "Tabelle in Tabelle darf hier nicht vorkommen" );
+ if( !pTable && (IsNewDoc() || !pPam->GetNode()->FindTableNode()) &&
+ (pPam->GetPoint()->nNode.GetIndex() >
+ pDoc->GetNodes().GetEndOfExtras().GetIndex() ||
+ !pPam->GetNode()->FindFootnoteStartNode() ) )
+ {
+ if ( nParaCnt < 5 )
+ Show(); // bis hierhin schon mal anzeigen
+
+ SvxAdjust eAdjust = aAttrTab.pAdjust
+ ? ((const SvxAdjustItem&)aAttrTab.pAdjust->GetItem()).
+ GetAdjust()
+ : SVX_ADJUST_END;
+ BuildTable( eAdjust );
+ }
+ else
+ bInsertUnknown = bKeepUnknown;
+ }
+ break;
+
+ // Listen
+ case HTML_DIRLIST_ON:
+ case HTML_MENULIST_ON:
+ case HTML_ORDERLIST_ON:
+ case HTML_UNORDERLIST_ON:
+ if( nOpenParaToken )
+ EndPara();
+ NewNumBulList( nToken );
+ break;
+
+ case HTML_DIRLIST_OFF:
+ case HTML_MENULIST_OFF:
+ case HTML_ORDERLIST_OFF:
+ case HTML_UNORDERLIST_OFF:
+ if( nOpenParaToken )
+ EndPara();
+ EndNumBulListItem( 0, TRUE, GetNumInfo().GetDepth()==1 );
+ EndNumBulList( nToken );
+ break;
+
+ case HTML_LI_ON:
+ case HTML_LISTHEADER_ON:
+ if( nOpenParaToken &&
+ (pPam->GetPoint()->nContent.GetIndex()
+ || HTML_PARABREAK_ON==nOpenParaToken) )
+ {
+ // nure bei <P><LI> den Absatz beenden, aber nicht bei <DD><LI>
+ EndPara();
+ }
+
+ EndNumBulListItem( 0, FALSE );// <LI>/<LH> beenden und keine Vorl. setzen
+ NewNumBulListItem( nToken );
+ break;
+
+ case HTML_LI_OFF:
+ case HTML_LISTHEADER_OFF:
+ EndNumBulListItem( nToken, FALSE );
+ break;
+
+ // Attribute :
+ case HTML_ITALIC_ON:
+ {
+ SvxPostureItem aPosture( ITALIC_NORMAL, RES_CHRATR_POSTURE );
+ SvxPostureItem aPostureCJK( ITALIC_NORMAL, RES_CHRATR_CJK_POSTURE );
+ SvxPostureItem aPostureCTL( ITALIC_NORMAL, RES_CHRATR_CTL_POSTURE );
+ NewStdAttr( HTML_ITALIC_ON,
+ &aAttrTab.pItalic, aPosture,
+ &aAttrTab.pItalicCJK, &aPostureCJK,
+ &aAttrTab.pItalicCTL, &aPostureCTL );
+ }
+ break;
+
+ case HTML_BOLD_ON:
+ {
+ SvxWeightItem aWeight( WEIGHT_BOLD, RES_CHRATR_WEIGHT );
+ SvxWeightItem aWeightCJK( WEIGHT_BOLD, RES_CHRATR_CJK_WEIGHT );
+ SvxWeightItem aWeightCTL( WEIGHT_BOLD, RES_CHRATR_CTL_WEIGHT );
+ NewStdAttr( HTML_BOLD_ON,
+ &aAttrTab.pBold, aWeight,
+ &aAttrTab.pBoldCJK, &aWeightCJK,
+ &aAttrTab.pBoldCTL, &aWeightCTL );
+ }
+ break;
+
+
+ case HTML_STRIKE_ON:
+ case HTML_STRIKETHROUGH_ON:
+ {
+ NewStdAttr( HTML_STRIKE_ON, &aAttrTab.pStrike,
+ SvxCrossedOutItem(STRIKEOUT_SINGLE, RES_CHRATR_CROSSEDOUT) );
+ }
+ break;
+
+ case HTML_UNDERLINE_ON:
+ {
+ NewStdAttr( HTML_UNDERLINE_ON, &aAttrTab.pUnderline,
+ SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE) );
+ }
+ break;
+
+ case HTML_SUPERSCRIPT_ON:
+ {
+ NewStdAttr( HTML_SUPERSCRIPT_ON, &aAttrTab.pEscapement,
+ SvxEscapementItem(HTML_ESC_SUPER,HTML_ESC_PROP, RES_CHRATR_ESCAPEMENT) );
+ }
+ break;
+
+ case HTML_SUBSCRIPT_ON:
+ {
+ NewStdAttr( HTML_SUBSCRIPT_ON, &aAttrTab.pEscapement,
+ SvxEscapementItem(HTML_ESC_SUB,HTML_ESC_PROP, RES_CHRATR_ESCAPEMENT) );
+ }
+ break;
+
+ case HTML_BLINK_ON:
+ {
+ NewStdAttr( HTML_BLINK_ON, &aAttrTab.pBlink,
+ SvxBlinkItem( TRUE, RES_CHRATR_BLINK ) );
+ }
+ break;
+
+ case HTML_SPAN_ON:
+ NewStdAttr( HTML_SPAN_ON );
+ break;
+
+
+ case HTML_ITALIC_OFF:
+ case HTML_BOLD_OFF:
+ case HTML_STRIKE_OFF:
+ case HTML_UNDERLINE_OFF:
+ case HTML_SUPERSCRIPT_OFF:
+ case HTML_SUBSCRIPT_OFF:
+ case HTML_BLINK_OFF:
+ case HTML_SPAN_OFF:
+ EndTag( nToken );
+ break;
+
+ case HTML_STRIKETHROUGH_OFF:
+ EndTag( HTML_STRIKE_OFF );
+ break;
+
+ case HTML_BASEFONT_ON:
+ NewBasefontAttr();
+ break;
+ case HTML_BASEFONT_OFF:
+ EndBasefontAttr();
+ break;
+ case HTML_FONT_ON:
+ case HTML_BIGPRINT_ON:
+ case HTML_SMALLPRINT_ON:
+ NewFontAttr( nToken );
+ break;
+ case HTML_FONT_OFF:
+ case HTML_BIGPRINT_OFF:
+ case HTML_SMALLPRINT_OFF:
+ EndFontAttr( nToken );
+ break;
+
+ case HTML_EMPHASIS_ON:
+ case HTML_CITIATION_ON:
+ case HTML_STRONG_ON:
+ case HTML_CODE_ON:
+ case HTML_SAMPLE_ON:
+ case HTML_KEYBOARD_ON:
+ case HTML_VARIABLE_ON:
+ case HTML_DEFINSTANCE_ON:
+ case HTML_SHORTQUOTE_ON:
+ case HTML_LANGUAGE_ON:
+ case HTML_AUTHOR_ON:
+ case HTML_PERSON_ON:
+ case HTML_ACRONYM_ON:
+ case HTML_ABBREVIATION_ON:
+ case HTML_INSERTEDTEXT_ON:
+ case HTML_DELETEDTEXT_ON:
+
+ case HTML_TELETYPE_ON:
+ NewCharFmt( nToken );
+ break;
+
+ case HTML_SDFIELD_ON:
+ NewField();
+ bCallNextToken = bInField && pTable!=0;
+ break;
+
+ case HTML_EMPHASIS_OFF:
+ case HTML_CITIATION_OFF:
+ case HTML_STRONG_OFF:
+ case HTML_CODE_OFF:
+ case HTML_SAMPLE_OFF:
+ case HTML_KEYBOARD_OFF:
+ case HTML_VARIABLE_OFF:
+ case HTML_DEFINSTANCE_OFF:
+ case HTML_SHORTQUOTE_OFF:
+ case HTML_LANGUAGE_OFF:
+ case HTML_AUTHOR_OFF:
+ case HTML_PERSON_OFF:
+ case HTML_ACRONYM_OFF:
+ case HTML_ABBREVIATION_OFF:
+ case HTML_INSERTEDTEXT_OFF:
+ case HTML_DELETEDTEXT_OFF:
+
+ case HTML_TELETYPE_OFF:
+ EndTag( nToken );
+ break;
+
+ case HTML_HEAD_OFF:
+ if( aStyleSource.Len() )
+ {
+ pCSS1Parser->ParseStyleSheet( aStyleSource );
+ aStyleSource.Erase();
+ }
+ break;
+
+ case HTML_DOCTYPE:
+ case HTML_BODY_OFF:
+ case HTML_HTML_OFF:
+ case HTML_HEAD_ON:
+ case HTML_TITLE_OFF:
+ break; // nicht weiter auswerten, oder???
+ case HTML_HTML_ON:
+ {
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[ --i ];
+ if( HTML_O_DIR == pOption->GetToken() )
+ {
+ const String& rDir = pOption->GetString();
+ SfxItemSet aItemSet( pDoc->GetAttrPool(),
+ pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+ String aDummy;
+ ParseStyleOptions( aDummy, aDummy, aDummy, aItemSet,
+ aPropInfo, 0, &rDir );
+
+ pCSS1Parser->SetPageDescAttrs( 0, &aItemSet );
+ break;
+ }
+ }
+ }
+ break;
+
+ case HTML_INPUT:
+ InsertInput();
+ break;
+
+ case HTML_TEXTAREA_ON:
+ NewTextArea();
+ bCallNextToken = bTextArea && pTable!=0;
+ break;
+
+ case HTML_SELECT_ON:
+ NewSelect();
+ bCallNextToken = bSelect && pTable!=0;
+ break;
+
+ case HTML_ANCHOR_ON:
+ NewAnchor();
+ break;
+
+ case HTML_ANCHOR_OFF:
+ EndAnchor();
+ break;
+
+ case HTML_COMMENT:
+ if( ( aToken.Len() > 5 ) && ( ! bIgnoreHTMLComments ) )
+ {
+ // als Post-It einfuegen
+ // MIB 8.12.2000: If there are no space characters right behind
+ // the <!-- and on front of the -->, leave the comment untouched.
+ if( ' ' == aToken.GetChar( 3 ) &&
+ ' ' == aToken.GetChar( aToken.Len()-3 ) )
+ {
+ String aComment( aToken.Copy( 3, aToken.Len()-5 ) );
+ aComment.EraseLeadingChars().EraseTrailingChars();
+ InsertComment( aComment );
+ }
+ else
+ {
+ String aComment( '<' );
+ (aComment += aToken) += '>';
+ InsertComment( aComment );
+ }
+ }
+ break;
+
+ case HTML_MAP_ON:
+ // Image Maps werden asynchron gelesen: Zunaechst wird nur eine
+ // ImageMap angelegt. Die Bereiche kommen spaeter. Trozdem wird
+ // die ImageMap schon in das IMap-Array eingetragen, denn sie
+ // koennte ja schon verwendet werden.
+ pImageMap = new ImageMap;
+ if( ParseMapOptions( pImageMap) )
+ {
+ if( !pImageMaps )
+ pImageMaps = new ImageMaps;
+ pImageMaps->Insert( pImageMap, pImageMaps->Count() );
+ }
+ else
+ {
+ delete pImageMap;
+ pImageMap = 0;
+ }
+ break;
+
+ case HTML_MAP_OFF:
+ // jetzt gibt es keine ImageMap mehr (IMap nicht Loeschen, denn
+ // die stckt ja schon in dem Array!)
+ pImageMap = 0;
+ break;
+
+ case HTML_AREA:
+ if( pImageMap )
+ ParseAreaOptions( pImageMap, sBaseURL, SFX_EVENT_MOUSEOVER_OBJECT,
+ SFX_EVENT_MOUSEOUT_OBJECT );
+ break;
+
+ case HTML_FRAMESET_ON:
+ bInsertUnknown = bKeepUnknown;
+ break;
+
+ case HTML_NOFRAMES_ON:
+ if( IsInHeader() )
+ FinishHeader( TRUE );
+ bInsertUnknown = bKeepUnknown;
+ break;
+
+ case HTML_UNKNOWNCONTROL_ON:
+ // Im Header muss der Inhalt von unbekannten Token ignoriert werden,
+ // es sei denn, das Token faengt mit einem '!' an.
+ if( IsInHeader() && !IsReadPRE() && !aUnknownToken.Len() &&
+ sSaveToken.Len() && '!' != sSaveToken.GetChar(0) &&
+ '%' != sSaveToken.GetChar(0) )
+ aUnknownToken = sSaveToken;
+ // kein break
+
+ default:
+ bInsertUnknown = bKeepUnknown;
+ break;
+ }
+
+ if( bGetIDOption )
+ InsertIDOption();
+
+ if( bInsertUnknown )
+ {
+ String aComment(
+ String::CreateFromAscii(TOOLS_CONSTASCII_STRINGPARAM("HTML: <")) );
+ if( (HTML_TOKEN_ONOFF & nToken) != 0 && (1 & nToken) != 0 )
+ aComment += '/';
+ aComment += sSaveToken;
+ if( aToken.Len() )
+ {
+ UnescapeToken();
+ (aComment += ' ') += aToken;
+ }
+ aComment += '>';
+ InsertComment( aComment );
+ }
+
+ // wenn es noch vorlaefige Absatz-Attribute gibt, der Absatz aber
+ // nicht leer ist, dann sind die Absatz-Attribute entgueltig.
+ if( aParaAttrs.Count() && pPam->GetPoint()->nContent.GetIndex() )
+ aParaAttrs.Remove( 0, aParaAttrs.Count() );
+}
+
+/* */
+
+extern BOOL lcl_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 );
+
+void lcl_swhtml_getItemInfo( const _HTMLAttr& rAttr,
+ sal_Bool& rScriptDependent, sal_Bool& rFont,
+ sal_uInt16& rScriptType )
+{
+ sal_uInt16 nWhich = rAttr.GetItem().Which();
+ switch( nWhich )
+ {
+ case RES_CHRATR_FONT:
+ rFont = sal_True;
+ case RES_CHRATR_FONTSIZE:
+ case RES_CHRATR_LANGUAGE:
+ case RES_CHRATR_POSTURE:
+ case RES_CHRATR_WEIGHT:
+ rScriptType = i18n::ScriptType::LATIN;
+ rScriptDependent = sal_True;
+ break;
+ case RES_CHRATR_CJK_FONT:
+ rFont = sal_True;
+ case RES_CHRATR_CJK_FONTSIZE:
+ case RES_CHRATR_CJK_LANGUAGE:
+ case RES_CHRATR_CJK_POSTURE:
+ case RES_CHRATR_CJK_WEIGHT:
+ rScriptType = i18n::ScriptType::ASIAN;
+ rScriptDependent = sal_True;
+ break;
+ case RES_CHRATR_CTL_FONT:
+ rFont = sal_True;
+ case RES_CHRATR_CTL_FONTSIZE:
+ case RES_CHRATR_CTL_LANGUAGE:
+ case RES_CHRATR_CTL_POSTURE:
+ case RES_CHRATR_CTL_WEIGHT:
+ rScriptType = i18n::ScriptType::COMPLEX;
+ rScriptDependent = sal_True;
+ break;
+ default:
+ rScriptDependent = sal_False;
+ rFont = sal_False;
+ break;
+ }
+}
+
+BOOL SwHTMLParser::AppendTxtNode( SwHTMLAppendMode eMode, BOOL bUpdateNum )
+{
+ // Ein harter Zeilen-Umbruch am Ende muss immer entfernt werden.
+ // Einen zweiten ersetzen wir durch einen Absatz-Abstand.
+ xub_StrLen nLFStripped = StripTrailingLF();
+ if( (AM_NOSPACE==eMode || AM_SOFTNOSPACE==eMode) && nLFStripped > 1 )
+ eMode = AM_SPACE;
+
+ // die harten Attribute an diesem Absatz werden nie mehr ungueltig
+ if( aParaAttrs.Count() )
+ aParaAttrs.Remove( 0, aParaAttrs.Count() );
+
+ if( AM_SPACE==eMode || AM_NOSPACE==eMode )
+ {
+ SwTxtNode *pTxtNode =
+ pDoc->GetNodes()[pPam->GetPoint()->nNode]->GetTxtNode();
+
+ const SvxULSpaceItem& rULSpace =
+ (const SvxULSpaceItem&)pTxtNode->SwCntntNode::GetAttr( RES_UL_SPACE );
+
+ BOOL bChange = AM_NOSPACE==eMode ? rULSpace.GetLower() > 0
+ : rULSpace.GetLower() == 0;
+
+ if( bChange )
+ {
+ const SvxULSpaceItem& rCollULSpace =
+ pTxtNode->GetAnyFmtColl().GetULSpace();
+
+ BOOL bMayReset = AM_NOSPACE==eMode ? rCollULSpace.GetLower() == 0
+ : rCollULSpace.GetLower() > 0;
+
+ if( bMayReset &&
+ rCollULSpace.GetUpper() == rULSpace.GetUpper() )
+ {
+ pTxtNode->ResetAttr( RES_UL_SPACE );
+ }
+ else
+ {
+ pTxtNode->SetAttr(
+ SvxULSpaceItem( rULSpace.GetUpper(),
+ AM_NOSPACE==eMode ? 0 : HTML_PARSPACE, RES_UL_SPACE ) );
+ }
+ }
+ }
+ bNoParSpace = AM_NOSPACE==eMode || AM_SOFTNOSPACE==eMode;
+
+ SwPosition aOldPos( *pPam->GetPoint() );
+
+ BOOL bRet = pDoc->AppendTxtNode( *pPam->GetPoint() );
+
+ // Zeichen-Attribute aufspalten und ggf keine setzen, die ueber den
+ // ganzen Absatz gesetzt sind
+ const SwNodeIndex& rEndIdx = aOldPos.nNode;
+ xub_StrLen nEndCnt = aOldPos.nContent.GetIndex();
+ const SwPosition& rPos = *pPam->GetPoint();
+
+ _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
+ for( USHORT nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
+ nCnt--; ++pTbl )
+ {
+ _HTMLAttr *pAttr = *pTbl;
+ if( pAttr && pAttr->GetItem().Which() < RES_PARATR_BEGIN )
+ {
+ BOOL bWholePara = FALSE;
+
+ while( pAttr )
+ {
+ _HTMLAttr *pNext = pAttr->GetNext();
+ if( pAttr->GetSttParaIdx() < rEndIdx.GetIndex() ||
+ (!bWholePara &&
+ pAttr->GetSttPara() == rEndIdx &&
+ pAttr->GetSttCnt() != nEndCnt) )
+ {
+ bWholePara =
+ pAttr->GetSttPara() == rEndIdx &&
+ pAttr->GetSttCnt() == 0;
+
+ xub_StrLen nStt = pAttr->nSttCntnt;
+ sal_Bool bScript = sal_False, bFont = sal_False;
+ sal_uInt16 nScriptItem;
+ sal_Bool bInsert = sal_True;
+ lcl_swhtml_getItemInfo( *pAttr, bScript, bFont,
+ nScriptItem );
+ // den besehrigen Teil setzen
+ if( bInsert && bScript )
+ {
+ const SwTxtNode *pTxtNd =
+ pAttr->GetSttPara().GetNode().GetTxtNode();
+ ASSERT( pTxtNd, "No text node" );
+ if( pTxtNd )
+ {
+ const String& rText = pTxtNd->GetTxt();
+ sal_uInt16 nScriptTxt =
+ pBreakIt->GetBreakIter()->getScriptType(
+ rText, pAttr->GetSttCnt() );
+ xub_StrLen nScriptEnd = (xub_StrLen)pBreakIt->GetBreakIter()
+ ->endOfScript( rText, nStt, nScriptTxt );
+ while( nScriptEnd < nEndCnt )
+ {
+ if( nScriptItem == nScriptTxt )
+ {
+ _HTMLAttr *pSetAttr =
+ pAttr->Clone( rEndIdx, nScriptEnd );
+ pSetAttr->nSttCntnt = nStt;
+ pSetAttr->ClearPrev();
+ if( !pNext || bWholePara )
+ {
+ USHORT nTmp = pSetAttr->bInsAtStart ? 0
+ : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pSetAttr, nTmp );
+ }
+ else
+ pNext->InsertPrev( pSetAttr );
+ }
+ nStt = nScriptEnd;
+ nScriptTxt = pBreakIt->GetBreakIter()->getScriptType(
+ rText, nStt );
+ nScriptEnd = (xub_StrLen)pBreakIt->GetBreakIter()
+ ->endOfScript( rText, nStt, nScriptTxt );
+ }
+ bInsert = nScriptItem == nScriptTxt;
+ }
+ }
+ if( bInsert )
+ {
+ _HTMLAttr *pSetAttr =
+ pAttr->Clone( rEndIdx, nEndCnt );
+ pSetAttr->nSttCntnt = nStt;
+
+ // Wenn das Attribut den gesamten Absatz umspannt, werden
+ // alle auesseren Attribute nicht mehr beachtet. Deshalb
+ // darf es auch nicht in die Prev-Liste eines ausseren
+ // Attributs eingetragen werden, denn dieses wird ja
+ // erstmal nicht gesetzt. Das fuehrt zu verschiebenungen,
+ // wenn Felder ins Rennen kommen (siehe #51020#)
+ if( !pNext || bWholePara )
+ {
+ USHORT nTmp = pSetAttr->bInsAtStart ? 0
+ : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pSetAttr, nTmp );
+ }
+ else
+ pNext->InsertPrev( pSetAttr );
+ }
+ else
+ {
+ _HTMLAttr *pPrev = pAttr->GetPrev();
+ if( pPrev )
+ {
+ // Die Previous-Attribute muessen trotzdem gesetzt werden.
+ if( !pNext || bWholePara )
+ {
+ USHORT nTmp = pPrev->bInsAtStart ? 0 : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pPrev, nTmp );
+ }
+ else
+ pNext->InsertPrev( pPrev );
+ }
+ }
+ pAttr->ClearPrev();
+ }
+
+ pAttr->SetStart( rPos );
+ pAttr = pNext;
+ }
+ }
+ }
+
+ if( bUpdateNum )
+ {
+ if( GetNumInfo().GetDepth() )
+ {
+ BYTE nLvl = GetNumInfo().GetLevel();
+ // --> OD 2008-04-02 #refactorlists#
+// SetNoNum (&nLvl, TRUE);
+// SetNodeNum( nLvl);
+ SetNodeNum( nLvl, false );
+ // <--
+ }
+ else
+ pPam->GetNode()->GetTxtNode()->ResetAttr( RES_PARATR_NUMRULE );
+ }
+
+ // Attrubute im Absatz davor sollte man jetzt setzen (wegen JavaScript)
+ SetAttr();
+
+ // Now it is time to get rid of all script dependent hints that are
+ // equal to the settings in the style
+ SwTxtNode *pTxtNd = rEndIdx.GetNode().GetTxtNode();
+ ASSERT( pTxtNd, "There is the txt node" );
+ sal_uInt16 nCntAttr = (pTxtNd && pTxtNd->GetpSwpHints())
+ ? pTxtNd->GetSwpHints().Count() : 0;
+ if( nCntAttr )
+ {
+ // These are the end position of all script depenent hints.
+ // If we find a hint that starts before the current end position,
+ // we have to set it. If we finf a hint that start behind or at
+ // that position, we have to take the hint's value into account.
+ // If it is equal to the style, or in fact the paragarph's value
+ // for that hint, the hint is removed. Otherwise it's end position
+ // is remembered.
+ xub_StrLen aEndPos[15] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ SwpHints& rHints = pTxtNd->GetSwpHints();
+ for( sal_uInt16 i=0; i < nCntAttr; i++ )
+ {
+ SwTxtAttr *pHt = rHints.GetTextHint( i );
+ sal_uInt16 nWhich = pHt->Which();
+ sal_Int16 nIdx = -1;
+ if( RES_CHRATR_CJK_FONT <= nWhich &&
+ nWhich <= RES_CHRATR_CTL_WEIGHT )
+ {
+ nIdx = static_cast< USHORT >(nWhich - RES_CHRATR_CJK_FONT + 5);
+ }
+ else switch( nWhich )
+ {
+ case RES_CHRATR_FONT: nIdx = 0; break;
+ case RES_CHRATR_FONTSIZE: nIdx = 1; break;
+ case RES_CHRATR_LANGUAGE: nIdx = 2; break;
+ case RES_CHRATR_POSTURE: nIdx = 3; break;
+ case RES_CHRATR_WEIGHT: nIdx = 4; break;
+ }
+ if( nIdx != -1 )
+ {
+ xub_StrLen nStt = *pHt->GetStart();
+ if( nStt >= aEndPos[nIdx] )
+ {
+ sal_Bool bFont = (nIdx % 5) == 0;
+ const SfxPoolItem& rItem =
+ ((const SwCntntNode *)pTxtNd)->GetAttr( nWhich );
+ if( bFont ? lcl_css1atr_equalFontItems(rItem,pHt->GetAttr())
+ : rItem == pHt->GetAttr() )
+ {
+ // The hint is the same as set in the paragraph and
+ // therfor, it can be deleted
+ // CAUTION!!! This WILL delete the hint and it MAY
+ // also delete the SwpHints!!! To avoid any trouble
+ // we leave the loop immediately if this is the last
+ // hint.
+ pTxtNd->DeleteAttribute( pHt );
+ if( 1 == nCntAttr )
+ break;
+ i--;
+ nCntAttr--;
+ }
+ else
+ {
+ // The hint is deifferent. Therfor all hints within that
+ // hint have to be ignored.
+ aEndPos[nIdx] = pHt->GetEnd() ? *pHt->GetEnd() : nStt;
+ }
+ }
+ else
+ {
+ // The hint starts before another one ends.
+ // The hint in this case is not deleted
+ ASSERT( pHt->GetEnd() && *pHt->GetEnd() <= aEndPos[nIdx],
+ "hints aren't nested properly!" );
+ }
+ }
+ }
+ }
+
+
+ if( !pTable && !--nParaCnt )
+ Show();
+
+ return bRet;
+}
+
+void SwHTMLParser::AddParSpace()
+{
+ if( !bNoParSpace )
+ return;
+
+ bNoParSpace = FALSE;
+
+ ULONG nNdIdx = pPam->GetPoint()->nNode.GetIndex() - 1;
+
+ SwTxtNode *pTxtNode = pDoc->GetNodes()[nNdIdx]->GetTxtNode();
+ if( !pTxtNode )
+ return;
+
+ SvxULSpaceItem rULSpace =
+ (const SvxULSpaceItem&)pTxtNode->SwCntntNode::GetAttr( RES_UL_SPACE );
+ if( !rULSpace.GetLower() )
+ {
+ const SvxULSpaceItem& rCollULSpace =
+ pTxtNode->GetAnyFmtColl().GetULSpace();
+ if( rCollULSpace.GetLower() &&
+ rCollULSpace.GetUpper() == rULSpace.GetUpper() )
+ {
+ pTxtNode->ResetAttr( RES_UL_SPACE );
+ }
+ else
+ {
+ pTxtNode->SetAttr(
+ SvxULSpaceItem( rULSpace.GetUpper(), HTML_PARSPACE, RES_UL_SPACE ) );
+ }
+ }
+}
+
+
+void SwHTMLParser::Show()
+{
+ // Hier wird
+ // - ein EndAction gerufen, damit formatiert wird
+ // - ein Reschedule gerufen,
+ // - die eiegen View-Shell wieder gesetzt
+ // - und Start-Action gerufen
+
+ ASSERT( SVPAR_WORKING==eState, "Show nicht im Working-State - Das kann ins Auge gehen" );
+ ViewShell *pOldVSh = CallEndAction();
+
+ GetpApp()->Reschedule();
+
+ if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
+ || 1 == pDoc->getReferenceCount() )
+ {
+ // wurde der Import vom SFX abgebrochen?
+ eState = SVPAR_ERROR;
+ }
+
+ // Die ViewShell nochmal holen, denn sie koennte im Reschedule
+ // zerstoert wirden sein.
+ ViewShell *pVSh = CallStartAction( pOldVSh );
+
+ // ist der aktuelle Node nicht mehr sichtbar, dann benutzen wir
+ // eine groessere Schrittweite
+ if( pVSh )
+ nParaCnt = pDoc->GetNodes()[pPam->GetPoint()->nNode]
+ ->IsInVisibleArea(pVSh) ? 5 : 50;
+}
+
+void SwHTMLParser::ShowStatline()
+{
+ // Hier wird
+ // - ein Reschedule gerufen, damit gescrollt werden kann
+ // - die eiegen View-Shell wieder gesetzt
+ // - ein Start/End-Action gerufen, wenn gescrollt wurde.
+
+ ASSERT( SVPAR_WORKING==eState, "ShowStatLine nicht im Working-State - Das kann ins Auge gehen" );
+
+ // Laufbalkenanzeige
+ if( !GetMedium() || !GetMedium()->IsRemote() )
+ {
+ ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
+ CheckActionViewShell();
+ }
+ else
+ {
+ GetpApp()->Reschedule();
+
+ if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
+ || 1 == pDoc->getReferenceCount() )
+ // wurde der Import vom SFX abgebrochen?
+ eState = SVPAR_ERROR;
+
+ ViewShell *pVSh = CheckActionViewShell();
+ if( pVSh && pVSh->HasInvalidRect() )
+ {
+ CallEndAction( FALSE, FALSE );
+ CallStartAction( pVSh, FALSE );
+ }
+ }
+}
+
+ViewShell *SwHTMLParser::CallStartAction( ViewShell *pVSh, BOOL bChkPtr )
+{
+ ASSERT( !pActionViewShell, "CallStartAction: ViewShell schon gesetzt" );
+
+ if( !pVSh || bChkPtr )
+ {
+#ifdef DBG_UTIL
+ ViewShell *pOldVSh = pVSh;
+#endif
+ pDoc->GetEditShell( &pVSh );
+ ASSERT( !pVSh || !pOldVSh || pOldVSh == pVSh, "CallStartAction: Wer hat die ViewShell ausgetauscht?" );
+#ifdef DBG_UTIL
+ if( pOldVSh && !pVSh )
+ pVSh = 0;
+#endif
+ }
+ pActionViewShell = pVSh;
+
+ if( pActionViewShell )
+ {
+ if( pActionViewShell->ISA( SwEditShell ) )
+ ((SwEditShell*)pActionViewShell)->StartAction();
+ else
+ pActionViewShell->StartAction();
+ }
+
+ return pActionViewShell;
+}
+
+ViewShell *SwHTMLParser::CallEndAction( BOOL bChkAction, BOOL bChkPtr )
+{
+ if( bChkPtr )
+ {
+ ViewShell *pVSh = 0;
+ pDoc->GetEditShell( &pVSh );
+ ASSERT( !pVSh || pActionViewShell == pVSh,
+ "CallEndAction: Wer hat die ViewShell ausgetauscht?" );
+#if OSL_DEBUG_LEVEL > 1
+ if( pActionViewShell && !pVSh )
+ pVSh = 0;
+#endif
+ if( pVSh != pActionViewShell )
+ pActionViewShell = 0;
+ }
+
+ if( !pActionViewShell || (bChkAction && !pActionViewShell->ActionPend()) )
+ return pActionViewShell;
+
+ if( bSetCrsr )
+ {
+ // an allen CrsrEditShells die Cursor auf den Doc-Anfang setzen
+ ViewShell *pSh = pActionViewShell;
+ do {
+ if( pSh->IsA( TYPE( SwCrsrShell ) ) )
+ ((SwCrsrShell*)pSh)->SttEndDoc(TRUE);
+ pSh = (ViewShell *)pSh->GetNext();
+ } while( pSh != pActionViewShell );
+
+ bSetCrsr = FALSE;
+ }
+ if( pActionViewShell->ISA( SwEditShell ) )
+ {
+ //Schon gescrollt?, dann dafuer sorgen, dass die View sich nicht bewegt!
+ const BOOL bOldLock = pActionViewShell->IsViewLocked();
+ pActionViewShell->LockView( TRUE );
+ const BOOL bOldEndActionByVirDev = pActionViewShell->IsEndActionByVirDev();
+ pActionViewShell->SetEndActionByVirDev( TRUE );;
+ ((SwEditShell*)pActionViewShell)->EndAction();
+ pActionViewShell->SetEndActionByVirDev( bOldEndActionByVirDev );
+ pActionViewShell->LockView( bOldLock );
+
+ // bChkJumpMark ist nur gesetzt, wenn das Object auch gefunden wurde
+ if( bChkJumpMark )
+ {
+ const Point aVisSttPos( DOCUMENTBORDER, DOCUMENTBORDER );
+ if( GetMedium() && aVisSttPos == pActionViewShell->VisArea().Pos() )
+ ::JumpToSwMark( pActionViewShell,
+ GetMedium()->GetURLObject().GetMark() );
+ bChkJumpMark = FALSE;
+ }
+ }
+ else
+ pActionViewShell->EndAction();
+
+ // sollte der Parser der Letzte sein, der das Doc haelt, dann kann
+ // man hier abbrechen und einen Fehler setzen.
+ if( 1 == pDoc->getReferenceCount() )
+ {
+ eState = SVPAR_ERROR;
+ }
+
+ ViewShell *pVSh = pActionViewShell;
+ pActionViewShell = 0;
+
+ return pVSh;
+}
+
+ViewShell *SwHTMLParser::CheckActionViewShell()
+{
+ ViewShell *pVSh = 0;
+ pDoc->GetEditShell( &pVSh );
+ ASSERT( !pVSh || pActionViewShell == pVSh,
+ "CheckActionViewShell: Wer hat die ViewShell ausgetauscht?" );
+#if OSL_DEBUG_LEVEL > 1
+ if( pActionViewShell && !pVSh )
+ pVSh = 0;
+#endif
+ if( pVSh != pActionViewShell )
+ pActionViewShell = 0;
+
+ return pActionViewShell;
+}
+
+/* */
+
+void SwHTMLParser::_SetAttr( BOOL bChkEnd, BOOL bBeforeTable,
+ _HTMLAttrs *pPostIts )
+{
+ SwPaM* pAttrPam = new SwPaM( *pPam->GetPoint() );
+ const SwNodeIndex& rEndIdx = pPam->GetPoint()->nNode;
+ xub_StrLen nEndCnt = pPam->GetPoint()->nContent.GetIndex();
+ _HTMLAttr* pAttr;
+ SwCntntNode* pCNd;
+ USHORT n;
+
+ _HTMLAttrs aFields( 5, 5 );
+
+ for( n = aSetAttrTab.Count(); n; )
+ {
+ pAttr = aSetAttrTab[ --n ];
+ USHORT nWhich = pAttr->pItem->Which();
+
+ ULONG nEndParaIdx = pAttr->GetEndParaIdx();
+ BOOL bSetAttr;
+ if( bChkEnd )
+ {
+ // fix #42192#: Zechen-Attribute mit Ende moeglich frueh,
+ // also noch im aktuellen Absatz setzen (wegen JavaScript
+ // und diversen Chats). das darf man aber nicht fuer Attribute,
+ // die ueber den ganzen Absatz aufgspannt werden sollen, weil
+ // sie aus Absatzvorlgen stammen, die nicht gesetzt werden
+ // koennen. Weil die Attribute mit SETATTR_DONTREPLACE
+ // eingefuegt werden, sollte man sie auch anchtraeglich
+ // noch setzen koennen.
+ bSetAttr = ( nEndParaIdx < rEndIdx.GetIndex() &&
+ (RES_LR_SPACE != nWhich || !GetNumInfo().GetNumRule()) ) ||
+ ( !pAttr->IsLikePara() &&
+ nEndParaIdx == rEndIdx.GetIndex() &&
+ pAttr->GetEndCnt() < nEndCnt &&
+ (isCHRATR(nWhich) || isTXTATR_WITHEND(nWhich)) ) ||
+ ( bBeforeTable &&
+ nEndParaIdx == rEndIdx.GetIndex() &&
+ !pAttr->GetEndCnt() );
+ }
+ else
+ {
+ // Attribiute im Content-Bereich duerfen nicht gesetzt
+ // werden, wenn wir in einem Sonderbereich stehen, aber
+ // umgekekehrt schon.
+ ULONG nEndOfIcons = pDoc->GetNodes().GetEndOfExtras().GetIndex();
+ bSetAttr = nEndParaIdx < rEndIdx.GetIndex() ||
+ rEndIdx.GetIndex() > nEndOfIcons ||
+ nEndParaIdx <= nEndOfIcons;
+ }
+
+ if( bSetAttr )
+ {
+ // Das Attribute darf nicht in der liste der vorlaeufigen
+ // Absatz-Attribute stehen, weil es sonst geloescht wurde.
+ USHORT ii = aParaAttrs.Count();
+ while( ii-- )
+ {
+ ASSERT( pAttr != aParaAttrs[ii],
+ "SetAttr: Attribut duerfte noch nicht gesetzt werden" );
+ aParaAttrs.Remove( ii );
+ }
+
+
+ // dann also setzen
+ aSetAttrTab.Remove( n, 1 );
+
+ while( pAttr )
+ {
+ _HTMLAttr *pPrev = pAttr->GetPrev();
+ if( !pAttr->bValid )
+ {
+ // ungueltige Attribute koennen gloescht werden
+ delete pAttr;
+ pAttr = pPrev;
+ continue; //break;
+ }
+
+
+ pCNd = pDoc->GetNodes()[ pAttr->nSttPara ]->GetCntntNode();
+ if( !pCNd )
+ {
+ // durch die elende Loescherei von Nodes kann auch mal
+ // ein Index auf einen End-Node zeigen :-(
+ if ( (pAttr->GetSttPara() == pAttr->GetEndPara()) &&
+ !isTXTATR_NOEND(nWhich) )
+ {
+ // wenn der End-Index auch auf den Node zeigt
+ // brauchen wir auch kein Attribut mehr zu setzen,
+ // es sei denn, es ist ein Text-Attribut.
+ delete pAttr;
+ pAttr = pPrev;
+ continue; //break;
+ }
+ pCNd = pDoc->GetNodes().GoNext( &(pAttr->nSttPara) );
+ if( pCNd )
+ pAttr->nSttCntnt = 0;
+ else
+ {
+ ASSERT( !this, "SetAttr: GoNext() failed!" );
+ delete pAttr;
+ pAttr = pPrev;
+ continue; // break;
+ }
+ }
+ pAttrPam->GetPoint()->nNode = pAttr->nSttPara;
+
+
+
+ // durch das Loeschen von BRs kann der Start-Index
+ // auch mal hinter das Ende des Textes zeigen
+ if( pAttr->nSttCntnt > pCNd->Len() )
+ pAttr->nSttCntnt = pCNd->Len();
+ pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nSttCntnt );
+
+ pAttrPam->SetMark();
+ if ( (pAttr->GetSttPara() != pAttr->GetEndPara()) &&
+ !isTXTATR_NOEND(nWhich) )
+ {
+ pCNd = pDoc->GetNodes()[ pAttr->nEndPara ]->GetCntntNode();
+ if( !pCNd )
+ {
+ pCNd = pDoc->GetNodes().GoPrevious( &(pAttr->nEndPara) );
+ if( pCNd )
+ pAttr->nEndCntnt = pCNd->Len();
+ else
+ {
+ ASSERT( !this, "SetAttr: GoPrevious() failed!" );
+ pAttrPam->DeleteMark();
+ delete pAttr;
+ pAttr = pPrev;
+ continue; // break;
+ }
+ }
+
+ pAttrPam->GetPoint()->nNode = pAttr->nEndPara;
+ }
+ else if( pAttr->IsLikePara() )
+ {
+ pAttr->nEndCntnt = pCNd->Len();
+ }
+
+ // durch das Loeschen von BRs kann der End-Index
+ // auch mal hinter das Ende des Textes zeigen
+ if( pAttr->nEndCntnt > pCNd->Len() )
+ pAttr->nEndCntnt = pCNd->Len();
+
+ pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nEndCntnt );
+ if( bBeforeTable &&
+ pAttrPam->GetPoint()->nNode.GetIndex() ==
+ rEndIdx.GetIndex() )
+ {
+ // wenn wir vor dem Einfuegen einer Tabelle stehen
+ // und das Attribut im aktuellen Node beendet wird,
+ // muessen wir es im Node davor beenden oder wegschmeissen,
+ // wenn es erst in dem Node beginnt
+ if( nWhich != RES_BREAK && nWhich != RES_PAGEDESC &&
+ !isTXTATR_NOEND(nWhich) )
+ {
+ if( pAttrPam->GetMark()->nNode.GetIndex() !=
+ rEndIdx.GetIndex() )
+ {
+ ASSERT( !pAttrPam->GetPoint()->nContent.GetIndex(),
+ "Content-Position vor Tabelle nicht 0???" );
+ pAttrPam->Move( fnMoveBackward );
+ }
+ else
+ {
+ pAttrPam->DeleteMark();
+ delete pAttr;
+ pAttr = pPrev;
+ continue;
+ }
+ }
+ }
+
+ switch( nWhich )
+ {
+ case RES_FLTR_BOOKMARK: // insert bookmark
+ {
+ const String sName( ((SfxStringItem*)pAttr->pItem)->GetValue() );
+ IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
+ IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark( sName );
+ if( ppBkmk != pMarkAccess->getMarksEnd() &&
+ ppBkmk->get()->GetMarkStart() == *pAttrPam->GetPoint() )
+ break; // do not generate duplicates on this position
+ pAttrPam->DeleteMark();
+ const ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark(
+ *pAttrPam,
+ sName,
+ IDocumentMarkAccess::BOOKMARK );
+
+ // jump to bookmark
+ if( JUMPTO_MARK == eJumpTo && pNewMark->GetName() == ::rtl::OUString(sJmpMark) )
+ {
+ bChkJumpMark = TRUE;
+ eJumpTo = JUMPTO_NONE;
+ }
+ }
+ break;
+ case RES_TXTATR_FIELD:
+ {
+ USHORT nFldWhich =
+ pPostIts ? ((const SwFmtFld *)pAttr->pItem)
+ ->GetFld()->GetTyp()->Which() : 0;
+ if( pPostIts && (RES_POSTITFLD == nFldWhich ||
+ RES_SCRIPTFLD == nFldWhich) )
+ {
+ pPostIts->Insert( pAttr, 0 );
+ }
+ else
+ {
+ aFields.Insert( pAttr, aFields.Count() );
+ }
+ }
+ pAttrPam->DeleteMark();
+ pAttr = pPrev;
+ continue;
+
+ case RES_LR_SPACE:
+ if( pAttrPam->GetPoint()->nNode.GetIndex() ==
+ pAttrPam->GetMark()->nNode.GetIndex() &&
+ pCNd )
+ {
+ // wegen Numerierungen dieses Attribut direkt
+ // am Node setzen
+ pCNd->SetAttr( *pAttr->pItem );
+ break;
+ }
+ ASSERT( !this,
+ "LRSpace ueber mehrere Absaetze gesetzt!" );
+ // kein break (hier sollen wir trotzdem nie hinkommen;
+ default:
+
+ // ggfs. ein Bookmark anspringen
+ if( RES_TXTATR_INETFMT == nWhich &&
+ JUMPTO_MARK == eJumpTo &&
+ sJmpMark == ((SwFmtINetFmt*)pAttr->pItem)->GetName() )
+ {
+ bChkJumpMark = TRUE;
+ eJumpTo = JUMPTO_NONE;
+ }
+
+ pDoc->InsertPoolItem( *pAttrPam, *pAttr->pItem, nsSetAttrMode::SETATTR_DONTREPLACE );
+ }
+ pAttrPam->DeleteMark();
+
+ delete pAttr;
+ pAttr = pPrev;
+ }
+ }
+ }
+
+ for( n = aMoveFlyFrms.Count(); n; )
+ {
+ SwFrmFmt *pFrmFmt = aMoveFlyFrms[ --n ];
+
+ const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
+ ASSERT( FLY_AT_PARA == rAnchor.GetAnchorId(),
+ "Nur Auto-Rahmen brauchen eine Spezialbehandlung" );
+ const SwPosition *pFlyPos = rAnchor.GetCntntAnchor();
+ ULONG nFlyParaIdx = pFlyPos->nNode.GetIndex();
+ BOOL bMoveFly;
+ if( bChkEnd )
+ {
+ bMoveFly = nFlyParaIdx < rEndIdx.GetIndex() ||
+ ( nFlyParaIdx == rEndIdx.GetIndex() &&
+ aMoveFlyCnts[n] < nEndCnt );
+ }
+ else
+ {
+ ULONG nEndOfIcons = pDoc->GetNodes().GetEndOfExtras().GetIndex();
+ bMoveFly = nFlyParaIdx < rEndIdx.GetIndex() ||
+ rEndIdx.GetIndex() > nEndOfIcons ||
+ nFlyParaIdx <= nEndOfIcons;
+ }
+ if( bMoveFly )
+ {
+ pFrmFmt->DelFrms();
+ *pAttrPam->GetPoint() = *pFlyPos;
+ pAttrPam->GetPoint()->nContent.Assign( pAttrPam->GetCntntNode(),
+ aMoveFlyCnts[n] );
+ SwFmtAnchor aAnchor( rAnchor );
+ aAnchor.SetType( FLY_AT_CHAR );
+ aAnchor.SetAnchor( pAttrPam->GetPoint() );
+ pFrmFmt->SetFmtAttr( aAnchor );
+
+ const SwFmtHoriOrient& rHoriOri = pFrmFmt->GetHoriOrient();
+ if( text::HoriOrientation::LEFT == rHoriOri.GetHoriOrient() )
+ {
+ SwFmtHoriOrient aHoriOri( rHoriOri );
+ aHoriOri.SetRelationOrient( text::RelOrientation::CHAR );
+ pFrmFmt->SetFmtAttr( aHoriOri );
+ }
+ const SwFmtVertOrient& rVertOri = pFrmFmt->GetVertOrient();
+ if( text::VertOrientation::TOP == rVertOri.GetVertOrient() )
+ {
+ SwFmtVertOrient aVertOri( rVertOri );
+ aVertOri.SetRelationOrient( text::RelOrientation::CHAR );
+ pFrmFmt->SetFmtAttr( aVertOri );
+ }
+
+ pFrmFmt->MakeFrms();
+ aMoveFlyFrms.Remove( n, 1 );
+ aMoveFlyCnts.Remove( n, 1 );
+ }
+ }
+ while( aFields.Count() )
+ {
+ pAttr = aFields[0];
+
+ pCNd = pDoc->GetNodes()[ pAttr->nSttPara ]->GetCntntNode();
+ pAttrPam->GetPoint()->nNode = pAttr->nSttPara;
+ pAttrPam->GetPoint()->nContent.Assign( pCNd, pAttr->nSttCntnt );
+
+ if( bBeforeTable &&
+ pAttrPam->GetPoint()->nNode.GetIndex() == rEndIdx.GetIndex() )
+ {
+ ASSERT( !bBeforeTable, "Aha, der Fall tritt also doch ein" );
+ ASSERT( !pAttrPam->GetPoint()->nContent.GetIndex(),
+ "Content-Position vor Tabelle nicht 0???" );
+ // !!!
+ pAttrPam->Move( fnMoveBackward );
+ }
+
+ pDoc->InsertPoolItem( *pAttrPam, *pAttr->pItem, 0 );
+
+ aFields.Remove( 0, 1 );
+ delete pAttr;
+ }
+
+ delete pAttrPam;
+}
+
+void SwHTMLParser::NewAttr( _HTMLAttr **ppAttr, const SfxPoolItem& rItem )
+{
+ // Font-Hoehen und -Farben- sowie Escapement-Attribute duerfen nicht
+ // zusammengefasst werden. Sie werden deshalb in einer Liste gespeichert,
+ // in der das zuletzt aufgespannte Attribut vorne steht und der Count
+ // immer 1 ist. Fuer alle anderen Attribute wird der Count einfach
+ // hochgezaehlt.
+ if( *ppAttr )
+ {
+ _HTMLAttr *pAttr = new _HTMLAttr( *pPam->GetPoint(), rItem,
+ ppAttr );
+ pAttr->InsertNext( *ppAttr );
+ (*ppAttr) = pAttr;
+ }
+ else
+ (*ppAttr) = new _HTMLAttr( *pPam->GetPoint(), rItem, ppAttr );
+}
+
+
+void SwHTMLParser::EndAttr( _HTMLAttr* pAttr, _HTMLAttr **ppDepAttr,
+ BOOL bChkEmpty )
+{
+ ASSERT( !ppDepAttr, "SwHTMLParser::EndAttr: ppDepAttr-Feature ungetestet?" );
+ // Der Listenkopf ist im Attribut gespeichert
+ _HTMLAttr **ppHead = pAttr->ppHead;
+
+ ASSERT( ppHead, "keinen Attributs-Listenkopf gefunden!" );
+
+ // die aktuelle Psoition als Ende-Position merken
+ const SwNodeIndex* pEndIdx = &pPam->GetPoint()->nNode;
+ xub_StrLen nEndCnt = pPam->GetPoint()->nContent.GetIndex();
+
+ // WIrd das zueltzt gestartete oder ein frueher gestartetes Attribut
+ // beendet?
+ _HTMLAttr *pLast = 0;
+ if( ppHead && pAttr != *ppHead )
+ {
+ // Es wird nicht das zuletzt gestartete Attribut beendet
+
+ // Dann suche wir das unmittelbar danach gestartete Attribut, das
+ // ja ebenfalls noch nicht beendet wurde (sonst stuende es nicht
+ // mehr in der Liste
+ pLast = *ppHead;
+ while( pLast && pLast->GetNext() != pAttr )
+ pLast = pLast->GetNext();
+
+ ASSERT( pLast, "Attribut nicht in eigener Liste gefunden!" );
+
+ // das Attribut nicht an der PaM-Psoition beenden, sondern da,
+ // wo das danch gestartete Attribut anfing???
+ //pEndIdx = &pPrev->GetSttPara();
+ //nEndCnt = pPrev->GetSttCnt();
+ }
+
+ BOOL bMoveBack = FALSE;
+ USHORT nWhich = pAttr->pItem->Which();
+ if( /*!pLast &&*/ !nEndCnt && RES_PARATR_BEGIN <= nWhich &&
+ *pEndIdx != pAttr->GetSttPara() )
+ {
+ // dann eine Cntntnt Position zurueck!
+ bMoveBack = pPam->Move( fnMoveBackward );
+ nEndCnt = pPam->GetPoint()->nContent.GetIndex();
+ }
+
+ // nun das Attrubut beenden
+ _HTMLAttr *pNext = pAttr->GetNext();
+
+
+ sal_Bool bInsert;
+ sal_uInt16 nScriptItem = 0;
+ sal_Bool bScript = sal_False, bFont = sal_False;
+ // ein Bereich ??
+ if( !bChkEmpty || (RES_PARATR_BEGIN <= nWhich && bMoveBack) ||
+ RES_PAGEDESC == nWhich || RES_BREAK == nWhich ||
+ *pEndIdx != pAttr->GetSttPara() ||
+ nEndCnt != pAttr->GetSttCnt() )
+ {
+ bInsert = sal_True;
+ // We do some optimization for script depenedent attribtes here.
+ if( *pEndIdx == pAttr->GetSttPara() )
+ {
+ lcl_swhtml_getItemInfo( *pAttr, bScript, bFont, nScriptItem );
+ }
+ }
+ else
+ {
+ bInsert = sal_False;
+ }
+
+ if( bInsert && bScript )
+ {
+ const SwTxtNode *pTxtNd = pAttr->GetSttPara().GetNode()
+ .GetTxtNode();
+ ASSERT( pTxtNd, "No text node" );
+ const String& rText = pTxtNd->GetTxt();
+ sal_uInt16 nScriptTxt = pBreakIt->GetBreakIter()->getScriptType(
+ rText, pAttr->GetSttCnt() );
+ xub_StrLen nScriptEnd = (xub_StrLen)pBreakIt->GetBreakIter()
+ ->endOfScript( rText, pAttr->GetSttCnt(), nScriptTxt );
+ while( nScriptEnd < nEndCnt )
+ {
+ if( nScriptItem == nScriptTxt )
+ {
+ _HTMLAttr *pSetAttr = pAttr->Clone( *pEndIdx, nScriptEnd );
+ pSetAttr->ClearPrev();
+ if( pNext )
+ pNext->InsertPrev( pSetAttr );
+ else
+ {
+ USHORT nTmp = pSetAttr->bInsAtStart ? 0
+ : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pSetAttr, nTmp );
+ }
+ }
+ pAttr->nSttCntnt = nScriptEnd;
+ nScriptTxt = pBreakIt->GetBreakIter()->getScriptType(
+ rText, nScriptEnd );
+ nScriptEnd = (xub_StrLen)pBreakIt->GetBreakIter()
+ ->endOfScript( rText, nScriptEnd, nScriptTxt );
+ }
+ bInsert = nScriptItem == nScriptTxt;
+ }
+ if( bInsert )
+ {
+ pAttr->nEndPara = *pEndIdx;
+ pAttr->nEndCntnt = nEndCnt;
+ pAttr->bInsAtStart = RES_TXTATR_INETFMT != nWhich &&
+ RES_TXTATR_CHARFMT != nWhich;
+
+ if( !pNext )
+ {
+ // keine offenen Attribute dieses Typs mehr da,
+ // dann koennen alle gesetzt werden, es sei denn
+ // sie haengen noch von einem anderen Attribut ab,
+ // dann werden sie dort angehaengt
+ if( ppDepAttr && *ppDepAttr )
+ (*ppDepAttr)->InsertPrev( pAttr );
+ else
+ {
+ USHORT nTmp = pAttr->bInsAtStart ? 0 : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pAttr, nTmp );
+ }
+ }
+ else
+ {
+ // es gibt noch andere offene Attribute des Typs,
+ // daher muss das Setzen zurueckgestellt werden.
+ // das aktuelle Attribut wird deshalb hinten an die
+ // Previous-Liste des Nachfolgers angehaengt
+ pNext->InsertPrev( pAttr );
+ }
+ }
+ else
+ {
+ // dann nicht einfuegen, sondern Loeschen. Durch das "tuerken" von
+ // Vorlagen durch harte Attributierung koennen sich auch mal andere
+ // leere Attribute in der Prev-Liste befinden, die dann trotzdem
+ // gesetzt werden muessen
+ _HTMLAttr *pPrev = pAttr->GetPrev();
+ delete pAttr;
+
+ if( pPrev )
+ {
+ // Die Previous-Attribute muessen trotzdem gesetzt werden.
+ if( pNext )
+ pNext->InsertPrev( pPrev );
+ else
+ {
+ USHORT nTmp = pPrev->bInsAtStart ? 0 : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pPrev, nTmp );
+ }
+ }
+
+ }
+
+ // wenn das erste Attribut der Liste gesetzt wurde muss noch der
+ // Listenkopf korrigiert werden.
+ if( pLast )
+ pLast->pNext = pNext;
+ else if( ppHead )
+ *ppHead = pNext;
+
+ if( bMoveBack )
+ pPam->Move( fnMoveForward );
+}
+
+void SwHTMLParser::DeleteAttr( _HTMLAttr* pAttr )
+{
+ // 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() );
+
+ // Der Listenkopf ist im Attribut gespeichert
+ _HTMLAttr **ppHead = pAttr->ppHead;
+
+ ASSERT( ppHead, "keinen Attributs-Listenkopf gefunden!" );
+
+ // Wird das zueltzt gestartete oder ein frueher gestartetes Attribut
+ // entfernt?
+ _HTMLAttr *pLast = 0;
+ if( ppHead && pAttr != *ppHead )
+ {
+ // Es wird nicht das zuletzt gestartete Attribut beendet
+
+ // Dann suche wir das unmittelbar danach gestartete Attribut, das
+ // ja ebenfalls noch nicht beendet wurde (sonst stuende es nicht
+ // mehr in der Liste
+ pLast = *ppHead;
+ while( pLast && pLast->GetNext() != pAttr )
+ pLast = pLast->GetNext();
+
+ ASSERT( pLast, "Attribut nicht in eigener Liste gefunden!" );
+ }
+
+ // nun das Attrubut entfernen
+ _HTMLAttr *pNext = pAttr->GetNext();
+ _HTMLAttr *pPrev = pAttr->GetPrev();
+ delete pAttr;
+
+ if( pPrev )
+ {
+ // Die Previous-Attribute muessen trotzdem gesetzt werden.
+ if( pNext )
+ pNext->InsertPrev( pPrev );
+ else
+ {
+ USHORT nTmp = pPrev->bInsAtStart ? 0 : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pPrev, nTmp );
+ }
+ }
+
+ // wenn das erste Attribut der Liste entfernt wurde muss noch der
+ // Listenkopf korrigiert werden.
+ if( pLast )
+ pLast->pNext = pNext;
+ else if( ppHead )
+ *ppHead = pNext;
+}
+
+void SwHTMLParser::SaveAttrTab( _HTMLAttrTable& rNewAttrTab )
+{
+ // 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() );
+
+ _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
+ _HTMLAttr** pSaveTbl = (_HTMLAttr**)&rNewAttrTab;
+
+ for( USHORT nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
+ nCnt--; (++pTbl, ++pSaveTbl) )
+ {
+ *pSaveTbl = *pTbl;
+
+ _HTMLAttr *pAttr = *pSaveTbl;
+ while( pAttr )
+ {
+ pAttr->SetHead( pSaveTbl );
+ pAttr = pAttr->GetNext();
+ }
+
+ *pTbl = 0;
+ }
+}
+
+void SwHTMLParser::SplitAttrTab( _HTMLAttrTable& rNewAttrTab,
+ BOOL bMoveEndBack )
+{
+ // 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& nSttIdx = pPam->GetPoint()->nNode;
+ SwNodeIndex nEndIdx( nSttIdx );
+
+ // alle noch offenen Attribute beenden und hinter der Tabelle
+ // neu aufspannen
+ _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
+ _HTMLAttr** pSaveTbl = (_HTMLAttr**)&rNewAttrTab;
+ BOOL bSetAttr = TRUE;
+ xub_StrLen nSttCnt = pPam->GetPoint()->nContent.GetIndex();
+ xub_StrLen nEndCnt = nSttCnt;
+
+ if( bMoveEndBack )
+ {
+ ULONG nOldEnd = nEndIdx.GetIndex();
+ ULONG nTmpIdx;
+ if( ( nTmpIdx = pDoc->GetNodes().GetEndOfExtras().GetIndex()) >= nOldEnd ||
+ ( nTmpIdx = pDoc->GetNodes().GetEndOfAutotext().GetIndex()) >= nOldEnd )
+ {
+ nTmpIdx = pDoc->GetNodes().GetEndOfInserts().GetIndex();
+ }
+ SwCntntNode* pCNd = pDoc->GetNodes().GoPrevious(&nEndIdx);
+
+ // keine Attribute setzen, wenn der PaM aus dem Content-Bereich
+ // herausgeschoben wurde.
+ bSetAttr = pCNd && nTmpIdx < nEndIdx.GetIndex();
+
+ nEndCnt = (bSetAttr ? pCNd->Len() : 0);
+ }
+ for( USHORT nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
+ nCnt--; (++pTbl, ++pSaveTbl) )
+ {
+ _HTMLAttr *pAttr = *pTbl;
+ *pSaveTbl = 0;
+ while( pAttr )
+ {
+ _HTMLAttr *pNext = pAttr->GetNext();
+ _HTMLAttr *pPrev = pAttr->GetPrev();
+
+ if( bSetAttr &&
+ ( pAttr->GetSttParaIdx() < nEndIdx.GetIndex() ||
+ (pAttr->GetSttPara() == nEndIdx &&
+ pAttr->GetSttCnt() != nEndCnt) ) )
+ {
+ // das Attribut muss vor der Liste 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( nEndIdx, nEndCnt );
+
+ if( pNext )
+ pNext->InsertPrev( pSetAttr );
+ else
+ {
+ USHORT 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
+ {
+ USHORT nTmp = pPrev->bInsAtStart ? 0 : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pPrev, nTmp );
+ }
+ }
+
+ // den Start des Attributs neu setzen und die Verkettungen
+ // aufbrechen
+ pAttr->Reset( nSttIdx, nSttCnt, pSaveTbl );
+
+ if( *pSaveTbl )
+ {
+ _HTMLAttr *pSAttr = *pSaveTbl;
+ while( pSAttr->GetNext() )
+ pSAttr = pSAttr->GetNext();
+ pSAttr->InsertNext( pAttr );
+ }
+ else
+ *pSaveTbl = pAttr;
+
+ pAttr = pNext;
+ }
+
+ *pTbl = 0;
+ }
+}
+
+void SwHTMLParser::RestoreAttrTab( const _HTMLAttrTable& rNewAttrTab,
+ BOOL bSetNewStart )
+{
+ // 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() );
+
+ _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
+ _HTMLAttr** pSaveTbl = (_HTMLAttr**)&rNewAttrTab;
+
+ for( USHORT nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
+ nCnt--; (++pTbl, ++pSaveTbl) )
+ {
+ ASSERT( !*pTbl, "Die Attribut-Tabelle ist nicht leer!" );
+
+ const SwPosition *pPos = pPam->GetPoint();
+ const SwNodeIndex& rSttPara = pPos->nNode;
+ xub_StrLen nSttCnt = pPos->nContent.GetIndex();
+
+ *pTbl = *pSaveTbl;
+
+ _HTMLAttr *pAttr = *pTbl;
+ while( pAttr )
+ {
+ ASSERT( !pAttr->GetPrev() || !pAttr->GetPrev()->ppHead,
+ "Previous-Attribut hat noch einen Header" );
+ pAttr->SetHead( pTbl );
+ if( bSetNewStart )
+ {
+ pAttr->nSttPara = rSttPara;
+ pAttr->nEndPara = rSttPara;
+ pAttr->nSttCntnt = nSttCnt;
+ pAttr->nEndCntnt = nSttCnt;
+ }
+ pAttr = pAttr->GetNext();
+ }
+
+ *pSaveTbl = 0;
+ }
+}
+
+void SwHTMLParser::InsertAttr( const SfxPoolItem& rItem, BOOL bLikePara,
+ BOOL bInsAtStart )
+{
+ _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(),
+ rItem );
+ if( bLikePara )
+ pTmp->SetLikePara();
+ USHORT nTmp = bInsAtStart ? 0 : aSetAttrTab.Count();
+ aSetAttrTab.Insert( pTmp, nTmp );
+}
+
+void SwHTMLParser::InsertAttrs( _HTMLAttrs& rAttrs )
+{
+ while( rAttrs.Count() )
+ {
+ _HTMLAttr *pAttr = rAttrs[0];
+ InsertAttr( pAttr->GetItem() );
+ rAttrs.Remove( 0, 1 );
+ delete pAttr;
+ }
+}
+
+/* */
+
+void SwHTMLParser::NewStdAttr( int nToken )
+{
+ String aId, aStyle, aClass, aLang, aDir;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
+
+ // Styles parsen
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ if( HTML_SPAN_ON != nToken || !aClass.Len() ||
+ !CreateContainer( aClass, aItemSet, aPropInfo, pCntxt ) )
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+ InsertAttrs( aItemSet, aPropInfo, pCntxt, TRUE );
+ }
+ }
+
+ // den Kontext merken
+ PushContext( pCntxt );
+}
+
+void SwHTMLParser::NewStdAttr( int nToken,
+ _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
+ _HTMLAttr **ppAttr2, const SfxPoolItem *pItem2,
+ _HTMLAttr **ppAttr3, const SfxPoolItem *pItem3 )
+{
+ String aId, aStyle, aClass, aLang, aDir;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
+
+ // Styles parsen
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ aItemSet.Put( rItem );
+ if( pItem2 )
+ aItemSet.Put( *pItem2 );
+ if( pItem3 )
+ aItemSet.Put( *pItem3 );
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+
+ InsertAttrs( aItemSet, aPropInfo, pCntxt, TRUE );
+ }
+ else
+ {
+ InsertAttr( ppAttr ,rItem, pCntxt );
+ if( pItem2 )
+ {
+ ASSERT( ppAttr2, "missing table entry for item2" );
+ InsertAttr( ppAttr2, *pItem2, pCntxt );
+ }
+ if( pItem3 )
+ {
+ ASSERT( ppAttr3, "missing table entry for item3" );
+ InsertAttr( ppAttr3, *pItem3, pCntxt );
+ }
+ }
+
+ // den Kontext merken
+ PushContext( pCntxt );
+}
+
+void SwHTMLParser::EndTag( int nToken )
+{
+ // den Kontext holen
+ _HTMLAttrContext *pCntxt = PopContext( static_cast< sal_uInt16 >(nToken & ~1) );
+ if( pCntxt )
+ {
+ // und ggf. die Attribute beenden
+ EndContext( pCntxt );
+ delete pCntxt;
+ }
+}
+
+
+void SwHTMLParser::NewBasefontAttr()
+{
+ String aId, aStyle, aClass, aLang, aDir;
+ USHORT nSize = 3;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_SIZE:
+ nSize = (USHORT)pOption->GetNumber();
+ break;
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ if( nSize < 1 )
+ nSize = 1;
+
+ if( nSize > 7 )
+ nSize = 7;
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_BASEFONT_ON );
+
+ // Styles parsen
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ SvxFontHeightItem aFontHeight( aFontHeights[nSize-1], 100, RES_CHRATR_FONTSIZE );
+ aItemSet.Put( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ aItemSet.Put( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ aItemSet.Put( aFontHeight );
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+
+ InsertAttrs( aItemSet, aPropInfo, pCntxt, TRUE );
+ }
+ else
+ {
+ SvxFontHeightItem aFontHeight( aFontHeights[nSize-1], 100, RES_CHRATR_FONTSIZE );
+ InsertAttr( &aAttrTab.pFontHeight, aFontHeight, pCntxt );
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ InsertAttr( &aAttrTab.pFontHeightCJK, aFontHeight, pCntxt );
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ InsertAttr( &aAttrTab.pFontHeightCTL, aFontHeight, pCntxt );
+ }
+
+ // den Kontext merken
+ PushContext( pCntxt );
+
+ // die Font-Size merken
+ aBaseFontStack.Insert( nSize, aBaseFontStack.Count() );
+}
+
+void SwHTMLParser::EndBasefontAttr()
+{
+ EndTag( HTML_BASEFONT_ON );
+
+ // Stack-Unterlauf in Tabellen vermeiden
+ if( aBaseFontStack.Count() > nBaseFontStMin )
+ aBaseFontStack.Remove( aBaseFontStack.Count()-1, 1 );
+}
+
+void SwHTMLParser::NewFontAttr( int nToken )
+{
+ USHORT nBaseSize =
+ ( aBaseFontStack.Count() > nBaseFontStMin
+ ? (aBaseFontStack[aBaseFontStack.Count()-1] & FONTSIZE_MASK)
+ : 3 );
+ USHORT nFontSize =
+ ( aFontStack.Count() > nFontStMin
+ ? (aFontStack[aFontStack.Count()-1] & FONTSIZE_MASK)
+ : nBaseSize );
+
+ String aFace, aId, aStyle, aClass, aLang, aDir;
+ Color aColor;
+ ULONG nFontHeight = 0; // tatsaechlich einzustellende Font-Hoehe
+ USHORT nSize = 0; // Fontgroesse in Netscape-Notation (1-7)
+ BOOL bColor = FALSE;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_SIZE:
+ if( HTML_FONT_ON==nToken && pOption->GetString().Len() )
+ {
+ INT32 nSSize;
+ if( '+' == pOption->GetString().GetChar(0) ||
+ '-' == pOption->GetString().GetChar(0) )
+ nSSize = nBaseSize + pOption->GetSNumber();
+ else
+ nSSize = (INT32)pOption->GetNumber();
+
+ if( nSSize < 1 )
+ nSSize = 1;
+ else if( nSSize > 7 )
+ nSSize = 7;
+
+ nSize = (USHORT)nSSize;
+ nFontHeight = aFontHeights[nSize-1];
+ }
+ break;
+ case HTML_O_COLOR:
+ if( HTML_FONT_ON==nToken )
+ {
+ pOption->GetColor( aColor );
+ bColor = TRUE;
+ }
+ break;
+ case HTML_O_FACE:
+ if( HTML_FONT_ON==nToken )
+ aFace = pOption->GetString();
+ break;
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ if( HTML_FONT_ON != nToken )
+ {
+ // HTML_BIGPRINT_ON oder HTML_SMALLPRINT_ON
+
+ // in Ueberschriften bestimmt die aktuelle Ueberschrift
+ // die Font-Hoehe und nicht BASEFONT
+ USHORT nPoolId = GetCurrFmtColl()->GetPoolFmtId();
+ if( (nPoolId>=RES_POOLCOLL_HEADLINE1 &&
+ nPoolId<=RES_POOLCOLL_HEADLINE6) )
+ {
+ // wenn die Schriftgroesse in der Ueberschrift noch
+ // nicht veraendert ist, die aus der Vorlage nehmen
+ if( nFontStHeadStart==aFontStack.Count() )
+ nFontSize = static_cast< USHORT >(6 - (nPoolId - RES_POOLCOLL_HEADLINE1));
+ }
+ else
+ nPoolId = 0;
+
+ if( HTML_BIGPRINT_ON == nToken )
+ nSize = ( nFontSize<7 ? nFontSize+1 : 7 );
+ else
+ nSize = ( nFontSize>1 ? nFontSize-1 : 1 );
+
+ // in Ueberschriften wird die neue Fonthoehe wenn moeglich aus
+ // den Vorlagen geholt.
+ if( nPoolId && nSize>=1 && nSize <=6 )
+ nFontHeight =
+ pCSS1Parser->GetTxtCollFromPool(
+ RES_POOLCOLL_HEADLINE1+6-nSize )->GetSize().GetHeight();
+ else
+ nFontHeight = aFontHeights[nSize-1];
+ }
+
+ ASSERT( !nSize == !nFontHeight, "HTML-Font-Size != Font-Height" );
+
+ String aFontName, aStyleName;
+ FontFamily eFamily = FAMILY_DONTKNOW; // Family und Pitch,
+ FontPitch ePitch = PITCH_DONTKNOW; // falls nicht gefunden
+ rtl_TextEncoding eEnc = gsl_getSystemTextEncoding();
+
+ if( aFace.Len() && !pCSS1Parser->IsIgnoreFontFamily() )
+ {
+ 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();
+ }
+
+ BOOL bFound = FALSE;
+ xub_StrLen nStrPos = 0;
+ while( nStrPos!=STRING_NOTFOUND )
+ {
+ String aFName = aFace.GetToken( 0, ',', nStrPos );
+ aFName.EraseTrailingChars().EraseLeadingChars();
+ if( aFName.Len() )
+ {
+ if( !bFound && pFList )
+ {
+ sal_Handle hFont = pFList->GetFirstFontInfo( aFName );
+ if( 0 != hFont )
+ {
+ const FontInfo& rFInfo = pFList->GetFontInfo( hFont );
+ if( RTL_TEXTENCODING_DONTKNOW != rFInfo.GetCharSet() )
+ {
+ bFound = TRUE;
+ if( RTL_TEXTENCODING_SYMBOL == rFInfo.GetCharSet() )
+ eEnc = RTL_TEXTENCODING_SYMBOL;
+ }
+ }
+ }
+ if( aFontName.Len() )
+ aFontName += ';';
+ aFontName += aFName;
+ }
+ }
+ }
+
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
+
+ // Styles parsen
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( nFontHeight )
+ {
+ SvxFontHeightItem aFontHeight( nFontHeight, 100, RES_CHRATR_FONTSIZE );
+ aItemSet.Put( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ aItemSet.Put( aFontHeight );
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ aItemSet.Put( aFontHeight );
+ }
+ if( bColor )
+ aItemSet.Put( SvxColorItem(aColor, RES_CHRATR_COLOR) );
+ if( aFontName.Len() )
+ {
+ SvxFontItem aFont( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_FONT );
+ aItemSet.Put( aFont );
+ aFont.SetWhich( RES_CHRATR_CJK_FONT );
+ aItemSet.Put( aFont );
+ aFont.SetWhich( RES_CHRATR_CTL_FONT );
+ aItemSet.Put( aFont );
+ }
+
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+
+ InsertAttrs( aItemSet, aPropInfo, pCntxt, TRUE );
+ }
+ else
+ {
+ if( nFontHeight )
+ {
+ SvxFontHeightItem aFontHeight( nFontHeight, 100, RES_CHRATR_FONTSIZE );
+ InsertAttr( &aAttrTab.pFontHeight, aFontHeight, pCntxt );
+ aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ InsertAttr( &aAttrTab.pFontHeightCJK, aFontHeight, pCntxt );
+ aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE );
+ InsertAttr( &aAttrTab.pFontHeightCTL, aFontHeight, pCntxt );
+ }
+ if( bColor )
+ InsertAttr( &aAttrTab.pFontColor, SvxColorItem(aColor, RES_CHRATR_COLOR), pCntxt );
+ if( aFontName.Len() )
+ {
+ SvxFontItem aFont( eFamily, aFontName, aStyleName, ePitch, eEnc, RES_CHRATR_FONT );
+ InsertAttr( &aAttrTab.pFont, aFont, pCntxt );
+ aFont.SetWhich( RES_CHRATR_CJK_FONT );
+ InsertAttr( &aAttrTab.pFontCJK, aFont, pCntxt );
+ aFont.SetWhich( RES_CHRATR_CTL_FONT );
+ InsertAttr( &aAttrTab.pFontCTL, aFont, pCntxt );
+ }
+ }
+
+ // den Kontext merken
+ PushContext( pCntxt );
+
+ aFontStack.Insert( nSize, aFontStack.Count() );
+}
+
+void SwHTMLParser::EndFontAttr( int nToken )
+{
+ EndTag( nToken );
+
+ // Stack-Unterlauf in Tabellen vermeiden
+ if( aFontStack.Count() > nFontStMin )
+ aFontStack.Remove( aFontStack.Count()-1, 1 );
+}
+
+/* */
+
+void SwHTMLParser::NewPara()
+{
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_SPACE );
+ else
+ AddParSpace();
+
+ eParaAdjust = SVX_ADJUST_END;
+ String aId, aStyle, aClass, aLang, aDir;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_ALIGN:
+ eParaAdjust = (SvxAdjust)pOption->GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eParaAdjust) );
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt =
+ aClass.Len() ? new _HTMLAttrContext( HTML_PARABREAK_ON,
+ RES_POOLCOLL_TEXT, aClass )
+ : new _HTMLAttrContext( HTML_PARABREAK_ON );
+
+ // Styles parsen (Class nicht beruecksichtigen. Das geht nur, solange
+ // keine der CSS1-Properties der Klasse hart formatiert werden muss!!!)
+ if( HasStyleOptions( aStyle, aId, aEmptyStr, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aEmptyStr, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ ASSERT( !aClass.Len() || !pCSS1Parser->GetClass( aClass ),
+ "Class wird nicht beruecksichtigt" );
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+ InsertAttrs( aItemSet, aPropInfo, pCntxt );
+ }
+ }
+
+ if( SVX_ADJUST_END != eParaAdjust )
+ InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eParaAdjust, RES_PARATR_ADJUST), pCntxt );
+
+ // und auf den Stack packen
+ PushContext( pCntxt );
+
+ // die aktuelle Vorlage oder deren Attribute setzen
+ SetTxtCollAttrs( aClass.Len() ? pCntxt : 0 );
+
+ // Laufbalkenanzeige
+ ShowStatline();
+
+ ASSERT( !nOpenParaToken, "Jetzt geht ein offenes Absatz-Element verloren" );
+ nOpenParaToken = HTML_PARABREAK_ON;
+}
+
+void SwHTMLParser::EndPara( BOOL bReal )
+{
+ if( HTML_LI_ON==nOpenParaToken && pTable )
+ {
+#ifdef DBG_UTIL
+ const SwNumRule *pNumRule = pPam->GetNode()->GetTxtNode()->GetNumRule();
+#endif
+ ASSERT( pNumRule, "Wo ist die Numrule geblieben" );
+ }
+
+ // leere Absaetze werden von Netscape uebersprungen, von uns jetzt auch
+ if( bReal )
+ {
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_SPACE );
+ else
+ AddParSpace();
+ }
+
+ // wenn ein DD oder DT offen war, handelt es sich um eine
+ // implizite Def-Liste, die jetzt beendet werden muss
+ if( (nOpenParaToken==HTML_DT_ON || nOpenParaToken==HTML_DD_ON) &&
+ nDefListDeep)
+ {
+ nDefListDeep--;
+ }
+
+ // den Kontext vom Stack holen. Er kann auch von einer implizit
+ // geoeffneten Definitionsliste kommen
+ _HTMLAttrContext *pCntxt =
+ PopContext( static_cast< sal_uInt16 >(nOpenParaToken ? (nOpenParaToken & ~1)
+ : HTML_PARABREAK_ON) );
+
+ // Attribute beenden
+ if( pCntxt )
+ {
+ EndContext( pCntxt );
+ SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
+ delete pCntxt;
+ }
+
+ // und die bisherige Vorlage neu setzen
+ if( bReal )
+ SetTxtCollAttrs();
+
+ nOpenParaToken = 0;
+}
+
+
+void SwHTMLParser::NewHeading( int nToken )
+{
+ eParaAdjust = SVX_ADJUST_END;
+
+ String aId, aStyle, aClass, aLang, aDir;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_ALIGN:
+ eParaAdjust = (SvxAdjust)pOption->GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eParaAdjust) );
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ // einen neuen Absatz aufmachen
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_SPACE );
+ else
+ AddParSpace();
+
+ // die passende Vorlage suchen
+ USHORT nTxtColl;
+ switch( nToken )
+ {
+ case HTML_HEAD1_ON: nTxtColl = RES_POOLCOLL_HEADLINE1; break;
+ case HTML_HEAD2_ON: nTxtColl = RES_POOLCOLL_HEADLINE2; break;
+ case HTML_HEAD3_ON: nTxtColl = RES_POOLCOLL_HEADLINE3; break;
+ case HTML_HEAD4_ON: nTxtColl = RES_POOLCOLL_HEADLINE4; break;
+ case HTML_HEAD5_ON: nTxtColl = RES_POOLCOLL_HEADLINE5; break;
+ case HTML_HEAD6_ON: nTxtColl = RES_POOLCOLL_HEADLINE6; break;
+ default: nTxtColl = RES_POOLCOLL_STANDARD; break;
+ }
+
+ // den Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken), nTxtColl, aClass );
+
+ // Styles parsen (zu Class siehe auch NewPara)
+ if( HasStyleOptions( aStyle, aId, aEmptyStr, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aEmptyStr, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ ASSERT( !aClass.Len() || !pCSS1Parser->GetClass( aClass ),
+ "Class wird nicht beruecksichtigt" );
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+ InsertAttrs( aItemSet, aPropInfo, pCntxt );
+ }
+ }
+
+ if( SVX_ADJUST_END != eParaAdjust )
+ InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eParaAdjust, RES_PARATR_ADJUST), pCntxt );
+
+ // udn auf den Stack packen
+ PushContext( pCntxt );
+
+ // und die Vorlage oder deren Attribute setzen
+ SetTxtCollAttrs( pCntxt );
+
+ nFontStHeadStart = aFontStack.Count();
+
+ // Laufbalkenanzeige
+ ShowStatline();
+}
+
+void SwHTMLParser::EndHeading()
+{
+ // einen neuen Absatz aufmachen
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_SPACE );
+ else
+ AddParSpace();
+
+ // Kontext zu dem Token suchen und vom Stack holen
+ _HTMLAttrContext *pCntxt = 0;
+ USHORT nPos = aContexts.Count();
+ while( !pCntxt && nPos>nContextStMin )
+ {
+ switch( aContexts[--nPos]->GetToken() )
+ {
+ case HTML_HEAD1_ON:
+ case HTML_HEAD2_ON:
+ case HTML_HEAD3_ON:
+ case HTML_HEAD4_ON:
+ case HTML_HEAD5_ON:
+ case HTML_HEAD6_ON:
+ pCntxt = aContexts[nPos];
+ aContexts.Remove( nPos, 1 );
+ break;
+ }
+ }
+
+ // und noch Attribute beenden
+ if( pCntxt )
+ {
+ EndContext( pCntxt );
+ SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
+ delete pCntxt;
+ }
+
+ // die bisherige Vorlage neu setzen
+ SetTxtCollAttrs();
+
+ nFontStHeadStart = nFontStMin;
+}
+
+/* */
+
+void SwHTMLParser::NewTxtFmtColl( int nToken, USHORT nColl )
+{
+ String aId, aStyle, aClass, aLang, aDir;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ // einen neuen Absatz aufmachen
+ SwHTMLAppendMode eMode = AM_NORMAL;
+ switch( nToken )
+ {
+ case HTML_LISTING_ON:
+ case HTML_XMP_ON:
+ // Diese beiden Tags werden jetzt auf die PRE-Vorlage gemappt.
+ // Fuer dem Fall, dass ein CLASS angegeben ist, loeschen wir
+ // es damit wir nicht die CLASS der PRE-Vorlage bekommen.
+ aClass = aEmptyStr;
+ case HTML_BLOCKQUOTE_ON:
+ case HTML_BLOCKQUOTE30_ON:
+ case HTML_PREFORMTXT_ON:
+ eMode = AM_SPACE;
+ break;
+ case HTML_ADDRESS_ON:
+ eMode = AM_NOSPACE; // ADDRESS kann auf einen <P> ohne </P> folgen
+ break;
+ case HTML_DT_ON:
+ case HTML_DD_ON:
+ eMode = AM_SOFTNOSPACE;
+ break;
+ default:
+ ASSERT( !this, "unbekannte Vorlage" );
+ break;
+ }
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( eMode );
+ else if( AM_SPACE==eMode )
+ AddParSpace();
+
+ // ... und in einem Kontext merken
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken), nColl, aClass );
+
+ // Styles parsen (zu Class siehe auch NewPara)
+ if( HasStyleOptions( aStyle, aId, aEmptyStr, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aEmptyStr, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ ASSERT( !aClass.Len() || !pCSS1Parser->GetClass( aClass ),
+ "Class wird nicht beruecksichtigt" );
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+ InsertAttrs( aItemSet, aPropInfo, pCntxt );
+ }
+ }
+
+ PushContext( pCntxt );
+
+ // die neue Vorlage setzen
+ SetTxtCollAttrs( pCntxt );
+
+ // Laufbalkenanzeige aktualisieren
+ ShowStatline();
+}
+
+void SwHTMLParser::EndTxtFmtColl( int nToken )
+{
+ SwHTMLAppendMode eMode = AM_NORMAL;
+ switch( nToken & ~1 )
+ {
+ case HTML_BLOCKQUOTE_ON:
+ case HTML_BLOCKQUOTE30_ON:
+ case HTML_PREFORMTXT_ON:
+ case HTML_LISTING_ON:
+ case HTML_XMP_ON:
+ eMode = AM_SPACE;
+ break;
+ case HTML_ADDRESS_ON:
+ case HTML_DT_ON:
+ case HTML_DD_ON:
+ eMode = AM_SOFTNOSPACE;
+ break;
+ default:
+ ASSERT( !this, "unbekannte Vorlage" );
+ break;
+ }
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( eMode );
+ else if( AM_SPACE==eMode )
+ AddParSpace();
+
+ // den aktuellen Kontext vom Stack holen
+ _HTMLAttrContext *pCntxt = PopContext( static_cast< sal_uInt16 >(nToken & ~1) );
+
+ // und noch Attribute beenden
+ if( pCntxt )
+ {
+ EndContext( pCntxt );
+ SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
+ delete pCntxt;
+ }
+
+ // und die bisherige Vorlage setzen
+ SetTxtCollAttrs();
+}
+
+/* */
+
+void SwHTMLParser::NewDefList()
+{
+ String aId, aStyle, aClass, aLang, aDir;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ // einen neuen Absatz aufmachen
+ BOOL bSpace = (GetNumInfo().GetDepth() + nDefListDeep) == 0;
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( bSpace ? AM_SPACE : AM_SOFTNOSPACE );
+ else if( bSpace )
+ AddParSpace();
+
+ // ein Level mehr
+ nDefListDeep++;
+
+
+ BOOL bInDD = FALSE, bNotInDD = FALSE;
+ USHORT nPos = aContexts.Count();
+ while( !bInDD && !bNotInDD && nPos>nContextStMin )
+ {
+ USHORT nCntxtToken = aContexts[--nPos]->GetToken();
+ switch( nCntxtToken )
+ {
+ case HTML_DEFLIST_ON:
+ case HTML_DIRLIST_ON:
+ case HTML_MENULIST_ON:
+ case HTML_ORDERLIST_ON:
+ case HTML_UNORDERLIST_ON:
+ bNotInDD = TRUE;
+ break;
+ case HTML_DD_ON:
+ bInDD = TRUE;
+ break;
+ }
+ }
+
+
+ // ... und in einem Kontext merken
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_DEFLIST_ON );
+
+ // darin auch die Raender merken
+ sal_uInt16 nLeft=0, nRight=0;
+ short nIndent=0;
+ GetMarginsFromContext( nLeft, nRight, nIndent );
+
+ // Die Einrueckung, die sich schon aus einem DL-ergibt, entspricht der
+ // eines DT auf dem aktuellen Level, und die entspricht der eines
+ // DD auf dem Level davor. Fue einen Level >=2 muss also ein DD-Abstand
+ // hinzugefuegt werden
+ if( !bInDD && nDefListDeep > 1 )
+ {
+
+ // und den der DT-Vorlage des aktuellen Levels
+ SvxLRSpaceItem rLRSpace =
+ pCSS1Parser->GetTxtFmtColl( RES_POOLCOLL_HTML_DD, aEmptyStr )
+ ->GetLRSpace();
+ nLeft = nLeft + static_cast< sal_uInt16 >(rLRSpace.GetTxtLeft());
+ }
+
+ pCntxt->SetMargins( nLeft, nRight, nIndent );
+
+ // Styles parsen
+ if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+ InsertAttrs( aItemSet, aPropInfo, pCntxt );
+ }
+ }
+
+ PushContext( pCntxt );
+
+ // die Attribute der neuen Vorlage setzen
+ if( nDefListDeep > 1 )
+ SetTxtCollAttrs( pCntxt );
+}
+
+void SwHTMLParser::EndDefList()
+{
+ BOOL bSpace = (GetNumInfo().GetDepth() + nDefListDeep) == 1;
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( bSpace ? AM_SPACE : AM_SOFTNOSPACE );
+ else if( bSpace )
+ AddParSpace();
+
+ // ein Level weniger
+ if( nDefListDeep > 0 )
+ nDefListDeep--;
+
+ // den aktuellen Kontext vom Stack holen
+ _HTMLAttrContext *pCntxt = PopContext( HTML_DEFLIST_ON );
+
+ // und noch Attribute beenden
+ if( pCntxt )
+ {
+ EndContext( pCntxt );
+ SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
+ delete pCntxt;
+ }
+
+ // und Vorlage setzen
+ SetTxtCollAttrs();
+}
+
+void SwHTMLParser::NewDefListItem( int nToken )
+{
+ // festellen, ob das DD/DT in einer DL vorkommt
+ BOOL bInDefList = FALSE, bNotInDefList = FALSE;
+ USHORT nPos = aContexts.Count();
+ while( !bInDefList && !bNotInDefList && nPos>nContextStMin )
+ {
+ USHORT nCntxtToken = aContexts[--nPos]->GetToken();
+ switch( nCntxtToken )
+ {
+ case HTML_DEFLIST_ON:
+ bInDefList = TRUE;
+ break;
+ case HTML_DIRLIST_ON:
+ case HTML_MENULIST_ON:
+ case HTML_ORDERLIST_ON:
+ case HTML_UNORDERLIST_ON:
+ bNotInDefList = TRUE;
+ break;
+ }
+ }
+
+ // wenn nicht, implizit eine neue DL aufmachen
+ if( !bInDefList )
+ {
+ nDefListDeep++;
+ ASSERT( !nOpenParaToken,
+ "Jetzt geht ein offenes Absatz-Element verloren" );
+ nOpenParaToken = static_cast< sal_uInt16 >(nToken);
+ }
+
+ NewTxtFmtColl( nToken, static_cast< USHORT >(nToken==HTML_DD_ON ? RES_POOLCOLL_HTML_DD
+ : RES_POOLCOLL_HTML_DT) );
+}
+
+void SwHTMLParser::EndDefListItem( int nToken, BOOL bSetColl,
+ BOOL /*bLastPara*/ )
+{
+ // einen neuen Absatz aufmachen
+ if( !nToken && pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_SOFTNOSPACE );
+
+ // Kontext zu dem Token suchen und vom Stack holen
+ nToken &= ~1;
+ _HTMLAttrContext *pCntxt = 0;
+ USHORT nPos = aContexts.Count();
+ while( !pCntxt && nPos>nContextStMin )
+ {
+ USHORT nCntxtToken = aContexts[--nPos]->GetToken();
+ switch( nCntxtToken )
+ {
+ case HTML_DD_ON:
+ case HTML_DT_ON:
+ if( !nToken || nToken == nCntxtToken )
+ {
+ pCntxt = aContexts[nPos];
+ aContexts.Remove( nPos, 1 );
+ }
+ break;
+ case HTML_DEFLIST_ON:
+ // keine DD/DT ausserhalb der aktuelen DefListe betrachten
+ case HTML_DIRLIST_ON:
+ case HTML_MENULIST_ON:
+ case HTML_ORDERLIST_ON:
+ case HTML_UNORDERLIST_ON:
+ // und auch nicht ausserhalb einer anderen Liste
+ nPos = nContextStMin;
+ break;
+ }
+ }
+
+ // und noch Attribute beenden
+ if( pCntxt )
+ {
+ EndContext( pCntxt );
+ SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
+ delete pCntxt;
+ }
+
+ // und die bisherige Vorlage setzen
+ if( bSetColl )
+ SetTxtCollAttrs();
+}
+
+/* */
+
+BOOL SwHTMLParser::HasCurrentParaFlys( BOOL bNoSurroundOnly,
+ BOOL bSurroundOnly ) const
+{
+ // bNoSurroundOnly: Der Absatz enthaelt mindestens einen Rahmen
+ // ohne Umlauf
+ // bSurroundOnly: Der Absatz enthaelt mindestens einen Rahmen
+ // mit Umlauf aber keinen ohne Umlauf
+ // sonst: Der Absatz enthaelt irgendeinen Rahmen
+ SwNodeIndex& rNodeIdx = pPam->GetPoint()->nNode;
+
+ const SwSpzFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
+
+ BOOL bFound = FALSE;
+ for ( USHORT i=0; i<rFrmFmtTbl.Count(); i++ )
+ {
+ SwFrmFmt *const pFmt = rFrmFmtTbl[i];
+ SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
+ // Ein Rahmen wurde gefunden, wenn
+ // - er absatzgebunden ist, und
+ // - im aktuellen Absatz verankert ist, und
+ // - jeder absatzgebunene Rahmen zaehlt, oder
+ // - (nur Rahmen oder umlauf zaehlen und ) der Rahmen keinen
+ // Umlauf besitzt
+ SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
+ if (pAPos &&
+ ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
+ (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
+ pAPos->nNode == rNodeIdx )
+ {
+ if( !(bNoSurroundOnly || bSurroundOnly) )
+ {
+ bFound = TRUE;
+ break;
+ }
+ else
+ {
+ // fix #42282#: Wenn Rahmen mit Umlauf gesucht sind,
+ // auch keine mit Durchlauf beachten. Dabei handelt es
+ // sich (noch) um HIDDEN-Controls, und denen weicht man
+ // besser auch nicht aus.
+ SwSurround eSurround = pFmt->GetSurround().GetSurround();
+ if( bNoSurroundOnly )
+ {
+ if( SURROUND_NONE==eSurround )
+ {
+ bFound = TRUE;
+ break;
+ }
+ }
+ if( bSurroundOnly )
+ {
+ if( SURROUND_NONE==eSurround )
+ {
+ bFound = FALSE;
+ break;
+ }
+ else if( SURROUND_THROUGHT!=eSurround )
+ {
+ bFound = TRUE;
+ // weitersuchen: Es koennten ja noch welche ohne
+ // Umlauf kommen ...
+ }
+ }
+ }
+ }
+ }
+
+ return bFound;
+}
+
+/* */
+
+// die speziellen Methoden zum Einfuegen von Objecten
+
+const SwFmtColl *SwHTMLParser::GetCurrFmtColl() const
+{
+ const SwCntntNode* pCNd = pPam->GetCntntNode();
+ return &pCNd->GetAnyFmtColl();
+}
+
+
+void SwHTMLParser::SetTxtCollAttrs( _HTMLAttrContext *pContext )
+{
+ SwTxtFmtColl *pCollToSet = 0; // die zu setzende Vorlage
+ SfxItemSet *pItemSet = 0; // der Set fuer harte Attrs
+ USHORT nTopColl = pContext ? pContext->GetTxtFmtColl() : 0;
+ const String& rTopClass = pContext ? pContext->GetClass() : (const String&) aEmptyStr;
+ USHORT nDfltColl = RES_POOLCOLL_TEXT;
+
+ BOOL bInPRE=FALSE; // etwas Kontext Info
+
+ USHORT nLeftMargin = 0, nRightMargin = 0; // die Einzuege und
+ short nFirstLineIndent = 0; // Abstaende
+ USHORT i;
+
+ for( i = nContextStAttrMin; i < aContexts.Count(); i++ )
+ {
+ const _HTMLAttrContext *pCntxt = aContexts[i];
+
+ USHORT nColl = pCntxt->GetTxtFmtColl();
+ if( nColl )
+ {
+ // Es gibt eine Vorlage, die zu setzen ist. Dann
+ // muss zunaechst einmal entschieden werden,
+ // ob die Vorlage auch gesetzt werden kann
+ BOOL bSetThis = TRUE;
+ switch( nColl )
+ {
+ case USHORT(RES_POOLCOLL_HTML_PRE):
+ bInPRE = TRUE;
+ break;
+ case USHORT(RES_POOLCOLL_TEXT):
+ // <TD><P CLASS=xxx> muss TD.xxx werden
+ if( nDfltColl==RES_POOLCOLL_TABLE ||
+ nDfltColl==RES_POOLCOLL_TABLE_HDLN )
+ nColl = nDfltColl;
+ break;
+ case USHORT(RES_POOLCOLL_HTML_HR):
+ // <HR> auch in <PRE> als Vorlage setzen, sonst kann man sie
+ // nicht mehr exportieren
+ break;
+ default:
+ if( bInPRE )
+ bSetThis = FALSE;
+ break;
+ }
+
+ SwTxtFmtColl *pNewColl =
+ pCSS1Parser->GetTxtFmtColl( nColl, pCntxt->GetClass() );
+
+ if( bSetThis )
+ {
+ // wenn jetzt eine andere Vorlage gesetzt werden soll als
+ // bisher, muss die bishere Vorlage durch harte Attributierung
+ // ersetzt werden
+
+ if( pCollToSet )
+ {
+ // die Attribute, die die bisherige Vorlage setzt
+ // hart einfuegen
+ if( !pItemSet )
+ pItemSet = new SfxItemSet( pCollToSet->GetAttrSet() );
+ else
+ {
+ const SfxItemSet& rCollSet = pCollToSet->GetAttrSet();
+ SfxItemSet aItemSet( *rCollSet.GetPool(),
+ rCollSet.GetRanges() );
+ aItemSet.Set( rCollSet );
+ pItemSet->Put( aItemSet );
+ }
+ // aber die Attribute, die aktuelle Vorlage setzt
+ // entfernen, weil sie sonst spaeter ueberschrieben
+ // werden
+ pItemSet->Differentiate( pNewColl->GetAttrSet() );
+ }
+
+ pCollToSet = pNewColl;
+ }
+ else
+ {
+ // hart Attributieren
+ if( !pItemSet )
+ pItemSet = new SfxItemSet( pNewColl->GetAttrSet() );
+ else
+ {
+ const SfxItemSet& rCollSet = pNewColl->GetAttrSet();
+ SfxItemSet aItemSet( *rCollSet.GetPool(),
+ rCollSet.GetRanges() );
+ aItemSet.Set( rCollSet );
+ pItemSet->Put( aItemSet );
+ }
+ }
+ }
+ else
+ {
+ // vielliecht gibt es ja eine Default-Vorlage?
+ nColl = pCntxt->GetDfltTxtFmtColl();
+ if( nColl )
+ nDfltColl = nColl;
+ }
+
+ // ggf. neue Absatz-Einzuege holen
+ if( pCntxt->IsLRSpaceChanged() )
+ {
+ USHORT nLeft=0, nRight=0;
+
+ pCntxt->GetMargins( nLeft, nRight, nFirstLineIndent );
+ nLeftMargin = nLeft;
+ nRightMargin = nRight;
+ }
+ }
+
+ // wenn im aktuellen Kontext eine neue Vorlage gesetzt werden soll,
+ // muessen deren Absatz-Abstaende noch in den Kontext eingetragen werden
+ if( pContext && nTopColl )
+ {
+ // <TD><P CLASS=xxx> muss TD.xxx werden
+ if( nTopColl==RES_POOLCOLL_TEXT &&
+ (nDfltColl==RES_POOLCOLL_TABLE ||
+ nDfltColl==RES_POOLCOLL_TABLE_HDLN) )
+ nTopColl = nDfltColl;
+
+ const SwTxtFmtColl *pTopColl =
+ pCSS1Parser->GetTxtFmtColl( nTopColl, rTopClass );
+ const SfxItemSet& rItemSet = pTopColl->GetAttrSet();
+ const SfxPoolItem *pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState(RES_LR_SPACE,TRUE, &pItem) )
+ {
+ const SvxLRSpaceItem *pLRItem =
+ (const SvxLRSpaceItem *)pItem;
+
+ sal_Int32 nLeft = pLRItem->GetTxtLeft();
+ sal_Int32 nRight = pLRItem->GetRight();
+ nFirstLineIndent = pLRItem->GetTxtFirstLineOfst();
+
+ // In Definitions-Listen enthalten die Abstaende auch die der
+ // vorhergehenden Level
+ if( RES_POOLCOLL_HTML_DD == nTopColl )
+ {
+ const SvxLRSpaceItem& rDTLRSpace = pCSS1Parser
+ ->GetTxtFmtColl( RES_POOLCOLL_HTML_DT, aEmptyStr )
+ ->GetLRSpace();
+ nLeft -= rDTLRSpace.GetTxtLeft();
+ nRight -= rDTLRSpace.GetRight();
+ }
+ else if( RES_POOLCOLL_HTML_DT == nTopColl )
+ {
+ nLeft = 0;
+ nRight = 0;
+ }
+
+ // die Absatz-Abstaende addieren sich
+ nLeftMargin = nLeftMargin + static_cast< sal_uInt16 >(nLeft);
+ nRightMargin = nRightMargin + static_cast< sal_uInt16 >(nRight);
+
+ pContext->SetMargins( nLeftMargin, nRightMargin,
+ nFirstLineIndent );
+ }
+ if( SFX_ITEM_SET == rItemSet.GetItemState(RES_UL_SPACE,TRUE, &pItem) )
+ {
+ const SvxULSpaceItem *pULItem =
+ (const SvxULSpaceItem *)pItem;
+ pContext->SetULSpace( pULItem->GetUpper(), pULItem->GetLower() );
+ }
+ }
+
+ // wenn gar keine Vorlage im Kontext gesetzt ist, Textkoerper nehmen
+ if( !pCollToSet )
+ {
+ pCollToSet = pCSS1Parser->GetTxtCollFromPool( nDfltColl );
+ const SvxLRSpaceItem& rLRItem = pCollToSet->GetLRSpace();
+ if( !nLeftMargin )
+ nLeftMargin = static_cast< sal_uInt16 >(rLRItem.GetTxtLeft());
+ if( !nRightMargin )
+ nRightMargin = static_cast< sal_uInt16 >(rLRItem.GetRight());
+ if( !nFirstLineIndent )
+ nFirstLineIndent = rLRItem.GetTxtFirstLineOfst();
+ }
+
+ // bisherige harte Attributierung des Absatzes entfernen
+ if( aParaAttrs.Count() )
+ {
+ for( i=0; i<aParaAttrs.Count(); i++ )
+ aParaAttrs[i]->Invalidate();
+
+ aParaAttrs.Remove( 0, aParaAttrs.Count() );
+ }
+
+ // Die Vorlage setzen
+ pDoc->SetTxtFmtColl( *pPam, pCollToSet );
+
+ // ggf. noch den Absatz-Einzug korrigieren
+ const SvxLRSpaceItem& rLRItem = pCollToSet->GetLRSpace();
+ BOOL bSetLRSpace;
+
+ bSetLRSpace = nLeftMargin != rLRItem.GetTxtLeft() ||
+ nFirstLineIndent != rLRItem.GetTxtFirstLineOfst() ||
+ nRightMargin != rLRItem.GetRight();
+
+ if( bSetLRSpace )
+ {
+ SvxLRSpaceItem aLRItem( rLRItem );
+ aLRItem.SetTxtLeft( nLeftMargin );
+ aLRItem.SetRight( nRightMargin );
+ aLRItem.SetTxtFirstLineOfst( nFirstLineIndent );
+ if( pItemSet )
+ pItemSet->Put( aLRItem );
+ else
+ {
+ NewAttr( &aAttrTab.pLRSpace, aLRItem );
+ aAttrTab.pLRSpace->SetLikePara();
+ aParaAttrs.Insert( aAttrTab.pLRSpace, aParaAttrs.Count() );
+ EndAttr( aAttrTab.pLRSpace, 0, FALSE );
+ }
+ }
+
+ // und nun noch die Attribute setzen
+ if( pItemSet )
+ {
+ InsertParaAttrs( *pItemSet );
+ delete pItemSet;
+ }
+}
+
+/* */
+
+void SwHTMLParser::NewCharFmt( int nToken )
+{
+ String aId, aStyle, aClass, aLang, aDir;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ case HTML_O_LANG:
+ aLang = pOption->GetString();
+ break;
+ case HTML_O_DIR:
+ aDir = pOption->GetString();
+ break;
+ }
+ }
+
+ // einen neuen Kontext anlegen
+ _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
+
+ // die Vorlage setzen und im Kontext merken
+ SwCharFmt* pCFmt = pCSS1Parser->GetChrFmt( static_cast< sal_uInt16 >(nToken), aClass );
+ ASSERT( pCFmt, "keine Zeichenvorlage zu Token gefunden" );
+
+
+ // Styles parsen (zu Class siehe auch NewPara)
+ if( HasStyleOptions( aStyle, aId, aEmptyStr, &aLang, &aDir ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aEmptyStr, aItemSet, aPropInfo, &aLang, &aDir ) )
+ {
+ ASSERT( !aClass.Len() || !pCSS1Parser->GetClass( aClass ),
+ "Class wird nicht beruecksichtigt" );
+ DoPositioning( aItemSet, aPropInfo, pCntxt );
+ InsertAttrs( aItemSet, aPropInfo, pCntxt, TRUE );
+ }
+ }
+
+ // Zeichen-Vorlagen werden in einem eigenen Stack gehalten und
+ // koennen nie durch Styles eingefuegt werden. Das Attribut ist deshalb
+ // auch gar nicht im CSS1-Which-Range enthalten
+ if( pCFmt )
+ InsertAttr( &aAttrTab.pCharFmts, SwFmtCharFmt( pCFmt ), pCntxt );
+
+ // den Kontext merken
+ PushContext( pCntxt );
+}
+
+
+/* */
+
+void SwHTMLParser::InsertSpacer()
+{
+ // und es ggf. durch die Optionen veraendern
+ String aId;
+ sal_Int16 eVertOri = text::VertOrientation::TOP;
+ sal_Int16 eHoriOri = text::HoriOrientation::NONE;
+ Size aSize( 0, 0);
+ long nSize = 0;
+ BOOL bPrcWidth = FALSE;
+ BOOL bPrcHeight = FALSE;
+ USHORT nType = HTML_SPTYPE_HORI;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_TYPE:
+ pOption->GetEnum( nType, aHTMLSpacerTypeTable );
+ break;
+ case HTML_O_ALIGN:
+ eVertOri =
+ pOption->GetEnum( aHTMLImgVAlignTable,
+ eVertOri );
+ eHoriOri =
+ pOption->GetEnum( aHTMLImgHAlignTable,
+ eHoriOri );
+ break;
+ case HTML_O_WIDTH:
+ // erstmal nur als Pixelwerte merken!
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Width() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_HEIGHT:
+ // erstmal nur als Pixelwerte merken!
+ bPrcHeight = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ aSize.Height() = (long)pOption->GetNumber();
+ break;
+ case HTML_O_SIZE:
+ // erstmal nur als Pixelwerte merken!
+ nSize = pOption->GetNumber();
+ break;
+ }
+ }
+
+ switch( nType )
+ {
+ case HTML_SPTYPE_BLOCK:
+ {
+ // einen leeren Textrahmen anlegen
+
+ // den Itemset holen
+ SfxItemSet aFrmSet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
+ if( !IsNewDoc() )
+ Reader::ResetFrmFmtAttrs( aFrmSet );
+
+ // den Anker und die Ausrichtung setzen
+ SetAnchorAndAdjustment( eVertOri, eHoriOri, aFrmSet );
+
+ // und noch die Groesse des Rahmens
+ Size aDfltSz( MINFLY, MINFLY );
+ Size aSpace( 0, 0 );
+ SfxItemSet aDummyItemSet( pDoc->GetAttrPool(),
+ pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aDummyPropInfo;
+
+ SetFixSize( aSize, aDfltSz, bPrcWidth, bPrcHeight,
+ aDummyItemSet, aDummyPropInfo, aFrmSet );
+ SetSpace( aSpace, aDummyItemSet, aDummyPropInfo, aFrmSet );
+
+ // den Inhalt schuetzen
+ SvxProtectItem aProtectItem( RES_PROTECT) ;
+ aProtectItem.SetCntntProtect( TRUE );
+ aFrmSet.Put( aProtectItem );
+
+ // der Rahmen anlegen
+ RndStdIds eAnchorId =
+ ((const SwFmtAnchor &)aFrmSet.Get(RES_ANCHOR)).GetAnchorId();
+ SwFrmFmt *pFlyFmt = pDoc->MakeFlySection( eAnchorId,
+ pPam->GetPoint(), &aFrmSet );
+ // Ggf Frames anlegen und auto-geb. Rahmen registrieren
+ RegisterFlyFrm( pFlyFmt );
+ }
+ break;
+ case HTML_SPTYPE_VERT:
+ if( nSize > 0 )
+ {
+ if( nSize && Application::GetDefaultDevice() )
+ {
+ nSize = Application::GetDefaultDevice()
+ ->PixelToLogic( Size(0,nSize),
+ MapMode(MAP_TWIP) ).Height();
+ }
+
+ // einen Absatz-Abstand setzen
+ SwTxtNode *pTxtNode = 0;
+ if( !pPam->GetPoint()->nContent.GetIndex() )
+ {
+ // den unteren Absatz-Abstand des vorherigen Nodes aendern,
+ // wenn moeglich
+
+ SetAttr(); // noch offene Absatz-Attribute setzen
+
+ pTxtNode = pDoc->GetNodes()[pPam->GetPoint()->nNode.GetIndex()-1]
+ ->GetTxtNode();
+
+ // Wenn der Abstz davor kein Txtenode ist, dann wird jetzt
+ // ein leere Absatz angelegt, der eh schon eine Zeilenhoehe
+ // Abstand erzeugt.
+ if( !pTxtNode )
+ nSize = nSize>HTML_PARSPACE ? nSize-HTML_PARSPACE : 0;
+ }
+
+ if( pTxtNode )
+ {
+ SvxULSpaceItem aULSpace( (const SvxULSpaceItem&)pTxtNode
+ ->SwCntntNode::GetAttr( RES_UL_SPACE ) );
+ aULSpace.SetLower( aULSpace.GetLower() + (USHORT)nSize );
+ pTxtNode->SetAttr( aULSpace );
+ }
+ else
+ {
+ NewAttr( &aAttrTab.pULSpace, SvxULSpaceItem( 0, (USHORT)nSize, RES_UL_SPACE ) );
+ EndAttr( aAttrTab.pULSpace, 0, FALSE );
+
+ AppendTxtNode(); // nicht am Abstand drehen!
+ }
+ }
+ break;
+ case HTML_SPTYPE_HORI:
+ if( nSize > 0 )
+ {
+ // wenn der Absatz noch leer ist, einen Erstzeilen-Einzug
+ // setzen, sondern Sperrschrift ueber einem Space aufspannen
+
+ if( nSize && Application::GetDefaultDevice() )
+ {
+ nSize = Application::GetDefaultDevice()
+ ->PixelToLogic( Size(nSize,0),
+ MapMode(MAP_TWIP) ).Width();
+ }
+
+ if( !pPam->GetPoint()->nContent.GetIndex() )
+ {
+ USHORT nLeft=0, nRight=0;
+ short nIndent = 0;
+
+ GetMarginsFromContextWithNumBul( nLeft, nRight, nIndent );
+ nIndent = nIndent + (short)nSize;
+
+ SvxLRSpaceItem aLRItem( RES_LR_SPACE );
+ aLRItem.SetTxtLeft( nLeft );
+ aLRItem.SetRight( nRight );
+ aLRItem.SetTxtFirstLineOfst( nIndent );
+
+ NewAttr( &aAttrTab.pLRSpace, aLRItem );
+ EndAttr( aAttrTab.pLRSpace, 0, FALSE );
+ }
+ else
+ {
+ NewAttr( &aAttrTab.pKerning, SvxKerningItem( (short)nSize, RES_CHRATR_KERNING ) );
+ String aTmp( ' ' );
+ pDoc->InsertString( *pPam, aTmp );
+ EndAttr( aAttrTab.pKerning );
+ }
+ }
+ }
+}
+
+USHORT SwHTMLParser::ToTwips( USHORT nPixel ) const
+{
+ if( nPixel && Application::GetDefaultDevice() )
+ {
+ long nTwips = Application::GetDefaultDevice()->PixelToLogic(
+ Size( nPixel, nPixel ), MapMode( MAP_TWIP ) ).Width();
+ return nTwips <= USHRT_MAX ? (USHORT)nTwips : USHRT_MAX;
+ }
+ else
+ return nPixel;
+}
+
+SwTwips SwHTMLParser::GetCurrentBrowseWidth()
+{
+ const SwTwips nWidth = SwHTMLTableLayout::GetBrowseWidth( *pDoc );
+ if( nWidth )
+ return nWidth;
+
+ if( !aHTMLPageSize.Width() )
+ {
+ const SwFrmFmt& rPgFmt = pCSS1Parser->GetMasterPageDesc()->GetMaster();
+
+ const SwFmtFrmSize& rSz = rPgFmt.GetFrmSize();
+ const SvxLRSpaceItem& rLR = rPgFmt.GetLRSpace();
+ const SvxULSpaceItem& rUL = rPgFmt.GetULSpace();
+ const SwFmtCol& rCol = rPgFmt.GetCol();
+
+ aHTMLPageSize.Width() = rSz.GetWidth() - rLR.GetLeft() - rLR.GetRight();
+ aHTMLPageSize.Height() = rSz.GetHeight() - rUL.GetUpper() - rUL.GetLower();
+
+ if( 1 < rCol.GetNumCols() )
+ aHTMLPageSize.Width() /= rCol.GetNumCols();
+ }
+
+ return aHTMLPageSize.Width();
+}
+
+
+/* */
+
+void SwHTMLParser::InsertIDOption()
+{
+ String aId;
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ if( HTML_O_ID==pOption->GetToken() )
+ {
+ aId = pOption->GetString();
+ break;
+ }
+ }
+
+ if( aId.Len() )
+ InsertBookmark( aId );
+}
+
+
+/* */
+
+
+void SwHTMLParser::InsertLineBreak()
+{
+ // <BR CLEAR=xxx> wird wie folgt behandelt:
+ // 1.) Es werden nur nur absatzgebundene Rahmen betrachtet, die
+ // im aktuellen Absatz verankert sind.
+ // 2.) Fuer linksbuendig ausgerichtete Rahmen wird bei CLEAR=LEFT
+ // oder ALL und auf rechtsbuendige ausgerichtete Rahmen bei
+ // CLEAR=RIGHT oder ALL der Durchlauf wie folgt geaendert:
+ // 3.) Wenn der Absatz keinen Text enthaelt, bekommt der Rahmen keinen
+ // Umlauf
+ // 4.) sonst erhaelt ein links ausgerichteter Rahmen eine rechten
+ // "nur Anker" Umlauf und recht rechst ausg. Rahmen einen linken
+ // "nur Anker" Umlauf.
+ // 5.) wenn in einem nicht-leeren Absatz der Umlauf eines Rahmens
+ // geaendert wird, wird ein neuer Absatz aufgemacht
+ // 6.) Wenn von keinem Rahmen der Umlauf geaendert wird, wird ein
+ // harter Zeilenumbruch eingefuegt
+
+ String aId, aStyle, aClass; // die ID der Bookmark
+ BOOL bClearLeft = FALSE, bClearRight = FALSE;
+ BOOL bCleared = FALSE; // wurde ein CLEAR ausgefuehrt?
+
+ // dann holen wir mal die Optionen
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_CLEAR:
+ {
+ const String &aClear = pOption->GetString();
+ if( aClear.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_all ) )
+ {
+ bClearLeft = TRUE;
+ bClearRight = TRUE;
+ }
+ else if( aClear.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_left ) )
+ bClearLeft = TRUE;
+ else if( aClear.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_right ) )
+ bClearRight = TRUE;
+ }
+ break;
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_STYLE:
+ aStyle = pOption->GetString();
+ break;
+ case HTML_O_CLASS:
+ aClass = pOption->GetString();
+ break;
+ }
+ }
+
+ // CLEAR wird nur fuer den aktuellen Absaetz unterstuetzt
+ if( bClearLeft || bClearRight )
+ {
+ SwNodeIndex& rNodeIdx = pPam->GetPoint()->nNode;
+ SwTxtNode* pTxtNd = rNodeIdx.GetNode().GetTxtNode();
+ if( pTxtNd )
+ {
+ const SwSpzFrmFmts& rFrmFmtTbl = *pDoc->GetSpzFrmFmts();
+
+ for( USHORT i=0; i<rFrmFmtTbl.Count(); i++ )
+ {
+ SwFrmFmt *const pFmt = rFrmFmtTbl[i];
+ SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
+ SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
+ if (pAPos &&
+ ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
+ (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
+ pAPos->nNode == rNodeIdx &&
+ pFmt->GetSurround().GetSurround() != SURROUND_NONE )
+ {
+ sal_Int16 eHori = RES_DRAWFRMFMT == pFmt->Which()
+ ? text::HoriOrientation::LEFT
+ : pFmt->GetHoriOrient().GetHoriOrient();
+
+ SwSurround eSurround = SURROUND_PARALLEL;
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ {
+ if( bClearLeft && text::HoriOrientation::LEFT==eHori )
+ eSurround = SURROUND_RIGHT;
+ else if( bClearRight && text::HoriOrientation::RIGHT==eHori )
+ eSurround = SURROUND_LEFT;
+ }
+ else if( (bClearLeft && text::HoriOrientation::LEFT==eHori) ||
+ (bClearRight && text::HoriOrientation::RIGHT==eHori) )
+ {
+ eSurround = SURROUND_NONE;
+ }
+
+ if( SURROUND_PARALLEL != eSurround )
+ {
+ SwFmtSurround aSurround( eSurround );
+ if( SURROUND_NONE != eSurround )
+ aSurround.SetAnchorOnly( TRUE );
+ pFmt->SetFmtAttr( aSurround );
+ bCleared = TRUE;
+ }
+ } // Anker ist nicht im Node
+ } // Schleife ueber Fly-Frames
+ } // kein Text-Node
+ } // kein CLEAR
+
+ // Styles parsen
+ SvxFmtBreakItem aBreakItem( SVX_BREAK_NONE, RES_BREAK );
+ BOOL bBreakItem = FALSE;
+ if( HasStyleOptions( aStyle, aId, aClass ) )
+ {
+ SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
+ SvxCSS1PropertyInfo aPropInfo;
+
+ if( ParseStyleOptions( aStyle, aId, aClass, aItemSet, aPropInfo ) )
+ {
+ if( pCSS1Parser->SetFmtBreak( aItemSet, aPropInfo ) )
+ {
+ aBreakItem = (const SvxFmtBreakItem &)aItemSet.Get( RES_BREAK );
+ bBreakItem = TRUE;
+ }
+ if( aPropInfo.aId.Len() )
+ InsertBookmark( aPropInfo.aId );
+ }
+ }
+
+ if( bBreakItem && SVX_BREAK_PAGE_AFTER==aBreakItem.GetBreak() )
+ {
+ NewAttr( &aAttrTab.pBreak, aBreakItem );
+ EndAttr( aAttrTab.pBreak, 0, FALSE );
+ }
+
+ if( !bCleared && !bBreakItem )
+ {
+ // wenn kein CLEAR ausgefuehrt werden sollte oder konnte, wird
+ // ein Zeilenumbruch eingef?gt
+ String sTmp( (sal_Unicode)0x0a ); // make the Mac happy :-)
+ pDoc->InsertString( *pPam, sTmp );
+ }
+ else if( pPam->GetPoint()->nContent.GetIndex() )
+ {
+ // wenn ein Claer in einem nicht-leeren Absatz ausgefuehrt wurde,
+ // muss anschliessen ein neuer Absatz aufgemacht werden
+ // MIB 21.02.97: Eigentlich muesste man hier den unteren Absatz-
+ // Absatnd auf 0 drehen. Das geht aber bei sowas wie <BR ..><P>
+ // schief (>Netacpe). Deshalb lassen wir das erstmal.
+ AppendTxtNode( AM_NOSPACE );
+ }
+ if( bBreakItem && SVX_BREAK_PAGE_BEFORE==aBreakItem.GetBreak() )
+ {
+ NewAttr( &aAttrTab.pBreak, aBreakItem );
+ EndAttr( aAttrTab.pBreak, 0, FALSE );
+ }
+}
+
+void SwHTMLParser::InsertHorzRule()
+{
+ USHORT nSize = 0;
+ USHORT nWidth = 0;
+
+ SvxAdjust eAdjust = SVX_ADJUST_END;
+
+ BOOL bPrcWidth = FALSE;
+ BOOL bNoShade = FALSE;
+ BOOL bColor = FALSE;
+
+ Color aColor;
+ String aId;
+
+ // dann holen wir mal die Optionen
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[--i];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_ID:
+ aId = pOption->GetString();
+ break;
+ case HTML_O_SIZE:
+ nSize = (USHORT)pOption->GetNumber();
+ break;
+ case HTML_O_WIDTH:
+ bPrcWidth = (pOption->GetString().Search('%') != STRING_NOTFOUND);
+ nWidth = (USHORT)pOption->GetNumber();
+ if( bPrcWidth && nWidth>=100 )
+ {
+ // 100%-Linien sind der default-Fall (keine Attrs neotig)
+ nWidth = 0;
+ bPrcWidth = FALSE;
+ }
+ break;
+ case HTML_O_ALIGN:
+ eAdjust =
+ (SvxAdjust)pOption->GetEnum( aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
+ break;
+ case HTML_O_NOSHADE:
+ bNoShade = TRUE;
+ break;
+ case HTML_O_COLOR:
+ pOption->GetColor( aColor );
+ bColor = TRUE;
+ break;
+ }
+ }
+
+ if( pPam->GetPoint()->nContent.GetIndex() )
+ AppendTxtNode( AM_NOSPACE );
+ if( nOpenParaToken )
+ EndPara();
+ AppendTxtNode();
+ pPam->Move( fnMoveBackward );
+
+ // ... und in einem Kontext merken
+ _HTMLAttrContext *pCntxt =
+ new _HTMLAttrContext( HTML_HORZRULE, RES_POOLCOLL_HTML_HR, aEmptyStr );
+
+ PushContext( pCntxt );
+
+ // die neue Vorlage setzen
+ SetTxtCollAttrs( pCntxt );
+
+ // die harten Attribute an diesem Absatz werden nie mehr ungueltig
+ if( aParaAttrs.Count() )
+ aParaAttrs.Remove( 0, aParaAttrs.Count() );
+
+ if( nSize>0 || bColor || bNoShade )
+ {
+ // Farbe und/oder Breite der Linie setzen
+ if( !bColor )
+ aColor.SetColor( COL_GRAY );
+
+ SvxBorderLine aBorderLine( &aColor );
+ if( nSize )
+ {
+ long nPWidth = 0;
+ long nPHeight = (long)nSize;
+ SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
+ SvxCSS1Parser::SetBorderWidth( aBorderLine, (USHORT)nPHeight,
+ !bNoShade );
+ }
+ else if( bNoShade )
+ {
+ aBorderLine.SetOutWidth( DEF_LINE_WIDTH_2 );
+ }
+ else
+ {
+ aBorderLine.SetOutWidth( DEF_DOUBLE_LINE0_OUT );
+ aBorderLine.SetInWidth( DEF_DOUBLE_LINE0_IN );
+ aBorderLine.SetDistance( DEF_DOUBLE_LINE0_DIST );
+ }
+
+ SvxBoxItem aBoxItem(RES_BOX);
+ aBoxItem.SetLine( &aBorderLine, BOX_LINE_BOTTOM );
+ _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(), aBoxItem );
+ aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
+ }
+ if( nWidth )
+ {
+ // Wenn wir in keiner Tabelle sind, wird die Breitenangabe durch
+ // Absatz-Einzuege "getuerkt". In einer Tabelle macht das wenig
+ // Sinn. Um zu Vermeiden, dass die Linie bei der Breitenberechnung
+ // beruecksichtigt wird, bekommt sie aber trotzdem entsprechendes
+ // LRSpace-Item verpasst.
+#ifdef FIX41370
+ const SwFmtColl *pColl = GetCurrFmtColl();
+ SvxLRSpaceItem aLRItem( pColl->GetLRSpace() );
+#endif
+ if( !pTable )
+ {
+ // Laenge und Ausrichtung der Linie ueber Absatz-Einzuege "tuerken"
+ long nBrowseWidth = GetCurrentBrowseWidth();
+ nWidth = bPrcWidth ? (USHORT)((nWidth*nBrowseWidth) / 100)
+ : ToTwips( (USHORT)nBrowseWidth );
+ if( nWidth < MINLAY )
+ nWidth = MINLAY;
+
+ if( (long)nWidth < nBrowseWidth )
+ {
+#ifndef FIX41370
+ const SwFmtColl *pColl = GetCurrFmtColl();
+ SvxLRSpaceItem aLRItem( pColl->GetLRSpace() );
+#endif
+ long nDist = nBrowseWidth - nWidth;
+
+ switch( eAdjust )
+ {
+ case SVX_ADJUST_RIGHT:
+ aLRItem.SetTxtLeft( (USHORT)nDist );
+ break;
+ case SVX_ADJUST_LEFT:
+ aLRItem.SetRight( (USHORT)nDist );
+ break;
+ case SVX_ADJUST_CENTER:
+ default:
+ nDist /= 2;
+ aLRItem.SetTxtLeft( (USHORT)nDist );
+ aLRItem.SetRight( (USHORT)nDist );
+ break;
+ }
+
+#ifndef FIX41370
+ _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(), aLRItem );
+ aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
+#endif
+ }
+ }
+
+#ifdef FIX41370
+ _HTMLAttr* pTmp = new _HTMLAttr( *pPam->GetPoint(), aLRItem );
+ aSetAttrTab.Insert( pTmp, aSetAttrTab.Count() );
+#endif
+ }
+
+ // Bookmarks koennen nicht in Hyperlinks eingefueht werden
+ if( aId.Len() )
+ InsertBookmark( aId );
+
+ // den aktuellen Kontext vom Stack holen
+ _HTMLAttrContext *pPoppedContext = PopContext( HTML_HORZRULE );
+ ASSERT( pPoppedContext==pCntxt, "wo kommt denn da ein HR-Kontext her?" );
+ delete pPoppedContext;
+
+ pPam->Move( fnMoveForward );
+
+ // und im Absatz danach die dort aktuelle Vorlage setzen
+ SetTxtCollAttrs();
+}
+
+void SwHTMLParser::ParseMoreMetaOptions()
+{
+ String aName, aContent;
+ BOOL bHTTPEquiv = FALSE;
+
+ const HTMLOptions *pHTMLOptions = GetOptions();
+ for( USHORT i = pHTMLOptions->Count(); i; )
+ {
+ const HTMLOption *pOption = (*pHTMLOptions)[ --i ];
+ switch( pOption->GetToken() )
+ {
+ case HTML_O_NAME:
+ aName = pOption->GetString();
+ bHTTPEquiv = FALSE;
+ break;
+ case HTML_O_HTTPEQUIV:
+ aName = pOption->GetString();
+ bHTTPEquiv = TRUE;
+ break;
+ case HTML_O_CONTENT:
+ aContent = pOption->GetString();
+ break;
+ }
+ }
+
+ // Hier wird es etwas tricky: Wir wissen genau, da? die Dok-Info
+ // nicht geaendert wurde. Deshalb genuegt es, auf Generator und
+ // auf refresh abzufragen, um noch nicht verarbeitete Token zu finden,
+ // denn das sind die einzigen, die die Dok-Info nicht modifizieren.
+ if( aName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_generator ) ||
+ aName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_refresh ) ||
+ aName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_content_type ) ||
+ aName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_content_script_type ) )
+ return;
+
+ aContent.EraseAllChars( _CR );
+ aContent.EraseAllChars( _LF );
+
+ if( aName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_sdendnote ) )
+ {
+ FillEndNoteInfo( aContent );
+ return;
+ }
+
+ if( aName.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_sdfootnote ) )
+ {
+ FillFootNoteInfo( aContent );
+ return;
+ }
+
+ String sText(
+ String::CreateFromAscii(TOOLS_CONSTASCII_STRINGPARAM("HTML: <")) );
+ sText.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_meta) );
+ sText.Append( ' ' );
+ if( bHTTPEquiv )
+ sText.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_O_httpequiv) );
+ else
+ sText.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_O_name) );
+ sText.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("=\"") );
+ sText.Append( aName );
+ sText.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("\" ") );
+ sText.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_O_content) );
+ sText.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("=\"") );
+ sText.Append( aContent );
+ sText.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("\">") );
+
+ SwPostItField aPostItFld(
+ (SwPostItFieldType*)pDoc->GetSysFldType( RES_POSTITFLD ),
+ aEmptyStr, sText, DateTime() );
+ SwFmtFld aFmtFld( aPostItFld );
+ InsertAttr( aFmtFld );
+}
+
+/* */
+
+_HTMLAttr::_HTMLAttr( const SwPosition& rPos, const SfxPoolItem& rItem,
+ _HTMLAttr **ppHd ) :
+ nSttPara( rPos.nNode ),
+ nEndPara( rPos.nNode ),
+ nSttCntnt( rPos.nContent.GetIndex() ),
+ nEndCntnt(rPos.nContent.GetIndex() ),
+ bInsAtStart( TRUE ),
+ bLikePara( FALSE ),
+ bValid( TRUE ),
+ nCount( 1 ),
+ pNext( 0 ),
+ pPrev( 0 ),
+ ppHead( ppHd )
+{
+ pItem = rItem.Clone();
+}
+
+_HTMLAttr::_HTMLAttr( const _HTMLAttr &rAttr, const SwNodeIndex &rEndPara,
+ USHORT nEndCnt, _HTMLAttr **ppHd ) :
+ nSttPara( rAttr.nSttPara ),
+ nEndPara( rEndPara ),
+ nSttCntnt( rAttr.nSttCntnt ),
+ nEndCntnt( nEndCnt ),
+ bInsAtStart( rAttr.bInsAtStart ),
+ bLikePara( rAttr.bLikePara ),
+ bValid( rAttr.bValid ),
+ nCount( rAttr.nCount ),
+ pNext( 0 ),
+ pPrev( 0 ),
+ ppHead( ppHd )
+{
+ pItem = rAttr.pItem->Clone();
+}
+
+_HTMLAttr::~_HTMLAttr()
+{
+ delete pItem;
+}
+
+_HTMLAttr *_HTMLAttr::Clone( const SwNodeIndex& rEndPara, USHORT nEndCnt ) const
+{
+ // das Attribut mit der alten Start-Position neu anlegen
+ _HTMLAttr *pNew = new _HTMLAttr( *this, rEndPara, nEndCnt, ppHead );
+
+ // die Previous-Liste muss uebernommen werden, die Next-Liste nicht!
+ pNew->pPrev = pPrev;
+
+ return pNew;
+}
+
+void _HTMLAttr::Reset( const SwNodeIndex& rSttPara, USHORT nSttCnt,
+ _HTMLAttr **ppHd )
+{
+ // den Anfang (und das Ende) neu setzen
+ nSttPara = rSttPara;
+ nSttCntnt = nSttCnt;
+ nEndPara = rSttPara;
+ nEndCntnt = nSttCnt;
+
+ // den Head korrigieren und die Verkettungen aufheben
+ pNext = 0;
+ pPrev = 0;
+ ppHead = ppHd;
+}
+
+void _HTMLAttr::InsertPrev( _HTMLAttr *pPrv )
+{
+ ASSERT( !pPrv->pNext || pPrv->pNext == this,
+ "_HTMLAttr::InsertPrev: pNext falsch" );
+ pPrv->pNext = 0;
+
+ ASSERT( 0 == pPrv->ppHead || ppHead == pPrv->ppHead,
+ "_HTMLAttr::InsertPrev: ppHead falsch" );
+ pPrv->ppHead = 0;
+
+ _HTMLAttr *pAttr = this;
+ while( pAttr->GetPrev() )
+ pAttr = pAttr->GetPrev();
+
+ pAttr->pPrev = pPrv;
+}
+
+bool SwHTMLParser::ParseMetaOptions(
+ const uno::Reference<document::XDocumentProperties> & i_xDocProps,
+ SvKeyValueIterator *i_pHeader )
+{
+ // always call base ParseMetaOptions, it sets the encoding (#i96700#)
+ bool ret( HTMLParser::ParseMetaOptions(i_xDocProps, i_pHeader) );
+ if (!ret && IsNewDoc())
+ {
+ ParseMoreMetaOptions();
+ }
+ return ret;
+}
+
+// override so we can parse DOCINFO field subtypes INFO[1-4]
+void SwHTMLParser::AddMetaUserDefined( ::rtl::OUString const & i_rMetaName )
+{
+ // unless we already have 4 names, append the argument to m_InfoNames
+ ::rtl::OUString* pName // the first empty string in m_InfoNames
+ (!m_InfoNames[0].getLength() ? &m_InfoNames[0] :
+ (!m_InfoNames[1].getLength() ? &m_InfoNames[1] :
+ (!m_InfoNames[2].getLength() ? &m_InfoNames[2] :
+ (!m_InfoNames[3].getLength() ? &m_InfoNames[3] : 0 ))));
+ if (pName)
+ {
+ (*pName) = i_rMetaName;
+ }
+}
+
diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx
new file mode 100644
index 000000000000..e7d684842beb
--- /dev/null
+++ b/sw/source/filter/html/swhtml.hxx
@@ -0,0 +1,1040 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _SWHTML_HXX
+#define _SWHTML_HXX
+
+#if !defined(_SVSTDARR_XUB_STRLEN_DECL) || !defined(_SVSTDARR_LONGS_DECL) || \
+ !defined(_SVSTDARR_USHORTS_DECL) || !defined(_SVSTDARR_STRINGSDTOR_DECL)
+#ifndef _SVSTDARR_XUB_STRLEN_DECL
+#define _SVSTDARR_XUB_STRLEN
+#endif
+#ifndef _SVSTDARR_LONGS_DECL
+#define _SVSTDARR_LONGS
+#endif
+#ifndef _SVSTDARR_USHORTS_DECL
+#define _SVSTDARR_USHORTS
+#endif
+#ifndef _SVSTDARR_STRINGSDTOR_DECL
+#define _SVSTDARR_STRINGSDTOR
+#endif
+#include <svl/svstdarr.hxx>
+#endif
+#include <tools/urlobj.hxx>
+#include <sfx2/sfxhtml.hxx>
+#include <svl/macitem.hxx>
+#include <editeng/svxenum.hxx>
+#include <fmtornt.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/form/XFormComponent.hpp>
+#include <pam.hxx>
+
+#include "calbck.hxx"
+#include "htmlvsh.hxx"
+
+class SfxMedium;
+class SfxViewFrame;
+class SdrObject;
+class SvxMacroTableDtor;
+class SvStringsDtor;
+class SwDoc;
+class SwPaM;
+class ViewShell;
+class SwStartNode;
+class SwFmtColl;
+class SwField;
+class SwHTMLForm_Impl;
+class SwApplet_Impl;
+struct SwHTMLFootEndNote_Impl;
+class HTMLTableCnts;
+struct SwPendingStack;
+class SvxCSS1PropertyInfo;
+
+#define HTML_PARSPACE (MM50)
+
+#define HTML_DFLT_IMG_WIDTH (MM50*4)
+#define HTML_DFLT_IMG_HEIGHT (MM50*2)
+
+// ein par Sachen, die man oefter mal braucht
+extern HTMLOptionEnum __FAR_DATA aHTMLPAlignTable[];
+extern HTMLOptionEnum __FAR_DATA aHTMLImgHAlignTable[];
+extern HTMLOptionEnum __FAR_DATA aHTMLImgVAlignTable[];
+
+
+// der Attribut Stack:
+
+class _HTMLAttr;
+typedef _HTMLAttr *_HTMLAttrPtr;
+SV_DECL_PTRARR( _HTMLAttrs, _HTMLAttrPtr, 5, 5 )
+
+class _HTMLAttr
+{
+ friend class SwHTMLParser;
+ friend class _CellSaveStruct;
+
+ SwNodeIndex nSttPara, nEndPara;
+ xub_StrLen nSttCntnt, nEndCntnt;
+ sal_Bool bInsAtStart : 1;
+ sal_Bool bLikePara : 1; // Attribut ueber dem gesamten Absatz setzen
+ sal_Bool bValid : 1; // ist das Attribut gueltig?
+
+ SfxPoolItem* pItem;
+ sal_uInt16 nCount; // Anzahl noch zu schliessender Attrs mit einem Wert
+ _HTMLAttr *pNext; // noch zu schliessene Attrs mit unterschiedl. Werten
+ _HTMLAttr *pPrev; // bereits geschlossene aber noch nicht gesetze Attrs
+ _HTMLAttr **ppHead; // der Listenkopf
+
+ _HTMLAttr( const SwPosition& rPos, const SfxPoolItem& rItem,
+ _HTMLAttr **pHd=0 );
+
+ _HTMLAttr( const _HTMLAttr &rAttr, const SwNodeIndex &rEndPara,
+ xub_StrLen nEndCnt, _HTMLAttr **pHd );
+
+public:
+
+ ~_HTMLAttr();
+
+ _HTMLAttr *Clone( const SwNodeIndex& rEndPara, xub_StrLen nEndCnt ) const;
+ void Reset( const SwNodeIndex& rSttPara, xub_StrLen nSttCnt,
+ _HTMLAttr **pHd );
+ inline void SetStart( const SwPosition& rPos );
+
+ sal_uInt32 GetSttParaIdx() const { return nSttPara.GetIndex(); }
+ sal_uInt32 GetEndParaIdx() const { return nEndPara.GetIndex(); }
+
+ const SwNodeIndex& GetSttPara() const { return nSttPara; }
+ const SwNodeIndex& GetEndPara() const { return nEndPara; }
+
+ xub_StrLen GetSttCnt() const { return nSttCntnt; }
+ xub_StrLen GetEndCnt() const { return nEndCntnt; }
+
+ sal_Bool IsLikePara() const { return bLikePara; }
+ void SetLikePara( sal_Bool bPara=sal_True ) { bLikePara = bPara; }
+
+ SfxPoolItem& GetItem() { return *pItem; }
+ const SfxPoolItem& GetItem() const { return *pItem; }
+
+ _HTMLAttr *GetNext() const { return pNext; }
+ void InsertNext( _HTMLAttr *pNxt ) { pNext = pNxt; }
+
+ _HTMLAttr *GetPrev() const { return pPrev; }
+ void InsertPrev( _HTMLAttr *pPrv );
+ void ClearPrev() { pPrev = 0; }
+
+ void SetHead( _HTMLAttr **ppHd ) { ppHead = ppHd; }
+
+ // Beim Setzen von Attributen aus Vorlagen kann es passieren,
+ // dass Attribute doch nicht mehr gesetzt werden sollen. Die zu loeschen
+ // waere sehr aufwendig, da man nicht so genau weiss, wo sie eingekettet
+ // sind. Sie werden deshalb einfach invalidiert und erst beim naechsten
+ // _SetAttr() geloescht.
+ void Invalidate() { bValid = sal_False; }
+ sal_Bool IsValid() const { return bValid; }
+};
+
+// Tabelle der Attribute: Hier ist die Reihenfolge wichtig: Die Attribute
+// vorne in der Tabelle werden in EndAllAttrs auch zuerst gesetzt.
+struct _HTMLAttrTable
+{
+ _HTMLAttr
+ *pKeep, // ::com::sun::star::frame::Frame-Attribure
+ *pBox,
+ *pBrush,
+ *pBreak,
+ *pPageDesc,
+
+ *pLRSpace, // Absatz-Attribute
+ *pULSpace,
+ *pLineSpacing,
+ *pAdjust,
+ *pDropCap,
+ *pSplit,
+ *pWidows,
+ *pOrphans,
+ *pDirection,
+
+ *pCharFmts, // Text-Attribute
+ *pINetFmt,
+
+ *pBold, // Zeichen-Attribute
+ *pBoldCJK,
+ *pBoldCTL,
+ *pItalic,
+ *pItalicCJK,
+ *pItalicCTL,
+ *pStrike,
+ *pUnderline,
+ *pBlink,
+ *pFont,
+ *pFontCJK,
+ *pFontCTL,
+ *pFontHeight,
+ *pFontHeightCJK,
+ *pFontHeightCTL,
+ *pFontColor,
+ *pEscapement,
+ *pCaseMap,
+ *pKerning, // (nur fuer SPACER)
+ *pCharBrush, // Zeichen-Hintergrund
+ *pLanguage,
+ *pLanguageCJK,
+ *pLanguageCTL
+ ;
+};
+
+class _HTMLAttrContext_SaveDoc;
+
+enum SwHTMLAppendMode {
+ AM_NORMAL, // keine Absatz-Abstand-Behandlung
+ AM_NOSPACE, // Abstand hart auf 0cm setzen
+ AM_SPACE, // Abstand hart auf 0.5cm setzen
+ AM_SOFTNOSPACE, // Abstand nicht setzen aber 0cm merken
+ AM_NONE // gar kein Append
+};
+
+class _HTMLAttrContext
+{
+ _HTMLAttrs aAttrs; // die in dem Kontext gestarteten Attribute
+
+ String aClass; // die Klasse des Kontexts
+
+ _HTMLAttrContext_SaveDoc *pSaveDocContext;
+ SfxItemSet *pFrmItemSet;
+
+ sal_uInt16 nToken; // das Token, zu dem der Kontext gehoehrt
+
+ sal_uInt16 nTxtFmtColl; // eine in dem Kontext begonnene Vorlage oder 0
+
+ sal_uInt16 nLeftMargin; // ein veraenderter linker Rand
+ sal_uInt16 nRightMargin; // ein veraenderter rechter Rand
+ sal_uInt16 nFirstLineIndent; // ein veraenderter Erstzeilen-Einzug
+
+ sal_uInt16 nUpperSpace;
+ sal_uInt16 nLowerSpace;
+
+ SwHTMLAppendMode eAppend;
+
+ sal_Bool bLRSpaceChanged : 1;// linker/rechtr Rand, Einzug veraendert?
+ sal_Bool bULSpaceChanged : 1;// oberer/unterer Rand veraendert?
+ sal_Bool bDfltTxtFmtColl : 1;// nTxtFmtColl ist nur ein default
+ sal_Bool bSpansSection : 1; // Der Kontext spannt eine SwSection auf
+ sal_Bool bPopStack : 1; // Oberhalb liegende Stack-Elemente entf.
+ sal_Bool bFinishPREListingXMP : 1;
+ sal_Bool bRestartPRE : 1;
+ sal_Bool bRestartXMP : 1;
+ sal_Bool bRestartListing : 1;
+
+public:
+ void ClearSaveDocContext();
+
+ _HTMLAttrContext( sal_uInt16 nTokn, sal_uInt16 nPoolId, const String& rClass,
+ sal_Bool bDfltColl=sal_False ) :
+ aClass( rClass ),
+ pSaveDocContext( 0 ),
+ pFrmItemSet( 0 ),
+ nToken( nTokn ),
+ nTxtFmtColl( nPoolId ),
+ nLeftMargin( 0 ),
+ nRightMargin( 0 ),
+ nFirstLineIndent( 0 ),
+ nUpperSpace( 0 ),
+ nLowerSpace( 0 ),
+ eAppend( AM_NONE ),
+ bLRSpaceChanged( sal_False ),
+ bULSpaceChanged( sal_False ),
+ bDfltTxtFmtColl( bDfltColl ),
+ bSpansSection( sal_False ),
+ bPopStack( sal_False ),
+ bFinishPREListingXMP( sal_False ),
+ bRestartPRE( sal_False ),
+ bRestartXMP( sal_False ),
+ bRestartListing( sal_False )
+ {}
+
+ _HTMLAttrContext( sal_uInt16 nTokn ) :
+ pSaveDocContext( 0 ),
+ pFrmItemSet( 0 ),
+ nToken( nTokn ),
+ nTxtFmtColl( 0 ),
+ nLeftMargin( 0 ),
+ nRightMargin( 0 ),
+ nFirstLineIndent( 0 ),
+ nUpperSpace( 0 ),
+ nLowerSpace( 0 ),
+ eAppend( AM_NONE ),
+ bLRSpaceChanged( sal_False ),
+ bULSpaceChanged( sal_False ),
+ bDfltTxtFmtColl( sal_False ),
+ bSpansSection( sal_False ),
+ bPopStack( sal_False ),
+ bFinishPREListingXMP( sal_False ),
+ bRestartPRE( sal_False ),
+ bRestartXMP( sal_False ),
+ bRestartListing( sal_False )
+ {}
+
+ ~_HTMLAttrContext() { ClearSaveDocContext(); delete pFrmItemSet; }
+
+ sal_uInt16 GetToken() const { return nToken; }
+
+ sal_uInt16 GetTxtFmtColl() const { return bDfltTxtFmtColl ? 0 : nTxtFmtColl; }
+ sal_uInt16 GetDfltTxtFmtColl() const { return bDfltTxtFmtColl ? nTxtFmtColl : 0; }
+
+ const String& GetClass() const { return aClass; }
+
+ inline void SetMargins( sal_uInt16 nLeft, sal_uInt16 nRight, short nIndent );
+
+ inline sal_Bool IsLRSpaceChanged() const { return bLRSpaceChanged; }
+ inline void GetMargins( sal_uInt16& nLeft, sal_uInt16& nRight,
+ short &nIndent ) const;
+
+ inline void SetULSpace( sal_uInt16 nUpper, sal_uInt16 nLower );
+ inline sal_Bool IsULSpaceChanged() const { return bULSpaceChanged; }
+ inline void GetULSpace( sal_uInt16& rUpper, sal_uInt16& rLower ) const;
+
+ sal_Bool HasAttrs() const { return aAttrs.Count() != 0; }
+ const _HTMLAttrs& GetAttrs() const { return aAttrs; }
+ _HTMLAttrs& GetAttrs() { return aAttrs; }
+
+ void SetSpansSection( sal_Bool bSet ) { bSpansSection = bSet; }
+ sal_Bool GetSpansSection() const { return bSpansSection; }
+
+ void SetPopStack( sal_Bool bSet ) { bPopStack = bSet; }
+ sal_Bool GetPopStack() const { return bPopStack; }
+
+ sal_Bool HasSaveDocContext() const { return pSaveDocContext!=0; }
+ _HTMLAttrContext_SaveDoc *GetSaveDocContext( sal_Bool bCreate=sal_False );
+
+ const SfxItemSet *GetFrmItemSet() const { return pFrmItemSet; }
+ SfxItemSet *GetFrmItemSet( SwDoc *pCreateDoc );
+
+ void SetFinishPREListingXMP( sal_Bool bSet ) { bFinishPREListingXMP = bSet; }
+ sal_Bool IsFinishPREListingXMP() const { return bFinishPREListingXMP; }
+
+ void SetRestartPRE( sal_Bool bSet ) { bRestartPRE = bSet; }
+ sal_Bool IsRestartPRE() const { return bRestartPRE; }
+
+ void SetRestartXMP( sal_Bool bSet ) { bRestartXMP = bSet; }
+ sal_Bool IsRestartXMP() const { return bRestartXMP; }
+
+ void SetRestartListing( sal_Bool bSet ) { bRestartListing = bSet; }
+ sal_Bool IsRestartListing() const { return bRestartListing; }
+
+ void SetAppendMode( SwHTMLAppendMode eMode=AM_NORMAL ) { eAppend = eMode; }
+ SwHTMLAppendMode GetAppendMode() const { return eAppend; }
+};
+
+typedef _HTMLAttrContext *_HTMLAttrContextPtr;
+SV_DECL_PTRARR( _HTMLAttrContexts, _HTMLAttrContextPtr, 5, 5 )
+
+class HTMLTable;
+class SwCSS1Parser;
+class SwHTMLNumRuleInfo;
+
+typedef ImageMap *ImageMapPtr;
+SV_DECL_PTRARR_DEL( ImageMaps, ImageMapPtr, 1, 1 )
+typedef SwFrmFmt *SwFrmFmtPtr;
+SV_DECL_PTRARR( SwHTMLFrmFmts, SwFrmFmtPtr, 2, 2 )
+
+#define HTML_CNTXT_PROTECT_STACK 0x0001
+#define HTML_CNTXT_STRIP_PARA 0x0002
+#define HTML_CNTXT_KEEP_NUMRULE 0x0004
+#define HTML_CNTXT_HEADER_DIST 0x0008
+#define HTML_CNTXT_FOOTER_DIST 0x0010
+#define HTML_CNTXT_KEEP_ATTRS 0x0020
+
+#define CONTEXT_FLAGS_ABSPOS \
+ (HTML_CNTXT_PROTECT_STACK | \
+ HTML_CNTXT_STRIP_PARA)
+
+#define HTML_FF_BOX 0x0001
+#define HTML_FF_BACKGROUND 0x0002
+#define HTML_FF_PADDING 0x0004
+#define HTML_FF_DIRECTION 0x0008
+
+class SwHTMLParser : public SfxHTMLParser, public SwClient
+{
+ friend class _SectionSaveStruct;
+ friend class _CellSaveStruct;
+ friend class _CaptionSaveStruct;
+
+ String aPathToFile;
+ String sBaseURL;
+ String sSaveBaseURL;
+ String aBasicLib;
+ String aBasicModule;
+ String aScriptSource; // Inhalt des aktuellen Script-Blocks
+ String aScriptType; // Type des gelesenen Scripts (StarBasic/VB/JAVA)
+ String aScriptURL; // URL eines Scripts
+ String aStyleSource; // Inhalt des aktuellen Style-Sheets
+ String aContents; // Text des akteullen Marquee, Feldes etc.
+ String sTitle;
+ String aUnknownToken; // ein gestartetes unbekanntes Token
+ String aBulletGrfs[MAXLEVEL];
+ String sJmpMark;
+
+ SvUShorts aBaseFontStack; // Stack fuer <BASEFONT>
+ // Bit 0-2: Fontgroesse (1-7)
+ SvUShorts aFontStack; // Stack fuer <FONT>, <BIG>, <SMALL>
+ // Bit 0-2: Fontgroesse (1-7)
+ // Bit 15: Fontfarbe wurde gesetzt
+
+ _HTMLAttrs aSetAttrTab;// "geschlossene", noch nicht gesetzte Attr.
+ _HTMLAttrs aParaAttrs; // vorlauefige Absatz-Attribute
+ _HTMLAttrTable aAttrTab; // "offene" Attribute
+ _HTMLAttrContexts aContexts;// der aktuelle Attribut/Token-Kontext
+ SwHTMLFrmFmts aMoveFlyFrms;// Fly-Frames, deren Anker verschoben wird
+ SvXub_StrLens aMoveFlyCnts;// und deren Content-Positionen
+
+ SwApplet_Impl *pAppletImpl; // das aktuelle Applet
+
+ SwCSS1Parser *pCSS1Parser; // der Style-Sheet-Parser
+ SwHTMLNumRuleInfo *pNumRuleInfo;
+ SwPendingStack *pPendStack;
+
+ SwDoc *pDoc;
+ SwPaM *pPam; // SwPosition duerfte doch reichen, oder ??
+ ViewShell *pActionViewShell; // ViewShell, an der das StartAction
+ // gerufen wurde.
+ SwNodeIndex *pSttNdIdx;
+
+ HTMLTable *pTable; // die aktuelle "auesserste" Tabelle
+ SwHTMLForm_Impl *pFormImpl;// die aktuelle Form
+ SdrObject *pMarquee; // aktuelles Marquee
+ SwField *pField; // aktuelles Feld
+ ImageMap *pImageMap; // aktuelle Image-Map
+ ImageMaps *pImageMaps;// alle gelesenen Image-Maps
+ SwHTMLFootEndNote_Impl *pFootEndNoteImpl;
+
+ Size aHTMLPageSize; // die Seitengroesse der HTML-Vorlage
+
+ sal_uInt32 aFontHeights[7]; // die Font-Hoehen 1-7
+ sal_uInt32 nScriptStartLineNr; // Zeilennummer eines Script-Blocks
+ ULONG nEventId;
+
+ sal_uInt16 nBaseFontStMin; //
+ sal_uInt16 nFontStMin; //
+ sal_uInt16 nDefListDeep; //
+ sal_uInt16 nFontStHeadStart; // Elemente im Font-Stack bei <Hn>
+ sal_uInt16 nSBModuleCnt; // Zaehler fuer Basic-Module
+ sal_uInt16 nMissingImgMaps; // Wie viele Image-Maps fehlen noch?
+ sal_uInt16 nParaCnt;
+ sal_uInt16 nContextStMin; // Untergrenze fuer PopContext
+ sal_uInt16 nContextStAttrMin; // Untergrenze fuer Attributierung
+ sal_uInt16 nSelectEntryCnt; // Anzahl der Eintraege der akt. Listbox
+ sal_uInt16 nOpenParaToken; // ein geoeffnetes Absatz-Element
+
+ enum JumpToMarks { JUMPTO_NONE, JUMPTO_MARK, JUMPTO_TABLE, JUMPTO_FRAME,
+ JUMPTO_REGION, JUMPTO_GRAPHIC } eJumpTo;
+
+#ifdef DBG_UTIL
+ sal_uInt16 nContinue; // Tiefe der Continue-Aufrufe
+#endif
+
+ SvxAdjust eParaAdjust; // Ausrichtung des aktuellen Absatz
+ HTMLScriptLanguage eScriptLang; // die aktuelle Script-Language
+
+ sal_Bool bOldIsHTMLMode : 1; // War's mal ein HTML-Dokument?
+
+ sal_Bool bDocInitalized : 1; // Dokument bzw. Shell wurden initialisiert
+ // Flag um doppeltes init durch Rekursion
+ // zu verhindern.
+ sal_Bool bViewCreated : 1; // die View wurde schon erzeugt (asynchron)
+ sal_Bool bSetCrsr : 1; // Crsr wieder auf den Anfang setzen
+ sal_Bool bSetModEnabled : 1;
+
+ sal_Bool bInFloatingFrame : 1; // Wir sind in einen Floating ::com::sun::star::frame::Frame
+ sal_Bool bInField : 1;
+ sal_Bool bKeepUnknown : 1; // unbekannte/nicht unterstuetze Tokens beh.
+ // 8
+ sal_Bool bCallNextToken : 1; // In Tabellen: NextToken in jedem Fall rufen
+ sal_Bool bIgnoreRawData : 1; // Inhalt eines Scripts/Styles ignorieren.
+ sal_Bool bLBEntrySelected : 1; // Ist der aktuelle Listbox-Eintrag selekt.
+ sal_Bool bTAIgnoreNewPara : 1; // naechstes LF in TextArea ignorieren?
+ sal_Bool bFixMarqueeWidth : 1; // Groesse einer Laufschrift anpassen?
+ sal_Bool bFixMarqueeHeight : 1;
+
+ sal_Bool bUpperSpace : 1; // obererer Absatz-Abstand wird benoetigt
+ sal_Bool bNoParSpace : 1;
+ // 16
+
+ sal_Bool bAnyStarBasic : 1; // gibt es ueberhaupt ein StarBasic-Modul
+ sal_Bool bInNoEmbed : 1; // Wir sind in einem NOEMBED-Bereich
+
+ sal_Bool bInTitle : 1; // Wir sind im Titel
+
+ sal_Bool bChkJumpMark : 1; // springe ggfs. zu einem vorgegebenem Mark
+ sal_Bool bUpdateDocStat : 1;
+ sal_Bool bFixSelectWidth : 1; // Breite eines Selects neu setzen?
+ sal_Bool bFixSelectHeight : 1; // Breite eines Selects neu setzen?
+ sal_Bool bTextArea : 1;
+ // 24
+ sal_Bool bSelect : 1;
+ sal_Bool bInFootEndNoteAnchor : 1;
+ sal_Bool bInFootEndNoteSymbol : 1;
+ sal_Bool bIgnoreHTMLComments : 1;
+ sal_Bool bRemoveHidden : 1; // the filter implementation might set the hidden flag
+
+ /// the names corresponding to the DOCINFO field subtypes INFO[1-4]
+ ::rtl::OUString m_InfoNames[4];
+
+ SfxViewFrame* pTempViewFrame;
+
+ void DeleteFormImpl();
+
+ void DocumentDetected();
+ void Show();
+ void ShowStatline();
+ ViewShell *CallStartAction( ViewShell *pVSh = 0, sal_Bool bChkPtr = sal_True );
+ ViewShell *CallEndAction( sal_Bool bChkAction = sal_False, sal_Bool bChkPtr = sal_True );
+ ViewShell *CheckActionViewShell();
+
+ DECL_LINK( AsyncCallback, void* );
+
+ // Attribute am Dok setzen
+ void _SetAttr( sal_Bool bChkEnd, sal_Bool bBeforeTable, _HTMLAttrs *pPostIts );
+ inline void SetAttr( sal_Bool bChkEnd = sal_True, sal_Bool bBeforeTable = sal_False,
+ _HTMLAttrs *pPostIts = 0 )
+ {
+ if( aSetAttrTab.Count() || aMoveFlyFrms.Count() )
+ _SetAttr( bChkEnd, bBeforeTable, pPostIts );
+ }
+
+ _HTMLAttr **GetAttrTabEntry( sal_uInt16 nWhich );
+
+ // Einen neuen Textknoten an PaM-Position anlegen
+ sal_Bool AppendTxtNode( SwHTMLAppendMode eMode=AM_NORMAL, sal_Bool bUpdateNum=sal_True );
+ void AddParSpace();
+
+ // Ein Attribut beginnen/beenden
+ // ppDepAttr gibt einen Attribut-Tabellen-Eintrag an, dessen Attribute
+ // gesetzt sein muessen, bevor das Attribut beendet werden darf
+ void NewAttr( _HTMLAttr **ppAttr, const SfxPoolItem& rItem );
+ void EndAttr( _HTMLAttr *pAttr, _HTMLAttr **ppDepAttr=0,
+ sal_Bool bChkEmpty=sal_True );
+ void DeleteAttr( _HTMLAttr* pAttr );
+
+ void EndContextAttrs( _HTMLAttrContext *pContext, sal_Bool bRemove=sal_False );
+ void SaveAttrTab( _HTMLAttrTable& rNewAttrTab );
+ void SplitAttrTab( const SwPosition& rNewPos );
+ void SplitAttrTab( _HTMLAttrTable& rNewAttrTab, sal_Bool bMoveEndBack = sal_True );
+ void RestoreAttrTab( const _HTMLAttrTable& rNewAttrTab,
+ sal_Bool bSetNewStart = sal_False );
+ void InsertAttr( const SfxPoolItem& rItem, sal_Bool bLikePara = sal_False,
+ sal_Bool bInsAtStart=sal_False );
+ void InsertAttrs( _HTMLAttrs& rAttrs );
+
+ sal_Bool DoPositioning( SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo &rPropInfo,
+ _HTMLAttrContext *pContext );
+ sal_Bool CreateContainer( const String& rClass, SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo &rPropInfo,
+ _HTMLAttrContext *pContext );
+ sal_Bool EndSection( sal_Bool bLFStripped=sal_False );
+
+ void InsertAttrs( SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo,
+ _HTMLAttrContext *pContext, sal_Bool bCharLvl=sal_False );
+ void InsertAttr( _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
+ _HTMLAttrContext *pCntxt );
+ void SplitPREListingXMP( _HTMLAttrContext *pCntxt );
+ void FixHeaderFooterDistance( sal_Bool bHeader, const SwPosition *pOldPos );
+
+ void EndContext( _HTMLAttrContext *pContext );
+ void ClearContext( _HTMLAttrContext *pContext );
+
+ const SwFmtColl *GetCurrFmtColl() const;
+
+ SwTwips GetCurrentBrowseWidth();
+
+ SwHTMLNumRuleInfo& GetNumInfo() { return *pNumRuleInfo; }
+ // --> OD 2008-04-02 #refactorlists#
+ // add parameter <bCountedInList>
+ void SetNodeNum( sal_uInt8 nLevel, bool bCountedInList );
+ // <--
+
+ // Verwalten von Absatz-Vorlagen
+
+ // die Vorlagen auf dem Stack bzw. deren Attribute setzen
+ void SetTxtCollAttrs( _HTMLAttrContext *pContext = 0 );
+
+ void InsertParaAttrs( const SfxItemSet& rItemSet );
+
+ // Verwalten des Attribut-Kontexts
+
+ // aktuellen Kontext merken
+ inline void PushContext( _HTMLAttrContext *pCntxt );
+
+ // den obersten/spezifizierten Kontext holen, aber nicht ausserhalb
+ // des Kontexts mit Token nLimit suchen. Wenn bRemove gesetzt ist,
+ // wird er entfernt
+ _HTMLAttrContext *PopContext( sal_uInt16 nToken=0, sal_uInt16 nLimit=0,
+ sal_Bool bRemove=sal_True );
+ inline const _HTMLAttrContext *GetTopContext() const;
+
+ sal_Bool GetMarginsFromContext( sal_uInt16 &nLeft, sal_uInt16 &nRight, short& nIndent,
+ sal_Bool bIgnoreCurrent=sal_False ) const;
+ sal_Bool GetMarginsFromContextWithNumBul( sal_uInt16 &nLeft, sal_uInt16 &nRight,
+ short& nIndent ) const;
+ void GetULSpaceFromContext( sal_uInt16 &rUpper, sal_uInt16 &rLower ) const;
+
+
+ void MovePageDescAttrs( SwNode *pSrcNd, ULONG nDestIdx, sal_Bool bFmtBreak );
+
+ // Behandlung von Tags auf Absatz-Ebene
+
+ // <P> und <H1> bis <H6>
+ void NewPara();
+ void EndPara( sal_Bool bReal = sal_False );
+ void NewHeading( int nToken );
+ void EndHeading();
+
+ // <ADDRESS>, <BLOCKQUOTE> und <PRE>
+ void NewTxtFmtColl( int nToken, sal_uInt16 nPoolId );
+ void EndTxtFmtColl( int nToken );
+
+ // <DIV> und <CENTER>
+ void NewDivision( int nToken );
+ void EndDivision( int nToken );
+
+ // Fly-Frames einfuegen/verlassen
+ void InsertFlyFrame( const SfxItemSet& rItemSet, _HTMLAttrContext *pCntxt,
+ const String& rId, sal_uInt16 nFlags );
+
+ void SaveDocContext( _HTMLAttrContext *pCntxt, sal_uInt16 nFlags,
+ const SwPosition *pNewPos );
+ void RestoreDocContext( _HTMLAttrContext *pCntxt );
+
+ // alle durch <DIV> aufgespannten Bereiche verlassen
+ sal_Bool EndSections( sal_Bool bLFStripped );
+
+ // <MULTICOL>
+ void NewMultiCol();
+ void EndMultiCol();
+
+ // <MARQUEE>
+ void NewMarquee( HTMLTable *pCurTable=0 );
+ void EndMarquee();
+ void InsertMarqueeText();
+
+ // Behandluung von Listen
+
+ // Numerierungs <OL> und Aufzaehlungs-Listen <UL> mit <LI>
+ void NewNumBulList( int nToken );
+ void EndNumBulList( int nToken=0 );
+ void NewNumBulListItem( int nToken );
+ void EndNumBulListItem( int nToken=0, sal_Bool bSetColl=sal_True,
+ sal_Bool bLastPara=sal_False );
+
+ // Definitions-Listen <DL> mit <DD>, <DT>
+ void NewDefList();
+ void EndDefList();
+ void NewDefListItem( int nToken );
+ void EndDefListItem( int nToken=0, sal_Bool bSetColl=sal_True,
+ sal_Bool bLastPara=sal_False );
+
+
+ // Behandlung von Tags auf Zeichen-Ebene
+
+ // Tags wie <B>, <I> etc behandeln, die ein bestimmtes Attribut
+ // an und ausschalten, oder die wie SPAN nur Attribute aus Styles holen
+ void NewStdAttr( int nToken );
+ void NewStdAttr( int nToken,
+ _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
+ _HTMLAttr **ppAttr2=0, const SfxPoolItem *pItem2=0,
+ _HTMLAttr **ppAttr3=0, const SfxPoolItem *pItem3=0 );
+ void EndTag( int nToken );
+
+ // Font-Attribute behandeln
+ void NewBasefontAttr(); // fuer <BASEFONT>
+ void EndBasefontAttr();
+ void NewFontAttr( int nToken ); // fuer <FONT>, <BIG> und <SMALL>
+ void EndFontAttr( int nToken );
+
+ // Tags, die durch Zeichenvorlagen realisiert werden
+ void NewCharFmt( int nToken );
+
+ // <SDFIELD>
+public:
+ static sal_uInt16 GetNumType( const String& rStr, sal_uInt16 eDfltType );
+private:
+ void NewField();
+ void EndField();
+ void InsertFieldText();
+
+ // <SPACER>
+ void InsertSpacer();
+
+ // Einfuegen von Grafiken, Plugins und Applets
+
+ // Image-Maps suchen und mit Grafik-Nodes verbinden
+ ImageMap *FindImageMap( const String& rURL ) const;
+ void ConnectImageMaps();
+
+ // Verankerung eines Fly-Frames bestimmen und entsprechende Attribute
+ // in den Attrset setzen (htmlgrin.cxx)
+ void SetAnchorAndAdjustment( sal_Int16 eVertOri,
+ sal_Int16 eHoriOri,
+ const SfxItemSet &rItemSet,
+ const SvxCSS1PropertyInfo &rPropInfo,
+ SfxItemSet& rFrmSet );
+ void SetAnchorAndAdjustment( sal_Int16 eVertOri,
+ sal_Int16 eHoriOri,
+ SfxItemSet& rFrmSet,
+ sal_Bool bDontAppend=sal_False );
+ void SetAnchorAndAdjustment( const SfxItemSet &rItemSet,
+ const SvxCSS1PropertyInfo &rPropInfo,
+ SfxItemSet &rFrmItemSet );
+
+ void SetFrmFmtAttrs( SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo,
+ sal_uInt16 nFlags, SfxItemSet &rFrmItemSet );
+
+ // Frames anlegen und Auto-gebundene Rahmen registrieren
+ void RegisterFlyFrm( SwFrmFmt *pFlyFrm );
+
+ // Die Groesse des Fly-Frames an die Vorgaben und Gegebenheiten anpassen
+ // (nicht fuer Grafiken, deshalb htmlplug.cxx)
+ void SetFixSize( const Size& rPixSize, const Size& rTwipDfltSize,
+ sal_Bool bPrcWidth, sal_Bool bPrcHeight,
+ SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo,
+ SfxItemSet& rFlyItemSet );
+ void SetVarSize( SfxItemSet &rItemSet, SvxCSS1PropertyInfo &rPropInfo,
+ SfxItemSet& rFlyItemSet, SwTwips nDfltWidth=MINLAY,
+ sal_uInt8 nDltPrcWidth=0 );
+ void SetSpace( const Size& rPixSpace, SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo &rPropInfo, SfxItemSet& rFlyItemSet );
+
+ sal_uInt16 IncGrfsThatResizeTable();
+
+ void GetDefaultScriptType( ScriptType& rType,
+ String& rTypeStr ) const;
+
+ // die eigentlichen Einfuege-Methoden fuer <IMG>, <EMBED> und <APPLET>
+ // und <PARAM>
+ void InsertImage(); // htmlgrin.cxx
+ void InsertEmbed(); // htmlplug.cxx
+
+#ifdef SOLAR_JAVA
+ void NewObject(); // htmlplug.cxx
+#endif
+ void EndObject(); // CommandLine mit Applet verkn. (htmlplug.cxx)
+#ifdef SOLAR_JAVA
+ void InsertApplet(); // htmlplug.cxx
+#endif
+ void EndApplet(); // CommandLine mit Applet verkn. (htmlplug.cxx)
+ void InsertParam(); // htmlplug.cxx
+
+ void InsertFloatingFrame();
+ void EndFloatingFrame() { bInFloatingFrame = sal_False; }
+
+ // <BODY>-Tag auswerten: Hintergrund-Grafiken und -Farben setzen (htmlgrin.cxx)
+ void InsertBodyOptions();
+
+
+ // Einfuegen von Links und ::com::sun::star::text::Bookmarks (htmlgrin.cxx)
+
+ // <A>-Tag auswerten: einen Link bzw. eine ::com::sun::star::text::Bookmark einfuegen
+ void NewAnchor();
+ void EndAnchor();
+
+ // eine ::com::sun::star::text::Bookmark einfuegen
+ void InsertBookmark( const String& rName );
+
+
+ void InsertCommentText( const sal_Char *pTag = 0 );
+ void InsertComment( const String& rName, const sal_Char *pTag = 0 );
+
+ // sind im aktuellen Absatz ::com::sun::star::text::Bookmarks vorhanden?
+ sal_Bool HasCurrentParaBookmarks( sal_Bool bIgnoreStack=sal_False ) const;
+
+
+ // Einfuegen von Script/Basic-Elementen
+
+ // das zueletzt gelsene Basic-Modul parsen (htmlbas.cxx)
+ void NewScript();
+ void EndScript();
+
+ void AddScriptSource();
+
+ // ein Event in die SFX-Konfiguation eintragen (htmlbas.cxx)
+ void InsertBasicDocEvent( rtl::OUString aEventName, const String& rName,
+ ScriptType eScrType, const String& rScrType );
+
+ // ein Event an ein VC-Control anhaengen (htmlform.cxx)
+ void InsertBasicCtrlEvent( sal_uInt16 nEvent, const String& rName );
+
+ // Einfuegen von Styles
+
+ // <STYLE>
+ void NewStyle();
+ void EndStyle();
+
+ inline sal_Bool HasStyleOptions( const String &rStyle, const String &rId,
+ const String &rClass, const String *pLang=0,
+ const String *pDir=0 );
+ sal_Bool ParseStyleOptions( const String &rStyle, const String &rId,
+ const String &rClass, SfxItemSet &rItemSet,
+ SvxCSS1PropertyInfo &rPropInfo,
+ const String *pLang=0, const String *pDir=0 );
+
+
+ // Einfuegen von Controls und ::com::sun::star::form::Forms (htmlform.cxx)
+
+ // Ein Draw-Objekt in das Dokuement eintragen
+ void InsertDrawObject( SdrObject* pNewDrawObj, const Size& rSpace,
+ sal_Int16 eVertOri,
+ sal_Int16 eHoriOri,
+ SfxItemSet& rCSS1ItemSet,
+ SvxCSS1PropertyInfo& rCSS1PropInfo,
+ sal_Bool bHidden=sal_False );
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > InsertControl( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormComponent > & rFormComp,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rFCompPropSet,
+ const Size& rSize,
+ sal_Int16 eVertOri,
+ sal_Int16 eHoriOri,
+ SfxItemSet& rCSS1ItemSet,
+ SvxCSS1PropertyInfo& rCSS1PropInfo,
+ const SvxMacroTableDtor& rMacroTbl,
+ const SvStringsDtor& rUnoMacroTbl,
+ const SvStringsDtor& rUnoMacroParamTbl,
+ sal_Bool bSetPropSet = sal_True,
+ sal_Bool bHidden = sal_False );
+ void SetControlSize( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rShape, const Size& rTextSz,
+ sal_Bool bMinWidth, sal_Bool bMinHeight, int nToken );
+ void SetPendingControlSize( int nToken );
+
+public:
+ void ResizeDrawObject( SdrObject* pObj, SwTwips nWidth );
+private:
+ void RegisterDrawObjectToTable( HTMLTable *pCurTable, SdrObject* pObj,
+ sal_uInt8 nWidth );
+
+
+ // eine neue Form beginnen
+ void NewForm( sal_Bool bAppend=sal_True );
+ void EndForm( sal_Bool bAppend=sal_True );
+
+ // die Einfuege-Methoden fuer <INPUT>, <TEXTAREA> und <SELECT>
+ void InsertInput();
+
+ void NewTextArea();
+ void InsertTextAreaText( sal_uInt16 nToken );
+ void EndTextArea();
+
+ void NewSelect();
+ void InsertSelectOption();
+ void InsertSelectText();
+ void EndSelect();
+
+ // Einfuegen von Tabellen (htmltab.cxx)
+
+public: // wird in Tabellen benoetigt
+
+ // einen Boxen-Inhalt hinter dem angegebenen Node einfuegen
+ const SwStartNode *InsertTableSection( const SwStartNode *pPrevStNd );
+
+ // Einen Boxen-Inhalt am Ende der Tabelle einfuegen, in der der PaM
+ // steht un den PaM in die Zelle schieben
+ const SwStartNode *InsertTableSection( sal_uInt16 nPoolId );
+
+ // Einfeuge-Methoden fuer die diversen Tabellen-Tags
+ HTMLTableCnts *InsertTableContents( sal_Bool bHead );
+
+private:
+ // Eine Section fuer die voruebergende Aufnahme der Tabellen-Ueberschrift
+ // anlegen
+ SwStartNode *InsertTempTableCaptionSection();
+
+ void BuildTableCell( HTMLTable *pTable, sal_Bool bReadOptions, sal_Bool bHead );
+ void BuildTableRow( HTMLTable *pTable, sal_Bool bReadOptions,
+ SvxAdjust eGrpAdjust, sal_Int16 eVertOri );
+ void BuildTableSection( HTMLTable *pTable, sal_Bool bReadOptions, sal_Bool bHead );
+ void BuildTableColGroup( HTMLTable *pTable, sal_Bool bReadOptions );
+ void BuildTableCaption( HTMLTable *pTable );
+ HTMLTable *BuildTable( SvxAdjust eCellAdjust,
+ sal_Bool bIsParentHead = sal_False,
+ sal_Bool bHasParentSection=sal_True,
+ sal_Bool bIsInMulticol = sal_False,
+ sal_Bool bHasToFlow = sal_False );
+
+
+ // sonstiges ...
+
+ void ParseMoreMetaOptions();
+
+ sal_Bool FileDownload( const String& rURL, String& rStr );
+ void InsertLink();
+
+ void InsertIDOption();
+ void InsertLineBreak();
+ void InsertHorzRule();
+
+ void FillEndNoteInfo( const String& rContent );
+ void FillFootNoteInfo( const String& rContent );
+ void InsertFootEndNote( const String& rName, sal_Bool bEndNote, sal_Bool bFixed );
+ void FinishFootEndNote();
+ void InsertFootEndNoteText();
+ SwNodeIndex *GetFootEndNoteSection( const String& rName );
+ void DeleteFootEndNoteImpl();
+
+ // Line-Break am Ende eines Absatzes entfernen
+ xub_StrLen StripTrailingLF();
+
+ // Einen leeren Absatz an der PaM-Position entfernen
+ void StripTrailingPara();
+
+ // sind im aktuellen Absatz Fly-Frames vorhanden?
+ sal_Bool HasCurrentParaFlys( sal_Bool bNoSurroundOnly = sal_False,
+ sal_Bool bSurroundOnly = sal_False ) const;
+
+public: // wird in Tabellen benoetigt
+
+ // generieren eines BrushItems (mit new) oder 0
+ SvxBrushItem* CreateBrushItem( const Color *pColor,
+ const String &rImageURL,
+ const String &rStyle,
+ const String &rId,
+ const String &rClass );
+
+protected:
+ // wird fuer jedes Token gerufen, das in CallParser erkannt wird
+ virtual void NextToken( int nToken );
+ virtual ~SwHTMLParser();
+
+ // wird das Dok geloescht, ist auch der Parser zu loeschen
+ virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew );
+
+ virtual void AddMetaUserDefined( ::rtl::OUString const & i_rMetaName );
+
+public:
+
+ SwHTMLParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
+ const String& rFileName,
+ const String& rBaseURL,
+ int bReadNewDoc = sal_True,
+ SfxMedium* pMed = 0, sal_Bool bReadUTF8 = sal_False,
+ sal_Bool bIgnoreHTMLComments = sal_False );
+
+ virtual SvParserState CallParser(); // Aufruf des Parsers
+
+
+ sal_uInt16 ToTwips( sal_uInt16 nPixel ) const;
+
+ // fuers asynchrone lesen aus dem SvStream
+ virtual void Continue( int nToken );
+
+ virtual bool ParseMetaOptions( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::document::XDocumentProperties>&,
+ SvKeyValueIterator* );
+};
+
+
+struct SwPendingStackData
+{
+ virtual ~SwPendingStackData() {}
+};
+
+struct SwPendingStack
+{
+ int nToken;
+ SwPendingStackData* pData;
+ SwPendingStack* pNext;
+
+ SwPendingStack( int nTkn, SwPendingStack* pNxt )
+ : nToken( nTkn ), pData( 0 ), pNext( pNxt )
+ {}
+};
+
+inline void _HTMLAttr::SetStart( const SwPosition& rPos )
+{
+ nSttPara = rPos.nNode;
+ nSttCntnt = rPos.nContent.GetIndex();
+ nEndPara = nSttPara;
+ nEndCntnt = nSttCntnt;
+}
+
+inline void _HTMLAttrContext::SetMargins( sal_uInt16 nLeft, sal_uInt16 nRight,
+ short nIndent )
+{
+ nLeftMargin = nLeft;
+ nRightMargin = nRight;
+ nFirstLineIndent = nIndent;
+ bLRSpaceChanged = sal_True;
+}
+
+inline void _HTMLAttrContext::GetMargins( sal_uInt16& nLeft,
+ sal_uInt16& nRight,
+ short& nIndent ) const
+{
+ if( bLRSpaceChanged )
+ {
+ nLeft = nLeftMargin;
+ nRight = nRightMargin;
+ nIndent = nFirstLineIndent;
+ }
+}
+
+inline void _HTMLAttrContext::SetULSpace( sal_uInt16 nUpper, sal_uInt16 nLower )
+{
+ nUpperSpace = nUpper;
+ nLowerSpace = nLower;
+ bULSpaceChanged = sal_True;
+}
+
+inline void _HTMLAttrContext::GetULSpace( sal_uInt16& rUpper,
+ sal_uInt16& rLower ) const
+{
+ if( bULSpaceChanged )
+ {
+ rUpper = nUpperSpace;
+ rLower = nLowerSpace;
+ }
+}
+
+inline sal_Bool SwHTMLParser::HasStyleOptions( const String &rStyle,
+ const String &rId,
+ const String &rClass,
+ const String *pLang,
+ const String *pDir )
+{
+ return rStyle.Len() || rId.Len() || rClass.Len() ||
+ (pLang && pLang->Len()) || (pDir && pDir->Len());
+}
+
+inline const _HTMLAttrContext *SwHTMLParser::GetTopContext() const
+{
+ return aContexts.Count() > nContextStMin
+ ? aContexts[aContexts.Count()-1] : 0;
+}
+
+inline void SwHTMLParser::PushContext( _HTMLAttrContext *pCntxt )
+{
+ aContexts.Insert( pCntxt, aContexts.Count() );
+}
+
+
+#endif
+
+
diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx
new file mode 100644
index 000000000000..ab6dfd92554a
--- /dev/null
+++ b/sw/source/filter/html/wrthtml.cxx
@@ -0,0 +1,1439 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 <stdlib.h>
+#include <hintids.hxx>
+#include <svl/urihelper.hxx>
+#include <rtl/tencinfo.h>
+#include <vcl/wrkwin.hxx>
+#include <sfx2/linkmgr.hxx>
+
+#include <svtools/htmlcfg.hxx>
+#include <vcl/svapp.hxx>
+#include <i18npool/mslangid.hxx>
+#include <sfx2/frmhtmlw.hxx>
+#include <svx/xoutbmp.hxx>
+#include <svx/htmlmode.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/frmdiritem.hxx>
+
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/XImageProducerSupplier.hpp>
+#include <com/sun/star/form/XFormController.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <fmthdft.hxx>
+#include <fmtfld.hxx>
+#include <fmtpdsc.hxx>
+#include <txatbase.hxx>
+#include <frmatr.hxx>
+#include <charfmt.hxx>
+#include <docary.hxx>
+#include <pam.hxx>
+#include <doc.hxx>
+#include <ndtxt.hxx>
+#include <mdiexp.hxx> // ...Percent()
+#include <fltini.hxx>
+#include <viewopt.hxx>
+#include <IMark.hxx> // fuer SwBookmark ...
+#include <poolfmt.hxx>
+#include <pagedesc.hxx>
+#include <section.hxx>
+#include <swtable.hxx>
+#include <fldbas.hxx>
+#include <fmtclds.hxx>
+#ifndef _DOCSH_HXX
+#include <docsh.hxx>
+#endif
+#include <wrthtml.hxx>
+#include <htmlnum.hxx>
+#include <htmlfly.hxx>
+#include <swmodule.hxx>
+
+#ifndef _STATSTR_HRC
+#include <statstr.hrc> // ResId fuer Statusleiste
+#endif
+#include <swerror.h>
+
+#define MAX_INDENT_LEVEL 20
+
+#if defined(UNX)
+const sal_Char SwHTMLWriter::sNewLine = '\012';
+#else
+const sal_Char __FAR_DATA SwHTMLWriter::sNewLine[] = "\015\012";
+#endif
+
+static sal_Char __FAR_DATA sIndentTabs[MAX_INDENT_LEVEL+2] =
+ "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+
+SwHTMLWriter::SwHTMLWriter( const String& rBaseURL )
+{
+ SetBaseURL( rBaseURL );
+ bFirstLine = sal_True;
+ nBkmkTabPos = -1;
+ pDfltColor = 0;
+ nImgMapCnt = 1;
+ pStartNdIdx = 0;
+ pTemplate = 0;
+ pNumRuleInfo = new SwHTMLNumRuleInfo;
+ pNextNumRuleInfo = 0;
+ pFootEndNotes = 0;
+ pFmtFtn = 0;
+ eDestEnc = RTL_TEXTENCODING_MS_1252;
+ nDirection = FRMDIR_HORI_LEFT_TOP;
+}
+
+
+__EXPORT SwHTMLWriter::~SwHTMLWriter()
+{
+ delete pNumRuleInfo;
+}
+
+ULONG SwHTMLWriter::WriteStream()
+{
+ // neue Konfiguration setzen
+ SvxHtmlOptions* pHtmlOptions = SvxHtmlOptions::Get();
+
+ // die Fontgroessen 1-7
+ aFontHeights[0] = pHtmlOptions->GetFontSize( 0 ) * 20;
+ aFontHeights[1] = pHtmlOptions->GetFontSize( 1 ) * 20;
+ aFontHeights[2] = pHtmlOptions->GetFontSize( 2 ) * 20;
+ aFontHeights[3] = pHtmlOptions->GetFontSize( 3 ) * 20;
+ aFontHeights[4] = pHtmlOptions->GetFontSize( 4 ) * 20;
+ aFontHeights[5] = pHtmlOptions->GetFontSize( 5 ) * 20;
+ aFontHeights[6] = pHtmlOptions->GetFontSize( 6 ) * 20;
+
+ // ueberhaupt Styles ausgeben
+ // (dann auch obere und untere Absatz-Abstaende)
+ nExportMode = pHtmlOptions->GetExportMode();
+ nHTMLMode = GetHtmlMode(0);
+ if( HTML_CFG_WRITER==nExportMode ||
+ HTML_CFG_NS40==nExportMode )
+ nHTMLMode |= HTMLMODE_BLOCK_SPACER;
+
+ if( HTML_CFG_WRITER==nExportMode || HTML_CFG_MSIE==nExportMode )
+ nHTMLMode |= (HTMLMODE_FLOAT_FRAME | HTMLMODE_LSPACE_IN_NUMBUL);
+
+ if( HTML_CFG_MSIE==nExportMode )
+ nHTMLMode |= HTMLMODE_NBSP_IN_TABLES;
+
+ if( HTML_CFG_WRITER==nExportMode || HTML_CFG_NS40==nExportMode ||
+ HTML_CFG_MSIE==nExportMode )
+ nHTMLMode |= HTMLMODE_ABS_POS_FLY|HTMLMODE_ABS_POS_DRAW;
+
+ if( HTML_CFG_WRITER==nExportMode )
+// nHTMLMode |= HTMLMODE_FLY_MARGINS | HTMLMODE_FRSTLINE_IN_NUMBUL;
+ nHTMLMode |= HTMLMODE_FLY_MARGINS;
+
+ if( HTML_CFG_NS40==nExportMode )
+ nHTMLMode |= HTMLMODE_BORDER_NONE;
+
+ if( HTML_CFG_HTML32!=nExportMode )
+ nHTMLMode |= HTMLMODE_FONT_GENERIC;
+
+ if( HTML_CFG_NS40==nExportMode )
+ nHTMLMode |= HTMLMODE_NO_CONTROL_CENTERING;
+
+ bCfgOutStyles = IsHTMLMode(HTMLMODE_SOME_STYLES |
+ HTMLMODE_FULL_STYLES);
+ bCfgNetscape4 = (HTML_CFG_NS40==nExportMode);
+
+ if( IsHTMLMode(HTMLMODE_SOME_STYLES | HTMLMODE_FULL_STYLES) )
+ nHTMLMode |= HTMLMODE_PRINT_EXT;
+
+ const sal_Char *pHelpHack = getenv( "HelpEx" );
+ if( pHelpHack )
+ {
+ ByteString aTmp( pHelpHack );
+ if( aTmp.EqualsIgnoreCaseAscii( "Hilfe" ) )
+ nHTMLMode |= HTMLMODE_NO_BR_AT_PAREND;
+ }
+
+ eCSS1Unit = (FieldUnit)SW_MOD()->GetMetric( pDoc->get(IDocumentSettingAccess::HTML_MODE) );
+
+ sal_Bool bWriteUTF8 = bWriteClipboardDoc;
+ eDestEnc = bWriteUTF8 ? RTL_TEXTENCODING_UTF8
+ : pHtmlOptions->GetTextEncoding();
+ const sal_Char *pCharSet =
+ rtl_getBestMimeCharsetFromTextEncoding( eDestEnc );
+ eDestEnc = rtl_getTextEncodingFromMimeCharset( pCharSet );
+
+ // fuer Netscape optimieren heisst Spacer- und Multicol ausgeben
+// bCfgMultiCol = pHtmlOptions->IsNetscape3();
+// bCfgSpacer = pHtmlOptions->IsNetscape3();
+
+ // wenn Styles exportiert werden, wird ein Style einem HTML-Tag manchmal
+ // vorgezogen, wenn nicht fuer Netscape exportiert wird
+ // bCfgPreferStyles = bCfgOutStyles; // && !pHtmlOptions->IsNetscape3();
+
+ // Nur noch fuer den MS-IE ziehen wir den Export von Styles vor.
+ bCfgPreferStyles = HTML_CFG_MSIE==nExportMode;
+
+ bCfgStarBasic = pHtmlOptions->IsStarBasic();
+
+ bCfgFormFeed = !IsHTMLMode(HTMLMODE_PRINT_EXT);
+ bCfgCpyLinkedGrfs = pHtmlOptions->IsSaveGraphicsLocal();
+
+ // die HTML-Vorlage holen
+ sal_Bool bOldHTMLMode = sal_False;
+ sal_uInt16 nOldTxtFmtCollCnt = 0, nOldCharFmtCnt = 0;
+
+ ASSERT( !pTemplate, "Wo kommt denn die HTML-Vorlage hier her?" );
+ pTemplate = ((HTMLReader*)ReadHTML)->GetTemplateDoc();
+ if( pTemplate )
+ {
+ pTemplate->acquire();
+ bOldHTMLMode = pTemplate->get(IDocumentSettingAccess::HTML_MODE);
+ pTemplate->set(IDocumentSettingAccess::HTML_MODE, true);
+
+ nOldTxtFmtCollCnt = pTemplate->GetTxtFmtColls()->Count();
+ nOldCharFmtCnt = pTemplate->GetCharFmts()->Count();
+ }
+
+ if( bShowProgress )
+ ::StartProgress( STR_STATSTR_W4WWRITE, 0, pDoc->GetNodes().Count(),
+ pDoc->GetDocShell());
+
+ pDfltColor = 0;
+ pFootEndNotes = 0;
+ pFmtFtn = 0;
+ bOutTable = bOutHeader = bOutFooter = bOutFlyFrame = sal_False;
+ pxFormComps = 0;
+ nFormCntrlCnt = 0;
+ bPreserveForm = sal_False;
+ bClearLeft = bClearRight = sal_False;
+ bLFPossible = sal_False;
+
+ nLeftMargin = nDfltLeftMargin = nDfltRightMargin = 0;
+ nDfltTopMargin = nDfltBottomMargin = 0;
+ nFirstLineIndent = nDfltFirstLineIndent = 0;
+ bPoolCollTextModified = sal_False;
+ bFirstCSS1Property = bFirstCSS1Rule = sal_False;
+ bCSS1IgnoreFirstPageDesc = sal_False;
+ nIndentLvl = 0;
+ nWhishLineLen = 70;
+ nLastLFPos = 0;
+ nDefListLvl = 0;
+ nDefListMargin = ((pTemplate && !bCfgOutStyles) ? pTemplate : pDoc)
+ ->GetTxtCollFromPool( RES_POOLCOLL_HTML_DD, false )
+ ->GetLRSpace().GetTxtLeft();
+ nHeaderFooterSpace = 0;
+ nTxtAttrsToIgnore = 0;
+ nCSS1OutMode = 0;
+ sal_uInt16 nScript = SvtLanguageOptions::GetScriptTypeOfLanguage(
+ static_cast< LanguageType >( GetAppLanguage() ) );
+ switch( nScript )
+ {
+ case SCRIPTTYPE_ASIAN:
+ nCSS1Script = CSS1_OUTMODE_CJK;
+ break;
+ case SCRIPTTYPE_COMPLEX:
+ nCSS1Script = CSS1_OUTMODE_CTL;
+ break;
+ default:
+ nCSS1Script = CSS1_OUTMODE_WESTERN;
+ break;
+ }
+ eLang = ((const SvxLanguageItem&)pDoc
+ ->GetDefault(GetLangWhichIdFromScript(nCSS1Script))).GetLanguage();
+
+ nFootNote = nEndNote = 0;
+
+ nWarn = 0;
+ GetNumInfo().Clear();
+ pNextNumRuleInfo = 0;
+
+ ByteString aStartTags;
+
+ // Tabellen und Bereiche am Doc.-Anfang beachten
+ {
+ SwTableNode * pTNd = pCurPam->GetNode()->FindTableNode();
+ if( pTNd && bWriteAll )
+ {
+ // mit dem Tabellen-Node anfangen !!
+ pCurPam->GetPoint()->nNode = *pTNd;
+
+ if( bWriteOnlyFirstTable )
+ pCurPam->GetMark()->nNode = *pTNd->EndOfSectionNode();
+ }
+
+ // erster Node (der einen Seitenumbruch enthalten darf)
+ pStartNdIdx = new SwNodeIndex( pCurPam->GetPoint()->nNode );
+
+ SwSectionNode * pSNd = pCurPam->GetNode()->FindSectionNode();
+ while( pSNd )
+ {
+ if( bWriteAll )
+ {
+ // mit dem Section-Node anfangen !!
+ pCurPam->GetPoint()->nNode = *pSNd;
+ }
+ else
+ {
+ ASSERT( FILE_LINK_SECTION != pSNd->GetSection().GetType(),
+ "Export gelinkter Bereiche am Dok-Anfang ist nicht implemntiert" );
+
+ // nur das Tag fuer die Section merken
+ ByteString aName;
+ HTMLOutFuncs::ConvertStringToHTML(
+ pSNd->GetSection().GetSectionName(),
+ aName, eDestEnc, &aNonConvertableCharacters );
+
+ ByteString sOut( '<' );
+ (((((((sOut += OOO_STRING_SVTOOLS_HTML_division)
+ += ' ') += OOO_STRING_SVTOOLS_HTML_O_id) += "=\"")
+ += aName) += '\"')
+ += '>') += aStartTags;
+
+ aStartTags = sOut;
+ }
+ // FindSectionNode() an einem SectionNode liefert den selben!
+ pSNd = pSNd->StartOfSectionNode()->FindSectionNode();
+ }
+ }
+
+
+ // Tabelle fuer die freifliegenden Rahmen erzeugen, aber nur wenn
+ // das gesamte Dokument geschrieben wird
+ pHTMLPosFlyFrms = 0;
+ CollectFlyFrms();
+ nLastParaToken = 0;
+ GetControls();
+ CollectLinkTargets();
+
+ sal_uInt16 nHeaderAttrs = 0;
+ pCurrPageDesc = MakeHeader( nHeaderAttrs );
+
+ bLFPossible = sal_True;
+
+ // Formulare, die nur HiddenControls enthalten ausgeben.
+ OutHiddenForms();
+
+ if( aStartTags.Len() )
+ Strm() << aStartTags.GetBuffer();
+
+ const SfxPoolItem *pItem;
+ const SfxItemSet& rPageItemSet = pCurrPageDesc->GetMaster().GetAttrSet();
+ if( !bWriteClipboardDoc && pDoc->GetDocShell() &&
+ (!pDoc->get(IDocumentSettingAccess::HTML_MODE) &&
+ !pDoc->get(IDocumentSettingAccess::BROWSE_MODE)) &&
+ SFX_ITEM_SET == rPageItemSet.GetItemState( RES_HEADER, sal_True, &pItem) )
+ {
+ const SwFrmFmt *pHeaderFmt =
+ ((const SwFmtHeader *)pItem)->GetHeaderFmt();
+ if( pHeaderFmt )
+ OutHTML_HeaderFooter( *this, *pHeaderFmt, sal_True );
+ }
+
+ nTxtAttrsToIgnore = nHeaderAttrs;
+ Out_SwDoc( pOrigPam );
+ nTxtAttrsToIgnore = 0;
+
+ if( pxFormComps && pxFormComps->is() )
+ OutForm( sal_False, *pxFormComps );
+
+ if( pFootEndNotes )
+ OutFootEndNotes();
+
+ if( !bWriteClipboardDoc && pDoc->GetDocShell() &&
+ (!pDoc->get(IDocumentSettingAccess::HTML_MODE) && !pDoc->get(IDocumentSettingAccess::BROWSE_MODE)) &&
+ SFX_ITEM_SET == rPageItemSet.GetItemState( RES_FOOTER, sal_True, &pItem) )
+ {
+ const SwFrmFmt *pFooterFmt =
+ ((const SwFmtFooter *)pItem)->GetFooterFmt();
+ if( pFooterFmt )
+ OutHTML_HeaderFooter( *this, *pFooterFmt, sal_False );
+ }
+
+ if( bLFPossible )
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_body, sal_False );
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_html, sal_False );
+
+ // loesche die Tabelle mit den freifliegenden Rahmen
+ sal_uInt16 i;
+ ASSERT( !pHTMLPosFlyFrms, "Wurden nicht alle Rahmen ausgegeben" );
+ if( pHTMLPosFlyFrms )
+ {
+ pHTMLPosFlyFrms->DeleteAndDestroy( 0, pHTMLPosFlyFrms->Count() );
+ delete pHTMLPosFlyFrms;
+ pHTMLPosFlyFrms = 0;
+ }
+
+ if( aHTMLControls.Count() )
+ aHTMLControls.DeleteAndDestroy( sal_uInt16(0), aHTMLControls.Count() );
+
+ if( aChrFmtInfos.Count() )
+ aChrFmtInfos.DeleteAndDestroy( sal_uInt16(0), aChrFmtInfos.Count() );
+
+ if( aTxtCollInfos.Count() )
+ aTxtCollInfos.DeleteAndDestroy( sal_uInt16(0), aTxtCollInfos.Count() );
+
+ if( aImgMapNames.Count() )
+ aImgMapNames.DeleteAndDestroy( sal_uInt16(0), aImgMapNames.Count() );
+
+ if( aImplicitMarks.Count() )
+ aImplicitMarks.DeleteAndDestroy( sal_uInt16(0), aImplicitMarks.Count() );
+
+ if( aOutlineMarks.Count() )
+ aOutlineMarks.DeleteAndDestroy( sal_uInt16(0), aOutlineMarks.Count() );
+
+ if( aOutlineMarkPoss.Count() )
+ aOutlineMarkPoss.Remove( sal_uInt16(0), aOutlineMarkPoss.Count() );
+
+ if( aNumRuleNames.Count() )
+ aNumRuleNames.DeleteAndDestroy( sal_uInt16(0), aNumRuleNames.Count() );
+
+ if( aScriptParaStyles.Count() )
+ aScriptParaStyles.DeleteAndDestroy( sal_uInt16(0), aScriptParaStyles.Count() );
+ if( aScriptTextStyles.Count() )
+ aScriptTextStyles.DeleteAndDestroy( sal_uInt16(0), aScriptTextStyles.Count() );
+
+ delete pDfltColor;
+ pDfltColor = 0;
+
+ delete pStartNdIdx;
+ pStartNdIdx = 0;
+
+ delete pxFormComps;
+ pxFormComps = 0;
+
+ ASSERT( !pFootEndNotes,
+ "SwHTMLWriter::Write: Ftns nicht durch OutFootEndNotes geloescht" );
+
+ pCurrPageDesc = 0;
+
+ ClearNextNumInfo();
+
+ for( i=0; i<MAXLEVEL; i++ )
+ aBulletGrfs[i].Erase();
+
+ aNonConvertableCharacters.Erase();
+
+ if( bShowProgress )
+ ::EndProgress( pDoc->GetDocShell() );
+
+ if( pTemplate )
+ {
+ // Waehrend des Exports angelegte Zeichen- und Abastzvorlagen
+ // loeschen
+ sal_uInt16 nTxtFmtCollCnt = pTemplate->GetTxtFmtColls()->Count();
+ while( nTxtFmtCollCnt > nOldTxtFmtCollCnt )
+ pTemplate->DelTxtFmtColl( --nTxtFmtCollCnt );
+ ASSERT( pTemplate->GetTxtFmtColls()->Count() == nOldTxtFmtCollCnt,
+ "falsche Anzahl TxtFmtColls geloescht" );
+
+ sal_uInt16 nCharFmtCnt = pTemplate->GetCharFmts()->Count();
+ while( nCharFmtCnt > nOldCharFmtCnt )
+ pTemplate->DelCharFmt( --nCharFmtCnt );
+ ASSERT( pTemplate->GetCharFmts()->Count() == nOldCharFmtCnt,
+ "falsche Anzahl CharFmts geloescht" );
+
+ // HTML-Modus wieder restaurieren
+ pTemplate->set(IDocumentSettingAccess::HTML_MODE, bOldHTMLMode);
+
+ if( 0 == pTemplate->release() )
+ delete pTemplate;
+
+ pTemplate = 0;
+ }
+
+ return nWarn;
+}
+
+const SwFmtCol *lcl_html_GetFmtCol( const SwHTMLWriter& rHTMLWrt,
+ const SwSection& rSection,
+ const SwSectionFmt& rFmt )
+{
+ const SwFmtCol *pCol = 0;
+
+ const SfxPoolItem* pItem;
+ if( rHTMLWrt.IsHTMLMode( HTMLMODE_FRM_COLUMNS ) &&
+ FILE_LINK_SECTION != rSection.GetType() &&
+ SFX_ITEM_SET == rFmt.GetAttrSet().GetItemState(RES_COL,sal_False,&pItem) &&
+ ((const SwFmtCol *)pItem)->GetNumCols() > 1 )
+ {
+ pCol = (const SwFmtCol *)pItem;
+ }
+
+ return pCol;
+}
+
+sal_Bool lcl_html_IsMultiColStart( const SwHTMLWriter& rHTMLWrt, ULONG nIndex )
+{
+ sal_Bool bRet = sal_False;
+ const SwSectionNode *pSectNd =
+ rHTMLWrt.pDoc->GetNodes()[nIndex]->GetSectionNode();
+ if( pSectNd )
+ {
+ const SwSection& rSection = pSectNd->GetSection();
+ const SwSectionFmt *pFmt = rSection.GetFmt();
+ if( pFmt && lcl_html_GetFmtCol( rHTMLWrt, rSection, *pFmt ) )
+ bRet = sal_True;
+ }
+
+ return bRet;
+}
+
+sal_Bool lcl_html_IsMultiColEnd( const SwHTMLWriter& rHTMLWrt, ULONG nIndex )
+{
+ sal_Bool bRet = sal_False;
+ const SwEndNode *pEndNd = rHTMLWrt.pDoc->GetNodes()[nIndex]->GetEndNode();
+ if( pEndNd )
+ bRet = lcl_html_IsMultiColStart( rHTMLWrt,
+ pEndNd->StartOfSectionIndex() );
+
+ return bRet;
+}
+
+
+void lcl_html_OutSectionStartTag( SwHTMLWriter& rHTMLWrt,
+ const SwSection& rSection,
+ const SwSectionFmt& rFmt,
+ const SwFmtCol *pCol,
+ sal_Bool bContinued=sal_False )
+{
+ ASSERT( pCol || !bContinued, "Continuation of DIV" );
+
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+
+ const sal_Char *pTag = pCol ? OOO_STRING_SVTOOLS_HTML_multicol : OOO_STRING_SVTOOLS_HTML_division;
+
+ ByteString sOut( '<' );
+ sOut += pTag;
+
+ const String& rName = rSection.GetSectionName();
+ if( rName.Len() && !bContinued )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_id) += "=\"";
+ rHTMLWrt.Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( rHTMLWrt.Strm(), rName, rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ sOut = '\"';
+ }
+
+ sal_uInt16 nDir = rHTMLWrt.GetHTMLDirection( rFmt.GetAttrSet() );
+ rHTMLWrt.Strm() << sOut.GetBuffer();
+ sOut.Erase();
+ rHTMLWrt.OutDirection( nDir );
+
+ if( FILE_LINK_SECTION == rSection.GetType() )
+ {
+ ((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_href) += "=\"";
+ rHTMLWrt.Strm() << sOut.GetBuffer();
+
+ const String& aFName = rSection.GetLinkFileName();
+ String aURL( aFName.GetToken(0,sfx2::cTokenSeperator) );
+ String aFilter( aFName.GetToken(1,sfx2::cTokenSeperator) );
+ String aSection( aFName.GetToken(2,sfx2::cTokenSeperator) );
+
+ String aEncURL( URIHelper::simpleNormalizedMakeRelative(rHTMLWrt.GetBaseURL(), aURL ) );
+ sal_Unicode cDelim = 255U;
+ sal_Bool bURLContainsDelim =
+ (STRING_NOTFOUND != aEncURL.Search( cDelim ) );
+
+ HTMLOutFuncs::Out_String( rHTMLWrt.Strm(), aEncURL,
+ rHTMLWrt.eDestEnc,
+ &rHTMLWrt.aNonConvertableCharacters );
+ const sal_Char *pDelim = "&#255;";
+ if( aFilter.Len() || aSection.Len() || bURLContainsDelim )
+ rHTMLWrt.Strm() << pDelim;
+ if( aFilter.Len() )
+ HTMLOutFuncs::Out_String( rHTMLWrt.Strm(), aFilter,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ if( aSection.Len() || bURLContainsDelim )
+ rHTMLWrt.Strm() << pDelim;
+ if( aSection.Len() )
+ {
+ xub_StrLen nPos = aSection.Search( '%' );
+ while( STRING_NOTFOUND != nPos )
+ {
+ aSection.Erase( nPos, 1 );
+ aSection.InsertAscii( "%25", nPos );
+ nPos = aSection.Search( '%', nPos+3 );
+ }
+ nPos = aSection.Search( cDelim );
+ while( STRING_NOTFOUND != nPos )
+ {
+ aSection.Erase( nPos, 1 );
+ aSection.InsertAscii( "%FF", nPos );
+ nPos = aSection.Search( cDelim, nPos+3 );
+ }
+ HTMLOutFuncs::Out_String( rHTMLWrt.Strm(), aSection,
+ rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
+ }
+ sOut = '\"';
+ }
+ else if( pCol )
+ {
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=')
+ += ByteString::CreateFromInt32( pCol->GetNumCols() );
+
+ // minumum gutter width
+ sal_uInt16 nGutter = pCol->GetGutterWidth( sal_True );
+ if( nGutter!=USHRT_MAX )
+ {
+ if( nGutter && Application::GetDefaultDevice() )
+ {
+ nGutter = (sal_uInt16)Application::GetDefaultDevice()
+ ->LogicToPixel( Size(nGutter,0),
+ MapMode(MAP_TWIP) ).Width();
+ }
+ (((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_gutter) += '=')
+ += ByteString::CreateFromInt32( nGutter );
+ }
+ }
+
+ rHTMLWrt.Strm() << sOut.GetBuffer();
+ if( rHTMLWrt.IsHTMLMode( rHTMLWrt.bCfgOutStyles ) )
+ rHTMLWrt.OutCSS1_SectionFmtOptions( rFmt );
+
+ rHTMLWrt.Strm() << '>';
+
+ rHTMLWrt.bLFPossible = sal_True;
+ if( rName.Len() && !bContinued )
+ rHTMLWrt.OutImplicitMark( rName, pMarkToRegion );
+
+ rHTMLWrt.IncIndentLevel();
+}
+
+void lcl_html_OutSectionEndTag( SwHTMLWriter& rHTMLWrt,
+ const SwFmtCol *pCol )
+{
+ const sal_Char *pTag = pCol ? OOO_STRING_SVTOOLS_HTML_multicol : OOO_STRING_SVTOOLS_HTML_division;
+
+ rHTMLWrt.DecIndentLevel();
+ if( rHTMLWrt.bLFPossible )
+ rHTMLWrt.OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( rHTMLWrt.Strm(), pTag, sal_False );
+ rHTMLWrt.bLFPossible = sal_True;
+}
+
+static Writer& OutHTML_Section( Writer& rWrt, const SwSectionNode& rSectNd )
+{
+ SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
+
+ // End <PRE> and any <DL>, because a definition list's level may
+ // change inside the section.
+ rHTMLWrt.ChangeParaToken( 0 );
+ rHTMLWrt.OutAndSetDefList( 0 );
+
+ const SwSection& rSection = rSectNd.GetSection();
+ const SwSectionFmt *pFmt = rSection.GetFmt();
+ ASSERT( pFmt, "Section without a format?" );
+
+ sal_Bool bStartTag = sal_True;
+ sal_Bool bEndTag = sal_True;
+ const SwSectionFmt *pSurrFmt = 0;
+ const SwSectionNode *pSurrSectNd = 0;
+ const SwSection *pSurrSection = 0;
+ const SwFmtCol *pSurrCol = 0;
+
+ sal_uInt32 nSectSttIdx = rSectNd.GetIndex();
+ sal_uInt32 nSectEndIdx = rSectNd.EndOfSectionIndex();
+ const SwFmtCol *pCol = lcl_html_GetFmtCol( rHTMLWrt, rSection, *pFmt );
+ if( pCol )
+ {
+ // If the next node is a columned section node, too, don't export
+ // an empty section.
+ if( lcl_html_IsMultiColStart( rHTMLWrt, nSectSttIdx+1 ) )
+ bStartTag = sal_False;
+
+ // The same applies if the section end with another columned section.
+ if( lcl_html_IsMultiColEnd( rHTMLWrt, nSectEndIdx-1 ) )
+ bEndTag = sal_False;
+
+ //.is there a columned section arround this one?
+ const SwStartNode *pSttNd = rSectNd.StartOfSectionNode();
+ if( pSttNd )
+ {
+ pSurrSectNd = pSttNd->FindSectionNode();
+ if( pSurrSectNd )
+ {
+ const SwStartNode *pBoxSttNd = pSttNd->FindTableBoxStartNode();
+ if( !pBoxSttNd ||
+ pBoxSttNd->GetIndex() < pSurrSectNd->GetIndex() )
+ {
+ pSurrSection = &pSurrSectNd->GetSection();
+ pSurrFmt = pSurrSection->GetFmt();
+ if( pSurrFmt )
+ pSurrCol = lcl_html_GetFmtCol( rHTMLWrt, *pSurrSection,
+ *pSurrFmt );
+ }
+ }
+ }
+ }
+
+ // The surrounding section must be closed before the current one is
+ // opended, except that it start immediatly before the current one or
+ // another end immediately before the current one
+ if( pSurrCol && nSectSttIdx - pSurrSectNd->GetIndex() > 1 &&
+ !lcl_html_IsMultiColEnd( rHTMLWrt, nSectSttIdx-1 ) )
+ lcl_html_OutSectionEndTag( rHTMLWrt, pSurrCol );
+
+ if( bStartTag )
+ lcl_html_OutSectionStartTag( rHTMLWrt, rSection, *pFmt, pCol );
+
+ {
+ HTMLSaveData aSaveData( rHTMLWrt,
+ rHTMLWrt.pCurPam->GetPoint()->nNode.GetIndex()+1,
+ rSectNd.EndOfSectionIndex(),
+ sal_False, pFmt );
+ rHTMLWrt.Out_SwDoc( rHTMLWrt.pCurPam );
+ }
+
+ rHTMLWrt.pCurPam->GetPoint()->nNode = *rSectNd.EndOfSectionNode();
+
+ if( bEndTag )
+ lcl_html_OutSectionEndTag( rHTMLWrt, pCol );
+
+ // The surrounding section must be started again, except that it ends
+ // immeditaly behind the current one.
+ if( pSurrCol &&
+ pSurrSectNd->EndOfSectionIndex() - nSectEndIdx > 1 &&
+ !lcl_html_IsMultiColStart( rHTMLWrt, nSectEndIdx+1 ) )
+ lcl_html_OutSectionStartTag( rHTMLWrt, *pSurrSection, *pSurrFmt,
+ pSurrCol, sal_True );
+
+ return rWrt;
+}
+
+void SwHTMLWriter::Out_SwDoc( SwPaM* pPam )
+{
+ sal_Bool bSaveWriteAll = bWriteAll; // sichern
+
+ // suche die naechste text::Bookmark-Position aus der text::Bookmark-Tabelle
+ nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
+
+ // gebe alle Bereiche des Pams in das HTML-File aus.
+ do {
+ bWriteAll = bSaveWriteAll;
+ bFirstLine = sal_True;
+
+ // suche den ersten am Pam-auszugebenen FlyFrame
+ // fehlt noch:
+
+ while( pCurPam->GetPoint()->nNode.GetIndex() < pCurPam->GetMark()->nNode.GetIndex() ||
+ (pCurPam->GetPoint()->nNode.GetIndex() == pCurPam->GetMark()->nNode.GetIndex() &&
+ pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) )
+ {
+ SwNode * pNd = pCurPam->GetNode();
+
+ ASSERT( !(pNd->IsGrfNode() || pNd->IsOLENode()),
+ "Grf- oder OLE-Node hier unerwartet" );
+ if( pNd->IsTxtNode() )
+ {
+ SwTxtNode* pTxtNd = pNd->GetTxtNode();
+
+ if( !bFirstLine )
+ pCurPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
+
+ OutHTML_SwTxtNode( *this, *pTxtNd );
+ }
+ else if( pNd->IsTableNode() )
+ {
+ OutHTML_SwTblNode( *this, *pNd->GetTableNode(), 0 );
+ nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
+ }
+ else if( pNd->IsSectionNode() )
+ {
+ OutHTML_Section( *this, *pNd->GetSectionNode() );
+ nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
+ }
+ else if( pNd == &pDoc->GetNodes().GetEndOfContent() )
+ break;
+
+ pCurPam->GetPoint()->nNode++; // Bewegen
+ sal_uInt32 nPos = pCurPam->GetPoint()->nNode.GetIndex();
+
+ if( bShowProgress )
+ ::SetProgressState( nPos, pDoc->GetDocShell() ); // Wie weit ?
+
+ /* sollen nur die Selectierten Bereiche gesichert werden, so
+ * duerfen nur die vollstaendigen Nodes gespeichert werde,
+ * d.H. der 1. und n. Node teilweise, der 2. bis n-1. Node
+ * vollstaendig. (vollstaendig heisst mit allen Formaten! )
+ */
+ bWriteAll = bSaveWriteAll ||
+ nPos != pCurPam->GetMark()->nNode.GetIndex();
+ bFirstLine = sal_False;
+ bOutFooter = sal_False; // Nach einem Node keine Fusszeile mehr
+ }
+
+ ChangeParaToken( 0 ); // MIB 8.7.97: Machen wir jetzt hier und nicht
+ // beim Aufrufer
+ OutAndSetDefList( 0 );
+
+ } while( CopyNextPam( &pPam ) ); // bis alle PaM's bearbeitet
+
+ bWriteAll = bSaveWriteAll; // wieder auf alten Wert zurueck
+}
+
+
+// schreibe die StyleTabelle, algemeine Angaben,Header/Footer/Footnotes
+static void OutBodyColor( const sal_Char *pTag, const SwFmt *pFmt,
+ SwHTMLWriter& rHWrt )
+{
+ const SwFmt *pRefFmt = 0;
+
+ if( rHWrt.pTemplate )
+ pRefFmt = SwHTMLWriter::GetTemplateFmt( pFmt->GetPoolFmtId(),
+ rHWrt.pTemplate );
+
+ const SvxColorItem *pColorItem = 0;
+
+ const SfxItemSet& rItemSet = pFmt->GetAttrSet();
+ const SfxPoolItem *pRefItem = 0, *pItem = 0;
+ sal_Bool bItemSet = SFX_ITEM_SET == rItemSet.GetItemState( RES_CHRATR_COLOR,
+ sal_True, &pItem);
+ sal_Bool bRefItemSet = pRefFmt &&
+ SFX_ITEM_SET == pRefFmt->GetAttrSet().GetItemState( RES_CHRATR_COLOR,
+ sal_True, &pRefItem);
+ if( bItemSet )
+ {
+ // wenn das Item nur in der Vorlage des aktuellen Doks gesetzt
+ // ist oder einen anderen Wert hat, als in der HTML-Vorlage,
+ // wird es gesetzt
+ const SvxColorItem *pCItem = (const SvxColorItem*)pItem;
+
+ if( !bRefItemSet )
+ {
+ pColorItem = pCItem;
+ }
+ else
+ {
+ Color aColor( pCItem->GetValue() );
+ if( COL_AUTO == aColor.GetColor() )
+ aColor.SetColor( COL_BLACK );
+
+ Color aRefColor( ((const SvxColorItem*)pRefItem)->GetValue() );
+ if( COL_AUTO == aRefColor.GetColor() )
+ aRefColor.SetColor( COL_BLACK );
+
+ if( !aColor.IsRGBEqual( aRefColor ) )
+ pColorItem = pCItem;
+ }
+ }
+ else if( bRefItemSet )
+ {
+ // Das Item war in der HTML-Vorlage noch gesetzt, also geben wir
+ // das Default aus
+ pColorItem = (const SvxColorItem*)&rItemSet.GetPool()
+ ->GetDefaultItem( RES_CHRATR_COLOR );
+ }
+
+ if( pColorItem )
+ {
+ ByteString sOut( ' ' );
+ (sOut += pTag) += '=';
+ rHWrt.Strm() << sOut.GetBuffer();
+ Color aColor( pColorItem->GetValue() );
+ if( COL_AUTO == aColor.GetColor() )
+ aColor.SetColor( COL_BLACK );
+ HTMLOutFuncs::Out_Color( rHWrt.Strm(), aColor, rHWrt.eDestEnc );
+ if( RES_POOLCOLL_STANDARD==pFmt->GetPoolFmtId() )
+ rHWrt.pDfltColor = new Color( aColor );
+ }
+}
+
+sal_uInt16 SwHTMLWriter::OutHeaderAttrs()
+{
+ ULONG nIdx = pCurPam->GetPoint()->nNode.GetIndex();
+ ULONG nEndIdx = pCurPam->GetMark()->nNode.GetIndex();
+
+ SwTxtNode *pTxtNd = 0;
+ while( nIdx<=nEndIdx &&
+ 0==(pTxtNd=pDoc->GetNodes()[nIdx]->GetTxtNode()) )
+ nIdx++;
+
+ ASSERT( pTxtNd, "Kein Text-Node gefunden" );
+ if( !pTxtNd || !pTxtNd->HasHints() )
+ return 0;
+
+ sal_uInt16 nAttrs = 0;
+ sal_uInt16 nCntAttr = pTxtNd->GetSwpHints().Count();
+ xub_StrLen nOldPos = 0;
+ for( sal_uInt16 i=0; i<nCntAttr; i++ )
+ {
+ const SwTxtAttr *pHt = pTxtNd->GetSwpHints()[i];
+ if( !pHt->GetEnd() )
+ {
+ xub_StrLen nPos = *pHt->GetStart();
+ if( nPos-nOldPos > 1 || RES_TXTATR_FIELD != pHt->Which() )
+ break;
+
+ sal_uInt16 nFldWhich = ((const SwFmtFld&)pHt->GetAttr()).GetFld()
+ ->GetTyp()->Which();
+ if( RES_POSTITFLD!=nFldWhich &&
+ RES_SCRIPTFLD!=nFldWhich )
+ break;
+
+ OutNewLine();
+ OutHTML_SwFmtFld( *this, pHt->GetAttr() );
+ nOldPos = nPos;
+ nAttrs++;
+ }
+ }
+
+ return nAttrs;
+}
+
+const SwPageDesc *SwHTMLWriter::MakeHeader( sal_uInt16 &rHeaderAttrs )
+{
+ ByteString sOut( OOO_STRING_SVTOOLS_HTML_doctype );
+ (sOut += ' ') +=
+ (HTML_CFG_HTML32==nExportMode ? OOO_STRING_SVTOOLS_HTML_doctype32
+ : OOO_STRING_SVTOOLS_HTML_doctype40);
+ HTMLOutFuncs::Out_AsciiTag( Strm(), sOut.GetBuffer() );
+
+ // baue den Vorspann
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_html );
+
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_head );
+
+ IncIndentLevel(); // Inhalt von <HEAD> einruecken
+
+ // DokumentInfo
+ ByteString sIndent;
+ GetIndentString( sIndent );
+// OutNewLine();
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentProperties> xDocProps;
+ SwDocShell *pDocShell(pDoc->GetDocShell());
+ if (pDocShell) {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel(), uno::UNO_QUERY_THROW);
+ xDocProps.set(xDPS->getDocumentProperties());
+ }
+
+ // xDocProps may be null here (when copying)
+ SfxFrameHTMLWriter::Out_DocInfo( Strm(), GetBaseURL(), xDocProps,
+ sIndent.GetBuffer(), eDestEnc,
+ &aNonConvertableCharacters );
+
+ // Kommentare und Meta-Tags des ersten Absatzes
+ rHeaderAttrs = OutHeaderAttrs();
+
+ OutFootEndNoteInfo();
+
+ const SwPageDesc *pPageDesc = 0;
+ //if( !pDoc->IsHTMLMode() )
+ //{
+ // In Nicht-HTML-Dokumenten wird die erste gesetzte Seitenvorlage
+ // exportiert und wenn keine gesetzt ist die Standard-Vorlage
+ ULONG nNodeIdx = pCurPam->GetPoint()->nNode.GetIndex();
+
+ while( nNodeIdx < pDoc->GetNodes().Count() )
+ {
+ SwNode *pNd = pDoc->GetNodes()[ nNodeIdx ];
+ if( pNd->IsCntntNode() )
+ {
+ pPageDesc = ((const SwFmtPageDesc &)pNd->GetCntntNode()
+ ->GetAttr(RES_PAGEDESC)).GetPageDesc();
+ break;
+ }
+ else if( pNd->IsTableNode() )
+ {
+ pPageDesc = pNd->GetTableNode()->GetTable().GetFrmFmt()
+ ->GetPageDesc().GetPageDesc();
+ break;
+ }
+
+ nNodeIdx++;
+ }
+
+ if( !pPageDesc )
+ pPageDesc = &const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 );
+ //}
+ //else
+ //{
+ // In HTML-Dokumenten nehmen wir immer die HTML-Vorlage
+ // pPageDesc = pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML );
+ //}
+
+ // und nun ... das Style-Sheet!!!
+ if( bCfgOutStyles )
+ {
+ OutStyleSheet( *pPageDesc );
+ }
+
+ // und nun ... das BASIC und JavaScript!
+ if( pDoc->GetDocShell() ) // nur mit DocShell ist Basic moeglich
+ OutBasic();
+
+ DecIndentLevel(); // Inhalt von <HEAD> einruecken
+ OutNewLine();
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_head, sal_False );
+
+ // der Body wird nicht eingerueckt, weil sonst alles eingerueckt waere!
+ OutNewLine();
+ sOut = '<';
+ sOut += OOO_STRING_SVTOOLS_HTML_body;
+ Strm() << sOut.GetBuffer();
+ sOut.Erase();
+
+ // language
+ OutLanguage( eLang );
+
+ // Textfarbe ausgeben, wenn sie an der Standard-Vorlage gesetzt ist
+ // und sich geaendert hat.
+ OutBodyColor( OOO_STRING_SVTOOLS_HTML_O_text,
+ pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ),
+ *this );
+
+ // Farben fuer (un)besuchte Links
+ OutBodyColor( OOO_STRING_SVTOOLS_HTML_O_link,
+ pDoc->GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL ),
+ *this );
+ OutBodyColor( OOO_STRING_SVTOOLS_HTML_O_vlink,
+ pDoc->GetCharFmtFromPool( RES_POOLCHR_INET_VISIT ),
+ *this );
+
+ const SfxItemSet& rItemSet = pPageDesc->GetMaster().GetAttrSet();
+
+ String aEmbGrfName;
+ OutBackground( rItemSet, aEmbGrfName, sal_True );
+
+ nDirection = GetHTMLDirection( rItemSet );
+ OutDirection( nDirection );
+
+ if( bCfgOutStyles )
+ OutCSS1_BodyTagStyleOpt( *this, rItemSet, aEmbGrfName );
+
+ // Events anhaengen
+ if( pDoc->GetDocShell() ) // nur mit DocShell ist Basic moeglich
+ OutBasicBodyEvents();
+
+ Strm() << '>';
+
+ return pPageDesc;
+}
+
+void SwHTMLWriter::OutAnchor( const String& rName )
+{
+ ByteString sOut( '<' );
+ (((sOut += OOO_STRING_SVTOOLS_HTML_anchor) += ' ') += OOO_STRING_SVTOOLS_HTML_O_name) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), rName, eDestEnc, &aNonConvertableCharacters ) << "\">";
+ HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_anchor, sal_False );
+}
+
+void SwHTMLWriter::OutBookmarks()
+{
+ // hole das aktuelle Bookmark
+ const ::sw::mark::IMark* pBookmark = NULL;
+ IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
+ if(nBkmkTabPos != -1)
+ pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get();
+ // Ausgabe aller Bookmarks in diesem Absatz. Die Content-Position
+ // wird vorerst nicht beruecksichtigt!
+ sal_uInt32 nNode = pCurPam->GetPoint()->nNode.GetIndex();
+ while( nBkmkTabPos != -1 &&
+ pBookmark->GetMarkPos().nNode.GetIndex() == nNode )
+ {
+ // Der Bereich derBookmark wird erstam ignoriert, da er von uns
+ // auch nicht eingelesen wird.
+
+ // erst die SWG spezifischen Daten:
+ if(dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark) && pBookmark->GetName().getLength() )
+ OutAnchor( pBookmark->GetName() );
+
+ if( ++nBkmkTabPos >= pMarkAccess->getMarksCount() )
+ nBkmkTabPos = -1;
+ else
+ pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get();
+ }
+
+ sal_uInt16 nPos;
+ for( nPos = 0; nPos < aOutlineMarkPoss.Count() &&
+ aOutlineMarkPoss[nPos] < nNode; nPos++ )
+ ;
+
+ while( nPos < aOutlineMarkPoss.Count() && aOutlineMarkPoss[nPos] == nNode )
+ {
+ String sMark( *aOutlineMarks[nPos] );
+ sMark.SearchAndReplaceAll( '?', '_' ); // '?' causes problems in IE/Netscape 5
+ OutAnchor( sMark );
+ aOutlineMarkPoss.Remove( nPos, 1 );
+ aOutlineMarks.DeleteAndDestroy( nPos, 1 );
+ }
+}
+
+void SwHTMLWriter::OutImplicitMark( const String& rMark,
+ const sal_Char *pMarkType )
+{
+ if( rMark.Len() && aImplicitMarks.Count() )
+ {
+ String sMark( rMark );
+ sMark.Append( cMarkSeperator );
+ sMark.AppendAscii( pMarkType );
+ sal_uInt16 nPos;
+ if( aImplicitMarks.Seek_Entry( &sMark, &nPos ) )
+ {
+ sMark.SearchAndReplaceAll( '?', '_' ); // '?' causes problems in IE/Netscape 5
+ OutAnchor( sMark );
+ aImplicitMarks.DeleteAndDestroy( nPos, 1 );
+ }
+ }
+}
+
+void SwHTMLWriter::OutHyperlinkHRefValue( const String& rURL )
+{
+ String sURL( rURL );
+ xub_StrLen nPos = sURL.SearchBackward( cMarkSeperator );
+ if( STRING_NOTFOUND != nPos )
+ {
+ String sCmp( sURL.Copy( nPos+1 ) );
+ sCmp.EraseAllChars();
+ if( sCmp.Len() )
+ {
+ sCmp.ToLowerAscii();
+ if( sCmp.EqualsAscii( pMarkToRegion ) ||
+ sCmp.EqualsAscii( pMarkToFrame ) ||
+ sCmp.EqualsAscii( pMarkToGraphic ) ||
+ sCmp.EqualsAscii( pMarkToOLE ) ||
+ sCmp.EqualsAscii( pMarkToTable ) ||
+ sCmp.EqualsAscii( pMarkToOutline ) ||
+ sCmp.EqualsAscii( pMarkToText ) )
+ {
+ sURL.SearchAndReplaceAll( '?', '_' ); // '?' causes problems in IE/Netscape 5
+ }
+ }
+ }
+
+ sURL = URIHelper::simpleNormalizedMakeRelative( GetBaseURL(), sURL);
+ HTMLOutFuncs::Out_String( Strm(), sURL, eDestEnc,
+ &aNonConvertableCharacters );
+}
+
+void SwHTMLWriter::OutBackground( const SvxBrushItem *pBrushItem,
+ String& rEmbGrfNm, sal_Bool bGraphic )
+{
+ const Color &rBackColor = pBrushItem->GetColor();
+ /// OD 02.09.2002 #99657#
+ /// check, if background color is not "no fill"/"auto fill", instead of
+ /// only checking, if transparency is not set.
+ if( rBackColor.GetColor() != COL_TRANSPARENT )
+ {
+ ByteString sOut( ' ' );
+ (sOut += OOO_STRING_SVTOOLS_HTML_O_bgcolor) += '=';
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_Color( Strm(), rBackColor, eDestEnc);
+ }
+
+ if( !bGraphic )
+ return;
+
+ const String *pLink = pBrushItem->GetGraphicLink();
+
+ // embeddete Grafik -> WriteEmbedded schreiben
+ if( !pLink )
+ {
+ const Graphic* pGrf = pBrushItem->GetGraphic();
+ if( pGrf )
+ {
+ // Grafik als (JPG-)File speichern
+ const String* pTempFileName = GetOrigFileName();
+ if(pTempFileName)
+ rEmbGrfNm = *pTempFileName;
+ sal_uInt16 nErr = XOutBitmap::WriteGraphic( *pGrf, rEmbGrfNm,
+ String::CreateFromAscii( "JPG" ),
+ XOUTBMP_USE_NATIVE_IF_POSSIBLE );
+ if( !nErr ) // fehlerhaft, da ist nichts auszugeben
+ {
+ rEmbGrfNm = URIHelper::SmartRel2Abs(
+ INetURLObject( GetBaseURL() ), rEmbGrfNm,
+ URIHelper::GetMaybeFileHdl() );
+ pLink = &rEmbGrfNm;
+ }
+ else
+ {
+ nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
+ }
+ }
+ }
+ else
+ {
+ rEmbGrfNm = *pLink;
+ if( bCfgCpyLinkedGrfs )
+ {
+ CopyLocalFileToINet( rEmbGrfNm );
+ pLink = &rEmbGrfNm;
+ }
+ }
+
+ if( pLink )
+ {
+ ByteString sOut( ' ' );
+ String s( URIHelper::simpleNormalizedMakeRelative( GetBaseURL(), *pLink));
+ (sOut += OOO_STRING_SVTOOLS_HTML_O_background) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), s, eDestEnc, &aNonConvertableCharacters ) << '\"';
+ }
+}
+
+void SwHTMLWriter::OutBackground( const SfxItemSet& rItemSet,
+ String& rEmbGrfNm, sal_Bool bGraphic )
+{
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, sal_False,
+ &pItem ))
+ {
+ OutBackground( ((const SvxBrushItem*)pItem), rEmbGrfNm, bGraphic );
+ }
+}
+
+sal_uInt16 SwHTMLWriter::GetLangWhichIdFromScript( sal_uInt16 nScript )
+{
+ sal_uInt16 nWhichId;
+ switch( nScript )
+ {
+ case CSS1_OUTMODE_CJK:
+ nWhichId = RES_CHRATR_CJK_LANGUAGE;
+ break;
+ case CSS1_OUTMODE_CTL:
+ nWhichId = RES_CHRATR_CJK_LANGUAGE;
+ break;
+ default:
+ nWhichId = RES_CHRATR_LANGUAGE;
+ break;
+ }
+ return nWhichId;
+}
+
+void SwHTMLWriter::OutLanguage( LanguageType nLang )
+{
+ if( LANGUAGE_DONTKNOW != nLang )
+ {
+ ByteString sOut( ' ' );
+ (sOut += OOO_STRING_SVTOOLS_HTML_O_lang) += "=\"";
+ Strm() << sOut.GetBuffer();
+ HTMLOutFuncs::Out_String( Strm(), MsLangId::convertLanguageToIsoString(nLang),
+ eDestEnc, &aNonConvertableCharacters ) << '"';
+ }
+}
+
+sal_uInt16 SwHTMLWriter::GetHTMLDirection( const SfxItemSet& rItemSet ) const
+{
+ return GetHTMLDirection(
+ static_cast < const SvxFrameDirectionItem& >( rItemSet.Get( RES_FRAMEDIR ) )
+ .GetValue() );
+}
+
+sal_uInt16 SwHTMLWriter::GetHTMLDirection( sal_uInt16 nDir ) const
+{
+ switch( nDir )
+ {
+ case FRMDIR_VERT_TOP_LEFT:
+ nDir = FRMDIR_HORI_LEFT_TOP;
+ break;
+ case FRMDIR_VERT_TOP_RIGHT:
+ nDir = FRMDIR_HORI_RIGHT_TOP;
+ break;
+ case FRMDIR_ENVIRONMENT:
+ nDir = nDirection;
+ }
+
+ return nDir;
+}
+
+void SwHTMLWriter::OutDirection( sal_uInt16 nDir )
+{
+ const sal_Char *pValue = 0;
+ switch( nDir )
+ {
+ case FRMDIR_HORI_LEFT_TOP:
+ case FRMDIR_VERT_TOP_LEFT:
+ pValue = "LTR";
+ break;
+ case FRMDIR_HORI_RIGHT_TOP:
+ case FRMDIR_VERT_TOP_RIGHT:
+ pValue = "RTL";
+ break;
+ }
+ if( pValue != 0 )
+ {
+ ByteString sOut( ' ' );
+ (((sOut += OOO_STRING_SVTOOLS_HTML_O_dir) += "=\"") += pValue) += '\"';
+ Strm() << sOut.GetBuffer();
+ }
+}
+
+void SwHTMLWriter::GetIndentString( ByteString& rStr, sal_uInt16 nIncLvl )
+{
+ // etwas umstaendlich, aber wir haben nur einen Indent-String!
+ sal_uInt16 nLevel = nIndentLvl + nIncLvl;
+
+ if( nLevel && nLevel <= MAX_INDENT_LEVEL)
+ {
+ sIndentTabs[nLevel] = 0;
+ rStr = sIndentTabs;
+ sIndentTabs[nLevel] = '\t';
+ }
+}
+
+void SwHTMLWriter::OutNewLine( sal_Bool bCheck )
+{
+ if( !bCheck || (Strm().Tell()-nLastLFPos) > nIndentLvl )
+ {
+ Strm() << sNewLine;
+ nLastLFPos = Strm().Tell();
+ }
+
+ if( nIndentLvl && nIndentLvl <= MAX_INDENT_LEVEL)
+ {
+ sIndentTabs[nIndentLvl] = 0;
+ Strm() << sIndentTabs;
+ sIndentTabs[nIndentLvl] = '\t';
+ }
+}
+
+sal_uInt16 SwHTMLWriter::GetHTMLFontSize( sal_uInt32 nHeight ) const
+{
+ sal_uInt16 nSize = 1;
+ for( sal_uInt16 i=6; i>0; i-- )
+ {
+ if( nHeight > (aFontHeights[i] + aFontHeights[i-1])/2 )
+ {
+ nSize = i+1;
+ break;
+ }
+ }
+
+ return nSize;
+}
+
+// Struktur speichert die aktuellen Daten des Writers zwischen, um
+// einen anderen Dokument-Teil auszugeben, wie z.B. Header/Footer
+HTMLSaveData::HTMLSaveData( SwHTMLWriter& rWriter, ULONG nStt,
+ ULONG nEnd, sal_Bool bSaveNum,
+ const SwFrmFmt *pFrmFmt ) :
+ rWrt( rWriter ),
+ pOldPam( rWrt.pCurPam ),
+ pOldEnd( rWrt.GetEndPaM() ),
+ pOldNumRuleInfo( 0 ),
+ pOldNextNumRuleInfo( 0 ),
+ nOldDefListLvl( rWrt.nDefListLvl ),
+ nOldDirection( rWrt.nDirection ),
+ bOldOutHeader( rWrt.bOutHeader ),
+ bOldOutFooter( rWrt.bOutFooter ),
+ bOldOutFlyFrame( rWrt.bOutFlyFrame )
+{
+ bOldWriteAll = rWrt.bWriteAll;
+
+ rWrt.pCurPam = rWrt.NewSwPaM( *rWrt.pDoc, nStt, nEnd );
+
+ // Tabelle in Sonderbereichen erkennen
+ if( nStt != rWrt.pCurPam->GetMark()->nNode.GetIndex() )
+ {
+ const SwNode *pNd = rWrt.pDoc->GetNodes()[ nStt ];
+ if( pNd->IsTableNode() || pNd->IsSectionNode() )
+ rWrt.pCurPam->GetMark()->nNode = nStt;
+ }
+
+ rWrt.SetEndPaM( rWrt.pCurPam );
+ rWrt.pCurPam->Exchange( );
+ rWrt.bWriteAll = sal_True;
+ rWrt.nDefListLvl = 0;
+ rWrt.bOutHeader = rWrt.bOutFooter = sal_False;
+
+ // Ggf. die aktuelle Numerierungs-Info merken, damit sie wieder
+ // neu aufgenommen werden kann. Nur dann belibt auch die Numerierungs-
+ // Info des nachsten Absatz gueltig.
+ if( bSaveNum )
+ {
+ pOldNumRuleInfo = new SwHTMLNumRuleInfo( rWrt.GetNumInfo() );
+ pOldNextNumRuleInfo = rWrt.GetNextNumInfo();
+ rWrt.SetNextNumInfo( 0 );
+ }
+ else
+ {
+ rWrt.ClearNextNumInfo();
+ }
+
+ // Die Numerierung wird in jedem Fall unterbrochen.
+ rWrt.GetNumInfo().Clear();
+
+ if( pFrmFmt )
+ rWrt.nDirection = rWrt.GetHTMLDirection( pFrmFmt->GetAttrSet() );
+}
+
+
+HTMLSaveData::~HTMLSaveData()
+{
+ delete rWrt.pCurPam; // Pam wieder loeschen
+
+ rWrt.pCurPam = pOldPam;
+ rWrt.SetEndPaM( pOldEnd );
+ rWrt.bWriteAll = bOldWriteAll;
+ rWrt.nBkmkTabPos = bOldWriteAll ? rWrt.FindPos_Bkmk( *pOldPam->GetPoint() ) : -1;
+ rWrt.nLastParaToken = 0;
+ rWrt.nDefListLvl = nOldDefListLvl;
+ rWrt.nDirection = nOldDirection;
+ rWrt.bOutHeader = bOldOutHeader;
+ rWrt.bOutFooter = bOldOutFooter;
+ rWrt.bOutFlyFrame = bOldOutFlyFrame;
+
+ // Ggf. die Numerierung von vor der Section fortsetzen. Die Numerierung
+ // des naecshten Absatz wird in jedem Fall ungueltig.
+ if( pOldNumRuleInfo )
+ {
+ rWrt.GetNumInfo().Set( *pOldNumRuleInfo );
+ delete pOldNumRuleInfo;
+ rWrt.SetNextNumInfo( pOldNextNumRuleInfo );
+ }
+ else
+ {
+ rWrt.GetNumInfo().Clear();
+ rWrt.ClearNextNumInfo();
+ }
+}
+
+
+void GetHTMLWriter( const String&, const String& rBaseURL, WriterRef& xRet )
+{
+ xRet = new SwHTMLWriter( rBaseURL );
+}
+
+
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
new file mode 100644
index 000000000000..20511eecf3be
--- /dev/null
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -0,0 +1,603 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+#ifndef _WRTHTML_HXX
+#define _WRTHTML_HXX
+
+
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <vcl/field.hxx>
+#define _SVSTDARR_STRINGSDTOR
+#define _SVSTDARR_STRINGSSORTDTOR
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+#include <i18npool/lang.h>
+#include <tools/stream.hxx>
+
+#include "shellio.hxx"
+#include "wrt_fn.hxx"
+
+// einige Forward Deklarationen
+class Color;
+class SwFrmFmt;
+class SwFlyFrmFmt;
+class SwDrawFrmFmt;
+class SwFmtINetFmt;
+class SwFmtVertOrient;
+class SwFmtFtn;
+class SwStartNode;
+class SwTableNode;
+class SwPageDesc;
+class SwNodeIndex;
+class ImageMap;
+class SwNumRule;
+class SdrObject;
+class SvxBrushItem;
+class SvxFontItem;
+class SwHTMLNumRuleInfo;
+class SwHTMLPosFlyFrms;
+class SwHTMLTxtFtns;
+
+extern SwAttrFnTab aHTMLAttrFnTab;
+
+//#define HTML_PARSPACE ((MM50 * 7) / 10)
+#define HTML_PARSPACE (MM50)
+
+// Flags fuer die Ausgabe von Rahmen aller Art
+// BORDER geht nur bei OutHTML_Image
+// ANYSIZE gibt an, ob auch VAR_SIZE und MIN_SIZE angaben exportiert werden
+// ABSSIZE gibt an, ob Abstand und Umrandung ignoriert werden sollen
+const sal_uInt32 HTML_FRMOPT_ALIGN = 1<<0;
+const sal_uInt32 HTML_FRMOPT_S_ALIGN = 1<<1;
+
+const sal_uInt32 HTML_FRMOPT_WIDTH = 1<<2;
+const sal_uInt32 HTML_FRMOPT_HEIGHT = 1<<3;
+const sal_uInt32 HTML_FRMOPT_SIZE = HTML_FRMOPT_WIDTH|HTML_FRMOPT_HEIGHT;
+const sal_uInt32 HTML_FRMOPT_S_WIDTH = 1<<4;
+const sal_uInt32 HTML_FRMOPT_S_HEIGHT = 1<<5;
+const sal_uInt32 HTML_FRMOPT_S_SIZE = HTML_FRMOPT_S_WIDTH|HTML_FRMOPT_S_HEIGHT;
+const sal_uInt32 HTML_FRMOPT_ANYSIZE = 1<<6;
+const sal_uInt32 HTML_FRMOPT_ABSSIZE = 1<<7;
+const sal_uInt32 HTML_FRMOPT_MARGINSIZE = 1<<8;
+
+const sal_uInt32 HTML_FRMOPT_SPACE = 1<<9;
+const sal_uInt32 HTML_FRMOPT_S_SPACE = 1<<10;
+
+const sal_uInt32 HTML_FRMOPT_BORDER = 1<<11;
+const sal_uInt32 HTML_FRMOPT_S_BORDER = 1<<12;
+const sal_uInt32 HTML_FRMOPT_S_NOBORDER = 1<<13;
+
+const sal_uInt32 HTML_FRMOPT_S_BACKGROUND = 1<<14;
+
+const sal_uInt32 HTML_FRMOPT_NAME = 1<<15;
+const sal_uInt32 HTML_FRMOPT_ALT = 1<<16;
+const sal_uInt32 HTML_FRMOPT_BRCLEAR = 1<<17;
+const sal_uInt32 HTML_FRMOPT_S_PIXSIZE = 1<<18;
+const sal_uInt32 HTML_FRMOPT_ID = 1<<19;
+const sal_uInt32 HTML_FRMOPT_DIR = 1<<20;
+
+
+const sal_uInt32 HTML_FRMOPTS_GENIMG_ALL =
+ HTML_FRMOPT_ALT |
+ HTML_FRMOPT_SIZE |
+ HTML_FRMOPT_ABSSIZE |
+ HTML_FRMOPT_NAME;
+const sal_uInt32 HTML_FRMOPTS_GENIMG_CNTNR = HTML_FRMOPTS_GENIMG_ALL;
+const sal_uInt32 HTML_FRMOPTS_GENIMG =
+ HTML_FRMOPTS_GENIMG_ALL |
+ HTML_FRMOPT_ALIGN |
+ HTML_FRMOPT_SPACE |
+ HTML_FRMOPT_BRCLEAR;
+
+#define HTMLMODE_BLOCK_SPACER 0x00010000
+#define HTMLMODE_FLOAT_FRAME 0x00020000
+#define HTMLMODE_VERT_SPACER 0x00040000
+#define HTMLMODE_NBSP_IN_TABLES 0x00080000
+#define HTMLMODE_LSPACE_IN_NUMBUL 0x00100000
+#define HTMLMODE_NO_BR_AT_PAREND 0x00200000
+#define HTMLMODE_PRINT_EXT 0x00400000
+#define HTMLMODE_ABS_POS_FLY 0x00800000
+#define HTMLMODE_ABS_POS_DRAW 0x01000000
+#define HTMLMODE_FLY_MARGINS 0x02000000
+#define HTMLMODE_BORDER_NONE 0x04000000
+#define HTMLMODE_FONT_GENERIC 0x08000000
+#define HTMLMODE_FRSTLINE_IN_NUMBUL 0x10000000
+#define HTMLMODE_NO_CONTROL_CENTERING 0x20000000
+
+#define HTML_DLCOLL_DD 0x4000
+#define HTML_DLCOLL_DT 0x8000
+
+#define CSS1_FMT_ISTAG (USHRT_MAX)
+#define CSS1_FMT_CMPREF (USHRT_MAX-1)
+#define CSS1_FMT_SPECIAL (USHRT_MAX-1)
+
+// Die folgenden Flags bestimmen nur, welche Descriptoren, Tags, Optionen etc.
+// ausgegeben werden ...
+// bit 0,1,2
+#define CSS1_OUTMODE_SPAN_NO_ON 0x0000U
+#define CSS1_OUTMODE_SPAN_TAG_ON 0x0001U
+#define CSS1_OUTMODE_STYLE_OPT_ON 0x0002U
+#define CSS1_OUTMODE_RULE_ON 0x0003U
+#define CSS1_OUTMODE_SPAN_TAG1_ON 0x0004U
+#define CSS1_OUTMODE_ANY_ON 0x0007U
+
+// bit 3,4,5
+#define CSS1_OUTMODE_SPAN_NO_OFF 0x0000U
+#define CSS1_OUTMODE_SPAN_TAG_OFF ((sal_uInt16)(0x0001U << 3))
+#define CSS1_OUTMODE_STYLE_OPT_OFF ((sal_uInt16)(0x0002U << 3))
+#define CSS1_OUTMODE_RULE_OFF ((sal_uInt16)(0x0003U << 3))
+#define CSS1_OUTMODE_SPAN_TAG1_OFF ((sal_uInt16)(0x0004U << 3))
+#define CSS1_OUTMODE_ANY_OFF ((sal_uInt16)(0x0007U << 3))
+
+#define CSS1_OUTMODE_ONOFF(a) (CSS1_OUTMODE_##a##_ON|CSS1_OUTMODE_##a##_OFF)
+#define CSS1_OUTMODE_SPAN_TAG CSS1_OUTMODE_ONOFF(SPAN_TAG)
+#define CSS1_OUTMODE_STYLE_OPT CSS1_OUTMODE_ONOFF(STYLE_OPT)
+#define CSS1_OUTMODE_RULE CSS1_OUTMODE_ONOFF(RULE)
+#define CSS1_OUTMODE_SPAN_TAG1 CSS1_OUTMODE_ONOFF(TAG1)
+
+// Die folgenden Flags legen fest, was ausgegeben wird
+// bit 6,7,8,9
+#define CSS1_OUTMODE_TEMPLATE 0x0000U
+#define CSS1_OUTMODE_BODY ((sal_uInt16)(0x0001U << 6))
+#define CSS1_OUTMODE_PARA ((sal_uInt16)(0x0002U << 6))
+#define CSS1_OUTMODE_HINT ((sal_uInt16)(0x0003U << 6))
+#define CSS1_OUTMODE_FRAME ((sal_uInt16)(0x0004U << 6))
+#define CSS1_OUTMODE_TABLE ((sal_uInt16)(0x0005U << 6))
+#define CSS1_OUTMODE_TABLEBOX ((sal_uInt16)(0x0006U << 6))
+#define CSS1_OUTMODE_DROPCAP ((sal_uInt16)(0x0007U << 6))
+#define CSS1_OUTMODE_SECTION ((sal_uInt16)(0x0008U << 6))
+#define CSS1_OUTMODE_SOURCE ((sal_uInt16)(0x000fU << 6))
+
+// bit 10
+#define CSS1_OUTMODE_ENCODE ((sal_uInt16)(0x0001U << 10))
+
+// bit 11,12,13
+// don't care about script
+#define CSS1_OUTMODE_ANY_SCRIPT 0x0000U
+// no cjk or ctl items
+#define CSS1_OUTMODE_WESTERN ((sal_uInt16)(0x0001U << 11))
+// no western or ctl items
+#define CSS1_OUTMODE_CJK ((sal_uInt16)(0x0002U << 11))
+// no western or cjk items
+#define CSS1_OUTMODE_CTL ((sal_uInt16)(0x0003U << 11))
+// no western, cjk or ctl items
+#define CSS1_OUTMODE_NO_SCRIPT ((sal_uInt16)(0x0004U << 11))
+#define CSS1_OUTMODE_SCRIPT ((sal_uInt16)(0x0007U << 11))
+
+// der HTML-Writer
+struct HTMLControl;
+SV_DECL_PTRARR_SORT_DEL( HTMLControls, HTMLControl*, 1, 1 )
+SV_DECL_PTRARR( INetFmts, SwFmtINetFmt*, 1, 1 )
+
+struct SwHTMLFmtInfo;
+SV_DECL_PTRARR_SORT_DEL( SwHTMLFmtInfos, SwHTMLFmtInfo*, 1, 1 )
+
+class IDocumentStylePoolAccess;
+
+class SwHTMLWriter : public Writer
+{
+ SwHTMLPosFlyFrms *pHTMLPosFlyFrms;
+ SwHTMLNumRuleInfo *pNumRuleInfo;// aktuelle Numerierung
+ SwHTMLNumRuleInfo *pNextNumRuleInfo;
+ sal_uInt32 nHTMLMode; // Beschreibung der Export-Konfiguration
+
+ FieldUnit eCSS1Unit;
+
+ sal_uInt16 OutHeaderAttrs();
+ const SwPageDesc *MakeHeader( sal_uInt16& rHeaderAtrs );
+ void GetControls();
+
+ void AddLinkTarget( const String& rURL );
+ void CollectLinkTargets();
+
+protected:
+ ULONG WriteStream();
+
+public:
+#if defined(UNX)
+ static const sal_Char sNewLine; // nur \012 oder \015
+#else
+ static const sal_Char __FAR_DATA sNewLine[]; // \015\012
+#endif
+
+ SvStringsDtor aImgMapNames; // geschriebene Image Maps
+ SvStringsSortDtor aImplicitMarks;// implizite Stprungmarken
+ SvStringsDtor aOutlineMarks; // geschriebene Image Maps
+ SvStringsSortDtor aNumRuleNames;// Names of exported num rules
+ SvStringsSortDtor aScriptParaStyles;// script dependent para styles
+ SvStringsSortDtor aScriptTextStyles;// script dependent text styles
+ SvULongs aOutlineMarkPoss;
+ HTMLControls aHTMLControls; // die zu schreibenden ::com::sun::star::form::Forms
+ SwHTMLFmtInfos aChrFmtInfos;
+ SwHTMLFmtInfos aTxtCollInfos;
+ INetFmts aINetFmts; // die "offenen" INet-Attribute
+ SwHTMLTxtFtns *pFootEndNotes;
+
+ String aCSS1Selector; // der Selektor eines Styles
+ String aNonConvertableCharacters;
+ String aBulletGrfs[MAXLEVEL]; // die Grafiken fuer Listen
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > *pxFormComps; // die aktuelle Form
+
+ SwDoc *pTemplate; // die HTML-Vorlage
+ Color *pDfltColor; // default Farbe
+ SwNodeIndex *pStartNdIdx; // Index des ersten Absatz
+ const SwPageDesc *pCurrPageDesc;// Die aktuelle Seiten-Vorlage
+ const SwFmtFtn *pFmtFtn;
+
+ sal_uInt32 aFontHeights[7]; // die Font-Hoehen 1-7
+
+ sal_uInt32 nWarn; // Result-Code fuer Warnungen
+ sal_uInt32 nLastLFPos; // letzte Position eines LF
+
+ sal_uInt16 nLastParaToken; // fuers Absaetze zusammenhalten
+ sal_Int32 nBkmkTabPos; // akt. Position in der Bookmark-Tabelle
+ sal_uInt16 nImgMapCnt; // zum eindeutig
+ sal_uInt16 nFormCntrlCnt;
+ sal_uInt16 nEndNote;
+ sal_uInt16 nFootNote;
+ sal_Int32 nLeftMargin; // linker Einzug (z.B. aus Listen)
+ sal_Int32 nDfltLeftMargin; // die dafaults, der nicht geschrieben
+ sal_Int32 nDfltRightMargin; // werden muessen (aus der Vorlage)
+ short nFirstLineIndent; // Erstzeilen-Einzug (aus Listen)
+ short nDfltFirstLineIndent; // nicht zu schreibender default
+ sal_uInt16 nDfltTopMargin; // die defaults, der nicht geschrieben
+ sal_uInt16 nDfltBottomMargin; // werden muessen (aus der Vorlage)
+ sal_uInt16 nIndentLvl; // wie weit ist eingerueckt?
+ xub_StrLen nWhishLineLen; // wie lang darf eine Zeile werden?
+ sal_uInt16 nDefListLvl; // welcher DL-Level existiert gerade
+ sal_Int32 nDefListMargin; // Wie weit wird in DL eingerueckt
+ sal_uInt16 nHeaderFooterSpace;
+ sal_uInt16 nTxtAttrsToIgnore;
+ sal_uInt16 nExportMode;
+ sal_uInt16 nCSS1OutMode;
+ sal_uInt16 nCSS1Script; // contains default script (that's the one
+ // that is not contained in class names)
+ sal_uInt16 nDirection; // the current direction
+
+ rtl_TextEncoding eDestEnc;
+ LanguageType eLang;
+
+ // Beschreibung der Export-Konfiguration
+ // 0
+ sal_Bool bCfgOutStyles : 1; // Styles exportieren
+ sal_Bool bCfgPreferStyles : 1; // Styles herkoemmlichen Tags vorziehen
+ sal_Bool bCfgFormFeed : 1; // Form-Feeds exportieren
+ sal_Bool bCfgStarBasic : 1; // StarBasic exportieren
+ sal_Bool bCfgCpyLinkedGrfs : 1;
+
+ // Beschreibung dessen, was exportiert wird
+
+ sal_Bool bFirstLine : 1; // wird die 1. Zeile ausgegeben ?
+ sal_Bool bTagOn : 1; // Tag an oder aus/Attr-Start oder -Ende
+
+ // Die folgenden beiden Flags geben an, wir Attribute exportiert werden:
+ // bTxtAttr bOutOpts
+ // 0 0 Style-Sheets
+ // 1 0 Hints: Jedes Attribut wird als eignes Tag
+ // geschrieben und es gibt ein End-Tag
+ // 0 1 (Absatz-)Attribute: Das Attribut wird als Option
+ // eines bereits geschrieben Tags exportiert. Es
+ // gibt kein End-Tag.
+ sal_Bool bTxtAttr : 1;
+ // 8
+ sal_Bool bOutOpts : 1;
+
+ sal_Bool bOutTable : 1; // wird der Tabelleninhalt geschrieben?
+ sal_Bool bOutHeader : 1;
+ sal_Bool bOutFooter : 1;
+ sal_Bool bOutFlyFrame : 1;
+
+ // Flags fuer Style-Export
+
+ sal_Bool bFirstCSS1Rule : 1; // wurde schon eine Property ausgegeben
+ sal_Bool bFirstCSS1Property : 1; // wurde schon eine Property ausgegeben
+ sal_Bool bPoolCollTextModified : 1; // die Textkoerper-Vorlage wurde
+ // modifiziert.
+ // 16
+ sal_Bool bCSS1IgnoreFirstPageDesc : 1;
+
+ // was muss/kann/darf nicht ausgegeben werden?
+
+ sal_Bool bNoAlign : 1; // HTML-Tag erlaubt kein ALIGN=...
+ sal_Bool bClearLeft : 1; // <BR CLEAR=LEFT> am Absatz-Ende ausg.
+ sal_Bool bClearRight : 1; // <BR CLEAR=RIGHT> am Absatz-Ende ausg.
+ sal_Bool bLFPossible : 1; // ein Zeilenumbruch darf eingef. werden
+
+ // sonstiges
+
+ sal_Bool bPreserveForm : 1; // die aktuelle Form beibehalten
+
+ sal_Bool bCfgNetscape4 : 1; // Netscape4 Hacks
+ // 23
+
+ SwHTMLWriter( const String& rBaseURL );
+ virtual ~SwHTMLWriter();
+
+ void Out_SwDoc( SwPaM* ); // schreibe den makierten Bereich
+
+ // gebe alle an in aktuellen Ansatz stehenden ::com::sun::star::text::Bookmarks aus
+ void OutAnchor( const String& rName );
+ void OutBookmarks();
+ void OutImplicitMark( const String& rMark, const sal_Char *pMarkType );
+ void OutHyperlinkHRefValue( const String& rURL );
+
+ // gebe die evt. an der akt. Position stehenden FlyFrame aus.
+ sal_Bool OutFlyFrm( ULONG nNdIdx, xub_StrLen nCntntIdx,
+ sal_uInt8 nPos, HTMLOutContext *pContext = 0 );
+ void OutFrmFmt( sal_uInt8 nType, const SwFrmFmt& rFmt,
+ const SdrObject *pSdrObj );
+
+ void OutForm( sal_Bool bTagOn=sal_True, const SwStartNode *pStNd=0 );
+ void OutHiddenForms();
+ void OutHiddenForm( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::form::XForm > & rForm );
+
+ void OutForm( sal_Bool bOn, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > & rFormComps );
+ void OutHiddenControls( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XIndexContainer > & rFormComps,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet );
+ sal_Bool HasControls() const;
+
+ void OutFootEndNoteInfo();
+ void OutFootEndNotes();
+ String GetFootEndNoteSym( const SwFmtFtn& rFmtFtn );
+ void OutFootEndNoteSym( const SwFmtFtn& rFmtFtn, const String& rNum,
+ sal_uInt16 nScript );
+
+#ifdef JAVA_BASIC_IDE
+ void OutBasicModule( const String& rName, const String& rLanguage );
+#endif
+ void OutBasic();
+
+ void OutAndSetDefList( sal_uInt16 nNewLvl );
+
+ void OutStyleSheet( const SwPageDesc& rPageDesc, sal_Bool bUsed=sal_True );
+
+ inline void OutCSS1_PropertyAscii( const sal_Char *pProp,
+ const sal_Char *pVal );
+ inline void OutCSS1_PropertyAscii( const sal_Char *pProp,
+ const ByteString& rVal );
+ inline void OutCSS1_Property( const sal_Char *pProp, const String& rVal );
+ void OutCSS1_Property( const sal_Char *pProp, const sal_Char *pVal,
+ const String *pSVal );
+ void OutCSS1_UnitProperty( const sal_Char *pProp, long nVal );
+ void OutCSS1_PixelProperty( const sal_Char *pProp, long nVal, sal_Bool bVert );
+ void OutCSS1_SfxItemSet( const SfxItemSet& rItemSet, sal_Bool bDeep=sal_True );
+
+ // BODY-Tag-Events aus der SFX-Konfigaurion
+ void OutBasicBodyEvents();
+
+ // BACKGROUND/BGCOLOR-Option
+ void OutBackground( const SvxBrushItem *pBrushItem, String& rEmbGrfNm,
+ sal_Bool bGraphic );
+ void OutBackground( const SfxItemSet& rItemSet, String &rEmbGrfName,
+ sal_Bool bGraphic );
+
+ void OutLanguage( LanguageType eLang );
+ sal_uInt16 GetHTMLDirection( sal_uInt16 nDir ) const;
+ sal_uInt16 GetHTMLDirection( const SfxItemSet& rItemSet ) const;
+ void OutDirection( sal_uInt16 nDir );
+
+ // ALT/ALIGN/WIDTH/HEIGHT/HSPACE/VSPACE-Optionen des aktuellen
+ // Frame-Formats ausgeben und ggf. ein <BR CLEAR=...> vorne an
+ // rEndTags anhaengen
+ void OutFrmFmtOptions( const SwFrmFmt& rFrmFmt, const String& rAltTxt,
+ ByteString &rEndTags, sal_uInt32 nFrmOpts );
+ void OutCSS1_TableFrmFmtOptions( const SwFrmFmt& rFrmFmt );
+ void OutCSS1_SectionFmtOptions( const SwFrmFmt& rFrmFmt );
+ void OutCSS1_FrmFmtOptions( const SwFrmFmt& rFrmFmt, sal_uInt32 nFrmOpts,
+ const SdrObject *pSdrObj=0,
+ const SfxItemSet *pItemSet=0 );
+ void OutCSS1_FrmFmtBackground( const SwFrmFmt& rFrmFmt );
+
+ void ChangeParaToken( sal_uInt16 nNew );
+
+ void IncIndentLevel() { nIndentLvl++; }
+ void DecIndentLevel() { if ( nIndentLvl ) nIndentLvl--; }
+ void GetIndentString( ByteString& rStr, sal_uInt16 nIncLvl=0 );
+
+ xub_StrLen GetLineLen() { return (xub_StrLen)(Strm().Tell()-nLastLFPos); }
+ void OutNewLine( sal_Bool bCheck=sal_False );
+
+ // fuer HTMLSaveData
+ SwPaM* GetEndPaM() { return pOrigPam; }
+ void SetEndPaM( SwPaM* pPam ) { pOrigPam = pPam; }
+
+ sal_uInt32 ToPixel( sal_uInt32 nVal ) const;
+
+ sal_uInt16 GuessFrmType( const SwFrmFmt& rFrmFmt,
+ const SdrObject*& rpStrObj );
+ sal_uInt16 GuessOLENodeFrmType( const SwNode& rNd );
+
+ void CollectFlyFrms();
+
+ sal_uInt16 GetHTMLFontSize( sal_uInt32 nFontHeight ) const;
+
+ // Die aktuelle Numerierungs-Information holen.
+ SwHTMLNumRuleInfo& GetNumInfo() { return *pNumRuleInfo; }
+
+ // Die Numerierungs-Information des naechsten Absatz holen. Sie
+ // muss noch nicht vorhanden sein!
+ SwHTMLNumRuleInfo *GetNextNumInfo() { return pNextNumRuleInfo; }
+
+ // Die Numerierungs-Information des naechsten Absatz setzen.
+ void SetNextNumInfo( SwHTMLNumRuleInfo *pNxt ) { pNextNumRuleInfo=pNxt; }
+
+ // Die Numerierungs-Information des naeschten Absatz fuellen.
+ void FillNextNumInfo();
+
+ // Die Numerierungs-Information des naeschten Absatz loeschen.
+ void ClearNextNumInfo();
+
+ static const SdrObject *GetHTMLControl( const SwDrawFrmFmt& rFmt );
+ static const SdrObject *GetMarqueeTextObj( const SwDrawFrmFmt& rFmt );
+ static sal_uInt16 GetCSS1Selector( const SwFmt *pFmt, ByteString& rToken,
+ String& rClass, sal_uInt16& rRefPoolId,
+ String *pPseudo=0 );
+
+ static const SwFmt *GetTemplateFmt( sal_uInt16 nPoolId, IDocumentStylePoolAccess* /*SwDoc*/ pTemplate );
+ static const SwFmt *GetParentFmt( const SwFmt& rFmt, sal_uInt16 nDeep );
+
+ static void SubtractItemSet( SfxItemSet& rItemSet,
+ const SfxItemSet& rRefItemSet,
+ sal_Bool bSetDefaults,
+ sal_Bool bClearSame = sal_True,
+ const SfxItemSet *pRefScriptItemSet=0 );
+ static sal_Bool HasScriptDependentItems( const SfxItemSet& rItemSet,
+ sal_Bool bCheckDropCap );
+
+ static void GetEEAttrsFromDrwObj( SfxItemSet& rItemSet,
+ const SdrObject *pObj,
+ sal_Bool bSetDefaults );
+
+ static sal_uInt16 GetDefListLvl( const String& rNm, sal_uInt16 nPoolId );
+
+ sal_uInt32 GetHTMLMode() const { return nHTMLMode; }
+ sal_Bool IsHTMLMode( sal_uInt32 nMode ) const { return (nHTMLMode & nMode) != 0; }
+
+ inline sal_Bool IsCSS1Source( sal_uInt16 n ) const;
+ inline sal_Bool IsCSS1Script( sal_uInt16 n ) const;
+
+ static const sal_Char *GetNumFormat( sal_uInt16 nFmt );
+ static void PrepareFontList( const SvxFontItem& rFontItem, String& rNames,
+ sal_Unicode cQuote, sal_Bool bGeneric );
+ static sal_uInt16 GetCSS1ScriptForScriptType( sal_uInt16 nScriptType );
+ static sal_uInt16 GetLangWhichIdFromScript( sal_uInt16 nScript );
+
+ FieldUnit GetCSS1Unit() const { return eCSS1Unit; }
+};
+
+inline sal_Bool SwHTMLWriter::IsCSS1Source( sal_uInt16 n ) const
+{
+ return n == (nCSS1OutMode & CSS1_OUTMODE_SOURCE);
+}
+
+inline sal_Bool SwHTMLWriter::IsCSS1Script( sal_uInt16 n ) const
+{
+ sal_uInt16 nScript = (nCSS1OutMode & CSS1_OUTMODE_SCRIPT);
+ return CSS1_OUTMODE_ANY_SCRIPT == nScript || n == nScript;
+}
+
+inline void SwHTMLWriter::OutCSS1_PropertyAscii( const sal_Char *pProp,
+ const sal_Char *pVal )
+{
+ OutCSS1_Property( pProp, pVal, 0 );
+}
+
+inline void SwHTMLWriter::OutCSS1_PropertyAscii( const sal_Char *pProp,
+ const ByteString& rVal )
+{
+ OutCSS1_Property( pProp, rVal.GetBuffer(), 0 );
+}
+
+inline void SwHTMLWriter::OutCSS1_Property( const sal_Char *pProp,
+ const String& rVal )
+{
+ OutCSS1_Property( pProp, 0, &rVal );
+}
+
+// Struktur speichert die aktuellen Daten des Writers zwischen, um
+// einen anderen Dokument-Teil auszugeben, wie z.B. Header/Footer
+// Mit den beiden USHORTs im CTOR wird ein neuer PaM erzeugt und auf
+// die Position im Dokument gesetzt.
+// Im Destructor werden alle Daten wieder restauriert und der angelegte
+// Pam wieder geloescht.
+
+struct HTMLSaveData
+{
+ SwHTMLWriter& rWrt;
+ SwPaM* pOldPam, *pOldEnd;
+ SwHTMLNumRuleInfo *pOldNumRuleInfo; // Owner = this
+ SwHTMLNumRuleInfo *pOldNextNumRuleInfo; // Owner = HTML-Writer
+ sal_uInt16 nOldDefListLvl;
+ sal_uInt16 nOldDirection;
+ sal_Bool bOldWriteAll : 1;
+ sal_Bool bOldOutHeader : 1;
+ sal_Bool bOldOutFooter : 1;
+ sal_Bool bOldOutFlyFrame : 1;
+ const SwFlyFrmFmt* pOldFlyFmt;
+
+ HTMLSaveData( SwHTMLWriter&, ULONG nStt, ULONG nEnd,
+ sal_Bool bSaveNum=sal_True,
+ const SwFrmFmt *pFrmFmt=0 );
+ ~HTMLSaveData();
+};
+
+
+// einige Funktions-Deklarationen
+Writer& OutHTML_FrmFmtOLENode( Writer& rWrt, const SwFrmFmt& rFmt,
+ sal_Bool bInCntnr );
+Writer& OutHTML_FrmFmtOLENodeGrf( Writer& rWrt, const SwFrmFmt& rFmt,
+ sal_Bool bInCntnr );
+
+Writer& OutHTML_SwTxtNode( Writer&, const SwCntntNode& );
+Writer& OutHTML_SwTblNode( Writer& , SwTableNode &, const SwFrmFmt *,
+ const String* pCaption=0, sal_Bool bTopCaption=sal_False );
+
+Writer& OutHTML_DrawFrmFmtAsControl( Writer& rWrt, const SwDrawFrmFmt& rFmt,
+ const SdrObject& rSdrObj, sal_Bool bInCntnr );
+Writer& OutHTML_DrawFrmFmtAsMarquee( Writer& rWrt, const SwDrawFrmFmt& rFmt,
+ const SdrObject& rSdrObj );
+
+Writer& OutHTML_HeaderFooter( Writer& rWrt, const SwFrmFmt& rFrmFmt,
+ sal_Bool bHeader );
+
+Writer& OutHTML_Image( Writer&, const SwFrmFmt& rFmt,
+ const String& rGrfName, const String& rAlternateTxt,
+ const Size& rRealSize, sal_uInt32 nFrmOpts,
+ const sal_Char *pMarkType = 0,
+ const ImageMap *pGenImgMap = 0 );
+Writer& OutHTML_BulletImage( Writer& rWrt, const sal_Char *pTag,
+ const SvxBrushItem* pBrush, String &rGrfName,
+ const Size &rSize,
+ const SwFmtVertOrient* pVertOrient );
+
+Writer& OutHTML_SwFmtFld( Writer& rWrt, const SfxPoolItem& rHt );
+Writer& OutHTML_SwFmtFtn( Writer& rWrt, const SfxPoolItem& rHt );
+Writer& OutHTML_INetFmt( Writer&, const SwFmtINetFmt& rINetFmt, sal_Bool bOn );
+
+Writer& OutCSS1_BodyTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet,
+ String aEmbBGGrfName );
+Writer& OutCSS1_ParaTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet );
+
+Writer& OutCSS1_HintSpanTag( Writer& rWrt, const SfxPoolItem& rHt );
+Writer& OutCSS1_HintStyleOpt( Writer& rWrt, const SfxPoolItem& rHt );
+
+Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const SfxPoolItem& rHt );
+Writer& OutCSS1_NumBulListStyleOpt( Writer& rWrt, const SwNumRule& rNumRule,
+ sal_uInt8 nLevel );
+
+Writer& OutHTML_NumBulListStart( SwHTMLWriter& rWrt,
+ const SwHTMLNumRuleInfo& rInfo );
+Writer& OutHTML_NumBulListEnd( SwHTMLWriter& rWrt,
+ const SwHTMLNumRuleInfo& rNextInfo );
+
+
+#endif // _WRTHTML_HXX
+