diff options
Diffstat (limited to 'sw/source/filter/ww8')
26 files changed, 11619 insertions, 4601 deletions
diff --git a/sw/source/filter/ww8/WW8TableInfo.cxx b/sw/source/filter/ww8/WW8TableInfo.cxx index eb3dfe80b5d0..89411344bf7b 100644 --- a/sw/source/filter/ww8/WW8TableInfo.cxx +++ b/sw/source/filter/ww8/WW8TableInfo.cxx @@ -557,8 +557,7 @@ WW8TableNodeInfo::Pointer_t WW8TableInfo::insertTableNodeInfo if (pNodeInfo.get() == NULL) { - pNodeInfo = WW8TableNodeInfo::Pointer_t - (new WW8TableNodeInfo(pNode)); + pNodeInfo = WW8TableNodeInfo::Pointer_t(new WW8TableNodeInfo(pNode)); mMap.insert(Map_t::value_type(pNode, pNodeInfo)); } diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx new file mode 100644 index 000000000000..98f2f6074349 --- /dev/null +++ b/sw/source/filter/ww8/attributeoutputbase.hxx @@ -0,0 +1,584 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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 _ATTRIBUTEOUTPUTBASE_HXX_ +#define _ATTRIBUTEOUTPUTBASE_HXX_ + +#include "fields.hxx" +#include "WW8TableInfo.hxx" + +#include <rtl/textenc.h> +#include <svx/svxenum.hxx> +#include <tools/solar.h> + +#include <swtypes.hxx> +#include <wrtswtbl.hxx> +#include <fldbas.hxx> + +#include <vector> + +class Point; +class SvxCaseMapItem; +class SvxColorItem; +class SvxContourItem; +class SvxCrossedOutItem; +class SvxEscapementItem; +class SvxFontItem; +class SvxFontHeightItem; +class SvxKerningItem; +class SvxLanguageItem; +class SvxPostureItem; +class SvxShadowedItem; +class SvxUnderlineItem; +class SvxWeightItem; +class SvxAutoKernItem; +class SvxBlinkItem; +class SvxBrushItem; +class SvxFontItem; +class SvxFontHeightItem; +class SvxLanguageItem; +class SvxPostureItem; +class SvxWeightItem; +class SvxFontItem; +class SvxFontHeightItem; +class SvxLanguageItem; +class SvxPostureItem; +class SvxWeightItem; +class SvxCharRotateItem; +class SvxEmphasisMarkItem; +class SvxTwoLinesItem; +class SvxCharScaleWidthItem; +class SvxCharReliefItem; +class SvxCharHiddenItem; +class SwFmtINetFmt; +class SwFmtCharFmt; +class SwFmtFld; +class SwFmtFlyCnt; +class SwFmtFtn; +class SwFmtHardBlank; +class SvxLineSpacingItem; +class SvxAdjustItem; +class SvxFmtSplitItem; +class SvxWidowsItem; +class SvxTabStopItem; +class SvxHyphenZoneItem; +class SwNumRuleItem; +class SfxBoolItem; +class SfxPoolItem; +class SfxItemSet; +class SvxParaVertAlignItem; +class SvxParaGridItem; +class SwFmtFrmSize; +class SvxPaperBinItem; +class SvxLRSpaceItem; +class SvxULSpaceItem; +class SwFmtPageDesc; +class SvxFmtBreakItem; +class SwFmtSurround; +class SwFmtVertOrient; +class SwFmtHoriOrient; +class SwFmtAnchor; +class SvxBrushItem; +class SvxBoxItem; +class SwFmtCol; +class SvxFmtKeepItem; +class SwTextGridItem; +class SwFmtLineNumber; +class SvxFrameDirectionItem; +class SwFmtRuby; +class SwTxtNode; +class SwTOXMark; +class SwRedlineData; +class SwSection; +class SwFmtDrop; +class SwFrmFmt; +class SwNumFmt; +class SwFmt; +class SwTableNode; +struct WW8_SepInfo; +struct WW8_PdAttrDesc; +class SwLineNumberInfo; +class SwNumRule; +class wwFont; + +class String; + +class MSWordExportBase; + +namespace sw { class Frame; } + +namespace msword { + const BYTE ColumnBreak = 0xE; + const BYTE PageBreak = 0xC; +} + +class AttributeOutputBase +{ +public: + /// Export the state of RTL/CJK. + virtual void RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ) = 0; + + /// Start of the paragraph. + virtual void StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo ) = 0; + + /// End of the paragraph. + virtual void EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) = 0; + + /// Called before we start outputting the attributes. + virtual void StartParagraphProperties( const SwTxtNode& rNode ) = 0; + + /// Called after we end outputting the attributes. + virtual void EndParagraphProperties() = 0; + + /// Empty paragraph. + virtual void EmptyParagraph() = 0; + + /// Start of the text run. + virtual void StartRun( const SwRedlineData* pRedlineData ) = 0; + + /// End of the text run. + virtual void EndRun() = 0; + + /// Called before we start outputting the attributes. + virtual void StartRunProperties() = 0; + + /// Called after we end outputting the attributes. + virtual void EndRunProperties( const SwRedlineData* pRedlineData ) = 0; + + /// Output text (inside a run). + virtual void RunText( const String& rText, rtl_TextEncoding eCharSet ) = 0; + + /// Output text (without markup). + virtual void RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet ) = 0; + + /// Output ruby start. + virtual void StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby ) = 0; + + /// Output ruby end. + virtual void EndRuby() = 0; + + /// Output URL start. + virtual bool StartURL( const String& rUrl, const String& rTarget ) = 0; + + /// Output URL end. + virtual bool EndURL() = 0; + + virtual void FieldVanish( const String& rTxt, ww::eField eType ) = 0; + + void StartTOX( const SwSection& rSect ); + + void EndTOX( const SwSection& rSect ); + + virtual void TOXMark( const SwTxtNode& rNode, const SwTOXMark& rAttr ); + + /// Output redlining. + virtual void Redline( const SwRedlineData* pRedline ) = 0; + + virtual void FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, USHORT nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) = 0; + + /// Output FKP (Formatted disK Page) - necessary for binary formats only. + /// FIXME having it in AttributeOutputBase is probably a hack, it + /// should be in WW8AttributeOutput only... + virtual void OutputFKP() {} + + /// Output style. + virtual void ParagraphStyle( USHORT nStyle ) = 0; + + virtual void TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ) = 0; + + virtual void TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo ) = 0; + + virtual void TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner ) = 0; + + virtual void TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) = 0; + + virtual void TableRowEnd( sal_uInt32 nDepth ) = 0; + + /// Start of the styles table. + virtual void StartStyles() = 0; + + /// End of the styles table. + virtual void EndStyles( USHORT nNumberOfStyles ) = 0; + + /// Write default style. + virtual void DefaultStyle( USHORT nStyle ) = 0; + + /// Start of a style in the styles table. + virtual void StartStyle( const String& rName, bool bPapFmt, + USHORT nBase, USHORT nNext, USHORT nWwId, USHORT nId ) = 0; + + /// End of a style in the styles table. + virtual void EndStyle() = 0; + + /// Start of (paragraph or run) properties of a style. + virtual void StartStyleProperties( bool bParProp, USHORT nStyle ) = 0; + + /// End of (paragraph or run) properties of a style. + virtual void EndStyleProperties( bool bParProp ) = 0; + + /// Numbering rule and Id. + virtual void OutlineNumbering( BYTE nLvl, const SwNumFmt& rNFmt, const SwFmt& rFmt ) = 0; + + /// Page break + /// As a paragraph property - the paragraph should be on the next page. + virtual void PageBreakBefore( bool bBreak ) = 0; + + /// Write a section break + /// msword::ColumnBreak or msword::PageBreak + virtual void SectionBreak( BYTE nC, const WW8_SepInfo* pSectionInfo = NULL ) = 0; + + /// Start of the section properties. + virtual void StartSection() = 0; + + /// End of the section properties. + virtual void EndSection() = 0; + + /// Protection of forms. + virtual void SectionFormProtection( bool bProtected ) = 0; + + /// Numbering of the lines in the document. + virtual void SectionLineNumbering( ULONG nRestartNo, const SwLineNumberInfo& rLnNumInfo ) = 0; + + /// Has different headers/footers for the title page. + virtual void SectionTitlePage() = 0; + + /// Description of the page borders. + virtual void SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* pFirstPageFmt ) = 0; + + /// Columns populated from right/numbers on the right side? + virtual void SectionBiDi( bool bBiDi ) = 0; + + /// The style of the page numbers. + /// + /// nPageRestartNumberr being 0 means no restart. + virtual void SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber ) = 0; + + /// The type of breaking. + virtual void SectionType( BYTE nBreakCode ) = 0; + + /// Special header/footer flags, needed for old versions only. + virtual void SectionWW6HeaderFooterFlags( BYTE /*nHeadFootFlags*/ ) {} + + /// Definition of a numbering instance. + virtual void NumberingDefinition( USHORT nId, const SwNumRule &rRule ) = 0; + + /// Start of the abstract numbering definition instance. + virtual void StartAbstractNumbering( USHORT /*nId*/ ) {} + + /// End of the abstract numbering definition instance. + virtual void EndAbstractNumbering() {} + + /// All the numbering level information. + virtual void NumberingLevel( BYTE nLevel, + USHORT nStart, + USHORT nNumberingType, + SvxAdjust eAdjust, + const BYTE *pNumLvlPos, + BYTE nFollow, + const wwFont *pFont, + const SfxItemSet *pOutSet, + sal_Int16 nIndentAt, + sal_Int16 nFirstLineIndex, + sal_Int16 nListTabPos, + const String &rNumberingString ) = 0; + +protected: + + void GetNumberPara( String& rStr, const SwField& rFld ); + + /// Output frames - the implementation. + virtual void OutputFlyFrame_Impl( const sw::Frame& rFmt, const Point& rNdTopLeft ) = 0; + + /// Sfx item Sfx item RES_CHRATR_CASEMAP + virtual void CharCaseMap( const SvxCaseMapItem& ) = 0; + + /// Sfx item Sfx item RES_CHRATR_COLOR + virtual void CharColor( const SvxColorItem& ) = 0; + + /// Sfx item Sfx item RES_CHRATR_CONTOUR + virtual void CharContour( const SvxContourItem& ) = 0; + + /// Sfx item RES_CHRATR_CROSSEDOUT + virtual void CharCrossedOut( const SvxCrossedOutItem& ) = 0; + + /// Sfx item RES_CHRATR_ESCAPEMENT + virtual void CharEscapement( const SvxEscapementItem& ) = 0; + + /// Sfx item RES_CHRATR_FONT + virtual void CharFont( const SvxFontItem& ) = 0; + + /// Sfx item RES_CHRATR_FONTSIZE + virtual void CharFontSize( const SvxFontHeightItem& ) = 0; + + /// Sfx item RES_CHRATR_KERNING + virtual void CharKerning( const SvxKerningItem& ) = 0; + + /// Sfx item RES_CHRATR_LANGUAGE + virtual void CharLanguage( const SvxLanguageItem& ) = 0; + + /// Sfx item RES_CHRATR_POSTURE + virtual void CharPosture( const SvxPostureItem& ) = 0; + + /// Sfx item RES_CHRATR_SHADOWED + virtual void CharShadow( const SvxShadowedItem& ) = 0; + + /// Sfx item RES_CHRATR_UNDERLINE + virtual void CharUnderline( const SvxUnderlineItem& ) = 0; + + /// Sfx item RES_CHRATR_WEIGHT + virtual void CharWeight( const SvxWeightItem& ) = 0; + + /// Sfx item RES_CHRATR_AUTOKERN + virtual void CharAutoKern( const SvxAutoKernItem& ) = 0; + + /// Sfx item RES_CHRATR_BLINK + virtual void CharAnimatedText( const SvxBlinkItem& ) = 0; + + /// Sfx item RES_CHRATR_BACKGROUND + virtual void CharBackground( const SvxBrushItem& ) = 0; + + /// Sfx item RES_CHRATR_CJK_FONT + virtual void CharFontCJK( const SvxFontItem& ) = 0; + + /// Sfx item RES_CHRATR_CJK_FONTSIZE + virtual void CharFontSizeCJK( const SvxFontHeightItem& ) = 0; + + /// Sfx item RES_CHRATR_CJK_LANGUAGE + virtual void CharLanguageCJK( const SvxLanguageItem& ) = 0; + + /// Sfx item RES_CHRATR_CJK_POSTURE + virtual void CharPostureCJK( const SvxPostureItem& ) = 0; + + /// Sfx item RES_CHRATR_CJK_WEIGHT + virtual void CharWeightCJK( const SvxWeightItem& ) = 0; + + /// Sfx item RES_CHRATR_CTL_FONT + virtual void CharFontCTL( const SvxFontItem& ) = 0; + + /// Sfx item RES_CHRATR_CTL_FONTSIZE + virtual void CharFontSizeCTL( const SvxFontHeightItem& ) = 0; + + /// Sfx item RES_CHRATR_CTL_LANGUAGE + virtual void CharLanguageCTL( const SvxLanguageItem& ) = 0; + + /// Sfx item RES_CHRATR_CTL_POSTURE + virtual void CharPostureCTL( const SvxPostureItem& ) = 0; + + /// Sfx item RES_CHRATR_CTL_WEIGHT + virtual void CharWeightCTL( const SvxWeightItem& ) = 0; + + /// Sfx item RES_CHRATR_ROTATE + virtual void CharRotate( const SvxCharRotateItem& ) = 0; + + /// Sfx item RES_CHRATR_EMPHASIS_MARK + virtual void CharEmphasisMark( const SvxEmphasisMarkItem& ) = 0; + + /// Sfx item RES_CHRATR_TWO_LINES + virtual void CharTwoLines( const SvxTwoLinesItem& ) = 0; + + /// Sfx item RES_CHRATR_SCALEW + virtual void CharScaleWidth( const SvxCharScaleWidthItem& ) = 0; + + /// Sfx item RES_CHRATR_RELIEF + virtual void CharRelief( const SvxCharReliefItem& ) = 0; + + /// Sfx item RES_CHRATR_HIDDEN + virtual void CharHidden( const SvxCharHiddenItem& ) = 0; + + /// Sfx item RES_TXTATR_INETFMT + virtual void TextINetFormat( const SwFmtINetFmt& ) = 0; + + /// Sfx item RES_TXTATR_CHARFMT + virtual void TextCharFormat( const SwFmtCharFmt& ) = 0; + + /// Sfx item RES_TXTATR_FIELD + void TextField( const SwFmtFld& ); + + /// Sfx item RES_TXTATR_FLYCNT + virtual void TextFlyContent( const SwFmtFlyCnt& ); + + /// Sfx item RES_TXTATR_FTN + /// + /// This one is common for both WW8AttributeOutput as well as + /// DocxAttributeOutput. + void TextFootnote( const SwFmtFtn& ); + + /// Sfx item RES_TXTATR_FTN + virtual void TextFootnote_Impl( const SwFmtFtn& ) = 0; + + /// Sfx item RES_TXTATR_HARDBLANK + virtual void TextHardBlank( const SwFmtHardBlank& ) = 0; + + /// Sfx item RES_PARATR_LINESPACING + void ParaLineSpacing( const SvxLineSpacingItem& ); + + /// Count the values in ParaLineSpacing, and pass theme here. + virtual void ParaLineSpacing_Impl( short nSpace, short nMulti ) = 0; + + /// Sfx item RES_PARATR_ADJUST + virtual void ParaAdjust( const SvxAdjustItem& ) = 0; + + /// Sfx item RES_PARATR_SPLIT + virtual void ParaSplit( const SvxFmtSplitItem& ) = 0; + + /// Sfx item RES_PARATR_WIDOWS + virtual void ParaWidows( const SvxWidowsItem& ) = 0; + + /// Sfx item RES_PARATR_TABSTOP + virtual void ParaTabStop( const SvxTabStopItem& ) = 0; + + /// Sfx item RES_PARATR_HYPHENZONE + virtual void ParaHyphenZone( const SvxHyphenZoneItem& ) = 0; + + /// Sfx item RES_PARATR_NUMRULE + void ParaNumRule( const SwNumRuleItem& ); + + /// Numbering - the implementation. + virtual void ParaNumRule_Impl( const SwTxtNode *pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId ) = 0; + + /// Sfx item RES_PARATR_SCRIPTSPACE + virtual void ParaScriptSpace( const SfxBoolItem& ) = 0; + + /// Sfx item RES_PARATR_HANGINGPUNCTUATION + void ParaHangingPunctuation( const SfxBoolItem& rHt ) { ParaScriptSpace( rHt ); }; + + /// Sfx item RES_PARATR_FORBIDDEN_RULES + void ParaForbiddenRules( const SfxBoolItem& rHt ) { ParaScriptSpace( rHt ); }; + + /// Sfx item RES_PARATR_VERTALIGN + virtual void ParaVerticalAlign( const SvxParaVertAlignItem& ) = 0; + + /// Sfx item RES_PARATR_SNAPTOGRID + virtual void ParaSnapToGrid( const SvxParaGridItem& ) = 0; + + /// Sfx item RES_FRM_SIZE + virtual void FormatFrameSize( const SwFmtFrmSize& ) = 0; + + /// Sfx item RES_PAPER_BIN + virtual void FormatPaperBin( const SvxPaperBinItem& ) = 0; + + /// Sfx item RES_LR_SPACE + virtual void FormatLRSpace( const SvxLRSpaceItem& ) = 0; + + /// Sfx item RES_UL_SPACE + virtual void FormatULSpace( const SvxULSpaceItem& ) = 0; + + /// Sfx item RES_PAGEDESC + void FormatPageDescription( const SwFmtPageDesc& ); + + /// Sfx item RES_BREAK + void FormatBreak( const SvxFmtBreakItem& ); + + /// Sfx item RES_SURROUND + virtual void FormatSurround( const SwFmtSurround& ) = 0; + + /// Sfx item RES_VERT_ORIENT + virtual void FormatVertOrientation( const SwFmtVertOrient& ) = 0; + + /// Sfx item RES_HORI_ORIENT + virtual void FormatHorizOrientation( const SwFmtHoriOrient& ) = 0; + + /// Sfx item RES_ANCHOR + virtual void FormatAnchor( const SwFmtAnchor& ) = 0; + + /// Sfx item RES_BACKGROUND + virtual void FormatBackground( const SvxBrushItem& ) = 0; + + /// Sfx item RES_BOX + virtual void FormatBox( const SvxBoxItem& ) = 0; + + /// Sfx item RES_COL + void FormatColumns( const SwFmtCol& ); + + virtual void FormatColumns_Impl( USHORT nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize ) = 0; + + /// Sfx item RES_KEEP + virtual void FormatKeep( const SvxFmtKeepItem& ) = 0; + + /// Sfx item RES_TEXTGRID + virtual void FormatTextGrid( const SwTextGridItem& ) = 0; + + /// Sfx item RES_LINENUMBER + virtual void FormatLineNumbering( const SwFmtLineNumber& ) = 0; + + /// Sfx item RES_FRAMEDIR + virtual void FormatFrameDirection( const SvxFrameDirectionItem& ) = 0; + + /// Write the expanded field + virtual void WriteExpand( const SwField* pFld ) = 0; + + virtual void RefField( const SwField& rFld, const String& rRef ) = 0; + virtual void HiddenField( const SwField& rFld ) = 0; + virtual void SetField( const SwField& rFld, ww::eField eType, const String& rCmd ) = 0; + virtual void PostitField( const SwField* pFld ) = 0; + virtual bool DropdownField( const SwField* pFld ) = 0; + + virtual bool AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark ); + + std::vector<SwTwips> GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + void GetTablePageSize( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize ); + +public: + AttributeOutputBase() {} + virtual ~AttributeOutputBase() {} + + /// Return the right export class. + virtual MSWordExportBase& GetExport() = 0; + + /// Call the right virtual function according to the type of the item. + void OutputItem( const SfxPoolItem& rHt ); + + /// Use OutputItem() on an item set - for styles. + void OutputStyleItemSet( const SfxItemSet& rSet, BOOL bDeep, BOOL bTestForDefault ); + + /// Output frames. + void OutputFlyFrame( const sw::Frame& rFmt ); +}; + +#endif // _ATTRIBUTEOUTPUTBASE_HXX_ + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx new file mode 100644 index 000000000000..537a881f76ad --- /dev/null +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -0,0 +1,3331 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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. + * + ************************************************************************/ + +#include "docxattributeoutput.hxx" +#include "docxexport.hxx" +#include "docxfootnotes.hxx" +#include "writerwordglue.hxx" +#include "wrtww8.hxx" +#include "ww8par.hxx" + +#include <oox/core/tokens.hxx> +#include <oox/export/drawingml.hxx> +#include <oox/export/utils.hxx> +#include <oox/export/vmlexport.hxx> + +#include <i18npool/mslangid.hxx> + +#include <hintids.hxx> + +#include <svtools/poolitem.hxx> + +#include <svx/fontitem.hxx> +#include <svx/tstpitem.hxx> +#include <svx/adjitem.hxx> +#include <svx/spltitem.hxx> +#include <svx/widwitem.hxx> +#include <svx/lspcitem.hxx> +#include <svx/keepitem.hxx> +#include <svx/shaditem.hxx> +#include <svx/brshitem.hxx> +#include <svx/postitem.hxx> +#include <svx/wghtitem.hxx> +#include <svx/kernitem.hxx> +#include <svx/crsditem.hxx> +#include <svx/cmapitem.hxx> +#include <svx/wrlmitem.hxx> +#include <svx/udlnitem.hxx> +#include <svx/langitem.hxx> +#include <svx/escpitem.hxx> +#include <svx/fhgtitem.hxx> +#include <svx/colritem.hxx> +#include <svx/hyznitem.hxx> +#include <svx/brkitem.hxx> +#include <svx/lrspitem.hxx> +#include <svx/ulspitem.hxx> +#include <svx/boxitem.hxx> +#include <svx/cntritem.hxx> +#include <svx/shdditem.hxx> +#include <svx/akrnitem.hxx> +#include <svx/pbinitem.hxx> +#include <svx/emphitem.hxx> +#include <svx/twolinesitem.hxx> +#include <svx/charscaleitem.hxx> +#include <svx/charrotateitem.hxx> +#include <svx/charreliefitem.hxx> +#include <svx/paravertalignitem.hxx> +#include <svx/pgrditem.hxx> +#include <svx/frmdiritem.hxx> +#include <svx/blnkitem.hxx> +#include <svx/charhiddenitem.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdobj.hxx> + +#include <docufld.hxx> +#include <flddropdown.hxx> +#include <format.hxx> +#include <fmtclds.hxx> +#include <fmtinfmt.hxx> +#include <fmtfld.hxx> +#include <fmtfsize.hxx> +#include <fmtftn.hxx> +#include <fmtrowsplt.hxx> +#include <fmtline.hxx> +#include <frmfmt.hxx> +#include <frmatr.hxx> +#include <ftninfo.hxx> +#include <htmltbl.hxx> +#include <ndgrf.hxx> +#include <ndtxt.hxx> +#include <node.hxx> +#include <pagedesc.hxx> +#include <paratr.hxx> +#include <swmodule.hxx> +#include <swtable.hxx> +#include <txtftn.hxx> +#include <txtinet.hxx> +#include <numrule.hxx> + +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> + +#include <tools/color.hxx> + +#include <com/sun/star/i18n/ScriptType.hdl> + +#if OSL_DEBUG_LEVEL > 0 +#include <stdio.h> +#endif + +using rtl::OString; +using rtl::OStringBuffer; +using rtl::OUString; +using rtl::OUStringBuffer; +using rtl::OUStringToOString; + +using namespace docx; +using namespace sax_fastparser; +using namespace nsSwDocInfoSubType; +using namespace nsFieldFlags; +using namespace sw::util; + +void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ ) +{ + if (bIsRTL) + m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND ); +} + +void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo ) +{ + if ( m_nColBreakStatus == COLBRK_POSTPONE ) + m_nColBreakStatus = COLBRK_WRITE; + + // Output table/table row/table cell starts if needed + if ( pTextNodeInfo.get() ) + { + sal_uInt32 nRow = pTextNodeInfo->getRow(); + sal_uInt32 nCell = pTextNodeInfo->getCell(); + + // New cell/row? + if ( m_nTableDepth > 0 && !m_bTableCellOpen ) + { + ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) ); + if ( pDeepInner->getCell() == 0 ) + StartTableRow( pDeepInner ); + + StartTableCell( pDeepInner ); + } + + if ( nRow == 0 && nCell == 0 ) + { + // Do we have to start the table? + // [If we are at the rigth depth already, it means that we + // continue the table cell] + sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth(); + + if ( nCurrentDepth > m_nTableDepth ) + { + // Start all the tables that begin here + for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth ) + { + ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) ); + + StartTable( pInner ); + StartTableRow( pInner ); + StartTableCell( pInner ); + } + + m_nTableDepth = nCurrentDepth; + } + } + } + + m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); + + // postpone the output of the run (we get it before the paragraph + // properties, but must write it after them) + m_pSerializer->mark(); + + // no section break in this paragraph yet; can be set in SectionBreak() + m_pSectionInfo = NULL; + + m_bParagraphOpened = true; +} + +void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) +{ + // write the paragraph properties + the run, already in the correct order + m_pSerializer->mergeTopMarks(); + m_pSerializer->endElementNS( XML_w, XML_p ); + + // Check for end of cell, rows, tables here + FinishTableRowCell( pTextNodeInfoInner ); + + m_bParagraphOpened = false; +} + +void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph ) +{ + if ( pInner.get() ) + { + // Where are we in the table + sal_uInt32 nRow = pInner->getRow( ); + + const SwTable *pTable = pInner->getTable( ); + const SwTableLines& rLines = pTable->GetTabLines( ); + USHORT nLinesCount = rLines.Count( ); + + if ( pInner->isEndOfCell() ) + { + if ( bForceEmptyParagraph ) + m_pSerializer->singleElementNS( XML_w, XML_p, FSEND ); + + EndTableCell(); + } + + // This is a line end + if ( pInner->isEndOfLine() ) + EndTableRow(); + + // This is the end of the table + if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount ) + EndTable(); + } +} + +void DocxAttributeOutput::EmptyParagraph() +{ + m_pSerializer->singleElementNS( XML_w, XML_p, FSEND ); +} + +void DocxAttributeOutput::StartParagraphProperties( const SwTxtNode& rNode ) +{ + // output page/section breaks + // Writer can have them at the beginning of a paragraph, or at the end, but + // in docx, we have to output them in the paragraph properties of the last + // paragraph in a section. To get it right, we have to switch to the next + // paragraph, and detect the section breaks there. + SwNodeIndex aNextIndex( rNode, 1 ); + if ( aNextIndex.GetNode().IsTxtNode() ) + { + const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() ); + m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode ); + } + else if ( aNextIndex.GetNode().IsTableNode() ) + { + const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() ); + const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt(); + m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode ); + } + + // postpone the output so that we can later [in EndParagraphProperties()] + // prepend the properties before the run + m_pSerializer->mark(); + + m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND ); + + // and output the section break now (if it appeared) + if ( m_pSectionInfo ) + { + m_rExport.SectionProperties( *m_pSectionInfo ); + m_pSectionInfo = NULL; + } + + InitCollectedParagraphProperties(); +} + +void DocxAttributeOutput::InitCollectedParagraphProperties() +{ + m_pSpacingAttrList = NULL; +} + +void DocxAttributeOutput::WriteCollectedParagraphProperties() +{ + if ( m_pSpacingAttrList ) + { + XFastAttributeListRef xAttrList( m_pSpacingAttrList ); + m_pSpacingAttrList = NULL; + + m_pSerializer->singleElementNS( XML_w, XML_spacing, xAttrList ); + } +} + +void DocxAttributeOutput::EndParagraphProperties() +{ + WriteCollectedParagraphProperties(); + + m_pSerializer->endElementNS( XML_w, XML_pPr ); + + if ( m_nColBreakStatus == COLBRK_WRITE ) + { + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_br, + FSNS( XML_w, XML_type ), "column", FSEND ); + m_pSerializer->endElementNS( XML_w, XML_r ); + + m_nColBreakStatus = COLBRK_NONE; + } + + // merge the properties _before_ the run (strictly speaking, just + // after the start of the paragraph) + m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); +} + +void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData ) +{ + // if there is some redlining in the document, output it + StartRedline( pRedlineData ); + + // postpone the output of the start of a run (there are elements that need + // to be written before the start of the run, but we learn which they are + // _inside_ of the run) + m_pSerializer->mark(); // let's call it "postponed run start" + + // postpone the output of the text (we get it before the run properties, + // but must write it after them) + m_pSerializer->mark(); // let's call it "postponed text" +} + +void DocxAttributeOutput::EndRun() +{ + // Write field starts + for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt ) + { + // Add the fields starts for all but hyperlinks and TOCs + if ( pIt->bOpen && pIt->pField ) + { + StartField_Impl( *pIt ); + + // Remove the field from the stack if only the start has to be written + // Unknown fields sould be removed too + if ( !pIt->bClose || ( pIt->eType == ww::eUNKNOWN ) ) + { + m_Fields.erase( pIt ); + --pIt; + } + } + } + + + // write the run properties + the text, already in the correct order + m_pSerializer->mergeTopMarks(); // merges with "postponed text", see above + + // level down, to be able to prepend the actual run start attribute (just + // before "postponed run start") + m_pSerializer->mark(); // let's call it "actual run start" + + // prepend the actual run start + if ( m_pHyperlinkAttrList ) + { + XFastAttributeListRef xAttrList ( m_pHyperlinkAttrList ); + + m_pSerializer->startElementNS( XML_w, XML_hyperlink, xAttrList ); + } + + // Write the hyperlink and toc fields starts + for ( std::vector<FieldInfos>::iterator pIt = m_Fields.begin(); pIt != m_Fields.end(); ++pIt ) + { + // Add the fields starts for hyperlinks, TOCs and index marks + if ( pIt->bOpen ) + { + StartField_Impl( *pIt, sal_True ); + + // Remove the field if no end needs to be written + if ( !pIt->bClose ) { + m_Fields.erase( pIt ); + --pIt; + } + } + } + + DoWriteBookmarks( ); + + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); // merges with "postponed run start", see above + + // write the run start + the run content + m_pSerializer->mergeTopMarks(); // merges the "actual run start" + + // append the actual run end + m_pSerializer->endElementNS( XML_w, XML_r ); + + if ( m_pHyperlinkAttrList ) + { + m_pSerializer->endElementNS( XML_w, XML_hyperlink ); + m_pHyperlinkAttrList = NULL; + } + + while ( m_Fields.begin() != m_Fields.end() ) + { + EndField_Impl( m_Fields.front( ) ); + m_Fields.erase( m_Fields.begin( ) ); + } + + // if there is some redlining in the document, output it + EndRedline(); +} + +void DocxAttributeOutput::DoWriteBookmarks() +{ + // Write the start bookmarks + for ( std::vector< OString >::const_iterator it = m_rMarksStart.begin(), end = m_rMarksStart.end(); + it < end; ++it ) + { + const OString& rName = *it; + + // Output the bookmark + USHORT nId = m_nNextMarkId++; + m_rOpenedMarksIds[rName] = nId; + m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart, + FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ), + FSNS( XML_w, XML_name ), rName.getStr(), + FSEND ); + } + m_rMarksStart.clear(); + + // export the end bookmarks + for ( std::vector< OString >::const_iterator it = m_rMarksEnd.begin(), end = m_rMarksEnd.end(); + it < end; ++it ) + { + const OString& rName = *it; + + // Get the id of the bookmark + std::map< OString, USHORT >::iterator pPos = m_rOpenedMarksIds.find( rName ); + if ( pPos != m_rOpenedMarksIds.end( ) ) + { + USHORT nId = ( *pPos ).second; + m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd, + FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr( ), + FSEND ); + m_rOpenedMarksIds.erase( rName ); + } + } + m_rMarksEnd.clear(); +} + +void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, sal_Bool bWriteRun ) +{ + if ( rInfos.pField && rInfos.eType == ww::eUNKNOWN ) + { + // Expand unsupported fields + RunText( rInfos.pField->Expand( ) ); + } + else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands + { + if ( bWriteRun ) + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + + if ( rInfos.eType == ww::eFORMDROPDOWN ) + { + m_pSerializer->startElementNS( XML_w, XML_fldChar, + FSNS( XML_w, XML_fldCharType ), "begin", + FSEND ); + + const SwDropDownField& rFld2 = *(SwDropDownField*)rInfos.pField; + uno::Sequence<rtl::OUString> aItems = + rFld2.GetItemSequence(); + GetExport().DoComboBox(rFld2.GetName(), + rFld2.GetHelp(), + rFld2.GetToolTip(), + rFld2.GetSelectedItem(), aItems); + + m_pSerializer->endElementNS( XML_w, XML_fldChar ); + + if ( bWriteRun ) + m_pSerializer->endElementNS( XML_w, XML_r ); + + } + else + { + // Write the field start + m_pSerializer->singleElementNS( XML_w, XML_fldChar, + FSNS( XML_w, XML_fldCharType ), "begin", + FSEND ); + + if ( bWriteRun ) + m_pSerializer->endElementNS( XML_w, XML_r ); + + // The hyperlinks fields can't be expanded: the value is + // normally in the text run + if ( !rInfos.pField ) + CmdField_Impl( rInfos ); + } + } +} + +void DocxAttributeOutput::DoWriteCmd( String& rCmd ) +{ + // Write the Field command + m_pSerializer->startElementNS( XML_w, XML_instrText, FSEND ); + m_pSerializer->writeEscaped( OUString( rCmd ) ); + m_pSerializer->endElementNS( XML_w, XML_instrText ); + +} + +void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos ) +{ + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + xub_StrLen nNbToken = rInfos.sCmd.GetTokenCount( '\t' ); + + for ( xub_StrLen i = 0; i < nNbToken; i++ ) + { + String sToken = rInfos.sCmd.GetToken( i, '\t' ); + // Write the Field command + DoWriteCmd( sToken ); + + // Replace tabs by </instrText><tab/><instrText> + if ( i < ( nNbToken - 1 ) ) + RunText( String::CreateFromAscii( "\t" ) ); + } + + m_pSerializer->endElementNS( XML_w, XML_r ); + + + // Write the Field separator + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_fldChar, + FSNS( XML_w, XML_fldCharType ), "separate", + FSEND ); + m_pSerializer->endElementNS( XML_w, XML_r ); +} + +void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos ) +{ + // The command has to be written before for the hyperlinks + if ( rInfos.pField ) + { + CmdField_Impl( rInfos ); + } + + // Write the bookmark start if any + OUString aBkmName( m_sFieldBkm ); + if ( aBkmName.getLength( ) > 0 ) + { + m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart, + FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ), + FSNS( XML_w, XML_name ), OUStringToOString( aBkmName, RTL_TEXTENCODING_UTF8 ).getStr( ), + FSEND ); + } + + if (rInfos.pField ) // For hyperlinks and TOX + { + // Write the Field latest value + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + + // Find another way for hyperlinks + RunText( rInfos.pField->Expand( ) ); + m_pSerializer->endElementNS( XML_w, XML_r ); + } + + // Write the bookmark end if any + if ( aBkmName.getLength( ) > 0 ) + { + m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd, + FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( m_nNextMarkId ) ).getStr( ), + FSEND ); + + m_nNextMarkId++; + } + + // Write the Field end + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_fldChar, + FSNS( XML_w, XML_fldCharType ), "end", + FSEND ); + m_pSerializer->endElementNS( XML_w, XML_r ); + + + // Write the ref field if a bookmark had to be set and the field + // should be visible + if ( rInfos.pField ) + { + USHORT nSubType = rInfos.pField->GetSubType( ); + bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD; + bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true; + + if ( ( m_sFieldBkm.Len( ) > 0 ) && bShowRef ) + { + // Write the field beginning + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_fldChar, + FSNS( XML_w, XML_fldCharType ), "begin", + FSEND ); + m_pSerializer->endElementNS( XML_w, XML_r ); + + rInfos.sCmd = FieldString( ww::eREF ); + rInfos.sCmd.APPEND_CONST_ASC( "\"" ); + rInfos.sCmd += m_sFieldBkm; + rInfos.sCmd.APPEND_CONST_ASC( "\" " ); + + // Clean the field bookmark data to avoid infinite loop + m_sFieldBkm = String( ); + + // Write the end of the field + EndField_Impl( rInfos ); + } + } +} + +void DocxAttributeOutput::StartRunProperties() +{ + // postpone the output so that we can later [in EndRunProperties()] + // prepend the properties before the text + m_pSerializer->mark(); + + m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND ); + + InitCollectedRunProperties(); +} + +void DocxAttributeOutput::InitCollectedRunProperties() +{ + m_pFontsAttrList = NULL; + m_pEastAsianLayoutAttrList = NULL; + m_pCharLangAttrList = NULL; +} + +void DocxAttributeOutput::WriteCollectedRunProperties() +{ + // Write all differed properties + if ( m_pFontsAttrList ) + { + XFastAttributeListRef xAttrList( m_pFontsAttrList ); + m_pFontsAttrList = NULL; + + m_pSerializer->singleElementNS( XML_w, XML_rFonts, xAttrList ); + } + + if ( m_pEastAsianLayoutAttrList ) + { + XFastAttributeListRef xAttrList( m_pEastAsianLayoutAttrList ); + m_pEastAsianLayoutAttrList = NULL; + + m_pSerializer->singleElementNS( XML_w, XML_eastAsianLayout, xAttrList ); + } + + if ( m_pCharLangAttrList ) + { + XFastAttributeListRef xAttrList( m_pCharLangAttrList ); + m_pCharLangAttrList = NULL; + + m_pSerializer->singleElementNS( XML_w, XML_lang, xAttrList ); + } +} + +void DocxAttributeOutput::EndRunProperties( const SwRedlineData* /*pRedlineData*/ ) +{ + WriteCollectedRunProperties(); + + m_pSerializer->endElementNS( XML_w, XML_rPr ); + + // write footnotes/endnotes if we have any + FootnoteEndnoteReference(); + + // merge the properties _before_ the run text (strictly speaking, just + // after the start of the run) + m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); +} + +/** Output sal_Unicode* as a run text (<t>the text</t>). + + When bMove is true, update rBegin to point _after_ the end of the text + + 1, meaning that it skips one character after the text. This is to make + the switch in DocxAttributeOutput::RunText() nicer ;-) + */ +static void impl_WriteRunText( FSHelperPtr pSerializer, sal_Int32 nTextToken, + const sal_Unicode* &rBegin, const sal_Unicode* pEnd, bool bMove = true ) +{ + const sal_Unicode *pBegin = rBegin; + + // skip one character after the end + if ( bMove ) + rBegin = pEnd + 1; + + if ( pBegin >= pEnd ) + return; // we want to write at least one character + + // we have to add 'preserve' when starting/ending with space + if ( *pBegin == sal_Unicode( ' ' ) || *( pEnd - 1 ) == sal_Unicode( ' ' ) ) + { + pSerializer->startElementNS( XML_w, nTextToken, FSNS( XML_xml, XML_space ), "preserve", FSEND ); + } + else + pSerializer->startElementNS( XML_w, nTextToken, FSEND ); + + pSerializer->writeEscaped( OUString( pBegin, pEnd - pBegin ) ); + + pSerializer->endElementNS( XML_w, nTextToken ); +} + +void DocxAttributeOutput::RunText( const String& rText, rtl_TextEncoding /*eCharSet*/ ) +{ + OUString aText( rText ); + + // one text can be split into more <w:t>blah</w:t>'s by line breaks etc. + const sal_Unicode *pBegin = aText.getStr(); + const sal_Unicode *pEnd = pBegin + aText.getLength(); + + // the text run is usually XML_t, with the exception of the deleted text + sal_Int32 nTextToken = XML_t; + if ( m_pRedlineData && m_pRedlineData->GetType() == nsRedlineType_t::REDLINE_DELETE ) + nTextToken = XML_delText; + + for ( const sal_Unicode *pIt = pBegin; pIt < pEnd; ++pIt ) + { + switch ( *pIt ) + { + case 0x09: // tab + impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt ); + m_pSerializer->singleElementNS( XML_w, XML_tab, FSEND ); + break; + case 0x0b: // line break + impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt ); + m_pSerializer->singleElementNS( XML_w, XML_br, FSEND ); + break; + default: + if ( *pIt < 0x0020 ) // filter out the control codes + { + impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pIt ); +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "Ignored control code %x in a text run.", *pIt ); +#endif + } + break; + } + } + + impl_WriteRunText( m_pSerializer, nTextToken, pBegin, pEnd, false ); +} + +void DocxAttributeOutput::RawText( const String& /*rText*/, bool /*bForceUnicode*/, rtl_TextEncoding /*eCharSet*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )\n" ); +#endif +} + +void DocxAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, const SwFmtRuby& /*rRuby*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )\n" ); +#endif +} + +void DocxAttributeOutput::EndRuby() +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::EndRuby()\n" ); +#endif +} + +bool DocxAttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark ) +{ + bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark ); + + String sURL = *pLinkURL; + String sMark = *pMark; + + bool bOutputField = sMark.Len(); + + if ( bOutputField ) + { + if ( bBookMarkOnly ) + sURL = FieldString( ww::eHYPERLINK ); + else + { + String sFld( FieldString( ww::eHYPERLINK ) ); + sFld.APPEND_CONST_ASC( "\"" ); + sURL.Insert( sFld, 0 ); + sURL += '\"'; + } + + if ( sMark.Len() ) + ( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"'; + + if ( rTarget.Len() ) + ( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget; + } + + *pLinkURL = sURL; + *pMark = sMark; + + return bBookMarkOnly; +} + +bool DocxAttributeOutput::StartURL( const String& rUrl, const String& rTarget ) +{ + String sMark; + String sUrl; + + bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark ); + + if ( sMark.Len() && !bBookmarkOnly ) + { + m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl ); + } + else + { + // Output a hyperlink XML element + + m_pHyperlinkAttrList = m_pSerializer->createAttrList(); + if ( !bBookmarkOnly ) + { + OUString osUrl( sUrl ); + + ::rtl::OString sId = m_rExport.AddRelation( + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ), + osUrl, S("External") ); + m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr()); + } + else + m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ), + OUStringToOString( OUString( sMark ), RTL_TEXTENCODING_UTF8 ).getStr( ) ); + + OUString sTarget( rTarget ); + if ( sTarget.getLength( ) > 0 ) + { + OString soTarget = OUStringToOString( sTarget, RTL_TEXTENCODING_UTF8 ); + m_pHyperlinkAttrList->add(FSNS( XML_w, XML_tgtFrame ), soTarget.getStr()); + } + } + + return true; +} + +bool DocxAttributeOutput::EndURL() +{ + return true; +} + +void DocxAttributeOutput::FieldVanish( const String& rTxt, ww::eField eType ) +{ + WriteField_Impl( NULL, eType, rTxt, WRITEFIELD_ALL ); +} + +void DocxAttributeOutput::Redline( const SwRedlineData* /*pRedline*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::Redline( const SwRedlineData* pRedline )\n" ); +#endif +} + +/// Append the number as 2-digit when less than 10. +static void impl_AppendTwoDigits( OStringBuffer &rBuffer, sal_Int32 nNum ) +{ + if ( nNum < 0 || nNum > 99 ) + { + rBuffer.append( "00" ); + return; + } + + if ( nNum < 10 ) + rBuffer.append( '0' ); + + rBuffer.append( nNum ); +} + +/** Convert DateTime to xsd::dateTime string. + +I guess there must be an implementation of this somewhere in OOo, but I failed +to find it, unfortunately :-( +*/ +static OString impl_DateTimeToOString( const DateTime& rDateTime ) +{ + DateTime aInUTC( rDateTime ); + aInUTC.ConvertToUTC(); + + OStringBuffer aBuffer( 25 ); + aBuffer.append( sal_Int32( aInUTC.GetYear() ) ); + aBuffer.append( '-' ); + + impl_AppendTwoDigits( aBuffer, aInUTC.GetMonth() ); + aBuffer.append( '-' ); + + impl_AppendTwoDigits( aBuffer, aInUTC.GetDay() ); + aBuffer.append( 'T' ); + + impl_AppendTwoDigits( aBuffer, aInUTC.GetHour() ); + aBuffer.append( ':' ); + + impl_AppendTwoDigits( aBuffer, aInUTC.GetMin() ); + aBuffer.append( ':' ); + + impl_AppendTwoDigits( aBuffer, aInUTC.GetSec() ); + aBuffer.append( 'Z' ); // we are in UTC + + return aBuffer.makeStringAndClear(); +} + +void DocxAttributeOutput::StartRedline( const SwRedlineData* pRedlineData ) +{ + m_pRedlineData = pRedlineData; + + if ( !m_pRedlineData ) + return; + + // FIXME check if it's necessary to travel over the Next()'s in pRedlineData + + OString aId( OString::valueOf( m_nRedlineId++ ) ); + + const String &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) ); + OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) ); + + OString aDate( impl_DateTimeToOString( pRedlineData->GetTimeStamp() ) ); + + switch ( pRedlineData->GetType() ) + { + case nsRedlineType_t::REDLINE_INSERT: + m_pSerializer->startElementNS( XML_w, XML_ins, + FSNS( XML_w, XML_id ), aId.getStr(), + FSNS( XML_w, XML_author ), aAuthor.getStr(), + FSNS( XML_w, XML_date ), aDate.getStr(), + FSEND ); + break; + + case nsRedlineType_t::REDLINE_DELETE: + m_pSerializer->startElementNS( XML_w, XML_del, + FSNS( XML_w, XML_id ), aId.getStr(), + FSNS( XML_w, XML_author ), aAuthor.getStr(), + FSNS( XML_w, XML_date ), aDate.getStr(), + FSEND ); + break; + + case nsRedlineType_t::REDLINE_FORMAT: +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::StartRedline()\n" ); +#endif + default: + break; + } +} + +void DocxAttributeOutput::EndRedline() +{ + if ( !m_pRedlineData ) + return; + + switch ( m_pRedlineData->GetType() ) + { + case nsRedlineType_t::REDLINE_INSERT: + m_pSerializer->endElementNS( XML_w, XML_ins ); + break; + + case nsRedlineType_t::REDLINE_DELETE: + m_pSerializer->endElementNS( XML_w, XML_del ); + break; + + case nsRedlineType_t::REDLINE_FORMAT: +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::EndRedline()\n" ); +#endif + break; + default: + break; + } + + m_pRedlineData = NULL; +} + +void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, USHORT /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, USHORT nStyle )\n" ); +#endif +} + +void DocxAttributeOutput::ParagraphStyle( USHORT nStyle ) +{ + OString aStyleId( "style" ); + aStyleId += OString::valueOf( sal_Int32( nStyle ) ); + + m_pSerializer->singleElementNS( XML_w, XML_pStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); +} + +#if 0 +void DocxAttributeOutput::InTable() +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::InTable()\n" ); +#endif +} + + +void DocxAttributeOutput::TableRowProperties( bool /*bHeader*/, long /*nCellHeight*/, bool /*bCannotSplit*/, bool /*bRightToLeft*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::TableRowProperties()\n" ); +#endif +} +#endif + +static OString impl_ConvertColor( const Color &rColor ) +{ + OString color( "auto" ); + if ( rColor.GetColor() != COL_AUTO ) + { + const char pHexDigits[] = "0123456789ABCDEF"; + char pBuffer[] = "000000"; + + pBuffer[0] = pHexDigits[ ( rColor.GetRed() >> 4 ) & 0x0F ]; + pBuffer[1] = pHexDigits[ rColor.GetRed() & 0x0F ]; + pBuffer[2] = pHexDigits[ ( rColor.GetGreen() >> 4 ) & 0x0F ]; + pBuffer[3] = pHexDigits[ rColor.GetGreen() & 0x0F ]; + pBuffer[4] = pHexDigits[ ( rColor.GetBlue() >> 4 ) & 0x0F ]; + pBuffer[5] = pHexDigits[ rColor.GetBlue() & 0x0F ]; + + color = OString( pBuffer ); + } + return color; +} + +static void impl_borderLine( FSHelperPtr pSerializer, sal_Int32 elementToken, const SvxBorderLine* pBorderLine, USHORT nDist ) +{ + FastAttributeList* pAttr = pSerializer->createAttrList(); + + USHORT inW = pBorderLine->GetInWidth(); + USHORT outW = pBorderLine->GetOutWidth(); + USHORT nWidth = inW + outW; + + // Compute val attribute value + // Can be one of: + // single, double, + // basicWideOutline, basicWideInline + // OOXml also supports those types of borders, but we'll try to play with the first ones. + // thickThinMediumGap, thickThinLargeGap, thickThinSmallGap + // thinThickLargeGap, thinThickMediumGap, thinThickSmallGap + const char* pVal = "single"; + if ( pBorderLine->isDouble() ) + { + if ( inW == outW ) + pVal = ( sal_Char* )"double"; + else if ( inW > outW ) + { + pVal = ( sal_Char* )"thinThickMediumGap"; + } + else if ( inW < outW ) + { + pVal = ( sal_Char* )"thickThinMediumGap"; + } + } + + pAttr->add( FSNS( XML_w, XML_val ), OString( pVal ) ); + + // Compute the sz attribute + + // The unit is the 8th of point + nWidth = sal_Int32( nWidth / 2.5 ); + USHORT nMinWidth = 2; + USHORT nMaxWidth = 96; + + if ( nWidth > nMaxWidth ) + nWidth = nMaxWidth; + else if ( nWidth < nMinWidth ) + nWidth = nMinWidth; + + pAttr->add( FSNS( XML_w, XML_sz ), OString::valueOf( sal_Int32( nWidth ) ) ); + + // Get the distance (in pt) + pAttr->add( FSNS( XML_w, XML_space ), OString::valueOf( sal_Int32( nDist / 20 ) ) ); + + // Get the color code as an RRGGBB hex value + OString sColor( impl_ConvertColor( pBorderLine->GetColor( ) ) ); + pAttr->add( FSNS( XML_w, XML_color ), sColor ); + + XFastAttributeListRef xAttrs( pAttr ); + pSerializer->singleElementNS( XML_w, elementToken, xAttrs ); +} + +static void impl_pageBorders( FSHelperPtr pSerializer, const SvxBoxItem& rBox ) +{ + static const USHORT aBorders[] = + { + BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT + }; + + static const USHORT aXmlElements[] = + { + XML_top, XML_left, XML_bottom, XML_right + }; + const USHORT* pBrd = aBorders; + for( int i = 0; i < 4; ++i, ++pBrd ) + { + const SvxBorderLine* pLn = rBox.GetLine( *pBrd ); + if ( pLn ) + impl_borderLine( pSerializer, aXmlElements[i], pLn, 0 ); + } +} + +void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + m_pSerializer->startElementNS( XML_w, XML_tcPr, FSEND ); + + const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( ); + + // The cell borders + m_pSerializer->startElementNS( XML_w, XML_tcBorders, FSEND ); + SwFrmFmt *pFmt = pTblBox->GetFrmFmt( ); + impl_pageBorders( m_pSerializer, pFmt->GetBox( ) ); + m_pSerializer->endElementNS( XML_w, XML_tcBorders ); + + // Vertical merges + long vSpan = pTblBox->getRowSpan( ); + if ( vSpan > 1 ) + { + m_pSerializer->singleElementNS( XML_w, XML_vMerge, + FSNS( XML_w, XML_val ), "restart", + FSEND ); + } + else if ( vSpan < 0 ) + { + m_pSerializer->singleElementNS( XML_w, XML_vMerge, + FSNS( XML_w, XML_val ), "continue", + FSEND ); + } + + // Horizontal spans + const SwWriteTableRows& aRows = m_pTableWrt->GetRows( ); + SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ]; + SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ]; + + USHORT nColSpan = pCell->GetColSpan(); + if ( nColSpan > 1 ) + m_pSerializer->singleElementNS( XML_w, XML_gridSpan, + FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nColSpan ) ).getStr(), + FSEND ); + + TableBackgrounds( pTableTextNodeInfoInner ); + + // Cell prefered width + SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )[ pTableTextNodeInfoInner->getCell() ]; + m_pSerializer->singleElementNS( XML_w, XML_tcW, + FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nWidth ) ).getStr( ), + FSNS( XML_w, XML_type ), "dxa", + FSEND ); + + // Cell margins + m_pSerializer->startElementNS( XML_w, XML_tcMar, FSEND ); + const SvxBoxItem& rBox = pFmt->GetBox( ); + static const USHORT aBorders[] = + { + BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT + }; + + static const USHORT aXmlElements[] = + { + XML_top, XML_left, XML_bottom, XML_right + }; + const USHORT* pBrd = aBorders; + for( int i = 0; i < 4; ++i, ++pBrd ) + { + sal_Int32 nDist = sal_Int32( rBox.GetDistance( *pBrd ) ); + m_pSerializer->singleElementNS( XML_w, aXmlElements[i], + FSNS( XML_w, XML_w ), OString::valueOf( nDist ).getStr( ), + FSNS( XML_w, XML_type ), "dxa", + FSEND ); + } + + m_pSerializer->endElementNS( XML_w, XML_tcMar ); + + TableVerticalCell( pTableTextNodeInfoInner ); + + m_pSerializer->endElementNS( XML_w, XML_tcPr ); +} + +void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + sal_uInt32 nPageSize = 0; + bool bRelBoxSize = false; + + // Create the SwWriteTable instance to use col spans (and maybe other infos) + GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize ); + + const SwTable* pTable = pTableTextNodeInfoInner->getTable( ); + const SwFrmFmt *pFmt = pTable->GetFrmFmt( ); + SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( ); + + const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout(); + if( pLayout && pLayout->IsExportable() ) + m_pTableWrt = new SwWriteTable( pLayout ); + else + m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (USHORT)nPageSize, + (USHORT)nTblSz, false); +} + +void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND ); + + InitTableHelper( pTableTextNodeInfoInner ); + TableDefinition( pTableTextNodeInfoInner ); +} + +void DocxAttributeOutput::EndTable() +{ + m_pSerializer->endElementNS( XML_w, XML_tbl ); + + if ( m_nTableDepth > 0 ) + --m_nTableDepth; + + // We closed the table; if it is a nested table, the cell that contains it + // still continues + m_bTableCellOpen = true; + + // Cleans the table helper + delete m_pTableWrt, m_pTableWrt = NULL; +} + +void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + m_pSerializer->startElementNS( XML_w, XML_tr, FSEND ); + + // Output the row properties + m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND ); + + // Header row: tblHeader + const SwTable *pTable = pTableTextNodeInfoInner->getTable( ); + if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) ) + m_pSerializer->singleElementNS( XML_w, XML_tblHeader, + FSNS( XML_w, XML_val ), "true", + FSEND ); + + TableHeight( pTableTextNodeInfoInner ); + TableCanSplit( pTableTextNodeInfoInner ); + + m_pSerializer->endElementNS( XML_w, XML_trPr ); +} + +void DocxAttributeOutput::EndTableRow( ) +{ + m_pSerializer->endElementNS( XML_w, XML_tr ); +} + + +void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + if ( !m_pTableWrt ) + InitTableHelper( pTableTextNodeInfoInner ); + + m_pSerializer->startElementNS( XML_w, XML_tc, FSEND ); + + // Write the cell properties here + TableCellProperties( pTableTextNodeInfoInner ); + + m_bTableCellOpen = true; +} + +void DocxAttributeOutput::EndTableCell( ) +{ + m_pSerializer->endElementNS( XML_w, XML_tc ); + + m_bTableCellOpen = false; +} + +void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ ) +{ +} + +void DocxAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ ) +{ +} + +void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + // Write the table properties + m_pSerializer->startElementNS( XML_w, XML_tblPr, FSEND ); + + sal_uInt32 nPageSize = 0; + bool bRelBoxSize = false; + + // Create the SwWriteTable instance to use col spans (and maybe other infos) + GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize ); + + // Output the table prefered width + if ( nPageSize != 0 ) + m_pSerializer->singleElementNS( XML_w, XML_tblW, + FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nPageSize ) ).getStr( ), + FSNS( XML_w, XML_type ), "dxa", + FSEND ); + + // Output the table borders + TableDefaultBorders( pTableTextNodeInfoInner ); + TableBidi( pTableTextNodeInfoInner ); + + // Output the table alignement + const SwTable *pTable = pTableTextNodeInfoInner->getTable(); + SwFrmFmt *pTblFmt = pTable->GetFrmFmt( ); + const char* pJcVal; + sal_Int32 nIndent = 0; + switch ( pTblFmt->GetHoriOrient( ).GetHoriOrient( ) ) + { + case text::HoriOrientation::CENTER: + pJcVal = "center"; + break; + case text::HoriOrientation::RIGHT: + pJcVal = "right"; + break; + default: + case text::HoriOrientation::NONE: + case text::HoriOrientation::LEFT_AND_WIDTH: + { + pJcVal = "left"; + nIndent = sal_Int32( pTblFmt->GetLRSpace( ).GetLeft( ) ); + break; + } + } + m_pSerializer->singleElementNS( XML_w, XML_jc, + FSNS( XML_w, XML_val ), pJcVal, + FSEND ); + + // Table indent + if ( nIndent != 0 ) + m_pSerializer->singleElementNS( XML_w, XML_tblInd, + FSNS( XML_w, XML_w ), OString::valueOf( nIndent ).getStr( ), + FSNS( XML_w, XML_type ), "dxa", + FSEND ); + + m_pSerializer->endElementNS( XML_w, XML_tblPr ); + + + // Write the table grid infos + m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND ); + + std::vector<SwTwips> gridCols = GetGridCols( pTableTextNodeInfoInner ); + for ( std::vector<SwTwips>::const_iterator it = gridCols.begin(); it != gridCols.end(); ++it ) + m_pSerializer->singleElementNS( XML_w, XML_gridCol, + FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( *it ) ).getStr( ), + FSEND ); + + m_pSerializer->endElementNS( XML_w, XML_tblGrid ); +} + +void DocxAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); + const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt(); + + // the defaults of the table are taken from the top-left cell + m_pSerializer->startElementNS( XML_w, XML_tblBorders, FSEND ); + impl_pageBorders( m_pSerializer, pFrmFmt->GetBox( ) ); + m_pSerializer->endElementNS( XML_w, XML_tblBorders ); +} + +void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( ); + const SwFrmFmt *pFmt = pTblBox->GetFrmFmt( ); + const SfxPoolItem *pI = NULL; + + Color aColor; + if ( SFX_ITEM_ON == pFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) ) + aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor(); + else + aColor = COL_AUTO; + + OString sColor = impl_ConvertColor( aColor ); + m_pSerializer->singleElementNS( XML_w, XML_shd, + FSNS( XML_w, XML_fill ), sColor.getStr( ), + FSEND ); +} + +void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); + const SwTableLine * pTabLine = pTabBox->GetUpper(); + const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt(); + + const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize(); + if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() ) + { + sal_Int32 nHeight = rLSz.GetHeight(); + const char *pRule = NULL; + + switch ( rLSz.GetHeightSizeType() ) + { + case ATT_FIX_SIZE: pRule = "exact"; break; + case ATT_MIN_SIZE: pRule = "atLeast"; break; + default: break; + } + + if ( pRule ) + m_pSerializer->singleElementNS( XML_w, XML_trHeight, + FSNS( XML_w, XML_val ), OString::valueOf( nHeight ).getStr( ), + FSNS( XML_w, XML_hRule ), pRule, + FSEND ); + } +} + +void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); + const SwTableLine * pTabLine = pTabBox->GetUpper(); + const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt(); + + const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( ); + const char* pCantSplit = ( !rSplittable.GetValue( ) ) ? "on" : "off"; + + m_pSerializer->singleElementNS( XML_w, XML_cantSplit, + FSNS( XML_w, XML_val ), pCantSplit, + FSEND ); +} + +void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + const SwTable * pTable = pTableTextNodeInfoInner->getTable(); + const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt(); + + if ( m_rExport.TrueFrameDirection( *pFrmFmt ) == FRMDIR_HORI_RIGHT_TOP ) + { + m_pSerializer->singleElementNS( XML_w, XML_bidiVisual, + FSNS( XML_w, XML_val ), "on", + FSEND ); + } +} + +void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); + const SwFrmFmt *pFrmFmt = pTabBox->GetFrmFmt( ); + + if ( FRMDIR_VERT_TOP_RIGHT == m_rExport.TrueFrameDirection( *pFrmFmt ) ) + m_pSerializer->singleElementNS( XML_w, XML_textDirection, + FSNS( XML_w, XML_val ), "tbRl", + FSEND ); +} + +void DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO: DocxAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )\n" ); +#endif +} + +void DocxAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner ) +{ + // This is called when the nested table ends in a cell, and there's no + // paragraph benhind that; so we must check for the ends of cell, rows, + // tables + // ['true' to write an empty paragraph, MS Word insists on that] + FinishTableRowCell( pNodeInfoInner, true ); +} + +void DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO: DocxAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )\n" ); +#endif +} + +void DocxAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )\n" ); +#endif +} + +void DocxAttributeOutput::StartStyles() +{ + m_pSerializer->startElementNS( XML_w, XML_styles, + FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + FSEND ); +} + +void DocxAttributeOutput::EndStyles( USHORT /*nNumberOfStyles*/ ) +{ + m_pSerializer->endElementNS( XML_w, XML_styles ); +} + +void DocxAttributeOutput::DefaultStyle( USHORT nStyle ) +{ + // are these the values of enum ww::sti (see ../inc/wwstyles.hxx)? +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::DefaultStyle( USHORT nStyle )- %d\n", nStyle ); +#else + (void) nStyle; // to quiet the warning +#endif +} + +void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ) - some stuff still missing\n" ); +#endif + // create the relation ID + OString aRelId; + sal_Int32 nImageType; + if ( rGrfNode.IsLinkedFile() ) + { + // linked image, just create the relation + String aFileName; + rGrfNode.GetFileFilterNms( &aFileName, 0 ); + + // TODO Convert the file name to relative for better interoperability + + aRelId = m_rExport.AddRelation( + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" ), + OUString( aFileName ), + S( "External" ) ); + + nImageType = XML_link; + } + else + { + // inline, we also have to write the image itself + Graphic& rGraphic = const_cast< Graphic& >( rGrfNode.GetGrf() ); + + m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream + OUString aImageId = m_rDrawingML.WriteImage( rGraphic ); + + aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 ); + + nImageType = XML_embed; + } + + if ( aRelId.getLength() == 0 ) + return; + + m_pSerializer->startElementNS( XML_w, XML_drawing, + FSEND ); + m_pSerializer->startElementNS( XML_wp, XML_inline, + XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0", + FSEND ); + + // extent of the image + OString aWidth( OString::valueOf( TwipsToEMU( rSize.Width() ) ) ); + OString aHeight( OString::valueOf( TwipsToEMU( rSize.Height() ) ) ); + m_pSerializer->singleElementNS( XML_wp, XML_extent, + XML_cx, aWidth.getStr(), + XML_cy, aHeight.getStr(), + FSEND ); + // TODO - the right effectExtent, extent including the effect + m_pSerializer->singleElementNS( XML_wp, XML_effectExtent, + XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0", + FSEND ); + + // picture description + // TODO the right image description + m_pSerializer->startElementNS( XML_wp, XML_docPr, + XML_id, "1", + XML_name, "Picture", + XML_descr, "A description...", + FSEND ); + // TODO hyperlink + // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick, + // FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main", + // FSNS( XML_r, XML_id ), "rId4", + // FSEND ); + m_pSerializer->endElementNS( XML_wp, XML_docPr ); + + m_pSerializer->startElementNS( XML_wp, XML_cNvGraphicFramePr, + FSEND ); + // TODO change aspect? + m_pSerializer->singleElementNS( XML_a, XML_graphicFrameLocks, + FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main", + XML_noChangeAspect, "1", + FSEND ); + m_pSerializer->endElementNS( XML_wp, XML_cNvGraphicFramePr ); + + m_pSerializer->startElementNS( XML_a, XML_graphic, + FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main", + FSEND ); + m_pSerializer->startElementNS( XML_a, XML_graphicData, + XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/picture", + FSEND ); + + m_pSerializer->startElementNS( XML_pic, XML_pic, + FSNS( XML_xmlns, XML_pic ), "http://schemas.openxmlformats.org/drawingml/2006/picture", + FSEND ); + + m_pSerializer->startElementNS( XML_pic, XML_nvPicPr, + FSEND ); + // TODO the right image description + m_pSerializer->startElementNS( XML_pic, XML_cNvPr, + XML_id, "0", + XML_name, "Picture", + XML_descr, "A description...", + FSEND ); + // TODO hyperlink + // m_pSerializer->singleElementNS( XML_a, XML_hlinkClick, + // FSNS( XML_r, XML_id ), "rId4", + // FSEND ); + m_pSerializer->endElementNS( XML_pic, XML_cNvPr ); + + m_pSerializer->startElementNS( XML_pic, XML_cNvPicPr, + FSEND ); + // TODO change aspect? + m_pSerializer->singleElementNS( XML_a, XML_picLocks, + XML_noChangeAspect, "1", XML_noChangeArrowheads, "1", + FSEND ); + m_pSerializer->endElementNS( XML_pic, XML_cNvPicPr ); + m_pSerializer->endElementNS( XML_pic, XML_nvPicPr ); + + // the actual picture + m_pSerializer->startElementNS( XML_pic, XML_blipFill, + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_blip, + FSNS( XML_r, nImageType ), aRelId.getStr(), + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_srcRect, + FSEND ); + m_pSerializer->startElementNS( XML_a, XML_stretch, + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_fillRect, + FSEND ); + m_pSerializer->endElementNS( XML_a, XML_stretch ); + m_pSerializer->endElementNS( XML_pic, XML_blipFill ); + + // TODO setup the right values below + m_pSerializer->startElementNS( XML_pic, XML_spPr, + XML_bwMode, "auto", + FSEND ); + m_pSerializer->startElementNS( XML_a, XML_xfrm, + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_off, + XML_x, "0", XML_y, "0", + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_ext, + XML_cx, aWidth.getStr(), + XML_cy, aHeight.getStr(), + FSEND ); + m_pSerializer->endElementNS( XML_a, XML_xfrm ); + m_pSerializer->startElementNS( XML_a, XML_prstGeom, + XML_prst, "rect", + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_avLst, + FSEND ); + m_pSerializer->endElementNS( XML_a, XML_prstGeom ); + m_pSerializer->singleElementNS( XML_a, XML_noFill, + FSEND ); + m_pSerializer->startElementNS( XML_a, XML_ln, + XML_w, "9525", + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_noFill, + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_miter, + XML_lim, "800000", + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_headEnd, + FSEND ); + m_pSerializer->singleElementNS( XML_a, XML_tailEnd, + FSEND ); + m_pSerializer->endElementNS( XML_a, XML_ln ); + m_pSerializer->endElementNS( XML_pic, XML_spPr ); + + m_pSerializer->endElementNS( XML_pic, XML_pic ); + + m_pSerializer->endElementNS( XML_a, XML_graphicData ); + m_pSerializer->endElementNS( XML_a, XML_graphic ); + m_pSerializer->endElementNS( XML_wp, XML_inline ); + + m_pSerializer->endElementNS( XML_w, XML_drawing ); +} + +void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Point& /*rNdTopLeft*/ ) +{ + m_pSerializer->mark(); + + switch ( rFrame.GetWriterType() ) + { + case sw::Frame::eGraphic: + { + const SwNode *pNode = rFrame.GetContent(); + const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0; + if ( pGrfNode ) + FlyFrameGraphic( *pGrfNode, rFrame.GetLayoutSize() ); + } + break; + case sw::Frame::eDrawing: + { + const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject(); + if ( pSdrObj ) + { + bool bSwapInPage = false; + if ( !pSdrObj->GetPage() ) + { + if ( SdrModel* pModel = m_rExport.pDoc->GetDrawModel() ) + { + if ( SdrPage *pPage = pModel->GetPage( 0 ) ) + { + bSwapInPage = true; + const_cast< SdrObject* >( pSdrObj )->SetPage( pPage ); + } + } + } + + m_pSerializer->startElementNS( XML_w, XML_pict, + FSEND ); + + m_rExport.VMLExporter().AddSdrObject( *pSdrObj ); + + m_pSerializer->endElementNS( XML_w, XML_pict ); + + if ( bSwapInPage ) + const_cast< SdrObject* >( pSdrObj )->SetPage( 0 ); + } + } + break; + default: +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& rNdTopLeft ) - frame type '%s'\n", + rFrame.GetWriterType() == sw::Frame::eTxtBox? "eTxtBox": + ( rFrame.GetWriterType() == sw::Frame::eOle? "eOle": + ( rFrame.GetWriterType() == sw::Frame::eFormControl? "eFormControl": "???" ) ) ); +#endif + break; + } + + m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_POSTPONE ); +} + +void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt, + USHORT nBase, USHORT nNext, USHORT /*nWwId*/, USHORT nId ) +{ + OString aStyle( "style" ); + + m_pSerializer->startElementNS( XML_w, XML_style, + FSNS( XML_w, XML_type ), bPapFmt? "paragraph": "character", // FIXME is this correct? + FSNS( XML_w, XML_styleId ), ( aStyle + OString::valueOf( sal_Int32( nId ) ) ).getStr(), + FSEND ); + + m_pSerializer->singleElementNS( XML_w, XML_name, + FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); + + if ( nBase != 0x0FFF ) + { + m_pSerializer->singleElementNS( XML_w, XML_basedOn, + FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nBase ) ) ).getStr(), + FSEND ); + } + + m_pSerializer->singleElementNS( XML_w, XML_next, + FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nNext ) ) ).getStr(), + FSEND ); +} + +void DocxAttributeOutput::EndStyle() +{ + m_pSerializer->endElementNS( XML_w, XML_style ); +} + +void DocxAttributeOutput::StartStyleProperties( bool bParProp, USHORT /*nStyle*/ ) +{ + if ( bParProp ) + { + m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND ); + InitCollectedParagraphProperties(); + } + else + { + m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND ); + InitCollectedRunProperties(); + } +} + +void DocxAttributeOutput::EndStyleProperties( bool bParProp ) +{ + if ( bParProp ) + { + WriteCollectedParagraphProperties(); + m_pSerializer->endElementNS( XML_w, XML_pPr ); + } + else + { + WriteCollectedRunProperties(); + m_pSerializer->endElementNS( XML_w, XML_rPr ); + } +} + +void DocxAttributeOutput::OutlineNumbering( BYTE nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ ) +{ + if ( nLvl >= WW8ListManager::nMaxLevel ) + nLvl = WW8ListManager::nMaxLevel - 1; + + m_pSerializer->singleElementNS( XML_w, XML_outlineLvl, + FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl ) ).getStr( ), + FSEND ); +} + +void DocxAttributeOutput::PageBreakBefore( bool bBreak ) +{ + if ( bBreak ) + m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_pageBreakBefore, + FSNS( XML_w, XML_val ), "off", + FSEND ); +} + +void DocxAttributeOutput::SectionBreak( BYTE nC, const WW8_SepInfo* pSectionInfo ) +{ + switch ( nC ) + { + case msword::ColumnBreak: + // The column break should be output in the next paragraph... + m_nColBreakStatus = COLBRK_POSTPONE; + break; + case msword::PageBreak: + if ( pSectionInfo ) + { + if ( !m_bParagraphOpened ) + { + // Create a dummy paragraph if needed + m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); + m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND ); + + m_rExport.SectionProperties( *pSectionInfo ); + + m_pSerializer->endElementNS( XML_w, XML_pPr ); + m_pSerializer->endElementNS( XML_w, XML_p ); + } + else + { + // postpone the output of this; it has to be done inside the + // paragraph properties, so remember it until then + m_pSectionInfo = pSectionInfo; + } + } + else + { + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_br, + FSNS( XML_w, XML_type ), "page", FSEND ); + m_pSerializer->endElementNS( XML_w, XML_r ); + } + break; + default: +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "Unknown section break to write: %d\n", nC ); +#endif + break; + } +} + +void DocxAttributeOutput::StartSection() +{ + m_pSerializer->startElementNS( XML_w, XML_sectPr, FSEND ); + m_bOpenedSectPr = true; +} + +void DocxAttributeOutput::EndSection() +{ + // Write the section properties + if ( m_pSpacingAttrList ) + { + XFastAttributeListRef xAttrList( m_pSpacingAttrList ); + m_pSpacingAttrList = NULL; + + m_pSerializer->singleElementNS( XML_w, XML_pgMar, xAttrList ); + } + + m_pSerializer->endElementNS( XML_w, XML_sectPr ); + m_bOpenedSectPr = false; +} + +void DocxAttributeOutput::SectionFormProtection( bool bProtected ) +{ + if ( bProtected ) + m_pSerializer->singleElementNS( XML_w, XML_formProt, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_formProt, + FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::SectionLineNumbering( ULONG /*nRestartNo*/, const SwLineNumberInfo& /*rLnNumInfo*/ ) +{ + // see 2.6.8 lnNumType (Line Numbering Settings) +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::SectionLineNumbering()\n" ); +#endif +} + +void DocxAttributeOutput::SectionTitlePage() +{ + m_pSerializer->singleElementNS( XML_w, XML_titlePg, FSEND ); +} + +void DocxAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ ) +{ + // Output the margins + + + const SvxBoxItem& rBox = pFmt->GetBox( ); + + const SvxBorderLine* pBottom = rBox.GetBottom( ); + const SvxBorderLine* pTop = rBox.GetTop( ); + const SvxBorderLine* pLeft = rBox.GetLeft( ); + const SvxBorderLine* pRight = rBox.GetRight( ); + + if ( pBottom || pTop || pLeft || pRight ) + { + // All distances are relative to the text margins + m_pSerializer->startElementNS( XML_w, XML_pgBorders, + FSNS( XML_w, XML_display ), "allPages", + FSNS( XML_w, XML_offsetFrom ), "text", + FSEND ); + + m_pSerializer->mark(); + + m_pSerializer->endElementNS( XML_w, XML_pgBorders ); + m_pSerializer->mark(); + } +} + +void DocxAttributeOutput::SectionBiDi( bool bBiDi ) +{ + if ( bBiDi ) + m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND ); +} + +static OString impl_NumberingType( USHORT nNumberingType ) +{ + OString aType; + + switch ( nNumberingType ) + { + case SVX_NUM_CHARS_UPPER_LETTER: + case SVX_NUM_CHARS_UPPER_LETTER_N: aType = "upperLetter"; break; + case SVX_NUM_CHARS_LOWER_LETTER: + case SVX_NUM_CHARS_LOWER_LETTER_N: aType = "lowerLetter"; break; + case SVX_NUM_ROMAN_UPPER: aType = "upperRoman"; break; + case SVX_NUM_ROMAN_LOWER: aType = "lowerRoman"; break; + + case SVX_NUM_ARABIC: aType = "decimal"; break; + + case SVX_NUM_BITMAP: + case SVX_NUM_CHAR_SPECIAL: aType = "bullet"; break; + + default: aType = "none"; break; + } + + return aType; +} + +void DocxAttributeOutput::SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber ) +{ + // FIXME Not called properly with page styles like "First Page" + + FastAttributeList* pAttr = m_pSerializer->createAttrList(); + + // 0 means no restart: then don't output that attribute if 0 + if ( nPageRestartNumber > 0 ) + pAttr->add( FSNS( XML_w, XML_start ), OString::valueOf( sal_Int32( nPageRestartNumber ) ) ); + + // nNumType corresponds to w:fmt. See WW8Export::GetNumId() for more precisions + OString aFmt( impl_NumberingType( nNumType ) ); + if ( aFmt.getLength() ) + pAttr->add( FSNS( XML_w, XML_fmt ), aFmt.getStr() ); + + XFastAttributeListRef xAttrs( pAttr ); + m_pSerializer->singleElementNS( XML_w, XML_pgNumType, xAttrs ); + + // see 2.6.12 pgNumType (Page Numbering Settings) +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::SectionPageNumbering()\n" ); +#endif +} + +void DocxAttributeOutput::SectionType( BYTE nBreakCode ) +{ + /* break code: 0 No break, 1 New column + 2 New page, 3 Even page, 4 Odd page + */ + const char* pType = NULL; + switch ( nBreakCode ) + { + case 1: pType = "nextColumn"; break; + case 2: pType = "nextPage"; break; + case 3: pType = "evenPage"; break; + case 4: pType = "oddPage"; break; + default: pType = "continuous"; break; + } + + if ( pType ) + m_pSerializer->singleElementNS( XML_w, XML_type, + FSNS( XML_w, XML_val ), pType, + FSEND ); +} + +void DocxAttributeOutput::StartFont( const String& rFamilyName ) const +{ + m_pSerializer->startElementNS( XML_w, XML_font, + FSNS( XML_w, XML_name ), OUStringToOString( OUString( rFamilyName ), RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); +} + +void DocxAttributeOutput::EndFont() const +{ + m_pSerializer->endElementNS( XML_w, XML_font ); +} + +void DocxAttributeOutput::FontAlternateName( const String& rName ) const +{ + m_pSerializer->singleElementNS( XML_w, XML_altName, + FSNS( XML_w, XML_val ), OUStringToOString( OUString( rName ), RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); +} + +void DocxAttributeOutput::FontCharset( sal_uInt8 nCharSet ) const +{ + OString aCharSet( OString::valueOf( sal_Int32( nCharSet ), 16 ) ); + if ( aCharSet.getLength() == 1 ) + aCharSet = OString( "0" ) + aCharSet; + + m_pSerializer->singleElementNS( XML_w, XML_charset, + FSNS( XML_w, XML_val ), aCharSet.getStr(), + FSEND ); +} + +void DocxAttributeOutput::FontFamilyType( FontFamily eFamily ) const +{ + const char *pFamily = NULL; + switch ( eFamily ) + { + case FAMILY_ROMAN: pFamily = "roman"; break; + case FAMILY_SWISS: pFamily = "swiss"; break; + case FAMILY_MODERN: pFamily = "modern"; break; + case FAMILY_SCRIPT: pFamily = "script"; break; + case FAMILY_DECORATIVE: pFamily = "decorative"; break; + default: pFamily = "auto"; break; // no font family + } + + if ( pFamily ) + m_pSerializer->singleElementNS( XML_w, XML_family, + FSNS( XML_w, XML_val ), pFamily, + FSEND ); +} + +void DocxAttributeOutput::FontPitchType( FontPitch ePitch ) const +{ + const char *pPitch = NULL; + switch ( ePitch ) + { + case PITCH_VARIABLE: pPitch = "variable"; break; + case PITCH_FIXED: pPitch = "fixed"; break; + default: pPitch = "default"; break; // no info about the pitch + } + + if ( pPitch ) + m_pSerializer->singleElementNS( XML_w, XML_pitch, + FSNS( XML_w, XML_val ), pPitch, + FSEND ); +} + +void DocxAttributeOutput::NumberingDefinition( USHORT nId, const SwNumRule &rRule ) +{ + // nId is the same both for abstract numbering definition as well as the + // numbering definition itself + // TODO check that this is actually true & fix if not ;-) + OString aId( OString::valueOf( sal_Int32( nId ) ) ); + + m_pSerializer->startElementNS( XML_w, XML_num, + FSNS( XML_w, XML_numId ), aId.getStr(), + FSEND ); + + m_pSerializer->singleElementNS( XML_w, XML_abstractNumId, + FSNS( XML_w, XML_val ), aId.getStr(), + FSEND ); + +#if OSL_DEBUG_LEVEL > 0 + // TODO ww8 version writes this, anything to do about it here? + if ( rRule.IsContinusNum() ) + fprintf( stderr, "TODO DocxAttributeOutput::NumberingDefinition()\n" ); +#else + (void) rRule; // to quiet the warning... +#endif + + m_pSerializer->endElementNS( XML_w, XML_num ); +} + +void DocxAttributeOutput::StartAbstractNumbering( USHORT nId ) +{ + m_pSerializer->startElementNS( XML_w, XML_abstractNum, + FSNS( XML_w, XML_abstractNumId ), OString::valueOf( sal_Int32( nId ) ).getStr(), + FSEND ); +} + +void DocxAttributeOutput::EndAbstractNumbering() +{ + m_pSerializer->endElementNS( XML_w, XML_abstractNum ); +} + +void DocxAttributeOutput::NumberingLevel( BYTE nLevel, + USHORT nStart, + USHORT nNumberingType, + SvxAdjust eAdjust, + const BYTE * /*pNumLvlPos*/, + BYTE nFollow, + const wwFont *pFont, + const SfxItemSet *pOutSet, + sal_Int16 nIndentAt, + sal_Int16 nFirstLineIndex, + sal_Int16 /*nListTabPos*/, + const String &rNumberingString ) +{ + m_pSerializer->startElementNS( XML_w, XML_lvl, + FSNS( XML_w, XML_ilvl ), OString::valueOf( sal_Int32( nLevel ) ).getStr(), + FSEND ); + + // start with the nStart value + m_pSerializer->singleElementNS( XML_w, XML_start, + FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nStart ) ).getStr(), + FSEND ); + + // format + OString aFmt( impl_NumberingType( nNumberingType ) ); + + if ( aFmt.getLength() ) + m_pSerializer->singleElementNS( XML_w, XML_numFmt, + FSNS( XML_w, XML_val ), aFmt.getStr(), + FSEND ); + + // justification + const char *pJc; + switch ( eAdjust ) + { + case SVX_ADJUST_CENTER: pJc = "center"; break; + case SVX_ADJUST_RIGHT: pJc = "right"; break; + default: pJc = "left"; break; + } + m_pSerializer->singleElementNS( XML_w, XML_lvlJc, + FSNS( XML_w, XML_val ), pJc, + FSEND ); + + // suffix + const char *pSuffix = NULL; + switch ( nFollow ) + { + case 1: pSuffix = "space"; break; + case 2: pSuffix = "nothing"; break; + default: /*pSuffix = "tab";*/ break; + } + if ( pSuffix ) + m_pSerializer->singleElementNS( XML_w, XML_suff, + FSNS( XML_w, XML_val ), pSuffix, + FSEND ); + + // text + OUString aText( rNumberingString ); + OUStringBuffer aBuffer( aText.getLength() + WW8ListManager::nMaxLevel ); + + const sal_Unicode *pPrev = aText.getStr(); + const sal_Unicode *pIt = aText.getStr(); + while ( pIt < aText.getStr() + aText.getLength() ) + { + // convert the level values to %NUMBER form + // (we don't use pNumLvlPos at all) + // FIXME so far we support the ww8 limit of levels only + if ( *pIt < sal_Unicode( WW8ListManager::nMaxLevel ) ) + { + aBuffer.append( pPrev, pIt - pPrev ); + aBuffer.appendAscii( "%" ); + aBuffer.append( OUString::valueOf( sal_Int32( *pIt ) + 1 ) ); + + pPrev = pIt + 1; + } + ++pIt; + } + if ( pPrev < pIt ) + aBuffer.append( pPrev, pIt - pPrev ); + + m_pSerializer->singleElementNS( XML_w, XML_lvlText, + FSNS( XML_w, XML_val ), OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); + + // indentation + m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_ind, + FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nIndentAt ) ).getStr(), + FSNS( XML_w, XML_hanging ), OString::valueOf( sal_Int32( -nFirstLineIndex ) ).getStr(), + FSEND ); + m_pSerializer->endElementNS( XML_w, XML_pPr ); + + // font + if ( pOutSet ) + { + m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND ); + + if ( pFont ) + { + OString aFamilyName( OUStringToOString( OUString( pFont->GetFamilyName() ), RTL_TEXTENCODING_UTF8 ) ); + m_pSerializer->singleElementNS( XML_w, XML_rFonts, + FSNS( XML_w, XML_ascii ), aFamilyName.getStr(), + FSNS( XML_w, XML_hAnsi ), aFamilyName.getStr(), + FSNS( XML_w, XML_cs ), aFamilyName.getStr(), + FSNS( XML_w, XML_hint ), "default", + FSEND ); + } + m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN ); + + m_pSerializer->endElementNS( XML_w, XML_rPr ); + } + + // TODO anything to do about nListTabPos? + + m_pSerializer->endElementNS( XML_w, XML_lvl ); +} + +void DocxAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap ) +{ + switch ( rCaseMap.GetValue() ) + { + case SVX_CASEMAP_KAPITAELCHEN: + m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSEND ); + break; + case SVX_CASEMAP_VERSALIEN: + m_pSerializer->singleElementNS( XML_w, XML_caps, FSEND ); + break; + default: // Something that ooxml does not support + m_pSerializer->singleElementNS( XML_w, XML_smallCaps, FSNS( XML_w, XML_val ), "off", FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_caps, FSNS( XML_w, XML_val ), "off", FSEND ); + break; + } +} + +void DocxAttributeOutput::CharColor( const SvxColorItem& rColor ) +{ + const Color aColor( rColor.GetValue() ); + OString aColorString; + + aColorString = impl_ConvertColor( aColor ); + + m_pSerializer->singleElementNS( XML_w, XML_color, + FSNS( XML_w, XML_val ), aColorString.getStr(), FSEND ); +} + +void DocxAttributeOutput::CharContour( const SvxContourItem& rContour ) +{ + if ( rContour.GetValue() ) + m_pSerializer->singleElementNS( XML_w, XML_outline, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_outline, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut ) +{ + switch ( rCrossedOut.GetStrikeout() ) + { + case STRIKEOUT_DOUBLE: + m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSEND ); + break; + case STRIKEOUT_NONE: + m_pSerializer->singleElementNS( XML_w, XML_dstrike, FSNS( XML_w, XML_val ), "off", FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_strike, FSNS( XML_w, XML_val ), "off", FSEND ); + break; + default: + m_pSerializer->singleElementNS( XML_w, XML_strike, FSEND ); + break; + } +} + +void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& /*rEscapement*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::CharEscapement()\n" ); +#endif +} + +void DocxAttributeOutput::CharFont( const SvxFontItem& rFont) +{ + if (!m_pFontsAttrList) + m_pFontsAttrList = m_pSerializer->createAttrList(); + OUString sFontName(rFont.GetFamilyName()); + OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8); + m_pFontsAttrList->add(FSNS(XML_w, XML_ascii), sFontNameUtf8); + m_pFontsAttrList->add(FSNS(XML_w, XML_hAnsi), sFontNameUtf8); +} + +void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize) +{ + OString fontSize = OString::valueOf( sal_Int32( ( rFontSize.GetHeight() + 5 ) / 10 ) ); + + switch ( rFontSize.Which() ) + { + case RES_CHRATR_FONTSIZE: + case RES_CHRATR_CJK_FONTSIZE: + m_pSerializer->singleElementNS( XML_w, XML_sz, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND ); + break; + case RES_CHRATR_CTL_FONTSIZE: + m_pSerializer->singleElementNS( XML_w, XML_szCs, FSNS( XML_w, XML_val ), fontSize.getStr(), FSEND ); + break; + } +} + +void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning ) +{ + OString aKerning = OString::valueOf( ( sal_Int32 ) rKerning.GetValue() ); + m_pSerializer->singleElementNS( XML_w, XML_kern, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND ); +} + +void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage ) +{ + if (!m_pCharLangAttrList) + m_pCharLangAttrList = m_pSerializer->createAttrList(); + + ::com::sun::star::lang::Locale xLocale= MsLangId::convertLanguageToLocale( rLanguage.GetLanguage( ) ); + OString sLanguage = OUStringToOString(xLocale.Language, RTL_TEXTENCODING_UTF8); + OString sCountry = OUStringToOString(xLocale.Country, RTL_TEXTENCODING_UTF8); + + OString aLanguageCode = sLanguage + "-" + sCountry; + + switch ( rLanguage.Which() ) + { + case RES_CHRATR_LANGUAGE: + m_pCharLangAttrList->add(FSNS(XML_w, XML_val), aLanguageCode); + break; + case RES_CHRATR_CJK_LANGUAGE: + m_pCharLangAttrList->add(FSNS(XML_w, XML_eastAsia), aLanguageCode); + break; + case RES_CHRATR_CTL_LANGUAGE: + m_pCharLangAttrList->add(FSNS(XML_w, XML_bidi), aLanguageCode); + break; + } +} + +void DocxAttributeOutput::CharPosture( const SvxPostureItem& rPosture ) +{ + if ( rPosture.GetPosture() != ITALIC_NONE ) + m_pSerializer->singleElementNS( XML_w, XML_i, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::CharShadow( const SvxShadowedItem& rShadow ) +{ + if ( rShadow.GetValue() ) + m_pSerializer->singleElementNS( XML_w, XML_shadow, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_shadow, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline ) +{ + const char *pUnderline; + + switch ( rUnderline.GetLineStyle() ) + { + case UNDERLINE_SINGLE: pUnderline = "single"; break; + case UNDERLINE_BOLD: pUnderline = "thick"; break; + case UNDERLINE_DOUBLE: pUnderline = "double"; break; + case UNDERLINE_DOTTED: pUnderline = "dotted"; break; + case UNDERLINE_DASH: pUnderline = "dash"; break; + case UNDERLINE_DASHDOT: pUnderline = "dotDash"; break; + case UNDERLINE_DASHDOTDOT: pUnderline = "dotDotDash"; break; + case UNDERLINE_WAVE: pUnderline = "wave"; break; + case UNDERLINE_BOLDDOTTED: pUnderline = "dottedHeavy"; break; + case UNDERLINE_BOLDDASH: pUnderline = "dashedHeavy"; break; + case UNDERLINE_LONGDASH: pUnderline = "dashLongHeavy"; break; + case UNDERLINE_BOLDLONGDASH: pUnderline = "dashLongHeavy"; break; + case UNDERLINE_BOLDDASHDOT: pUnderline = "dashDotHeavy"; break; + case UNDERLINE_BOLDDASHDOTDOT: pUnderline = "dashDotDotHeavy"; break; + case UNDERLINE_BOLDWAVE: pUnderline = "wavyHeavy"; break; + case UNDERLINE_DOUBLEWAVE: pUnderline = "wavyDouble"; break; + case UNDERLINE_NONE: // fall through + default: pUnderline = "none"; break; + } + + m_pSerializer->singleElementNS( XML_w, XML_u, FSNS( XML_w, XML_val ), pUnderline, FSEND ); +} + +void DocxAttributeOutput::CharWeight( const SvxWeightItem& rWeight ) +{ + if ( rWeight.GetWeight() == WEIGHT_BOLD ) + m_pSerializer->singleElementNS( XML_w, XML_b, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::CharAutoKern( const SvxAutoKernItem& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::CharAutoKern()\n" ); +#endif +} + +void DocxAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink ) +{ + if ( rBlink.GetValue() ) + m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "blinkBackground", FSEND ); + else + m_pSerializer->singleElementNS(XML_w, XML_effect, FSNS( XML_w, XML_val ), "none", FSEND ); +} + +void DocxAttributeOutput::CharBackground( const SvxBrushItem& rBrush ) +{ + m_pSerializer->singleElementNS( XML_w, XML_shd, + FSNS( XML_w, XML_fill ), impl_ConvertColor( rBrush.GetColor() ).getStr(), FSEND ); +} + +void DocxAttributeOutput::CharFontCJK( const SvxFontItem& rFont ) +{ + if (!m_pFontsAttrList) + m_pFontsAttrList = m_pSerializer->createAttrList(); + OUString sFontName(rFont.GetFamilyName()); + OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8); + m_pFontsAttrList->add(FSNS(XML_w, XML_eastAsia), sFontNameUtf8); +} + +void DocxAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture ) +{ + if ( rPosture.GetPosture() != ITALIC_NONE ) + m_pSerializer->singleElementNS( XML_w, XML_i, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_i, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight ) +{ + if ( rWeight.GetWeight() == WEIGHT_BOLD ) + m_pSerializer->singleElementNS( XML_w, XML_b, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_b, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::CharFontCTL( const SvxFontItem& rFont ) +{ + if (!m_pFontsAttrList) + m_pFontsAttrList = m_pSerializer->createAttrList(); + OUString sFontName(rFont.GetFamilyName()); + OString sFontNameUtf8 = OUStringToOString(sFontName, RTL_TEXTENCODING_UTF8); + m_pFontsAttrList->add(FSNS(XML_w, XML_cs), sFontNameUtf8); + +} + +void DocxAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture) +{ + if ( rPosture.GetPosture() != ITALIC_NONE ) + m_pSerializer->singleElementNS( XML_w, XML_iCs, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_iCs, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight ) +{ + if ( rWeight.GetWeight() == WEIGHT_BOLD ) + m_pSerializer->singleElementNS( XML_w, XML_bCs, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_bCs, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate) +{ + if ( !rRotate.GetValue() ) + return; + + if (!m_pEastAsianLayoutAttrList) + m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList(); + OString sTrue((sal_Char *)"true"); + m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vert), sTrue); + + if (rRotate.IsFitToLine()) + m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_vertCompress), sTrue); +} + +void DocxAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark ) +{ + const char *pEmphasis; + + switch ( rEmphasisMark.GetValue() ) + { + case EMPHASISMARK_NONE: pEmphasis = "none"; break; + case EMPHASISMARK_SIDE_DOTS: pEmphasis = "dot"; break; + case EMPHASISMARK_CIRCLE_ABOVE: pEmphasis = "circle"; break; + case EMPHASISMARK_DOTS_BELOW: pEmphasis = "underDot"; break; + default: pEmphasis = "comma"; break; + } + + m_pSerializer->singleElementNS( XML_w, XML_em, FSNS( XML_w, XML_val ), pEmphasis, FSEND ); +} + +void DocxAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines ) +{ + if ( !rTwoLines.GetValue() ) + return; + + if (!m_pEastAsianLayoutAttrList) + m_pEastAsianLayoutAttrList = m_pSerializer->createAttrList(); + OString sTrue((sal_Char *)"true"); + m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combine), sTrue); + + sal_Unicode cStart = rTwoLines.GetStartBracket(); + sal_Unicode cEnd = rTwoLines.GetEndBracket(); + + if (!cStart && !cEnd) + return; + + OString sBracket; + if ((cStart == '{') || (cEnd == '}')) + sBracket = (sal_Char *)"curly"; + else if ((cStart == '<') || (cEnd == '>')) + sBracket = (sal_Char *)"angle"; + else if ((cStart == '[') || (cEnd == ']')) + sBracket = (sal_Char *)"square"; + else + sBracket = (sal_Char *)"round"; + m_pEastAsianLayoutAttrList->add(FSNS(XML_w, XML_combineBrackets), sBracket); +} + +void DocxAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth ) +{ + m_pSerializer->singleElementNS( XML_w, XML_w, + FSNS( XML_w, XML_val ), rtl::OString::valueOf( sal_Int32( rScaleWidth.GetValue() ) ).getStr(), FSEND ); +} + +void DocxAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief ) +{ + switch ( rRelief.GetValue() ) + { + case RELIEF_EMBOSSED: + m_pSerializer->singleElementNS( XML_w, XML_emboss, FSEND ); + break; + case RELIEF_ENGRAVED: + m_pSerializer->singleElementNS( XML_w, XML_imprint, FSEND ); + break; + default: + m_pSerializer->singleElementNS( XML_w, XML_emboss, FSNS( XML_w, XML_val ), "off", FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_imprint, FSNS( XML_w, XML_val ), "off", FSEND ); + break; + } +} + +void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden ) +{ + if ( rHidden.GetValue() ) + m_pSerializer->singleElementNS( XML_w, XML_vanish, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink ) +{ + const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt(); + const SwCharFmt* pCharFmt = pINetFmt->GetCharFmt(); + + OString aStyleId( "style" ); + aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) ); + + m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); +} + +void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::TextCharFormat()\n" ); +#endif +} + +void DocxAttributeOutput::RefField( const SwField& rFld, const String& rRef ) +{ + USHORT nType = rFld.GetTyp( )->Which( ); + if ( nType == RES_GETEXPFLD ) + { + String sCmd = FieldString( ww::eREF ); + sCmd.APPEND_CONST_ASC( "\"" ); + sCmd += rRef; + sCmd.APPEND_CONST_ASC( "\" " ); + + m_rExport.OutputField( &rFld, ww::eREF, sCmd ); + } + + // There is nothing to do here for the set fields +} + +void DocxAttributeOutput::HiddenField( const SwField& /*rFld*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::HiddenField()\n" ); +#endif +} + +void DocxAttributeOutput::PostitField( const SwField* /* pFld*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::PostitField()\n" ); +#endif +} + +bool DocxAttributeOutput::DropdownField( const SwField* pFld ) +{ + bool bExpand = false; + + ww::eField eType = ww::eFORMDROPDOWN; + String sCmd = FieldString( eType ); + GetExport( ).OutputField( pFld, eType, sCmd ); + + return bExpand; +} + +void DocxAttributeOutput::SetField( const SwField& rFld, ww::eField eType, const String& rCmd ) +{ + // field bookmarks are handled in the EndRun method + GetExport().OutputField(&rFld, eType, rCmd ); +} + +void DocxAttributeOutput::WriteExpand( const SwField* pFld ) +{ + // Will be written in the next End Run + String sCmd; + m_rExport.OutputField( pFld, ww::eUNKNOWN, sCmd ); +} + +void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType, const String& rFldCmd, BYTE nMode ) +{ + struct FieldInfos infos; + infos.pField = pFld; + infos.sCmd = rFldCmd; + infos.eType = eType; + infos.bClose = WRITEFIELD_CLOSE & nMode; + infos.bOpen = WRITEFIELD_START & nMode; + + m_Fields.push_back( infos ); + + if ( pFld ) + { + USHORT nType = pFld->GetTyp( )->Which( ); + USHORT nSubType = pFld->GetSubType(); + + // TODO Any other field types here ? + if ( ( nType == RES_SETEXPFLD ) && ( nSubType & nsSwGetSetExpType::GSE_STRING ) ) + { + const SwSetExpField *pSet = ( const SwSetExpField* )( pFld ); + m_sFieldBkm = pSet->GetPar1( ); + } + else if ( nType == RES_DROPDOWN ) + { + const SwDropDownField* pDropDown = ( const SwDropDownField* )( pFld ); + m_sFieldBkm = pDropDown->GetName( ); + } + } +} + +void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts, + std::vector< OUString >& rEnds ) +{ + for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it < end; ++it ) + { + OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( ); + m_rMarksStart.push_back( rName ); + } + rStarts.clear(); + + for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it < end; ++it ) + { + OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( ); + m_rMarksEnd.push_back( rName ); + } + rEnds.clear(); +} + +void DocxAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote ) +{ + const SwEndNoteInfo& rInfo = rFootnote.IsEndNote()? + m_rExport.pDoc->GetEndNoteInfo(): m_rExport.pDoc->GetFtnInfo(); + + // footnote/endnote run properties + const SwCharFmt* pCharFmt = rInfo.GetAnchorCharFmt( *m_rExport.pDoc ); + + OString aStyleId( "style" ); + aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *pCharFmt ) ) ); + + m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND ); + + // remember the footnote/endnote to + // 1) write the footnoteReference/endnoteReference in EndRunProperties() + // 2) be able to dump them all to footnotes.xml/endnotes.xml + if ( !rFootnote.IsEndNote() ) + m_pFootnotesList->add( rFootnote ); + else + m_pEndnotesList->add( rFootnote ); +} + +void DocxAttributeOutput::FootnoteEndnoteReference() +{ + sal_Int32 nId; + const SwFmtFtn *pFootnote = m_pFootnotesList->getCurrent( nId ); + + // both cannot be set at the same time - if they are, it's a bug + if ( !pFootnote ) + pFootnote = m_pEndnotesList->getCurrent( nId ); + + if ( !pFootnote ) + return; + + sal_Int32 nToken = pFootnote->IsEndNote()? XML_endnoteReference: XML_footnoteReference; + + // write it + if ( pFootnote->GetNumStr().Len() == 0 ) + { + // autonumbered + m_pSerializer->singleElementNS( XML_w, nToken, + FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(), + FSEND ); + } + else + { + // not autonumbered + m_pSerializer->singleElementNS( XML_w, nToken, + FSNS( XML_w, XML_customMarkFollows ), "1", + FSNS( XML_w, XML_id ), ::rtl::OString::valueOf( nId ).getStr(), + FSEND ); + + RunText( pFootnote->GetNumStr() ); + } +} + +void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes ) +{ + const FootnotesVector& rVector = bFootnotes? m_pFootnotesList->getVector(): m_pEndnotesList->getVector(); + + sal_Int32 nBody = bFootnotes? XML_footnotes: XML_endnotes; + sal_Int32 nItem = bFootnotes? XML_footnote: XML_endnote; + + m_pSerializer->startElementNS( XML_w, nBody, + FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + FSEND ); + + sal_Int32 nIndex = 0; + + // separator + m_pSerializer->startElementNS( XML_w, nItem, + FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(), + FSNS( XML_w, XML_type ), "separator", + FSEND ); + m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_separator, FSEND ); + m_pSerializer->endElementNS( XML_w, XML_r ); + m_pSerializer->endElementNS( XML_w, XML_p ); + m_pSerializer->endElementNS( XML_w, nItem ); + + // separator + m_pSerializer->startElementNS( XML_w, nItem, + FSNS( XML_w, XML_id ), OString::valueOf( nIndex++ ).getStr(), + FSNS( XML_w, XML_type ), "continuationSeparator", + FSEND ); + m_pSerializer->startElementNS( XML_w, XML_p, FSEND ); + m_pSerializer->startElementNS( XML_w, XML_r, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_continuationSeparator, FSEND ); + m_pSerializer->endElementNS( XML_w, XML_r ); + m_pSerializer->endElementNS( XML_w, XML_p ); + m_pSerializer->endElementNS( XML_w, nItem ); + + // footnotes/endnotes themselves + for ( FootnotesVector::const_iterator i = rVector.begin(); i != rVector.end(); ++i, ++nIndex ) + { + m_pSerializer->startElementNS( XML_w, nItem, + FSNS( XML_w, XML_id ), OString::valueOf( nIndex ).getStr(), + FSEND ); + + const SwNodeIndex* pIndex = (*i)->GetTxtFtn()->GetStartNode(); + + m_rExport.WriteSpecialText( pIndex->GetIndex() + 1, + pIndex->GetNode().EndOfSectionIndex(), + bFootnotes? TXT_FTN: TXT_EDN ); + + m_pSerializer->endElementNS( XML_w, nItem ); + } + + m_pSerializer->endElementNS( XML_w, nBody ); + +} + +void DocxAttributeOutput::TextHardBlank( const SwFmtHardBlank& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::TextHardBlank()\n" ); +#endif +} + +void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short /*nMulti*/ ) +{ + if ( !m_pSpacingAttrList ) + m_pSpacingAttrList = m_pSerializer->createAttrList(); + + if ( nSpace < 0 ) + { + m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "exact" ); + m_pSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( -nSpace ) ) ); + } + else if ( nSpace > 0 ) + { + m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "atLeast" ); + m_pSpacingAttrList->add( FSNS( XML_w, XML_line ), OString::valueOf( sal_Int32( nSpace ) ) ); + } + else + m_pSpacingAttrList->add( FSNS( XML_w, XML_lineRule ), "auto" ); +} + +void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust ) +{ + const char *pAdjustString; + + switch ( rAdjust.GetAdjust() ) + { + case SVX_ADJUST_LEFT: + pAdjustString = "left"; + break; + case SVX_ADJUST_RIGHT: + pAdjustString = "right"; + break; + case SVX_ADJUST_BLOCKLINE: + case SVX_ADJUST_BLOCK: + pAdjustString = "both"; + break; + case SVX_ADJUST_CENTER: + pAdjustString = "center"; + break; + default: + return; // not supported attribute + } + m_pSerializer->singleElementNS( XML_w, XML_jc, FSNS( XML_w, XML_val ), pAdjustString, FSEND ); +} + +void DocxAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit ) +{ + if (rSplit.GetValue()) + m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSNS( XML_w, XML_val ), "off", FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_keepLines, FSEND ); +} + +void DocxAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows ) +{ + if (rWidows.GetValue()) + m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSEND ); + else + m_pSerializer->singleElementNS( XML_w, XML_widowControl, FSNS( XML_w, XML_val ), "off", FSEND ); +} + +static void impl_WriteTabElement( FSHelperPtr pSerializer, + const SvxTabStop& rTab, long nCurrentLeft ) +{ + FastAttributeList *pTabElementAttrList = pSerializer->createAttrList(); + + switch (rTab.GetAdjustment()) + { + case SVX_TAB_ADJUST_RIGHT: + pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"right") ); + break; + case SVX_TAB_ADJUST_DECIMAL: + pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"decimal") ); + break; + case SVX_TAB_ADJUST_CENTER: + pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"center") ); + break; + case SVX_TAB_ADJUST_DEFAULT: + case SVX_TAB_ADJUST_LEFT: + default: + pTabElementAttrList->add( FSNS( XML_w, XML_val ), OString( (sal_Char *)"left") ); + break; + } + + pTabElementAttrList->add( FSNS( XML_w, XML_pos ), OString::valueOf( rTab.GetTabPos() + nCurrentLeft ) ); + + sal_Unicode cFillChar = rTab.GetFill(); + + if (sal_Unicode('.') == cFillChar ) + pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "dot" ) ); + else if ( sal_Unicode('-') == cFillChar ) + pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "hyphen" ) ); + else if ( sal_Unicode(0xB7) == cFillChar ) // middle dot + pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "middleDot" ) ); + else if ( sal_Unicode('_') == cFillChar ) + pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "underscore" ) ); + else + pTabElementAttrList->add( FSNS( XML_w, XML_leader ), OString( (sal_Char *) "none" ) ); + + pSerializer->singleElementNS( XML_w, XML_tab, pTabElementAttrList ); +} + +void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop ) +{ + const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE ); + long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0; + + m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND ); + + sal_uInt16 nCount = rTabStop.Count(); + for (sal_uInt16 i = 0; i < nCount; i++ ) + impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft ); + + m_pSerializer->endElementNS( XML_w, XML_tabs ); +} + +void DocxAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone ) +{ + m_pSerializer->singleElementNS( XML_w, XML_suppressAutoHyphens, + FSNS( XML_w, XML_val ), rHyphenZone.IsHyphen( ) ? "false" : "true" , + FSEND ); +} + +void DocxAttributeOutput::ParaNumRule_Impl( const SwTxtNode* /*pTxtNd*/, sal_Int32 nLvl, sal_Int32 nNumId ) +{ + if ( USHRT_MAX != nNumId && 0 != nNumId ) + { + m_pSerializer->startElementNS( XML_w, XML_numPr, FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_ilvl, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nLvl )).getStr(), FSEND ); + m_pSerializer->singleElementNS( XML_w, XML_numId, FSNS( XML_w, XML_val ), OString::valueOf( sal_Int32( nNumId )).getStr(), FSEND ); + m_pSerializer->endElementNS( XML_w, XML_numPr ); + } +} + +void DocxAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace ) +{ + USHORT nXmlElement = 0; + + switch ( rScriptSpace.Which( ) ) + { + case RES_PARATR_SCRIPTSPACE: + nXmlElement = XML_autoSpaceDE; + break; + case RES_PARATR_HANGINGPUNCTUATION: + nXmlElement = XML_overflowPunct; + break; + case RES_PARATR_FORBIDDEN_RULES: + nXmlElement = XML_kinsoku; + break; + } + + if ( nXmlElement ) + { + m_pSerializer->singleElementNS( XML_w, nXmlElement, + FSNS( XML_w, XML_val ), rScriptSpace.GetValue( ) ? "true": "false", + FSEND ); + } +} + +void DocxAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign ) +{ + const char *pAlignString; + + switch ( rAlign.GetValue() ) + { + case SvxParaVertAlignItem::BASELINE: + pAlignString = "baseline"; + break; + case SvxParaVertAlignItem::TOP: + pAlignString = "top"; + break; + case SvxParaVertAlignItem::CENTER: + pAlignString = "center"; + break; + case SvxParaVertAlignItem::BOTTOM: + pAlignString = "bottom"; + break; + case SvxParaVertAlignItem::AUTOMATIC: + pAlignString = "auto"; + break; + default: + return; // not supported attribute + } + m_pSerializer->singleElementNS( XML_w, XML_textAlignment, FSNS( XML_w, XML_val ), pAlignString, FSEND ); +} + +void DocxAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid ) +{ + m_pSerializer->singleElementNS( XML_w, XML_snapToGrid, + FSNS( XML_w, XML_val ), rGrid.GetValue( ) ? "true": "false", + FSEND ); +} + +void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize ) +{ + if ( m_rExport.bOutFlyFrmAttrs ) + { + #if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatFrameSize() - Fly frames\n" ); + #endif + } + else if ( m_rExport.bOutPageDescs ) + { + FastAttributeList *attrList = m_pSerializer->createAttrList( ); + if ( m_rExport.pAktPageDesc->GetLandscape( ) ) + attrList->add( FSNS( XML_w, XML_orient ), "landscape" ); + + + attrList->add( FSNS( XML_w, XML_w ), OString::valueOf( rSize.GetWidth( ) ) ); + attrList->add( FSNS( XML_w, XML_h ), OString::valueOf( rSize.GetHeight( ) ) ); + + XFastAttributeListRef xAttrList( attrList ); + attrList = NULL; + + m_pSerializer->singleElementNS( XML_w, XML_pgSz, xAttrList ); + } +} + +void DocxAttributeOutput::FormatPaperBin( const SvxPaperBinItem& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatPaperBin()\n" ); +#endif +} + +void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace ) +{ + if ( m_rExport.bOutFlyFrmAttrs ) + { +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "DocxAttributeOutput::FormatLRSpace() - Fly frames\n" ); +#endif + } + else if ( m_rExport.bOutPageDescs ) + { + if ( !m_pSpacingAttrList ) + m_pSpacingAttrList = m_pSerializer->createAttrList(); + + + USHORT nLDist, nRDist; + const SfxPoolItem* pItem = m_rExport.HasItem( RES_BOX ); + if ( pItem ) + { + nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT ); + nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT ); + } + else + nLDist = nRDist = 0; + nLDist = nLDist + (USHORT)rLRSpace.GetLeft(); + nRDist = nRDist + (USHORT)rLRSpace.GetRight(); + + m_pSpacingAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( sal_Int32( nLDist ) ) ); + m_pSpacingAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( sal_Int32( nRDist ) ) ); + } + else + { + FastAttributeList *pLRSpaceAttrList = m_pSerializer->createAttrList(); + + pLRSpaceAttrList->add( FSNS( XML_w, XML_left ), OString::valueOf( (sal_Int32) rLRSpace.GetTxtLeft() ) ); + pLRSpaceAttrList->add( FSNS( XML_w, XML_right ), OString::valueOf( (sal_Int32) rLRSpace.GetRight() ) ); + + sal_Int32 nFirstLineAdjustment = rLRSpace.GetTxtFirstLineOfst(); + if (nFirstLineAdjustment > 0) + pLRSpaceAttrList->add( FSNS( XML_w, XML_firstLine ), OString::valueOf( nFirstLineAdjustment ) ); + else + pLRSpaceAttrList->add( FSNS( XML_w, XML_hanging ), OString::valueOf( - nFirstLineAdjustment ) ); + m_pSerializer->singleElementNS( XML_w, XML_ind, pLRSpaceAttrList ); + } +} + +void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace ) +{ + if (!m_pSpacingAttrList) + m_pSpacingAttrList = m_pSerializer->createAttrList(); + + if ( m_rExport.bOutFlyFrmAttrs ) + { + } + else if (m_rExport.bOutPageDescs ) + { + ASSERT( m_rExport.GetCurItemSet(), "Impossible" ); + if ( !m_rExport.GetCurItemSet() ) + return; + + HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() ); + + if ( aDistances.HasHeader() ) + { + // Header top + m_pSpacingAttrList->add( FSNS( XML_w, XML_header ), + OString::valueOf( sal_Int32( aDistances.dyaHdrTop ) ) ); + } + + // Page top + m_pSpacingAttrList->add( FSNS( XML_w, XML_top ), + OString::valueOf( sal_Int32( aDistances.dyaTop ) ) ); + + if ( aDistances.HasFooter() ) + { + // Footer bottom + m_pSpacingAttrList->add( FSNS( XML_w, XML_footer ), + OString::valueOf( sal_Int32( aDistances.dyaHdrBottom ) ) ); + } + + // Page Bottom + m_pSpacingAttrList->add( FSNS( XML_w, XML_bottom ), + OString::valueOf( sal_Int32( aDistances.dyaBottom ) ) ); + + } + else + { + m_pSpacingAttrList->add( FSNS( XML_w, XML_before ), + OString::valueOf( (sal_Int32)rULSpace.GetUpper() ) ); + m_pSpacingAttrList->add( FSNS( XML_w, XML_after ), + OString::valueOf( (sal_Int32)rULSpace.GetLower() ) ); + } +} + +void DocxAttributeOutput::FormatSurround( const SwFmtSurround& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatSurround()\n" ); +#endif +} + +void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatVertOrientation()\n" ); +#endif +} + +void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatHorizOrientation()\n" ); +#endif +} + +void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatAnchor()\n" ); +#endif +} + +void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush ) +{ + if ( !m_rExport.bOutPageDescs ) + { + OString sColor = impl_ConvertColor( rBrush.GetColor( ) ); + m_pSerializer->singleElementNS( XML_w, XML_shd, + FSNS( XML_w, XML_fill ), sColor.getStr( ), + FSEND ); + } + +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatBackground()\n" ); +#endif +} + +void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox ) +{ + + if ( !m_bOpenedSectPr ) + { + // Normally open the borders tag for paragraphs + m_pSerializer->startElementNS( XML_w, XML_pBdr, FSEND ); + } + + impl_pageBorders( m_pSerializer, rBox ); + + if ( m_bOpenedSectPr ) + { + // Special handling for pgBorder + m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); + m_pSerializer->mergeTopMarks( ); + } + else + { + // Normally close the borders tag for paragraphs + m_pSerializer->endElementNS( XML_w, XML_pBdr ); + } +} + +void DocxAttributeOutput::FormatColumns_Impl( USHORT nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize ) +{ + // Get the columns attributes + FastAttributeList *pColsAttrList = m_pSerializer->createAttrList(); + + pColsAttrList->add( FSNS( XML_w, XML_num ), + OString::valueOf( sal_Int32( nCols ) ). getStr( ) ); + + const char* pEquals = "false"; + if ( bEven ) + { + USHORT nWidth = rCol.GetGutterWidth( true ); + pColsAttrList->add( FSNS( XML_w, XML_space ), + OString::valueOf( sal_Int32( nWidth ) ).getStr( ) ); + + pEquals = "true"; + } + + pColsAttrList->add( FSNS( XML_w, XML_equalWidth ), pEquals ); + + bool bHasSep = COLADJ_NONE == rCol.GetLineAdj( ); + pColsAttrList->add( FSNS( XML_w, XML_sep ), bHasSep ? "true" : "false" ); + + // Write the element + m_pSerializer->startElementNS( XML_w, XML_cols, pColsAttrList ); + + // Write the columns width if non-equals + const SwColumns & rColumns = rCol.GetColumns( ); + if ( !bEven ) + { + for ( USHORT n = 0; n < nCols; ++n ) + { + FastAttributeList *pColAttrList = m_pSerializer->createAttrList(); + USHORT nWidth = rCol.CalcPrtColWidth( n, ( USHORT ) nPageSize ); + pColAttrList->add( FSNS( XML_w, XML_w ), + OString::valueOf( sal_Int32( nWidth ) ).getStr( ) ); + + if ( n + 1 != nCols ) + { + USHORT nSpacing = rColumns[n]->GetRight( ) + rColumns[n + 1]->GetLeft( ); + pColAttrList->add( FSNS( XML_w, XML_space ), + OString::valueOf( sal_Int32( nSpacing ) ).getStr( ) ); + } + + m_pSerializer->singleElementNS( XML_w, XML_col, pColAttrList ); + } + } + + m_pSerializer->endElementNS( XML_w, XML_cols ); +} + +void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& ) +{ + m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND ); +} + +void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxAttributeOutput::FormatTextGrid()\n" ); +#endif +} + +void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering ) +{ + if ( !rNumbering.IsCount( ) ) + m_pSerializer->singleElementNS( XML_w, XML_suppressLineNumbers, FSEND ); +} + +void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection ) +{ + OString sTextFlow; + bool bBiDi = false; + short nDir = rDirection.GetValue(); + + if ( nDir == FRMDIR_ENVIRONMENT ) + nDir = GetExport( ).GetDefaultFrameDirection( ); + + switch ( nDir ) + { + default: + case FRMDIR_HORI_LEFT_TOP: + sTextFlow = OString( "lrTb" ); + break; + case FRMDIR_HORI_RIGHT_TOP: + sTextFlow = OString( "lrTb" ); + bBiDi = true; + break; + case FRMDIR_VERT_TOP_LEFT: // many things but not this one + case FRMDIR_VERT_TOP_RIGHT: + sTextFlow = OString( "tbRl" ); + break; + } + + if ( m_rExport.bOutPageDescs ) + { + m_pSerializer->singleElementNS( XML_w, XML_textDirection, + FSNS( XML_w, XML_val ), sTextFlow.getStr( ), + FSEND ); + if ( bBiDi ) + m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND ); + } + else if ( !m_rExport.bOutFlyFrmAttrs ) + { + if ( bBiDi ) + m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND ); + } +} + +DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML ) + : m_rExport( rExport ), + m_pSerializer( pSerializer ), + m_rDrawingML( *pDrawingML ), + m_pFontsAttrList( NULL ), + m_pEastAsianLayoutAttrList( NULL ), + m_pCharLangAttrList( NULL ), + m_pSpacingAttrList( NULL ), + m_pHyperlinkAttrList( NULL ), + m_pFootnotesList( new ::docx::FootnotesList() ), + m_pEndnotesList( new ::docx::FootnotesList() ), + m_pSectionInfo( NULL ), + m_pRedlineData( NULL ), + m_nRedlineId( 0 ), + m_bOpenedSectPr( false ), + m_sFieldBkm( ), + m_nNextMarkId( 0 ), + m_pTableWrt( NULL ), + m_bTableCellOpen( false ), + m_nTableDepth( 0 ), + m_bParagraphOpened( false ), + m_nColBreakStatus( COLBRK_NONE ) +{ +} + +DocxAttributeOutput::~DocxAttributeOutput() +{ + delete m_pFontsAttrList, m_pFontsAttrList = NULL; + delete m_pEastAsianLayoutAttrList, m_pEastAsianLayoutAttrList = NULL; + delete m_pCharLangAttrList, m_pCharLangAttrList = NULL; + delete m_pSpacingAttrList, m_pSpacingAttrList = NULL; + delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL; + + delete m_pFootnotesList, m_pFootnotesList = NULL; + delete m_pEndnotesList, m_pEndnotesList = NULL; + + delete m_pTableWrt, m_pTableWrt = NULL; +} + +MSWordExportBase& DocxAttributeOutput::GetExport() +{ + return m_rExport; +} + +bool DocxAttributeOutput::HasFootnotes() +{ + return !m_pFootnotesList->isEmpty(); +} + +bool DocxAttributeOutput::HasEndnotes() +{ + return !m_pEndnotesList->isEmpty(); +} diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx new file mode 100644 index 000000000000..71b1a452f440 --- /dev/null +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -0,0 +1,616 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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 _DOCXATTRIBUTEOUTPUT_HXX_ +#define _DOCXATTRIBUTEOUTPUT_HXX_ + +#include "attributeoutputbase.hxx" +#include "fields.hxx" + +#include <sax/fshelper.hxx> +#include <sax/fastattribs.hxx> +#include <vcl/vclenum.hxx> + +#include <fldbas.hxx> + +#include <vector> + +class DocxExport; + +class SwGrfNode; + +namespace docx { class FootnotesList; } +namespace oox { namespace drawingml { class DrawingML; } } + +struct FieldInfos +{ + const SwField* pField; + ww::eField eType; + bool bOpen; + bool bClose; + String sCmd; +}; + +enum DocxColBreakStatus +{ + COLBRK_NONE, + COLBRK_POSTPONE, + COLBRK_WRITE +}; + +class DocxAttributeOutput : public AttributeOutputBase +{ +public: + /// Export the state of RTL/CJK. + virtual void RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ); + + /// Start of the paragraph. + virtual void StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo ); + + /// End of the paragraph. + virtual void EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ); + + /// Empty paragraph. + virtual void EmptyParagraph(); + + /// Called before we start outputting the attributes. + virtual void StartParagraphProperties( const SwTxtNode& rNode ); + + /// Called after we end outputting the attributes. + virtual void EndParagraphProperties(); + + /// Start of the text run. + virtual void StartRun( const SwRedlineData* pRedlineData ); + + /// End of the text run. + virtual void EndRun(); + + /// Called before we start outputting the attributes. + virtual void StartRunProperties(); + + /// Called after we end outputting the attributes. + virtual void EndRunProperties( const SwRedlineData* pRedlineData ); + + /// Output text (inside a run). + virtual void RunText( const String& rText, rtl_TextEncoding eCharSet = RTL_TEXTENCODING_UTF8 ); + + /// Output text (without markup). + virtual void RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet ); + + /// Output ruby start. + virtual void StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby ); + + /// Output ruby end. + virtual void EndRuby(); + + /// Output URL start. + virtual bool StartURL( const String& rUrl, const String& rTarget ); + + /// Output URL end. + virtual bool EndURL(); + + virtual void FieldVanish( const String& rTxt, ww::eField eType ); + + /// Output redlining. + /// + /// The common attribute that can be among the run properties. + virtual void Redline( const SwRedlineData* pRedline ); + + /// Output redlining. + /// + /// Start of the tag that encloses the run, fills the info according to + /// the value of m_pRedlineData. + void StartRedline( const SwRedlineData* pRedlineData ); + + /// Output redlining. + /// + /// End of the tag that encloses the run. + void EndRedline(); + + virtual void FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, USHORT nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ); + + /// Output style. + virtual void ParagraphStyle( USHORT nStyle ); + + virtual void TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo ); + + virtual void TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner ); + + virtual void TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableRowEnd( sal_uInt32 nDepth = 1 ); + + /// Start of the styles table. + virtual void StartStyles(); + + /// End of the styles table. + virtual void EndStyles( USHORT nNumberOfStyles ); + + /// Write default style. + virtual void DefaultStyle( USHORT nStyle ); + + /// Start of a style in the styles table. + virtual void StartStyle( const String& rName, bool bPapFmt, + USHORT nBase, USHORT nNext, USHORT nWwId, USHORT nId ); + + /// End of a style in the styles table. + virtual void EndStyle(); + + /// Start of (paragraph or run) properties of a style. + virtual void StartStyleProperties( bool bParProp, USHORT nStyle ); + + /// End of (paragraph or run) properties of a style. + virtual void EndStyleProperties( bool bParProp ); + + /// Numbering rule and Id. + virtual void OutlineNumbering( BYTE nLvl, const SwNumFmt &rNFmt, const SwFmt &rFmt ); + + /// Page break + /// As a paragraph property - the paragraph should be on the next page. + virtual void PageBreakBefore( bool bBreak ); + + /// Write a section break + /// msword::ColumnBreak or msword::PageBreak + virtual void SectionBreak( BYTE nC, const WW8_SepInfo* pSectionInfo = NULL ); + + /// Start of the section properties. + virtual void StartSection(); + + /// End of the section properties. + virtual void EndSection(); + + /// Protection of forms. + virtual void SectionFormProtection( bool bProtected ); + + /// Numbering of the lines in the document. + virtual void SectionLineNumbering( ULONG nRestartNo, const SwLineNumberInfo& rLnNumInfo ); + + /// Has different headers/footers for the title page. + virtual void SectionTitlePage(); + + /// Description of the page borders. + virtual void SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* pFirstPageFmt ); + + /// Columns populated from right/numbers on the right side? + virtual void SectionBiDi( bool bBiDi ); + + /// The style of the page numbers. + /// + /// nPageRestartNumberr being 0 means no restart. + virtual void SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber ); + + /// The type of breaking. + virtual void SectionType( BYTE nBreakCode ); + + /// Start the font. + void StartFont( const String& rFamilyName ) const; + + /// End the font. + void EndFont() const; + + /// Alternate name for the font. + void FontAlternateName( const String& rName ) const; + + /// Font charset. + void FontCharset( sal_uInt8 nCharSet ) const; + + /// Font family. + void FontFamilyType( FontFamily eFamily ) const; + + /// Font pitch. + void FontPitchType( FontPitch ePitch ) const; + + /// Definition of a numbering instance. + virtual void NumberingDefinition( USHORT nId, const SwNumRule &rRule ); + + /// Start of the abstract numbering definition instance. + virtual void StartAbstractNumbering( USHORT nId ); + + /// End of the abstract numbering definition instance. + virtual void EndAbstractNumbering(); + + /// All the numbering level information. + virtual void NumberingLevel( BYTE nLevel, + USHORT nStart, + USHORT nNumberingType, + SvxAdjust eAdjust, + const BYTE *pNumLvlPos, + BYTE nFollow, + const wwFont *pFont, + const SfxItemSet *pOutSet, + sal_Int16 nIndentAt, + sal_Int16 nFirstLineIndex, + sal_Int16 nListTabPos, + const String &rNumberingString ); + + void WriteField_Impl( const SwField* pFld, ww::eField eType, const String& rFldCmd, BYTE nMode ); + + void WriteBookmarks_Impl( std::vector< rtl::OUString >& rStarts, std::vector< rtl::OUString >& rEnds ); + +private: + /// Initialize the structures where we are going to collect some of the paragraph properties. + /// + /// Some of the properties have to be collected from more sources, and are + /// actually not written between StartParagraphProperties and + /// EndParagraphProperties. They are output in this method, which is + /// supposed to be called just before outputting </rPr> whenever it is done. + void InitCollectedParagraphProperties(); + + /// Output what we collected during the run properties output. + /// + /// @see WriteCollectedParagrapProperties(). + void WriteCollectedParagraphProperties(); + + /// Initialize the structures where we are going to collect some of the run properties. + /// + /// This is an equivalent of InitCollectedParagraphProperties(), resp. + /// WriteCollectectedParagraphProperties(). + /// + /// @see InitCollectedParagraphProperties(). + void InitCollectedRunProperties(); + + /// Output what we collected during the run properties output. + /// + /// @see InitCollectedRunProperies(), WriteCollectedParagraphProperties() + void WriteCollectedRunProperties(); + + /// Output graphic fly frames. + void FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ); + + void InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + void StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + void StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + void StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + void TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + void EndTableCell( ); + + void EndTableRow( ); + + void EndTable(); + + /// End cell, row, and even the entire table if necessary. + void FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph = false ); + +protected: + + /// Output frames - the implementation. + virtual void OutputFlyFrame_Impl( const sw::Frame& rFmt, const Point& rNdTopLeft ); + + /// Sfx item Sfx item RES_CHRATR_CASEMAP + virtual void CharCaseMap( const SvxCaseMapItem& rCaseMap ); + + /// Sfx item Sfx item RES_CHRATR_COLOR + virtual void CharColor( const SvxColorItem& rColor); + + /// Sfx item Sfx item RES_CHRATR_CONTOUR + virtual void CharContour( const SvxContourItem& rContour ); + + /// Sfx item RES_CHRATR_CROSSEDOUT + virtual void CharCrossedOut( const SvxCrossedOutItem& rCrossedOut ); + + /// Sfx item RES_CHRATR_ESCAPEMENT + virtual void CharEscapement( const SvxEscapementItem& rEscapement ); + + /// Sfx item RES_CHRATR_FONT + virtual void CharFont( const SvxFontItem& rFont ); + + /// Sfx item RES_CHRATR_FONTSIZE + virtual void CharFontSize( const SvxFontHeightItem& rFontSize ); + + /// Sfx item RES_CHRATR_KERNING + virtual void CharKerning( const SvxKerningItem& rKerning ); + + /// Sfx item RES_CHRATR_LANGUAGE + virtual void CharLanguage( const SvxLanguageItem& rLanguage ); + + /// Sfx item RES_CHRATR_POSTURE + virtual void CharPosture( const SvxPostureItem& rPosture ); + + /// Sfx item RES_CHRATR_SHADOWED + virtual void CharShadow( const SvxShadowedItem& rShadow ); + + /// Sfx item RES_CHRATR_UNDERLINE + virtual void CharUnderline( const SvxUnderlineItem& rUnderline ); + + /// Sfx item RES_CHRATR_WEIGHT + virtual void CharWeight( const SvxWeightItem& rWeight ); + + /// Sfx item RES_CHRATR_AUTOKERN + virtual void CharAutoKern( const SvxAutoKernItem& ); + + /// Sfx item RES_CHRATR_BLINK + virtual void CharAnimatedText( const SvxBlinkItem& rBlink ); + + /// Sfx item RES_CHRATR_BACKGROUND + virtual void CharBackground( const SvxBrushItem& rBrush ); + + /// Sfx item RES_CHRATR_CJK_FONT + virtual void CharFontCJK( const SvxFontItem& rFont ); + + /// Sfx item RES_CHRATR_CJK_FONTSIZE + virtual void CharFontSizeCJK( const SvxFontHeightItem& rFontSize ) { CharFontSize( rFontSize ); } + + /// Sfx item RES_CHRATR_CJK_LANGUAGE + virtual void CharLanguageCJK( const SvxLanguageItem& rLanguageItem ) { CharLanguage( rLanguageItem ); } + + /// Sfx item RES_CHRATR_CJK_POSTURE + virtual void CharPostureCJK( const SvxPostureItem& rPosture ); + + /// Sfx item RES_CHRATR_CJK_WEIGHT + virtual void CharWeightCJK( const SvxWeightItem& rWeight ); + + /// Sfx item RES_CHRATR_CTL_FONT + virtual void CharFontCTL( const SvxFontItem& rFont ); + + /// Sfx item RES_CHRATR_CTL_FONTSIZE + virtual void CharFontSizeCTL( const SvxFontHeightItem& rFontSize ) { CharFontSize( rFontSize ); } + + /// Sfx item RES_CHRATR_CTL_LANGUAGE + virtual void CharLanguageCTL( const SvxLanguageItem& rLanguageItem ) { CharLanguage( rLanguageItem); } + + /// Sfx item RES_CHRATR_CTL_POSTURE + virtual void CharPostureCTL( const SvxPostureItem& rWeight ); + + /// Sfx item RES_CHRATR_CTL_WEIGHT + virtual void CharWeightCTL( const SvxWeightItem& rWeight ); + + /// Sfx item RES_CHRATR_ROTATE + virtual void CharRotate( const SvxCharRotateItem& rRotate ); + + /// Sfx item RES_CHRATR_EMPHASIS_MARK + virtual void CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark ); + + /// Sfx item RES_CHRATR_TWO_LINES + virtual void CharTwoLines( const SvxTwoLinesItem& rTwoLines ); + + /// Sfx item RES_CHRATR_SCALEW + virtual void CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth ); + + /// Sfx item RES_CHRATR_RELIEF + virtual void CharRelief( const SvxCharReliefItem& rRelief); + + /// Sfx item RES_CHRATR_HIDDEN + virtual void CharHidden( const SvxCharHiddenItem& rHidden ); + + /// Sfx item RES_TXTATR_INETFMT + virtual void TextINetFormat( const SwFmtINetFmt& ); + + /// Sfx item RES_TXTATR_CHARFMT + virtual void TextCharFormat( const SwFmtCharFmt& ); + + /// Sfx item RES_TXTATR_FTN + virtual void TextFootnote_Impl( const SwFmtFtn& ); + + /// Output the footnote/endnote reference (if there's one to output). + void FootnoteEndnoteReference(); + + /// Sfx item RES_TXTATR_HARDBLANK + virtual void TextHardBlank( const SwFmtHardBlank& ); + + /// Sfx item RES_PARATR_LINESPACING + virtual void ParaLineSpacing_Impl( short nSpace, short nMulti ); + + /// Sfx item RES_PARATR_ADJUST + virtual void ParaAdjust( const SvxAdjustItem& rAdjust ); + + /// Sfx item RES_PARATR_SPLIT + virtual void ParaSplit( const SvxFmtSplitItem& rSplit ); + + /// Sfx item RES_PARATR_WIDOWS + virtual void ParaWidows( const SvxWidowsItem& rWidows ); + + /// Sfx item RES_PARATR_TABSTOP + virtual void ParaTabStop( const SvxTabStopItem& rTabStop ); + + /// Sfx item RES_PARATR_HYPHENZONE + virtual void ParaHyphenZone( const SvxHyphenZoneItem& ); + + /// Sfx item RES_PARATR_NUMRULE + virtual void ParaNumRule_Impl( const SwTxtNode *pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId ); + + /// Sfx item RES_PARATR_SCRIPTSPACE + virtual void ParaScriptSpace( const SfxBoolItem& ); + + /// Sfx item RES_PARATR_VERTALIGN + virtual void ParaVerticalAlign( const SvxParaVertAlignItem& rAlign ); + + /// Sfx item RES_PARATR_SNAPTOGRID + virtual void ParaSnapToGrid( const SvxParaGridItem& ); + + /// Sfx item RES_FRM_SIZE + virtual void FormatFrameSize( const SwFmtFrmSize& ); + + /// Sfx item RES_PAPER_BIN + virtual void FormatPaperBin( const SvxPaperBinItem& ); + + /// Sfx item RES_LR_SPACE + virtual void FormatLRSpace( const SvxLRSpaceItem& rLRSpace ); + + /// Sfx item RES_UL_SPACE + virtual void FormatULSpace( const SvxULSpaceItem& rULSpace ); + + /// Sfx item RES_SURROUND + virtual void FormatSurround( const SwFmtSurround& ); + + /// Sfx item RES_VERT_ORIENT + virtual void FormatVertOrientation( const SwFmtVertOrient& ); + + /// Sfx item RES_HORI_ORIENT + virtual void FormatHorizOrientation( const SwFmtHoriOrient& ); + + /// Sfx item RES_ANCHOR + virtual void FormatAnchor( const SwFmtAnchor& ); + + /// Sfx item RES_BACKGROUND + virtual void FormatBackground( const SvxBrushItem& ); + + /// Sfx item RES_BOX + virtual void FormatBox( const SvxBoxItem& ); + + /// Sfx item RES_COL + virtual void FormatColumns_Impl( USHORT nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize ); + + /// Sfx item RES_KEEP + virtual void FormatKeep( const SvxFmtKeepItem& ); + + /// Sfx item RES_TEXTGRID + virtual void FormatTextGrid( const SwTextGridItem& ); + + /// Sfx item RES_LINENUMBER + virtual void FormatLineNumbering( const SwFmtLineNumber& ); + + /// Sfx item RES_FRAMEDIR + virtual void FormatFrameDirection( const SvxFrameDirectionItem& ); + + /// Write the expanded field + virtual void WriteExpand( const SwField* pFld ); + + virtual void RefField( const SwField& rFld, const String& rRef ); + virtual void HiddenField( const SwField& rFld ); + virtual void SetField( const SwField& rFld, ww::eField eType, const String& rCmd ); + virtual void PostitField( const SwField* pFld ); + virtual bool DropdownField( const SwField* pFld ); + + virtual bool AnalyzeURL( const String& rURL, const String& rTarget, String* pLinkURL, String* pMark ); + + /// Reference to the export, where to get the data from + DocxExport &m_rExport; + + /// Fast serializer to output the data + ::sax_fastparser::FSHelperPtr m_pSerializer; + + /// DrawingML access + oox::drawingml::DrawingML &m_rDrawingML; + +private: + + void DoWriteBookmarks( ); + + void StartField_Impl( FieldInfos& rInfos, sal_Bool bWriteRun = sal_False ); + void DoWriteCmd( String& rCmd ); + void CmdField_Impl( FieldInfos& rInfos ); + void EndField_Impl( FieldInfos& rInfos ); + + ::sax_fastparser::FastAttributeList *m_pFontsAttrList, *m_pEastAsianLayoutAttrList; + ::sax_fastparser::FastAttributeList *m_pCharLangAttrList; + ::sax_fastparser::FastAttributeList *m_pSpacingAttrList; + ::sax_fastparser::FastAttributeList *m_pHyperlinkAttrList; + + ::docx::FootnotesList *m_pFootnotesList; + ::docx::FootnotesList *m_pEndnotesList; + + const WW8_SepInfo *m_pSectionInfo; + + /// Redline data to remember in the text run. + const SwRedlineData *m_pRedlineData; + + /// Id of the redline + sal_Int32 m_nRedlineId; + + /// Flag indicating that the section properties are being written + sal_Bool m_bOpenedSectPr; + + /// Field data to remember in the text run + std::vector< FieldInfos > m_Fields; + String m_sFieldBkm; + sal_Int32 m_nNextMarkId; + + /// Bookmarks to output + std::vector<rtl::OString> m_rMarksStart; + std::vector<rtl::OString> m_rMarksEnd; + + /// Maps of the bookmarks ids + std::map<rtl::OString, USHORT> m_rOpenedMarksIds; + + /// The current table helper + SwWriteTable *m_pTableWrt; + + /// Remember if we are in an open cell, or not. + bool m_bTableCellOpen; + + /// Remember the current table depth. + sal_uInt32 m_nTableDepth; + + bool m_bParagraphOpened; + + // Remember that a column break has to be opened at the + // beginning of the next paragraph + DocxColBreakStatus m_nColBreakStatus; + +public: + DocxAttributeOutput( DocxExport &rExport, ::sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML ); + + virtual ~DocxAttributeOutput(); + + /// Return the right export class. + virtual MSWordExportBase& GetExport(); + + /// For eg. the output of the styles, we need to switch the serializer to enother one. + void SetSerializer( ::sax_fastparser::FSHelperPtr pSerializer ) { m_pSerializer = pSerializer; } + + /// Occasionnaly need to use this serializer from the outside + ::sax_fastparser::FSHelperPtr GetSerializer( ) { return m_pSerializer; } + + /// Do we have any footnotes? + bool HasFootnotes(); + + /// Do we have any endnotes? + bool HasEndnotes(); + + /// Output the content of the footnotes.xml resp. endnotes.xml + void FootnotesEndnotes( bool bFootnotes ); +}; + +#endif // _DOCXATTRIBUTEOUTPUT_HXX_ + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx new file mode 100644 index 000000000000..6ad8d6fb6306 --- /dev/null +++ b/sw/source/filter/ww8/docxexport.cxx @@ -0,0 +1,812 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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. + * + ************************************************************************/ + +#include "docxexport.hxx" +#include "docxexportfilter.hxx" + +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/i18n/ScriptType.hdl> + +#include <oox/core/tokens.hxx> +#include <oox/export/drawingml.hxx> +#include <oox/export/vmlexport.hxx> + +#include <map> +#include <algorithm> + +#include <IMark.hxx> +#include <docsh.hxx> +#include <ndtxt.hxx> +#include <wrtww8.hxx> +#include <fltini.hxx> +#include <fmtline.hxx> +#include <fmtpdsc.hxx> +#include <frmfmt.hxx> +#include <section.hxx> + +#include <docary.hxx> +#include <numrule.hxx> +#include <charfmt.hxx> + +#include "ww8par.hxx" +#include "ww8scan.hxx" + +#include <comphelper/string.hxx> +#include <rtl/ustrbuf.hxx> +#include <vcl/font.hxx> + +using namespace ::comphelper; +using namespace ::com::sun::star; + +using oox::vml::VMLExport; + +using rtl::OUString; +using rtl::OUStringBuffer; + +using sw::mark::IMark; + +#define S( x ) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +AttributeOutputBase& DocxExport::AttrOutput() const +{ + return *m_pAttrOutput; +} + +MSWordSections& DocxExport::Sections() const +{ + return *m_pSections; +} + +bool DocxExport::CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich ) +{ + // TODO FIXME is this actually true for docx? - this is ~copied from WW8 + if ( nScript == i18n::ScriptType::ASIAN ) + { + // for asian in ww8, there is only one fontsize + // and one fontstyle (posture/weight) + switch ( nWhich ) + { + case RES_CHRATR_FONTSIZE: + case RES_CHRATR_POSTURE: + case RES_CHRATR_WEIGHT: + return false; + default: + break; + } + } + else if ( nScript != i18n::ScriptType::COMPLEX ) + { + // for western in ww8, there is only one fontsize + // and one fontstyle (posture/weight) + switch ( nWhich ) + { + case RES_CHRATR_CJK_FONTSIZE: + case RES_CHRATR_CJK_POSTURE: + case RES_CHRATR_CJK_WEIGHT: + return false; + default: + break; + } + } + return true; +} + +bool DocxExport::GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt, + xub_StrLen nEnd, IMarkVector& rArr ) +{ + IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); + ULONG nNd = rNd.GetIndex( ); + + const sal_Int32 nMarks = pMarkAccess->getMarksCount(); + for ( sal_Int32 i = 0; i < nMarks; i++ ) + { + IMark* pMark = ( pMarkAccess->getMarksBegin() + i )->get(); + + // Only keep the bookmarks starting or ending in this node + if ( pMark->GetMarkStart().nNode == nNd || + pMark->GetMarkEnd().nNode == nNd ) + { + xub_StrLen nBStart = pMark->GetMarkStart().nContent.GetIndex(); + xub_StrLen nBEnd = pMark->GetMarkEnd().nContent.GetIndex(); + + // Keep only the bookmars starting or ending in the snippet + bool bIsStartOk = ( nBStart >= nStt ) && ( nBStart <= nEnd ); + bool bIsEndOk = ( nBEnd >= nStt ) && ( nBEnd <= nEnd ); + + if ( bIsStartOk || bIsEndOk ) + rArr.push_back( pMark ); + } + } + return ( rArr.size() > 0 ); +} + +class CompareMarksEnd : public std::binary_function < const IMark *, const IMark *, bool > +{ +public: + inline bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const + { + xub_StrLen nOEnd = pOneB->GetMarkEnd().nContent.GetIndex(); + xub_StrLen nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex(); + + return nOEnd < nTEnd; + } +}; + +bool DocxExport::NearestBookmark( xub_StrLen& rNearest ) +{ + bool bHasBookmark = false; + + if ( m_rSortedMarksStart.size( ) > 0 ) + { + IMark* pMarkStart = m_rSortedMarksStart.front(); + rNearest = pMarkStart->GetMarkStart().nContent.GetIndex(); + bHasBookmark = true; + } + + if ( m_rSortedMarksEnd.size( ) > 0 ) + { + IMark* pMarkEnd = m_rSortedMarksEnd[0]; + if ( !bHasBookmark ) + rNearest = pMarkEnd->GetMarkEnd().nContent.GetIndex(); + else + rNearest = std::min( rNearest, pMarkEnd->GetMarkEnd().nContent.GetIndex() ); + bHasBookmark = true; + } + + return bHasBookmark; +} + +xub_StrLen DocxExport::GetNextPos( SwAttrIter* pAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos ) +{ + // Get the bookmarks for the normal run + xub_StrLen nNextPos = MSWordExportBase::GetNextPos( pAttrIter, rNode, nAktPos ); + + GetSortedBookmarks( rNode, nAktPos, nNextPos - nAktPos ); + + xub_StrLen nNextBookmark = nNextPos; + NearestBookmark( nNextPos ); + + return std::min( nNextPos, nNextBookmark ); +} + +void DocxExport::UpdatePosition( SwAttrIter* pAttrIter, xub_StrLen nAktPos, xub_StrLen nEnd ) +{ + xub_StrLen nNextPos; + + // either no bookmark, or it is not at the current position + if ( !NearestBookmark( nNextPos ) || nNextPos > nAktPos ) + { + MSWordExportBase::UpdatePosition( pAttrIter, nAktPos, nEnd ); + } +} + +void DocxExport::GetSortedBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen ) +{ + IMarkVector aMarksStart; + if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) ) + { + IMarkVector aSortedEnd; + IMarkVector aSortedStart; + for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = aMarksStart.end(); + it < end; ++it ) + { + IMark* pMark = (*it); + + // Remove the positions egals to the current pos + xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex(); + xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex(); + + if ( nStart > nAktPos ) + aSortedStart.push_back( pMark ); + + if ( nEnd > nAktPos ) + aSortedEnd.push_back( pMark ); + } + + // Sort the bookmarks by end position + std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() ); + + m_rSortedMarksStart.swap( aSortedStart ); + m_rSortedMarksEnd.swap( aSortedEnd ); + } + else + { + m_rSortedMarksStart.clear( ); + m_rSortedMarksEnd.clear( ); + } +} + +void DocxExport::AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen ) +{ + std::vector< OUString > aStarts; + std::vector< OUString > aEnds; + + IMarkVector aMarks; + if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) ) + { + for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end(); + it < end; ++it ) + { + IMark* pMark = (*it); + + xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex(); + xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex(); + + if ( nStart == nAktPos ) + aStarts.push_back( pMark->GetName() ); + + if ( nEnd == nAktPos ) + aEnds.push_back( pMark->GetName() ); + } + } + + m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds ); +} + +void DocxExport::AppendBookmark( const OUString& rName, bool /*bSkip*/ ) +{ + std::vector< OUString > aStarts; + std::vector< OUString > aEnds; + + aStarts.push_back( rName ); + aEnds.push_back( rName ); + + m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds ); +} + +::rtl::OString DocxExport::AddRelation( const OUString& rType, const OUString& rTarget, const OUString& rMode ) +{ + OUString sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + rType, rTarget, rMode ); + + return ::rtl::OUStringToOString( sId, RTL_TEXTENCODING_UTF8 ); +} + +bool DocxExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt ) +{ + bool bRet( false ); + + if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false)) + { + if (const SwFmt *pParent = rFmt.DerivedFrom()) + { + if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle()) + { + ::sax_fastparser::FSHelperPtr pSerializer = m_pAttrOutput->GetSerializer( ); + // Level 9 disables the outline + pSerializer->singleElementNS( XML_w, XML_outlineLvl, + FSNS( XML_w, XML_val ), "9" , + FSEND ); + + bRet = true; + } + } + } + + return bRet; +} + +void DocxExport::WriteHeadersFooters( BYTE nHeadFootFlags, + const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt ) +{ + // headers + if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN ) + WriteHeaderFooter( rLeftFmt, true, "even" ); + + if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD ) + WriteHeaderFooter( rFmt, true, "default" ); + + if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST ) + WriteHeaderFooter( rFirstPageFmt, true, "first" ); + + // footers + if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN ) + WriteHeaderFooter( rLeftFmt, false, "even" ); + + if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD ) + WriteHeaderFooter( rFmt, false, "default" ); + + if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST ) + WriteHeaderFooter( rFirstPageFmt, false, "first" ); +} + +void DocxExport::OutputField( const SwField* pFld, ww::eField eFldType, const String& rFldCmd, BYTE nMode ) +{ + m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode ); +} + +void DocxExport::WriteFormData( const ::sw::mark::IFieldmark& /*rFieldmark*/ ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxExport::WriteFormData()\n" ); +#endif +} + +void DocxExport::DoComboBox(const rtl::OUString& rName, + const rtl::OUString& rHelp, + const rtl::OUString& rToolTip, + const rtl::OUString& rSelected, + uno::Sequence<rtl::OUString>& rListItems) +{ + m_pDocumentFS->startElementNS( XML_w, XML_ffData, FSEND ); + + m_pDocumentFS->singleElementNS( XML_w, XML_name, + FSNS( XML_w, XML_val ), OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); + + m_pDocumentFS->singleElementNS( XML_w, XML_enabled, FSEND ); + + if ( rHelp.getLength( ) > 0 ) + m_pDocumentFS->singleElementNS( XML_w, XML_helpText, + FSNS( XML_w, XML_val ), OUStringToOString( rHelp, RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); + + if ( rToolTip.getLength( ) > 0 ) + m_pDocumentFS->singleElementNS( XML_w, XML_statusText, + FSNS( XML_w, XML_val ), OUStringToOString( rToolTip, RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); + + m_pDocumentFS->startElementNS( XML_w, XML_ddList, FSEND ); + + // Output the 0-based index of the selected value + sal_uInt32 nListItems = rListItems.getLength(); + sal_Int32 nId = 0; + sal_uInt32 nI = 0; + while ( ( nI < nListItems ) && ( nId == 0 ) ) + { + if ( rListItems[nI] == rSelected ) + nId = nI; + nI++; + } + + m_pDocumentFS->singleElementNS( XML_w, XML_result, + FSNS( XML_w, XML_val ), rtl::OString::valueOf( nId ).getStr( ), + FSEND ); + + // Loop over the entries + + for (sal_uInt32 i = 0; i < nListItems; i++) + { + m_pDocumentFS->singleElementNS( XML_w, XML_listEntry, + FSNS( XML_w, XML_val ), OUStringToOString( rListItems[i], RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); + } + + m_pDocumentFS->endElementNS( XML_w, XML_ddList ); + + m_pDocumentFS->endElementNS( XML_w, XML_ffData ); +} + +void DocxExport::DoFormText(const SwInputField* /*pFld*/) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxExport::ForFormText()\n" ); +#endif +} + +void DocxExport::ExportDocument_Impl() +{ + InitStyles(); + + // init sections + m_pSections = new MSWordSections( *this ); + + WriteMainText(); + + WriteFootnotesEndnotes(); + + WriteNumbering(); + + WriteFonts(); + + delete pStyles, pStyles = NULL; + delete m_pSections, m_pSections = NULL; +} + +void DocxExport::OutputPageSectionBreaks( const SwTxtNode& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxExport::OutputPageSectionBreaks( const SwTxtNode& )\n" ); +#endif +} + + +void DocxExport::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum ) +{ + AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() ); + m_pSections->AppendSep( pPageDesc, pFmt, nLnNum ); +} + +void DocxExport::OutputEndNode( const SwEndNode& rEndNode ) +{ + MSWordExportBase::OutputEndNode( rEndNode ); + + if ( TXT_MAINTEXT == nTxtTyp && rEndNode.StartOfSectionNode()->IsSectionNode() ) + { + // this originally comes from WW8Export::WriteText(), and looks like it + // could have some code common with SectionNode()... + + const SwSection& rSect = rEndNode.StartOfSectionNode()->GetSectionNode()->GetSection(); + if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() ) + bStartTOX = false; + + SwNodeIndex aIdx( rEndNode, 1 ); + const SwNode& rNd = aIdx.GetNode(); + if ( rNd.IsEndNode() && rNd.StartOfSectionNode()->IsSectionNode() ) + return; + + if ( !rNd.IsSectionNode() && !bIsInTable ) // No sections in table + { + const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent(); + if( !pParentFmt ) + pParentFmt = (SwSectionFmt*)0xFFFFFFFF; + + ULONG nRstLnNum; + if( rNd.IsCntntNode() ) + nRstLnNum = const_cast< SwCntntNode* >( rNd.GetCntntNode() )->GetSwAttrSet().GetLineNumber().GetStartValue(); + else + nRstLnNum = 0; + + AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo( ) ); + m_pSections->AppendSep( pAktPageDesc, pParentFmt, nRstLnNum ); + } + } +} + +void DocxExport::OutputTableNode( const SwTableNode& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxExport::OutputTableNode( const SwTableNode& )\n" ); +#endif +} + +void DocxExport::OutputGrfNode( const SwGrfNode& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxExport::OutputGrfNode( const SwGrfNode& )\n" ); +#endif +} + +void DocxExport::OutputOLENode( const SwOLENode& ) +{ +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "TODO DocxExport::OutputOLENode( const SwOLENode& )\n" ); +#endif +} + +ULONG DocxExport::ReplaceCr( BYTE ) +{ + // Completely unused for Docx export... only here for code sharing + // purpose with binary export + return 0; +} + +void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet, + const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt, + const SwPageDesc* pNewPgDesc ) +{ + // tell the attribute output that we are ready to write the section + // break [has to be output inside paragraph properties] + AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() ); + + const SwSectionFmt* pFmt = GetSectionFormat( rNd ); + const ULONG nLnNm = GetSectionLineNo( pSet, rNd ); + + ASSERT( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." ); + + if ( pNewPgDescFmt ) + { + m_pSections->AppendSep( *pNewPgDescFmt, rNd, pFmt, nLnNm ); + } + else if ( pNewPgDesc ) + { + m_pSections->AppendSep( pNewPgDesc, rNd, pFmt, nLnNm ); + } + +} + +void DocxExport::InitStyles() +{ + pStyles = new MSWordStyles( *this ); + + // setup word/styles.xml and the relations + content type + m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" ), + S( "styles.xml" ) ); + + ::sax_fastparser::FSHelperPtr pStylesFS = + m_pFilter->openOutputStreamWithSerializer( S( "word/styles.xml" ), + S( "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" ) ); + + // switch the serializer to redirect the output to word/styles.xml + m_pAttrOutput->SetSerializer( pStylesFS ); + + // do the work + pStyles->OutputStylesTable(); + + // switch the serializer back + m_pAttrOutput->SetSerializer( m_pDocumentFS ); +} + +void DocxExport::WriteFootnotesEndnotes() +{ + if ( m_pAttrOutput->HasFootnotes() ) + { + // setup word/styles.xml and the relations + content type + m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" ), + S( "footnotes.xml" ) ); + + ::sax_fastparser::FSHelperPtr pFootnotesFS = + m_pFilter->openOutputStreamWithSerializer( S( "word/footnotes.xml" ), + S( "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" ) ); + + // switch the serializer to redirect the output to word/footnotes.xml + m_pAttrOutput->SetSerializer( pFootnotesFS ); + + // do the work + m_pAttrOutput->FootnotesEndnotes( true ); + + // switch the serializer back + m_pAttrOutput->SetSerializer( m_pDocumentFS ); + } + + if ( m_pAttrOutput->HasEndnotes() ) + { + // setup word/styles.xml and the relations + content type + m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" ), + S( "endnotes.xml" ) ); + + ::sax_fastparser::FSHelperPtr pEndnotesFS = + m_pFilter->openOutputStreamWithSerializer( S( "word/endnotes.xml" ), + S( "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" ) ); + + // switch the serializer to redirect the output to word/endnotes.xml + m_pAttrOutput->SetSerializer( pEndnotesFS ); + + // do the work + m_pAttrOutput->FootnotesEndnotes( false ); + + // switch the serializer back + m_pAttrOutput->SetSerializer( m_pDocumentFS ); + } +} + +void DocxExport::WriteNumbering() +{ + if ( !pUsedNumTbl ) + return; // no numbering is used + + m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" ), + S( "numbering.xml" ) ); + + ::sax_fastparser::FSHelperPtr pNumberingFS = m_pFilter->openOutputStreamWithSerializer( S( "word/numbering.xml" ), + S( "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" ) ); + + // switch the serializer to redirect the output to word/nubering.xml + m_pAttrOutput->SetSerializer( pNumberingFS ); + + pNumberingFS->startElementNS( XML_w, XML_numbering, + FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + FSEND ); + + AbstractNumberingDefinitions(); + + NumberingDefinitions(); + + pNumberingFS->endElementNS( XML_w, XML_numbering ); + + // switch the serializer back + m_pAttrOutput->SetSerializer( m_pDocumentFS ); +} + +void DocxExport::WriteHeaderFooter( const SwFmt& rFmt, bool bHeader, const char* pType ) +{ + // setup the xml stream + OUString aRelId; + ::sax_fastparser::FSHelperPtr pFS; + if ( bHeader ) + { + OUString aName( OUStringBuffer().appendAscii( "header" ).append( ++m_nHeaders ).appendAscii( ".xml" ).makeStringAndClear() ); + + aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" ), + aName ); + + pFS = m_pFilter->openOutputStreamWithSerializer( OUStringBuffer().appendAscii( "word/" ).append( aName ).makeStringAndClear(), + S( "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" ) ); + + pFS->startElementNS( XML_w, XML_hdr, + FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + FSEND ); + } + else + { + OUString aName( OUStringBuffer().appendAscii( "footer" ).append( ++m_nFooters ).appendAscii( ".xml" ).makeStringAndClear() ); + + aRelId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" ), + aName ); + + pFS = m_pFilter->openOutputStreamWithSerializer( OUStringBuffer().appendAscii( "word/" ).append( aName ).makeStringAndClear(), + S( "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" ) ); + + pFS->startElementNS( XML_w, XML_ftr, + FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + FSEND ); + } + + // switch the serializer to redirect the output to word/styles.xml + m_pAttrOutput->SetSerializer( pFS ); + + // do the work + WriteHeaderFooterText( rFmt, bHeader ); + + // switch the serializer back + m_pAttrOutput->SetSerializer( m_pDocumentFS ); + + // close the tag + sal_Int32 nReference; + if ( bHeader ) + { + pFS->endElementNS( XML_w, XML_hdr ); + nReference = XML_headerReference; + } + else + { + pFS->endElementNS( XML_w, XML_ftr ); + nReference = XML_footerReference; + } + + // and write the reference + m_pDocumentFS->singleElementNS( XML_w, nReference, + FSNS( XML_w, XML_type ), pType, + FSNS( XML_r, XML_id ), rtl::OUStringToOString( aRelId, RTL_TEXTENCODING_UTF8 ).getStr(), + FSEND ); +} + +void DocxExport::WriteFonts() +{ + m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), + S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" ), + S( "fontTable.xml" ) ); + + ::sax_fastparser::FSHelperPtr pFS = m_pFilter->openOutputStreamWithSerializer( + S( "word/fontTable.xml" ), + S( "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" ) ); + + pFS->startElementNS( XML_w, XML_fonts, + FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + FSEND ); + + // switch the serializer to redirect the output to word/styles.xml + m_pAttrOutput->SetSerializer( pFS ); + + // do the work + maFontHelper.WriteFontTable( *m_pAttrOutput ); + + // switch the serializer back + m_pAttrOutput->SetSerializer( m_pDocumentFS ); + + pFS->endElementNS( XML_w, XML_fonts ); +} + + +void DocxExport::WriteProperties( ) +{ + // Write the core properties + SwDocShell* pDocShell( pDoc->GetDocShell( ) ); + uno::Reference<document::XDocumentProperties> xDocProps; + if ( pDocShell ) + { + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + pDocShell->GetModel( ), uno::UNO_QUERY ); + xDocProps = xDPS->getDocumentProperties(); + } + + m_pFilter->exportDocumentProperties( xDocProps ); +} + +VMLExport& DocxExport::VMLExporter() +{ + return *m_pVMLExport; +} + +void DocxExport::WriteMainText() +{ + // setup the namespaces + m_pDocumentFS->startElementNS( XML_w, XML_document, + FSNS( XML_xmlns, XML_o ), "urn:schemas-microsoft-com:office:office", + FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships", + FSNS( XML_xmlns, XML_v ), "urn:schemas-microsoft-com:vml", + FSNS( XML_xmlns, XML_w ), "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + FSNS( XML_xmlns, XML_w10 ), "urn:schemas-microsoft-com:office:word", + FSNS( XML_xmlns, XML_wp ), "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", + FSEND ); + + // body + m_pDocumentFS->startElementNS( XML_w, XML_body, FSEND ); + + pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex(); + + // the text + WriteText(); + + // the last section info + const WW8_SepInfo *pSectionInfo = m_pSections? m_pSections->CurrentSectionInfo(): NULL; + if ( pSectionInfo ) + SectionProperties( *pSectionInfo ); + + // finish body and document + m_pDocumentFS->endElementNS( XML_w, XML_body ); + m_pDocumentFS->endElementNS( XML_w, XML_document ); +} + +DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam ) + : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ), + m_pFilter( pFilter ), + m_pAttrOutput( NULL ), + m_pSections( NULL ), + m_nHeaders( 0 ), + m_nFooters( 0 ), + m_pVMLExport( NULL ) +{ + // Write the document properies + WriteProperties( ); + + // relations for the document + m_pFilter->addRelation( S( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ), + S( "word/document.xml" ) ); + + // the actual document + m_pDocumentFS = m_pFilter->openOutputStreamWithSerializer( S( "word/document.xml" ), + S( "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" ) ); + + // the DrawingML access + m_pDrawingML = new oox::drawingml::DrawingML( m_pDocumentFS, m_pFilter, oox::drawingml::DrawingML::DOCUMENT_DOCX ); + + // the attribute output for the document + m_pAttrOutput = new DocxAttributeOutput( *this, m_pDocumentFS, m_pDrawingML ); + + // the related VMLExport + m_pVMLExport = new VMLExport( m_pDocumentFS ); +} + +DocxExport::~DocxExport() +{ + delete m_pVMLExport, m_pVMLExport = NULL; + delete m_pAttrOutput, m_pAttrOutput = NULL; + delete m_pDrawingML, m_pDrawingML = NULL; +} + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx new file mode 100644 index 000000000000..d27eaa4bb2ce --- /dev/null +++ b/sw/source/filter/ww8/docxexport.hxx @@ -0,0 +1,228 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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 _DOCXEXPORT_HXX_ +#define _DOCXEXPORT_HXX_ + +#include "docxattributeoutput.hxx" +#include "wrtww8.hxx" + +#include <sax/fshelper.hxx> +#include <rtl/ustring.hxx> + +#include <cstdio> +#include <vector> + +class DocxExportFilter; +class SwNode; +class SwEndNode; +class SwTableNode; +class SwTxtNode; +class SwGrfNode; +class SwOLENode; +class SwSectionNode; +class SwNumRuleTbl; + +namespace oox { + namespace drawingml { class DrawingML; } + namespace vml { class VMLExport; } +} + +/// The class that does all the actual DOCX export-related work. +class DocxExport : public MSWordExportBase +{ + /// Pointer to the filter that owns us. + DocxExportFilter *m_pFilter; + + /// Fast serializer for the document output. + ::sax_fastparser::FSHelperPtr m_pDocumentFS; + + /// Access to the DrawingML writer. + oox::drawingml::DrawingML *m_pDrawingML; + + /// Attribute output for document. + DocxAttributeOutput *m_pAttrOutput; + + /// Sections/headers/footers + MSWordSections *m_pSections; + + /// Header counter. + sal_Int32 m_nHeaders; + + /// Footer counter. + sal_Int32 m_nFooters; + + /// Used to split the runs according to the bookmarks start and ends + typedef std::vector< ::sw::mark::IMark* > IMarkVector; + IMarkVector m_rSortedMarksStart; + IMarkVector m_rSortedMarksEnd; + + /// Exporter of the VML shapes. + oox::vml::VMLExport *m_pVMLExport; + +public: + /// Access to the attribute output class. + virtual AttributeOutputBase& AttrOutput() const; + + /// Access to the sections/headers/footres. + virtual MSWordSections& Sections() const; + + /// Hack, unfortunately necessary at some places for now. + /// FIXME remove it when possible. + virtual bool HackIsWW8OrHigher() const { return true; } + + /// Guess the script (asian/western). + virtual bool CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich ); + + virtual void AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen ); + + virtual void AppendBookmark( const rtl::OUString& rName, bool bSkip = false ); + + /// Returns the relationd id + rtl::OString AddRelation( const rtl::OUString& rType, const rtl::OUString& rTarget, const rtl::OUString& rMode ); + + virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t()*/ ) { /* FIXME no-op for docx, most probably should not even be in MSWordExportBase */ } + virtual void WriteChar( sal_Unicode ) { /* FIXME */ fprintf( stderr, "HACK! WriteChar() has nothing to do for docx.\n" ); } + + /// Return value indicates if an inherited outline numbering is suppressed. + virtual bool DisallowInheritingOutlineNumbering( const SwFmt &rFmt ); + + /// Output the actual headers and footers. + virtual void WriteHeadersFooters( BYTE nHeadFootFlags, + const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt ); + + /// Write the field + virtual void OutputField( const SwField* pFld, ww::eField eFldType, + const String& rFldCmd, BYTE nMode = nsFieldFlags::WRITEFIELD_ALL ); + + /// Write the data of the form field + virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ); + + virtual void DoComboBox(const rtl::OUString &rName, + const rtl::OUString &rHelp, + const rtl::OUString &ToolTip, + const rtl::OUString &rSelected, + com::sun::star::uno::Sequence<rtl::OUString> &rListItems); + + virtual void DoFormText(const SwInputField * pFld); + + virtual ULONG ReplaceCr( BYTE nChar ); + +protected: + /// Format-dependant part of the actual export. + virtual void ExportDocument_Impl(); + + /// Output page/section breaks + virtual void OutputPageSectionBreaks( const SwTxtNode& ); + + /// Output SwEndNode + virtual void OutputEndNode( const SwEndNode& ); + + /// Output SwTableNode + virtual void OutputTableNode( const SwTableNode& ); + + /// Output SwGrfNode + virtual void OutputGrfNode( const SwGrfNode& ); + + /// Output SwOLENode + virtual void OutputOLENode( const SwOLENode& ); + + + virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum ); + + virtual void SectionBreaksAndFrames( const SwTxtNode& rNode ) {} + + /// Get ready for a new section. + virtual void PrepareNewPageDesc( const SfxItemSet* pSet, + const SwNode& rNd, + const SwFmtPageDesc* pNewPgDescFmt = 0, + const SwPageDesc* pNewPgDesc = 0 ); + + /// Get the next position in the text node to output + virtual xub_StrLen GetNextPos( SwAttrIter* pAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos ); + + /// Update the information for GetNextPos(). + virtual void UpdatePosition( SwAttrIter* pAttrIter, xub_StrLen nAktPos, xub_StrLen nEnd ); + +private: + /// Find the nearest bookmark from the current position. + /// + /// Returns false when there is no bookmark. + bool NearestBookmark( xub_StrLen& rNearest ); + + void GetSortedBookmarks( const SwTxtNode& rNd, xub_StrLen nAktPos, + xub_StrLen nLen ); + + bool GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt, xub_StrLen nEnd, + IMarkVector& rArr ); + + /// Setup pStyles and write styles.xml + void InitStyles(); + + /// Write footnotes.xml and endnotes.xml. + void WriteFootnotesEndnotes(); + + /// Write the numbering table. + virtual void WriteNumbering(); + + /// Write reference to a header/foorter + the actual xml containing the text. + void WriteHeaderFooter( const SwFmt& rFmt, bool bHeader, const char* pType ); + + /// Write word/fontTable.xml. + void WriteFonts(); + + /// Write docProps/core.xml + void WriteProperties(); + +public: + /// FIXME this is temporary, remotely reminding the method of the same + /// name in WW8Export. + void WriteMainText(); + + /// Pass the pDocument, pCurrentPam and pOriginalPam to the base class. + DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, + SwPaM *pCurrentPam, SwPaM *pOriginalPam ); + + /// Destructor. + virtual ~DocxExport(); + + /// Reference to the VMLExport instance for the main document. + oox::vml::VMLExport& VMLExporter(); + +private: + /// No copying. + DocxExport( const DocxExport& ); + + /// No copying. + DocxExport& operator=( const DocxExport& ); +}; + +#endif // _DOCXEXPORT_HXX_ +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxexportfilter.cxx b/sw/source/filter/ww8/docxexportfilter.cxx new file mode 100644 index 000000000000..b09cf8a22b3f --- /dev/null +++ b/sw/source/filter/ww8/docxexportfilter.cxx @@ -0,0 +1,190 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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. + * + ************************************************************************/ + +#include "docxexportfilter.hxx" +#include "docxexport.hxx" + +#include <docsh.hxx> +#include <pam.hxx> +#include <unotxdoc.hxx> + +#include <cppuhelper/factory.hxx> + +using namespace ::comphelper; +using namespace ::com::sun::star; +using ::rtl::OUString; + +#define S( x ) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) ) + +DocxExportFilter::DocxExportFilter( const uno::Reference< lang::XMultiServiceFactory >& rMSF ) + : oox::core::XmlFilterBase( rMSF ) +{ +} + +bool DocxExportFilter::exportDocument() +{ + fprintf( stderr, "DocxExportFilter::exportDocument()\n" ); // DEBUG remove me + + // get SwDoc* + uno::Reference< uno::XInterface > xIfc( getModel(), uno::UNO_QUERY ); + SwXTextDocument *pTxtDoc = dynamic_cast< SwXTextDocument * >( xIfc.get() ); + if ( !pTxtDoc ) + return false; + + SwDoc *pDoc = pTxtDoc->GetDocShell()->GetDoc(); + if ( !pDoc ) + return false; + + // get SwPaM* + // FIXME so far we get SwPaM for the entire document; probably we should + // be able to output just the selection as well - though no idea how to + // get the correct SwPaM* then... + SwPaM aPam( pDoc->GetNodes().GetEndOfContent() ); + aPam.SetMark(); + aPam.Move( fnMoveBackward, fnGoDoc ); + + SwPaM *pCurPam = new SwPaM( *aPam.End(), *aPam.Start() ); + + // export the document + // (in a separate block so that it's destructed before the commit) + { + DocxExport aExport( this, pDoc, pCurPam, &aPam ); + aExport.ExportDocument( true ); // FIXME support exporting selection only + } + + commit(); + + // delete the pCurPam + if ( pCurPam ) + { + while ( pCurPam->GetNext() != pCurPam ) + delete pCurPam->GetNext(); + delete pCurPam; + } + + return true; +} + +////////////////////////////////////////////////////////////////////////// +// UNO stuff so that the filter is registered +////////////////////////////////////////////////////////////////////////// + +#define IMPL_NAME "com.sun.star.comp.Writer.DocxExport" + +OUString DocxExport_getImplementationName() +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPL_NAME ) ); +} + +OUString DocxExportFilter::implGetImplementationName() const +{ + return DocxExport_getImplementationName(); +} + +uno::Sequence< OUString > SAL_CALL DocxExport_getSupportedServiceNames() throw() +{ + const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.ExportFilter" ) ); + const uno::Sequence< OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +uno::Reference< uno::XInterface > SAL_CALL DocxExport_createInstance(const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception ) +{ + return (cppu::OWeakObject*) new DocxExportFilter( rSMgr ); +} + +#ifdef __cplusplus +extern "C" +{ +#endif + +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /* pServiceManager */, void* pRegistryKey ) +{ + sal_Bool bRet = sal_False; + + if( pRegistryKey ) + { + try + { + uno::Reference< registry::XRegistryKey > xNewKey1( + static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey( + OUString::createFromAscii( IMPL_NAME "/UNO/SERVICES/" ) ) ); + xNewKey1->createKey( DocxExport_getSupportedServiceNames().getConstArray()[0] ); + + bRet = sal_True; + } + catch( registry::InvalidRegistryException& ) + { + OSL_ENSURE( sal_False, "### InvalidRegistryException!" ); + } + } + + return bRet; +} + +// ------------------------ +// - component_getFactory - +// ------------------------ + +SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /* pRegistryKey */ ) +{ + uno::Reference< lang::XSingleServiceFactory > xFactory; + void* pRet = 0; + + if ( rtl_str_compare( pImplName, IMPL_NAME ) == 0 ) + { + const OUString aServiceName( OUString::createFromAscii( IMPL_NAME ) ); + + xFactory = uno::Reference< lang::XSingleServiceFactory >( ::cppu::createSingleFactory( + reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ), + DocxExport_getImplementationName(), + DocxExport_createInstance, + DocxExport_getSupportedServiceNames() ) ); + } + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + +#ifdef __cplusplus +} +#endif + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxexportfilter.hxx b/sw/source/filter/ww8/docxexportfilter.hxx new file mode 100644 index 000000000000..19d10260787b --- /dev/null +++ b/sw/source/filter/ww8/docxexportfilter.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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 _DOCXEXPORTFILTER_HXX_ +#define _DOCXEXPORTFILTER_HXX_ + +#include <oox/core/xmlfilterbase.hxx> +#include <oox/drawingml/chart/chartconverter.hxx> +#include <oox/vml/drawing.hxx> + +#include <com/sun/star/beans/PropertyValue.hpp> + +/// The physical access to the DOCX document (for writing). +class DocxExportFilter : public oox::core::XmlFilterBase +{ +public: + DocxExportFilter( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rMSF ); + + // FIXME these should not even exist for the export-only filter! + // For now, let's just do empty implementations of those. + virtual bool importDocument() { return false; } + virtual const ::oox::drawingml::Theme* getCurrentTheme() const { return NULL; } + virtual sal_Int32 getSchemeClr( sal_Int32 ) const { return 0; } + virtual const ::oox::vml::DrawingPtr getDrawings() { return ::oox::vml::DrawingPtr(); } + virtual ::oox::drawingml::chart::ChartConverter& getChartConverter() { static ::oox::drawingml::chart::ChartConverter aConverter; return aConverter; } + virtual const ::oox::drawingml::table::TableStyleListPtr getTableStyles() { return ::oox::drawingml::table::TableStyleListPtr(); } + + // Actual export of the DOCX document + virtual bool exportDocument(); + +private: + + /// Implementatio of the filter abstract method. + virtual ::rtl::OUString implGetImplementationName() const; +}; + +#endif // _DOCXEXPORTFILTER_HXX_ +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxfootnotes.hxx b/sw/source/filter/ww8/docxfootnotes.hxx new file mode 100644 index 000000000000..b885c3fe51e4 --- /dev/null +++ b/sw/source/filter/ww8/docxfootnotes.hxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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 _DOCXFOOTNOTES_HXX_ +#define _DOCXFOOTNOTES_HXX_ + +#include <fmtftn.hxx> + +#include <oox/core/tokens.hxx> +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> +#include <sax/fshelper.hxx> + +#include <vector> + +namespace docx { + +typedef ::std::vector< const SwFmtFtn* > FootnotesVector; + +/** Remember footnotes/endnotes so that we can dump them in one go. + + Also rememeber the last added footnote Id to be able to write it in the + DocxAttributeOutput::EndRunProperties() method. +*/ +class FootnotesList { + /// The current footnote, that was not written yet. + sal_Int32 m_nCurrent; + + /// List of the footnotes. + FootnotesVector m_aFootnotes; + +public: + FootnotesList() : m_nCurrent( -1 ) {} + + void add( const SwFmtFtn& rFootnote ) + { + m_aFootnotes.push_back( &rFootnote ); + m_nCurrent = m_aFootnotes.size() - 1; + } + + /// Return the current footnote/endnote and clear the 'current' state. + const SwFmtFtn* getCurrent( sal_Int32& rId ) + { + // skip ids 0 and 1 - they are reserved for separator and + // continuationSeparator + rId = m_nCurrent + 2; + + // anything to write at all? + if ( m_nCurrent < 0 ) + { + rId = -1; + return NULL; + } + + const SwFmtFtn *pFootnote = m_aFootnotes[m_nCurrent]; + m_nCurrent = -1; + + return pFootnote; + } + + /// Return all the footnotes/endnotes. + const FootnotesVector& getVector() const + { + return m_aFootnotes; + } + + /// Do we have any footnotes/endnotes at all? + bool isEmpty() const + { + return m_aFootnotes.empty(); + } +}; + +} // namespace docx + +#endif // _DOCXFOOTNOTES_HXX_ diff --git a/sw/source/filter/ww8/dump/ww8scan.hxx b/sw/source/filter/ww8/dump/ww8scan.hxx index f6eba4d0ff27..6df865fbfced 100644 --- a/sw/source/filter/ww8/dump/ww8scan.hxx +++ b/sw/source/filter/ww8/dump/ww8scan.hxx @@ -811,7 +811,8 @@ public: - +/** FIB - File Information Block +*/ class WW8Fib { public: @@ -1267,7 +1268,9 @@ public: }; -class WW8Dop // Document Properties +/** Document Properties +*/ +class WW8Dop { public: /* diff --git a/sw/source/filter/ww8/escher.hxx b/sw/source/filter/ww8/escher.hxx index 0ca507f50b46..0fb39dcc7a02 100644 --- a/sw/source/filter/ww8/escher.hxx +++ b/sw/source/filter/ww8/escher.hxx @@ -96,7 +96,7 @@ class SwBasicEscherEx : public EscherEx private: void Init(); protected: - SwWW8Writer& rWrt; + WW8Export& rWrt; SvStream* pEscherStrm; SvStream* pPictStrm; long mnEmuMul, mnEmuDiv; @@ -121,7 +121,7 @@ protected: SdrLayerID GetInvisibleHellId() const; public: - SwBasicEscherEx(SvStream* pStrm, SwWW8Writer& rWrt, UINT32 nDrawings = 1); + SwBasicEscherEx(SvStream* pStrm, WW8Export& rWrt, UINT32 nDrawings = 1); INT32 WriteGrfFlyFrame(const SwFrmFmt& rFmt, UINT32 nShapeId); INT32 WriteOLEFlyFrame(const SwFrmFmt& rFmt, UINT32 nShapeId); void WriteEmptyFlyFrame(const SwFrmFmt& rFmt, UINT32 nShapeId); @@ -161,7 +161,7 @@ private: virtual void SetPicId(const SdrObject &rSdrObj, UINT32 nShapeId, EscherPropertyContainer &rPropOpt); public: - SwEscherEx( SvStream* pStrm, SwWW8Writer& rWW8Wrt ); + SwEscherEx( SvStream* pStrm, WW8Export& rWW8Wrt ); virtual ~SwEscherEx(); void FinishEscher(); virtual void WritePictures(); diff --git a/sw/source/filter/ww8/writerhelper.cxx b/sw/source/filter/ww8/writerhelper.cxx index 6aec829b8649..2ad32c7be689 100644 --- a/sw/source/filter/ww8/writerhelper.cxx +++ b/sw/source/filter/ww8/writerhelper.cxx @@ -164,20 +164,6 @@ namespace return aRet; } - /* - Utility to extract flyfmts from a document, potentially from a - selection, and with bAll off ignores the drawing objects - */ - sw::Frames GetFrames(const SwDoc &rDoc, SwPaM *pPaM, bool /*bAll*/) - { - SwPosFlyFrms aFlys; - rDoc.GetAllFlyFmts(aFlys, pPaM, true); - sw::Frames aRet(SwPosFlyFrmsToFrames(aFlys)); - for (USHORT i = aFlys.Count(); i > 0;) - delete aFlys[--i]; - return aRet; - } - //Utility to test if a frame is anchored at a given node index class anchoredto: public std::unary_function<const sw::Frame&, bool> { @@ -570,14 +556,18 @@ namespace sw } // <-- - Frames GetAllFrames(const SwDoc &rDoc, SwPaM *pPaM) - { - return GetFrames(rDoc, pPaM, true); - } - - Frames GetNonDrawingFrames(const SwDoc &rDoc, SwPaM *pPaM) - { - return GetFrames(rDoc, pPaM, false); + /* + Utility to extract flyfmts from a document, potentially from a + selection. + */ + Frames GetFrames(const SwDoc &rDoc, SwPaM *pPaM /*, bool bAll*/) + { + SwPosFlyFrms aFlys; + rDoc.GetAllFlyFmts(aFlys, pPaM, true); + sw::Frames aRet(SwPosFlyFrmsToFrames(aFlys)); + for (USHORT i = aFlys.Count(); i > 0;) + delete aFlys[--i]; + return aRet; } Frames GetFramesBetweenNodes(const Frames &rFrames, diff --git a/sw/source/filter/ww8/writerhelper.hxx b/sw/source/filter/ww8/writerhelper.hxx index fa8a17fd5312..18e73b1e2d56 100644 --- a/sw/source/filter/ww8/writerhelper.hxx +++ b/sw/source/filter/ww8/writerhelper.hxx @@ -39,13 +39,14 @@ #include <com/sun/star/embed/XEmbeddedObject.hpp> #include <sfx2/objsh.hxx> -# include "types.hxx" -# include <svtools/itempool.hxx> //SfxItemPool -# include <svtools/itemset.hxx> //SfxItemSet -# include <format.hxx> //SwFmt -# include <node.hxx> //SwCntntNode -# include <pam.hxx> //SwPaM -# include <tools/poly.hxx> //Polygon, PolyPolygon +#include "types.hxx" +#include <svtools/itempool.hxx> //SfxItemPool +#include <svtools/itemset.hxx> //SfxItemSet +#include <format.hxx> //SwFmt +#include <node.hxx> //SwCntntNode +#include <pam.hxx> //SwPaM +#include <tools/poly.hxx> //Polygon, PolyPolygon +#include <doc.hxx> //SwDoc //Uncomment to dump debugging streams of graphics #if OSL_DEBUG_LEVEL > 1 @@ -633,8 +634,6 @@ namespace sw need them to have something to be anchored to. So this method returns all the floating elements in a document as a STL container of sw::Frames which are guaranteed to have an appropiate anchor. - This will include drawing objects, use GetNonDrawingFrames if - you are not interested in the drawing objects. @param rDoc The SwDoc document to get the styles from @@ -648,31 +647,7 @@ namespace sw @author <a href="mailto:cmc@openoffice.org">Caolán McNamara</a> */ - Frames GetAllFrames(const SwDoc &rDoc, SwPaM *pPaM = 0); - - /** Get the Floating elements in a SwDoc - - Writer's FrmFmts may or may not be anchored to some text content, - e.g. Page Anchored elements will not be. For the winword export we - need them to have something to be anchored to. So this method - returns all the floating elements in a document as a STL container - of sw::Frames which are guaranteed to have an appropiate anchor. - This will not include drawing objects, use GetAllFrames if you - are interested in the drawing objects. - - @param rDoc - The SwDoc document to get the styles from - - @param pPaM - The SwPam to describe the selection in the document to get the - elements from. 0 means the entire document. - - @return A Frames containing the selections Floating elements - - @author - <a href="mailto:cmc@openoffice.org">Caolán McNamara</a> - */ - Frames GetNonDrawingFrames(const SwDoc &rDoc, SwPaM *pPaM = 0); + Frames GetFrames(const SwDoc &rDoc, SwPaM *pPaM = 0); /** Get the Frames anchored to a given node diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx index 51017f70ec2e..03b4e52c2c6f 100644 --- a/sw/source/filter/ww8/wrtw8esh.cxx +++ b/sw/source/filter/ww8/wrtw8esh.cxx @@ -99,9 +99,8 @@ #include <pagedesc.hxx> #include <ww8par.hxx> #include <breakit.hxx> -#ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_ #include <com/sun/star/i18n/ScriptType.hdl> -#endif +#include "ww8attributeoutput.hxx" #include "writerhelper.hxx" #include "writerwordglue.hxx" #include "wrtww8.hxx" @@ -117,7 +116,7 @@ using namespace sw::types; using namespace nsFieldFlags; //#110185# get a part fix for this type of element -bool SwWW8Writer::MiserableFormFieldExportHack(const SwFrmFmt& rFrmFmt) +bool WW8Export::MiserableFormFieldExportHack(const SwFrmFmt& rFrmFmt) { ASSERT(bWrtWW8, "Not allowed"); if (!bWrtWW8) @@ -149,7 +148,7 @@ bool SwWW8Writer::MiserableFormFieldExportHack(const SwFrmFmt& rFrmFmt) } -void SwWW8Writer::DoComboBox(uno::Reference<beans::XPropertySet> xPropSet) +void WW8Export::DoComboBox(uno::Reference<beans::XPropertySet> xPropSet) { rtl::OUString sSelected; uno::Sequence<rtl::OUString> aListItems; @@ -191,7 +190,7 @@ void SwWW8Writer::DoComboBox(uno::Reference<beans::XPropertySet> xPropSet) DoComboBox(sName, sHelp, sToolTip, sSelected, aListItems); } -void SwWW8Writer::DoComboBox(const rtl::OUString &rName, +void WW8Export::DoComboBox(const rtl::OUString &rName, const rtl::OUString &rHelp, const rtl::OUString &rToolTip, const rtl::OUString &rSelected, @@ -200,7 +199,7 @@ void SwWW8Writer::DoComboBox(const rtl::OUString &rName, ASSERT(bWrtWW8, "Not allowed"); if (!bWrtWW8) return; - OutField(0, ww::eFORMDROPDOWN, FieldString(ww::eFORMDROPDOWN), + OutputField(0, ww::eFORMDROPDOWN, FieldString(ww::eFORMDROPDOWN), WRITEFIELD_START | WRITEFIELD_CMD_START); // write the refence to the "picture" structure ULONG nDataStt = pDataStrm->Tell(); @@ -220,7 +219,7 @@ void SwWW8Writer::DoComboBox(const rtl::OUString &rName, pChpPlc->AppendFkpEntry(Strm().Tell(), sizeof(aArr1), aArr1); - OutField(0, ww::eFORMDROPDOWN, FieldString(ww::eFORMDROPDOWN), + OutputField(0, ww::eFORMDROPDOWN, FieldString(ww::eFORMDROPDOWN), WRITEFIELD_CLOSE); ::sw::WW8FFData aFFData; @@ -240,15 +239,14 @@ void SwWW8Writer::DoComboBox(const rtl::OUString &rName, } aFFData.Write(pDataStrm); - } -void SwWW8Writer::DoCheckBox(uno::Reference<beans::XPropertySet> xPropSet) +void WW8Export::DoCheckBox(uno::Reference<beans::XPropertySet> xPropSet) { uno::Reference<beans::XPropertySetInfo> xPropSetInfo = xPropSet->getPropertySetInfo(); - OutField(0, ww::eFORMCHECKBOX, FieldString(ww::eFORMCHECKBOX), + OutputField(0, ww::eFORMCHECKBOX, FieldString(ww::eFORMCHECKBOX), WRITEFIELD_START | WRITEFIELD_CMD_START); // write the refence to the "picture" structure ULONG nDataStt = pDataStrm->Tell(); @@ -318,12 +316,12 @@ void SwWW8Writer::DoCheckBox(uno::Reference<beans::XPropertySet> xPropSet) aFFData.Write(pDataStrm); - OutField(0, ww::eFORMCHECKBOX, aEmptyStr, WRITEFIELD_CLOSE); + OutputField(0, ww::eFORMCHECKBOX, aEmptyStr, WRITEFIELD_CLOSE); } -void SwWW8Writer::DoFormText(const SwInputField * pFld) +void WW8Export::DoFormText(const SwInputField * pFld) { - OutField(0, ww::eFORMTEXT, FieldString(ww::eFORMTEXT), + OutputField(0, ww::eFORMTEXT, FieldString(ww::eFORMTEXT), WRITEFIELD_START | WRITEFIELD_CMD_START); // write the refence to the "picture" structure ULONG nDataStt = pDataStrm->Tell(); @@ -351,7 +349,7 @@ void SwWW8Writer::DoFormText(const SwInputField * pFld) aFFData.setStatus(pFld->GetToolTip()); aFFData.Write(pDataStrm); - OutField(0, ww::eFORMTEXT, aEmptyStr, WRITEFIELD_CMD_END); + OutputField(0, ww::eFORMTEXT, aEmptyStr, WRITEFIELD_CMD_END); SwWW8Writer::WriteString16(Strm(), pFld->Expand(), false); @@ -366,7 +364,7 @@ void SwWW8Writer::DoFormText(const SwInputField * pFld) pChpPlc->AppendFkpEntry(Strm().Tell(), sizeof( aArr2 ), aArr2 ); - OutField(0, ww::eFORMTEXT, aEmptyStr, WRITEFIELD_CLOSE); + OutputField(0, ww::eFORMTEXT, aEmptyStr, WRITEFIELD_CLOSE); } PlcDrawObj::~PlcDrawObj() @@ -429,7 +427,7 @@ bool RTLDrawingsHack(long &rLeft, long /*nWidth*/, return bRet; } -bool SwWW8Writer::MiserableRTLFrmFmtHack(SwTwips &rLeft, SwTwips &rRight, +bool WW8Export::MiserableRTLFrmFmtHack(SwTwips &rLeft, SwTwips &rRight, const sw::Frame &rFrmFmt) { //Require nasty bidi swap @@ -465,7 +463,7 @@ bool SwWW8Writer::MiserableRTLFrmFmtHack(SwTwips &rLeft, SwTwips &rRight, return bRet; } -void PlcDrawObj::WritePlc(SwWW8Writer& rWrt) const +void PlcDrawObj::WritePlc( WW8Export& rWrt ) const { if (8 > rWrt.pFib->nVersion) // Cannot export drawobject in vers 7- return; @@ -690,8 +688,8 @@ DrawObj& DrawObj::operator=(const DrawObj& rOther) return *this; } -bool PlcDrawObj::Append(SwWW8Writer& rWrt, WW8_CP nCp, const sw::Frame& rFmt, - const Point& rNdTopLeft) +bool PlcDrawObj::Append( WW8Export& rWrt, WW8_CP nCp, const sw::Frame& rFmt, + const Point& rNdTopLeft ) { bool bRet = false; const SwFrmFmt &rFormat = rFmt.GetFrmFmt(); @@ -722,7 +720,7 @@ void DrawObj::SetShapeDetails(UINT32 nId, INT32 nThick) mnThick = nThick; } -bool WW8_WrPlcTxtBoxes::WriteTxt(SwWW8Writer& rWrt) +bool WW8_WrPlcTxtBoxes::WriteTxt( WW8Export& rWrt ) { bool bRet = false; rWrt.bInWriteEscher = true; @@ -756,7 +754,7 @@ const SvULongs* WW8_WrPlcTxtBoxes::GetShapeIdArr() const /* */ -UINT32 SwWW8Writer::GetSdrOrdNum( const SwFrmFmt& rFmt ) const +UINT32 WW8Export::GetSdrOrdNum( const SwFrmFmt& rFmt ) const { UINT32 nOrdNum; const SdrObject* pObj = rFmt.FindRealSdrObject(); @@ -775,7 +773,7 @@ UINT32 SwWW8Writer::GetSdrOrdNum( const SwFrmFmt& rFmt ) const return nOrdNum; } -void SwWW8Writer::AppendFlyInFlys(const sw::Frame& rFrmFmt, +void WW8Export::AppendFlyInFlys(const sw::Frame& rFrmFmt, const Point& rNdTopLeft) { ASSERT(bWrtWW8, "this has gone horribly wrong"); @@ -790,7 +788,7 @@ void SwWW8Writer::AppendFlyInFlys(const sw::Frame& rFrmFmt, if (rFrmFmt.IsInline()) { - OutField(0, ww::eSHAPE, FieldString(ww::eSHAPE), + OutputField(0, ww::eSHAPE, FieldString(ww::eSHAPE), WRITEFIELD_START | WRITEFIELD_CMD_START | WRITEFIELD_CMD_END); } @@ -818,10 +816,10 @@ void SwWW8Writer::AppendFlyInFlys(const sw::Frame& rFrmFmt, } if (rFrmFmt.IsInline()) - OutField(0, ww::eSHAPE, aEmptyStr, WRITEFIELD_CLOSE); + OutputField(0, ww::eSHAPE, aEmptyStr, WRITEFIELD_CLOSE); } -class WW8_SdrAttrIter : public WW8_AttrIter +class WW8_SdrAttrIter : public MSWordAttrIter { private: const EditTextObject* pEditObj; @@ -843,8 +841,8 @@ private: WW8_SdrAttrIter(const WW8_SdrAttrIter&); WW8_SdrAttrIter& operator=(const WW8_SdrAttrIter&); public: - WW8_SdrAttrIter(SwWW8Writer& rWr, const EditTextObject& rEditObj, - BYTE nType); + WW8_SdrAttrIter( WW8Export& rWr, const EditTextObject& rEditObj, + BYTE nType ); void NextPara( USHORT nPar ); void OutParaAttr(bool bCharAttr); void OutEEField(const SfxPoolItem& rHt); @@ -863,9 +861,9 @@ public: }; -WW8_SdrAttrIter::WW8_SdrAttrIter(SwWW8Writer& rWr, - const EditTextObject& rEditObj, BYTE nTyp) - : WW8_AttrIter( rWr ), pEditObj(&rEditObj), pEditPool(0), +WW8_SdrAttrIter::WW8_SdrAttrIter( WW8Export& rWr, + const EditTextObject& rEditObj, BYTE nTyp ) + : MSWordAttrIter( rWr ), pEditObj(&rEditObj), pEditPool(0), aTxtAtrArr( 0, 4 ), aChrTxtAtrArr( 0, 4 ), aChrSetArr( 0, 4 ), mnTyp(nTyp) { @@ -978,16 +976,16 @@ void WW8_SdrAttrIter::OutEEField(const SfxPoolItem& rHt) const SvxFieldData *pFld = rField.GetField(); if (pFld && pFld->ISA(SvxURLField)) { - BYTE nOldTxtTyp = rWrt.nTxtTyp; - rWrt.nTxtTyp = mnTyp; + BYTE nOldTxtTyp = m_rExport.nTxtTyp; + m_rExport.nTxtTyp = mnTyp; const SvxURLField *pURL = (const SvxURLField *)pFld; - StartURL(pURL->GetURL(), pURL->GetTargetFrame()); + m_rExport.AttrOutput().StartURL( pURL->GetURL(), pURL->GetTargetFrame() ); const String &rStr = pURL->GetRepresentation(); - rWrt.OutSwString(rStr, 0, rStr.Len(), true, GetNodeCharSet()); + m_rExport.AttrOutput().RawText( rStr, true, GetNodeCharSet() ); // FIXME kendy: is the 'true' actually correct here? It was here before, but... ;-) - EndURL(); - rWrt.nTxtTyp = nOldTxtTyp; + m_rExport.AttrOutput().EndURL(); + m_rExport.nTxtTyp = nOldTxtTyp; } } @@ -997,15 +995,14 @@ void WW8_SdrAttrIter::OutAttr( xub_StrLen nSwPos ) if( aTxtAtrArr.Count() ) { - const SwModify* pOldMod = rWrt.pOutFmtNode; - rWrt.pOutFmtNode = 0; + const SwModify* pOldMod = m_rExport.pOutFmtNode; + m_rExport.pOutFmtNode = 0; const SfxItemPool* pSrcPool = pEditPool; - const SfxItemPool& rDstPool = rWrt.pDoc->GetAttrPool(); + const SfxItemPool& rDstPool = m_rExport.pDoc->GetAttrPool(); nTmpSwPos = nSwPos; USHORT i, nWhich, nSlotId; - FnAttrOut pOut; for( i = 0; i < aTxtAtrArr.Count(); i++ ) { const EECharAttrib& rHt = aTxtAtrArr[ i ]; @@ -1019,7 +1016,7 @@ void WW8_SdrAttrIter::OutAttr( xub_StrLen nSwPos ) } else if (nWhich == EE_FEATURE_TAB) { - rWrt.WriteChar(0x9); + m_rExport.WriteChar(0x9); continue; } nSlotId = pSrcPool->GetSlotId(nWhich); @@ -1029,16 +1026,13 @@ void WW8_SdrAttrIter::OutAttr( xub_StrLen nSwPos ) nWhich = rDstPool.GetWhich(nSlotId); if (nWhich && nWhich != nSlotId && nWhich < RES_UNKNOWNATR_BEGIN && - 0 != (pOut = aWW8AttrFnTab[nWhich - RES_CHRATR_BEGIN])) + m_rExport.CollapseScriptsforWordOk(nScript,nWhich)) { - if (rWrt.CollapseScriptsforWordOk(nScript,nWhich)) - { - // use always the SW-Which Id ! - SfxPoolItem* pI = rHt.pAttr->Clone(); - pI->SetWhich( nWhich ); - (*pOut)( rWrt, *pI ); - delete pI; - } + // use always the SW-Which Id ! + SfxPoolItem* pI = rHt.pAttr->Clone(); + pI->SetWhich( nWhich ); + m_rExport.AttrOutput().OutputItem( *pI ); + delete pI; } } } @@ -1048,7 +1042,7 @@ void WW8_SdrAttrIter::OutAttr( xub_StrLen nSwPos ) } nTmpSwPos = 0; // HasTextItem nur in dem obigen Bereich erlaubt - rWrt.pOutFmtNode = pOldMod; + m_rExport.pOutFmtNode = pOldMod; } } @@ -1081,7 +1075,7 @@ const SfxPoolItem* WW8_SdrAttrIter::HasTextItem(USHORT nWhich) const { const SfxPoolItem* pRet = 0; nWhich = sw::hack::TransformWhichBetweenPools(*pEditPool, - rWrt.pDoc->GetAttrPool(), nWhich); + m_rExport.pDoc->GetAttrPool(), nWhich); if (nWhich) { for (USHORT i = 0; i < aTxtAtrArr.Count(); ++i) @@ -1109,7 +1103,7 @@ const SfxPoolItem& WW8_SdrAttrIter::GetItem( USHORT nWhich ) const if (!pRet) { SfxItemSet aSet(pEditObj->GetParaAttribs(nPara)); - nWhich = GetSetWhichFromSwDocWhich(aSet, *rWrt.pDoc, nWhich); + nWhich = GetSetWhichFromSwDocWhich(aSet, *m_rExport.pDoc, nWhich); ASSERT(nWhich, "Impossible, catastrophic failure imminent"); pRet = &aSet.Get(nWhich); } @@ -1121,42 +1115,38 @@ void WW8_SdrAttrIter::OutParaAttr(bool bCharAttr) SfxItemSet aSet( pEditObj->GetParaAttribs( nPara )); if( aSet.Count() ) { - const SfxItemSet* pOldSet = rWrt.GetCurItemSet(); - rWrt.SetCurItemSet( &aSet ); + const SfxItemSet* pOldSet = m_rExport.GetCurItemSet(); + m_rExport.SetCurItemSet( &aSet ); SfxItemIter aIter( aSet ); const SfxPoolItem* pItem = aIter.GetCurItem(); - FnAttrOut pOut; const SfxItemPool* pSrcPool = pEditPool, - * pDstPool = &rWrt.pDoc->GetAttrPool(); + * pDstPool = &m_rExport.pDoc->GetAttrPool(); do { - USHORT nWhich = pItem->Which(), - nSlotId = pSrcPool->GetSlotId( nWhich ); - if( nSlotId && nWhich != nSlotId && - 0 != ( nWhich = pDstPool->GetWhich( nSlotId ) ) && - nWhich != nSlotId && - ( bCharAttr ? ( nWhich >= RES_CHRATR_BEGIN - && nWhich < RES_TXTATR_END) - : (nWhich >= RES_PARATR_BEGIN - && nWhich < RES_FRMATR_END) ) && - 0 != ( pOut = aWW8AttrFnTab[ nWhich - RES_CHRATR_BEGIN ] ) ) - { - // use always the SW-Which Id ! - SfxPoolItem* pI = pItem->Clone(); - pI->SetWhich( nWhich ); - if (rWrt.CollapseScriptsforWordOk(nScript,nWhich)) - (*pOut)( rWrt, *pI ); - delete pI; - } - + USHORT nWhich = pItem->Which(), + nSlotId = pSrcPool->GetSlotId( nWhich ); + + if ( nSlotId && nWhich != nSlotId && + 0 != ( nWhich = pDstPool->GetWhich( nSlotId ) ) && + nWhich != nSlotId && + ( bCharAttr ? ( nWhich >= RES_CHRATR_BEGIN && nWhich < RES_TXTATR_END ) + : ( nWhich >= RES_PARATR_BEGIN && nWhich < RES_FRMATR_END ) ) ) + { + // use always the SW-Which Id ! + SfxPoolItem* pI = pItem->Clone(); + pI->SetWhich( nWhich ); + if (m_rExport.CollapseScriptsforWordOk(nScript,nWhich)) + m_rExport.AttrOutput().OutputItem( *pI ); + delete pI; + } } while( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) ); - rWrt.SetCurItemSet( pOldSet ); + m_rExport.SetCurItemSet( pOldSet ); } } -void SwWW8Writer::WriteSdrTextObj(const SdrObject& rObj, BYTE nTyp) +void WW8Export::WriteSdrTextObj(const SdrObject& rObj, BYTE nTyp) { const SdrTextObj* pTxtObj = PTR_CAST(SdrTextObj, &rObj); ASSERT(pTxtObj, "That is no SdrTextObj!"); @@ -1189,7 +1179,7 @@ void SwWW8Writer::WriteSdrTextObj(const SdrObject& rObj, BYTE nTyp) } } -void SwWW8Writer::WriteOutliner(const OutlinerParaObject& rParaObj, BYTE nTyp) +void WW8Export::WriteOutliner(const OutlinerParaObject& rParaObj, BYTE nTyp) { bool bAnyWrite = false; const EditTextObject& rEditObj = rParaObj.GetTextObject(); @@ -1290,7 +1280,7 @@ void WinwordAnchoring::WriteData( EscherEx& rEx ) const /* */ -void SwWW8Writer::CreateEscher() +void WW8Export::CreateEscher() { SfxItemState eBackSet = (const_cast<const SwDoc*>(pDoc))->GetPageDesc(0).GetMaster(). @@ -1304,7 +1294,7 @@ void SwWW8Writer::CreateEscher() } } -void SwWW8Writer::WriteEscher() +void WW8Export::WriteEscher() { if (pEscher) { @@ -1339,7 +1329,7 @@ void SwEscherEx::WritePictures() // Output- Routines for Escher Export -SwBasicEscherEx::SwBasicEscherEx(SvStream* pStrm, SwWW8Writer& rWW8Wrt, +SwBasicEscherEx::SwBasicEscherEx(SvStream* pStrm, WW8Export& rWW8Wrt, UINT32 nDrawings) : EscherEx(*pStrm, nDrawings), rWrt(rWW8Wrt), pEscherStrm(pStrm), pPictStrm(0) @@ -1938,7 +1928,7 @@ void SwBasicEscherEx::WritePictures() } } -SwEscherEx::SwEscherEx(SvStream* pStrm, SwWW8Writer& rWW8Wrt) +SwEscherEx::SwEscherEx(SvStream* pStrm, WW8Export& rWW8Wrt) : SwBasicEscherEx(pStrm, rWW8Wrt, rWW8Wrt.pHFSdrObjs->size() ? 2 : 1), pTxtBxs(0) { @@ -2824,10 +2814,8 @@ UINT32 SwEscherEx::QueryTextID( return nId; } -bool SwMSConvertControls::ExportControl(Writer &rWrt, const SdrObject *pObj) +bool SwMSConvertControls::ExportControl(WW8Export &rWW8Wrt, const SdrObject *pObj) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - if (!rWW8Wrt.bWrtWW8) return false; @@ -2846,7 +2834,7 @@ bool SwMSConvertControls::ExportControl(Writer &rWrt, const SdrObject *pObj) aSize.Height = TWIPS_TO_MM(aRect.Bottom()); //Open the ObjectPool - SvStorageRef xObjPool = rWW8Wrt.GetStorage().OpenSotStorage( + SvStorageRef xObjPool = rWW8Wrt.GetWriter().GetStorage().OpenSotStorage( CREATE_CONST_ASC(SL::aObjectPool), STREAM_READWRITE | STREAM_SHARE_DENYALL); @@ -2879,13 +2867,13 @@ bool SwMSConvertControls::ExportControl(Writer &rWrt, const SdrObject *pObj) sFld += sName; sFld.APPEND_CONST_ASC(".1 \\s "); - rWW8Wrt.OutField(0, ww::eCONTROL, sFld, + rWW8Wrt.OutputField(0, ww::eCONTROL, sFld, WRITEFIELD_START|WRITEFIELD_CMD_START|WRITEFIELD_CMD_END); rWW8Wrt.pChpPlc->AppendFkpEntry(rWW8Wrt.Strm().Tell(),sizeof(aSpecOLE), aSpecOLE); rWW8Wrt.WriteChar( 0x1 ); - rWW8Wrt.OutField(0, ww::eCONTROL, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE); + rWW8Wrt.OutputField(0, ww::eCONTROL, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE); return true; } diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 18d75d5826bf..d42a389e3704 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -32,7 +32,6 @@ #include "precompiled_sw.hxx" /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ - #include <vector> #include <list> #include <utility> @@ -53,9 +52,7 @@ #include <svx/ulspitem.hxx> #include <svx/brkitem.hxx> #include <svx/frmdiritem.hxx> -#ifndef _SVX_TSTPITEM_HXX #include <svx/tstpitem.hxx> -#endif #include "svtools/urihelper.hxx" #include <svtools/whiter.hxx> #include <fmtpdsc.hxx> @@ -93,18 +90,21 @@ #include <txtatr.hxx> #include <fmtsrnd.hxx> #include <fmtrowsplt.hxx> -#ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_ #include <com/sun/star/i18n/ScriptType.hdl> -#endif -#ifndef _COM_SUN_STAR_I18N_WORDTYPE_HDL_ #include <com/sun/star/i18n/WordType.hpp> -#endif + +#include <writerfilter/doctok/sprmids.hxx> + #include "writerhelper.hxx" #include "writerwordglue.hxx" #include <numrule.hxx> #include "wrtww8.hxx" #include "ww8par.hxx" #include <IMark.hxx> +#include "ww8attributeoutput.hxx" + +#include <ndgrf.hxx> +#include <ndole.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::i18n; @@ -114,18 +114,18 @@ using namespace nsFieldFlags; /* */ -WW8_AttrIter::WW8_AttrIter(SwWW8Writer& rWr) - : pOld(rWr.pChpIter), rWrt(rWr) +MSWordAttrIter::MSWordAttrIter( MSWordExportBase& rExport ) + : pOld( rExport.pChpIter ), m_rExport( rExport ) { - rWrt.pChpIter = this; + m_rExport.pChpIter = this; } -WW8_AttrIter::~WW8_AttrIter() +MSWordAttrIter::~MSWordAttrIter() { - rWrt.pChpIter = pOld; + m_rExport.pChpIter = pOld; } -// Die Klasse WW8_SwAttrIter ist eine Hilfe zum Aufbauen der Fkp.chpx. +// Die Klasse SwAttrIter ist eine Hilfe zum Aufbauen der Fkp.chpx. // Dabei werden nur Zeichen-Attribute beachtet; Absatz-Attribute brauchen // diese Behandlung nicht. // Die Absatz- und Textattribute des Writers kommen rein, und es wird @@ -135,7 +135,7 @@ WW8_AttrIter::~WW8_AttrIter() // Mit OutAttr() werden die Attribute an der angegebenen SwPos // ausgegeben. -class WW8_SwAttrIter : public WW8_AttrIter +class SwAttrIter : public MSWordAttrIter { private: const SwTxtNode& rNd; @@ -161,18 +161,15 @@ private: xub_StrLen SearchNext( xub_StrLen nStartPos ); void FieldVanish( const String& rTxt ); - void OutSwFmtINetFmt(const SwFmtINetFmt& rAttr, bool bStart); void OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool bStart); - void OutSwTOXMark(const SwTOXMark& rAttr, bool bStart); - void OutSwFmtRuby(const SwFmtRuby& rRuby, bool bStart); void IterToCurrent(); //No copying - WW8_SwAttrIter(const WW8_SwAttrIter&); - WW8_SwAttrIter& operator=(const WW8_SwAttrIter&); + SwAttrIter(const SwAttrIter&); + SwAttrIter& operator=(const SwAttrIter&); public: - WW8_SwAttrIter( SwWW8Writer& rWr, const SwTxtNode& rNd ); + SwAttrIter( MSWordExportBase& rWr, const SwTxtNode& rNd ); bool IsTxtAttr( xub_StrLen nSwPos ); bool IsRedlineAtEnd( xub_StrLen nPos ) const; @@ -185,7 +182,7 @@ public: virtual const SfxPoolItem* HasTextItem( USHORT nWhich ) const; virtual const SfxPoolItem& GetItem( USHORT nWhich ) const; int OutAttrWithRange(xub_StrLen nPos); - void OutRedlines(xub_StrLen nPos); + const SwRedlineData* GetRedline( xub_StrLen nPos ); void OutFlys(xub_StrLen nSwPos); xub_StrLen WhereNext() const { return nAktSwPos; } @@ -198,24 +195,6 @@ public: const SwFmtDrop& GetSwFmtDrop() const { return mrSwFmtDrop; } }; -void SwWW8Writer::push_charpropstart(xub_StrLen nPos) -{ - maCurrentCharPropStarts.push(nPos); -} - -void SwWW8Writer::pop_charpropstart() -{ - ASSERT(!maCurrentCharPropStarts.empty(), "cannot be empty!"); - if (!maCurrentCharPropStarts.empty()) - maCurrentCharPropStarts.pop(); -} - -xub_StrLen SwWW8Writer::top_charpropstart() const -{ - ASSERT(!maCurrentCharPropStarts.empty(), "cannot be empty!"); - return maCurrentCharPropStarts.empty() ? 0 : maCurrentCharPropStarts.top(); -} - class sortswflys : public std::binary_function<const sw::Frame&, const sw::Frame&, bool> { @@ -226,7 +205,7 @@ public: } }; -void WW8_SwAttrIter::IterToCurrent() +void SwAttrIter::IterToCurrent() { ASSERT(maCharRuns.begin() != maCharRuns.end(), "Impossible"); mnScript = maCharRunIter->mnScript; @@ -234,10 +213,10 @@ void WW8_SwAttrIter::IterToCurrent() mbCharIsRTL = maCharRunIter->mbRTL; } -WW8_SwAttrIter::WW8_SwAttrIter(SwWW8Writer& rWr, const SwTxtNode& rTxtNd) : - WW8_AttrIter(rWr), +SwAttrIter::SwAttrIter(MSWordExportBase& rWr, const SwTxtNode& rTxtNd) : + MSWordAttrIter(rWr), rNd(rTxtNd), - maCharRuns(GetPseudoCharRuns(rTxtNd, 0, !rWr.bWrtWW8)), + maCharRuns(GetPseudoCharRuns(rTxtNd, 0, !rWr.HackIsWW8OrHigher())), pCurRedline(0), nAktSwPos(0), nCurRedlinePos(USHRT_MAX), @@ -260,14 +239,13 @@ WW8_SwAttrIter::WW8_SwAttrIter(SwWW8Writer& rWr, const SwTxtNode& rTxtNd) : maFlyFrms = GetFramesInNode(rWr.maFrames, rNd); std::sort(maFlyFrms.begin(), maFlyFrms.end(), sortswflys()); - /* #i18480# If we are inside a frame then anything anchored inside this frame can only be supported by word anchored inline ("as character"), so force this in the supportable case. */ - if (rWr.bWrtWW8 && rWr.bInWriteEscher) + if (rWr.HackIsWW8OrHigher() && rWr.bInWriteEscher) { std::for_each(maFlyFrms.begin(), maFlyFrms.end(), std::mem_fun_ref(&sw::Frame::ForceTreatAsInline)); @@ -275,16 +253,16 @@ WW8_SwAttrIter::WW8_SwAttrIter(SwWW8Writer& rWr, const SwTxtNode& rTxtNd) : maFlyIter = maFlyFrms.begin(); - if (rWrt.pDoc->GetRedlineTbl().Count()) + if ( m_rExport.pDoc->GetRedlineTbl().Count() ) { SwPosition aPosition( rNd, SwIndex( (SwTxtNode*)&rNd ) ); - pCurRedline = rWrt.pDoc->GetRedline( aPosition, &nCurRedlinePos ); + pCurRedline = m_rExport.pDoc->GetRedline( aPosition, &nCurRedlinePos ); } nAktSwPos = SearchNext(1); } -xub_StrLen WW8_SwAttrIter::SearchNext( xub_StrLen nStartPos ) +xub_StrLen SwAttrIter::SearchNext( xub_StrLen nStartPos ) { xub_StrLen nPos; xub_StrLen nMinPos = STRING_MAXLEN; @@ -309,16 +287,16 @@ xub_StrLen WW8_SwAttrIter::SearchNext( xub_StrLen nStartPos ) nMinPos = i; } - if( nCurRedlinePos < rWrt.pDoc->GetRedlineTbl().Count() ) + if ( nCurRedlinePos < m_rExport.pDoc->GetRedlineTbl().Count() ) { // nCurRedlinePos point to the next redline nPos = nCurRedlinePos; if( pCurRedline ) ++nPos; - for( ; nPos < rWrt.pDoc->GetRedlineTbl().Count(); ++nPos ) + for ( ; nPos < m_rExport.pDoc->GetRedlineTbl().Count(); ++nPos ) { - const SwRedline* pRedl = rWrt.pDoc->GetRedlineTbl()[ nPos ]; + const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nPos ]; const SwPosition* pStt = pRedl->Start(); const SwPosition* pEnd = pStt == pRedl->GetPoint() @@ -417,28 +395,16 @@ xub_StrLen WW8_SwAttrIter::SearchNext( xub_StrLen nStartPos ) return nMinPos; } -void WW8_SwAttrIter::OutAttr(xub_StrLen nSwPos) +void SwAttrIter::OutAttr( xub_StrLen nSwPos ) { - if (rWrt.bWrtWW8 && IsCharRTL()) - { - rWrt.InsUInt16(0x85a); - rWrt.pO->Insert((BYTE)1, rWrt.pO->Count()); - } - - // #i46087# patch from james_clark; complex texts needs the undocumented SPRM 0x0882 with param 0x81. - if (rWrt.bWrtWW8 && GetScript() == i18n::ScriptType::COMPLEX && !IsCharRTL()) - { - rWrt.InsUInt16(0x882); - rWrt.pO->Insert((BYTE)0x81, rWrt.pO->Count()); - rWrt.pDop->bUseThaiLineBreakingRules=true; - } + m_rExport.AttrOutput().RTLAndCJKState( IsCharRTL(), GetScript() ); /* Depending on whether text is in CTL/CJK or Western, get the id of that script, the idea is that the font that is actually in use to render this range of text ends up in pFont */ - sal_uInt16 nFontId = GetWhichOfScript(RES_CHRATR_FONT, GetScript()); + sal_uInt16 nFontId = GetWhichOfScript( RES_CHRATR_FONT, GetScript() ); const SvxFontItem &rParentFont = ItemGet<SvxFontItem>( (const SwTxtFmtColl&)rNd.GetAnyFmtColl(), nFontId); @@ -508,34 +474,34 @@ void WW8_SwAttrIter::OutAttr(xub_StrLen nSwPos) this for us like writer does */ const SwFmtCharFmt *pCharFmtItem = - HasItem<SwFmtCharFmt>(aRangeItems, RES_TXTATR_CHARFMT); - if (pCharFmtItem) - ClearOverridesFromSet(*pCharFmtItem, aExportSet); + HasItem< SwFmtCharFmt >( aRangeItems, RES_TXTATR_CHARFMT ); + if ( pCharFmtItem ) + ClearOverridesFromSet( *pCharFmtItem, aExportSet ); sw::PoolItems aExportItems; - GetPoolItems(aExportSet, aExportItems); + GetPoolItems( aExportSet, aExportItems ); sw::cPoolItemIter aEnd = aRangeItems.end(); - for (sw::cPoolItemIter aI = aRangeItems.begin(); aI != aEnd; ++aI) + for ( sw::cPoolItemIter aI = aRangeItems.begin(); aI != aEnd; ++aI ) aExportItems[aI->first] = aI->second; - if (!aExportItems.empty()) + if ( !aExportItems.empty() ) { - const SwModify* pOldMod = rWrt.pOutFmtNode; - rWrt.pOutFmtNode = &rNd; - rWrt.push_charpropstart(nSwPos); + const SwModify* pOldMod = m_rExport.pOutFmtNode; + m_rExport.pOutFmtNode = &rNd; + m_rExport.m_aCurrentCharPropStarts.push( nSwPos ); - rWrt.ExportPoolItemsToCHP(aExportItems, GetScript()); + m_rExport.ExportPoolItemsToCHP( aExportItems, GetScript() ); // HasTextItem nur in dem obigen Bereich erlaubt - rWrt.pop_charpropstart(); - rWrt.pOutFmtNode = pOldMod; + m_rExport.m_aCurrentCharPropStarts.pop(); + m_rExport.pOutFmtNode = pOldMod; } - ASSERT(pFont, "must be *some* font associated with this txtnode"); - if (pFont) + ASSERT( pFont, "must be *some* font associated with this txtnode" ); + if ( pFont ) { - SvxFontItem aFont(*pFont); + SvxFontItem aFont( *pFont ); /* If we are a nonunicode aware format then we set the charset we want to @@ -547,40 +513,37 @@ void WW8_SwAttrIter::OutAttr(xub_StrLen nSwPos) this makes older nonunicode aware versions of word display the correct characters. */ - if (!rWrt.bWrtWW8) + if ( !m_rExport.HackIsWW8OrHigher() ) aFont.GetCharSet() = GetCharSet(); - if (rParentFont != aFont) - Out(aWW8AttrFnTab, aFont, rWrt); + if ( rParentFont != aFont ) + m_rExport.AttrOutput().OutputItem( aFont ); } - - OutRedlines(nSwPos); } -void WW8_SwAttrIter::OutFlys(xub_StrLen nSwPos) +void SwAttrIter::OutFlys(xub_StrLen nSwPos) { /* #i2916# May have an anchored graphic to be placed, loop through sorted array and output all at this position */ - while (maFlyIter != maFlyFrms.end()) + while ( maFlyIter != maFlyFrms.end() ) { const SwPosition &rAnchor = maFlyIter->GetPosition(); xub_StrLen nPos = rAnchor.nContent.GetIndex(); - if (nPos != nSwPos) + if ( nPos != nSwPos ) break; else { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - rWrtWW8.OutFlyFrm(*maFlyIter); + m_rExport.AttrOutput().OutputFlyFrame( *maFlyIter ); ++maFlyIter; } } } -bool WW8_SwAttrIter::IsTxtAttr( xub_StrLen nSwPos ) +bool SwAttrIter::IsTxtAttr( xub_StrLen nSwPos ) { // search for attrs without end position if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints()) @@ -596,7 +559,7 @@ bool WW8_SwAttrIter::IsTxtAttr( xub_StrLen nSwPos ) return false; } -bool WW8_SwAttrIter::IsDropCap( int nSwPos ) +bool SwAttrIter::IsDropCap( int nSwPos ) { // see if the current position falls on a DropCap int nDropChars = mrSwFmtDrop.GetChars(); @@ -615,14 +578,14 @@ bool WW8_SwAttrIter::IsDropCap( int nSwPos ) return false; } -bool WW8_SwAttrIter::RequiresImplicitBookmark() +bool SwAttrIter::RequiresImplicitBookmark() { - SwImplBookmarksIter bkmkIterEnd = rWrt.maImplicitBookmarks.end(); - for (SwImplBookmarksIter aIter = rWrt.maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter) + SwImplBookmarksIter bkmkIterEnd = m_rExport.maImplicitBookmarks.end(); + for ( SwImplBookmarksIter aIter = m_rExport.maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter ) { ULONG sample = aIter->second; - if(sample == rNd.GetIndex()) + if ( sample == rNd.GetIndex() ) return true; } return false; @@ -634,11 +597,11 @@ bool WW8_SwAttrIter::RequiresImplicitBookmark() // Attribut-Anfangposition fragen kann. // Es koennen nur Attribute mit Ende abgefragt werden. // Es wird mit bDeep gesucht -const SfxPoolItem* WW8_SwAttrIter::HasTextItem( USHORT nWhich ) const +const SfxPoolItem* SwAttrIter::HasTextItem( USHORT nWhich ) const { const SfxPoolItem* pRet = 0; const SwpHints* pTxtAttrs = rNd.GetpSwpHints(); - xub_StrLen nTmpSwPos = rWrt.top_charpropstart(); + xub_StrLen nTmpSwPos = m_rExport.m_aCurrentCharPropStarts.top(); if (pTxtAttrs) { for (USHORT i = 0; i < pTxtAttrs->Count(); ++i) @@ -660,162 +623,152 @@ const SfxPoolItem* WW8_SwAttrIter::HasTextItem( USHORT nWhich ) const return pRet; } -void SwWW8Writer::GetCurrentItems(WW8Bytes& rItems) const +void WW8Export::GetCurrentItems(WW8Bytes& rItems) const { USHORT nEnd = pO ? pO->Count() : 0; for (USHORT nI = 0; nI < nEnd; ++nI) rItems.Insert((*pO)[nI], rItems.Count()); } -const SfxPoolItem& WW8_SwAttrIter::GetItem(USHORT nWhich) const +const SfxPoolItem& SwAttrIter::GetItem(USHORT nWhich) const { const SfxPoolItem* pRet = HasTextItem(nWhich); return pRet ? *pRet : rNd.SwCntntNode::GetAttr(nWhich); } -void WW8_SwAttrIter::OutSwFmtRuby(const SwFmtRuby& rRuby, bool bStart) +void WW8AttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby ) { - if (bStart) - { - String aStr(FieldString(ww::eEQ)); - aStr.APPEND_CONST_ASC("\\* jc"); - sal_Int32 nJC=0; - sal_Char cDirective=0; - switch(rRuby.GetAdjustment()) - { - case 0: - nJC = 3; - cDirective = 'l'; - break; - case 1: - //defaults to 0 - break; - case 2: - nJC = 4; - cDirective = 'r'; - break; - case 3: - nJC = 1; - cDirective = 'd'; - break; - case 4: - nJC = 2; - cDirective = 'd'; - break; - default: - ASSERT(!this,"Unhandled Ruby justication code"); - break; - } - aStr += String::CreateFromInt32(nJC); - - /* - MS needs to know the name and size of the font used in the ruby item, - but we coud have written it in a mixture of asian and western - scripts, and each of these can be a different font and size than the - other, so we make a guess based upon the first character of the text, - defaulting to asian. - */ - USHORT nRubyScript; - if( pBreakIt->xBreak.is() ) - nRubyScript = pBreakIt->xBreak->getScriptType( rRuby.GetText(), 0); - else - nRubyScript = i18n::ScriptType::ASIAN; - - const SwTxtRuby* pRubyTxt = rRuby.GetTxtRuby(); - const SwCharFmt* pFmt = pRubyTxt ? pRubyTxt->GetCharFmt() : 0; - String sFamilyName; - long nHeight; - if (pFmt) - { - const SvxFontItem &rFont = ItemGet<SvxFontItem>(*pFmt, - GetWhichOfScript(RES_CHRATR_FONT,nRubyScript)); - sFamilyName = rFont.GetFamilyName(); + String aStr( FieldString( ww::eEQ ) ); + aStr.APPEND_CONST_ASC( "\\* jc" ); + sal_Int32 nJC = 0; + sal_Char cDirective = 0; + switch ( rRuby.GetAdjustment() ) + { + case 0: + nJC = 3; + cDirective = 'l'; + break; + case 1: + //defaults to 0 + break; + case 2: + nJC = 4; + cDirective = 'r'; + break; + case 3: + nJC = 1; + cDirective = 'd'; + break; + case 4: + nJC = 2; + cDirective = 'd'; + break; + default: + ASSERT( !this,"Unhandled Ruby justication code" ); + break; + } + aStr += String::CreateFromInt32( nJC ); - const SvxFontHeightItem &rHeight = ItemGet<SvxFontHeightItem>(*pFmt, - GetWhichOfScript(RES_CHRATR_FONTSIZE,nRubyScript)); - nHeight = rHeight.GetHeight(); - } - else - { - /*Get defaults if no formatting on ruby text*/ + /* + MS needs to know the name and size of the font used in the ruby item, + but we coud have written it in a mixture of asian and western + scripts, and each of these can be a different font and size than the + other, so we make a guess based upon the first character of the text, + defaulting to asian. + */ + USHORT nRubyScript; + if ( pBreakIt->xBreak.is() ) + nRubyScript = pBreakIt->xBreak->getScriptType( rRuby.GetText(), 0); + else + nRubyScript = i18n::ScriptType::ASIAN; - const SfxItemPool *pPool = rNd.GetSwAttrSet().GetPool(); - const SfxItemPool &rPool = - pPool ? *pPool : rWrt.pDoc->GetAttrPool(); + const SwTxtRuby* pRubyTxt = rRuby.GetTxtRuby(); + const SwCharFmt* pFmt = pRubyTxt ? pRubyTxt->GetCharFmt() : 0; + String sFamilyName; + long nHeight; + if ( pFmt ) + { + const SvxFontItem &rFont = ItemGet< SvxFontItem >( *pFmt, + GetWhichOfScript(RES_CHRATR_FONT,nRubyScript) ); + sFamilyName = rFont.GetFamilyName(); - const SvxFontItem &rFont = DefaultItemGet<SvxFontItem>(rPool, - GetWhichOfScript(RES_CHRATR_FONT,nRubyScript)); - sFamilyName = rFont.GetFamilyName(); + const SvxFontHeightItem &rHeight = ItemGet< SvxFontHeightItem >( *pFmt, + GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) ); + nHeight = rHeight.GetHeight(); + } + else + { + /*Get defaults if no formatting on ruby text*/ - const SvxFontHeightItem &rHeight = DefaultItemGet<SvxFontHeightItem> - (rPool, GetWhichOfScript(RES_CHRATR_FONTSIZE,nRubyScript)); - nHeight = rHeight.GetHeight(); - } - nHeight = (nHeight + 5)/10; - - aStr.APPEND_CONST_ASC(" \\* \"Font:"); - aStr.Append(sFamilyName); - aStr.APPEND_CONST_ASC("\" \\* hps"); - aStr += String::CreateFromInt32(nHeight); - aStr.APPEND_CONST_ASC(" \\o"); - if (cDirective) - { - aStr.APPEND_CONST_ASC("\\a"); - aStr.Append(cDirective); - } - aStr.APPEND_CONST_ASC("(\\s\\up "); + const SfxItemPool *pPool = rNode.GetSwAttrSet().GetPool(); + const SfxItemPool &rPool = pPool ? *pPool : m_rWW8Export.pDoc->GetAttrPool(); + const SvxFontItem &rFont = DefaultItemGet< SvxFontItem >( rPool, + GetWhichOfScript( RES_CHRATR_FONT,nRubyScript ) ); + sFamilyName = rFont.GetFamilyName(); - if( pBreakIt->xBreak.is() ) - nRubyScript = pBreakIt->xBreak->getScriptType( rNd.GetTxt(), - *(pRubyTxt->GetStart())); - else - nRubyScript = i18n::ScriptType::ASIAN; - - const SwAttrSet& rSet = rNd.GetSwAttrSet(); - const SvxFontHeightItem &rHeightItem = - (const SvxFontHeightItem&)rSet.Get( - GetWhichOfScript(RES_CHRATR_FONTSIZE,nRubyScript)); - nHeight = (rHeightItem.GetHeight() + 10)/20-1; - aStr += String::CreateFromInt32(nHeight); - aStr += '('; - aStr += rRuby.GetText(); - aStr.APPEND_CONST_ASC(");"); - rWrt.OutField(0, ww::eEQ, aStr, - WRITEFIELD_START | WRITEFIELD_CMD_START); + const SvxFontHeightItem &rHeight = DefaultItemGet< SvxFontHeightItem > + ( rPool, GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) ); + nHeight = rHeight.GetHeight(); } - else + nHeight = (nHeight + 5)/10; + + aStr.APPEND_CONST_ASC( " \\* \"Font:" ); + aStr.Append( sFamilyName ); + aStr.APPEND_CONST_ASC( "\" \\* hps" ); + aStr += String::CreateFromInt32( nHeight ); + aStr.APPEND_CONST_ASC( " \\o" ); + if ( cDirective ) { - rWrt.WriteChar(')'); - rWrt.OutField(0, ww::eEQ, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE); + aStr.APPEND_CONST_ASC( "\\a" ); + aStr.Append( cDirective ); } + aStr.APPEND_CONST_ASC( "(\\s\\up " ); + + + if ( pBreakIt->xBreak.is() ) + nRubyScript = pBreakIt->xBreak->getScriptType( rNode.GetTxt(), + *( pRubyTxt->GetStart() ) ); + else + nRubyScript = i18n::ScriptType::ASIAN; + + const SwAttrSet& rSet = rNode.GetSwAttrSet(); + const SvxFontHeightItem &rHeightItem = + ( const SvxFontHeightItem& )rSet.Get( + GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) ); + nHeight = (rHeightItem.GetHeight() + 10)/20-1; + aStr += String::CreateFromInt32(nHeight); + aStr += '('; + aStr += rRuby.GetText(); + aStr.APPEND_CONST_ASC( ");" ); + m_rWW8Export.OutputField( 0, ww::eEQ, aStr, + WRITEFIELD_START | WRITEFIELD_CMD_START ); } -void WW8_SwAttrIter::OutSwFmtINetFmt(const SwFmtINetFmt& rINet, bool bStart) +void WW8AttributeOutput::EndRuby() { - if( bStart ) - StartURL(rINet.GetValue(), rINet.GetTargetFrame()); - else - EndURL(); + m_rWW8Export.WriteChar( ')' ); + m_rWW8Export.OutputField( 0, ww::eEQ, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE ); } /*#i15387# Better ideas welcome*/ -String &TruncateBookmark(String &rRet) +String &TruncateBookmark( String &rRet ) { - if (rRet.Len() > 40) - rRet.Erase(40); - ASSERT(rRet.Len() <= 40, "Word cannot have bookmarks longer than 40 chars"); + if ( rRet.Len() > 40 ) + rRet.Erase( 40 ); + ASSERT( rRet.Len() <= 40, "Word cannot have bookmarks longer than 40 chars" ); return rRet; } -void WW8_AttrIter::StartURL(const String &rUrl, const String &rTarget) +bool AttributeOutputBase::AnalyzeURL( const String& rUrl, const String& /*rTarget*/, String* pLinkURL, String* pMark ) { bool bBookMarkOnly = false; - INetURLObject aURL(rUrl); - String sURL; + + INetURLObject aURL( rUrl ); String sMark; + String sURL; - if (rUrl.Len() > 1 && rUrl.GetChar(0) == INET_MARK_TOKEN) + if ( rUrl.Len() > 1 && rUrl.GetChar(0) == INET_MARK_TOKEN ) { sMark = BookmarkToWriter( rUrl.Copy(1) ); @@ -825,58 +778,92 @@ void WW8_AttrIter::StartURL(const String &rUrl, const String &rTarget) sRefType.EraseAllChars(); // i21465 Only interested in outline references - if(sRefType.EqualsAscii( pMarkToOutline ) ) + if ( sRefType.EqualsAscii( pMarkToOutline ) ) { String sLink = sMark.Copy(0, nPos); - SwImplBookmarksIter bkmkIterEnd = rWrt.maImplicitBookmarks.end(); - for (SwImplBookmarksIter aIter = rWrt.maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter) + SwImplBookmarksIter bkmkIterEnd = GetExport().maImplicitBookmarks.end(); + for ( SwImplBookmarksIter aIter = GetExport().maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter ) { String bkmkName = aIter->first; - if(bkmkName == sLink) + if ( bkmkName == sLink ) { - sMark = String(RTL_CONSTASCII_STRINGPARAM("_toc")); - sMark += String::CreateFromInt32(aIter->second); + sMark = String( RTL_CONSTASCII_STRINGPARAM( "_toc" ) ); + sMark += String::CreateFromInt32( aIter->second ); } } } } else { - sURL = aURL.GetURLNoMark(INetURLObject::DECODE_UNAMBIGUOUS); - sMark = aURL.GetMark(INetURLObject::DECODE_UNAMBIGUOUS); + sURL = aURL.GetURLNoMark( INetURLObject::DECODE_UNAMBIGUOUS ); + sMark = aURL.GetMark( INetURLObject::DECODE_UNAMBIGUOUS ); - sURL = URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), - sURL); } - if (sMark.Len() && !sURL.Len()) + if ( sMark.Len() && !sURL.Len() ) bBookMarkOnly = true; - if (bBookMarkOnly) - sURL = FieldString(ww::eHYPERLINK); + + + *pMark = sMark; + *pLinkURL = sURL; + return bBookMarkOnly; +} + +bool WW8AttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark ) +{ + bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark ); + + String sURL = *pLinkURL; + String sMark = *pMark; + + if ( sURL.Len() ) + sURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), sURL ); + + if ( bBookMarkOnly ) + sURL = FieldString( ww::eHYPERLINK ); else { - String sFld(FieldString(ww::eHYPERLINK)); - sFld.APPEND_CONST_ASC("\""); - sURL.Insert(sFld, 0); + String sFld( FieldString( ww::eHYPERLINK ) ); + sFld.APPEND_CONST_ASC( "\"" ); + sURL.Insert( sFld, 0 ); sURL += '\"'; } - if (sMark.Len()) - (( sURL.APPEND_CONST_ASC(" \\l \"") ) += sMark) += '\"'; + if ( sMark.Len() ) + ( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"'; + + if ( rTarget.Len() ) + ( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget; + + *pLinkURL = sURL; + *pMark = sMark; + + return bBookMarkOnly; +} + +bool WW8AttributeOutput::StartURL( const String &rUrl, const String &rTarget ) +{ + // hyperlinks only in WW8 + if ( !m_rWW8Export.bWrtWW8 ) + return false; + + INetURLObject aURL( rUrl ); + String sURL; + String sMark; + + bool bBookMarkOnly = AnalyzeURL( rUrl, rTarget, &sURL, &sMark ); - if (rTarget.Len()) - (sURL.APPEND_CONST_ASC(" \\n ")) += rTarget; - rWrt.OutField(0, ww::eHYPERLINK, sURL, WRITEFIELD_START | WRITEFIELD_CMD_START); + m_rWW8Export.OutputField( 0, ww::eHYPERLINK, sURL, WRITEFIELD_START | WRITEFIELD_CMD_START ); // write the refence to the "picture" structure - ULONG nDataStt = rWrt.pDataStrm->Tell(); - rWrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell() ); + ULONG nDataStt = m_rWW8Export.pDataStrm->Tell(); + m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() ); // WinWord 2000 doesn't write this - so its a temp solution by W97 ? - rWrt.WriteChar( 0x01 ); + m_rWW8Export.WriteChar( 0x01 ); static BYTE aArr1[] = { 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation @@ -888,9 +875,9 @@ void WW8_AttrIter::StartURL(const String &rUrl, const String &rTarget) BYTE* pDataAdr = aArr1 + 2; Set_UInt32( pDataAdr, nDataStt ); - rWrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), sizeof( aArr1 ), aArr1 ); + m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), sizeof( aArr1 ), aArr1 ); - rWrt.OutField(0, ww::eHYPERLINK, sURL, WRITEFIELD_CMD_END); + m_rWW8Export.OutputField( 0, ww::eHYPERLINK, sURL, WRITEFIELD_CMD_END ); // now write the picture structur sURL = aURL.GetURLNoMark(); @@ -913,22 +900,24 @@ void WW8_AttrIter::StartURL(const String &rUrl, const String &rTarget) 0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B }; - rWrt.pDataStrm->Write( aURLData1, sizeof(aURLData1) ); - BYTE nAnchor=0x00; - if( sMark.Len() ) - nAnchor=0x08; - rWrt.pDataStrm->Write( &nAnchor, 1 ); - rWrt.pDataStrm->Write( MAGIC_A, sizeof(MAGIC_A) ); - SwWW8Writer::WriteLong( *rWrt.pDataStrm, 0x00000002); + m_rWW8Export.pDataStrm->Write( aURLData1, sizeof( aURLData1 ) ); + BYTE nAnchor = 0x00; + if ( sMark.Len() ) + nAnchor = 0x08; + m_rWW8Export.pDataStrm->Write( &nAnchor, 1 ); + m_rWW8Export.pDataStrm->Write( MAGIC_A, sizeof(MAGIC_A) ); + SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 0x00000002); UINT32 nFlag = bBookMarkOnly ? 0 : 0x01; - if (bAbsolute) nFlag |= 0x02; - if( sMark.Len() ) nFlag |= 0x08; - SwWW8Writer::WriteLong( *rWrt.pDataStrm, nFlag ); + if ( bAbsolute ) + nFlag |= 0x02; + if ( sMark.Len() ) + nFlag |= 0x08; + SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, nFlag ); INetProtocol eProto = aURL.GetProtocol(); - if (eProto == INET_PROT_FILE) + if ( eProto == INET_PROT_FILE ) { -// version 1 (for a document) + // version 1 (for a document) static BYTE __READONLY_DATA MAGIC_C[] = { 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -943,7 +932,7 @@ void WW8_AttrIter::StartURL(const String &rUrl, const String &rTarget) }; // save the links to files as relative - sURL = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), sURL ); + sURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), sURL ); if ( sURL.EqualsAscii( "/", 0, 1 ) ) sURL = aURL.PathToFileName(); @@ -958,18 +947,18 @@ void WW8_AttrIter::StartURL(const String &rUrl, const String &rTarget) sURL.SearchAndReplaceAll( '/', '\\' ); } - rWrt.pDataStrm->Write( MAGIC_C, sizeof(MAGIC_C) ); - SwWW8Writer::WriteLong( *rWrt.pDataStrm, sURL.Len()+1 ); - SwWW8Writer::WriteString8( *rWrt.pDataStrm, sURL, true, + m_rWW8Export.pDataStrm->Write( MAGIC_C, sizeof(MAGIC_C) ); + SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sURL.Len()+1 ); + SwWW8Writer::WriteString8( *m_rWW8Export.pDataStrm, sURL, true, RTL_TEXTENCODING_MS_1252 ); - rWrt.pDataStrm->Write( MAGIC_D, sizeof( MAGIC_D) ); + m_rWW8Export.pDataStrm->Write( MAGIC_D, sizeof( MAGIC_D ) ); - SwWW8Writer::WriteLong( *rWrt.pDataStrm, 2*sURL.Len()+6); - SwWW8Writer::WriteLong( *rWrt.pDataStrm, 2*sURL.Len()); - SwWW8Writer::WriteShort( *rWrt.pDataStrm, 3 ); - SwWW8Writer::WriteString16(*rWrt.pDataStrm, sURL, false); + SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.Len() + 6 ); + SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.Len() ); + SwWW8Writer::WriteShort( *m_rWW8Export.pDataStrm, 3 ); + SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sURL, false ); } - else if (eProto != INET_PROT_NOT_VALID) + else if ( eProto != INET_PROT_NOT_VALID ) { // version 2 (simple url) // an write some data to the data stream, but dont ask @@ -981,23 +970,31 @@ void WW8_AttrIter::StartURL(const String &rUrl, const String &rTarget) 0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B }; - rWrt.pDataStrm->Write( MAGIC_B, sizeof(MAGIC_B) ); - SwWW8Writer::WriteLong( *rWrt.pDataStrm, 2 * (sURL.Len()+1) ); - SwWW8Writer::WriteString16( *rWrt.pDataStrm, sURL, true); + m_rWW8Export.pDataStrm->Write( MAGIC_B, sizeof(MAGIC_B) ); + SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2 * ( sURL.Len() + 1 ) ); + SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sURL, true ); } - if (sMark.Len()) + if ( sMark.Len() ) { - SwWW8Writer::WriteLong( *rWrt.pDataStrm, sMark.Len()+1 ); - SwWW8Writer::WriteString16( *rWrt.pDataStrm, sMark, true); + SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sMark.Len()+1 ); + SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sMark, true ); } - SwWW8Writer::WriteLong( *rWrt.pDataStrm, nDataStt, - rWrt.pDataStrm->Tell() - nDataStt ); + SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, nDataStt, + m_rWW8Export.pDataStrm->Tell() - nDataStt ); + + return true; } -void WW8_AttrIter::EndURL() +bool WW8AttributeOutput::EndURL() { - rWrt.OutField(0, ww::eHYPERLINK, aEmptyStr, WRITEFIELD_CLOSE); + // hyperlinks only in WW8 + if ( !m_rWW8Export.bWrtWW8 ) + return false; + + m_rWW8Export.OutputField( 0, ww::eHYPERLINK, aEmptyStr, WRITEFIELD_CLOSE ); + + return true; } String BookmarkToWord(const String &rBookmark) @@ -1014,21 +1011,21 @@ String BookmarkToWriter(const String &rBookmark) INetURLObject::DECODE_UNAMBIGUOUS, RTL_TEXTENCODING_ASCII_US); } -void WW8_SwAttrIter::OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool) +void SwAttrIter::OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool) { - if( rWrt.HasRefToObject( REF_SETREFATTR, &rAttr.GetRefName(), 0 )) - rWrt.AppendBookmark( rWrt.GetBookmarkName( REF_SETREFATTR, + if ( m_rExport.HasRefToObject( REF_SETREFATTR, &rAttr.GetRefName(), 0 ) ) + m_rExport.AppendBookmark( m_rExport.GetBookmarkName( REF_SETREFATTR, &rAttr.GetRefName(), 0 )); } -void WW8_SwAttrIter::FieldVanish( const String& rTxt ) +void WW8AttributeOutput::FieldVanish( const String& rTxt, ww::eField /*eType*/ ) { WW8Bytes aItems; - rWrt.GetCurrentItems(aItems); + m_rWW8Export.GetCurrentItems( aItems ); // sprmCFFldVanish - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( aItems, 0x802 ); + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFFldVanish ); else aItems.Insert( 67, aItems.Count() ); aItems.Insert( 1, aItems.Count() ); @@ -1036,158 +1033,153 @@ void WW8_SwAttrIter::FieldVanish( const String& rTxt ) USHORT nStt_sprmCFSpec = aItems.Count(); // sprmCFSpec -- fSpec-Attribut true - if( rWrt.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) SwWW8Writer::InsUInt16( aItems, 0x855 ); else aItems.Insert( 117, aItems.Count() ); aItems.Insert( 1, aItems.Count() ); - rWrt.WriteChar( '\x13' ); - rWrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), aItems.Count(), + m_rWW8Export.WriteChar( '\x13' ); + m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.Count(), aItems.GetData() ); - rWrt.OutSwString( rTxt, 0, rTxt.Len(), rWrt.IsUnicode(), + m_rWW8Export.OutSwString( rTxt, 0, rTxt.Len(), m_rWW8Export.IsUnicode(), RTL_TEXTENCODING_MS_1252 ); - rWrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), nStt_sprmCFSpec, + m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), nStt_sprmCFSpec, aItems.GetData() ); - rWrt.WriteChar( '\x15' ); - rWrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), aItems.Count(), + m_rWW8Export.WriteChar( '\x15' ); + m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.Count(), aItems.GetData() ); } -void WW8_SwAttrIter::OutSwTOXMark(const SwTOXMark& rAttr, - bool -#ifndef PRODUCT - bStart -#endif - ) +void AttributeOutputBase::TOXMark( const SwTxtNode& rNode, const SwTOXMark& rAttr ) { // its a field; so get the Text form the Node and build the field -#ifndef PRODUCT - ASSERT( bStart, "calls only with the startposition!" ); -#endif String sTxt; + ww::eField eType = ww::eNONE; const SwTxtTOXMark& rTxtTOXMark = *rAttr.GetTxtTOXMark(); const xub_StrLen* pTxtEnd = rTxtTOXMark.GetEnd(); - if( pTxtEnd ) // has range? - sTxt = rNd.GetExpandTxt( *rTxtTOXMark.GetStart(), - *pTxtEnd - *rTxtTOXMark.GetStart() ); + if ( pTxtEnd ) // has range? + { + sTxt = rNode.GetExpandTxt( *rTxtTOXMark.GetStart(), + *pTxtEnd - *rTxtTOXMark.GetStart() ); + } else sTxt = rAttr.GetAlternativeText(); - switch( rAttr.GetTOXType()->GetType() ) + switch ( rAttr.GetTOXType()->GetType() ) { - case TOX_INDEX: - if( rAttr.GetPrimaryKey().Len() ) - { - if ( rAttr.GetSecondaryKey( ).Len( ) ) + case TOX_INDEX: + eType = ww::eXE; + if ( rAttr.GetPrimaryKey().Len() ) { + if ( rAttr.GetSecondaryKey().Len() ) + { + sTxt.Insert( ':', 0 ); + sTxt.Insert( rAttr.GetSecondaryKey(), 0 ); + } + sTxt.Insert( ':', 0 ); - sTxt.Insert( rAttr.GetSecondaryKey(), 0 ); + sTxt.Insert( rAttr.GetPrimaryKey(), 0 ); } + sTxt.InsertAscii( " XE \"", 0 ); + sTxt.InsertAscii( "\" " ); + break; - sTxt.Insert( ':', 0 ); - sTxt.Insert( rAttr.GetPrimaryKey(), 0 ); - } - sTxt.InsertAscii( " XE \"", 0 ); - sTxt.InsertAscii( "\" " ); - break; - - case TOX_USER: - ( sTxt.APPEND_CONST_ASC( "\" \\f \"" )) - += (sal_Char)( 'A' + rWrt.GetId( *rAttr.GetTOXType() )); - // kein break; - case TOX_CONTENT: - { - sTxt.InsertAscii( " TC \"", 0 ); - USHORT nLvl = rAttr.GetLevel(); - if (nLvl > WW8ListManager::nMaxLevel) - nLvl = WW8ListManager::nMaxLevel; - - ((sTxt.APPEND_CONST_ASC( "\" \\l " )) - += String::CreateFromInt32( nLvl )) += ' '; - } - break; - default: - ASSERT(!this, "Unhandled option for toc export"); - break; + case TOX_USER: + ( sTxt.APPEND_CONST_ASC( "\" \\f \"" ) ) + += (sal_Char)( 'A' + GetExport( ).GetId( *rAttr.GetTOXType() ) ); + // fall through - no break; + case TOX_CONTENT: + { + eType = ww::eTC; + sTxt.InsertAscii( " TC \"", 0 ); + USHORT nLvl = rAttr.GetLevel(); + if (nLvl > WW8ListManager::nMaxLevel) + nLvl = WW8ListManager::nMaxLevel; + + ((sTxt.APPEND_CONST_ASC( "\" \\l " )) + += String::CreateFromInt32( nLvl )) += ' '; + } + break; + default: + ASSERT( !this, "Unhandled option for toc export" ); + break; } - if( sTxt.Len() ) - FieldVanish( sTxt ); + if ( sTxt.Len() ) + FieldVanish( sTxt, eType ); } -int WW8_SwAttrIter::OutAttrWithRange(xub_StrLen nPos) +int SwAttrIter::OutAttrWithRange(xub_StrLen nPos) { int nRet = 0; - if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints()) + if ( const SwpHints* pTxtAttrs = rNd.GetpSwpHints() ) { - rWrt.push_charpropstart(nPos); + m_rExport.m_aCurrentCharPropStarts.push( nPos ); const xub_StrLen* pEnd; - for (USHORT i = 0; i < pTxtAttrs->Count(); ++i ) + for ( USHORT i = 0; i < pTxtAttrs->Count(); ++i ) { const SwTxtAttr* pHt = (*pTxtAttrs)[i]; const SfxPoolItem* pItem = &pHt->GetAttr(); - switch( pItem->Which() ) + switch ( pItem->Which() ) { - case RES_TXTATR_INETFMT: - if( rWrt.bWrtWW8 ) // nur WW8 kann Hyperlinks - { - if( nPos == *pHt->GetStart() ) + case RES_TXTATR_INETFMT: + if ( nPos == *pHt->GetStart() ) + { + const SwFmtINetFmt *rINet = static_cast< const SwFmtINetFmt* >( pItem ); + if ( m_rExport.AttrOutput().StartURL( rINet->GetValue(), rINet->GetTargetFrame() ) ) + ++nRet; + } + if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd ) { - OutSwFmtINetFmt((SwFmtINetFmt&)*pItem, true); + if ( m_rExport.AttrOutput().EndURL() ) + --nRet; + } + break; + case RES_TXTATR_REFMARK: + if ( nPos == *pHt->GetStart() ) + { + OutSwFmtRefMark( *static_cast< const SwFmtRefMark* >( pItem ), true ); ++nRet; } - if( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd ) + if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd ) { - OutSwFmtINetFmt((SwFmtINetFmt&)*pItem, false); + OutSwFmtRefMark( *static_cast< const SwFmtRefMark* >( pItem ), false ); --nRet; } - } - break; - case RES_TXTATR_REFMARK: - if( nPos == *pHt->GetStart() ) - { - OutSwFmtRefMark((SwFmtRefMark&)*pItem, true); - ++nRet; - } - if( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd ) - { - OutSwFmtRefMark((SwFmtRefMark&)*pItem, false); - --nRet; - } - break; - case RES_TXTATR_TOXMARK: - if (nPos == *pHt->GetStart()) - OutSwTOXMark((SwTOXMark&)*pItem, true); - break; - case RES_TXTATR_CJK_RUBY: - if( nPos == *pHt->GetStart() ) - { - OutSwFmtRuby((SwFmtRuby&)*pItem, true); - ++nRet; - } - if( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd ) - { - OutSwFmtRuby((SwFmtRuby&)*pItem, false); - --nRet; - } - break; + break; + case RES_TXTATR_TOXMARK: + if ( nPos == *pHt->GetStart() ) + m_rExport.AttrOutput().TOXMark( rNd, *static_cast< const SwTOXMark* >( pItem ) ); + break; + case RES_TXTATR_CJK_RUBY: + if ( nPos == *pHt->GetStart() ) + { + m_rExport.AttrOutput().StartRuby( rNd, *static_cast< const SwFmtRuby* >( pItem ) ); + ++nRet; + } + if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd ) + { + m_rExport.AttrOutput().EndRuby(); + --nRet; + } + break; } } - rWrt.pop_charpropstart();//HasTextItem nur in dem obigen Bereich erlaubt + m_rExport.m_aCurrentCharPropStarts.pop(); // HasTextItem nur in dem obigen Bereich erlaubt } return nRet; } -bool WW8_SwAttrIter::IsRedlineAtEnd( xub_StrLen nEnd ) const +bool SwAttrIter::IsRedlineAtEnd( xub_StrLen nEnd ) const { bool bRet = false; // search next Redline for( USHORT nPos = nCurRedlinePos; - nPos < rWrt.pDoc->GetRedlineTbl().Count(); ++nPos ) + nPos < m_rExport.pDoc->GetRedlineTbl().Count(); ++nPos ) { - const SwPosition* pEnd = rWrt.pDoc->GetRedlineTbl()[ nPos ]->End(); + const SwPosition* pEnd = m_rExport.pDoc->GetRedlineTbl()[ nPos ]->End(); if( pEnd->nNode == rNd ) { if( pEnd->nContent.GetIndex() == nEnd ) @@ -1202,7 +1194,7 @@ bool WW8_SwAttrIter::IsRedlineAtEnd( xub_StrLen nEnd ) const return bRet; } -void WW8_SwAttrIter::OutRedlines( xub_StrLen nPos ) +const SwRedlineData* SwAttrIter::GetRedline( xub_StrLen nPos ) { if( pCurRedline ) { @@ -1214,17 +1206,19 @@ void WW8_SwAttrIter::OutRedlines( xub_StrLen nPos ) ++nCurRedlinePos; } else + { // write data of current redline - rWrt.OutRedline( pCurRedline->GetRedlineData() ); + return &( pCurRedline->GetRedlineData() ); + } } if( !pCurRedline ) { // search next Redline - for( ; nCurRedlinePos < rWrt.pDoc->GetRedlineTbl().Count(); + for( ; nCurRedlinePos < m_rExport.pDoc->GetRedlineTbl().Count(); ++nCurRedlinePos ) { - const SwRedline* pRedl = rWrt.pDoc->GetRedlineTbl()[ nCurRedlinePos ]; + const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nCurRedlinePos ]; const SwPosition* pStt = pRedl->Start(); const SwPosition* pEnd = pStt == pRedl->GetPoint() @@ -1239,7 +1233,7 @@ void WW8_SwAttrIter::OutRedlines( xub_StrLen nPos ) { // write data of this redline pCurRedline = pRedl; - rWrt.OutRedline( pCurRedline->GetRedlineData() ); + return &( pCurRedline->GetRedlineData() ); } break; } @@ -1255,34 +1249,62 @@ void WW8_SwAttrIter::OutRedlines( xub_StrLen nPos ) } } } + return NULL; } /* */ -short SwWW8Writer::GetCurrentPageDirection() const +short MSWordExportBase::GetCurrentPageDirection() const { const SwFrmFmt &rFmt = pAktPageDesc ? pAktPageDesc->GetMaster() - : const_cast<const SwDoc *>(pDoc)->GetPageDesc(0).GetMaster(); + : const_cast<const SwDoc *>( pDoc )->GetPageDesc( 0 ).GetMaster(); return rFmt.GetFrmDir().GetValue(); } -short SwWW8Writer::TrueFrameDirection(const SwFrmFmt &rFlyFmt) const +short MSWordExportBase::GetDefaultFrameDirection( ) const +{ + short nDir = FRMDIR_ENVIRONMENT; + + if ( bOutPageDescs ) + nDir = GetCurrentPageDirection( ); + else if ( pOutFmtNode ) + { + if ( bOutFlyFrmAttrs ) //frame + { + nDir = TrueFrameDirection( *( const SwFrmFmt * ) pOutFmtNode ); + } + else if ( pOutFmtNode->ISA( SwCntntNode ) ) //pagagraph + { + const SwCntntNode *pNd = ( const SwCntntNode * ) pOutFmtNode; + SwPosition aPos( *pNd ); + nDir = pDoc->GetTextDirection( aPos ); + } + else if ( pOutFmtNode->ISA( SwTxtFmtColl ) ) + nDir = FRMDIR_HORI_LEFT_TOP; //what else can we do :-( + } + + if ( nDir == FRMDIR_ENVIRONMENT ) + nDir = FRMDIR_HORI_LEFT_TOP; //Set something + + return nDir; +} + +short MSWordExportBase::TrueFrameDirection( const SwFrmFmt &rFlyFmt ) const { const SwFrmFmt *pFlyFmt = &rFlyFmt; const SvxFrameDirectionItem* pItem = 0; - while (pFlyFmt) + while ( pFlyFmt ) { pItem = &pFlyFmt->GetFrmDir(); - if (FRMDIR_ENVIRONMENT == pItem->GetValue()) + if ( FRMDIR_ENVIRONMENT == pItem->GetValue() ) { pItem = 0; const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor(); - if (FLY_PAGE != pAnchor->GetAnchorId() && - pAnchor->GetCntntAnchor()) + if ( FLY_PAGE != pAnchor->GetAnchorId() && + pAnchor->GetCntntAnchor() ) { - pFlyFmt = - pAnchor->GetCntntAnchor()->nNode.GetNode().GetFlyFmt(); + pFlyFmt = pAnchor->GetCntntAnchor()->nNode.GetNode().GetFlyFmt(); } else pFlyFmt = 0; @@ -1292,16 +1314,16 @@ short SwWW8Writer::TrueFrameDirection(const SwFrmFmt &rFlyFmt) const } short nRet; - if (pItem) + if ( pItem ) nRet = pItem->GetValue(); else nRet = GetCurrentPageDirection(); - ASSERT(nRet != FRMDIR_ENVIRONMENT, "leaving with environment direction"); + ASSERT( nRet != FRMDIR_ENVIRONMENT, "leaving with environment direction" ); return nRet; } -const SvxBrushItem* SwWW8Writer::GetCurrentPageBgBrush() const +const SvxBrushItem* WW8Export::GetCurrentPageBgBrush() const { const SwFrmFmt &rFmt = pAktPageDesc ? pAktPageDesc->GetMaster() @@ -1320,7 +1342,7 @@ const SvxBrushItem* SwWW8Writer::GetCurrentPageBgBrush() const return pRet; } -SvxBrushItem SwWW8Writer::TrueFrameBgBrush(const SwFrmFmt &rFlyFmt) const +SvxBrushItem WW8Export::TrueFrameBgBrush(const SwFrmFmt &rFlyFmt) const { const SwFrmFmt *pFlyFmt = &rFlyFmt; const SvxBrushItem* pRet = 0; @@ -1367,7 +1389,7 @@ Convert characters that need to be converted, the basic replacements and the ridicously complicated title case attribute mapping to hardcoded upper case because word doesn't have the feature */ -String WW8_SwAttrIter::GetSnippet(const String &rStr, xub_StrLen nAktPos, +String SwAttrIter::GetSnippet(const String &rStr, xub_StrLen nAktPos, xub_StrLen nLen) const { String aSnippet(rStr, nAktPos, nLen); @@ -1381,7 +1403,7 @@ String WW8_SwAttrIter::GetSnippet(const String &rStr, xub_StrLen nAktPos, aSnippet.SearchAndReplaceAll(CHAR_HARDHYPHEN, 0x1e); aSnippet.SearchAndReplaceAll(CHAR_SOFTHYPHEN, 0x1f); - rWrt.push_charpropstart(nAktPos); + m_rExport.m_aCurrentCharPropStarts.push( nAktPos ); const SfxPoolItem &rItem = GetItem(RES_CHRATR_CASEMAP); if (SVX_CASEMAP_TITEL == ((const SvxCaseMapItem&)rItem).GetValue()) @@ -1420,7 +1442,7 @@ String WW8_SwAttrIter::GetSnippet(const String &rStr, xub_StrLen nAktPos, aSnippet.SetChar(0, rStr.GetChar(nAktPos)); } } - rWrt.pop_charpropstart(); + m_rExport.m_aCurrentCharPropStarts.pop(); return aSnippet; } @@ -1431,14 +1453,13 @@ String WW8_SwAttrIter::GetSnippet(const String &rStr, xub_StrLen nAktPos, the track changes have to be analysed. A deletion, starting in paragraph A with style A, ending in paragraph B with style B, needs a hack. */ - -SwTxtFmtColl& lcl_getFormatCollection( Writer& rWrt, SwTxtNode* pTxtNode ) +static SwTxtFmtColl& lcl_getFormatCollection( MSWordExportBase& rExport, const SwTxtNode* pTxtNode ) { USHORT nPos = 0; - USHORT nMax = rWrt.pDoc->GetRedlineTbl().Count(); + USHORT nMax = rExport.pDoc->GetRedlineTbl().Count(); while( nPos < nMax ) { - const SwRedline* pRedl = rWrt.pDoc->GetRedlineTbl()[ nPos++ ]; + const SwRedline* pRedl = rExport.pDoc->GetRedlineTbl()[ nPos++ ]; const SwPosition* pStt = pRedl->Start(); const SwPosition* pEnd = pStt == pRedl->GetPoint() ? pRedl->GetMark() @@ -1456,47 +1477,162 @@ SwTxtFmtColl& lcl_getFormatCollection( Writer& rWrt, SwTxtNode* pTxtNode ) return static_cast<SwTxtFmtColl&>( pTxtNode->GetAnyFmtColl() ); } -Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) +void WW8AttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop &rSwFmtDrop, USHORT nStyle, + ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) { + short nDropLines = rSwFmtDrop.GetLines(); + short nDistance = rSwFmtDrop.GetDistance(); + int rFontHeight, rDropHeight, rDropDescent; + + SVBT16 nSty; + ShortToSVBT16( nStyle, nSty ); + m_rWW8Export.pO->Insert( (BYTE*)&nSty, 2, m_rWW8Export.pO->Count() ); // Style # + + if ( m_rWW8Export.bWrtWW8 ) + { + m_rWW8Export.InsUInt16( NS_sprm::LN_PPc ); // Alignment (sprmPPc) + m_rWW8Export.pO->Insert( 0x20, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( NS_sprm::LN_PWr ); // Wrapping (sprmPWr) + m_rWW8Export.pO->Insert( 0x02, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( NS_sprm::LN_PDcs ); // Dropcap (sprmPDcs) + int nDCS = ( nDropLines << 3 ) | 0x01; + m_rWW8Export.InsUInt16( static_cast< UINT16 >( nDCS ) ); + + m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaFromText ); // Distance from text (sprmPDxaFromText) + m_rWW8Export.InsUInt16( nDistance ); + + if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) ) + { + m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaLine ); // Line spacing + m_rWW8Export.InsUInt16( static_cast< UINT16 >( -rDropHeight ) ); + m_rWW8Export.InsUInt16( 0 ); + } + } + else + { + m_rWW8Export.pO->Insert( 29, m_rWW8Export.pO->Count() ); // Alignment (sprmPPc) + m_rWW8Export.pO->Insert( 0x20, m_rWW8Export.pO->Count() ); + + m_rWW8Export.pO->Insert( 37, m_rWW8Export.pO->Count() ); // Wrapping (sprmPWr) + m_rWW8Export.pO->Insert( 0x02, m_rWW8Export.pO->Count() ); + + m_rWW8Export.pO->Insert( 46, m_rWW8Export.pO->Count() ); // Dropcap (sprmPDcs) + int nDCS = ( nDropLines << 3 ) | 0x01; + m_rWW8Export.InsUInt16( static_cast< UINT16 >( nDCS ) ); + + m_rWW8Export.pO->Insert( 49, m_rWW8Export.pO->Count() ); // Distance from text (sprmPDxaFromText) + m_rWW8Export.InsUInt16( nDistance ); + + if (rNode.GetDropSize(rFontHeight, rDropHeight, rDropDescent)) + { + m_rWW8Export.pO->Insert( 20, m_rWW8Export.pO->Count() ); // Line spacing + m_rWW8Export.InsUInt16( static_cast< UINT16 >( -rDropHeight ) ); + m_rWW8Export.InsUInt16( 0 ); + } + } + + m_rWW8Export.WriteCR( pTextNodeInfoInner ); + + if ( pTextNodeInfo.get() != NULL ) + { #ifdef DEBUG - ::std::clog << "<OutWW8_SwTxtNode>" << ::std::endl; + ::std::clog << pTextNodeInfo->toString() << ::std::endl; #endif - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - SwTxtNode* pNd = &((SwTxtNode&)rNode); + TableInfoCell( pTextNodeInfoInner ); + } - bool bFlyInTable = rWW8Wrt.mpParentFrame && rWW8Wrt.bIsInTable; + m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() ); + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); - // akt. Style - if( !bFlyInTable ) + if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) ) { - rWW8Wrt.nStyleBeforeFly - = rWW8Wrt.GetId( lcl_getFormatCollection( rWrt, pNd ) ); + if ( m_rWW8Export.bWrtWW8 ) + { + const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt(); + if ( pSwCharFmt ) + { + m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd ); + m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pSwCharFmt ) ); + } + + m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsPos ); // Lower the chars + m_rWW8Export.InsUInt16( static_cast< UINT16 >( -((nDropLines - 1)*rDropDescent) / 10 ) ); + + m_rWW8Export.InsUInt16( NS_sprm::LN_CHps ); // Font Size + m_rWW8Export.InsUInt16( static_cast< UINT16 >( rFontHeight / 10 ) ); + } + else + { + const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt(); + if ( pSwCharFmt ) + { + m_rWW8Export.InsUInt16( 80 ); + m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pSwCharFmt ) ); + } + + m_rWW8Export.pO->Insert( 101, m_rWW8Export.pO->Count() ); // Lower the chars + m_rWW8Export.InsUInt16( static_cast< UINT16 >( -((nDropLines - 1)*rDropDescent) / 10 ) ); + + m_rWW8Export.pO->Insert( 99, m_rWW8Export.pO->Count() ); // Font Size + m_rWW8Export.InsUInt16( static_cast< UINT16 >( rFontHeight / 10 ) ); + } } - SVBT16 nSty; - ShortToSVBT16( rWW8Wrt.nStyleBeforeFly, nSty ); + m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() ); + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); +} - WW8Bytes* pO = rWW8Wrt.pO; - WW8_SwAttrIter aAttrIter( rWW8Wrt, *pNd ); +xub_StrLen MSWordExportBase::GetNextPos( SwAttrIter* aAttrIter, const SwTxtNode& /*rNode*/, xub_StrLen /*nAktPos*/ ) +{ + return aAttrIter->WhereNext(); +} + +void MSWordExportBase::UpdatePosition( SwAttrIter* aAttrIter, xub_StrLen /*nAktPos*/, xub_StrLen /*nEnd*/ ) +{ + aAttrIter->NextPos(); +} + +void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) +{ +#ifdef DEBUG + ::std::clog << "<OutWW8_SwTxtNode>" << ::std::endl; +#endif + + ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo( mpTableInfo->getTableNodeInfo( &rNode ) ); + + AttrOutput().StartParagraph( pTextNodeInfo ); + + bool bFlyInTable = mpParentFrame && bIsInTable; + + if ( !bFlyInTable ) + nStyleBeforeFly = GetId( lcl_getFormatCollection( *this, &rNode ) ); + + // nStyleBeforeFly may change when we recurse into another node, so we + // have to remember it in nStyle + USHORT nStyle = nStyleBeforeFly; + + SwAttrIter aAttrIter( *this, rNode ); rtl_TextEncoding eChrSet = aAttrIter.GetCharSet(); - if( rWW8Wrt.bStartTOX ) + if ( bStartTOX ) { // ignore TOX header section const SwSectionNode* pSectNd = rNode.FindSectionNode(); - if( TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() ) + if ( pSectNd && TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() ) { - rWW8Wrt.StartTOX( pSectNd->GetSection() ); - rWW8Wrt.push_charpropstart(0); + AttrOutput().StartTOX( pSectNd->GetSection() ); + m_aCurrentCharPropStarts.push( 0 ); } } const SwSection* pTOXSect = 0; - if( rWW8Wrt.bInWriteTOX ) + if( bInWriteTOX ) { // check for end of TOX - SwNodeIndex aIdx( *pNd, 1 ); + SwNodeIndex aIdx( rNode, 1 ); if( !aIdx.GetNode().IsTxtNode() ) { const SwSectionNode* pTOXSectNd = rNode.FindSectionNode(); @@ -1508,349 +1644,221 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) } } - if (aAttrIter.RequiresImplicitBookmark()) + if ( aAttrIter.RequiresImplicitBookmark() ) { - String sBkmkName = String(RTL_CONSTASCII_STRINGPARAM("_toc")); - sBkmkName += String::CreateFromInt32(pNd->GetIndex()); - rWW8Wrt.AddBookmark(sBkmkName); + String sBkmkName = String( RTL_CONSTASCII_STRINGPARAM( "_toc" ) ); + sBkmkName += String::CreateFromInt32( rNode.GetIndex() ); + AppendWordBookmark( sBkmkName ); } - ASSERT( !pO->Count(), " pO ist am Zeilenanfang nicht leer" ); + //Would need to move into WW8Export, probably not worth it + //ASSERT( pO->Count(), " pO ist am Zeilenanfang nicht leer" ); - String aStr( pNd->GetTxt() ); - - ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo(rWW8Wrt.mpTableInfo->getTableNodeInfo(pNd)); - ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner; - - if (pTextNodeInfo.get() != NULL) - pTextNodeInfoInner = pTextNodeInfo->getFirstInner(); + String aStr( rNode.GetTxt() ); xub_StrLen nAktPos = 0; xub_StrLen nEnd = aStr.Len(); - bool bUnicode = rWW8Wrt.bWrtWW8, bRedlineAtEnd = false; + bool bRedlineAtEnd = false; int nOpenAttrWithRange = 0; + ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner; + if ( pTextNodeInfo.get() != NULL ) + pTextNodeInfoInner = pTextNodeInfo->getFirstInner(); + do { - xub_StrLen nNextAttr = aAttrIter.WhereNext(); + const SwRedlineData* pRedlineData = aAttrIter.GetRedline( nAktPos ); + + AttrOutput().StartRun( pRedlineData ); + + xub_StrLen nNextAttr = GetNextPos( &aAttrIter, rNode, nAktPos ); if( nNextAttr > nEnd ) nNextAttr = nEnd; - aAttrIter.OutFlys(nAktPos); + aAttrIter.OutFlys( nAktPos ); //Append bookmarks in this range after flys, exclusive of final //position of this range - rWW8Wrt.AppendBookmarks( *pNd, nAktPos, nNextAttr - nAktPos ); + AppendBookmarks( rNode, nAktPos, nNextAttr - nAktPos ); bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos ); nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nAktPos); xub_StrLen nLen = nNextAttr - nAktPos; - if (!bTxtAtr && nLen) - { - sal_Unicode ch=aStr.GetChar(nAktPos); - int ofs=(ch==CH_TXT_ATR_FIELDSTART || ch==CH_TXT_ATR_FIELDEND || ch==CH_TXT_ATR_FORMELEMENT?1:0); - IDocumentMarkAccess* const pMarkAccess = rWW8Wrt.pDoc->getIDocumentMarkAccess(); - if(ch==CH_TXT_ATR_FIELDSTART) - { - SwPosition aPosition(*pNd, SwIndex((SwTxtNode*)pNd, nAktPos+1)); - ::sw::mark::IFieldmark const * const pFieldmark=pMarkAccess->getFieldmarkFor(aPosition); - OSL_ENSURE(pFieldmark, - "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??"); - if(pFieldmark) - rWW8Wrt.AppendBookmark(pFieldmark->GetName(), 1); - rWW8Wrt.OutField(NULL, ww::eFORMTEXT, String::CreateFromAscii(" FORMTEXT "), WRITEFIELD_START | WRITEFIELD_CMD_START); - if(pFieldmark) - rWW8Wrt.WriteFormData(*pFieldmark); - rWW8Wrt.OutField(NULL, ww::eFORMTEXT, String(), WRITEFIELD_CMD_END); - } - else if (ch==CH_TXT_ATR_FIELDEND) - { - SwPosition aPosition(*pNd, SwIndex((SwTxtNode*)pNd, nAktPos)); - ::sw::mark::IFieldmark const * const pFieldmark=pMarkAccess->getFieldmarkFor(aPosition); - OSL_ENSURE(pFieldmark, - "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??"); - rWW8Wrt.OutField(NULL, ww::eFORMTEXT, String(), WRITEFIELD_CLOSE); - if (pFieldmark) - rWW8Wrt.AppendBookmark(pFieldmark->GetName(), 0); - } - else if (ch==CH_TXT_ATR_FORMELEMENT) - { - SwPosition aPosition(*pNd, SwIndex((SwTxtNode*)pNd, nAktPos)); - ::sw::mark::IFieldmark const * const pFieldmark=pMarkAccess->getFieldmarkFor(aPosition); - OSL_ENSURE(pFieldmark, - "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??"); - if(pFieldmark) - rWW8Wrt.AppendBookmark(pFieldmark->GetName(), 1); - rWW8Wrt.OutField(NULL, ww::eFORMCHECKBOX, String::CreateFromAscii(" FORMCHECKBOX "), WRITEFIELD_START | WRITEFIELD_CMD_START); - if(pFieldmark) - rWW8Wrt.WriteFormData(*pFieldmark); - rWW8Wrt.OutField(NULL, ww::eFORMCHECKBOX, String(), WRITEFIELD_CMD_END | WRITEFIELD_CLOSE); - if(pFieldmark) - rWW8Wrt.AppendBookmark(pFieldmark->GetName(), 0); - } - nLen-=static_cast<USHORT>(ofs); - String aSnippet(aAttrIter.GetSnippet(aStr, nAktPos+static_cast<USHORT>(ofs), nLen)); - if ((rWW8Wrt.nTxtTyp == TXT_EDN || rWW8Wrt.nTxtTyp == TXT_FTN) && nAktPos ==0 && nLen>0) - { - // Insert tab for aesthetic puposes #i24762# - if (aSnippet.GetChar(0) != 0x09) - { - nLen++; - aSnippet.Insert(0x09,0); - } - } - rWW8Wrt.OutSwString(aSnippet, 0, nLen, bUnicode, eChrSet); - } - - if (aAttrIter.IsDropCap(nNextAttr)) + if ( !bTxtAtr && nLen ) { + sal_Unicode ch = aStr.GetChar( nAktPos ); + int ofs = ( ch == CH_TXT_ATR_FIELDSTART || ch == CH_TXT_ATR_FIELDEND || ch == CH_TXT_ATR_FORMELEMENT? 1: 0 ); - const SwFmtDrop &rSwFmtDrop = aAttrIter.GetSwFmtDrop(); - short nDropLines = rSwFmtDrop.GetLines(); - short nDistance = rSwFmtDrop.GetDistance(); - int rFontHeight, rDropHeight, rDropDescent; - - pO->Insert( (BYTE*)&nSty, 2, pO->Count() ); // Style # - - if (rWW8Wrt.bWrtWW8) + IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); + if ( ch == CH_TXT_ATR_FIELDSTART ) { - rWW8Wrt.InsUInt16( 0x261b ); // Alignment (sprmPPc) - rWW8Wrt.pO->Insert( 0x20, rWW8Wrt.pO->Count() ); - - rWW8Wrt.InsUInt16( 0x2423 ); // Wrapping (sprmPWr) - rWW8Wrt.pO->Insert( 0x02, rWW8Wrt.pO->Count() ); - - rWW8Wrt.InsUInt16( 0x442c ); // Dropcap (sprmPDcs) - int nDCS = (nDropLines << 3) | 0x01; - rWW8Wrt.InsUInt16( static_cast< UINT16 >(nDCS) ); - - rWW8Wrt.InsUInt16( 0x842F ); // Distance from text (sprmPDxaFromText) - rWW8Wrt.InsUInt16( nDistance ); - - if (pNd->GetDropSize(rFontHeight, rDropHeight, rDropDescent)) - { - rWW8Wrt.InsUInt16( 0x6412 ); // Line spacing - rWW8Wrt.InsUInt16( static_cast< UINT16 >(-rDropHeight) ); - rWW8Wrt.InsUInt16( 0 ); - } + SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos + 1 ) ); + ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition ); + OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" ); + + if ( pFieldmark ) + AppendBookmark( pFieldmark->GetName(), true ); + OutputField( NULL, ww::eFORMTEXT, String::CreateFromAscii( " FORMTEXT " ), WRITEFIELD_START | WRITEFIELD_CMD_START ); + if ( pFieldmark ) + WriteFormData( *pFieldmark ); + OutputField( NULL, ww::eFORMTEXT, String(), WRITEFIELD_CMD_END ); } - else + else if ( ch == CH_TXT_ATR_FIELDEND ) { - rWW8Wrt.pO->Insert( 29, rWW8Wrt.pO->Count() ); // Alignment (sprmPPc) - rWW8Wrt.pO->Insert( 0x20, rWW8Wrt.pO->Count() ); - - rWW8Wrt.pO->Insert( 37, rWW8Wrt.pO->Count() ); // Wrapping (sprmPWr) - rWW8Wrt.pO->Insert( 0x02, rWW8Wrt.pO->Count() ); - - rWW8Wrt.pO->Insert( 46, rWW8Wrt.pO->Count() ); // Dropcap (sprmPDcs) - int nDCS = (nDropLines << 3) | 0x01; - rWW8Wrt.InsUInt16( static_cast< UINT16 >(nDCS) ); + SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) ); + ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition ); + OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" ); - rWW8Wrt.pO->Insert( 49, rWW8Wrt.pO->Count() ); // Distance from text (sprmPDxaFromText) - rWW8Wrt.InsUInt16( nDistance ); - - if (pNd->GetDropSize(rFontHeight, rDropHeight, rDropDescent)) - { - rWW8Wrt.pO->Insert( 20, rWW8Wrt.pO->Count() ); // Line spacing - rWW8Wrt.InsUInt16( static_cast< UINT16 >(-rDropHeight) ); - rWW8Wrt.InsUInt16( 0 ); - } + OutputField( NULL, ww::eFORMTEXT, String(), WRITEFIELD_CLOSE ); + if ( pFieldmark ) + AppendBookmark( pFieldmark->GetName(), false ); } - - rWW8Wrt.WriteCR(pTextNodeInfoInner); - - if (pTextNodeInfo.get() != NULL) + else if ( ch == CH_TXT_ATR_FORMELEMENT ) { -#ifdef DEBUG - ::std::clog << pTextNodeInfo->toString() << ::std::endl; -#endif - - rWW8Wrt.OutWW8TableInfoCell(pTextNodeInfoInner); + SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) ); + ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition ); + OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" ); + + if ( pFieldmark ) + AppendBookmark( pFieldmark->GetName(), true ); + OutputField( NULL, ww::eFORMCHECKBOX, String::CreateFromAscii( " FORMCHECKBOX " ), WRITEFIELD_START | WRITEFIELD_CMD_START ); + if ( pFieldmark ) + WriteFormData( *pFieldmark ); + OutputField( NULL, ww::eFORMCHECKBOX, String(), WRITEFIELD_CMD_END | WRITEFIELD_CLOSE ); + if ( pFieldmark ) + AppendBookmark( pFieldmark->GetName(), false ); } + nLen -= static_cast< USHORT >( ofs ); - rWW8Wrt.pPapPlc->AppendFkpEntry( rWrt.Strm().Tell(), pO->Count(), - pO->GetData() ); - pO->Remove( 0, pO->Count() ); - - if(pNd->GetDropSize(rFontHeight, rDropHeight, rDropDescent)) + String aSnippet( aAttrIter.GetSnippet( aStr, nAktPos + static_cast< USHORT >( ofs ), nLen ) ); + if ( ( nTxtTyp == TXT_EDN || nTxtTyp == TXT_FTN ) && nAktPos == 0 && nLen > 0 ) { - if (rWW8Wrt.bWrtWW8) - { - const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt(); - if(pSwCharFmt) - { - rWW8Wrt.InsUInt16( 0x4A30 ); - rWW8Wrt.InsUInt16( rWW8Wrt.GetId( *pSwCharFmt ) ); - } - - rWW8Wrt.InsUInt16( 0x4845 ); // Lower the chars - rWW8Wrt.InsUInt16( static_cast< UINT16 >(-((nDropLines - 1)*rDropDescent) / 10 )); - - rWW8Wrt.InsUInt16( 0x4a43 ); // Font Size - rWW8Wrt.InsUInt16( static_cast< UINT16 >(rFontHeight / 10) ); - } - else - { - const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt(); - if(pSwCharFmt) - { - rWW8Wrt.InsUInt16( 80 ); - rWW8Wrt.InsUInt16( rWW8Wrt.GetId( *pSwCharFmt ) ); - } - - rWW8Wrt.pO->Insert(101, rWW8Wrt.pO->Count() ); // Lower the chars - rWW8Wrt.InsUInt16( static_cast< UINT16 >(-((nDropLines - 1)*rDropDescent) / 10) ); - - rWW8Wrt.pO->Insert( 99, rWW8Wrt.pO->Count() ); // Font Size - rWW8Wrt.InsUInt16( static_cast< UINT16 >(rFontHeight / 10) ); - } + // Insert tab for aesthetic puposes #i24762# + if ( aSnippet.GetChar( 0 ) != 0x09 ) + aSnippet.Insert( 0x09, 0 ); } - - rWW8Wrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), - pO->Count(), pO->GetData() ); - pO->Remove( 0, pO->Count() ); + AttrOutput().RunText( aSnippet, eChrSet ); } - // Am Zeilenende werden die Attribute bis ueber das CR aufgezogen. - // Ausnahme: Fussnoten am Zeilenende - if (nNextAttr == nEnd) + if ( aAttrIter.IsDropCap( nNextAttr ) ) + AttrOutput().FormatDrop( rNode, aAttrIter.GetSwFmtDrop(), nStyle, pTextNodeInfo, pTextNodeInfoInner ); + + // At the end of line, output the attributes until the CR. + // Exception: footnotes at the end of line + if ( nNextAttr == nEnd ) { - ASSERT(nOpenAttrWithRange >= 0, - "odd to see this happening, expected >= 0"); - if (!bTxtAtr && nOpenAttrWithRange <= 0) + ASSERT( nOpenAttrWithRange >= 0, "odd to see this happening, expected >= 0" ); + if ( !bTxtAtr && nOpenAttrWithRange <= 0 ) { - if (aAttrIter.IsRedlineAtEnd(nEnd)) + if ( aAttrIter.IsRedlineAtEnd( nEnd ) ) bRedlineAtEnd = true; else { - //insert final graphic anchors if any before CR - aAttrIter.OutFlys(nEnd); - //insert final bookmarks if any before CR and after flys - rWW8Wrt.AppendBookmarks( *pNd, nEnd, 1 ); - if (pTOXSect) + // insert final graphic anchors if any before CR + aAttrIter.OutFlys( nEnd ); + // insert final bookmarks if any before CR and after flys + AppendBookmarks( rNode, nEnd, 1 ); + if ( pTOXSect ) { - rWW8Wrt.pop_charpropstart(); - rWW8Wrt.EndTOX(*pTOXSect); + m_aCurrentCharPropStarts.pop(); + AttrOutput().EndTOX( *pTOXSect ); } - rWW8Wrt.WriteCR(pTextNodeInfoInner); // CR danach + WriteCR( pTextNodeInfoInner ); } } } - WW8_WrPlcFld* pCurrentFields = rWW8Wrt.CurrentFieldPlc(); - USHORT nOldFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0; + // Output the character attributes + AttrOutput().StartRunProperties(); + aAttrIter.OutAttr( nAktPos ); // nAktPos - 1 ?? + AttrOutput().EndRunProperties( pRedlineData ); - // Export of Character attributes - aAttrIter.OutAttr( nAktPos ); // nAktPos - 1 ?? - - pCurrentFields = rWW8Wrt.CurrentFieldPlc(); - USHORT nNewFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0; - - bool bExportedFieldResult = nOldFieldResults != nNewFieldResults; - //If we have exported a field result, then we will have been forced to - //split up the text into a 0x13, 0x14, <result> 0x15 sequence with the - //properties forced out at the end of the result, so the 0x15 itself - //should remain clean of all other attributes to avoid #iXXXXX# - if (!bExportedFieldResult) - { - rWW8Wrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), - pO->Count(), pO->GetData() ); - } - pO->Remove( 0, pO->Count() ); // erase - - // Ausnahme: Fussnoten am Zeilenende - if (nNextAttr == nEnd) + // Exception: footnotes at the end of line + if ( nNextAttr == nEnd ) { ASSERT(nOpenAttrWithRange >= 0, "odd to see this happening, expected >= 0"); bool bAttrWithRange = (nOpenAttrWithRange > 0); - if (nAktPos != nEnd) + if ( nAktPos != nEnd ) { nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nEnd); ASSERT(nOpenAttrWithRange == 0, "odd to see this happening, expected 0"); } - if(pO->Count()) - { - rWW8Wrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), - pO->Count(), pO->GetData() ); - pO->Remove(0, pO->Count()); // leeren - } + AttrOutput().OutputFKP(); - if( bTxtAtr || bAttrWithRange || bRedlineAtEnd ) + if ( bTxtAtr || bAttrWithRange || bRedlineAtEnd ) { - //insert final graphic anchors if any before CR - aAttrIter.OutFlys(nEnd); - //insert final bookmarks if any before CR and after flys - rWW8Wrt.AppendBookmarks( *pNd, nEnd, 1 ); + // insert final graphic anchors if any before CR + aAttrIter.OutFlys( nEnd ); + // insert final bookmarks if any before CR and after flys + AppendBookmarks( rNode, nEnd, 1 ); - if (pTOXSect) + if ( pTOXSect ) { - rWW8Wrt.pop_charpropstart(); - rWW8Wrt.EndTOX( *pTOXSect ); + m_aCurrentCharPropStarts.pop(); + AttrOutput().EndTOX( *pTOXSect ); } - rWW8Wrt.WriteCR(pTextNodeInfoInner); // CR danach + WriteCR( pTextNodeInfoInner ); - if( bRedlineAtEnd ) + if ( bRedlineAtEnd ) { - aAttrIter.OutRedlines( nEnd ); - if( pO->Count() ) - { - rWW8Wrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), - pO->Count(), pO->GetData() ); - pO->Remove( 0, pO->Count() ); // delete - } + AttrOutput().Redline( aAttrIter.GetRedline( nEnd ) ); + AttrOutput().OutputFKP(); } } } + + AttrOutput().EndRun(); + nAktPos = nNextAttr; - aAttrIter.NextPos(); + UpdatePosition( &aAttrIter, nAktPos, nEnd ); eChrSet = aAttrIter.GetCharSet(); } - while( nAktPos < nEnd ); + while ( nAktPos < nEnd ); - ASSERT( !pO->Count(), " pO ist am ZeilenEnde nicht leer" ); + AttrOutput().StartParagraphProperties( rNode ); - pO->Insert( (BYTE*)&nSty, 2, pO->Count() ); // Style # + AttrOutput().ParagraphStyle( nStyle ); - if (rWW8Wrt.mpParentFrame && !rWW8Wrt.bIsInTable) // Fly-Attrs - rWW8Wrt.Out_SwFmt(rWW8Wrt.mpParentFrame->GetFrmFmt(), false, false, true); + if ( mpParentFrame && !bIsInTable ) // Fly-Attrs + OutputFormat( mpParentFrame->GetFrmFmt(), false, false, true ); - if (pTextNodeInfo.get() != NULL) + if ( pTextNodeInfo.get() != NULL ) { #ifdef DEBUG ::std::clog << pTextNodeInfo->toString() << ::std::endl; #endif - rWW8Wrt.OutWW8TableInfoCell(pTextNodeInfoInner); + AttrOutput().TableInfoCell( pTextNodeInfoInner ); } - if( !bFlyInTable ) + if ( !bFlyInTable ) { SfxItemSet* pTmpSet = 0; - const BYTE nPrvNxtNd = pNd->HasPrevNextLayNode(); + const BYTE nPrvNxtNd = rNode.HasPrevNextLayNode(); if( (ND_HAS_PREV_LAYNODE|ND_HAS_NEXT_LAYNODE ) != nPrvNxtNd ) { const SfxPoolItem* pItem; - if( SFX_ITEM_SET == pNd->GetSwAttrSet().GetItemState( + if( SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState( RES_UL_SPACE, true, &pItem ) && ( ( !( ND_HAS_PREV_LAYNODE & nPrvNxtNd ) && ((SvxULSpaceItem*)pItem)->GetUpper()) || ( !( ND_HAS_NEXT_LAYNODE & nPrvNxtNd ) && ((SvxULSpaceItem*)pItem)->GetLower()) )) { - pTmpSet = new SfxItemSet( pNd->GetSwAttrSet() ); + pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() ); SvxULSpaceItem aUL( *(SvxULSpaceItem*)pItem ); // OD, MMAHER 2004-03-01 #i25901#- consider compatibility option - if (!rWrt.pDoc->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES)) + if (!pDoc->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES)) { if( !(ND_HAS_PREV_LAYNODE & nPrvNxtNd )) aUL.SetUpper( 0 ); } // OD, MMAHER 2004-03-01 #i25901# - consider compatibility option - if (!rWrt.pDoc->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS)) + if (!pDoc->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS)) { if( !(ND_HAS_NEXT_LAYNODE & nPrvNxtNd )) aUL.SetLower( 0 ); @@ -1861,20 +1869,20 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) BOOL bParaRTL = FALSE; const SvxFrameDirectionItem* pItem = (const SvxFrameDirectionItem*) - pNd->GetSwAttrSet().GetItem(RES_FRAMEDIR); + rNode.GetSwAttrSet().GetItem(RES_FRAMEDIR); if ( aAttrIter.IsParaRTL()) bParaRTL = TRUE; - if( pNd->IsNumbered()) + if( rNode.IsNumbered()) { - const SwNumRule* pRule = pNd->GetNumRule(); - BYTE nLvl = static_cast< BYTE >(pNd->GetActualListLevel()); + const SwNumRule* pRule = rNode.GetNumRule(); + BYTE nLvl = static_cast< BYTE >( rNode.GetActualListLevel() ); const SwNumFmt* pFmt = pRule->GetNumFmt( nLvl ); if( !pFmt ) pFmt = &pRule->Get( nLvl ); if( !pTmpSet ) - pTmpSet = new SfxItemSet( pNd->GetSwAttrSet() ); + pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() ); SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*pTmpSet, RES_LR_SPACE)); // --> OD 2008-06-03 #i86652# @@ -1885,16 +1893,16 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) } // <-- - if( pNd->IsNumbered() && pNd->IsCountedInList() ) + if( rNode.IsNumbered() && rNode.IsCountedInList() ) { // --> OD 2008-06-03 #i86652# if ( pFmt->GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) { if (bParaRTL) - aLR.SetTxtFirstLineOfstValue(pFmt->GetAbsLSpace() - pFmt->GetFirstLineOffset()); + aLR.SetTxtFirstLineOfstValue(pFmt->GetAbsLSpace() - pFmt->GetFirstLineOffset()); else - aLR.SetTxtFirstLineOfst(GetWordFirstLineOffset(*pFmt)); + aLR.SetTxtFirstLineOfst(GetWordFirstLineOffset(*pFmt)); } // <-- @@ -1913,7 +1921,7 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) // indent values are not applicable. if ( pFmt->GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT && - !pNd->AreListLevelIndentsApplicable() ) + !rNode.AreListLevelIndentsApplicable() ) { pTmpSet->Put( aLR ); } @@ -1935,7 +1943,7 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) aItem.Insert(aTabStop); pTmpSet->Put(aItem); - SwWW8Writer::CorrTabStopInSet(*pTmpSet, pFmt->GetAbsLSpace()); + MSWordExportBase::CorrectTabStopInSet(*pTmpSet, pFmt->GetAbsLSpace()); } } @@ -1945,14 +1953,14 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) default. Otherwise we must add a RTL attribute to our export list */ pItem = (const SvxFrameDirectionItem*) - pNd->GetSwAttrSet().GetItem(RES_FRAMEDIR); + rNode.GetSwAttrSet().GetItem(RES_FRAMEDIR); if ( (!pItem || pItem->GetValue() == FRMDIR_ENVIRONMENT) && aAttrIter.IsParaRTL() ) { if ( !pTmpSet ) - pTmpSet = new SfxItemSet(pNd->GetSwAttrSet()); + pTmpSet = new SfxItemSet(rNode.GetSwAttrSet()); pTmpSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP, RES_FRAMEDIR)); } @@ -1962,17 +1970,17 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) // is found in <pTmpSet> // #i44815# adjust numbering/indents for numbered paragraphs // without number (NO_NUMLEVEL) - // #i47013# need to check pNd->GetNumRule()!=NULL as well. - if ( ! pNd->IsCountedInList() && pNd->GetNumRule()!=NULL ) + // #i47013# need to check rNode.GetNumRule()!=NULL as well. + if ( ! rNode.IsCountedInList() && rNode.GetNumRule()!=NULL ) { // WW8 does not know numbered paragraphs without number - // (NO_NUMLEVEL). In OutWW8_SwNumRuleItem, we will export + // (NO_NUMLEVEL). In WW8AttributeOutput::ParaNumRule(), we will export // the RES_PARATR_NUMRULE as list-id 0, which in WW8 means // no numbering. Here, we will adjust the indents to match // visually. if ( !pTmpSet ) - pTmpSet = new SfxItemSet(pNd->GetSwAttrSet()); + pTmpSet = new SfxItemSet(rNode.GetSwAttrSet()); // create new LRSpace item, based on the current (if present) const SfxPoolItem* pPoolItem = NULL; @@ -1983,8 +1991,8 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) : *static_cast<const SvxLRSpaceItem*>( pPoolItem ) ); // new left margin = old left + label space - const SwNumRule* pRule = pNd->GetNumRule(); - const SwNumFmt& rNumFmt = pRule->Get( static_cast< USHORT >(pNd->GetActualListLevel()) ); + const SwNumRule* pRule = rNode.GetNumRule(); + const SwNumFmt& rNumFmt = pRule->Get( static_cast< USHORT >(rNode.GetActualListLevel()) ); // --> OD 2008-06-03 #i86652# if ( rNumFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) @@ -2010,38 +2018,36 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) // --> OD 2007-04-24 #i75457# // Export page break after attribute from paragraph style. + // If page break attribute at the text node exist, an existing page + // break after at the paragraph style hasn't got to be considered. + if ( !rNode.GetpSwAttrSet() || + SFX_ITEM_SET != rNode.GetpSwAttrSet()->GetItemState(RES_BREAK, false) ) { - // If page break attribute at the text node exist, an existing page - // break after at the paragraph style hasn't got to be considered. - if ( !pNd->GetpSwAttrSet() || - SFX_ITEM_SET != pNd->GetpSwAttrSet()->GetItemState(RES_BREAK, false) ) + const SvxFmtBreakItem* pBreakAtParaStyle = + &(ItemGet<SvxFmtBreakItem>(rNode.GetSwAttrSet(), RES_BREAK)); + if ( pBreakAtParaStyle && + pBreakAtParaStyle->GetBreak() == SVX_BREAK_PAGE_AFTER ) { - const SvxFmtBreakItem* pBreakAtParaStyle = - &(ItemGet<SvxFmtBreakItem>(pNd->GetSwAttrSet(), RES_BREAK)); - if ( pBreakAtParaStyle && - pBreakAtParaStyle->GetBreak() == SVX_BREAK_PAGE_AFTER ) + if ( !pTmpSet ) { - if ( !pTmpSet ) - { - pTmpSet = new SfxItemSet(pNd->GetSwAttrSet()); - } - pTmpSet->Put( *pBreakAtParaStyle ); - } - else if( pTmpSet ) - { // Even a pagedesc item is set, the break item can be set 'NONE', - // this has to be overruled. - const SwFmtPageDesc& rPageDescAtParaStyle = - ItemGet<SwFmtPageDesc>( *pNd, RES_PAGEDESC ); - if( rPageDescAtParaStyle.GetRegisteredIn() ) - pTmpSet->ClearItem( RES_BREAK ); + pTmpSet = new SfxItemSet(rNode.GetSwAttrSet()); } + pTmpSet->Put( *pBreakAtParaStyle ); + } + else if( pTmpSet ) + { // Even a pagedesc item is set, the break item can be set 'NONE', + // this has to be overruled. + const SwFmtPageDesc& rPageDescAtParaStyle = + ItemGet<SwFmtPageDesc>( rNode, RES_PAGEDESC ); + if( rPageDescAtParaStyle.GetRegisteredIn() ) + pTmpSet->ClearItem( RES_BREAK ); } } // --> FME 2007-05-30 #i76520# Emulate non-splitting tables - if ( rWW8Wrt.bOutTable ) + if ( bOutTable ) { - const SwTableNode* pTableNode = pNd->FindTableNode(); + const SwTableNode* pTableNode = rNode.FindTableNode(); if ( pTableNode ) { @@ -2057,7 +2063,7 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) // bKeep: set keep at first paragraphs in all lines // bDontSplit : set keep at first paragraphs in all lines except from last line // but only for non-complex tables - const SwTableBox* pBox = pNd->GetTblBox(); + const SwTableBox* pBox = rNode.GetTblBox(); const SwTableLine* pLine = pBox ? pBox->GetUpper() : 0; if ( pLine && !pLine->GetUpper() ) @@ -2066,7 +2072,7 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) if ( 0 == pLine->GetTabBoxes().GetPos( pBox ) && pBox->GetSttNd() ) { // check if paragraph is first in that line: - if ( 1 == ( pNd->GetIndex() - pBox->GetSttNd()->GetIndex() ) ) + if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) ) { bool bSetAtPara = false; if ( bKeep ) @@ -2081,7 +2087,7 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) if ( bSetAtPara ) { if ( !pTmpSet ) - pTmpSet = new SfxItemSet(pNd->GetSwAttrSet()); + pTmpSet = new SfxItemSet(rNode.GetSwAttrSet()); const SvxFmtKeepItem aKeepItem( TRUE, RES_KEEP ); pTmpSet->Put( aKeepItem ); @@ -2094,76 +2100,57 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ) } // <-- - const SfxItemSet* pNewSet = pTmpSet ? pTmpSet : pNd->GetpSwAttrSet(); + const SfxItemSet* pNewSet = pTmpSet ? pTmpSet : rNode.GetpSwAttrSet(); if( pNewSet ) { // Para-Attrs - rWW8Wrt.pStyAttr = &pNd->GetAnyFmtColl().GetAttrSet(); + pStyAttr = &rNode.GetAnyFmtColl().GetAttrSet(); - const SwModify* pOldMod = rWW8Wrt.pOutFmtNode; - rWW8Wrt.pOutFmtNode = pNd; + const SwModify* pOldMod = pOutFmtNode; + pOutFmtNode = &rNode; // Pap-Attrs, so script is not necessary - rWW8Wrt.Out_SfxItemSet( *pNewSet, true, false, - i18n::ScriptType::LATIN); + OutputItemSet( *pNewSet, true, false, i18n::ScriptType::LATIN); - rWW8Wrt.pStyAttr = 0; - rWW8Wrt.pOutFmtNode = pOldMod; + pStyAttr = 0; + pOutFmtNode = pOldMod; - if( pNewSet != pNd->GetpSwAttrSet() ) + if( pNewSet != rNode.GetpSwAttrSet() ) delete pNewSet; } } - rWW8Wrt.pPapPlc->AppendFkpEntry( rWrt.Strm().Tell(), pO->Count(), - pO->GetData() ); - pO->Remove( 0, pO->Count() ); // leeren + AttrOutput().EndParagraphProperties(); - if (pTextNodeInfoInner.get() != NULL) - { - if (pTextNodeInfoInner->isEndOfLine()) - { - rWW8Wrt.WriteRowEnd(pTextNodeInfoInner->getDepth()); - - pO->Insert( (BYTE*)&nSty, 2, pO->Count() ); // Style # - rWW8Wrt.OutWW8TableInfoRow(pTextNodeInfoInner); - rWW8Wrt.pPapPlc->AppendFkpEntry( rWrt.Strm().Tell(), pO->Count(), - pO->GetData() ); - pO->Remove( 0, pO->Count() ); // leeren - } - } + AttrOutput().EndParagraph( pTextNodeInfoInner ); #ifdef DEBUG ::std::clog << "</OutWW8_SwTxtNode>" << ::std::endl; #endif - - return rWrt; } -void SwWW8Writer::OutWW8TableNodeInfo(ww8::WW8TableNodeInfo::Pointer_t pNodeInfo) +void WW8AttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo ) { SVBT16 nSty; - ShortToSVBT16( nStyleBeforeFly, nSty ); + ShortToSVBT16( GetExport().nStyleBeforeFly, nSty ); - ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt - (pNodeInfo->getInners().begin()); - ww8::WW8TableNodeInfo::Inners_t::const_iterator aItEnd - (pNodeInfo->getInners().end()); + ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt( pNodeInfo->getInners().begin() ); + ww8::WW8TableNodeInfo::Inners_t::const_iterator aItEnd( pNodeInfo->getInners().end() ); while (aIt != aItEnd) { ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second; - if (pInner->isEndOfCell()) + if ( pInner->isEndOfCell() ) { - WriteRowEnd(pInner->getDepth()); + TableRowEnd( pInner->getDepth() ); - pO->Insert( (BYTE*)&nSty, 2, pO->Count() ); // Style # - OutWW8TableInfoRow(pInner); - pPapPlc->AppendFkpEntry( Strm().Tell(), pO->Count(), - pO->GetData() ); - pO->Remove( 0, pO->Count() ); // leeren + m_rWW8Export.pO->Insert( (BYTE*)&nSty, 2, m_rWW8Export.pO->Count() ); // Style # + TableInfoRow( pInner ); + m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), + m_rWW8Export.pO->GetData() ); + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren } - if (pInner->isEndOfLine()) + if ( pInner->isEndOfLine() ) { } @@ -2174,13 +2161,11 @@ void SwWW8Writer::OutWW8TableNodeInfo(ww8::WW8TableNodeInfo::Pointer_t pNodeInfo #if 0 /* */ -USHORT SwWW8Writer::StartTableFromFrmFmt(WW8Bytes &rAt, const SwFrmFmt *pFmt, - SwTwips &rTblOffset) - +USHORT WW8Export::StartTableFromFrmFmt( WW8Bytes &rAt, const SwFrmFmt *pFmt ) { - //Tell the undocumented table hack that everything between here and - //the last table position is nontable text - if (WW8_CP nPos = Fc2Cp(Strm().Tell())) + // Tell the undocumented table hack that everything between here and + // the last table position is nontable text + if ( WW8_CP nPos = Fc2Cp( Strm().Tell() ) ) pMagicTable->Append(nPos,0); // sprmPDxaFromText10 @@ -2201,8 +2186,8 @@ USHORT SwWW8Writer::StartTableFromFrmFmt(WW8Bytes &rAt, const SwFrmFmt *pFmt, rAt.Insert( aTabLineAttr, sizeof( aTabLineAttr ), rAt.Count() ); } - ASSERT(pFmt, "No pFmt!"); - if (pFmt) + ASSERT( pFmt, "No pFmt!" ); + if ( pFmt ) { const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient(); const SwFmtVertOrient &rVert = pFmt->GetVertOrient(); @@ -2220,29 +2205,12 @@ USHORT SwWW8Writer::StartTableFromFrmFmt(WW8Bytes &rAt, const SwFrmFmt *pFmt, case text::HoriOrientation::CENTER: case text::HoriOrientation::RIGHT: if( bWrtWW8 ) - InsUInt16( rAt, 0x5400 ); + SwWW8Writer::InsUInt16( rAt, NS_sprm::LN_TJc ); else rAt.Insert( 182, rAt.Count() ); - InsUInt16( rAt, (text::HoriOrientation::RIGHT == eHOri ? 2 : 1 )); + SwWW8Writer::InsUInt16( rAt, (text::HoriOrientation::RIGHT == eHOri ? 2 : 1 )); break; default: -#if 1 -#if 1 - rTblOffset = rHori.GetPos(); - const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace(); - rTblOffset += rLRSp.GetLeft(); -#else - Point aOffset = pFmt->FindLayoutRect(true).Pos(); - rTblOffset = aOffset.X(); -#endif - -#else - { - const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace(); - rTblOffset = rLRSp.GetLeft(); - rPageSize -= rTblOffset + rLRSp.GetRight(); - } -#endif break; } } @@ -2251,23 +2219,23 @@ USHORT SwWW8Writer::StartTableFromFrmFmt(WW8Bytes &rAt, const SwFrmFmt *pFmt, } //See #i19484# for why we need this -bool CellContainsProblematicGraphic(const SwWriteTableCell *pCell, - const SwWW8Writer &rWr) +static bool CellContainsProblematicGraphic( const SwWriteTableCell *pCell, + const MSWordExportBase &rExport ) { const SwNode *pStart = pCell ? pCell->GetBox()->GetSttNd() : 0; const SwNode *pEnd = pStart ? pStart->EndOfSectionNode() : 0; - ASSERT(pStart && pEnd, "No start or end?"); - if (!(pStart && pEnd)) + ASSERT( pStart && pEnd, "No start or end?" ); + if ( !pStart || !pEnd ) return false; bool bHasGraphic = false; - sw::Frames aFrames(GetFramesBetweenNodes(rWr.maFrames, *pStart, *pEnd)); + sw::Frames aFrames( GetFramesBetweenNodes( rExport.maFrames, *pStart, *pEnd ) ); sw::FrameIter aEnd = aFrames.end(); - for (sw::FrameIter aIter = aFrames.begin(); aIter != aEnd; ++aIter) + for ( sw::FrameIter aIter = aFrames.begin(); aIter != aEnd; ++aIter ) { const SwFrmFmt &rEntry = aIter->GetFrmFmt(); - if (rEntry.GetSurround().GetSurround() == SURROUND_THROUGHT) + if ( rEntry.GetSurround().GetSurround() == SURROUND_THROUGHT ) { bHasGraphic = true; break; @@ -2276,13 +2244,13 @@ bool CellContainsProblematicGraphic(const SwWriteTableCell *pCell, return bHasGraphic; } -bool RowContainsProblematicGraphic(const SwWriteTableCellPtr *pRow, - USHORT nCols, const SwWW8Writer &rWr) +static bool RowContainsProblematicGraphic( const SwWriteTableCellPtr *pRow, + USHORT nCols, const MSWordExportBase &rExport ) { bool bHasGraphic = false; - for (USHORT nI = 0; nI < nCols; ++nI) + for ( USHORT nI = 0; nI < nCols; ++nI ) { - if (CellContainsProblematicGraphic(pRow[nI], rWr)) + if ( CellContainsProblematicGraphic( pRow[nI], rExport ) ) { bHasGraphic = true; break; @@ -2295,7 +2263,12 @@ bool RowContainsProblematicGraphic(const SwWriteTableCellPtr *pRow, // Tabellen //--------------------------------------------------------------------------- -bool SwWW8Writer::NoPageBreakSection(const SfxItemSet* pSet) +void WW8AttributeOutput::EmptyParagraph() +{ + m_rWW8Export.WriteStringAsPara( aEmptyStr ); +} + +bool MSWordExportBase::NoPageBreakSection( const SfxItemSet* pSet ) { bool bRet = false; const SfxPoolItem* pI; @@ -2333,23 +2306,22 @@ bool SwWW8Writer::NoPageBreakSection(const SfxItemSet* pSet) /* */ -Writer& OutWW8_SwSectionNode( Writer& rWrt, SwSectionNode& rSectionNode ) +void MSWordExportBase::OutputSectionNode( const SwSectionNode& rSectionNode ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; const SwSection& rSection = rSectionNode.GetSection(); SwNodeIndex aIdx( rSectionNode, 1 ); const SwNode& rNd = aIdx.GetNode(); - if (!rNd.IsSectionNode() && !rWW8Wrt.bIsInTable) //No sections in table + if ( !rNd.IsSectionNode() && !bIsInTable ) //No sections in table { // Bug 74245 - if the first Node inside the section has an own // PageDesc or PageBreak attribut, then dont write // here the section break ULONG nRstLnNum = 0; const SfxItemSet* pSet; - if( rNd.IsTableNode() ) + if ( rNd.IsTableNode() ) pSet = &rNd.GetTableNode()->GetTable().GetFrmFmt()->GetAttrSet(); - else if( rNd.IsCntntNode() ) + else if ( rNd.IsCntntNode() ) { pSet = &rNd.GetCntntNode()->GetSwAttrSet(); nRstLnNum = ((SwFmtLineNumber&)pSet->Get( @@ -2358,30 +2330,34 @@ Writer& OutWW8_SwSectionNode( Writer& rWrt, SwSectionNode& rSectionNode ) else pSet = 0; - if( pSet && SwWW8Writer::NoPageBreakSection(pSet)) + if ( pSet && NoPageBreakSection( pSet ) ) pSet = 0; - if( !pSet ) + if ( !pSet ) { // new Section with no own PageDesc/-Break // -> write follow section break; const SwSectionFmt& rFmt = *rSection.GetFmt(); - rWW8Wrt.ReplaceCr( (char)0xc ); // Indikator fuer Page/Section-Break + ReplaceCr( msword::PageBreak ); // Indikator fuer Page/Section-Break //Get the page in use at the top of this section SwNodeIndex aIdxTmp(rSectionNode, 1); const SwPageDesc *pCurrent = SwPageDesc::GetPageDescOfNode(aIdxTmp.GetNode()); if (!pCurrent) - pCurrent = rWW8Wrt.pAktPageDesc; + pCurrent = pAktPageDesc; - rWW8Wrt.pSepx->AppendSep(rWW8Wrt.Fc2Cp(rWrt.Strm().Tell()), - pCurrent, &rFmt, nRstLnNum); + AppendSection( pCurrent, &rFmt, nRstLnNum ); } } - if( TOX_CONTENT_SECTION == rSection.GetType() ) - rWW8Wrt.bStartTOX = true; - return rWrt; + if ( TOX_CONTENT_SECTION == rSection.GetType() ) + bStartTOX = true; +} + + +void WW8Export::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum ) +{ + pSepx->AppendSep(Fc2Cp(Strm().Tell()), pPageDesc, pFmt, nLnNum); } /* */ @@ -2390,9 +2366,11 @@ Writer& OutWW8_SwSectionNode( Writer& rWrt, SwSectionNode& rSectionNode ) // Flys //--------------------------------------------------------------------------- -void SwWW8Writer::OutWW8FlyFrmsInCntnt( const SwTxtNode& rNd ) +void WW8Export::OutWW6FlyFrmsInCntnt( const SwTxtNode& rNd ) { ASSERT(!bWrtWW8, "I shouldn't be needed for Word >=8"); + if ( bWrtWW8 ) + return; if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints()) { @@ -2421,15 +2399,17 @@ void SwWW8Writer::OutWW8FlyFrmsInCntnt( const SwTxtNode& rNd ) aOffset = aFlyRect.Pos() - aParentRect.Pos(); // PaM umsetzen: auf Inhalt des Fly-Frameformats - WW8SaveData aSaveData( *this, nStt, nEnd ); + SaveData( nStt, nEnd ); - // wird in Out_SwFmt() ausgewertet + // wird in OutputFormat() ausgewertet pFlyOffset = &aOffset; eNewAnchorType = rFlyFrmFmt.GetAnchor().GetAnchorId(); sw::Frame aFrm(rFlyFrmFmt, SwPosition(rNd)); mpParentFrame = &aFrm; // Ok, rausschreiben: WriteText(); + + RestoreData(); } } } @@ -2437,15 +2417,14 @@ void SwWW8Writer::OutWW8FlyFrmsInCntnt( const SwTxtNode& rNd ) } } - -void SwWW8Writer::OutWW8FlyFrm(const sw::Frame& rFmt, const Point& rNdTopLeft) +void WW8AttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFmt, const Point& rNdTopLeft ) { const SwFrmFmt &rFrmFmt = rFmt.GetFrmFmt(); const SwFmtAnchor& rAnch = rFrmFmt.GetAnchor(); - bool bUseEscher = bWrtWW8; + bool bUseEscher = m_rWW8Export.bWrtWW8; - if (bWrtWW8 && rFmt.IsInline()) + if ( m_rWW8Export.bWrtWW8 && rFmt.IsInline() ) { sw::Frame::WriterSource eType = rFmt.GetWriterType(); if ((eType == sw::Frame::eGraphic) || (eType == sw::Frame::eOle)) @@ -2460,16 +2439,16 @@ void SwWW8Writer::OutWW8FlyFrm(const sw::Frame& rFmt, const Point& rNdTopLeft) */ if ((bUseEscher == true) && (eType == sw::Frame::eFormControl)) { - if (MiserableFormFieldExportHack(rFrmFmt)) + if ( m_rWW8Export.MiserableFormFieldExportHack( rFrmFmt ) ) return ; } } if (bUseEscher) { - ASSERT(bWrtWW8, "this has gone horribly wrong"); + ASSERT( m_rWW8Export.bWrtWW8, "this has gone horribly wrong" ); // write as escher - AppendFlyInFlys(rFmt, rNdTopLeft); + m_rWW8Export.AppendFlyInFlys(rFmt, rNdTopLeft); } else { @@ -2484,11 +2463,11 @@ void SwWW8Writer::OutWW8FlyFrm(const sw::Frame& rFmt, const Point& rNdTopLeft) if( nStt >= nEnd ) // kein Bereich, also kein gueltiger Node return; - if (!bIsInTable && rFmt.IsInline()) + if ( !m_rWW8Export.bIsInTable && rFmt.IsInline() ) { //Test to see if this textbox contains only a single graphic/ole SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode(); - if( pParTxtNode && !pDoc->GetNodes()[ nStt ]->IsNoTxtNode() ) + if ( pParTxtNode && !m_rWW8Export.pDoc->GetNodes()[ nStt ]->IsNoTxtNode() ) bDone = true; } if( !bDone ) @@ -2501,53 +2480,53 @@ void SwWW8Writer::OutWW8FlyFrm(const sw::Frame& rFmt, const Point& rNdTopLeft) // nFlyHeight = rS.GetHeight(); // <-- - { - WW8SaveData aSaveData( *this, nStt, nEnd ); + m_rWW8Export.SaveData( nStt, nEnd ); - Point aOffset; - if (mpParentFrame) - { - /* - #90804# - Munge flys in fly into absolutely positioned elements for - word 6 - */ - const SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode(); - const SwRect aPageRect = pParTxtNode->FindPageFrmRect( FALSE, 0, FALSE ); - - aOffset = rFrmFmt.FindLayoutRect().Pos(); - aOffset -= aPageRect.Pos(); - - pFlyOffset = &aOffset; - eNewAnchorType = FLY_PAGE; - } + Point aOffset; + if ( m_rWW8Export.mpParentFrame ) + { + /* + #90804# + Munge flys in fly into absolutely positioned elements for + word 6 + */ + const SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode(); + const SwRect aPageRect = pParTxtNode->FindPageFrmRect( FALSE, 0, FALSE ); + + aOffset = rFrmFmt.FindLayoutRect().Pos(); + aOffset -= aPageRect.Pos(); + + m_rWW8Export.pFlyOffset = &aOffset; + m_rWW8Export.eNewAnchorType = FLY_PAGE; + } - mpParentFrame = &rFmt; - if ( - bIsInTable && (FLY_PAGE != rAnch.GetAnchorId()) && - !pDoc->GetNodes()[ nStt ]->IsNoTxtNode() - ) - { - // Beachten: Flag bOutTable wieder setzen, - // denn wir geben ja ganz normalen Content der - // Tabelenzelle aus und keinen Rahmen - // (Flag wurde oben in aSaveData() geloescht) - bOutTable = true; - const String& rName = rFrmFmt.GetName(); - StartCommentOutput(rName); - WriteText(); - EndCommentOutput(rName); - } - else - WriteText(); + m_rWW8Export.mpParentFrame = &rFmt; + if ( + m_rWW8Export.bIsInTable && (FLY_PAGE != rAnch.GetAnchorId()) && + !m_rWW8Export.pDoc->GetNodes()[ nStt ]->IsNoTxtNode() + ) + { + // Beachten: Flag bOutTable wieder setzen, + // denn wir geben ja ganz normalen Content der + // Tabelenzelle aus und keinen Rahmen + // (Flag wurde oben in aSaveData() geloescht) + m_rWW8Export.bOutTable = true; + const String& rName = rFrmFmt.GetName(); + m_rWW8Export.StartCommentOutput(rName); + m_rWW8Export.WriteText(); + m_rWW8Export.EndCommentOutput(rName); } + else + m_rWW8Export.WriteText(); + + m_rWW8Export.RestoreData(); } } } -void SwWW8Writer::OutFlyFrm(const sw::Frame& rFmt) +void AttributeOutputBase::OutputFlyFrame( const sw::Frame& rFmt ) { - if (!rFmt.GetCntntNode()) + if ( !rFmt.GetCntntNode() ) return; const SwCntntNode &rNode = *rFmt.GetCntntNode(); @@ -2555,10 +2534,10 @@ void SwWW8Writer::OutFlyFrm(const sw::Frame& rFmt) Point* pLayPos; bool bValidNdPos = false, bValidPgPos = false; - if (FLY_PAGE == rFmt.GetFrmFmt().GetAnchor().GetAnchorId()) + if ( FLY_PAGE == rFmt.GetFrmFmt().GetAnchor().GetAnchorId() ) { // get the Layout Node-Position. - if (!bValidPgPos) + if ( !bValidPgPos ) { aPgPos = rNode.FindPageFrmRect(false, &aPgPos).Pos(); bValidPgPos = true; @@ -2568,7 +2547,7 @@ void SwWW8Writer::OutFlyFrm(const sw::Frame& rFmt) else { // get the Layout Node-Position. - if (!bValidNdPos) + if ( !bValidNdPos ) { aNdPos = rNode.FindLayoutRect(false, &aNdPos).Pos(); bValidNdPos = true; @@ -2576,27 +2555,30 @@ void SwWW8Writer::OutFlyFrm(const sw::Frame& rFmt) pLayPos = &aNdPos; } - OutWW8FlyFrm(rFmt, *pLayPos); + OutputFlyFrame_Impl( rFmt, *pLayPos ); } // write data of any redline -void SwWW8Writer::OutRedline( const SwRedlineData& rRedline ) +void WW8AttributeOutput::Redline( const SwRedlineData* pRedline ) { - if( rRedline.Next() ) - OutRedline( *rRedline.Next() ); + if ( !pRedline ) + return; + + if ( pRedline->Next() ) + Redline( pRedline->Next() ); static USHORT __READONLY_DATA aSprmIds[ 2 * 2 * 3 ] = { // Ids for insert - 0x0801, 0x4804, 0x6805, // for WW8 + NS_sprm::LN_CFRMark, NS_sprm::LN_CIbstRMark, NS_sprm::LN_CDttmRMark, // for WW8 0x0042, 0x0045, 0x0046, // for WW6 // Ids for delete - 0x0800, 0x4863, 0x6864, // for WW8 + NS_sprm::LN_CFRMarkDel, NS_sprm::LN_CIbstRMarkDel, NS_sprm::LN_CDttmRMarkDel, // for WW8 0x0041, 0x0045, 0x0046 // for WW6 }; const USHORT* pSprmIds = 0; - switch( rRedline.GetType() ) + switch( pRedline->GetType() ) { case nsRedlineType_t::REDLINE_INSERT: pSprmIds = aSprmIds; @@ -2607,13 +2589,13 @@ void SwWW8Writer::OutRedline( const SwRedlineData& rRedline ) break; case nsRedlineType_t::REDLINE_FORMAT: - if( bWrtWW8 ) + if( m_rWW8Export.bWrtWW8 ) { - InsUInt16( 0xca57 ); - pO->Insert( 7, pO->Count() ); // len - pO->Insert( 1, pO->Count() ); - InsUInt16( AddRedlineAuthor( rRedline.GetAuthor() ) ); - InsUInt32( sw::ms::DateTime2DTTM( rRedline.GetTimeStamp() )); + m_rWW8Export.InsUInt16( NS_sprm::LN_CPropRMark ); + m_rWW8Export.pO->Insert( 7, m_rWW8Export.pO->Count() ); // len + m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( m_rWW8Export.AddRedlineAuthor( pRedline->GetAuthor() ) ); + m_rWW8Export.InsUInt32( sw::ms::DateTime2DTTM( pRedline->GetTimeStamp() )); } break; default: @@ -2621,37 +2603,52 @@ void SwWW8Writer::OutRedline( const SwRedlineData& rRedline ) break; } - if( pSprmIds ) + if ( pSprmIds ) { - if( !bWrtWW8 ) + if ( !m_rWW8Export.bWrtWW8 ) pSprmIds += 3; - if( bWrtWW8 ) - InsUInt16( pSprmIds[0] ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( pSprmIds[0] ); else - pO->Insert(msword_cast<sal_uInt8>(pSprmIds[0]), pO->Count()); - pO->Insert( 1, pO->Count() ); + m_rWW8Export.pO->Insert( msword_cast<sal_uInt8>(pSprmIds[0]), m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() ); - if( bWrtWW8 ) - InsUInt16( pSprmIds[1] ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( pSprmIds[1] ); else - pO->Insert(msword_cast<sal_uInt8>(pSprmIds[1]), pO->Count()); - InsUInt16( AddRedlineAuthor( rRedline.GetAuthor() ) ); + m_rWW8Export.pO->Insert( msword_cast<sal_uInt8>(pSprmIds[1]), m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( m_rWW8Export.AddRedlineAuthor( pRedline->GetAuthor() ) ); - if( bWrtWW8 ) - InsUInt16( pSprmIds[2] ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( pSprmIds[2] ); else - pO->Insert(msword_cast<sal_uInt8>(pSprmIds[2]), pO->Count()); - InsUInt32( sw::ms::DateTime2DTTM( rRedline.GetTimeStamp() )); + m_rWW8Export.pO->Insert( msword_cast<sal_uInt8>(pSprmIds[2]), m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt32( sw::ms::DateTime2DTTM( pRedline->GetTimeStamp() )); } } /* */ -SwNodeFnTab aWW8NodeFnTab = { -/* RES_TXTNODE */ OutWW8_SwTxtNode, -/* RES_GRFNODE */ OutWW8_SwGrfNode, -/* RES_OLENODE */ OutWW8_SwOleNode, -}; +void MSWordExportBase::OutputContentNode( const SwCntntNode& rNode ) +{ + switch ( rNode.GetNodeType() ) + { + case ND_TEXTNODE: + OutputTextNode( *rNode.GetTxtNode() ); + break; + case ND_GRFNODE: + OutputGrfNode( *rNode.GetGrfNode() ); + break; + case ND_OLENODE: + OutputOLENode( *rNode.GetOLENode() ); + break; + default: +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "Unhandled node, type == %d\n", rNode.GetNodeType() ); +#endif + break; + } +} /* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx index e222bc4984d8..b318a14019b4 100644 --- a/sw/source/filter/ww8/wrtw8num.cxx +++ b/sw/source/filter/ww8/wrtw8num.cxx @@ -33,7 +33,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ - #include <hintids.hxx> #include <vcl/font.hxx> #include <svx/fontitem.hxx> @@ -44,9 +43,11 @@ #include <paratr.hxx> #include <charfmt.hxx> #include <ndtxt.hxx> -#ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_ #include <com/sun/star/i18n/ScriptType.hdl> -#endif + +#include <writerfilter/doctok/sprmids.hxx> + +#include "ww8attributeoutput.hxx" #include "writerhelper.hxx" #include "writerwordglue.hxx" #include "wrtww8.hxx" @@ -61,56 +62,51 @@ using namespace ::com::sun::star; using namespace sw::types; using namespace sw::util; -USHORT SwWW8Writer::DupNumRuleWithLvlStart(const SwNumRule *pRule,BYTE nLvl, - USHORT nVal) +USHORT MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, BYTE nLevel, USHORT nVal ) { - //List is set to restart at a particular value so for export make a - //completely new list based on this one and export that instead, - //which duplicates words behaviour in this respect. USHORT nNumId = USHRT_MAX; - String sPrefix(CREATE_CONST_ASC("WW8TempExport")); + String sPrefix( CREATE_CONST_ASC( "WW8TempExport" ) ); sPrefix += String::CreateFromInt32( nUniqueList++ ); // --> OD 2008-02-11 #newlistlevelattrs# SwNumRule* pMyNumRule = - new SwNumRule( pDoc->GetUniqueNumRuleName(&sPrefix), + new SwNumRule( pDoc->GetUniqueNumRuleName( &sPrefix ), SvxNumberFormat::LABEL_WIDTH_AND_POSITION ); // <-- pUsedNumTbl->Insert( pMyNumRule, pUsedNumTbl->Count() ); - for (USHORT i=0;i<MAXLEVEL;i++) + for ( USHORT i = 0; i < MAXLEVEL; i++ ) { const SwNumFmt& rSubRule = pRule->Get(i); pMyNumRule->Set( i, rSubRule ); } - SwNumFmt aNumFmt(pMyNumRule->Get(nLvl)); - aNumFmt.SetStart(nVal); - pMyNumRule->Set(nLvl,aNumFmt); + SwNumFmt aNumFmt( pMyNumRule->Get( nLevel ) ); + aNumFmt.SetStart( nVal ); + pMyNumRule->Set( nLevel, aNumFmt ); nNumId = GetId( *pMyNumRule ); //Map the old list to our new list - aRuleDuplicates[GetId(*pRule)] = nNumId; + aRuleDuplicates[GetId( *pRule )] = nNumId; return nNumId; } -USHORT SwWW8Writer::GetId( const SwNumRule& rNumRule ) const +USHORT MSWordExportBase::GetId( const SwNumRule& rNumRule ) { - if( !pUsedNumTbl ) + if ( !pUsedNumTbl ) { - SwWW8Writer* pThis = (SwWW8Writer*)this; - pThis->pUsedNumTbl = new SwNumRuleTbl; - pThis->pUsedNumTbl->Insert( &pDoc->GetNumRuleTbl(), 0 ); + pUsedNumTbl = new SwNumRuleTbl; + pUsedNumTbl->Insert( &pDoc->GetNumRuleTbl(), 0 ); // --> OD 2005-10-17 #126238# - Check, if the outline rule is // already inserted into <pUsedNumTbl>. If yes, do not insert it again. bool bOutlineRuleAdded( false ); - for( USHORT n = pUsedNumTbl->Count(); n; ) + for ( USHORT n = pUsedNumTbl->Count(); n; ) { const SwNumRule& rRule = *pUsedNumTbl->GetObject( --n ); if ( !pDoc->IsUsed( rRule ) ) { - pThis->pUsedNumTbl->Remove( n ); + pUsedNumTbl->Remove( n ); } else if ( &rRule == pDoc->GetOutlineNumRule() ) { @@ -122,7 +118,7 @@ USHORT SwWW8Writer::GetId( const SwNumRule& rNumRule ) const { // jetzt noch die OutlineRule einfuegen SwNumRule* pR = (SwNumRule*)pDoc->GetOutlineNumRule(); - pThis->pUsedNumTbl->Insert( pR, pUsedNumTbl->Count() ); + pUsedNumTbl->Insert( pR, pUsedNumTbl->Count() ); } // <-- } @@ -160,58 +156,174 @@ sal_Int16 GetWordFirstLineOffset(const SwNumFmt &rFmt) return nFirstLineOffset; } -void SwWW8Writer::OutListTab() +void WW8Export::WriteNumbering() { - if( !pUsedNumTbl ) - return ; // no numbering is used - - USHORT nCount = pUsedNumTbl->Count(); - USHORT n; + if ( !pUsedNumTbl ) + return; // no numbering is used + // list formats - LSTF pFib->fcPlcfLst = pTableStrm->Tell(); - SwWW8Writer::WriteShort( *pTableStrm, nCount ); + SwWW8Writer::WriteShort( *pTableStrm, pUsedNumTbl->Count() ); + NumberingDefinitions(); + // set len to FIB + pFib->lcbPlcfLst = pTableStrm->Tell() - pFib->fcPlcfLst; - // First Loop - write static data of SwNumRule - LSTF - for( n = 0; n < nCount; ++n ) + // list formats - LVLF + AbstractNumberingDefinitions(); + + // list formats - LFO + OutOverrideListTab(); + + // list formats - ListNames + OutListNamesTab(); +} + +void WW8AttributeOutput::NumberingDefinition( USHORT nId, const SwNumRule &rRule ) +{ + SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId ); + SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId ); + + // mit keinen Styles verbunden + for ( int i = 0; i < WW8ListManager::nMaxLevel; ++i ) + SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0xFFF ); + + BYTE nFlags = 0, nDummy = 0; + if ( rRule.IsContinusNum() ) + nFlags |= 0x1; + + *m_rWW8Export.pTableStrm << nFlags << nDummy; +} + +void MSWordExportBase::NumberingDefinitions() +{ + if ( !pUsedNumTbl ) + return; // no numbering is used + + USHORT nCount = pUsedNumTbl->Count(); + + // Write static data of SwNumRule - LSTF + for ( USHORT n = 0; n < nCount; ++n ) { const SwNumRule& rRule = *pUsedNumTbl->GetObject( n ); - SwWW8Writer::WriteLong( *pTableStrm, n + 1 ); - SwWW8Writer::WriteLong( *pTableStrm, n + 1 ); + AttrOutput().NumberingDefinition( n + 1, rRule ); + } +} - // mit keinen Styles verbunden - for( int i = 0; i < WW8ListManager::nMaxLevel; ++i ) - SwWW8Writer::WriteShort( *pTableStrm, 0xFFF ); +void WW8AttributeOutput::NumberingLevel( BYTE /*nLevel*/, + USHORT nStart, + USHORT nNumberingType, + SvxAdjust eAdjust, + const BYTE *pNumLvlPos, + BYTE nFollow, + const wwFont *pFont, + const SfxItemSet *pOutSet, + sal_Int16 nIndentAt, + sal_Int16 nFirstLineIndex, + sal_Int16 nListTabPos, + const String &rNumberingString + ) +{ + // Start value + SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nStart ); + + // Type + *m_rWW8Export.pTableStrm << WW8Export::GetNumId( nNumberingType ); - BYTE nFlags = 0, nDummy = 0; - if( rRule.IsContinusNum() ) - nFlags |= 0x1; - *pTableStrm << nFlags << nDummy; + // Justification + BYTE nAlign; + switch ( eAdjust ) + { + case SVX_ADJUST_CENTER: nAlign = 1; break; + default: nAlign = 0; break; } + *m_rWW8Export.pTableStrm << nAlign; - // set len to FIB - pFib->lcbPlcfLst = pTableStrm->Tell() - pFib->fcPlcfLst; + // Write the rgbxchNums[9], positions of placeholders for paragraph + // numbers in the text + m_rWW8Export.pTableStrm->Write( pNumLvlPos, WW8ListManager::nMaxLevel ); - // second Loop - write all Levels for all SwNumRules - LVLF + // Type of the character between the bullet and the text + *m_rWW8Export.pTableStrm << nFollow; - // prepare the NodeNum to generate the NumString - SwNumberTree::tNumberVector aNumVector; - for (n = 0; n < WW8ListManager::nMaxLevel; ++n) - aNumVector.push_back(n); + // dxaSoace/dxaIndent (Word 6 compatibility) + SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 ); + SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 ); + + // cbGrpprlChpx + WW8Bytes aCharAtrs; + if ( pOutSet ) + { + WW8Bytes* pOldpO = m_rWW8Export.pO; + m_rWW8Export.pO = &aCharAtrs; + if ( pFont ) + { + USHORT nFontID = m_rWW8Export.maFontHelper.GetId( *pFont ); + if ( m_rWW8Export.bWrtWW8 ) + { + m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc0 ); + m_rWW8Export.InsUInt16( nFontID ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc2 ); + } + else + m_rWW8Export.pO->Insert( 93, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( nFontID ); + } + + m_rWW8Export.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN ); + + m_rWW8Export.pO = pOldpO; + } + *m_rWW8Export.pTableStrm << BYTE( aCharAtrs.Count() ); + + // cbGrpprlPapx BYTE aPapSprms [] = { 0x5e, 0x84, 0, 0, // sprmPDxaLeft 0x60, 0x84, 0, 0, // sprmPDxaLeft1 0x15, 0xc6, 0x05, 0x00, 0x01, 0, 0, 0x06 }; + *m_rWW8Export.pTableStrm << BYTE( sizeof( aPapSprms ) ); + + // reserved + SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0 ); + + // pap sprms + BYTE* pData = aPapSprms + 2; + Set_UInt16( pData, nIndentAt ); + pData += 2; + Set_UInt16( pData, nFirstLineIndex ); + pData += 5; + Set_UInt16( pData, nListTabPos ); + + m_rWW8Export.pTableStrm->Write( aPapSprms, sizeof( aPapSprms )); + + // write Chpx + if( aCharAtrs.Count() ) + m_rWW8Export.pTableStrm->Write( aCharAtrs.GetData(), aCharAtrs.Count() ); + + // write the num string + SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, rNumberingString.Len() ); + SwWW8Writer::WriteString16( *m_rWW8Export.pTableStrm, rNumberingString, false ); +} + +void MSWordExportBase::AbstractNumberingDefinitions() +{ + USHORT nCount = pUsedNumTbl->Count(); + USHORT n; + + // prepare the NodeNum to generate the NumString + SwNumberTree::tNumberVector aNumVector; + for ( n = 0; n < WW8ListManager::nMaxLevel; ++n ) + aNumVector.push_back( n ); StarSymbolToMSMultiFont *pConvert = 0; for( n = 0; n < nCount; ++n ) { + AttrOutput().StartAbstractNumbering( n + 1 ); + const SwNumRule& rRule = *pUsedNumTbl->GetObject( n ); BYTE nLvl; - BYTE nFlags = 0; - BYTE nAlign; BYTE nLevels = static_cast< BYTE >(rRule.IsContinusNum() ? WW8ListManager::nMinLevel : WW8ListManager::nMaxLevel); for( nLvl = 0; nLvl < nLevels; ++nLvl ) @@ -220,49 +332,23 @@ void SwWW8Writer::OutListTab() BYTE aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 }; const SwNumFmt& rFmt = rRule.Get( nLvl ); - SwWW8Writer::WriteLong( *pTableStrm, rFmt.GetStart() ); - *pTableStrm << SwWW8Writer::GetNumId( rFmt.GetNumberingType() ); - - switch( rFmt.GetNumAdjust() ) - { - case SVX_ADJUST_CENTER: - nAlign = 1; - break; - default: - nAlign = 0; - break; - } - *pTableStrm << nAlign; + BYTE nFollow = 0; // --> OD 2008-06-03 #i86652# - if ( rFmt.GetPositionAndSpaceMode() == - SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) + if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) { - nFlags = 2; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing + nFollow = 2; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing } - else if ( rFmt.GetPositionAndSpaceMode() == - SvxNumberFormat::LABEL_ALIGNMENT ) + else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT ) { switch ( rFmt.GetLabelFollowedBy() ) { - case SvxNumberFormat::LISTTAB: - { - nFlags = 0; - } - break; - case SvxNumberFormat::SPACE: - { - nFlags = 1; - } - break; - case SvxNumberFormat::NOTHING: - { - nFlags = 2; - } - break; + case SvxNumberFormat::LISTTAB: nFollow = 0; break; + case SvxNumberFormat::SPACE: nFollow = 1; break; + case SvxNumberFormat::NOTHING: nFollow = 2; break; default: { - nFlags = 0; + nFollow = 0; ASSERT( false, "unknown GetLabelFollowedBy() return value" ); } @@ -293,19 +379,19 @@ void SwWW8Writer::OutListTab() sFontName = pBulletFont->GetName(); eFamily = pBulletFont->GetFamily(); - if (sw::util::IsStarSymbol(sFontName)) - SubstituteBullet(sNumStr,eChrSet,sFontName); + if ( sw::util::IsStarSymbol( sFontName ) ) + SubstituteBullet( sNumStr, eChrSet, sFontName ); // --> OD 2008-06-03 #i86652# if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) { // --> OD 2007-07-23 #148661# - // <nFlags = 2>, if minimum label width equals 0 and + // <nFollow = 2>, if minimum label width equals 0 and // minimum distance between label and text equals 0 - nFlags = ( rFmt.GetFirstLineOffset() == 0 && - rFmt.GetCharTextDistance() == 0 ) - ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing + nFollow = ( rFmt.GetFirstLineOffset() == 0 && + rFmt.GetCharTextDistance() == 0 ) + ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing // <-- } // <-- @@ -337,11 +423,11 @@ void SwWW8Writer::OutListTab() SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) { // --> OD 2007-07-23 #148661# - // <nFlags = 2>, if minimum label width equals 0 and + // <nFollow = 2>, if minimum label width equals 0 and // minimum distance between label and text equals 0 - nFlags = ( rFmt.GetFirstLineOffset() == 0 && - rFmt.GetCharTextDistance() == 0 ) - ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing + nFollow = ( rFmt.GetFirstLineOffset() == 0 && + rFmt.GetCharTextDistance() == 0 ) + ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing // <-- } // <-- @@ -352,113 +438,70 @@ void SwWW8Writer::OutListTab() sNumStr += rFmt.GetSuffix(); } - // write the rgbxchNums[9] - pTableStrm->Write(aNumLvlPos, WW8ListManager::nMaxLevel); - - *pTableStrm << nFlags; - // dxaSoace/dxaIndent (Word 6 compatibility) - SwWW8Writer::WriteLong( *pTableStrm, 0 ); - SwWW8Writer::WriteLong( *pTableStrm, 0 ); + // Attributes of the numbering + wwFont *pPseudoFont = NULL; + const SfxItemSet* pOutSet = NULL; // cbGrpprlChpx - WW8Bytes aCharAtrs; - if( rFmt.GetCharFmt() || bWriteBullet ) + SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_BEGIN, + RES_CHRATR_END ); + if ( rFmt.GetCharFmt() || bWriteBullet ) { - WW8Bytes* pOldpO = pO; - pO = &aCharAtrs; - SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_BEGIN, - RES_CHRATR_END ); - const SfxItemSet* pOutSet; - if (bWriteBullet) + if ( bWriteBullet ) { pOutSet = &aSet; - if (rFmt.GetCharFmt()) + if ( rFmt.GetCharFmt() ) aSet.Put( rFmt.GetCharFmt()->GetAttrSet() ); - aSet.ClearItem(RES_CHRATR_CJK_FONT); - aSet.ClearItem(RES_CHRATR_FONT); + aSet.ClearItem( RES_CHRATR_CJK_FONT ); + aSet.ClearItem( RES_CHRATR_FONT ); - if (!sFontName.Len()) + if ( !sFontName.Len() ) sFontName = pBulletFont->GetName(); - wwFont aPseudoFont(sFontName, pBulletFont->GetPitch(), - eFamily, eChrSet, bWrtWW8); - USHORT nFontID = maFontHelper.GetId(aPseudoFont); - - if (bWrtWW8) - { - InsUInt16(0x4a4f); - InsUInt16(nFontID); - InsUInt16(0x4a51); - } - else - pO->Insert(93, pO->Count()); - InsUInt16(nFontID); + pPseudoFont = new wwFont( sFontName, pBulletFont->GetPitch(), + eFamily, eChrSet, HackIsWW8OrHigher() ); } else pOutSet = &rFmt.GetCharFmt()->GetAttrSet(); - - Out_SfxItemSet(*pOutSet, false, true, i18n::ScriptType::LATIN); - - pO = pOldpO; } - nFlags = (BYTE)aCharAtrs.Count(); - *pTableStrm << nFlags; - - // cbGrpprlPapx - nFlags = sizeof( aPapSprms ); - *pTableStrm << nFlags; - // reserved - SwWW8Writer::WriteShort( *pTableStrm, 0 ); + sal_Int16 nIndentAt = 0; + sal_Int16 nFirstLineIndex = 0; + sal_Int16 nListTabPos = 0; // --> OD 2008-06-03 #i86652# - if ( rFmt.GetPositionAndSpaceMode() == - SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) + if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) { - const sal_uInt16 nAbsLSpace = rFmt.GetAbsLSpace(); - const sal_Int16 nFirstLineOffset = GetWordFirstLineOffset(rFmt); - - // write Papx - BYTE* pData = aPapSprms + 2; - Set_UInt16( pData, nAbsLSpace ); - pData += 2; - Set_UInt16( pData, nFirstLineOffset ); - pData += 5; - Set_UInt16( pData, nAbsLSpace ); + nIndentAt = nListTabPos = rFmt.GetAbsLSpace(); + nFirstLineIndex = GetWordFirstLineOffset(rFmt); } - else if ( rFmt.GetPositionAndSpaceMode() == - SvxNumberFormat::LABEL_ALIGNMENT ) + else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT ) { - const sal_Int16 nIndentAt = static_cast<sal_Int16>(rFmt.GetIndentAt()); - const sal_Int16 nFirstLineIndenx = static_cast<sal_Int16>(rFmt.GetFirstLineIndent()); - const sal_Int16 nListTabPos = - rFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB - ? static_cast<sal_Int16>(rFmt.GetListtabPos()) - : 0; - // write Papx - BYTE* pData = aPapSprms + 2; - Set_UInt16( pData, nIndentAt ); - pData += 2; - Set_UInt16( pData, nFirstLineIndenx ); - pData += 5; - Set_UInt16( pData, nListTabPos ); + nIndentAt = static_cast<sal_Int16>(rFmt.GetIndentAt()); + nFirstLineIndex = static_cast<sal_Int16>(rFmt.GetFirstLineIndent()); + nListTabPos = rFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB? + static_cast<sal_Int16>( rFmt.GetListtabPos() ) : 0; } - pTableStrm->Write( aPapSprms, sizeof( aPapSprms )); - // write Chpx - if( aCharAtrs.Count() ) - pTableStrm->Write( aCharAtrs.GetData(), aCharAtrs.Count() ); - - // write the num string - SwWW8Writer::WriteShort(*pTableStrm, sNumStr.Len()); - SwWW8Writer::WriteString16(*pTableStrm, sNumStr, false); + AttrOutput().NumberingLevel( nLvl, + rFmt.GetStart(), + rFmt.GetNumberingType(), + rFmt.GetNumAdjust(), + aNumLvlPos, + nFollow, + pPseudoFont, pOutSet, + nIndentAt, nFirstLineIndex, nListTabPos, + sNumStr ); + + delete pPseudoFont; } + AttrOutput().EndAbstractNumbering(); } delete pConvert; } -void SwWW8Writer::OutOverrideListTab() +void WW8Export::OutOverrideListTab() { if( !pUsedNumTbl ) return ; // no numbering is used @@ -482,7 +525,7 @@ void SwWW8Writer::OutOverrideListTab() pFib->lcbPlfLfo = pTableStrm->Tell() - pFib->fcPlfLfo; } -void SwWW8Writer::OutListNamesTab() +void WW8Export::OutListNamesTab() { if( !pUsedNumTbl ) return ; // no numbering is used @@ -515,8 +558,11 @@ void SwWW8Writer::OutListNamesTab() // old WW95-Code -void SwWW8Writer::Out_Olst( const SwNumRule& rRule ) +void WW8Export::OutputOlst( const SwNumRule& rRule ) { + if ( bWrtWW8 ) + return; + static BYTE __READONLY_DATA aAnlvBase[] = { // Defaults 1,0,0, // Upper Roman 0x0C, // Hanging Indent, fPrev @@ -545,13 +591,13 @@ void SwWW8Writer::Out_Olst( const SwNumRule& rRule ) } -void SwWW8Writer::Out_WwNumLvl( BYTE nWwLevel ) +void WW8Export::Out_WwNumLvl( BYTE nWwLevel ) { pO->Insert( 13, pO->Count() ); pO->Insert( nWwLevel, pO->Count() ); } -void SwWW8Writer::Out_SwNumLvl( BYTE nSwLevel ) +void WW8Export::Out_SwNumLvl( BYTE nSwLevel ) { // --> OD 2008-04-02 #refactorlists# // ASSERT(IsNum(nSwLevel), "numbered?"); @@ -560,7 +606,7 @@ void SwWW8Writer::Out_SwNumLvl( BYTE nSwLevel ) Out_WwNumLvl( nSwLevel + 1 ); } -void SwWW8Writer::BuildAnlvBulletBase(WW8_ANLV& rAnlv, BYTE*& rpCh, +void WW8Export::BuildAnlvBulletBase(WW8_ANLV& rAnlv, BYTE*& rpCh, USHORT& rCharLen, const SwNumFmt& rFmt) { ByteToSVBT8(11, rAnlv.nfc); @@ -658,8 +704,8 @@ void SwWW8Writer::BuildAnlvBulletBase(WW8_ANLV& rAnlv, BYTE*& rpCh, // <-- } -void SwWW8Writer::SubstituteBullet(String& rNumStr, - rtl_TextEncoding& rChrSet, String& rFontName) const +void MSWordExportBase::SubstituteBullet( String& rNumStr, + rtl_TextEncoding& rChrSet, String& rFontName ) const { StarSymbolToMSMultiFont *pConvert = 0; FontFamily eFamily = FAMILY_DECORATIVE; @@ -686,7 +732,7 @@ void SwWW8Writer::SubstituteBullet(String& rNumStr, rFontName = sFont; rChrSet = RTL_TEXTENCODING_SYMBOL; } - else if ( bWrtWW8 && + else if ( HackIsWW8OrHigher() && (rNumStr.GetChar(0) < 0xE000 || rNumStr.GetChar(0) > 0xF8FF) ) { /* @@ -730,11 +776,11 @@ static void SwWw8_InsertAnlText( const String& rStr, BYTE*& rpCh, ByteToSVBT8( nb, r8Len ); } -void SwWW8Writer::BuildAnlvBase(WW8_ANLV& rAnlv, BYTE*& rpCh, +void WW8Export::BuildAnlvBase(WW8_ANLV& rAnlv, BYTE*& rpCh, USHORT& rCharLen, const SwNumRule& rRul, const SwNumFmt& rFmt, BYTE nSwLevel) { - ByteToSVBT8(SwWW8Writer::GetNumId(rFmt.GetNumberingType()), rAnlv.nfc); + ByteToSVBT8(WW8Export::GetNumId(rFmt.GetNumberingType()), rAnlv.nfc); BYTE nb = 0; switch (rFmt.GetNumAdjust()) @@ -802,7 +848,7 @@ void SwWW8Writer::BuildAnlvBase(WW8_ANLV& rAnlv, BYTE*& rpCh, // <-- } -void SwWW8Writer::Out_NumRuleAnld( const SwNumRule& rRul, const SwNumFmt& rFmt, +void WW8Export::Out_NumRuleAnld( const SwNumRule& rRul, const SwNumFmt& rFmt, BYTE nSwLevel ) { static BYTE __READONLY_DATA aSprmAnldDefault[54] = { @@ -830,7 +876,7 @@ void SwWW8Writer::Out_NumRuleAnld( const SwNumRule& rRul, const SwNumFmt& rFmt, // Return: ist es eine Gliederung ? -bool SwWW8Writer::Out_SwNum(const SwTxtNode* pNd) +bool WW8Export::Out_SwNum(const SwTxtNode* pNd) { int nLevel = pNd->GetActualListLevel(); diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx index a28067b9367d..a0ef954869b6 100644 --- a/sw/source/filter/ww8/wrtw8sty.cxx +++ b/sw/source/filter/ww8/wrtw8sty.cxx @@ -33,17 +33,10 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ - -#ifndef __SGI_STL_ALGORITHM #include <algorithm> -#endif -#ifndef __SGI_STL_FUNCTIONAL #include <functional> -#endif -#ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_ #include <com/sun/star/i18n/ScriptType.hdl> -#endif #include <rtl/tencinfo.h> #include <hintids.hxx> #include <svx/boxitem.hxx> @@ -76,16 +69,22 @@ #include <ftnidx.hxx> #include <fmtclds.hxx> #include <lineinfo.hxx> +#include <fmtline.hxx> +#include <swtable.hxx> #include <msfilter.hxx> -# include "writerhelper.hxx" -# include "writerwordglue.hxx" -# include "../inc/wwstyles.hxx" + +#include <writerfilter/doctok/sprmids.hxx> + +#include "writerhelper.hxx" +#include "writerwordglue.hxx" +#include "../inc/wwstyles.hxx" #include "ww8par.hxx" +#include "ww8attributeoutput.hxx" +#include "docxattributeoutput.hxx" using namespace sw::util; using namespace nsHdFtFlags; - struct WW8_SED { SVBT16 aBits1; // orientation change + internal, Default: 6 @@ -97,13 +96,6 @@ struct WW8_SED // cbSED is 12 (decimal)), C (hex). }; -struct WW8_PdAttrDesc -{ - BYTE* pData; - USHORT nLen; - WW8_FC nSepxFcPos; -}; - SV_IMPL_VARARR( WW8_WrSepInfoPtrs, WW8_SepInfo ) // class WW8_WrPlc0 ist erstmal nur fuer Header / Footer-Positionen, d.h. es @@ -132,89 +124,91 @@ public: // GetId( SwCharFmt ) zur Benutzung im Text -> nil verboten, // "Default Char Style" stattdessen -USHORT SwWW8Writer::GetId( const SwCharFmt& rFmt ) const +USHORT MSWordExportBase::GetId( const SwCharFmt& rFmt ) const { - USHORT nRet = pStyles->Sty_GetWWSlot( rFmt ); + USHORT nRet = pStyles->GetSlot( rFmt ); return ( nRet != 0x0fff ) ? nRet : 10; // Default Char Style } // GetId( SwTxtFmtColl ) zur Benutzung an TextNodes -> nil verboten, // "Standard" stattdessen -USHORT SwWW8Writer::GetId( const SwTxtFmtColl& rColl ) const +USHORT MSWordExportBase::GetId( const SwTxtFmtColl& rColl ) const { - USHORT nRet = pStyles->Sty_GetWWSlot( rColl ); + USHORT nRet = pStyles->GetSlot( rColl ); return ( nRet != 0xfff ) ? nRet : 0; // Default TxtFmtColl } //typedef pFmtT -WW8WrtStyle::WW8WrtStyle( SwWW8Writer& rWr ) - : rWrt( rWr ), nPOPosStdLen1( 0 ), nPOPosStdLen2( 0 ) +MSWordStyles::MSWordStyles( MSWordExportBase& rExport ) + : m_rExport( rExport ) { - rWrt.pO->Remove( 0, rWrt.pO->Count() ); // leeren - SwDoc& rDoc = *rWrt.pDoc; - // if exist any Foot-/End-Notes then get from the EndNoteInfo struct // the CharFormats. They will create it! - if( rDoc.GetFtnIdxs().Count() ) + if ( m_rExport.pDoc->GetFtnIdxs().Count() ) { - rDoc.GetEndNoteInfo().GetAnchorCharFmt( rDoc ); - rDoc.GetEndNoteInfo().GetCharFmt( rDoc ); - rDoc.GetFtnInfo().GetAnchorCharFmt( rDoc ); - rDoc.GetFtnInfo().GetCharFmt( rDoc ); + m_rExport.pDoc->GetEndNoteInfo().GetAnchorCharFmt( *m_rExport.pDoc ); + m_rExport.pDoc->GetEndNoteInfo().GetCharFmt( *m_rExport.pDoc ); + m_rExport.pDoc->GetFtnInfo().GetAnchorCharFmt( *m_rExport.pDoc ); + m_rExport.pDoc->GetFtnInfo().GetCharFmt( *m_rExport.pDoc ); } - USHORT nAlloc = WW8_RESERVED_SLOTS + rDoc.GetCharFmts()->Count() - 1 + - rDoc.GetTxtFmtColls()->Count() - 1; - // etwas grosszuegig ( bis zu 15 frei ) + USHORT nAlloc = WW8_RESERVED_SLOTS + m_rExport.pDoc->GetCharFmts()->Count() - 1 + + m_rExport.pDoc->GetTxtFmtColls()->Count() - 1; + + // etwas grosszuegig ( bis zu 15 frei ) pFmtA = new SwFmt*[ nAlloc ]; memset( pFmtA, 0, nAlloc * sizeof( SwFmt* ) ); - BuildStyleTab(); + + BuildStylesTable(); } -WW8WrtStyle::~WW8WrtStyle() +MSWordStyles::~MSWordStyles() { delete[] pFmtA; - rWrt.pO->Remove( 0, rWrt.pO->Count() ); // leeren } // Sty_SetWWSlot() fuer Abhaengigkeiten der Styles -> nil ist erlaubt -USHORT WW8WrtStyle::Sty_GetWWSlot( const SwFmt& rFmt ) const +USHORT MSWordStyles::GetSlot( const SwFmt& rFmt ) const { USHORT n; - for( n = 0; n < nUsedSlots; n++ ) - if( pFmtA[n] == &rFmt ) + for ( n = 0; n < nUsedSlots; n++ ) + if ( pFmtA[n] == &rFmt ) return n; return 0xfff; // 0xfff: WW: nil } -USHORT WW8WrtStyle::Build_GetWWSlot( const SwFmt& rFmt ) +USHORT MSWordStyles::BuildGetSlot( const SwFmt& rFmt ) { USHORT nRet; - switch( nRet = rFmt.GetPoolFmtId() ) - { - case RES_POOLCOLL_STANDARD: nRet = 0; break; - - case RES_POOLCOLL_HEADLINE1: - case RES_POOLCOLL_HEADLINE2: - case RES_POOLCOLL_HEADLINE3: - case RES_POOLCOLL_HEADLINE4: - case RES_POOLCOLL_HEADLINE5: - case RES_POOLCOLL_HEADLINE6: - case RES_POOLCOLL_HEADLINE7: - case RES_POOLCOLL_HEADLINE8: - case RES_POOLCOLL_HEADLINE9: nRet -= RES_POOLCOLL_HEADLINE1-1; break; - -// case RES_POOLCHR_FOOTNOTE_ANCHOR: nRet = -// case RES_POOLCHR_ENDNOTE_ANCHOR: - default: - nRet = nUsedSlots++; - break; + switch ( nRet = rFmt.GetPoolFmtId() ) + { + case RES_POOLCOLL_STANDARD: + nRet = 0; + break; + + case RES_POOLCOLL_HEADLINE1: + case RES_POOLCOLL_HEADLINE2: + case RES_POOLCOLL_HEADLINE3: + case RES_POOLCOLL_HEADLINE4: + case RES_POOLCOLL_HEADLINE5: + case RES_POOLCOLL_HEADLINE6: + case RES_POOLCOLL_HEADLINE7: + case RES_POOLCOLL_HEADLINE8: + case RES_POOLCOLL_HEADLINE9: + nRet -= RES_POOLCOLL_HEADLINE1-1; + break; + + //case RES_POOLCHR_FOOTNOTE_ANCHOR: nRet = + //case RES_POOLCHR_ENDNOTE_ANCHOR: + default: + nRet = nUsedSlots++; + break; } return nRet; } -USHORT WW8WrtStyle::GetWWId( const SwFmt& rFmt ) const +USHORT MSWordStyles::GetWWId( const SwFmt& rFmt ) const { USHORT nRet = ww::stiUser; // User-Style als default USHORT nPoolId = rFmt.GetPoolFmtId(); @@ -262,45 +256,52 @@ USHORT WW8WrtStyle::GetWWId( const SwFmt& rFmt ) const return nRet; } -void WW8WrtStyle::BuildStyleTab() +void MSWordStyles::BuildStylesTable() { nUsedSlots = WW8_RESERVED_SLOTS; // soviele sind reserviert fuer // Standard und HeadingX u.a. SwFmt* pFmt; USHORT n; - const SvPtrarr& rArr = *rWrt.pDoc->GetCharFmts(); // erst CharFmt - // das Default-ZeichenStyle ( 0 ) wird nicht mit ausgegeben ! + const SvPtrarr& rArr = *m_rExport.pDoc->GetCharFmts(); // erst CharFmt + // das Default-ZeichenStyle ( 0 ) wird nicht mit ausgegeben ! for( n = 1; n < rArr.Count(); n++ ) { pFmt = (SwFmt*)rArr[n]; - pFmtA[ Build_GetWWSlot( *pFmt ) ] = pFmt; + pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt; } - const SvPtrarr& rArr2 = *rWrt.pDoc->GetTxtFmtColls(); // dann TxtFmtColls - // das Default-TextStyle ( 0 ) wird nicht mit ausgegeben ! + + const SvPtrarr& rArr2 = *m_rExport.pDoc->GetTxtFmtColls(); // dann TxtFmtColls + // das Default-TextStyle ( 0 ) wird nicht mit ausgegeben ! for( n = 1; n < rArr2.Count(); n++ ) { pFmt = (SwFmt*)rArr2[n]; - pFmtA[ Build_GetWWSlot( *pFmt ) ] = pFmt; + pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt; } } -void WW8WrtStyle::WriteStyle( SvStream& rStrm ) +/// For WW8 only - extend pO so that the size of pTableStrm is even. +static void impl_SkipOdd( WW8Bytes* pO, sal_Size nTableStrmTell ) +{ + if ( ( nTableStrmTell + pO->Count() ) & 1 ) // Start auf gerader + pO->Insert( (BYTE)0, pO->Count() ); // Adresse +} + +void WW8AttributeOutput::EndStyle() { - WW8Bytes* pO = rWrt.pO; + impl_SkipOdd( m_rWW8Export.pO, m_rWW8Export.pTableStrm->Tell() ); - short nLen = pO->Count() - 2; // Laenge des Styles - BYTE* p = (BYTE*)pO->GetData() + nPOPosStdLen1; + short nLen = m_rWW8Export.pO->Count() - 2; // Laenge des Styles + BYTE* p = (BYTE*)m_rWW8Export.pO->GetData() + nPOPosStdLen1; ShortToSVBT16( nLen, p ); // nachtragen - p = (BYTE*)pO->GetData() + nPOPosStdLen2; + p = (BYTE*)m_rWW8Export.pO->GetData() + nPOPosStdLen2; ShortToSVBT16( nLen, p ); // dito - rStrm.Write( pO->GetData(), pO->Count() ); // ins File damit - pO->Remove( 0, pO->Count() ); // leeren fuer naechsten + m_rWW8Export.pTableStrm->Write( m_rWW8Export.pO->GetData(), m_rWW8Export.pO->Count() ); // ins File damit + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren fuer naechsten } - -void WW8WrtStyle::BuildStd(const String& rName, bool bPapFmt, short nWwBase, - short nWwNext, USHORT nWwId) +void WW8AttributeOutput::StartStyle( const String& rName, bool bPapFmt, USHORT nWwBase, + USHORT nWwNext, USHORT nWwId, USHORT /*nId*/ ) { BYTE aWW8_STD[ sizeof( WW8_STD ) ]; BYTE* pData = aWW8_STD; @@ -320,7 +321,7 @@ void WW8WrtStyle::BuildStd(const String& rName, bool bPapFmt, short nWwBase, pData += sizeof( UINT16 ); // bchUpe - if( rWrt.bWrtWW8 ) + if( m_rWW8Export.bWrtWW8 ) { //-------- jetzt neu: // ab Ver8 gibts zwei Felder mehr: @@ -332,9 +333,9 @@ void WW8WrtStyle::BuildStd(const String& rName, bool bPapFmt, short nWwBase, UINT16 nLen = static_cast< UINT16 >( ( pData - aWW8_STD ) + 1 + - ((rWrt.bWrtWW8 ? 2 : 1 ) * (rName.Len() + 1)) ); // vorlaeufig + ((m_rWW8Export.bWrtWW8 ? 2 : 1 ) * (rName.Len() + 1)) ); // vorlaeufig - WW8Bytes* pO = rWrt.pO; + WW8Bytes* pO = m_rWW8Export.pO; nPOPosStdLen1 = pO->Count(); // Adr1 zum nachtragen der Laenge SwWW8Writer::InsUInt16( *pO, nLen ); @@ -343,7 +344,7 @@ void WW8WrtStyle::BuildStd(const String& rName, bool bPapFmt, short nWwBase, nPOPosStdLen2 = nPOPosStdLen1 + 8; // Adr2 zum nachtragen von "end of upx" // Namen schreiben - if( rWrt.bWrtWW8 ) + if( m_rWW8Export.bWrtWW8 ) { SwWW8Writer::InsUInt16( *pO, rName.Len() ); // Laenge SwWW8Writer::InsAsString16( *pO, rName ); @@ -356,17 +357,10 @@ void WW8WrtStyle::BuildStd(const String& rName, bool bPapFmt, short nWwBase, pO->Insert( (BYTE)0, pO->Count() ); // Trotz P-String 0 am Ende! } -void WW8WrtStyle::SkipOdd() // Ruecke zu gerader Adresse vor +void MSWordStyles::SetStyleDefaults( const SwFmt& rFmt, bool bPap ) { - WW8Bytes* pO = rWrt.pO; - if( ( rWrt.pTableStrm->Tell() + pO->Count() ) & 1 ) // Start auf gerader - pO->Insert( (BYTE)0, pO->Count() ); // Adresse -} - -void WW8WrtStyle::Set1StyleDefaults(const SwFmt& rFmt, bool bPap) -{ - const SwModify* pOldMod = rWrt.pOutFmtNode; - rWrt.pOutFmtNode = &rFmt; + const SwModify* pOldMod = m_rExport.pOutFmtNode; + m_rExport.pOutFmtNode = &rFmt; bool aFlags[ static_cast< USHORT >(RES_FRMATR_END) - RES_CHRATR_BEGIN ]; USHORT nStt, nEnd, n; if( bPap ) @@ -391,95 +385,101 @@ void WW8WrtStyle::Set1StyleDefaults(const SwFmt& rFmt, bool bPap) aFlags[ RES_CHRATR_LANGUAGE - RES_CHRATR_BEGIN ] = 1; } - const SfxItemSet* pOldI = rWrt.GetCurItemSet(); - rWrt.SetCurItemSet( &rFmt.GetAttrSet() ); + const SfxItemSet* pOldI = m_rExport.GetCurItemSet(); + m_rExport.SetCurItemSet( &rFmt.GetAttrSet() ); const bool* pFlags = aFlags + ( nStt - RES_CHRATR_BEGIN ); - for( n = nStt; n < nEnd; ++n, ++pFlags ) + for ( n = nStt; n < nEnd; ++n, ++pFlags ) { - if( *pFlags && SFX_ITEM_SET != rFmt.GetItemState(n, false)) + if ( *pFlags && SFX_ITEM_SET != rFmt.GetItemState(n, false)) { //If we are a character property then see if it is one of the //western/asian ones that must be collapsed together for export to //word. If so default to the western varient. - if ( bPap || rWrt.CollapseScriptsforWordOk( + if ( bPap || m_rExport.CollapseScriptsforWordOk( i18n::ScriptType::LATIN, n) ) { - Out(aWW8AttrFnTab, rFmt.GetFmtAttr(n, true), rWrt); + m_rExport.AttrOutput().OutputItem( rFmt.GetFmtAttr( n, true ) ); } } } - rWrt.SetCurItemSet( pOldI ); - rWrt.pOutFmtNode = pOldMod; + m_rExport.SetCurItemSet( pOldI ); + m_rExport.pOutFmtNode = pOldMod; } -void WW8WrtStyle::BuildUpx(const SwFmt* pFmt, bool bPap, USHORT nPos, - bool bInsDefCharSiz) +void WW8AttributeOutput::StartStyleProperties( bool bParProp, USHORT nStyle ) { - WW8Bytes* pO = rWrt.pO; + WW8Bytes* pO = m_rWW8Export.pO; - SkipOdd(); - UINT16 nLen = ( bPap ) ? 2 : 0; // Default-Laenge - USHORT nLenPos = pO->Count(); // Laenge zum Nachtragen + impl_SkipOdd( pO, m_rWW8Export.pTableStrm->Tell() ); + + UINT16 nLen = ( bParProp ) ? 2 : 0; // Default-Laenge + m_nStyleLenPos = pO->Count(); // Laenge zum Nachtragen // Keinen Pointer merken, da sich bei // _grow der Pointer aendert ! SwWW8Writer::InsUInt16( *pO, nLen ); // Style-Len - UINT16 nStartSiz = pO->Count(); + m_nStyleStartSize = pO->Count(); - if( bPap ) - SwWW8Writer::InsUInt16( *pO, nPos); // Style-Nummer + if ( bParProp ) + SwWW8Writer::InsUInt16( *pO, nStyle ); // Style-Nummer +} - ASSERT(rWrt.pCurrentStyle==NULL, "Current style not NULL"); // set current style before calling out - rWrt.pCurrentStyle=pFmt; +void MSWordStyles::WriteProperties( const SwFmt* pFmt, bool bParProp, USHORT nPos, + bool bInsDefCharSiz ) +{ + m_rExport.AttrOutput().StartStyleProperties( bParProp, nPos ); + + ASSERT( m_rExport.pCurrentStyle == NULL, "Current style not NULL" ); // set current style before calling out + m_rExport.pCurrentStyle = pFmt; + + m_rExport.OutputFormat( *pFmt, bParProp, !bParProp ); - rWrt.Out_SwFmt( *pFmt, bPap, !bPap ); + ASSERT( m_rExport.pCurrentStyle != pFmt, "current style was changed" ); // reset current style... + m_rExport.pCurrentStyle = NULL; - ASSERT(rWrt.pCurrentStyle!=pFmt, "current style was changed"); // reset current style... - rWrt.pCurrentStyle=NULL; + if ( bInsDefCharSiz ) // nicht abgeleitet v. anderem Style + SetStyleDefaults( *pFmt, bParProp ); - if( bInsDefCharSiz ) // nicht abgeleitet v. anderem Style - Set1StyleDefaults( *pFmt, bPap ); + m_rExport.AttrOutput().EndStyleProperties( bParProp ); +} + +void WW8AttributeOutput::EndStyleProperties( bool /*bParProp*/ ) +{ + WW8Bytes* pO = m_rWW8Export.pO; - nLen = pO->Count() - nStartSiz; - BYTE* pUpxLen = (BYTE*)pO->GetData() + nLenPos; // Laenge zum Nachtragen + UINT16 nLen = pO->Count() - m_nStyleStartSize; + BYTE* pUpxLen = (BYTE*)pO->GetData() + m_nStyleLenPos; // Laenge zum Nachtragen ShortToSVBT16( nLen, pUpxLen ); // Default-Laenge eintragen } -// Out1Style geht fuer TxtFmtColls und CharFmts -void WW8WrtStyle::Out1Style( SwFmt* pFmt, USHORT nPos ) +void MSWordStyles::GetStyleData( SwFmt* pFmt, bool& bFmtColl, USHORT& nBase, USHORT& nNext ) { - if( pFmt ) - { - bool bFmtColl = pFmt->Which() == RES_TXTFMTCOLL || - pFmt->Which() == RES_CONDTXTFMTCOLL; - short nWwBase = 0xfff; // Default: none + bFmtColl = pFmt->Which() == RES_TXTFMTCOLL || pFmt->Which() == RES_CONDTXTFMTCOLL; - if( !pFmt->IsDefault() ) // Abgeleitet von ? - nWwBase = Sty_GetWWSlot( *pFmt->DerivedFrom() ); + // Default: none + nBase = 0xfff; - SwFmt* pNext; - if( bFmtColl ) - pNext = &((SwTxtFmtColl*)pFmt)->GetNextTxtFmtColl(); - else - pNext = pFmt; // CharFmt: Naechstes CharFmt == Selbes + // Derived from? + if ( !pFmt->IsDefault() ) + nBase = GetSlot( *pFmt->DerivedFrom() ); - short nWwNext = Sty_GetWWSlot( *pNext ); + SwFmt* pNext; + if ( bFmtColl ) + pNext = &((SwTxtFmtColl*)pFmt)->GetNextTxtFmtColl(); + else + pNext = pFmt; // CharFmt: next CharFmt == self - BuildStd( pFmt->GetName(), bFmtColl, nWwBase, nWwNext, - GetWWId( *pFmt ) ); - if( bFmtColl ) - BuildUpx( pFmt, true, nPos, nWwBase==0xfff ); // UPX.papx - BuildUpx( pFmt, false, nPos, bFmtColl && nWwBase==0xfff ); // UPX.chpx + nNext = GetSlot( *pNext ); +} - SkipOdd(); - WriteStyle( *rWrt.pTableStrm ); - } - else if( nPos == 10 ) // Default Char-Style ( nur WW ) +void WW8AttributeOutput::DefaultStyle( USHORT nStyle ) +{ + if ( nStyle == 10 ) // Default Char-Style ( nur WW ) { - if( rWrt.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { static BYTE __READONLY_DATA aDefCharSty[] = { 0x42, 0x00, @@ -492,7 +492,7 @@ void WW8WrtStyle::Out1Style( SwFmt* pFmt, USHORT nPos ) 0x72, 0x00, 0x69, 0x00, 0x66, 0x00, 0x74, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00 }; - rWrt.pTableStrm->Write( &aDefCharSty, sizeof( aDefCharSty ) ); + m_rWW8Export.pTableStrm->Write( &aDefCharSty, sizeof( aDefCharSty ) ); } else { @@ -503,31 +503,54 @@ void WW8WrtStyle::Out1Style( SwFmt* pFmt, USHORT nPos ) 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x73, 0x63, 0x68, 0x72, 0x69, 0x66, 0x74, 0x61, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00 }; - rWrt.pTableStrm->Write( &aDefCharSty, sizeof( aDefCharSty ) ); + m_rWW8Export.pTableStrm->Write( &aDefCharSty, sizeof( aDefCharSty ) ); } } else { UINT16 n = 0; - rWrt.pTableStrm->Write( &n , 2 ); // leerer Style + m_rWW8Export.pTableStrm->Write( &n , 2 ); // leerer Style } } -void WW8WrtStyle::OutStyleTab() +// OutputStyle geht fuer TxtFmtColls und CharFmts +void MSWordStyles::OutputStyle( SwFmt* pFmt, USHORT nPos ) { - WW8Fib& rFib = *rWrt.pFib; + if ( !pFmt ) + m_rExport.AttrOutput().DefaultStyle( nPos ); + else + { + bool bFmtColl; + USHORT nBase, nWwNext; + + GetStyleData( pFmt, bFmtColl, nBase, nWwNext ); + + m_rExport.AttrOutput().StartStyle( pFmt->GetName(), bFmtColl, + nBase, nWwNext, GetWWId( *pFmt ), nPos ); + + if ( bFmtColl ) + WriteProperties( pFmt, true, nPos, nBase==0xfff ); // UPX.papx + + WriteProperties( pFmt, false, nPos, bFmtColl && nBase==0xfff ); // UPX.chpx - ULONG nCurPos = rWrt.pTableStrm->Tell(); - if( nCurPos & 1 ) // Start auf gerader + m_rExport.AttrOutput().EndStyle(); + } +} + +void WW8AttributeOutput::StartStyles() +{ + WW8Fib& rFib = *m_rWW8Export.pFib; + + ULONG nCurPos = m_rWW8Export.pTableStrm->Tell(); + if ( nCurPos & 1 ) // Start auf gerader { - *rWrt.pTableStrm << (char)0; // Adresse + *m_rWW8Export.pTableStrm << (char)0; // Adresse ++nCurPos; } - rWrt.bStyDef = true; rFib.fcStshfOrig = rFib.fcStshf = nCurPos; - ULONG nStyAnzPos = nCurPos + 2; // Anzahl wird nachgetragen + m_nStyAnzPos = nCurPos + 2; // Anzahl wird nachgetragen - if( rWrt.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { static BYTE __READONLY_DATA aStShi[] = { 0x12, 0x00, @@ -535,7 +558,7 @@ void WW8WrtStyle::OutStyleTab() 0x0F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - rWrt.pTableStrm->Write( &aStShi, sizeof( aStShi ) ); + m_rWW8Export.pTableStrm->Write( &aStShi, sizeof( aStShi ) ); } else { @@ -543,16 +566,31 @@ void WW8WrtStyle::OutStyleTab() 0x0E, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4B, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00 }; - rWrt.pTableStrm->Write( &aStShi, sizeof( aStShi ) ); + m_rWW8Export.pTableStrm->Write( &aStShi, sizeof( aStShi ) ); } +} + +void WW8AttributeOutput::EndStyles( USHORT nNumberOfStyles ) +{ + WW8Fib& rFib = *m_rWW8Export.pFib; + + rFib.lcbStshfOrig = rFib.lcbStshf = m_rWW8Export.pTableStrm->Tell() - rFib.fcStshf; + SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, m_nStyAnzPos, nNumberOfStyles ); +} + +void MSWordStyles::OutputStylesTable() +{ + m_rExport.bStyDef = true; + + m_rExport.AttrOutput().StartStyles(); USHORT n; - for( n = 0; n < nUsedSlots; n++ ) - Out1Style( pFmtA[n], n ); + for ( n = 0; n < nUsedSlots; n++ ) + OutputStyle( pFmtA[n], n ); - rFib.lcbStshfOrig = rFib.lcbStshf = rWrt.pTableStrm->Tell() - rFib.fcStshf; - SwWW8Writer::WriteShort( *rWrt.pTableStrm, nStyAnzPos, nUsedSlots ); - rWrt.bStyDef = false; + m_rExport.AttrOutput().EndStyles( nUsedSlots ); + + m_rExport.bStyDef = false; } /* */ @@ -561,7 +599,7 @@ void WW8WrtStyle::OutStyleTab() // Fonts //--------------------------------------------------------------------------- wwFont::wwFont(const String &rFamilyName, FontPitch ePitch, FontFamily eFamily, - rtl_TextEncoding eChrSet, bool bWrtWW8) : mbAlt(false), mbWrtWW8(bWrtWW8) + rtl_TextEncoding eChrSet, bool bWrtWW8) : mbAlt(false), mbWrtWW8(bWrtWW8), mePitch(ePitch), meFamily(eFamily), meChrSet(eChrSet) { FontMapExport aResult(rFamilyName); msFamilyNm = aResult.msPrimary; @@ -659,6 +697,23 @@ bool wwFont::Write(SvStream *pTableStrm) const return true; } +#ifdef DOCX +void wwFont::WriteDocx( const DocxAttributeOutput* rAttrOutput ) const +{ + // no font embedding, panose id, subsetting, ... implemented + + rAttrOutput->StartFont( msFamilyNm ); + + if ( mbAlt ) + rAttrOutput->FontAlternateName( msAltNm ); + rAttrOutput->FontCharset( sw::ms::rtl_TextEncodingToWinCharset( meChrSet ) ); + rAttrOutput->FontFamilyType( meFamily ); + rAttrOutput->FontPitchType( mePitch ); + + rAttrOutput->EndFont(); +} +#endif + bool operator<(const wwFont &r1, const wwFont &r2) { int nRet = memcmp(r1.maWW8_FFN, r2.maWW8_FFN, sizeof(r1.maWW8_FFN)); @@ -727,6 +782,18 @@ USHORT wwFontHelper::GetId(const SvxFontItem& rFont) return GetId(aFont); } +::std::vector< const wwFont* > wwFontHelper::AsVector() const +{ + ::std::vector<const wwFont *> aFontList( maFonts.size() ); + + typedef ::std::map<wwFont, USHORT>::const_iterator myiter; + myiter aEnd = maFonts.end(); + for ( myiter aIter = maFonts.begin(); aIter != aEnd; ++aIter ) + aFontList[aIter->second] = &aIter->first; + + return aFontList; +} + void wwFontHelper::WriteFontTable(SvStream *pTableStream, WW8Fib& rFib) { rFib.fcSttbfffn = pTableStream->Tell(); @@ -742,12 +809,7 @@ void wwFontHelper::WriteFontTable(SvStream *pTableStream, WW8Fib& rFib) * Convert from fast insertion map to linear vector in the order that we * want to write. */ - ::std::vector<const wwFont *> aFontList(maFonts.size()); - - typedef ::std::map<wwFont, USHORT>::iterator myiter; - myiter aEnd = maFonts.end(); - for(myiter aIter = maFonts.begin(); aIter != aEnd; ++aIter) - aFontList[aIter->second] = &aIter->first; + ::std::vector<const wwFont *> aFontList( AsVector() ); /* * Write them all to pTableStream @@ -768,6 +830,16 @@ void wwFontHelper::WriteFontTable(SvStream *pTableStream, WW8Fib& rFib) } } +#ifdef DOCX +void wwFontHelper::WriteFontTable( const DocxAttributeOutput& rAttrOutput ) +{ + ::std::vector<const wwFont *> aFontList( AsVector() ); + + ::std::for_each( aFontList.begin(), aFontList.end(), + ::std::bind2nd( ::std::mem_fun( &wwFont::WriteDocx ), &rAttrOutput ) ); +} +#endif + /* */ WW8_WrPlc0::WW8_WrPlc0( ULONG nOffset ) @@ -795,13 +867,71 @@ void WW8_WrPlc0::Write( SvStream& rStrm ) /* */ //------------------------------------------------------------------------------ -// class WW8_WrPlcSepx : Uebersetzung PageDescs in Sections +// class MSWordSections : Uebersetzung PageDescs in Sections // behandelt auch Header und Footer //------------------------------------------------------------------------------ -WW8_WrPlcSepx::WW8_WrPlcSepx() : - mbDocumentIsProtected(false), aSects(4, 4), aCps(4, 4), pAttrs(0), - pTxtPos(0) +MSWordSections::MSWordSections( MSWordExportBase& rExport ) + : mbDocumentIsProtected( false ), + aSects( 4, 4 ) +{ + const SwSectionFmt *pFmt = 0; + rExport.pAktPageDesc = &const_cast<const SwDoc *>(rExport.pDoc)->GetPageDesc( 0 ); + + const SfxPoolItem* pI; + const SwNode* pNd = rExport.pCurPam->GetCntntNode(); + const SfxItemSet* pSet = pNd ? &((SwCntntNode*)pNd)->GetSwAttrSet() : 0; + + ULONG nRstLnNum = pSet ? ((SwFmtLineNumber&)pSet->Get( RES_LINENUMBER )).GetStartValue() : 0; + + const SwTableNode* pTblNd = rExport.pCurPam->GetNode()->FindTableNode(); + const SwSectionNode* pSectNd; + if ( pTblNd ) + { + pSet = &pTblNd->GetTable().GetFrmFmt()->GetAttrSet(); + pNd = pTblNd; + } + else if ( 0 != ( pSectNd = pNd->FindSectionNode() ) ) + { + if ( TOX_HEADER_SECTION == pSectNd->GetSection().GetType() && + pSectNd->StartOfSectionNode()->IsSectionNode() ) + { + pSectNd = pSectNd->StartOfSectionNode()->GetSectionNode(); + } + + if ( TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() ) + { + pNd = pSectNd; + rExport.pCurPam->GetPoint()->nNode = *pNd; + } + + if ( CONTENT_SECTION == pSectNd->GetSection().GetType() ) + pFmt = pSectNd->GetSection().GetFmt(); + } + + // Hole evtl. Pagedesc des 1. Nodes + if ( pSet && + SFX_ITEM_ON == pSet->GetItemState( RES_PAGEDESC, true, &pI ) && + ( (SwFmtPageDesc*)pI )->GetPageDesc() ) + { + AppendSep( *(SwFmtPageDesc*)pI, *pNd, pFmt, nRstLnNum ); + } + else + AppendSep( rExport.pAktPageDesc, pFmt, nRstLnNum ); +} + +WW8_WrPlcSepx::WW8_WrPlcSepx( MSWordExportBase& rExport ) + : MSWordSections( rExport ), + aCps( 4, 4 ), + pAttrs( 0 ), + pTxtPos( 0 ) +{ + // to be in sync with the AppendSep() call in the MSWordSections + // constructor + aCps.Insert( ULONG( 0 ), aCps.Count() ); +} + +MSWordSections::~MSWordSections() { } @@ -817,79 +947,93 @@ WW8_WrPlcSepx::~WW8_WrPlcSepx() delete pTxtPos; } -sal_uInt16 WW8_WrPlcSepx::CurrentNoColumns(const SwDoc &rDoc) const +sal_uInt16 MSWordSections::CurrentNumberOfColumns( const SwDoc &rDoc ) const { - ASSERT(aSects.Count(), "no segement inserted yet"); - if (!aSects.Count()) + ASSERT( aSects.Count(), "no segement inserted yet" ); + if ( !aSects.Count() ) return 1; - WW8_SepInfo& rInfo = aSects[aSects.Count() - 1]; + return NumberOfColumns( rDoc, aSects[aSects.Count() - 1] ); +} + +sal_uInt16 MSWordSections::NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo ) const +{ const SwPageDesc* pPd = rInfo.pPageDesc; - if (!pPd) - pPd = &rDoc.GetPageDesc(0); + if ( !pPd ) + pPd = &rDoc.GetPageDesc( 0 ); - if (!pPd) + if ( !pPd ) { - ASSERT(pPd, "totally impossible"); + ASSERT( pPd, "totally impossible" ); return 1; } const SfxItemSet &rSet = pPd->GetMaster().GetAttrSet(); - SfxItemSet aSet(*rSet.GetPool(), RES_COL, RES_COL); - aSet.SetParent(&rSet); + SfxItemSet aSet( *rSet.GetPool(), RES_COL, RES_COL ); + aSet.SetParent( &rSet ); //0xffffffff, what the hell is going on with that!, fixme most terribly - if (rInfo.pSectionFmt && (SwSectionFmt*)0xFFFFFFFF != rInfo.pSectionFmt) - aSet.Put(rInfo.pSectionFmt->GetFmtAttr(RES_COL)); + if ( rInfo.pSectionFmt && (SwSectionFmt*)0xFFFFFFFF != rInfo.pSectionFmt ) + aSet.Put( rInfo.pSectionFmt->GetFmtAttr( RES_COL ) ); - const SwFmtCol& rCol = (const SwFmtCol&)aSet.Get(RES_COL); + const SwFmtCol& rCol = (const SwFmtCol&)aSet.Get( RES_COL ); const SwColumns& rColumns = rCol.GetColumns(); return rColumns.Count(); } -void WW8_WrPlcSepx::AppendSep(WW8_CP nStartCp, const SwPageDesc* pPd, - const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo) +const WW8_SepInfo* MSWordSections::CurrentSectionInfo() { - aCps.Insert(nStartCp, aCps.Count()); - aSects.Insert(WW8_SepInfo(pPd, pSectionFmt, nLnNumRestartNo), - aSects.Count()); - NeedsDocumentProtected(aSects[aSects.Count()-1]); + if ( aSects.Count() > 0 ) + return &aSects[aSects.Count() - 1]; + + return NULL; +} + +void MSWordSections::AppendSep( const SwPageDesc* pPd, + const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo ) +{ + aSects.Insert( WW8_SepInfo( pPd, pSectionFmt, nLnNumRestartNo ), + aSects.Count() ); + NeedsDocumentProtected( aSects[aSects.Count()-1] ); +} + +void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwPageDesc* pPd, + const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo ) +{ + aCps.Insert( nStartCp, aCps.Count() ); + + MSWordSections::AppendSep( pPd, pSectionFmt, nLnNumRestartNo ); +} + +void MSWordSections::AppendSep( const SwFmtPageDesc& rPD, + const SwNode& rNd, const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo ) +{ + WW8_SepInfo aI( rPD.GetPageDesc(), pSectionFmt, nLnNumRestartNo, + rPD.GetNumOffset(), &rNd ); + aSects.Insert( aI, aSects.Count() ); + NeedsDocumentProtected( aI ); } void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwFmtPageDesc& rPD, const SwNode& rNd, const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo ) { aCps.Insert(nStartCp, aCps.Count()); - WW8_SepInfo aI(rPD.GetPageDesc(), pSectionFmt, nLnNumRestartNo); - aI.nPgRestartNo = rPD.GetNumOffset(); - aI.pPDNd = &rNd; - aSects.Insert(aI, aSects.Count()); - NeedsDocumentProtected(aI); + + MSWordSections::AppendSep( rPD, rNd, pSectionFmt, nLnNumRestartNo ); } -// WW8_WrPlcSepx::SetNum() setzt in jeder Section beim 1. Aufruf den +// MSWordSections::SetNum() setzt in jeder Section beim 1. Aufruf den // Num-Pointer, alle folgenden Aufrufe werden ignoriert. Damit wird // die erste Aufzaehlung einer Section uebernommen. -void WW8_WrPlcSepx::SetNum( const SwTxtNode* pNumNd ) +void MSWordSections::SetNum( const SwTxtNode* pNumNd ) { WW8_SepInfo& rInfo = aSects[ aSects.Count() - 1 ]; - if( !rInfo.pNumNd ) // noch nicht belegt + if ( !rInfo.pNumNd ) // noch nicht belegt rInfo.pNumNd = pNumNd; } -void WW8_WrPlcSepx::WriteOlst( SwWW8Writer& rWrt, USHORT i ) -{ - if( !rWrt.bWrtWW8 ) - { - const SwNumRule* pRule; - const SwTxtNode* pNd = aSects[i].pNumNd; - if( pNd && 0 != ( pRule = pNd->GetNumRule() )) - rWrt.Out_Olst( *pRule ); - } -} - -void WW8_WrPlcSepx::WriteFtnEndTxt( SwWW8Writer& rWrt, ULONG nCpStt ) +void WW8_WrPlcSepx::WriteFtnEndTxt( WW8Export& rWrt, ULONG nCpStt ) { BYTE nInfoFlags = 0; const SwFtnInfo& rInfo = rWrt.pDoc->GetFtnInfo(); @@ -940,19 +1084,19 @@ void WW8_WrPlcSepx::WriteFtnEndTxt( SwWW8Writer& rWrt, ULONG nCpStt ) case FTNNUM_CHAPTER: rDop.rncFtn = 1; break; default: rDop.rncFtn = 0; break; } // rncFtn - rDop.nfcFtnRef = SwWW8Writer::GetNumId( rInfo.aFmt.GetNumberingType() ); + rDop.nfcFtnRef = WW8Export::GetNumId( rInfo.aFmt.GetNumberingType() ); rDop.nFtn = rInfo.nFtnOffset + 1; rDop.fpc = rWrt.bFtnAtTxtEnd ? 2 : 1; // Endnote Info rDop.rncEdn = 0; // rncEdn: Don't Restart const SwEndNoteInfo& rEndInfo = rWrt.pDoc->GetEndNoteInfo(); - rDop.nfcEdnRef = SwWW8Writer::GetNumId( rEndInfo.aFmt.GetNumberingType() ); + rDop.nfcEdnRef = WW8Export::GetNumId( rEndInfo.aFmt.GetNumberingType() ); rDop.nEdn = rEndInfo.nFtnOffset + 1; rDop.epc = rWrt.bEndAtTxtEnd ? 3 : 0; } -void WW8_WrPlcSepx::SetHeaderFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt, +void MSWordSections::SetHeaderFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt, BYTE nFlag ) { const SfxPoolItem* pItem; @@ -962,7 +1106,7 @@ void WW8_WrPlcSepx::SetHeaderFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt, rHeadFootFlags |= nFlag; } -void WW8_WrPlcSepx::SetFooterFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt, +void MSWordSections::SetFooterFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt, BYTE nFlag ) { const SfxPoolItem* pItem; @@ -972,58 +1116,29 @@ void WW8_WrPlcSepx::SetFooterFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt, rHeadFootFlags |= nFlag; } -void WW8_WrPlcSepx::OutHeader( SwWW8Writer& rWrt, const SwFmt& rFmt, - ULONG& rCpPos, BYTE nHFFlags, BYTE nFlag ) -{ - if( nFlag & nHFFlags ) - { - rWrt.bHasHdr = true; - const SwFmtHeader& rHd = rFmt.GetHeader(); - ASSERT( rHd.GetHeaderFmt(), "KopfText nicht richtig da" ); - const SwFmtCntnt& rCntnt = rHd.GetHeaderFmt()->GetCntnt(); - pTxtPos->Append( rCpPos ); - rWrt.WriteKFTxt1( rCntnt ); - rWrt.WriteStringAsPara( aEmptyStr ); // CR ans Ende ( sonst mault WW ) - rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() ); - } - else if( rWrt.bWrtWW8 ) - { - pTxtPos->Append( rCpPos ); - if (rWrt.bHasHdr) - { - rWrt.WriteStringAsPara( aEmptyStr ); // Empty paragraph for empty header - rWrt.WriteStringAsPara( aEmptyStr ); // a CR that WW8 needs for end of the stream - rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() ); - } - } -} -void WW8_WrPlcSepx::OutFooter( SwWW8Writer& rWrt, const SwFmt& rFmt, - ULONG& rCpPos, BYTE nHFFlags, BYTE nFlag ) +void WW8_WrPlcSepx::OutHeaderFooter( WW8Export& rWrt, bool bHeader, + const SwFmt& rFmt, ULONG& rCpPos, BYTE nHFFlags, BYTE nFlag ) { - if( nFlag & nHFFlags ) + if ( nFlag & nHFFlags ) { - rWrt.bHasFtr = true; - const SwFmtFooter& rFt = rFmt.GetFooter(); - ASSERT( rFt.GetFooterFmt(), "KopfText nicht richtig da" ); - const SwFmtCntnt& rCntnt = rFt.GetFooterFmt()->GetCntnt(); pTxtPos->Append( rCpPos ); - rWrt.WriteKFTxt1( rCntnt ); + rWrt.WriteHeaderFooterText( rFmt, bHeader ); rWrt.WriteStringAsPara( aEmptyStr ); // CR ans Ende ( sonst mault WW ) rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() ); } - else if( rWrt.bWrtWW8 ) + else if ( rWrt.bWrtWW8 ) { pTxtPos->Append( rCpPos ); - if (rWrt.bHasFtr) + if ( bHeader? rWrt.bHasHdr: rWrt.bHasFtr ) { - rWrt.WriteStringAsPara( aEmptyStr ); // Empty paragraph for empty footer + rWrt.WriteStringAsPara( aEmptyStr ); // Empty paragraph for empty header/footer rWrt.WriteStringAsPara( aEmptyStr ); // a CR that WW8 needs for end of the stream rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() ); } } } -void WW8_WrPlcSepx::NeedsDocumentProtected(const WW8_SepInfo &rInfo) +void MSWordSections::NeedsDocumentProtected(const WW8_SepInfo &rInfo) { if (rInfo.IsProtected()) mbDocumentIsProtected = true; @@ -1047,7 +1162,7 @@ bool WW8_SepInfo::IsProtected() const } -void WW8_WrPlcSepx::CheckForFacinPg( SwWW8Writer& rWrt ) const +void MSWordSections::CheckForFacinPg( WW8Export& rWrt ) const { // 2 Werte werden gesetzt // Dop.fFacingPages == Kopf-/Fusszeilen unterschiedlich @@ -1099,7 +1214,7 @@ void WW8_WrPlcSepx::CheckForFacinPg( SwWW8Writer& rWrt ) const } } -int WW8_WrPlcSepx::HasBorderItem( const SwFmt& rFmt ) +int MSWordSections::HasBorderItem( const SwFmt& rFmt ) { const SfxPoolItem* pItem; return SFX_ITEM_SET == rFmt.GetItemState(RES_BOX, true, &pItem) && @@ -1109,447 +1224,496 @@ int WW8_WrPlcSepx::HasBorderItem( const SwFmt& rFmt ) ((SvxBoxItem*)pItem)->GetRight() ); } +void WW8AttributeOutput::StartSection() +{ + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren +} -bool WW8_WrPlcSepx::WriteKFTxt(SwWW8Writer& rWrt) +void WW8AttributeOutput::SectionFormProtection( bool bProtected ) { - pAttrs = new WW8_PdAttrDesc[ aSects.Count() ]; - WW8Bytes* pO = rWrt.pO; - ULONG nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() ); - bool bOldPg = rWrt.bOutPageDescs; - rWrt.bOutPageDescs = true; + //If the document is to be exported as protected, then if a segment + //is not protected, set the unlocked flag + if ( m_rWW8Export.pSepx->DocumentIsProtected() && !bProtected ) + { + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFProtected ); + else + m_rWW8Export.pO->Insert( 139, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( 1 , m_rWW8Export.pO->Count() ); + } +} - ASSERT( !pTxtPos, "wer hat den Pointer gesetzt?" ); - pTxtPos = new WW8_WrPlc0( nCpStart ); +void WW8AttributeOutput::SectionLineNumbering( ULONG nRestartNo, const SwLineNumberInfo& rLnNumInfo ) +{ + // sprmSNLnnMod - activate Line Numbering and define Modulo + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SNLnnMod ); + else + m_rWW8Export.pO->Insert( 154, m_rWW8Export.pO->Count() ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (UINT16)rLnNumInfo.GetCountBy() ); - WriteFtnEndTxt( rWrt, nCpStart ); - CheckForFacinPg( rWrt ); + // sprmSDxaLnn - xPosition of Line Number + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SDxaLnn ); + else + m_rWW8Export.pO->Insert( 155, m_rWW8Export.pO->Count() ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (UINT16)rLnNumInfo.GetPosFromLeft() ); - WW8Bytes aLineNum; - const SwLineNumberInfo& rLnNumInfo = rWrt.pDoc->GetLineNumberInfo(); - if( rLnNumInfo.IsPaintLineNumbers() ) + // sprmSLnc - restart number: 0 per page, 1 per section, 2 never restart + if ( nRestartNo || !rLnNumInfo.IsRestartEachPage() ) { - // sprmSNLnnMod - activate Line Numbering and define Modulo - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( aLineNum, 0x5015 ); + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SLnc ); else - aLineNum.Insert( 154, aLineNum.Count() ); - SwWW8Writer::InsUInt16( aLineNum, (UINT16)rLnNumInfo.GetCountBy() ); + m_rWW8Export.pO->Insert( 152, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( nRestartNo ? 1 : 2, m_rWW8Export.pO->Count() ); + } - // sprmSDxaLnn - xPosition of Line Number - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( aLineNum, 0x9016 ); + // sprmSLnnMin - Restart the Line Number with given value + if ( nRestartNo ) + { + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SLnnMin ); else - aLineNum.Insert( 155, aLineNum.Count() ); - SwWW8Writer::InsUInt16( aLineNum, (UINT16)rLnNumInfo.GetPosFromLeft() ); + m_rWW8Export.pO->Insert( 160, m_rWW8Export.pO->Count() ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (UINT16)nRestartNo - 1 ); + } +} - // +void WW8AttributeOutput::SectionTitlePage() +{ + // sprmSFTitlePage + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFTitlePage ); + else + m_rWW8Export.pO->Insert( 143, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() ); +} + +void WW8AttributeOutput::SectionPageBorders( const SwFrmFmt* pPdFmt, const SwFrmFmt* pPdFirstPgFmt ) +{ + if ( m_rWW8Export.bWrtWW8 ) // Seitenumrandung schreiben + { + USHORT nPgBorder = MSWordSections::HasBorderItem( *pPdFmt ) ? 0 : USHRT_MAX; + if ( pPdFmt != pPdFirstPgFmt ) + { + if ( MSWordSections::HasBorderItem( *pPdFirstPgFmt ) ) + { + if ( USHRT_MAX == nPgBorder ) + { + nPgBorder = 1; + // nur die 1. Seite umrandet -> BoxItem aus dem + // richtigen Format besorgen + m_rWW8Export.pISet = &pPdFirstPgFmt->GetAttrSet(); + OutputItem( pPdFirstPgFmt->GetFmtAttr( RES_BOX ) ); + } + } + else if ( !nPgBorder ) + nPgBorder = 2; + } + + if ( USHRT_MAX != nPgBorder ) + { + // Flag und das Border Attribut schreiben + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SPgbProp ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nPgBorder ); + } } +} - unsigned int nOldIndex = rWrt.GetHdFtIndex(); - unsigned int nHdFtGroup = 0; - for (USHORT i = 0; i < aSects.Count(); ++i) +void WW8AttributeOutput::SectionBiDi( bool bBiDi ) +{ + if ( m_rWW8Export.bWrtWW8 ) { - WW8_PdAttrDesc* pA = pAttrs + i; - WW8_SepInfo& rSepInfo = aSects[i]; - const SwPageDesc* pPd = rSepInfo.pPageDesc; + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFBiDi ); + m_rWW8Export.pO->Insert( bBiDi? 1: 0, m_rWW8Export.pO->Count() ); + } +} - if( rSepInfo.pSectionFmt && !pPd ) - pPd = &const_cast<const SwDoc *>(rWrt.pDoc)->GetPageDesc(0); +void WW8AttributeOutput::SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber ) +{ + // sprmSNfcPgn + BYTE nb = WW8Export::GetNumId( nNumType ); + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SNfcPgn ); + else + m_rWW8Export.pO->Insert( 147, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( nb, m_rWW8Export.pO->Count() ); - rWrt.pAktPageDesc = pPd; - pA->nSepxFcPos = 0xffffffff; // Default: none + if ( nPageRestartNumber ) + { + // sprmSFPgnRestart + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFPgnRestart ); + else + m_rWW8Export.pO->Insert( 150, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() ); - if( !pPd ) - { - pA->pData = 0; - pA->nLen = 0; - continue; - } + // sprmSPgnStart + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SPgnStart ); + else + m_rWW8Export.pO->Insert( 161, m_rWW8Export.pO->Count() ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nPageRestartNumber ); + } +} - pO->Remove( 0, pO->Count() ); // leeren - rWrt.bOutPageDescs = true; +void WW8AttributeOutput::SectionType( BYTE nBreakCode ) +{ + if ( 2 != nBreakCode ) // new page is the default + { + if ( m_rWW8Export.bWrtWW8 ) + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SBkc ); + else + m_rWW8Export.pO->Insert( 142, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( nBreakCode, m_rWW8Export.pO->Count() ); + } +} - //If the document is to be exported as protected, then if a segment - //is not protected, set the unlocked flag - if (mbDocumentIsProtected && !rSepInfo.IsProtected()) +void WW8AttributeOutput::SectionWW6HeaderFooterFlags( BYTE nHeadFootFlags ) +{ + if ( nHeadFootFlags && !m_rWW8Export.bWrtWW8 ) + { + BYTE nTmpFlags = nHeadFootFlags; + if ( m_rWW8Export.pDop->fFacingPages ) { - if (rWrt.bWrtWW8) - SwWW8Writer::InsUInt16(*pO, 0x3006); - else - pO->Insert(139, pO->Count()); - pO->Insert(1 , pO->Count()); + if ( !(nTmpFlags & WW8_FOOTER_EVEN) && (nTmpFlags & WW8_FOOTER_ODD ) ) + nTmpFlags |= WW8_FOOTER_EVEN; + + if ( !(nTmpFlags & WW8_HEADER_EVEN) && (nTmpFlags & WW8_HEADER_ODD ) ) + nTmpFlags |= WW8_HEADER_EVEN; } - if( aLineNum.Count() ) - { - pO->Insert( &aLineNum, pO->Count() ); + // sprmSGprfIhdt, wird nur noch im WW95 benoetigt + m_rWW8Export.pO->Insert( 153, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( nTmpFlags, m_rWW8Export.pO->Count() ); + } +} - // sprmSLnc - restart number: 0 per page, 1 per section, 2 never restart - if( rSepInfo.nLnNumRestartNo || !rLnNumInfo.IsRestartEachPage() ) - { - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( *pO, 0x3013 ); - else - pO->Insert( 152, pO->Count() ); - pO->Insert( rSepInfo.nLnNumRestartNo ? 1 : 2, pO->Count() ); - } +void WW8Export::SetupSectionPositions( WW8_PdAttrDesc* pA ) +{ + if ( !pA ) + return; + + if ( pO->Count() ) + { // waren Attrs vorhanden ? + pA->nLen = pO->Count(); + pA->pData = new BYTE [pO->Count()]; + memcpy( pA->pData, pO->GetData(), pO->Count() ); // -> merken + pO->Remove( 0, pO->Count() ); // leeren fuer HdFt-Text + } + else + { // keine Attrs da + pA->pData = 0; + pA->nLen = 0; + } +} - // sprmSLnnMin - Restart the Line Number with given value - if( rSepInfo.nLnNumRestartNo ) - { - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( *pO, 0x501B ); - else - pO->Insert( 160, pO->Count() ); - SwWW8Writer::InsUInt16( *pO, (UINT16)rSepInfo.nLnNumRestartNo - 1 ); - } - } +void WW8Export::WriteHeadersFooters( BYTE nHeadFootFlags, + const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt ) +{ + ULONG nCpPos = Fc2Cp( Strm().Tell() ); + + IncrementHdFtIndex(); + if ( !(nHeadFootFlags & WW8_HEADER_EVEN) && pDop->fFacingPages ) + pSepx->OutHeaderFooter( *this, true, rFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD ); + else + pSepx->OutHeaderFooter( *this, true, rLeftFmt, nCpPos, nHeadFootFlags, WW8_HEADER_EVEN ); + IncrementHdFtIndex(); + pSepx->OutHeaderFooter( *this, true, rFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD ); + + IncrementHdFtIndex(); + if ( !(nHeadFootFlags & WW8_FOOTER_EVEN) && pDop->fFacingPages ) + pSepx->OutHeaderFooter( *this, false, rFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD ); + else + pSepx->OutHeaderFooter( *this, false, rLeftFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_EVEN ); + IncrementHdFtIndex(); + pSepx->OutHeaderFooter( *this, false, rFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD ); + + //#i24344# Drawing objects cannot be directly shared between main hd/ft + //and title hd/ft so we need to differenciate them + IncrementHdFtIndex(); + pSepx->OutHeaderFooter( *this, true, rFirstPageFmt, nCpPos, nHeadFootFlags, WW8_HEADER_FIRST ); + pSepx->OutHeaderFooter( *this, false, rFirstPageFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_FIRST ); +} + +void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAttrDesc* pA ) +{ + const SwPageDesc* pPd = rSepInfo.pPageDesc; + + if ( rSepInfo.pSectionFmt && !pPd ) + pPd = &const_cast<const SwDoc *>( pDoc )->GetPageDesc( 0 ); + + pAktPageDesc = pPd; + + if ( !pPd ) + return; + bool bOldPg = bOutPageDescs; + bOutPageDescs = true; - /* sprmSBkc, break code: 0 No break, 1 New column - 2 New page, 3 Even page, 4 Odd page + AttrOutput().StartSection(); + + // forms + AttrOutput().SectionFormProtection( rSepInfo.IsProtected() ); + + // line numbers + const SwLineNumberInfo& rLnNumInfo = pDoc->GetLineNumberInfo(); + if ( rLnNumInfo.IsPaintLineNumbers() ) + AttrOutput().SectionLineNumbering( rSepInfo.nLnNumRestartNo, rLnNumInfo ); + + /* sprmSBkc, break code: 0 No break, 1 New column + 2 New page, 3 Even page, 4 Odd page */ - BYTE nBreakCode = 2; // default neue Seite beginnen - bool bOutPgDscSet = true, bLeftRightPgChain = false; - const SwFrmFmt* pPdFmt = &pPd->GetMaster(); - const SwFrmFmt* pPdFirstPgFmt = pPdFmt; - if( rSepInfo.pSectionFmt ) - { - // ist pSectionFmt gesetzt, dann gab es einen SectionNode - // gueltiger Pointer -> Section beginnt, - // 0xfff -> Section wird beendet - nBreakCode = 0; // fortlaufender Abschnitt + BYTE nBreakCode = 2; // default neue Seite beginnen + bool bOutPgDscSet = true, bLeftRightPgChain = false; + const SwFrmFmt* pPdFmt = &pPd->GetMaster(); + const SwFrmFmt* pPdFirstPgFmt = pPdFmt; + if ( rSepInfo.pSectionFmt ) + { + // ist pSectionFmt gesetzt, dann gab es einen SectionNode + // gueltiger Pointer -> Section beginnt, + // 0xfff -> Section wird beendet + nBreakCode = 0; // fortlaufender Abschnitt - if (rSepInfo.pPDNd && rSepInfo.pPDNd->IsCntntNode()) + if ( rSepInfo.pPDNd && rSepInfo.pPDNd->IsCntntNode() ) + { + if ( !NoPageBreakSection( &rSepInfo.pPDNd->GetCntntNode()->GetSwAttrSet() ) ) { - if (!(SwWW8Writer::NoPageBreakSection( - &rSepInfo.pPDNd->GetCntntNode()->GetSwAttrSet()))) - { - nBreakCode = 2; - } + nBreakCode = 2; } + } - if( (SwSectionFmt*)0xFFFFFFFF != rSepInfo.pSectionFmt ) - { - if (nBreakCode == 0) - bOutPgDscSet = false; - - // Itemset erzeugen, das das PgDesk-AttrSet beerbt: - // als Nachkomme wird bei 'deep'-Out_SfxItemSet - // auch der Vorfahr abgeklappert - const SfxItemSet* pPdSet = &pPdFmt->GetAttrSet(); - SfxItemSet aSet( *pPdSet->GetPool(), pPdSet->GetRanges() ); - aSet.SetParent( pPdSet ); - - // am Nachkommen NUR die Spaltigkeit gemaess Sect-Attr. - // umsetzen - aSet.Put(rSepInfo.pSectionFmt->GetFmtAttr(RES_COL)); - - const SvxLRSpaceItem &rSectionLR = - ItemGet<SvxLRSpaceItem>(*(rSepInfo.pSectionFmt), - RES_LR_SPACE); - const SvxLRSpaceItem &rPageLR = - ItemGet<SvxLRSpaceItem>(*pPdFmt,RES_LR_SPACE); - - SvxLRSpaceItem aResultLR(rPageLR.GetLeft() + + if ( (SwSectionFmt*)0xFFFFFFFF != rSepInfo.pSectionFmt ) + { + if ( nBreakCode == 0 ) + bOutPgDscSet = false; + + // Itemset erzeugen, das das PgDesk-AttrSet beerbt: + // als Nachkomme wird bei 'deep'-OutputItemSet + // auch der Vorfahr abgeklappert + const SfxItemSet* pPdSet = &pPdFmt->GetAttrSet(); + SfxItemSet aSet( *pPdSet->GetPool(), pPdSet->GetRanges() ); + aSet.SetParent( pPdSet ); + + // am Nachkommen NUR die Spaltigkeit gemaess Sect-Attr. + // umsetzen + aSet.Put( rSepInfo.pSectionFmt->GetFmtAttr( RES_COL ) ); + + const SvxLRSpaceItem &rSectionLR = + ItemGet<SvxLRSpaceItem>( *(rSepInfo.pSectionFmt), RES_LR_SPACE ); + const SvxLRSpaceItem &rPageLR = + ItemGet<SvxLRSpaceItem>( *pPdFmt, RES_LR_SPACE ); + + SvxLRSpaceItem aResultLR( rPageLR.GetLeft() + rSectionLR.GetLeft(), rPageLR.GetRight() + - rSectionLR.GetRight(), 0, 0, RES_LR_SPACE); - - aSet.Put(aResultLR); - - // und raus damit ins WW-File - const SfxItemSet* pOldI = rWrt.pISet; - rWrt.pISet = &aSet; - // --> OD 2007-06-12 #TESTING# - // Switch off test on default item values, if page description - // set (value of <bOutPgDscSet>) isn't written. - Out_SfxItemSet( aWW8AttrFnTab, rWrt, aSet, true, bOutPgDscSet ); - // <-- - - //Cannot export as normal page framedir, as continous sections - //cannot contain any grid settings like proper sections - if (rWrt.bWrtWW8) - { - BYTE nDir; - SwWW8Writer::InsUInt16(*pO, 0x3228); - if (FRMDIR_HORI_RIGHT_TOP == - rWrt.TrueFrameDirection(*rSepInfo.pSectionFmt)) - { - nDir = 1; - } - else - nDir = 0; - pO->Insert( nDir, pO->Count() ); - } + rSectionLR.GetRight(), 0, 0, RES_LR_SPACE ); - rWrt.pISet = pOldI; - } + aSet.Put( aResultLR ); + + // und raus damit ins WW-File + const SfxItemSet* pOldI = pISet; + pISet = &aSet; + // --> OD 2007-06-12 #TESTING# + // Switch off test on default item values, if page description + // set (value of <bOutPgDscSet>) isn't written. + AttrOutput().OutputStyleItemSet( aSet, true, bOutPgDscSet ); + // <-- + + //Cannot export as normal page framedir, as continous sections + //cannot contain any grid settings like proper sections + AttrOutput().SectionBiDi( FRMDIR_HORI_RIGHT_TOP == TrueFrameDirection( *rSepInfo.pSectionFmt ) ); + + pISet = pOldI; } + } - if( bOutPgDscSet ) + if ( bOutPgDscSet ) + { + // es ist ein Follow gesetzt und dieser zeigt nicht auf sich + // selbst, so liegt eine Seitenverkettung vor. + // Falls damit eine "Erste Seite" simuliert werden soll, so + // koennen wir das auch als solches schreiben. + // Anders sieht es mit Links/Rechts wechseln aus. Dafuer muss + // erkannt werden, wo der Seitenwechsel statt findet. Hier ist + // es aber dafuer zuspaet! + if ( pPd->GetFollow() && pPd != pPd->GetFollow() && + pPd->GetFollow()->GetFollow() == pPd->GetFollow() && + ( !rSepInfo.pPDNd || pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) ) ) { - // es ist ein Follow gesetzt und dieser zeigt nicht auf sich - // selbst, so liegt eine Seitenverkettung vor. - // Falls damit eine "Erste Seite" simuliert werden soll, so - // koennen wir das auch als solches schreiben. - // Anders sieht es mit Links/Rechts wechseln aus. Dafuer muss - // erkannt werden, wo der Seitenwechsel statt findet. Hier ist - // es aber dafuer zuspaet! - if ( - pPd->GetFollow() && pPd != pPd->GetFollow() && - pPd->GetFollow()->GetFollow() == pPd->GetFollow() && - ( - !rSepInfo.pPDNd || - pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) - ) - ) + const SwPageDesc *pFollow = pPd->GetFollow(); + const SwFrmFmt& rFollowFmt = pFollow->GetMaster(); + if ( sw::util::IsPlausableSingleWordSection( *pPdFmt, rFollowFmt ) ) { - const SwPageDesc *pFollow = pPd->GetFollow(); - const SwFrmFmt& rFollowFmt = pFollow->GetMaster(); - if (sw::util::IsPlausableSingleWordSection(*pPdFmt, rFollowFmt)) - { - if (rSepInfo.pPDNd) - pPdFirstPgFmt = pPd->GetPageFmtOfNode(*rSepInfo.pPDNd); - else - pPdFirstPgFmt = &pPd->GetMaster(); - - rWrt.pAktPageDesc = pPd = pFollow; - pPdFmt = &rFollowFmt; - - // sprmSFTitlePage - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( *pO, 0x300A ); - else - pO->Insert( 143, pO->Count() ); - pO->Insert( 1, pO->Count() ); - } - } - - const SfxItemSet* pOldI = rWrt.pISet; + if (rSepInfo.pPDNd) + pPdFirstPgFmt = pPd->GetPageFmtOfNode( *rSepInfo.pPDNd ); + else + pPdFirstPgFmt = &pPd->GetMaster(); - if( rWrt.bWrtWW8 ) // Seitenumrandung schreiben - { - USHORT nPgBorder = HasBorderItem( *pPdFmt ) ? 0 : USHRT_MAX; - if( pPdFmt != pPdFirstPgFmt ) - { - if( HasBorderItem( *pPdFirstPgFmt )) - { - if( USHRT_MAX == nPgBorder ) - { - nPgBorder = 1; - // nur die 1. Seite umrandet -> BoxItem aus dem - // richtigen Format besorgen - rWrt.pISet = &pPdFirstPgFmt->GetAttrSet(); - Out( aWW8AttrFnTab, pPdFirstPgFmt->GetFmtAttr( - RES_BOX ), rWrt ); - } - } - else if( !nPgBorder ) - nPgBorder = 2; - } + pAktPageDesc = pPd = pFollow; + pPdFmt = &rFollowFmt; - if( USHRT_MAX != nPgBorder ) - { - // Flag und das Border Attribut schreiben - SwWW8Writer::InsUInt16( *pO, 0x522F ); - SwWW8Writer::InsUInt16( *pO, nPgBorder ); - } + // has different headers/footers for the title page + AttrOutput().SectionTitlePage(); } + } - const SfxPoolItem* pItem; - if( pPdFmt != pPdFirstPgFmt && SFX_ITEM_SET == - pPdFirstPgFmt->GetItemState(RES_PAPER_BIN, true, &pItem)) - { - rWrt.pISet = &pPdFirstPgFmt->GetAttrSet(); - rWrt.bOutFirstPage = true; - Out( aWW8AttrFnTab, *pItem, rWrt ); - rWrt.bOutFirstPage = false; - } + const SfxItemSet* pOldI = pISet; + AttrOutput().SectionPageBorders( pPdFmt, pPdFirstPgFmt ); - // left-/right chain of pagedescs ? - if( pPd->GetFollow() && pPd != pPd->GetFollow() && + const SfxPoolItem* pItem; + if ( pPdFmt != pPdFirstPgFmt && SFX_ITEM_SET == + pPdFirstPgFmt->GetItemState( RES_PAPER_BIN, true, &pItem ) ) + { + pISet = &pPdFirstPgFmt->GetAttrSet(); + bOutFirstPage = true; + AttrOutput().OutputItem( *pItem ); + bOutFirstPage = false; + } + + + // left-/right chain of pagedescs ? + if ( pPd->GetFollow() && pPd != pPd->GetFollow() && pPd->GetFollow()->GetFollow() == pPd && (( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) && nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) || ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) && nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) )) - { - bLeftRightPgChain = true; + { + bLeftRightPgChain = true; - // welches ist der Bezugspunkt ????? (links oder rechts?) - // annahme die rechte Seite! - if( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() )) - { - nBreakCode = 3; - pPd = pPd->GetFollow(); - pPdFmt = &pPd->GetMaster(); - } - else - nBreakCode = 4; + // welches ist der Bezugspunkt ????? (links oder rechts?) + // annahme die rechte Seite! + if ( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) ) + { + nBreakCode = 3; + pPd = pPd->GetFollow(); + pPdFmt = &pPd->GetMaster(); } - - rWrt.pISet = &pPdFmt->GetAttrSet(); - Out_SfxItemSet(aWW8AttrFnTab, rWrt, pPdFmt->GetAttrSet(), - true, false); - rWrt.pISet = pOldI; - - // dann noch die restlichen Einstellungen aus dem PageDesc - - // sprmSNfcPgn - BYTE nb = SwWW8Writer::GetNumId( pPd->GetNumType().GetNumberingType() ); - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( *pO, 0x300E ); else - pO->Insert( 147, pO->Count() ); - pO->Insert( nb, pO->Count() ); + nBreakCode = 4; + } -//??? const SwPageFtnInfo& rFtnInfo = pPd->GetFtnInfo(); + pISet = &pPdFmt->GetAttrSet(); + AttrOutput().OutputStyleItemSet( pPdFmt->GetAttrSet(), true, false ); + pISet = pOldI; - if( rSepInfo.nPgRestartNo ) - { - // sprmSFPgnRestart - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( *pO, 0x3011 ); - else - pO->Insert( 150, pO->Count() ); - pO->Insert( 1, pO->Count() ); - // sprmSPgnStart - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( *pO, 0x501C ); - else - pO->Insert( 161, pO->Count() ); - SwWW8Writer::InsUInt16( *pO, rSepInfo.nPgRestartNo ); - } + // dann noch die restlichen Einstellungen aus dem PageDesc - // werden es nur linke oder nur rechte Seiten? - if( 2 == nBreakCode ) - { - if( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() )) - nBreakCode = 3; - else if( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() )) - nBreakCode = 4; - } - } + AttrOutput().SectionPageNumbering( pPd->GetNumType().GetNumberingType(), rSepInfo.nPgRestartNo ); - if( 2 != nBreakCode ) // neue Seite ist default + // werden es nur linke oder nur rechte Seiten? + if ( 2 == nBreakCode ) { - if( rWrt.bWrtWW8 ) - SwWW8Writer::InsUInt16( *pO, 0x3009 ); - else - pO->Insert( 142, pO->Count() ); - pO->Insert( nBreakCode, pO->Count() ); + if ( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) ) + nBreakCode = 3; + else if ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) ) + nBreakCode = 4; } + } - WriteOlst( rWrt, i ); + AttrOutput().SectionType( nBreakCode ); + const SwTxtNode* pNd = rSepInfo.pNumNd; + if ( pNd ) + { + const SwNumRule* pRule = pNd->GetNumRule(); + if ( pRule ) + OutputOlst( *pRule ); + } - // Header oder Footer - BYTE nHeadFootFlags = 0; + // Header oder Footer + BYTE nHeadFootFlags = 0; - const SwFrmFmt* pPdLeftFmt = bLeftRightPgChain - ? &pPd->GetFollow()->GetMaster() - : &pPd->GetLeft(); + const SwFrmFmt* pPdLeftFmt = bLeftRightPgChain + ? &pPd->GetFollow()->GetMaster() + : &pPd->GetLeft(); - if (nBreakCode != 0) - { - SetHeaderFlag( nHeadFootFlags, *pPdFmt, WW8_HEADER_ODD ); - SetFooterFlag( nHeadFootFlags, *pPdFmt, WW8_FOOTER_ODD ); - if( !pPd->IsHeaderShared() || bLeftRightPgChain ) - SetHeaderFlag( nHeadFootFlags, *pPdLeftFmt, WW8_HEADER_EVEN ); - if( !pPd->IsFooterShared() || bLeftRightPgChain ) - SetFooterFlag( nHeadFootFlags, *pPdLeftFmt, WW8_FOOTER_EVEN ); - if( pPdFmt != pPdFirstPgFmt ) - { - // es gibt eine ErsteSeite: - SetHeaderFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_HEADER_FIRST ); - SetFooterFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_FOOTER_FIRST ); - } + if ( nBreakCode != 0 ) + { + MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFmt, WW8_HEADER_ODD ); + MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFmt, WW8_FOOTER_ODD ); - if( nHeadFootFlags && !rWrt.bWrtWW8 ) - { - BYTE nTmpFlags = nHeadFootFlags; - if( rWrt.pDop->fFacingPages ) - { - if( !(nTmpFlags & WW8_FOOTER_EVEN) && - (nTmpFlags & WW8_FOOTER_ODD ) ) - nTmpFlags |= WW8_FOOTER_EVEN; + if ( !pPd->IsHeaderShared() || bLeftRightPgChain ) + MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdLeftFmt, WW8_HEADER_EVEN ); - if( !(nTmpFlags & WW8_HEADER_EVEN) && - (nTmpFlags & WW8_HEADER_ODD ) ) - nTmpFlags |= WW8_HEADER_EVEN; - } + if ( !pPd->IsFooterShared() || bLeftRightPgChain ) + MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdLeftFmt, WW8_FOOTER_EVEN ); - // sprmSGprfIhdt, wird nur noch im WW95 benoetigt - pO->Insert( 153, pO->Count() ); - pO->Insert( nTmpFlags, pO->Count() ); - } + if ( pPdFmt != pPdFirstPgFmt ) + { + // es gibt eine ErsteSeite: + MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_HEADER_FIRST ); + MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_FOOTER_FIRST ); } - if( pO->Count() ) - { // waren Attrs vorhanden ? - pA->nLen = pO->Count(); - pA->pData = new BYTE [pO->Count()]; - memcpy( pA->pData, pO->GetData(), pO->Count() ); // -> merken - pO->Remove( 0, pO->Count() ); // leeren fuer HdFt-Text - } - else - { // keine Attrs da - pA->pData = 0; - pA->nLen = 0; - } + AttrOutput().SectionWW6HeaderFooterFlags( nHeadFootFlags ); + } -/* -!!!!!!!!!!! - // Umrandungen an Kopf- und Fusstexten muessten etwa so gehen: - // Dabei muss etwas wie pOut eingebaut werden, - // das bei jeder Spezialtext-Zeile wiederholt wird. - const SwFrmFmt* pFFmt = rFt.GetFooterFmt(); - const SvxBoxItem& rBox = pFFmt->GetBox(false); - OutWW8_SwFmtBox1( rWrt.pOut, rBox, false); -!!!!!!!!!!! - Man koennt daraus Absatzattribute machen, die dann bei jedem Absatz - beachtet werden. Gilt fuer Hintergrund/Umrandung -!!!!!!!!!!! -*/ - - const SwTxtNode *pOldPageRoot = rWrt.GetHdFtPageRoot(); - rWrt.SetHdFtPageRoot(rSepInfo.pPDNd ? rSepInfo.pPDNd->GetTxtNode() : 0); - - ULONG nCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() ); - - rWrt.SetHdFtIndex(++nHdFtGroup); - if( !(nHeadFootFlags & WW8_HEADER_EVEN) && rWrt.pDop->fFacingPages ) - OutHeader( rWrt, *pPdFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD ); - else - OutHeader( rWrt, *pPdLeftFmt, nCpPos, nHeadFootFlags, WW8_HEADER_EVEN ); - rWrt.SetHdFtIndex(++nHdFtGroup); - OutHeader( rWrt, *pPdFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD ); + // binary filters only + SetupSectionPositions( pA ); - rWrt.SetHdFtIndex(++nHdFtGroup); - if( !(nHeadFootFlags & WW8_FOOTER_EVEN) && rWrt.pDop->fFacingPages ) - OutFooter( rWrt, *pPdFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD ); - else - OutFooter( rWrt, *pPdLeftFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_EVEN ); - rWrt.SetHdFtIndex(++nHdFtGroup); - OutFooter( rWrt, *pPdFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD ); + /* + !!!!!!!!!!! + // Umrandungen an Kopf- und Fusstexten muessten etwa so gehen: + // Dabei muss etwas wie pOut eingebaut werden, + // das bei jeder Spezialtext-Zeile wiederholt wird. + const SwFrmFmt* pFFmt = rFt.GetFooterFmt(); + const SvxBoxItem& rBox = pFFmt->GetBox(false); + OutWW8_SwFmtBox1( m_rWW8Export.pOut, rBox, false); + !!!!!!!!!!! + Man koennt daraus Absatzattribute machen, die dann bei jedem Absatz + beachtet werden. Gilt fuer Hintergrund/Umrandung + !!!!!!!!!!! + */ + + const SwTxtNode *pOldPageRoot = GetHdFtPageRoot(); + SetHdFtPageRoot( rSepInfo.pPDNd ? rSepInfo.pPDNd->GetTxtNode() : 0 ); + + WriteHeadersFooters( nHeadFootFlags, *pPdFmt, *pPdLeftFmt, *pPdFirstPgFmt ); + + SetHdFtPageRoot( pOldPageRoot ); + + AttrOutput().EndSection(); + + // outside of the section properties again + bOutPageDescs = bOldPg; +} - //#i24344# Drawing objects cannot be directly shared between main hd/ft - //and title hd/ft so we need to differenciate them - rWrt.SetHdFtIndex(++nHdFtGroup); - OutHeader( rWrt, *pPdFirstPgFmt, nCpPos, nHeadFootFlags, WW8_HEADER_FIRST ); - OutFooter( rWrt, *pPdFirstPgFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_FIRST ); - rWrt.SetHdFtPageRoot(pOldPageRoot); +bool WW8_WrPlcSepx::WriteKFTxt( WW8Export& rWrt ) +{ + pAttrs = new WW8_PdAttrDesc[ aSects.Count() ]; + ULONG nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() ); + + ASSERT( !pTxtPos, "wer hat den Pointer gesetzt?" ); + pTxtPos = new WW8_WrPlc0( nCpStart ); + + WriteFtnEndTxt( rWrt, nCpStart ); + CheckForFacinPg( rWrt ); + + unsigned int nOldIndex = rWrt.GetHdFtIndex(); + rWrt.SetHdFtIndex( 0 ); + for ( USHORT i = 0; i < aSects.Count(); ++i ) + { + WW8_PdAttrDesc* pA = pAttrs + i; + pA->pData = 0; + pA->nLen = 0; + pA->nSepxFcPos = 0xffffffff; // Default: none + + WW8_SepInfo& rSepInfo = aSects[i]; + + rWrt.SectionProperties( rSepInfo, pA ); } - rWrt.SetHdFtIndex(nOldIndex); //0 + rWrt.SetHdFtIndex( nOldIndex ); //0 - if( pTxtPos->Count() ) + if ( pTxtPos->Count() ) { // HdFt vorhanden ? ULONG nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() ); pTxtPos->Append( nCpEnd ); // Ende letzter Hd/Ft fuer PlcfHdd - if( nCpEnd > nCpStart ) + if ( nCpEnd > nCpStart ) { ++nCpEnd; pTxtPos->Append( nCpEnd + 1 ); // Ende letzter Hd/Ft fuer PlcfHdd @@ -1562,7 +1726,6 @@ bool WW8_WrPlcSepx::WriteKFTxt(SwWW8Writer& rWrt) else delete pTxtPos, pTxtPos = 0; - rWrt.bOutPageDescs = bOldPg; return rWrt.pFib->ccpHdr != 0; } @@ -1583,7 +1746,7 @@ void WW8_WrPlcSepx::WriteSepx( SvStream& rStrm ) const } } -void WW8_WrPlcSepx::WritePlcSed( SwWW8Writer& rWrt ) const +void WW8_WrPlcSepx::WritePlcSed( WW8Export& rWrt ) const { ASSERT( aCps.Count() == aSects.Count() + 1, "WrPlcSepx: DeSync" ); ULONG nFcStart = rWrt.pTableStrm->Tell(); @@ -1612,7 +1775,7 @@ void WW8_WrPlcSepx::WritePlcSed( SwWW8Writer& rWrt ) const } -void WW8_WrPlcSepx::WritePlcHdd( SwWW8Writer& rWrt ) const +void WW8_WrPlcSepx::WritePlcHdd( WW8Export& rWrt ) const { if( pTxtPos && pTxtPos->Count() ) { @@ -1623,11 +1786,27 @@ void WW8_WrPlcSepx::WritePlcHdd( SwWW8Writer& rWrt ) const } } -void SwWW8Writer::WriteKFTxt1( const SwFmtCntnt& rCntnt ) +void MSWordExportBase::WriteHeaderFooterText( const SwFmt& rFmt, bool bHeader ) { - const SwNodeIndex* pSttIdx = rCntnt.GetCntntIdx(); + const SwFmtCntnt *pCntnt; + if ( bHeader ) + { + bHasHdr = true; + const SwFmtHeader& rHd = rFmt.GetHeader(); + ASSERT( rHd.GetHeaderFmt(), "Header text is not here" ); + pCntnt = &rHd.GetHeaderFmt()->GetCntnt(); + } + else + { + bHasFtr = true; + const SwFmtFooter& rFt = rFmt.GetFooter(); + ASSERT( rFt.GetFooterFmt(), "Footer text is not here" ); + pCntnt = &rFt.GetFooterFmt()->GetCntnt(); + } - if (pSttIdx) + const SwNodeIndex* pSttIdx = pCntnt->GetCntntIdx(); + + if ( pSttIdx ) { SwNodeIndex aIdx( *pSttIdx, 1 ), aEnd( *pSttIdx->GetNode().EndOfSectionNode() ); @@ -1635,7 +1814,7 @@ void SwWW8Writer::WriteKFTxt1( const SwFmtCntnt& rCntnt ) ULONG nEnd = aEnd.GetIndex(); // Bereich also gueltiger Node - if (nStart < nEnd) + if ( nStart < nEnd ) { bool bOldKF = bOutKF; bOutKF = true; @@ -1646,11 +1825,11 @@ void SwWW8Writer::WriteKFTxt1( const SwFmtCntnt& rCntnt ) pSttIdx = 0; } - if (!pSttIdx) + if ( !pSttIdx ) { // es gibt keine Kopf-/Fusszeile, aber ein CR ist immer noch noetig ASSERT( pSttIdx, "K/F-Text nicht richtig da" ); - WriteStringAsPara( aEmptyStr ); // CR ans Ende ( sonst mault WW ) + AttrOutput().EmptyParagraph(); // CR ans Ende ( sonst mault WW ) } } @@ -1684,21 +1863,21 @@ void WW8_WrPlcPostIt::Append( WW8_CP nCp, const SwPostItField& rPostIt ) aCntnt.Insert( p, aCntnt.Count() ); } -bool WW8_WrPlcSubDoc::WriteGenericTxt(SwWW8Writer& rWrt, BYTE nTTyp, - WW8_CP& rCount) +bool WW8_WrPlcSubDoc::WriteGenericTxt( WW8Export& rWrt, BYTE nTTyp, + WW8_CP& rCount ) { - bool bRet = false; USHORT nLen = aCntnt.Count(); - if( nLen ) - { - ULONG nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() ); - pTxtPos = new WW8_WrPlc0( nCpStart ); - USHORT i; + if ( !nLen ) + return false; - switch( nTTyp ) - { + ULONG nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() ); + pTxtPos = new WW8_WrPlc0( nCpStart ); + USHORT i; + + switch ( nTTyp ) + { case TXT_ATN: - for( i = 0; i < nLen; i++ ) + for ( i = 0; i < nLen; i++ ) { // Anfaenge fuer PlcfAtnTxt pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() )); @@ -1718,7 +1897,7 @@ bool WW8_WrPlcSubDoc::WriteGenericTxt(SwWW8Writer& rWrt, BYTE nTTyp, case TXT_TXTBOX: case TXT_HFTXTBOX: - for( i = 0; i < nLen; i++ ) + for ( i = 0; i < nLen; i++ ) { // textbox - content WW8_CP nCP = rWrt.Fc2Cp( rWrt.Strm().Tell() ); @@ -1744,8 +1923,8 @@ bool WW8_WrPlcSubDoc::WriteGenericTxt(SwWW8Writer& rWrt, BYTE nTTyp, const SwNodeIndex* pNdIdx = pFmt->GetCntnt().GetCntntIdx(); ASSERT( pNdIdx, "wo ist der StartNode der Textbox?" ); rWrt.WriteSpecialText( pNdIdx->GetIndex() + 1, - pNdIdx->GetNode().EndOfSectionIndex(), - nTTyp ); + pNdIdx->GetNode().EndOfSectionIndex(), + nTTyp ); // --> OD 2008-08-07 #156757# { SwNodeIndex aContentIdx = *pNdIdx; @@ -1781,7 +1960,7 @@ bool WW8_WrPlcSubDoc::WriteGenericTxt(SwWW8Writer& rWrt, BYTE nTTyp, case TXT_EDN: case TXT_FTN: - for( i = 0; i < nLen; i++ ) + for ( i = 0; i < nLen; i++ ) { // Anfaenge fuer PlcfFtnTxt/PlcfEdnTxt pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() )); @@ -1799,43 +1978,42 @@ bool WW8_WrPlcSubDoc::WriteGenericTxt(SwWW8Writer& rWrt, BYTE nTTyp, default: ASSERT( !this, "was ist das fuer ein SubDocType?" ); - } + } - pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() )); - // CR ans Ende ( sonst mault WW ) - rWrt.WriteStringAsPara( aEmptyStr ); + pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() )); + // CR ans Ende ( sonst mault WW ) + rWrt.WriteStringAsPara( aEmptyStr ); - WW8_CP nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() ); - pTxtPos->Append( nCpEnd ); - rCount = nCpEnd - nCpStart; - if (rCount) - bRet = true; - } - return bRet; + WW8_CP nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() ); + pTxtPos->Append( nCpEnd ); + rCount = nCpEnd - nCpStart; + + return ( rCount != 0 ); } -void WW8_WrPlcSubDoc::WriteGenericPlc( SwWW8Writer& rWrt, BYTE nTTyp, +void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, BYTE nTTyp, WW8_FC& rTxtStart, sal_Int32& rTxtCount, WW8_FC& rRefStart, sal_Int32& rRefCount ) const { typedef ::std::vector<String>::iterator myiter; ULONG nFcStart = rWrt.pTableStrm->Tell(); USHORT nLen = aCps.Count(); - if( nLen ) - { - ASSERT( aCps.Count() + 2 == pTxtPos->Count(), "WritePlc: DeSync" ); + if ( !nLen ) + return; - ::std::vector<String> aStrArr; - WW8Fib& rFib = *rWrt.pFib; // n+1-te CP-Pos nach Handbuch - USHORT i; - bool bWriteCP = true; + ASSERT( aCps.Count() + 2 == pTxtPos->Count(), "WritePlc: DeSync" ); - switch( nTTyp ) - { + ::std::vector<String> aStrArr; + WW8Fib& rFib = *rWrt.pFib; // n+1-te CP-Pos nach Handbuch + USHORT i; + bool bWriteCP = true; + + switch ( nTTyp ) + { case TXT_ATN: { // then write first the GrpXstAtnOwners - for( i = 0; i < nLen; ++i ) + for ( i = 0; i < nLen; ++i ) { const SwPostItField& rPFld = *(SwPostItField*)aCntnt[ i ]; aStrArr.push_back(rPFld.GetPar1()); @@ -1846,24 +2024,24 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( SwWW8Writer& rWrt, BYTE nTTyp, myiter aIter = ::std::unique(aStrArr.begin(), aStrArr.end()); aStrArr.erase(aIter, aStrArr.end()); - if( rWrt.bWrtWW8 ) + if ( rWrt.bWrtWW8 ) { - for( i = 0; i < aStrArr.size(); ++i ) + for ( i = 0; i < aStrArr.size(); ++i ) { const String& rStr = aStrArr[i]; SwWW8Writer::WriteShort(*rWrt.pTableStrm, rStr.Len()); SwWW8Writer::WriteString16(*rWrt.pTableStrm, rStr, - false); + false); } } else { - for( i = 0; i < aStrArr.size(); ++i ) + for ( i = 0; i < aStrArr.size(); ++i ) { const String& rStr = aStrArr[i]; *rWrt.pTableStrm << (BYTE)rStr.Len(); SwWW8Writer::WriteString8(*rWrt.pTableStrm, rStr, false, - RTL_TEXTENCODING_MS_1252); + RTL_TEXTENCODING_MS_1252); } } @@ -1904,19 +2082,19 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( SwWW8Writer& rWrt, BYTE nTTyp, ASSERT( pShapeIds, "wo sind die ShapeIds?" ); // nLen = pTxtPos->Count(); - for( i = 0; i < nLen; ++i ) + for ( i = 0; i < nLen; ++i ) { // write textbox story - FTXBXS // is it an writer or sdr - textbox? const SdrObject* pObj = (SdrObject*)aCntnt[ i ]; INT32 nCnt = 1; - if( !pObj->ISA( SdrTextObj ) ) + if ( !pObj->ISA( SdrTextObj ) ) { // find the "highest" SdrObject of this const SwFrmFmt& rFmt = *::FindFrmFmt( pObj ); const SwFmtChain* pChn = &rFmt.GetChain(); - while( pChn->GetNext() ) + while ( pChn->GetNext() ) { // has a chain? // then calc the cur pos in the chain @@ -1934,7 +2112,7 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( SwWW8Writer& rWrt, BYTE nTTyp, SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 ); // long lid SwWW8Writer::WriteLong( *rWrt.pTableStrm, - (*pShapeIds)[i]); + (*pShapeIds)[i]); // long txidUndo SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 ); } @@ -1942,91 +2120,91 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( SwWW8Writer& rWrt, BYTE nTTyp, bWriteCP = false; } break; - } + } - if( bWriteCP ) - { - // Schreibe CP-Positionen - for( i = 0; i < nLen; i++ ) - SwWW8Writer::WriteLong( *rWrt.pTableStrm, aCps[ i ] ); + if ( bWriteCP ) + { + // Schreibe CP-Positionen + for ( i = 0; i < nLen; i++ ) + SwWW8Writer::WriteLong( *rWrt.pTableStrm, aCps[ i ] ); - // n+1-te CP-Pos nach Handbuch - SwWW8Writer::WriteLong( *rWrt.pTableStrm, + // n+1-te CP-Pos nach Handbuch + SwWW8Writer::WriteLong( *rWrt.pTableStrm, rFib.ccpText + rFib.ccpFtn + rFib.ccpHdr + rFib.ccpEdn + rFib.ccpTxbx + rFib.ccpHdrTxbx + 1 ); - if( TXT_ATN == nTTyp ) + if ( TXT_ATN == nTTyp ) + { + for ( i = 0; i < nLen; ++i ) { - for( i = 0; i < nLen; ++i ) - { - const SwPostItField& rPFld = *(SwPostItField*)aCntnt[ i ]; + const SwPostItField& rPFld = *(SwPostItField*)aCntnt[ i ]; - //aStrArr is sorted - myiter aIter = ::std::lower_bound(aStrArr.begin(), + //aStrArr is sorted + myiter aIter = ::std::lower_bound(aStrArr.begin(), aStrArr.end(), rPFld.GetPar1()); - ASSERT(aIter != aStrArr.end() && *aIter == rPFld.GetPar1(), + ASSERT(aIter != aStrArr.end() && *aIter == rPFld.GetPar1(), "Impossible"); - sal_uInt16 nFndPos = static_cast< sal_uInt16 >(aIter - aStrArr.begin()); - String sAuthor(*aIter); - BYTE nNameLen = (BYTE)sAuthor.Len(); - if (nNameLen > 9) - { - sAuthor.Erase( 9 ); - nNameLen = 9; - } + sal_uInt16 nFndPos = static_cast< sal_uInt16 >(aIter - aStrArr.begin()); + String sAuthor(*aIter); + BYTE nNameLen = (BYTE)sAuthor.Len(); + if ( nNameLen > 9 ) + { + sAuthor.Erase( 9 ); + nNameLen = 9; + } - // xstUsrInitl[ 10 ] pascal-style String holding initials - // of annotation author - if( rWrt.bWrtWW8 ) - { - SwWW8Writer::WriteShort(*rWrt.pTableStrm, nNameLen); - SwWW8Writer::WriteString16(*rWrt.pTableStrm, sAuthor, + // xstUsrInitl[ 10 ] pascal-style String holding initials + // of annotation author + if ( rWrt.bWrtWW8 ) + { + SwWW8Writer::WriteShort(*rWrt.pTableStrm, nNameLen); + SwWW8Writer::WriteString16(*rWrt.pTableStrm, sAuthor, false); - SwWW8Writer::FillCount( *rWrt.pTableStrm, + SwWW8Writer::FillCount( *rWrt.pTableStrm, (9 - nNameLen) * 2 ); - } - else - { - *rWrt.pTableStrm << nNameLen; - SwWW8Writer::WriteString8(*rWrt.pTableStrm, sAuthor, - false, RTL_TEXTENCODING_MS_1252); - SwWW8Writer::FillCount(*rWrt.pTableStrm, 9 - nNameLen); - } + } + else + { + *rWrt.pTableStrm << nNameLen; + SwWW8Writer::WriteString8(*rWrt.pTableStrm, sAuthor, + false, RTL_TEXTENCODING_MS_1252); + SwWW8Writer::FillCount(*rWrt.pTableStrm, 9 - nNameLen); + } - //SVBT16 ibst; // index into GrpXstAtnOwners - //SVBT16 ak; // not used - //SVBT16 grfbmc; // not used - //SVBT32 ITagBkmk; // when not -1, this tag identifies the + //SVBT16 ibst; // index into GrpXstAtnOwners + //SVBT16 ak; // not used + //SVBT16 grfbmc; // not used + //SVBT32 ITagBkmk; // when not -1, this tag identifies the - SwWW8Writer::WriteShort( *rWrt.pTableStrm, nFndPos ); - SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); - SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); - SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 ); - } + SwWW8Writer::WriteShort( *rWrt.pTableStrm, nFndPos ); + SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); + SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); + SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 ); } - else + } + else + { + USHORT nNo = 0; + for ( i = 0; i < nLen; ++i ) // Schreibe Flags { - USHORT nNo = 0; - for( i = 0; i < nLen; ++i ) // Schreibe Flags - { - const SwFmtFtn* pFtn = (SwFmtFtn*)aCntnt[ i ]; - SwWW8Writer::WriteShort( *rWrt.pTableStrm, - pFtn->GetNumStr().Len() ? 0 : ++nNo ); - } + const SwFmtFtn* pFtn = (SwFmtFtn*)aCntnt[ i ]; + SwWW8Writer::WriteShort( *rWrt.pTableStrm, + pFtn->GetNumStr().Len() ? 0 : ++nNo ); } } - rRefStart = nFcStart; - nFcStart = rWrt.pTableStrm->Tell(); - rRefCount = nFcStart - rRefStart; + } + rRefStart = nFcStart; + nFcStart = rWrt.pTableStrm->Tell(); + rRefCount = nFcStart - rRefStart; - pTxtPos->Write( *rWrt.pTableStrm ); + pTxtPos->Write( *rWrt.pTableStrm ); - switch( nTTyp ) - { + switch ( nTTyp ) + { case TXT_TXTBOX: case TXT_HFTXTBOX: - for( i = 0; i < nLen; ++i ) + for ( i = 0; i < nLen; ++i ) { // write break descriptor (BKD) // short itxbxs @@ -2039,11 +2217,10 @@ void WW8_WrPlcSubDoc::WriteGenericPlc( SwWW8Writer& rWrt, BYTE nTTyp, } SwWW8Writer::FillCount( *rWrt.pTableStrm, 6 ); break; - } - - rTxtStart = nFcStart; - rTxtCount = rWrt.pTableStrm->Tell() - nFcStart; } + + rTxtStart = nFcStart; + rTxtCount = rWrt.pTableStrm->Tell() - nFcStart; } const SvULongs* WW8_WrPlcSubDoc::GetShapeIdArr() const diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 99df3307254c..032c1fda8171 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -97,8 +97,12 @@ #include <fmtline.hxx> #include <fmtfsize.hxx> #include <comphelper/extract.hxx> + +#include <writerfilter/doctok/sprmids.hxx> + #include "writerhelper.hxx" #include "writerwordglue.hxx" +#include "ww8attributeoutput.hxx" #include <IDocumentMarkAccess.hxx> @@ -117,6 +121,8 @@ using namespace sw::util; using namespace sw::types; +/** FKP - Formatted disK Page +*/ class WW8_WrFkp { BYTE* pFkp; // gesamter Fkp ( zuerst nur FCs und Sprms ) @@ -197,7 +203,7 @@ public: ~WW8_WrtBookmarks(); void Append( WW8_CP nStartCp, const String& rNm, const ::sw::mark::IMark* pBkmk=NULL ); - void Write( SwWW8Writer& rWrt ); + void Write( WW8Export& rWrt ); void MoveFieldMarks(ULONG nFrom,ULONG nTo); // String GetWWBkmkName( const String& rName ) const; @@ -217,7 +223,7 @@ typedef WW8_WrPc* WW8_WrPcPtr; SV_DECL_PTRARR_DEL( WW8_WrPcPtrs, WW8_WrPcPtr, 4, 4 ) SV_IMPL_PTRARR( WW8_WrPcPtrs, WW8_WrPcPtr ) -static void WriteDop( SwWW8Writer& rWrt ) +static void WriteDop( WW8Export& rWrt ) { WW8Dop& rDop = *rWrt.pDop; @@ -336,7 +342,7 @@ Converts the OOo Asian Typography into a best fit match for Microsoft Asian typography. This structure is actually dumped to disk within the Dop Writer. Assumption is that rTypo is cleared to 0 on entry */ -void SwWW8Writer::ExportDopTypography(WW8DopTypography &rTypo) +void WW8Export::ExportDopTypography(WW8DopTypography &rTypo) { static const sal_Unicode aLangNotBegin[4][WW8DopTypography::nMaxFollowing]= { @@ -507,7 +513,7 @@ void SwWW8Writer::ExportDopTypography(WW8DopTypography &rTypo) (rTypo.cchLeadingPunct+1)*2); } - const IDocumentSettingAccess* pIDocumentSettingAccess = getIDocumentSettingAccess(); + const IDocumentSettingAccess* pIDocumentSettingAccess = GetWriter().getIDocumentSettingAccess(); rTypo.fKerningPunct = pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION); rTypo.iJustification = pDoc->getCharacterCompressionType(); @@ -517,8 +523,8 @@ void SwWW8Writer::ExportDopTypography(WW8DopTypography &rTypo) // Underline / WordLineMode und Box / Shadow. // Es kann nur etwas gefunden werden, wenn diese Methode innerhalb // der aufgerufenen Methoden WW8_SwAttrIter::OutAttr() und -// SwWW8Writer::Out_SfxItemSet() benutzt wird. -const SfxPoolItem* SwWW8Writer::HasItem( USHORT nWhich ) const +// WW8Export::OutputItemSet() benutzt wird. +const SfxPoolItem* MSWordExportBase::HasItem( USHORT nWhich ) const { const SfxPoolItem* pItem=0; if (pISet) @@ -540,7 +546,7 @@ const SfxPoolItem* SwWW8Writer::HasItem( USHORT nWhich ) const return pItem; } -const SfxPoolItem& SwWW8Writer::GetItem(USHORT nWhich) const +const SfxPoolItem& MSWordExportBase::GetItem(USHORT nWhich) const { const SfxPoolItem* pItem; if (pISet) @@ -624,7 +630,7 @@ void WW8_WrPlc1::Write( SvStream& rStrm ) //------------------------------------------------------------------------------ -bool WW8_WrPlcFld::Write(SwWW8Writer& rWrt) +bool WW8_WrPlcFld::Write( WW8Export& rWrt ) { if( WW8_WrPlc1::Count() <= 1 ) return false; @@ -682,7 +688,7 @@ bool WW8_WrPlcFld::Write(SwWW8Writer& rWrt) return true; } -bool WW8_WrMagicTable::Write(SwWW8Writer& rWrt) +bool WW8_WrMagicTable::Write( WW8Export& rWrt ) { if( WW8_WrPlc1::Count() <= 1 ) return false; @@ -744,7 +750,7 @@ ULONG SwWW8Writer::FillUntil( SvStream& rStrm, ULONG nEndPos ) //-------------------------------------------------------------------------- /* */ -WW8_WrPlcPn::WW8_WrPlcPn( SwWW8Writer& rWr, ePLCFT ePl, WW8_FC nStartFc ) +WW8_WrPlcPn::WW8_WrPlcPn( WW8Export& rWr, ePLCFT ePl, WW8_FC nStartFc ) : rWrt(rWr), nFkpStartPage(0), ePlc(ePl), nMark(0) { WW8_FkpPtr pF = new WW8_WrFkp( ePlc, nStartFc, rWrt.bWrtWW8 ); @@ -1168,7 +1174,7 @@ void WW8_WrPct::AppendPc(WW8_FC nStartFc, bool bIsUnicode) } -void WW8_WrPct::WritePc( SwWW8Writer& rWrt ) +void WW8_WrPct::WritePc( WW8Export& rWrt ) { ULONG nPctStart; ULONG nOldPos, nEndPos; @@ -1277,7 +1283,7 @@ void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const String& rNm, const ::sw:: } -void WW8_WrtBookmarks::Write( SwWW8Writer& rWrt ) +void WW8_WrtBookmarks::Write( WW8Export& rWrt ) { USHORT nCount = aSttCps.Count(), i; if( nCount ) @@ -1358,13 +1364,13 @@ void WW8_WrtBookmarks::MoveFieldMarks(ULONG nFrom, ULONG nTo) } } -void SwWW8Writer::AppendBookmarks( const SwTxtNode& rNd, +void WW8Export::AppendBookmarks( const SwTxtNode& rNd, xub_StrLen nAktPos, xub_StrLen nLen ) { SvPtrarr aArr( 8, 8 ); USHORT nCntnt; xub_StrLen nAktEnd = nAktPos + nLen; - if( GetBookmarks( rNd, nAktPos, nAktEnd, aArr )) + if( GetWriter().GetBookmarks( rNd, nAktPos, nAktEnd, aArr )) { ULONG nNd = rNd.GetIndex(), nSttCP = Fc2Cp( Strm().Tell() ); for( USHORT n = 0; n < aArr.Count(); ++n ) @@ -1402,15 +1408,20 @@ void SwWW8Writer::AppendBookmarks( const SwTxtNode& rNd, } } -void SwWW8Writer::MoveFieldMarks(ULONG nFrom, ULONG nTo) +void WW8Export::MoveFieldMarks(ULONG nFrom, ULONG nTo) { pBkmks->MoveFieldMarks(nFrom, nTo); } -void SwWW8Writer::AppendBookmark(const String& rName, USHORT nOffset) +void WW8Export::AppendBookmark( const rtl::OUString& rName, bool bSkip ) +{ + ULONG nSttCP = Fc2Cp( Strm().Tell() ) + ( bSkip? 1: 0 ); + pBkmks->Append( nSttCP, rName ); +} + +void MSWordExportBase::AppendWordBookmark( const String& rName ) { - ULONG nSttCP = Fc2Cp(Strm().Tell()) + nOffset; - pBkmks->Append(nSttCP, rName); + AppendBookmark( BookmarkToWord( rName ) ); } @@ -1419,12 +1430,12 @@ void SwWW8Writer::AppendBookmark(const String& rName, USHORT nOffset) void WW8_WrtRedlineAuthor::Write( Writer& rWrt ) { - SwWW8Writer & rWW8Wrt = (SwWW8Writer&)rWrt; + WW8Export & rWW8Wrt = *(((SwWW8Writer&)rWrt).m_pExport); rWW8Wrt.WriteAsStringTable(maAuthors, rWW8Wrt.pFib->fcSttbfRMark, rWW8Wrt.pFib->lcbSttbfRMark, rWW8Wrt.bWrtWW8 ? 0 : 2); } -USHORT SwWW8Writer::AddRedlineAuthor( USHORT nId ) +USHORT WW8Export::AddRedlineAuthor( USHORT nId ) { if( !pRedlAuthors ) { @@ -1437,7 +1448,7 @@ USHORT SwWW8Writer::AddRedlineAuthor( USHORT nId ) //-------------------------------------------------------------------------- /* */ -void SwWW8Writer::WriteAsStringTable(const std::vector<String>& rStrings, +void WW8Export::WriteAsStringTable(const std::vector<String>& rStrings, INT32& rfcSttbf, INT32& rlcbSttbf, USHORT nExtraLen) { USHORT n, nCount = static_cast< USHORT >(rStrings.size()); @@ -1612,7 +1623,7 @@ void SwWW8Writer::WriteString8(SvStream& rStrm, const String& rStr, rStrm.Write(&aBytes[0], aBytes.size()); } -void SwWW8Writer::WriteStringAsPara( const String& rTxt, USHORT nStyleId ) +void WW8Export::WriteStringAsPara( const String& rTxt, USHORT nStyleId ) { if( rTxt.Len() ) OutSwString( rTxt, 0, rTxt.Len(), IsUnicode(), RTL_TEXTENCODING_MS_1252 ); @@ -1624,7 +1635,7 @@ void SwWW8Writer::WriteStringAsPara( const String& rTxt, USHORT nStyleId ) { // Tab-Attr // sprmPFInTable if( bWrtWW8 ) - SwWW8Writer::InsUInt16( aArr, 0x2416 ); + SwWW8Writer::InsUInt16( aArr, NS_sprm::LN_PFInTable ); else aArr.Insert( 24, aArr.Count() ); aArr.Insert( 1, aArr.Count() ); @@ -1635,7 +1646,7 @@ void SwWW8Writer::WriteStringAsPara( const String& rTxt, USHORT nStyleId ) pChpPlc->AppendFkpEntry( nPos ); } -void SwWW8Writer::WriteSpecialText( ULONG nStart, ULONG nEnd, BYTE nTTyp ) +void MSWordExportBase::WriteSpecialText( ULONG nStart, ULONG nEnd, BYTE nTTyp ) { BYTE nOldTyp = nTxtTyp; nTxtTyp = nTTyp; @@ -1644,12 +1655,14 @@ void SwWW8Writer::WriteSpecialText( ULONG nStart, ULONG nEnd, BYTE nTTyp ) bool bOldPageDescs = bOutPageDescs; bOutPageDescs = false; // bOutKF wird in WriteKF1 gemerkt / gesetzt - pCurPam = NewSwPaM( *pDoc, nStart, nEnd ); + pCurPam = Writer::NewSwPaM( *pDoc, nStart, nEnd ); // Tabelle in Sonderbereichen erkennen - if( (nStart != pCurPam->GetMark()->nNode.GetIndex()) - && pDoc->GetNodes()[ nStart ]->IsTableNode() ) + if ( ( nStart != pCurPam->GetMark()->nNode.GetIndex() ) && + pDoc->GetNodes()[ nStart ]->IsTableNode() ) + { pCurPam->GetMark()->nNode = nStart; + } pOrigPam = pCurPam; pCurPam->Exchange(); @@ -1663,7 +1676,7 @@ void SwWW8Writer::WriteSpecialText( ULONG nStart, ULONG nEnd, BYTE nTTyp ) nTxtTyp = nOldTyp; } -void SwWW8Writer::OutSwString(const String& rStr, xub_StrLen nStt, +void WW8Export::OutSwString(const String& rStr, xub_StrLen nStt, xub_StrLen nLen, bool bUnicode, rtl_TextEncoding eChrSet) { @@ -1707,7 +1720,7 @@ void SwWW8Writer::OutSwString(const String& rStr, xub_StrLen nStt, #endif } -void SwWW8Writer::WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8Export::WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) { if (pTableTextNodeInfoInner.get() != NULL && pTableTextNodeInfoInner->getDepth() == 1 && pTableTextNodeInfoInner->isEndOfCell()) WriteChar('\007'); @@ -1717,7 +1730,7 @@ void SwWW8Writer::WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeIn pPiece->SetParaBreak(); } -void SwWW8Writer::WriteChar( sal_Unicode c ) +void WW8Export::WriteChar( sal_Unicode c ) { if( pPiece->IsUnicode() ) Strm() << c; @@ -1725,136 +1738,177 @@ void SwWW8Writer::WriteChar( sal_Unicode c ) Strm() << (BYTE)c; } -/* */ -//--------------------------------------------------------------------------- -// Hilfsroutinen fuer Flys -//--------------------------------------------------------------------------- -// Struktur speichert die aktuellen Daten des Writers zwischen, um -// einen anderen Dokument-Teil auszugeben, wie z.B. Header/Footer -WW8SaveData::WW8SaveData( SwWW8Writer& rWriter, ULONG nStt, ULONG nEnd ) - : rWrt( rWriter ), - pOldPam( rWrt.pCurPam ), pOldEnd( rWrt.GetEndPaM() ), - pOldFlyFmt(rWrt.mpParentFrame), pOldPageDesc( rWrt.pAktPageDesc ) - +void MSWordExportBase::SaveData( ULONG nStt, ULONG nEnd ) { - pOldFlyOffset = rWrt.pFlyOffset; - eOldAnchorType = rWrt.eNewAnchorType; - if( rWrt.pO->Count() ) + MSWordSaveData aData; + + // WW8Export only stuff - zeroed here not to issue warnings + aData.pOOld = NULL; + aData.mpTableAtOld = NULL; + aData.mnTableStdAtLenOld = 0; + + // Common stuff + aData.pOldPam = pCurPam; + aData.pOldEnd = pOrigPam; + aData.pOldFlyFmt = mpParentFrame; + aData.pOldPageDesc = pAktPageDesc; + + aData.pOldFlyOffset = pFlyOffset; + aData.eOldAnchorType = eNewAnchorType; + + aData.bOldOutTable = bOutTable; + aData.bOldIsInTable = bIsInTable; + aData.bOldFlyFrmAttrs = bOutFlyFrmAttrs; + aData.bOldStartTOX = bStartTOX; + aData.bOldInWriteTOX = bInWriteTOX; + + pCurPam = Writer::NewSwPaM( *pDoc, nStt, nEnd ); + + // Recognize tables in special cases + if ( nStt != pCurPam->GetMark()->nNode.GetIndex() && + pDoc->GetNodes()[ nStt ]->IsTableNode() ) { - pOOld = rWrt.pO; - rWrt.pO = new WW8Bytes( 128, 128 ); + pCurPam->GetMark()->nNode = nStt; } - else - pOOld = 0; - bOldWriteAll = rWrt.bWriteAll; - bOldOutTable = rWrt.bOutTable; - bOldIsInTable= rWrt.bIsInTable; - bOldFlyFrmAttrs = rWrt.bOutFlyFrmAttrs; - bOldStartTOX = rWrt.bStartTOX; - bOldInWriteTOX = rWrt.bInWriteTOX; - rWrt.pCurPam = rWrt.NewSwPaM( *rWrt.pDoc, nStt, nEnd ); + pOrigPam = pCurPam; + pCurPam->Exchange(); - // Tabelle in Sonderbereichen erkennen - if( nStt != rWrt.pCurPam->GetMark()->nNode.GetIndex() && - rWrt.pDoc->GetNodes()[ nStt ]->IsTableNode() ) - rWrt.pCurPam->GetMark()->nNode = nStt; + bOutTable = false; + // Caution: bIsInTable should not be set here + bOutFlyFrmAttrs = false; +// pAttrSet = 0; + bStartTOX = false; + bInWriteTOX = false; + + maSaveData.push( aData ); +} + +void MSWordExportBase::RestoreData() +{ + MSWordSaveData &rData = maSaveData.top(); - rWrt.SetEndPaM( rWrt.pCurPam ); - rWrt.pCurPam->Exchange( ); - rWrt.bWriteAll = true; - rWrt.bOutTable = false; - // Vorsicht: rWrt.bIsInTable darf hier NICHT veraendert werden! - rWrt.bOutFlyFrmAttrs = false; -// rWrt.pAttrSet = 0; - rWrt.bStartTOX = false; - rWrt.bInWriteTOX = false; + delete pCurPam; + pCurPam = rData.pOldPam; + pOrigPam = rData.pOldEnd; + + bOutTable = rData.bOldOutTable; + bIsInTable = rData.bOldIsInTable; + bOutFlyFrmAttrs = rData.bOldFlyFrmAttrs; + bStartTOX = rData.bOldStartTOX; + bInWriteTOX = rData.bOldInWriteTOX; + + mpParentFrame = rData.pOldFlyFmt; + pAktPageDesc = rData.pOldPageDesc; + + eNewAnchorType = rData.eOldAnchorType; + pFlyOffset = rData.pOldFlyOffset; + + maSaveData.pop(); } +void WW8Export::SaveData( ULONG nStt, ULONG nEnd ) +{ + MSWordExportBase::SaveData( nStt, nEnd ); + + MSWordSaveData &rData = maSaveData.top(); + + if ( pO->Count() ) + { + rData.pOOld = pO; + pO = new WW8Bytes( 128, 128 ); + } + else + rData.pOOld = 0; // reuse pO + + rData.mpTableAtOld = mpTableAt; + mpTableAt = NULL; + rData.mnTableStdAtLenOld = mnTableStdAtLen; + mnTableStdAtLen = 0; + + rData.bOldWriteAll = GetWriter().bWriteAll; + GetWriter().bWriteAll = true; +} -WW8SaveData::~WW8SaveData() +void WW8Export::RestoreData() { - delete rWrt.pCurPam; // Pam wieder loeschen - rWrt.pCurPam = pOldPam; - rWrt.SetEndPaM( pOldEnd ); - rWrt.bWriteAll = bOldWriteAll; - rWrt.bOutTable = bOldOutTable; - rWrt.bIsInTable= bOldIsInTable; - rWrt.bOutFlyFrmAttrs = bOldFlyFrmAttrs; - rWrt.bStartTOX = bOldStartTOX; - rWrt.bInWriteTOX = bOldInWriteTOX; - rWrt.mpParentFrame = pOldFlyFmt; - rWrt.pAktPageDesc = pOldPageDesc; - ASSERT( !rWrt.pO->Count(), " pO ist am Ende von WW8SaveData nicht leer" ); - if( pOOld ) + MSWordSaveData &rData = maSaveData.top(); + + GetWriter().bWriteAll = rData.bOldWriteAll; + + ASSERT( !pO->Count(), "pO is not empty in WW8Export::RestoreData()" ); + if ( rData.pOOld ) { - delete rWrt.pO; - rWrt.pO = pOOld; + delete pO; + pO = rData.pOOld; } - rWrt.eNewAnchorType = eOldAnchorType; - rWrt.pFlyOffset = pOldFlyOffset; + + ASSERT( !mpTableAt || !mpTableAt->Count(), "mpTableAt is not empty in WW8Export::RestoreData()" ); + if ( mpTableAt ) + delete mpTableAt; + mpTableAt = rData.mpTableAtOld; + mnTableStdAtLen = rData.mnTableStdAtLenOld; + + MSWordExportBase::RestoreData(); } -void SwWW8Writer::OutWW8TableInfoCell -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth(); - if (nDepth > 0) + if ( nDepth > 0 ) { /* Cell */ - InsUInt16(0x2416); - pO->Insert((BYTE)0x1, pO->Count()); - InsUInt16(0x6649); - InsUInt32(nDepth); + m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable ); + m_rWW8Export.pO->Insert( (BYTE)0x1, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth ); + m_rWW8Export.InsUInt32( nDepth ); - if (nDepth > 1 && pTableTextNodeInfoInner->isEndOfCell()) + if ( nDepth > 1 && pTableTextNodeInfoInner->isEndOfCell() ) { - InsUInt16(0x244b); - pO->Insert((BYTE)0x1, pO->Count()); + m_rWW8Export.InsUInt16( NS_sprm::LN_PCell ); + m_rWW8Export.pO->Insert( (BYTE)0x1, m_rWW8Export.pO->Count() ); } } } -void SwWW8Writer::OutWW8TableInfoRow -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth(); - if (nDepth > 0) + if ( nDepth > 0 ) { - /* Row */ - if (pTableTextNodeInfoInner->isEndOfLine()) + if ( pTableTextNodeInfoInner->isEndOfLine() ) { - InsUInt16(0x2416); - pO->Insert((BYTE)0x1, pO->Count()); + m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable ); + m_rWW8Export.pO->Insert( (BYTE)0x1, m_rWW8Export.pO->Count() ); - if (nDepth == 1) + if ( nDepth == 1 ) { - InsUInt16(0x2417); - pO->Insert((BYTE)0x1, pO->Count()); + m_rWW8Export.InsUInt16( NS_sprm::LN_PFTtp ); + m_rWW8Export.pO->Insert( (BYTE)0x1, m_rWW8Export.pO->Count() ); } - InsUInt16(0x6649); - InsUInt32(nDepth); + m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth ); + m_rWW8Export.InsUInt32( nDepth ); - if (nDepth > 1) + if ( nDepth > 1 ) { - InsUInt16(0x244b); - pO->Insert((BYTE)0x1, pO->Count()); - InsUInt16(0x244c); - pO->Insert((BYTE)0x1, pO->Count()); + m_rWW8Export.InsUInt16( NS_sprm::LN_PCell ); + m_rWW8Export.pO->Insert( (BYTE)0x1, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_PRow ); + m_rWW8Export.pO->Insert( (BYTE)0x1, m_rWW8Export.pO->Count() ); } - OutWW8TableDefinition(pTableTextNodeInfoInner); - OutWW8TableHeight(pTableTextNodeInfoInner); - OutWW8TableBackgrounds(pTableTextNodeInfoInner); - OutWW8TableDefaultBorders(pTableTextNodeInfoInner); - OutWW8TableCanSplit(pTableTextNodeInfoInner); - OutWW8TableBidi(pTableTextNodeInfoInner); - OutWW8TableVerticalCell(pTableTextNodeInfoInner); - OutWW8TableOrientation(pTableTextNodeInfoInner); + TableDefinition( pTableTextNodeInfoInner ); + TableHeight( pTableTextNodeInfoInner ); + TableBackgrounds( pTableTextNodeInfoInner ); + TableDefaultBorders( pTableTextNodeInfoInner ); + TableCanSplit( pTableTextNodeInfoInner ); + TableBidi( pTableTextNodeInfoInner ); + TableVerticalCell( pTableTextNodeInfoInner ); + TableOrientation( pTableTextNodeInfoInner ); } } } @@ -1886,31 +1940,29 @@ static sal_uInt16 lcl_TCFlags(const SwTableBox * pBox) return nFlags; } -void SwWW8Writer::OutWW8TableVerticalCell -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); const SwTableLine * pTabLine = pTabBox->GetUpper(); const SwTableBoxes & rTblBoxes = pTabLine->GetTabBoxes(); sal_uInt8 nBoxes = rTblBoxes.Count(); - for (sal_uInt8 n = 0; n < nBoxes; n++) + for ( sal_uInt8 n = 0; n < nBoxes; n++ ) { const SwTableBox * pTabBox1 = rTblBoxes[n]; const SwFrmFmt * pFrmFmt = pTabBox1->GetFrmFmt(); - if (FRMDIR_VERT_TOP_RIGHT == TrueFrameDirection(*pFrmFmt)) + if ( FRMDIR_VERT_TOP_RIGHT == m_rWW8Export.TrueFrameDirection( *pFrmFmt ) ) { - InsUInt16(0x7629); - pO->Insert(BYTE(n), pO->Count()); //start range - pO->Insert(BYTE(n + 1), pO->Count()); //end range - InsUInt16(5); //Equals vertical writing + m_rWW8Export.InsUInt16( NS_sprm::LN_TTextFlow ); + m_rWW8Export.pO->Insert( BYTE(n), m_rWW8Export.pO->Count() ); //start range + m_rWW8Export.pO->Insert( BYTE(n + 1), m_rWW8Export.pO->Count() ); //end range + m_rWW8Export.InsUInt16( 5 ); //Equals vertical writing } } } -void SwWW8Writer::OutWW8TableCanSplit -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); const SwTableLine * pTabLine = pTabBox->GetUpper(); @@ -1924,37 +1976,35 @@ void SwWW8Writer::OutWW8TableCanSplit const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit(); BYTE nCantSplit = (!rSplittable.GetValue()) ? 1 : 0; - if (bWrtWW8) + if ( m_rWW8Export.bWrtWW8 ) { - InsUInt16(0x3403); - pO->Insert(nCantSplit, pO->Count()); - InsUInt16(0x3466); // also write fCantSplit90 + m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit ); + m_rWW8Export.pO->Insert( nCantSplit, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit90 ); // also write fCantSplit90 } else { - pO->Insert(185, pO->Count()); + m_rWW8Export.pO->Insert( 185, m_rWW8Export.pO->Count() ); } - pO->Insert(nCantSplit, pO->Count()); + m_rWW8Export.pO->Insert( nCantSplit, m_rWW8Export.pO->Count() ); } -void SwWW8Writer::OutWW8TableBidi -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { const SwTable * pTable = pTableTextNodeInfoInner->getTable(); const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt(); - if (bWrtWW8) + if ( m_rWW8Export.bWrtWW8 ) { - if (TrueFrameDirection(*pFrmFmt) == FRMDIR_HORI_RIGHT_TOP) + if ( m_rWW8Export.TrueFrameDirection(*pFrmFmt) == FRMDIR_HORI_RIGHT_TOP ) { - InsUInt16(0x560B); - InsUInt16(1); + m_rWW8Export.InsUInt16( NS_sprm::LN_TFBiDi ); + m_rWW8Export.InsUInt16( 1 ); } } } -void SwWW8Writer::OutWW8TableHeight -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); const SwTableLine * pTabLine = pTabBox->GetUpper(); @@ -1984,27 +2034,26 @@ void SwWW8Writer::OutWW8TableHeight // Zeilenhoehe ausgeben sprmTDyaRowHeight long nHeight = 0; const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize(); - if( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() ) + if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() ) { - if (ATT_MIN_SIZE == rLSz.GetHeightSizeType()) + if ( ATT_MIN_SIZE == rLSz.GetHeightSizeType() ) nHeight = rLSz.GetHeight(); else nHeight = -rLSz.GetHeight(); } - if (nHeight) + if ( nHeight ) { - if( bWrtWW8 ) - InsUInt16( 0x9407 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_TDyaRowHeight ); else - pO->Insert( 189, pO->Count() ); - InsUInt16( (USHORT)nHeight ); + m_rWW8Export.pO->Insert( 189, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( (USHORT)nHeight ); } } -void SwWW8Writer::OutWW8TableOrientation -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { const SwTable * pTable = pTableTextNodeInfoInner->getTable(); @@ -2029,11 +2078,11 @@ void SwWW8Writer::OutWW8TableOrientation { case text::HoriOrientation::CENTER: case text::HoriOrientation::RIGHT: - if( bWrtWW8 ) - InsUInt16(0x5400 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_TJc ); else - pO->Insert(182, pO->Count()); - InsUInt16(text::HoriOrientation::RIGHT == eHOri ? 2 : 1); + m_rWW8Export.pO->Insert( 182, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( text::HoriOrientation::RIGHT == eHOri ? 2 : 1 ); break; default: break; @@ -2041,37 +2090,34 @@ void SwWW8Writer::OutWW8TableOrientation } } -void SwWW8Writer::OutWW8TableDefinition -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); const SwTableLine * pTabLine = pTabBox->GetUpper(); const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes(); - const SwNode * pTxtNd = pTableTextNodeInfoInner->getNode(); const SwTable * pTable = pTableTextNodeInfoInner->getTable(); - if( pTable->GetRowsToRepeat() > pTableTextNodeInfoInner->getRow()) + if ( pTable->GetRowsToRepeat() > pTableTextNodeInfoInner->getRow() ) { - if( bWrtWW8 ) - InsUInt16( 0x3404 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_TTableHeader ); else - pO->Insert(186, pO->Count()); - pO->Insert( 1, pO->Count() ); + m_rWW8Export.pO->Insert( 186, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() ); } // number of cell written sal_uInt32 nBoxes = rTabBoxes.Count(); - if (nBoxes > 32) + if ( nBoxes > 32 ) nBoxes = 32; // sprm header - InsUInt16(0xd608); + m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTable ); sal_uInt16 nSprmSize = 2 + (nBoxes + 1) * 2 + nBoxes * 20; - InsUInt16(nSprmSize); // length + m_rWW8Export.InsUInt16( nSprmSize ); // length // number of boxes - pO->Insert(static_cast<BYTE>(nBoxes), pO->Count()); - + m_rWW8Export.pO->Insert( static_cast<BYTE>(nBoxes), m_rWW8Export.pO->Count() ); /* cellxs */ /* @@ -2100,13 +2146,13 @@ void SwWW8Writer::OutWW8TableDefinition ) { sal_Int16 eHOri = rHori.GetHoriOrient(); - switch (eHOri) + switch ( eHOri ) { case text::HoriOrientation::CENTER: case text::HoriOrientation::RIGHT: break; - default: + default: nTblOffset = rHori.GetPos(); const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace(); nTblOffset += rLRSp.GetLeft(); @@ -2114,6 +2160,97 @@ void SwWW8Writer::OutWW8TableDefinition } } + sal_uInt32 n = 0; + m_rWW8Export.InsUInt16( nTblOffset ); + + std::vector<SwTwips> gridCols = GetGridCols( pTableTextNodeInfoInner ); + for ( std::vector<SwTwips>::const_iterator it = gridCols.begin(), end = gridCols.end(); it != end; ++it ) + { + m_rWW8Export.InsUInt16( static_cast<USHORT>( *it ) + nTblOffset ); + } + + /* TCs */ + for ( n = 0; n < nBoxes; n++ ) + { +#ifdef DEBUG + sal_uInt16 npOCount = m_rWW8Export.pO->Count(); +#endif + + SwTableBox * pTabBox1 = rTabBoxes[n]; + const SwFrmFmt & rBoxFmt = *(pTabBox1->GetFrmFmt()); + if ( m_rWW8Export.bWrtWW8 ) + { + sal_uInt16 nFlags = lcl_TCFlags(pTabBox1); + m_rWW8Export.InsUInt16( nFlags ); + } + + static BYTE aNullBytes[] = { 0x0, 0x0 }; + + m_rWW8Export.pO->Insert( aNullBytes, 2, m_rWW8Export.pO->Count() ); // dummy + m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, rBoxFmt.GetBox() ); // 8/16 Byte + +#ifdef DEBUG + ::std::clog << "<tclength>" << m_rWW8Export.pO->Count() - npOCount << "</tclength>" + << ::std::endl; +#endif + } +} + +std::vector<SwTwips> AttributeOutputBase::GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) +{ + std::vector<SwTwips> gridCols; + + const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); + const SwTableLine * pTabLine = pTabBox->GetUpper(); + const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes(); + const SwTable *pTable = pTableTextNodeInfoInner->getTable( ); + + // number of cell written + sal_uInt32 nBoxes = rTabBoxes.Count(); + if ( nBoxes > 32 ) + nBoxes = 32; + + const SwFrmFmt *pFmt = pTable->GetFrmFmt(); + ASSERT(pFmt,"Impossible"); + if (!pFmt) + return gridCols; + + const SwFmtFrmSize &rSize = pFmt->GetFrmSize(); + unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth()); + + sal_uInt32 nPageSize = 0; + bool bRelBoxSize = false; + + GetTablePageSize( pTableTextNodeInfoInner, nPageSize, bRelBoxSize ); + + SwTwips nSz = 0; + for ( sal_uInt32 n = 0; n < nBoxes; n++ ) + { + const SwFrmFmt* pBoxFmt = rTabBoxes[ n ]->GetFrmFmt(); + const SwFmtFrmSize& rLSz = pBoxFmt->GetFrmSize(); + nSz += rLSz.GetWidth(); + SwTwips nCalc = nSz; + if ( bRelBoxSize ) + nCalc = ( nCalc * nPageSize ) / nTblSz; + + gridCols.push_back( nCalc ); + } + + return gridCols; +} + +void AttributeOutputBase::GetTablePageSize( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize ) +{ + sal_uInt32 nPageSize = 0; + + const SwNode *pTxtNd = pTableTextNodeInfoInner->getNode( ); + const SwTable *pTable = pTableTextNodeInfoInner->getTable( ); + + const SwFrmFmt *pFmt = pTable->GetFrmFmt(); + ASSERT(pFmt,"Impossible"); + if (!pFmt) + return; + const SwFmtFrmSize &rSize = pFmt->GetFrmSize(); int nWidthPercent = rSize.GetWidthPercent(); bool bManualAligned = pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::NONE; @@ -2127,20 +2264,19 @@ void SwWW8Writer::OutWW8TableDefinition bRelBoxSize = true; } - unsigned long nPageSize = nTblSz; - if (bRelBoxSize) + if ( bRelBoxSize ) { Point aPt; - SwRect aRect(pFmt->FindLayoutRect(false, &aPt)); - if (aRect.IsEmpty()) + SwRect aRect( pFmt->FindLayoutRect( false, &aPt ) ); + if ( aRect.IsEmpty() ) { // dann besorge mal die Seitenbreite ohne Raender !! const SwFrmFmt* pParentFmt = - mpParentFrame ? - &(mpParentFrame->GetFrmFmt()) : - const_cast<const SwDoc *>(pDoc)->GetPageDesc(0).GetPageFmtOfNode(*pTxtNd, false); + GetExport().mpParentFrame ? + &(GetExport().mpParentFrame->GetFrmFmt()) : + const_cast<const SwDoc *>(GetExport().pDoc)->GetPageDesc(0).GetPageFmtOfNode(*pTxtNd, false); aRect = pParentFmt->FindLayoutRect(true); - if (0 == (nPageSize = aRect.Width())) + if ( 0 == ( nPageSize = aRect.Width() ) ) { const SvxLRSpaceItem& rLR = pParentFmt->GetLRSpace(); nPageSize = pParentFmt->GetFrmSize().GetWidth() - rLR.GetLeft() @@ -2150,7 +2286,7 @@ void SwWW8Writer::OutWW8TableDefinition else { nPageSize = aRect.Width(); - if(bManualAligned) + if ( bManualAligned ) { // #i37571# For manually aligned tables const SvxLRSpaceItem &rLR = pFmt->GetLRSpace(); @@ -2167,53 +2303,11 @@ void SwWW8Writer::OutWW8TableDefinition } } - SwTwips nSz = 0; - sal_uInt32 n = 0; - InsUInt16(nTblOffset); - - for (n = 0; n < nBoxes; n++) - { - const SwFrmFmt* pBoxFmt = rTabBoxes[ n ]->GetFrmFmt(); - const SwFmtFrmSize& rLSz = pBoxFmt->GetFrmSize(); - nSz += rLSz.GetWidth(); - SwTwips nCalc = nSz; - if (bRelBoxSize) - nCalc = (nCalc * nPageSize) / nTblSz; - - nCalc += nTblOffset; - - InsUInt16(static_cast<USHORT>(nCalc)); - } - - /* TCs */ - for (n = 0; n < nBoxes; n++) - { -#ifdef DEBUG - sal_uInt16 npOCount = pO->Count(); -#endif - - SwTableBox * pTabBox1 = rTabBoxes[n]; - const SwFrmFmt & rBoxFmt = *(pTabBox1->GetFrmFmt()); - if( bWrtWW8 ) - { - sal_uInt16 nFlags = lcl_TCFlags(pTabBox1); - InsUInt16( nFlags ); - } - - static BYTE aNullBytes[] = { 0x0, 0x0 }; - - pO->Insert( aNullBytes, 2, pO->Count() ); // dummy - Out_SwFmtTableBox( *pO, rBoxFmt.GetBox() ); // 8/16 Byte - -#ifdef DEBUG - ::std::clog << "<tclength>" << pO->Count() - npOCount << "</tclength>" - << ::std::endl; -#endif - } + rPageSize = nPageSize; + rRelBoxSize = bRelBoxSize; } -void SwWW8Writer::OutWW8TableDefaultBorders -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt(); @@ -2226,44 +2320,41 @@ void SwWW8Writer::OutWW8TableDefaultBorders BOX_LINE_BOTTOM, BOX_LINE_RIGHT }; - for( int i = 0; i < 4; ++i) + for ( int i = 0; i < 4; ++i ) { - SwWW8Writer::InsUInt16(*pO, 0xD634); - pO->Insert( BYTE(6), pO->Count() ); - pO->Insert( BYTE(0), pO->Count() ); - pO->Insert( BYTE(1), pO->Count() ); - pO->Insert( BYTE(1 << i), pO->Count() ); - pO->Insert( BYTE(3), pO->Count() ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, 0xD634 ); + m_rWW8Export.pO->Insert( BYTE(6), m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( BYTE(0), m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( BYTE(1), m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( BYTE(1 << i), m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( BYTE(3), m_rWW8Export.pO->Count() ); - SwWW8Writer::InsUInt16(*pO, - pFrmFmt->GetBox().GetDistance(aBorders[i])); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, + pFrmFmt->GetBox().GetDistance( aBorders[i] ) ); } - } -void SwWW8Writer::OutWW8TableBackgrounds -(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) +void WW8AttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) { const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); const SwTableLine * pTabLine = pTabBox->GetUpper(); const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes(); sal_uInt8 nBoxes = rTabBoxes.Count(); - if( bWrtWW8 ) - InsUInt16( 0xD609 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTableShd ); else - pO->Insert( (BYTE)191, pO->Count() ); - pO->Insert( (BYTE)(nBoxes * 2), pO->Count() ); // Len + m_rWW8Export.pO->Insert( (BYTE)191, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( (BYTE)(nBoxes * 2), m_rWW8Export.pO->Count() ); // Len - for (sal_uInt8 n = 0; n < nBoxes; n++) + for ( sal_uInt8 n = 0; n < nBoxes; n++ ) { const SwTableBox * pBox1 = rTabBoxes[n]; const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt(); const SfxPoolItem * pI = NULL; Color aColor; - if (SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState(RES_BACKGROUND, - false, &pI)) + if ( SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) ) { aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor(); } @@ -2271,28 +2362,27 @@ void SwWW8Writer::OutWW8TableBackgrounds aColor = COL_AUTO; WW8_SHD aShd; - TransBrush(aColor, aShd); - InsUInt16(aShd.GetValue()); + m_rWW8Export.TransBrush( aColor, aShd ); + m_rWW8Export.InsUInt16( aShd.GetValue() ); } - if (bWrtWW8) + if ( m_rWW8Export.bWrtWW8 ) { sal_uInt8 nBoxes0 = rTabBoxes.Count(); if (nBoxes0 > 21) nBoxes0 = 21; - InsUInt16(0xd612); - pO->Insert(static_cast<BYTE>(nBoxes0 * 10), pO->Count()); + m_rWW8Export.InsUInt16( NS_sprm::LN_TCellShd ); + m_rWW8Export.pO->Insert( static_cast<BYTE>(nBoxes0 * 10), m_rWW8Export.pO->Count() ); - for (sal_uInt8 n = 0; n < nBoxes0; n++) + for ( sal_uInt8 n = 0; n < nBoxes0; n++ ) { const SwTableBox * pBox1 = rTabBoxes[n]; const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt(); const SfxPoolItem * pI = NULL; Color aColor; - if (SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState(RES_BACKGROUND, - false, &pI)) + if ( SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) ) { aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor(); } @@ -2300,20 +2390,30 @@ void SwWW8Writer::OutWW8TableBackgrounds aColor = COL_AUTO; WW8SHDLong aSHD; - aSHD.setCvFore(0xFF000000); + aSHD.setCvFore( 0xFF000000 ); sal_uInt32 nBgColor = aColor.GetColor(); - if (nBgColor == COL_AUTO) - aSHD.setCvBack(0xFF000000); + if ( nBgColor == COL_AUTO ) + aSHD.setCvBack( 0xFF000000 ); else - aSHD.setCvBack(wwUtility::RGBToBGR(nBgColor)); + aSHD.setCvBack( wwUtility::RGBToBGR( nBgColor ) ); - aSHD.Write(*this); + aSHD.Write( m_rWW8Export ); } } } -void SwWW8Writer::WriteText() +void WW8Export::SectionBreaksAndFrames( const SwTxtNode& rNode ) +{ + // output page/section breaks + OutputSectionBreaks( rNode.GetpSwAttrSet(), rNode ); + + // all textframes anchored as character for the winword 7- format + if ( !bWrtWW8 && !bIsInTable ) + OutWW6FlyFrmsInCntnt( rNode ); +} + +void MSWordExportBase::WriteText() { #ifdef DEBUG ::std::clog << "<WriteText>" << ::std::endl; @@ -2321,78 +2421,69 @@ void SwWW8Writer::WriteText() #endif while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode || - (pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode && - pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) ) + ( pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode && + pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex() ) ) { SwNode * pNd = pCurPam->GetNode(); - if (pNd->IsTxtNode()) // blitzschnelle Methode - { - const SwTxtNode* pTxtNode = pNd->GetTxtNode(); - Out_SfxBreakItems(pTxtNode->GetpSwAttrSet(), *pTxtNode); - // all textframes anchored as character for the winword 7- format - if (!bWrtWW8 && !bIsInTable) - OutWW8FlyFrmsInCntnt(*pTxtNode); - } + if ( pNd->IsTxtNode() ) + SectionBreaksAndFrames( *pNd->GetTxtNode() ); - if( pNd->IsCntntNode() ) + // output the various types of nodes + if ( pNd->IsCntntNode() ) { SwCntntNode* pCNd = (SwCntntNode*)pNd; - const SwPageDesc* pTemp = - pCNd->GetSwAttrSet().GetPageDesc().GetPageDesc(); - if (pTemp) + const SwPageDesc* pTemp = pCNd->GetSwAttrSet().GetPageDesc().GetPageDesc(); + if ( pTemp ) pAktPageDesc = pTemp; pCurPam->GetPoint()->nContent.Assign( pCNd, 0 ); - Out( aWW8NodeFnTab, *pCNd, *this ); + OutputContentNode( *pCNd ); } - else if( pNd->IsTableNode() ) + else if ( pNd->IsTableNode() ) { - mpTableInfo->processSwTable(&(dynamic_cast<SwTableNode *>(pNd)->GetTable())); + mpTableInfo->processSwTable( &pNd->GetTableNode()->GetTable() ); } - else if( pNd->IsSectionNode() && TXT_MAINTEXT == nTxtTyp ) - OutWW8_SwSectionNode( *this, *pNd->GetSectionNode() ); - else if( TXT_MAINTEXT == nTxtTyp && pNd->IsEndNode() && - pNd->StartOfSectionNode()->IsSectionNode() ) + else if ( pNd->IsSectionNode() && TXT_MAINTEXT == nTxtTyp ) + OutputSectionNode( *pNd->GetSectionNode() ); + else if ( TXT_MAINTEXT == nTxtTyp && pNd->IsEndNode() && + pNd->StartOfSectionNode()->IsSectionNode() ) { const SwSection& rSect = pNd->StartOfSectionNode()->GetSectionNode() ->GetSection(); - if( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() ) + if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() ) bStartTOX = false; SwNodeIndex aIdx( *pNd, 1 ); - if( aIdx.GetNode().IsEndNode() - && aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) + if ( aIdx.GetNode().IsEndNode() && aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) ; - else - if( aIdx.GetNode().IsSectionNode() ) + else if ( aIdx.GetNode().IsSectionNode() ) ; - else if (!bIsInTable) //No sections in table + else if ( !bIsInTable ) //No sections in table { ReplaceCr( (char)0xc ); // Indikator fuer Page/Section-Break const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent(); - if( !pParentFmt ) + if ( !pParentFmt ) pParentFmt = (SwSectionFmt*)0xFFFFFFFF; ULONG nRstLnNum; - if( aIdx.GetNode().IsCntntNode() ) + if ( aIdx.GetNode().IsCntntNode() ) nRstLnNum = ((SwCntntNode&)aIdx.GetNode()).GetSwAttrSet(). GetLineNumber().GetStartValue(); else nRstLnNum = 0; - pSepx->AppendSep( Fc2Cp( Strm().Tell() ), - pAktPageDesc, pParentFmt, nRstLnNum ); + AppendSection( pAktPageDesc, pParentFmt, nRstLnNum ); } } - else if (pNd->IsEndNode()) + else if ( pNd->IsEndNode() ) { - OutWW8_SwEndNode(pNd); + OutputEndNode( *pNd->GetEndNode() ); } - if( pNd == &pNd->GetNodes().GetEndOfContent() ) + if ( pNd == &pNd->GetNodes().GetEndOfContent() ) break; SwNode * pCurrentNode = &pCurPam->GetPoint()->nNode.GetNode(); @@ -2404,7 +2495,7 @@ void SwWW8Writer::WriteText() pCurPam->GetPoint()->nNode++; ULONG nPos = pCurPam->GetPoint()->nNode.GetIndex(); - ::SetProgressState( nPos, pCurPam->GetDoc()->GetDocShell() ); // Wie weit ? + ::SetProgressState( nPos, pCurPam->GetDoc()->GetDocShell() ); } #ifdef DEBUG @@ -2412,7 +2503,7 @@ void SwWW8Writer::WriteText() #endif } -void SwWW8Writer::WriteMainText() +void WW8Export::WriteMainText() { #ifdef DEBUG ::std::clog << "<WriteMainText>" << ::std::endl; @@ -2444,7 +2535,7 @@ void SwWW8Writer::WriteMainText() #endif } -void SwWW8Writer::WriteFkpPlcUsw() +void WW8Export::WriteFkpPlcUsw() { if( !bWrtWW8 ) { @@ -2460,7 +2551,7 @@ void SwWW8Writer::WriteFkpPlcUsw() pChpPlc->WriteFkps(); // Fkp.Chpx pPapPlc->WriteFkps(); // Fkp.Papx - pStyles->OutStyleTab(); // Styles + pStyles->OutputStylesTable(); // Styles pFtn->WritePlc( *this ); // Footnote-Ref & Text Plc pEdn->WritePlc( *this ); // Endnote-Ref & Text Plc pAtn->WritePlc( *this ); // Annotation-Ref & Text Plc @@ -2470,7 +2561,7 @@ void SwWW8Writer::WriteFkpPlcUsw() pPapPlc->WritePlc(); // Plcx.Papx maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs if( pRedlAuthors ) - pRedlAuthors->Write( *this ); // sttbfRMark (RedlineAuthors) + pRedlAuthors->Write( GetWriter() ); // sttbfRMark (RedlineAuthors) pFldMain->Write( *this ); // Fields ( Main Text ) pFldHdFt->Write( *this ); // Fields ( Header/Footer ) pFldFtn->Write( *this ); // Fields ( FootNotes ) @@ -2492,7 +2583,7 @@ void SwWW8Writer::WriteFkpPlcUsw() pSepx->WriteSepx( Strm() ); // Sepx // Ausagbe in Table-Stream - pStyles->OutStyleTab(); // fuer WW8 StyleTab + pStyles->OutputStylesTable(); // fuer WW8 StyleTab pFtn->WritePlc( *this ); // Footnote-Ref & Text Plc pEdn->WritePlc( *this ); // Endnote-Ref & Text Plc pTxtBxs->WritePlc( *this ); // Textbox Text Plc @@ -2506,7 +2597,7 @@ void SwWW8Writer::WriteFkpPlcUsw() pPapPlc->WritePlc(); // Plcx.Papx if( pRedlAuthors ) - pRedlAuthors->Write( *this ); // sttbfRMark (RedlineAuthors) + pRedlAuthors->Write( GetWriter() ); // sttbfRMark (RedlineAuthors) pFldMain->Write( *this ); // Fields ( Main Text ) pFldHdFt->Write( *this ); // Fields ( Header/Footer ) pFldFtn->Write( *this ); // Fields ( FootNotes ) @@ -2537,7 +2628,7 @@ void SwWW8Writer::WriteFkpPlcUsw() #10570# Similiarly having msvbasic storage seems to also trigger creating this stream */ - GetStorage().OpenSotStorage(CREATE_CONST_ASC(SL::aObjectPool), + GetWriter().GetStorage().OpenSotStorage(CREATE_CONST_ASC(SL::aObjectPool), STREAM_READWRITE | STREAM_SHARE_DENYALL); } @@ -2552,9 +2643,7 @@ void SwWW8Writer::WriteFkpPlcUsw() pBkmks->Write( *this ); // Bookmarks - sttbfBkmk/ // plcfBkmkf/plcfBkmkl - OutListTab(); // listformats - LSTF - OutOverrideListTab(); // - "" - - LFO - OutListNamesTab(); // - "" - - ListNames + WriteNumbering(); RestoreMacroCmds(); @@ -2573,7 +2662,7 @@ void SwWW8Writer::WriteFkpPlcUsw() pFib->Write( Strm() ); // FIB } -void SwWW8Writer::StoreDoc1() +void WW8Export::StoreDoc1() { bool bNeedsFinalPara = false; // Start of Text ( Mangel ueber ) @@ -2610,7 +2699,7 @@ void SwWW8Writer::StoreDoc1() WriteFkpPlcUsw(); // FKP, PLC, ..... } -void SwWW8Writer::AddLinkTarget(const String& rURL) +void MSWordExportBase::AddLinkTarget(const String& rURL) { if( !rURL.Len() || rURL.GetChar(0) != INET_MARK_TOKEN ) return; @@ -2646,12 +2735,7 @@ void SwWW8Writer::AddLinkTarget(const String& rURL) } } -void SwWW8Writer::AddBookmark(String sBkmkName) -{ - pBkmks->Append(Fc2Cp(Strm().Tell()), BookmarkToWord(sBkmkName)); -} - -void SwWW8Writer::CollectOutlineBookmarks(const SwDoc &rDoc) +void MSWordExportBase::CollectOutlineBookmarks(const SwDoc &rDoc) { const SwFmtINetFmt* pINetFmt; const SwTxtINetFmt* pTxtAttr; @@ -2696,7 +2780,7 @@ void SwWW8Writer::CollectOutlineBookmarks(const SwDoc &rDoc) namespace { -#define WW_BLOCKSIZE 0x200 + const ULONG WW_BLOCKSIZE = 0x200; void EncryptRC4(svx::MSCodec_Std97& rCtx, SvStream &rIn, SvStream &rOut) { @@ -2716,7 +2800,7 @@ namespace } } -ULONG SwWW8Writer::StoreDoc() +void MSWordExportBase::ExportDocument( bool bWriteAll ) { nCharFmtStart = ANZ_DEFAULT_STYLES; nFmtCollStart = nCharFmtStart + pDoc->GetCharFmts()->Count() - 1; @@ -2741,64 +2825,91 @@ ULONG SwWW8Writer::StoreDoc() pOutFmtNode = 0; pEscher = 0; pRedlAuthors = 0; - if( aTOXArr.Count() ) + if ( aTOXArr.Count() ) aTOXArr.Remove( 0, aTOXArr.Count() ); - if( !pOLEExp ) + if ( !pOLEExp ) { UINT32 nSvxMSDffOLEConvFlags = 0; const SvtFilterOptions* pOpt = SvtFilterOptions::Get(); - if( pOpt->IsMath2MathType() ) + if ( pOpt->IsMath2MathType() ) nSvxMSDffOLEConvFlags |= OLE_STARMATH_2_MATHTYPE; - if( pOpt->IsWriter2WinWord() ) + if ( pOpt->IsWriter2WinWord() ) nSvxMSDffOLEConvFlags |= OLE_STARWRITER_2_WINWORD; - if( pOpt->IsCalc2Excel() ) + if ( pOpt->IsCalc2Excel() ) nSvxMSDffOLEConvFlags |= OLE_STARCALC_2_EXCEL; - if( pOpt->IsImpress2PowerPoint() ) + if ( pOpt->IsImpress2PowerPoint() ) nSvxMSDffOLEConvFlags |= OLE_STARIMPRESS_2_POWERPOINT; pOLEExp = new SvxMSExportOLEObjects( nSvxMSDffOLEConvFlags ); } - if( !pOleMap) + if ( !pOleMap) pOleMap = new WW8OleMaps; - if( !pOCXExp ) - pOCXExp = new SwMSConvertControls(pDoc->GetDocShell(),pCurPam); - - PrepareStorage(); + if ( !pOCXExp ) + pOCXExp = new SwMSConvertControls( pDoc->GetDocShell(), pCurPam ); // --> OD 2007-10-08 #i81405# // Collect anchored objects before changing the redline mode. - if (bWrtWW8) - maFrames = GetAllFrames(*pDoc, bWriteAll ? 0 : pOrigPam); - else - maFrames = GetNonDrawingFrames(*pDoc, bWriteAll ? 0 : pOrigPam); + maFrames = GetFrames( *pDoc, bWriteAll? NULL : pOrigPam ); // <-- - USHORT nRedlineMode = pDoc->GetRedlineMode(); - if (pDoc->GetRedlineTbl().Count()) + mnRedlineMode = pDoc->GetRedlineMode(); + if ( pDoc->GetRedlineTbl().Count() ) { - pDoc->SetRedlineMode((RedlineMode_t)(nRedlineMode | nsRedlineMode_t::REDLINE_SHOW_DELETE | - nsRedlineMode_t::REDLINE_SHOW_INSERT)); + pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode | nsRedlineMode_t::REDLINE_SHOW_DELETE | + nsRedlineMode_t::REDLINE_SHOW_INSERT) ); } - maFontHelper.InitFontTable(bWrtWW8, *pDoc); + maFontHelper.InitFontTable( HackIsWW8OrHigher(), *pDoc ); GatherChapterFields(); + CollectOutlineBookmarks(*pDoc); + + // make unique OrdNums (Z-Order) for all drawing-/fly Objects + if ( pDoc->GetDrawModel() ) + pDoc->GetDrawModel()->GetPage( 0 )->RecalcObjOrdNums(); + + ExportDocument_Impl(); + + if ( mnRedlineMode != pDoc->GetRedlineMode() ) + pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode) ); +} + +String SwWW8Writer::GetPassword() +{ + String sUniPassword; + if ( mpMedium ) + { + SfxItemSet* pSet = mpMedium->GetItemSet(); + + const SfxPoolItem* pPasswordItem = NULL; + if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_PASSWORD, sal_True, &pPasswordItem ) ) + if( pPasswordItem != NULL ) + sUniPassword = ( (const SfxStringItem*)pPasswordItem )->GetValue(); + } + + return sUniPassword; +} + +void WW8Export::ExportDocument_Impl() +{ + PrepareStorage(); + pFib = new WW8Fib( bWrtWW8 ? 8 : 6 ); - SvStream* pOldStrm = pStrm; // JP 19.05.99: wozu das ??? - SvStorageStreamRef xWwStrm( pStg->OpenSotStream( aMainStg ) ); + SvStream* pOldStrm = &(Strm()); // JP 19.05.99: wozu das ??? + SvStorageStreamRef xWwStrm( GetWriter().GetStorage().OpenSotStream( aMainStg ) ); SvStorageStreamRef xTableStrm( xWwStrm ), xDataStrm( xWwStrm ); xWwStrm->SetBufferSize( 32768 ); if( bWrtWW8 ) { pFib->fWhichTblStm = 1; - xTableStrm = pStg->OpenSotStream(CREATE_CONST_ASC(SL::a1Table), + xTableStrm = GetWriter().GetStorage().OpenSotStream(CREATE_CONST_ASC(SL::a1Table), STREAM_STD_WRITE ); - xDataStrm = pStg->OpenSotStream(CREATE_CONST_ASC(SL::aData), + xDataStrm = GetWriter().GetStorage().OpenSotStream(CREATE_CONST_ASC(SL::aData), STREAM_STD_WRITE ); xDataStrm->SetBufferSize( 32768 ); // fuer Grafiken @@ -2808,22 +2919,13 @@ ULONG SwWW8Writer::StoreDoc() xDataStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); } - pStrm = &xWwStrm; + GetWriter().SetStrm( *xWwStrm ); pTableStrm = &xTableStrm; pDataStrm = &xDataStrm; - pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - - String sUniPassword; - if ( mpMedium ) - { - SfxItemSet* pSet = mpMedium->GetItemSet(); + Strm().SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - const SfxPoolItem* pPasswordItem = NULL; - if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_PASSWORD, sal_True, &pPasswordItem ) ) - if( pPasswordItem != NULL ) - sUniPassword = ( (const SfxStringItem*)pPasswordItem )->GetValue(); - } + String sUniPassword( GetWriter().GetPassword() ); utl::TempFile aTempMain; aTempMain.EnableKillingFile(); @@ -2839,7 +2941,7 @@ ULONG SwWW8Writer::StoreDoc() { bEncrypt =true; - pStrm = aTempMain.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); + GetWriter().SetStrm( *aTempMain.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ) ); pTableStrm = aTempTable.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); @@ -2849,53 +2951,11 @@ ULONG SwWW8Writer::StoreDoc() pTableStrm->Write( aRC4EncryptionHeader, 52 ); } - const SwSectionFmt *pFmt=0; // Default: "Standard" - pAktPageDesc = &const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 ); - pSepx = new WW8_WrPlcSepx; // Sepx - { - const SfxPoolItem* pI; - const SwNode* pNd = pCurPam->GetCntntNode(); - const SfxItemSet* pSet = pNd ? &((SwCntntNode*)pNd)->GetSwAttrSet() - : 0; - - ULONG nRstLnNum = pSet ? ((SwFmtLineNumber&)pSet->Get( - RES_LINENUMBER )).GetStartValue() - : 0; - - const SwTableNode* pTblNd = pCurPam->GetNode()->FindTableNode(); - const SwSectionNode* pSectNd; - if( pTblNd ) - { - pSet = &pTblNd->GetTable().GetFrmFmt()->GetAttrSet(); - pNd = pTblNd; - } - else if( 0 != ( pSectNd = pNd->FindSectionNode() ) ) - { - if( TOX_HEADER_SECTION == pSectNd->GetSection().GetType() && - pSectNd->StartOfSectionNode()->IsSectionNode() ) - pSectNd = pSectNd->StartOfSectionNode()->GetSectionNode(); - - if( TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() ) - { - pNd = pSectNd; - pCurPam->GetPoint()->nNode = *pNd; - } - - if (CONTENT_SECTION == pSectNd->GetSection().GetType()) - pFmt = pSectNd->GetSection().GetFmt(); - } - - // Hole evtl. Pagedesc des 1. Nodes - if( pSet && SFX_ITEM_ON == pSet->GetItemState(RES_PAGEDESC, true, &pI) - && ((SwFmtPageDesc*)pI)->GetPageDesc() ) - pSepx->AppendSep( 0, *(SwFmtPageDesc*)pI, *pNd, pFmt, nRstLnNum ); - else - pSepx->AppendSep( 0, pAktPageDesc, pFmt, nRstLnNum ); - } + pSepx = new WW8_WrPlcSepx( *this ); // Sections/headers/footers - pFtn = new WW8_WrPlcFtnEdn( TXT_FTN ); // Ftn - pEdn = new WW8_WrPlcFtnEdn( TXT_EDN ); // Edn + pFtn = new WW8_WrPlcFtnEdn( TXT_FTN ); // Footnotes + pEdn = new WW8_WrPlcFtnEdn( TXT_EDN ); // Endnotes pAtn = new WW8_WrPlcPostIt; // PostIts pTxtBxs = new WW8_WrPlcTxtBoxes( TXT_TXTBOX ); pHFTxtBxs = new WW8_WrPlcTxtBoxes( TXT_HFTXTBOX ); @@ -2904,12 +2964,12 @@ ULONG SwWW8Writer::StoreDoc() pHFSdrObjs = new HdFtPlcDrawObj; // Draw-/Fly-Objects for header/footer pBkmks = new WW8_WrtBookmarks; // Bookmarks - CreateBookmarkTbl(); + GetWriter().CreateBookmarkTbl(); pPapPlc = new WW8_WrPlcPn( *this, PAP, pFib->fcMin ); pChpPlc = new WW8_WrPlcPn( *this, CHP, pFib->fcMin ); pO = new WW8Bytes( 128, 128 ); - pStyles = new WW8WrtStyle( *this ); + pStyles = new MSWordStyles( *this ); pFldMain = new WW8_WrPlcFld( 2, TXT_MAINTEXT ); pFldHdFt = new WW8_WrPlcFld( 2, TXT_HDFT ); pFldFtn = new WW8_WrPlcFld( 2, TXT_FTN ); @@ -2925,12 +2985,10 @@ ULONG SwWW8Writer::StoreDoc() pDop = new WW8Dop; - pDop->fRevMarking = 0 != (nsRedlineMode_t::REDLINE_ON & nRedlineMode); - pDop->fRMView = 0 != ( nsRedlineMode_t::REDLINE_SHOW_DELETE & nRedlineMode ); + pDop->fRevMarking = 0 != ( nsRedlineMode_t::REDLINE_ON & mnRedlineMode ); + pDop->fRMView = 0 != ( nsRedlineMode_t::REDLINE_SHOW_DELETE & mnRedlineMode ); pDop->fRMPrint = pDop->fRMView; - CollectOutlineBookmarks(*pDoc); - // set AutoHyphenation flag if found in default para style const SfxPoolItem* pItem; SwTxtFmtColl* pStdTxtFmtColl = @@ -2941,10 +2999,6 @@ ULONG SwWW8Writer::StoreDoc() pDop->fAutoHyphen = ((const SvxHyphenZoneItem*)pItem)->IsHyphen(); } - // make unique OrdNums (Z-Order) for all drawing-/fly Objects - if (pDoc->GetDrawModel()) - pDoc->GetDrawModel()->GetPage( 0 )->RecalcObjOrdNums(); - StoreDoc1(); if ( bEncrypt ) @@ -2991,7 +3045,7 @@ ULONG SwWW8Writer::StoreDoc() pTableStrmTemp->Write( pSaltData, 16 ); pTableStrmTemp->Write( pSaltDigest, 16 ); - EncryptRC4(aCtx, *pStrm, *pStrmTemp); + EncryptRC4(aCtx, GetWriter().Strm(), *pStrmTemp); // Write Unencrypted Fib 68 bytes to the start of the workdocument stream pFib->fEncrypted = 1; // fEncrypted indicates the document is encrypted. @@ -3003,9 +3057,6 @@ ULONG SwWW8Writer::StoreDoc() pFib->WriteHeader( *pStrmTemp ); } - if (nRedlineMode != pDoc->GetRedlineMode()) - pDoc->SetRedlineMode((RedlineMode_t)(nRedlineMode)); - if (pUsedNumTbl) // all used NumRules { // clear the part of the list array that was copied from the document @@ -3042,7 +3093,7 @@ ULONG SwWW8Writer::StoreDoc() delete pPiece; delete pDop; delete pFib; - pStrm = pOldStrm; + GetWriter().SetStrm( *pOldStrm ); xWwStrm->SetBufferSize( 0 ); @@ -3054,15 +3105,13 @@ ULONG SwWW8Writer::StoreDoc() { xDataStrm.Clear(); pDataStrm = 0; - pStg->Remove(CREATE_CONST_ASC(SL::aData)); + GetWriter().GetStorage().Remove(CREATE_CONST_ASC(SL::aData)); } } - - return 0; } -void SwWW8Writer::PrepareStorage() +void WW8Export::PrepareStorage() { ULONG nLen; const BYTE* pData; @@ -3123,8 +3172,8 @@ void SwWW8Writer::PrepareStorage() SvGlobalName aGName( nId1, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 ); - pStg->SetClass( aGName, 0, String::CreateFromAscii( pName )); - SvStorageStreamRef xStor( pStg->OpenSotStream(sCompObj) ); + GetWriter().GetStorage().SetClass( aGName, 0, String::CreateFromAscii( pName )); + SvStorageStreamRef xStor( GetWriter().GetStorage().OpenSotStream(sCompObj) ); xStor->Write( pData, nLen ); SwDocShell* pDocShell = pDoc->GetDocShell (); @@ -3145,10 +3194,10 @@ void SwWW8Writer::PrepareStorage() pDocShell->GetPreviewMetaFile (sal_False); uno::Sequence<sal_uInt8> metaFile( sfx2::convertMetaFile(pMetaFile.get())); - sfx2::SaveOlePropertySet(xDocProps, pStg, &metaFile); + sfx2::SaveOlePropertySet(xDocProps, &GetWriter().GetStorage(), &metaFile); } else - sfx2::SaveOlePropertySet( xDocProps, pStg ); + sfx2::SaveOlePropertySet( xDocProps, &GetWriter().GetStorage() ); } } } @@ -3172,11 +3221,16 @@ ULONG SwWW8Writer::WriteStorage() pCurPam->GetPoint()->nNode = *pTNd; } - ULONG nRet = StoreDoc(); + // Do the actual export + { + WW8Export aExport( this, pDoc, pCurPam, pOrigPam, m_bWrtWW8 ); + m_pExport = &aExport; + aExport.ExportDocument( bWriteAll ); + m_pExport = NULL; + } ::EndProgress( pDoc->GetDocShell() ); - bWrtWW8 = false; // sicherheitshalber: Default fuer's naechste Mal - return nRet; + return 0; } ULONG SwWW8Writer::WriteMedium( SfxMedium& ) @@ -3185,7 +3239,7 @@ ULONG SwWW8Writer::WriteMedium( SfxMedium& ) } ULONG SwWW8Writer::Write( SwPaM& rPaM, SfxMedium& rMed, - const String* pFileName ) + const String* pFileName ) { mpMedium = &rMed; ULONG nRet = StgWriter::Write( rPaM, rMed, pFileName ); @@ -3193,43 +3247,69 @@ ULONG SwWW8Writer::Write( SwPaM& rPaM, SfxMedium& rMed, return nRet; } -ULONG SwWW8Writer::Write( SwPaM& rPaM, const uno::Reference < embed::XStorage >& xStorage, const String* pFileName, SfxMedium* pMedium ) +MSWordExportBase::MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam ) + : aMainStg(sMainStream), pISet(0), pUsedNumTbl(0), mpTopNodeOfHdFtPage(0), + pBmpPal(0), pKeyMap(0), pOLEExp(0), pOCXExp(0), pOleMap(0), + mpTableInfo(new ww8::WW8TableInfo()), nUniqueList(0), + mnHdFtIndex(0), pAktPageDesc(0), pPapPlc(0), pChpPlc(0), pChpIter(0), + pStyles( NULL ), + bHasHdr(false), bHasFtr(false), + pDoc( pDocument ), + pCurPam( pCurrentPam ), + pOrigPam( pOriginalPam ) +{ +} + +MSWordExportBase::~MSWordExportBase() +{ + delete pBmpPal; + if (pKeyMap) + delete[] (NfKeywordTable*)pKeyMap; + delete pOLEExp; + delete pOCXExp; + delete pOleMap; +} + +WW8Export::WW8Export( SwWW8Writer *pWriter, + SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam, + bool bIsWW8 ) + : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ), + pO( NULL ), + mpTableAt( NULL ), + mnTableStdAtLen( 0 ), + pSepx( NULL ), + bWrtWW8( bIsWW8 ), + m_pWriter( pWriter ), + m_pAttrOutput( new WW8AttributeOutput( *this ) ) { - // this method was added to let the windows compiler be happy, otherwise it shows warning - return StgWriter::Write( rPaM, xStorage, pFileName, pMedium ); } -ULONG SwWW8Writer::Write( SwPaM& rPaM, SotStorage& rStorage, const String* pFileName ) +WW8Export::~WW8Export() { - // this method was added to let the windows compiler be happy, otherwise it shows warning - return StgWriter::Write( rPaM, rStorage, pFileName ); + delete m_pAttrOutput, m_pAttrOutput = NULL; } -ULONG SwWW8Writer::Write( SwPaM& rPaM, SvStream& rStream, const String* pFileName ) +AttributeOutputBase& WW8Export::AttrOutput() const { - // this method was added to let the solaris compiler be happy, otherwise it shows warning - return StgWriter::Write( rPaM, rStream, pFileName ); + return *m_pAttrOutput; +} + +MSWordSections& WW8Export::Sections() const +{ + return *pSepx; } SwWW8Writer::SwWW8Writer(const String& rFltName, const String& rBaseURL) - : aMainStg(sMainStream), pISet(0), pUsedNumTbl(0), mpTopNodeOfHdFtPage(0), - pBmpPal(0), pKeyMap(0), pOLEExp(0), pOCXExp(0), pOleMap(0), - mpTableInfo(new ww8::WW8TableInfo()), nUniqueList(0), - mnHdFtIndex(0), mpMedium(0), pAktPageDesc(0), pPapPlc(0), pChpPlc(0), pChpIter(0), pO(0), - bHasHdr(false), bHasFtr(false) + : StgWriter(), + m_bWrtWW8( rFltName.EqualsAscii( FILTER_WW8 ) ), + m_pExport( NULL ), + mpMedium( 0 ) { SetBaseURL( rBaseURL ); - bWrtWW8 = rFltName.EqualsAscii(FILTER_WW8); } SwWW8Writer::~SwWW8Writer() { - delete pBmpPal; - if (pKeyMap) - delete[] (NfKeywordTable*)pKeyMap; - delete pOLEExp; - delete pOCXExp; - delete pOleMap; } extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportDOC( const String& rFltName, const String& rBaseURL, WriterRef& xRet ) @@ -3237,7 +3317,7 @@ extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportDOC( const String& rFltName, xRet = new SwWW8Writer( rFltName, rBaseURL ); } -bool WW8_WrPlcFtnEdn::WriteTxt( SwWW8Writer& rWrt ) +bool WW8_WrPlcFtnEdn::WriteTxt( WW8Export& rWrt ) { bool bRet = false; if (TXT_FTN == nTyp) @@ -3256,7 +3336,7 @@ bool WW8_WrPlcFtnEdn::WriteTxt( SwWW8Writer& rWrt ) return bRet; } -void WW8_WrPlcFtnEdn::WritePlc( SwWW8Writer& rWrt ) const +void WW8_WrPlcFtnEdn::WritePlc( WW8Export& rWrt ) const { if( TXT_FTN == nTyp ) { @@ -3273,7 +3353,7 @@ void WW8_WrPlcFtnEdn::WritePlc( SwWW8Writer& rWrt ) const } -bool WW8_WrPlcPostIt::WriteTxt(SwWW8Writer& rWrt) +bool WW8_WrPlcPostIt::WriteTxt( WW8Export& rWrt ) { bool bRet = WriteGenericTxt( rWrt, TXT_ATN, rWrt.pFib->ccpAtn ); rWrt.pFldAtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ), @@ -3282,14 +3362,14 @@ bool WW8_WrPlcPostIt::WriteTxt(SwWW8Writer& rWrt) return bRet; } -void WW8_WrPlcPostIt::WritePlc( SwWW8Writer& rWrt ) const +void WW8_WrPlcPostIt::WritePlc( WW8Export& rWrt ) const { WriteGenericPlc( rWrt, TXT_ATN, rWrt.pFib->fcPlcfandTxt, rWrt.pFib->lcbPlcfandTxt, rWrt.pFib->fcPlcfandRef, rWrt.pFib->lcbPlcfandRef ); } -void WW8_WrPlcTxtBoxes::WritePlc( SwWW8Writer& rWrt ) const +void WW8_WrPlcTxtBoxes::WritePlc( WW8Export& rWrt ) const { if( TXT_TXTBOX == nTyp ) { @@ -3305,7 +3385,7 @@ void WW8_WrPlcTxtBoxes::WritePlc( SwWW8Writer& rWrt ) const } } -void SwWW8Writer::RestoreMacroCmds() +void WW8Export::RestoreMacroCmds() { pFib->fcCmds = pTableStrm->Tell(); @@ -3339,23 +3419,25 @@ void SwWW8Writer::RestoreMacroCmds() pFib->lcbCmds = pTableStrm->Tell() - pFib->fcCmds; } -void WW8SHDLong::Write(SwWW8Writer & rWriter) +void WW8SHDLong::Write( WW8Export& rExport ) { - rWriter.InsUInt32(m_cvFore); - rWriter.InsUInt32(m_cvBack); - rWriter.InsUInt16(m_ipat); + rExport.InsUInt32( m_cvFore ); + rExport.InsUInt32( m_cvBack ); + rExport.InsUInt16( m_ipat ); } -void SwWW8Writer::WriteFormData(const ::sw::mark::IFieldmark& rFieldmark) +void WW8Export::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) { - ASSERT(bWrtWW8, "No 95 export yet"); - if (!bWrtWW8) return; + ASSERT( bWrtWW8, "No 95 export yet" ); + if ( !bWrtWW8 ) + return; const ::sw::mark::IFieldmark* pFieldmark = &rFieldmark; - const ::sw::mark::ICheckboxFieldmark* pAsCheckbox = dynamic_cast< const ::sw::mark::ICheckboxFieldmark* >(pFieldmark); + const ::sw::mark::ICheckboxFieldmark* pAsCheckbox = dynamic_cast< const ::sw::mark::ICheckboxFieldmark* >( pFieldmark ); - int type=0; // TextFieldmark - if(pAsCheckbox) type=1; + int type = 0; // TextFieldmark + if ( pAsCheckbox ) + type = 1; const ::rtl::OUString ffname = rFieldmark.GetFieldname(); @@ -3374,7 +3456,7 @@ void SwWW8Writer::WriteFormData(const ::sw::mark::IFieldmark& rFieldmark) BYTE* pDataAdr = aArr1 + 2; Set_UInt32(pDataAdr, nDataStt); - pChpPlc->AppendFkpEntry(Strm().Tell(), sizeof(aArr1), aArr1); + pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aArr1 ), aArr1 ); sal_uInt8 aFldHeader[] = { @@ -3383,10 +3465,10 @@ void SwWW8Writer::WriteFormData(const ::sw::mark::IFieldmark& rFieldmark) }; aFldHeader[4] |= (type & 0x03); - int ffres=0; // rFieldmark.GetFFRes(); - if(pAsCheckbox && pAsCheckbox->IsChecked()) - ffres=1; - aFldHeader[4] |= ((ffres<<2) & 0x7C); + int ffres = 0; // rFieldmark.GetFFRes(); + if ( pAsCheckbox && pAsCheckbox->IsChecked() ) + ffres = 1; + aFldHeader[4] |= ( (ffres<<2) & 0x7C ); const ::rtl::OUString ffdeftext; const ::rtl::OUString ffformat; @@ -3405,42 +3487,39 @@ void SwWW8Writer::WriteFormData(const ::sw::mark::IFieldmark& rFieldmark) 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // | /16 0,0,0,0, // / /4 }; - int slen=sizeof(aFldData) - +sizeof(aFldHeader) - +2*ffname.getLength()+4 - +2*ffdeftext.getLength()+4 - +2*ffformat.getLength()+4 - +2*ffhelptext.getLength()+4 - +2*ffstattext.getLength()+4 - +2*ffentrymcr.getLength()+4 - +2*ffexitmcr.getLength()+4; + int slen = sizeof( aFldData ) + + sizeof( aFldHeader ) + + 2*ffname.getLength() + 4 + + 2*ffdeftext.getLength() + 4 + + 2*ffformat.getLength() + 4 + + 2*ffhelptext.getLength() + 4 + + 2*ffstattext.getLength() + 4 + + 2*ffentrymcr.getLength() + 4 + + 2*ffexitmcr.getLength() + 4; #ifdef OSL_BIGENDIAN - slen=SWAPLONG(slen); + slen = SWAPLONG( slen ); #endif // OSL_BIGENDIAN - *((sal_uInt32 *)aFldData)=slen; - int len=sizeof(aFldData); - OSL_ENSURE(len==0x44, - "SwWW8Writer::WriteFormData(..)" - " - wrong aFldData length"); - pDataStrm->Write(aFldData, len); - - len=sizeof(aFldHeader); - OSL_ENSURE(len==8, - "SwWW8Writer::WriteFormData(..)" - " - wrong aFldHeader length"); - pDataStrm->Write(aFldHeader, len); - - WriteString_xstz(*pDataStrm, ffname, true); // Form field name - - if (type==0) - WriteString_xstz(*pDataStrm, ffdeftext, true); + *( (sal_uInt32 *)aFldData ) = slen; + int len = sizeof( aFldData ); + OSL_ENSURE( len == 0x44, "SwWW8Writer::WriteFormData(..) - wrong aFldData length" ); + pDataStrm->Write( aFldData, len ); + + len = sizeof( aFldHeader ); + OSL_ENSURE( len == 8, "SwWW8Writer::WriteFormData(..) - wrong aFldHeader length" ); + pDataStrm->Write( aFldHeader, len ); + + SwWW8Writer::WriteString_xstz( *pDataStrm, ffname, true ); // Form field name + + if ( type == 0 ) + SwWW8Writer::WriteString_xstz( *pDataStrm, ffdeftext, true ); else - pDataStrm->WriteNumber((sal_uInt16)0); - WriteString_xstz(*pDataStrm, String(ffformat), true); - WriteString_xstz(*pDataStrm, String(ffhelptext), true); - WriteString_xstz(*pDataStrm, String(ffstattext), true); - WriteString_xstz(*pDataStrm, String(ffentrymcr), true); - WriteString_xstz(*pDataStrm, String(ffexitmcr), true); + pDataStrm->WriteNumber( (sal_uInt16)0 ); + + SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffformat ), true ); + SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffhelptext ), true ); + SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffstattext ), true ); + SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffentrymcr ), true ); + SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffexitmcr ), true ); // if (type==2) { // // 0xFF, 0xFF // // sal_uInt32 number of strings @@ -3448,30 +3527,30 @@ void SwWW8Writer::WriteFormData(const ::sw::mark::IFieldmark& rFieldmark) // } } -void SwWW8Writer::OutWW8_TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner) +void WW8AttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner ) { SVBT16 nStyle; - ShortToSVBT16(nStyleBeforeFly, nStyle); + ShortToSVBT16( m_rWW8Export.nStyleBeforeFly, nStyle ); #ifdef DEBUG ::std::clog << "<OutWW8_TableNodeInfoInner>" << pNodeInfoInner->toString(); #endif - pO->Remove( 0, pO->Count() ); // leeren + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren if (pNodeInfoInner->isEndOfCell()) { #ifdef DEBUG ::std::clog << "<endOfCell/>" << ::std::endl; #endif - WriteCR(pNodeInfoInner); + m_rWW8Export.WriteCR(pNodeInfoInner); - pO->Insert( (BYTE*)&nStyle, 2, pO->Count() ); // Style # - OutWW8TableInfoCell(pNodeInfoInner); - pPapPlc->AppendFkpEntry( Strm().Tell(), pO->Count(), - pO->GetData() ); + m_rWW8Export.pO->Insert( (BYTE*)&nStyle, 2, m_rWW8Export.pO->Count() ); // Style # + TableInfoCell(pNodeInfoInner); + m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), + m_rWW8Export.pO->GetData() ); - pO->Remove( 0, pO->Count() ); // leeren + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren } if (pNodeInfoInner->isEndOfLine()) @@ -3479,28 +3558,27 @@ void SwWW8Writer::OutWW8_TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_ #ifdef DEBUG ::std::clog << "<endOfLine/>" << ::std::endl; #endif - WriteRowEnd(pNodeInfoInner->getDepth()); + TableRowEnd(pNodeInfoInner->getDepth()); - pO->Insert( (BYTE*)&nStyle, 2, pO->Count() ); // Style # - OutWW8TableInfoRow(pNodeInfoInner); - pPapPlc->AppendFkpEntry( Strm().Tell(), pO->Count(), - pO->GetData() ); + m_rWW8Export.pO->Insert( (BYTE*)&nStyle, 2, m_rWW8Export.pO->Count() ); // Style # + TableInfoRow(pNodeInfoInner); + m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), + m_rWW8Export.pO->GetData() ); - pO->Remove( 0, pO->Count() ); // leeren + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren } #ifdef DEBUG ::std::clog << "</OutWW8_TableNodeInfoInner>" << ::std::endl; #endif } -void SwWW8Writer::OutWW8_SwEndNode(SwNode * pNode) +void MSWordExportBase::OutputEndNode( const SwEndNode &rNode ) { #ifdef DEBUG - ::std::clog << "<OutWW8_SwEndNode>" << dbg_out(pNode) << ::std::endl; + ::std::clog << "<OutWW8_SwEndNode>" << dbg_out(&rNode) << ::std::endl; #endif - ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = - mpTableInfo->getTableNodeInfo(pNode); + ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = mpTableInfo->getTableNodeInfo( &rNode ); if (pNodeInfo) { @@ -3516,7 +3594,7 @@ void SwWW8Writer::OutWW8_SwEndNode(SwNode * pNode) while (aIt != aEnd) { ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second; - OutWW8_TableNodeInfoInner(pInner); + AttrOutput().TableNodeInfoInner(pInner); aIt++; } } @@ -3524,9 +3602,6 @@ void SwWW8Writer::OutWW8_SwEndNode(SwNode * pNode) #ifdef DEBUG ::std::clog << "</OutWW8_SwEndNode>" << ::std::endl; #endif - } - - /* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 82af29567353..395daa557f42 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -39,24 +39,14 @@ #include <svtools/svstdarr.hxx> #endif -#ifndef __SGI_STL_MAP #include <map> -#endif -#ifndef __SGI_STL_VECTOR #include <vector> -#endif -#ifndef SHELLIO_HXX #include <shellio.hxx> -#endif -#ifndef WRT_FN_HXX #include <wrt_fn.hxx> -#endif #include <svx/msocximex.hxx> -#ifndef WW8STRUC_HXX #include "ww8struc.hxx" -#endif #include "ww8scan.hxx" #include "fields.hxx" #include "types.hxx" @@ -65,10 +55,14 @@ #include <expfld.hxx> // einige Forward Deklarationen +class SwAttrIter; +class AttributeOutputBase; +class DocxAttributeOutput; class BitmapPalette; class SwEscherEx; class DateTime; class Font; +class MSWordExportBase; class SdrObject; class SfxItemSet; class SvStream; @@ -103,9 +97,11 @@ class SwTxtFmtColl; class SwTxtNode; class SwWW8WrGrf; class SwWW8Writer; -class WW8WrtStyle; +class MSWordStyles; +class WW8AttributeOutput; class WW8Bytes; -class WW8_AttrIter; +class WW8Export; +class MSWordAttrIter; class WW8_WrFkp; class WW8_WrPlc0; class WW8_WrPlc1; @@ -114,7 +110,7 @@ class WW8_WrMagicTable; class WW8_WrPlcFtnEdn; class WW8_WrPlcPn; class WW8_WrPlcPostIt; -class WW8_WrPlcSepx; +class MSWordSections; class WW8_WrPlcTxtBoxes; class WW8_WrPct; // Verwaltung class WW8_WrPcPtrs; @@ -139,11 +135,11 @@ class SvxBrushItem; typedef BYTE FieldFlags; namespace nsFieldFlags // for InsertField- Method { - const FieldFlags WRITEFIELD_START = 0x01; - const FieldFlags WRITEFIELD_CMD_START = 0x02; + const FieldFlags WRITEFIELD_START = 0x01; + const FieldFlags WRITEFIELD_CMD_START = 0x02; const FieldFlags WRITEFIELD_CMD_END = 0x04; const FieldFlags WRITEFIELD_END = 0x10; - const FieldFlags WRITEFIELD_CLOSE = 0x20; + const FieldFlags WRITEFIELD_CLOSE = 0x20; const FieldFlags WRITEFIELD_ALL = 0xFF; } @@ -153,9 +149,6 @@ enum TxtTypes //enums for TextTypes TXT_EDN = 4, TXT_ATN = 5, TXT_TXTBOX = 6, TXT_HFTXTBOX= 7 }; -extern SwNodeFnTab aWW8NodeFnTab; -extern SwAttrFnTab aWW8AttrFnTab; - SV_DECL_VARARR( WW8Bytes, BYTE, 128, 128 ) struct WW8_SepInfo @@ -173,45 +166,78 @@ struct WW8_SepInfo {} WW8_SepInfo( const SwPageDesc* pPD, const SwSectionFmt* pFmt, - ULONG nLnRestart ) - : pPageDesc(pPD), pSectionFmt(pFmt), pPDNd(0), pNumNd(0), - nLnNumRestartNo(nLnRestart), nPgRestartNo(0) + ULONG nLnRestart, USHORT nPgRestart = 0, const SwNode* pNd = NULL ) + : pPageDesc( pPD ), pSectionFmt( pFmt ), pPDNd( pNd ), pNumNd( 0 ), + nLnNumRestartNo( nLnRestart ), nPgRestartNo( nPgRestart ) {} + bool IsProtected() const; }; -SV_DECL_VARARR( WW8_WrSepInfoPtrs, WW8_SepInfo, 4, 4 ) +SV_DECL_VARARR( WW8_WrSepInfoPtrs, WW8_SepInfo, 4, 4 ) -class WW8_WrPlcSepx // Plc fuer PageDescs -> Sepx ( Section Extensions ) +/// Class to collect and output the sections/headers/footers. +// Plc fuer PageDescs -> Sepx ( Section Extensions ) +class MSWordSections { -private: +protected: bool mbDocumentIsProtected; WW8_WrSepInfoPtrs aSects; // PTRARR von SwPageDesc und SwSectionFmt - SvULongs aCps; // PTRARR von CPs - WW8_PdAttrDesc* pAttrs; - WW8_WrPlc0* pTxtPos; // Pos der einzelnen Header / Footer - void CheckForFacinPg( SwWW8Writer& rWrt ) const; - void WriteOlst( SwWW8Writer& rWrt, USHORT i ); - void WriteFtnEndTxt( SwWW8Writer& rWrt, ULONG nCpStt ); - void OutHeader( SwWW8Writer& rWrt, const SwFmt& rFmt, - ULONG& rCpPos, BYTE nHFFlags, BYTE nFlag ); - void OutFooter( SwWW8Writer& rWrt, const SwFmt& rFmt, - ULONG& rCpPos, BYTE nHFFlags, BYTE nFlag ); + void CheckForFacinPg( WW8Export& rWrt ) const; + void WriteOlst( WW8Export& rWrt, const WW8_SepInfo& rSectionInfo ); + void NeedsDocumentProtected(const WW8_SepInfo &rInfo); + + //No copy, no assign + MSWordSections( const MSWordSections& ); + MSWordSections& operator=( const MSWordSections& ); +public: + MSWordSections( MSWordExportBase& rExport ); + ~MSWordSections(); + + void AppendSep( const SwPageDesc* pPd, + const SwSectionFmt* pSectionFmt = 0, + ULONG nLnNumRestartNo = 0 ); + void AppendSep( const SwFmtPageDesc& rPd, + const SwNode& rNd, + const SwSectionFmt* pSectionFmt, + ULONG nLnNumRestartNo ); + void SetNum( const SwTxtNode* pNumNd ); + + /// Number of columns based on the most recent WW8_SepInfo. + sal_uInt16 CurrentNumberOfColumns( const SwDoc &rDoc ) const; + + /// Number of columns of the provided WW8_SepInfo. + sal_uInt16 NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo ) const; + + bool DocumentIsProtected() const { return mbDocumentIsProtected; } + + /// The most recent WW8_SepInfo. + const WW8_SepInfo* CurrentSectionInfo(); + static void SetHeaderFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt, BYTE nFlag ); static void SetFooterFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt, BYTE nFlag ); + + /// Should we output borders? static int HasBorderItem( const SwFmt& rFmt ); +}; - void NeedsDocumentProtected(const WW8_SepInfo &rInfo); +class WW8_WrPlcSepx : public MSWordSections +{ + SvULongs aCps; // PTRARR von CPs + WW8_PdAttrDesc* pAttrs; + WW8_WrPlc0* pTxtPos; // Pos der einzelnen Header / Footer + + // No copy, no assign + WW8_WrPlcSepx( const WW8_WrPlcSepx& ); + WW8_WrPlcSepx& operator=( const WW8_WrPlcSepx& ); - //No copy, no assign - WW8_WrPlcSepx(const WW8_WrPlcSepx&); - WW8_WrPlcSepx& operator=(const WW8_WrPlcSepx&); public: - WW8_WrPlcSepx(); + WW8_WrPlcSepx( MSWordExportBase& rExport ); ~WW8_WrPlcSepx(); + void AppendSep( WW8_CP nStartCp, const SwPageDesc* pPd, const SwSectionFmt* pSectionFmt = 0, @@ -221,13 +247,17 @@ public: const SwSectionFmt* pSectionFmt, ULONG nLnNumRestartNo ); void Finish( WW8_CP nEndCp ) { aCps.Insert( nEndCp, aCps.Count() ); } - void SetNum( const SwTxtNode* pNumNd ); - bool WriteKFTxt( SwWW8Writer& rWrt ); + + bool WriteKFTxt( WW8Export& rWrt ); void WriteSepx( SvStream& rStrm ) const; - void WritePlcSed( SwWW8Writer& rWrt ) const; - void WritePlcHdd( SwWW8Writer& rWrt ) const; - sal_uInt16 CurrentNoColumns(const SwDoc &rDoc) const; - bool DocumentIsProtected() const { return mbDocumentIsProtected; } + void WritePlcSed( WW8Export& rWrt ) const; + void WritePlcHdd( WW8Export& rWrt ) const; + +private: + void WriteFtnEndTxt( WW8Export& rWrt, ULONG nCpStt ); +public: + void OutHeaderFooter( WW8Export& rWrt, bool bHeader, + const SwFmt& rFmt, ULONG& rCpPos, BYTE nHFFlags, BYTE nFlag ); }; //-------------------------------------------------------------------------- @@ -242,12 +272,13 @@ public: WW8_WrPct(WW8_FC nStartFc, bool bSaveUniCode); ~WW8_WrPct(); void AppendPc(WW8_FC nStartFc, bool bIsUnicode); - void WritePc(SwWW8Writer& rWrt); + void WritePc( WW8Export& rWrt ); void SetParaBreak(); bool IsUnicode() const { return bIsUni; } WW8_CP Fc2Cp( ULONG nFc ) const; }; +/// Collects and outputs fonts. class wwFont { //In some future land the stream could be converted to a nice stream interface @@ -258,29 +289,41 @@ private: String msAltNm; bool mbAlt; bool mbWrtWW8; + FontPitch mePitch; + FontFamily meFamily; + rtl_TextEncoding meChrSet; public: - wwFont(const String &rFamilyName, FontPitch ePitch, FontFamily eFamily, - rtl_TextEncoding eChrSet, bool bWrtWW8); - bool Write(SvStream *pTableStram) const; + wwFont( const String &rFamilyName, FontPitch ePitch, FontFamily eFamily, + rtl_TextEncoding eChrSet, bool bWrtWW8 ); + bool Write( SvStream *pTableStram ) const; +#ifdef DOCX + void WriteDocx( const DocxAttributeOutput* rAttrOutput ) const; +#endif + rtl::OUString GetFamilyName() const { return rtl::OUString( msFamilyNm ); } friend bool operator < (const wwFont &r1, const wwFont &r2); }; class wwFontHelper { private: - /* - * Keep track of fonts that need to be exported. - */ + /// Keep track of fonts that need to be exported. ::std::map<wwFont, USHORT> maFonts; bool mbWrtWW8; + + /// Convert from fast insertion map to linear vector in the order that we want to write. + ::std::vector< const wwFont* > AsVector() const; + public: wwFontHelper() : mbWrtWW8(false) {} - //rDoc used only to get the initial standard font(s) in use. + /// rDoc used only to get the initial standard font(s) in use. void InitFontTable(bool bWrtWW8, const SwDoc& rDoc); USHORT GetId(const Font& rFont); USHORT GetId(const SvxFontItem& rFont); USHORT GetId(const wwFont& rFont); - void WriteFontTable(SvStream *pTableStream, WW8Fib& pFib ); + void WriteFontTable( SvStream *pTableStream, WW8Fib& pFib ); +#ifdef DOCX + void WriteFontTable( const DocxAttributeOutput& rAttrOutput ); +#endif }; class DrawObj @@ -320,9 +363,9 @@ protected: virtual WW8_CP GetCpOffset(const WW8Fib &rFib) const = 0; public: PlcDrawObj() {} - void WritePlc(SwWW8Writer& rWrt) const; - bool Append(SwWW8Writer&, WW8_CP nCp, const sw::Frame& rFmt, - const Point& rNdTopLeft); + void WritePlc( WW8Export& rWrt ) const; + bool Append( WW8Export&, WW8_CP nCp, const sw::Frame& rFmt, + const Point& rNdTopLeft ); int size() { return maDrawObjs.size(); }; DrawObjVector &GetObjArr() { return maDrawObjs; } virtual ~PlcDrawObj(); @@ -370,13 +413,42 @@ class WW8_WrtRedlineAuthor : public sw::util::WrtRedlineAuthor virtual void Write(Writer &rWrt); }; -// der WW8-Writer -class SwWW8Writer: public StgWriter +/** Structure that is used to save some of the WW8Export/DocxExport data. + + It is used to be able to recurse inside of the WW8Export/DocxExport (eg. + for the needs of the tables) - you need to tall WriteText() from there with + new values of PaM etc. + + It must contain all the stuff that might be saved either in WW8Export or in + DocxExport, because it makes no sense to do it abstract, and specialize it + for each of the cases. If you implement other *Export, just add the needed + members here, and store them in the appropriate SaveData() method. + */ +struct MSWordSaveData { -friend bool WW8_WrPlcSepx::WriteKFTxt( SwWW8Writer& rWrt ); // pO -friend class WW8_WrPlcSepx; -friend Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ); + Point* pOldFlyOffset; + RndStdIds eOldAnchorType; + WW8Bytes* pOOld; ///< WW8Export only + WW8Bytes* mpTableAtOld; ///< WW8Export only: Additional buffer for the output of the tables + sal_uInt16 mnTableStdAtLenOld; ///< WW8Export only: Standard length of mpTableAt + SwPaM* pOldPam, *pOldEnd; + const sw::Frame* pOldFlyFmt; + const SwPageDesc* pOldPageDesc; + BYTE bOldWriteAll : 1; ///< WW8Export only + BYTE bOldOutTable : 1; + BYTE bOldIsInTable: 1; + BYTE bOldFlyFrmAttrs : 1; + BYTE bOldStartTOX : 1; + BYTE bOldInWriteTOX : 1; + // bOutPageDesc muss nicht gesichert werden, da es nur nicht waehrend der + // Ausgabe von Spezial-Texten veraendert wird. +}; + +/// Base class for WW8Export and DocxExport +class MSWordExportBase +{ +public: wwFontHelper maFontHelper; std::vector<ULONG> maChapterFieldLocs; typedef std::vector<ULONG>::const_iterator mycCFIter; @@ -385,9 +457,9 @@ friend Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ); const SfxItemSet* pISet; // fuer Doppel-Attribute WW8_WrPct* pPiece; // Pointer auf Piece-Table SwNumRuleTbl* pUsedNumTbl; // alle used NumRules - const SwTxtNode *mpTopNodeOfHdFtPage; //top node of host page when in hd/ft - std::map<USHORT, USHORT> aRuleDuplicates; //map to Duplicated numrules - std::stack<xub_StrLen> maCurrentCharPropStarts; + const SwTxtNode *mpTopNodeOfHdFtPage; ///< Top node of host page when in hd/ft + std::map< USHORT, USHORT > aRuleDuplicates; //map to Duplicated numrules + std::stack< xub_StrLen > m_aCurrentCharPropStarts; ///< To remember the position in a run. WW8_WrtBookmarks* pBkmks; WW8_WrtRedlineAuthor* pRedlAuthors; BitmapPalette* pBmpPal; @@ -399,68 +471,23 @@ friend Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode ); USHORT nCharFmtStart; USHORT nFmtCollStart; - USHORT nStyleBeforeFly; // Style-Nummer des Nodes, - // in/an dem ein Fly verankert ist - USHORT nLastFmtId; // Style of last TxtNode in normal range - USHORT nUniqueList; // current number for creating unique list names + USHORT nStyleBeforeFly; ///< Style-Nummer des Nodes, + ///< in/an dem ein Fly verankert ist + USHORT nLastFmtId; ///< Style of last TxtNode in normal range + USHORT nUniqueList; ///< current number for creating unique list names unsigned int mnHdFtIndex; - SfxMedium* mpMedium; - - virtual ULONG WriteStorage(); - virtual ULONG WriteMedium( SfxMedium& ); - - void PrepareStorage(); - void WriteFkpPlcUsw(); - void WriteMainText(); - void StoreDoc1(); - ULONG StoreDoc(); - void Out_Olst( const SwNumRule& rRule ); - void Out_WwNumLvl( BYTE nWwLevel ); - void Out_SwNumLvl( BYTE nSwLevel ); - void Out_NumRuleAnld( const SwNumRule& rRul, const SwNumFmt& rFmt, - BYTE nSwLevel ); - void BuildAnlvBulletBase( WW8_ANLV& rAnlv, BYTE*& rpCh, USHORT& rCharLen, - const SwNumFmt& rFmt ); - void SubstituteBullet(String& rNumStr, rtl_TextEncoding& rChrSet, - String& rFontName) const; - - static void BuildAnlvBase( WW8_ANLV& rAnlv, BYTE*& rpCh, USHORT& rCharLen, - const SwNumRule& rRul, const SwNumFmt& rFmt, BYTE nSwLevel ); + USHORT mnRedlineMode; ///< Remember the original redline mode - void Out_BorderLine(WW8Bytes& rO, const SvxBorderLine* pLine, - USHORT nDist, USHORT nSprmNo, bool bShadow); - - void OutListTab(); - void OutOverrideListTab(); - void OutListNamesTab(); - - void RestoreMacroCmds(); - - void InitFontTable(); - - bool MiserableFormFieldExportHack(const SwFrmFmt& rFrmFmt); - void DoComboBox(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPropSet); - void DoCheckBox(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPropSet); - void GatherChapterFields(); - bool FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const; - bool CntntContainsChapterField(const SwFmtCntnt &rCntnt) const; - void OutWW8_SwEndNode( SwNode * pNode ); public: - /* implicit bookmark vector containing pairs of node indexes and bookmark names */ SwImplBookmarks maImplicitBookmarks; sw::Frames maFrames; // The floating frames in this document const SwPageDesc *pAktPageDesc; - WW8Fib* pFib; - WW8Dop* pDop; WW8_WrPlcPn* pPapPlc; WW8_WrPlcPn* pChpPlc; - WW8_AttrIter* pChpIter; - WW8WrtStyle* pStyles; - WW8_WrPlcSepx* pSepx; - WW8_WrPlcFtnEdn* pFtn; - WW8_WrPlcFtnEdn* pEdn; + MSWordAttrIter* pChpIter; + MSWordStyles* pStyles; WW8_WrPlcPostIt* pAtn; WW8_WrPlcTxtBoxes *pTxtBxs, *pHFTxtBxs; @@ -490,10 +517,6 @@ public: MainTxtPlcDrawObj *pSdrObjs; // Draw-/Fly-Objects HdFtPlcDrawObj *pHFSdrObjs; // Draw-/Fly-Objects in header or footer - WW8Bytes* pO; - - SvStream *pTableStrm, *pDataStrm; // Streams fuer WW97 Export - SwEscherEx* pEscher; // escher export class // --> OD 2007-04-19 #i43447# - removed // SwTwips nFlyWidth, nFlyHeight; // Fuer Anpassung Graphic @@ -505,14 +528,13 @@ public: BYTE bBreakBefore : 1; // Breaks werden 2mal ausgegeben BYTE bOutKF : 1; // Kopf/Fusstexte werden ausgegeben BYTE bOutFlyFrmAttrs : 1; // Rahmen-Attr von Flys werden ausgegeben - BYTE bOutPageDescs : 1; // PageDescs werden ausgegeben ( am Doc-Ende ) + BYTE bOutPageDescs : 1; ///< PageDescs (section properties) are being written BYTE bOutFirstPage : 1; // write Attrset of FirstPageDesc BYTE bOutTable : 1; // Tabelle wird ausgegeben // ( wird zB bei Flys in Tabelle zurueckgesetzt ) BYTE bIsInTable : 1; // wird sind innerhalb der Ausgabe einer Tabelle // ( wird erst nach der Tabelle zurueckgesetzt ) BYTE bOutGrf : 1; // Grafik wird ausgegeben - BYTE bWrtWW8 : 1; // Schreibe WW95 oder WW97 FileFormat BYTE bInWriteEscher : 1; // in write textboxes BYTE bStartTOX : 1; // true: a TOX is startet BYTE bInWriteTOX : 1; // true: all content are in a TOX @@ -521,91 +543,454 @@ public: BYTE bHasHdr : 1; BYTE bHasFtr : 1; + SwDoc *pDoc; + SwPaM *pCurPam, *pOrigPam; + + /// Stack to remember the nesting (see MSWordSaveData for more) + ::std::stack< MSWordSaveData > maSaveData; + +public: + /// The main function to export the document. + void ExportDocument( bool bWriteAll ); + + /// Iterate through the nodes and call the appropriate OutputNode() on them. + void WriteText(); + + /// Set the pCurPam appropriately and call WriteText(). + /// + /// Used to export paragraphs in footnotes/endnotes/etc. + void WriteSpecialText( ULONG nStart, ULONG nEnd, BYTE nTTyp ); + + /// Export the pool items to attributes (through an attribute output class). + void ExportPoolItemsToCHP( sw::PoolItems &rItems, USHORT nScript ); + + /// Return the numeric id of the numbering rule + USHORT GetId( const SwNumRule& rNumRule ); + + /// Return the numeric id of the style. + USHORT GetId( const SwTxtFmtColl& rColl ) const; + + /// Return the numeric id of the style. + USHORT GetId( const SwCharFmt& rFmt ) const; + + USHORT GetId( const SwTOXType& rTOXType ); + + const SfxPoolItem& GetItem( USHORT nWhich ) const; + + /// Find the reference. + bool HasRefToObject( USHORT nTyp, const String* pName, USHORT nSeqNo ); + + /// Find the bookmark name. + String GetBookmarkName( USHORT nTyp, const String* pName, USHORT nSeqNo ); + + /// Add a bookmark converted to a Word name. + void AppendWordBookmark( const String& rName ); + + /// Use OutputItem() on an item set according to the parameters. + void OutputItemSet( const SfxItemSet& rSet, bool bPapFmt, bool bChpFmt, USHORT nScript ); + + short GetDefaultFrameDirection( ) const; + + /// Right to left? + short TrueFrameDirection( const SwFrmFmt& rFlyFmt ) const; + + /// Right to left? + short GetCurrentPageDirection() const; + + /// In case of numbering restart. + + /// List is set to restart at a particular value so for export make a + /// completely new list based on this one and export that instead, + /// which duplicates words behaviour in this respect. + USHORT DuplicateNumRule( const SwNumRule *pRule, BYTE nLevel, USHORT nVal ); + + /// Access to the attribute output class. + virtual AttributeOutputBase& AttrOutput() const = 0; + + /// Access to the sections/headers/footres. + virtual MSWordSections& Sections() const = 0; + + /// Hack, unfortunately necessary at some places for now. + /// FIXME remove it when possible. + virtual bool HackIsWW8OrHigher() const = 0; + + /// Guess the script (asian/western). + /// + /// Sadly word does not have two different sizes for asian font size and + /// western font size, it has two different fonts, but not sizes, so we + /// have to use our guess as to the script used and disable the export of + /// one type. The same occurs for font weight and posture (bold and + /// italic). + /// + /// In addition WW7- has only one character language identifier while WW8+ + /// has two + virtual bool CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich ) = 0; + + virtual void AppendBookmarks( const SwTxtNode& rNd, xub_StrLen nAktPos, xub_StrLen nLen ) = 0; + + virtual void AppendBookmark( const rtl::OUString& rName, bool bSkip = false ) = 0; + + // FIXME probably a hack... + virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() ) = 0; + + // FIXME definitely a hack, must not be here - it can't do anything + // sensible for docx + virtual void WriteChar( sal_Unicode c ) = 0; + + /// Output attributes. + void OutputFormat( const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, bool bFlyFmt = false ); + + /// Getter for pISet. + const SfxItemSet* GetCurItemSet() const { return pISet; } + + /// Setter for pISet. + void SetCurItemSet( const SfxItemSet* pS ) { pISet = pS; } + + /// Remember some of the memebers so that we can recurse in WriteText(). + virtual void SaveData( ULONG nStt, ULONG nEnd ); + + /// Restore what was saved in SaveData(). + virtual void RestoreData(); + + /// The return value indicates, if a follow page desc is written. + bool OutputFollowPageDesc( const SfxItemSet* pSet, + const SwTxtNode* pNd ); + + /// Write header/footer text. + void WriteHeaderFooterText( const SwFmt& rFmt, bool bHeader ); + + /// Format of the section. + const SwSectionFmt* GetSectionFormat( const SwNode& rNd ) const; + + /// Line number of the section start. + ULONG GetSectionLineNo( const SfxItemSet* pSet, const SwNode& rNd ) const; + + /// Start new section. + void OutputSectionBreaks( const SfxItemSet *pSet, const SwNode& rNd ); + /// Write section properties. + /// + /// pA is ignored for docx. + void SectionProperties( const WW8_SepInfo& rSectionInfo, WW8_PdAttrDesc* pA = NULL ); + + /// Output the numbering table. + virtual void WriteNumbering() = 0; + + /// Write static data of SwNumRule - LSTF + void NumberingDefinitions(); + + /// Write all Levels for all SwNumRules - LVLF + void AbstractNumberingDefinitions(); + + // Convert the bullet according to the font. + void SubstituteBullet( String& rNumStr, rtl_TextEncoding& rChrSet, + String& rFontName ) const; + + /// No-op for the newer WW versions. + virtual void OutputOlst( const SwNumRule& /*rRule*/ ) {} + + /// Setup the pA's info. + virtual void SetupSectionPositions( WW8_PdAttrDesc* /*pA*/ ) {} + + /// Top node of host page when in header/footer. + void SetHdFtPageRoot( const SwTxtNode *pNd ) { mpTopNodeOfHdFtPage = pNd; } + + /// Top node of host page when in header/footer. + const SwTxtNode *GetHdFtPageRoot() const { return mpTopNodeOfHdFtPage; } + + /// Output the actual headers and footers. + virtual void WriteHeadersFooters( BYTE nHeadFootFlags, + const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt ) = 0; + + /// Write the field + virtual void OutputField( const SwField* pFld, ww::eField eFldType, + const String& rFldCmd, BYTE nMode = nsFieldFlags::WRITEFIELD_ALL ) = 0; + + /// Write the data of the form field + virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) = 0; + + virtual void DoComboBox(const rtl::OUString &rName, + const rtl::OUString &rHelp, + const rtl::OUString &ToolTip, + const rtl::OUString &rSelected, + com::sun::star::uno::Sequence<rtl::OUString> &rListItems) = 0; + + virtual void DoFormText(const SwInputField * pFld) = 0; + + static bool NoPageBreakSection( const SfxItemSet *pSet ); + + // Compute the number format for WW dates + bool GetNumberFmt(const SwField& rFld, String& rStr); + + virtual ULONG ReplaceCr( BYTE nChar ) = 0; + + const SfxPoolItem* HasItem( USHORT nWhich ) const; + + +protected: + /// Format-dependant part of the actual export. + virtual void ExportDocument_Impl() = 0; + + /// Get the next position in the text node to output + virtual xub_StrLen GetNextPos( SwAttrIter* pAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos ); + + /// Update the information for GetNextPos(). + virtual void UpdatePosition( SwAttrIter* pAttrIter, xub_StrLen nAktPos, xub_StrLen nEnd ); + + /// Output SwTxtNode + void OutputTextNode( const SwTxtNode& ); + + /// Output SwTableNode + void OutputTableNode( const SwTableNode& ); + + /// Setup the chapter fields (maChapterFieldLocs). + void GatherChapterFields(); + + void AddLinkTarget( const String& rURL ); + void CollectOutlineBookmarks( const SwDoc &rDoc ); + + bool SetAktPageDescFromNode(const SwNode &rNd); + bool CntntContainsChapterField(const SwFmtCntnt &rCntnt) const; + bool FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const; + + virtual void SectionBreaksAndFrames( const SwTxtNode& rNode ) = 0; + + virtual void PrepareNewPageDesc( const SfxItemSet* pSet, + const SwNode& rNd, + const SwFmtPageDesc* pNewPgDescFmt = 0, + const SwPageDesc* pNewPgDesc = 0 ) = 0; + + /// Return value indicates if an inherited outline numbering is suppressed. + virtual bool DisallowInheritingOutlineNumbering(const SwFmt &rFmt) = 0; + +protected: + /// Output SwEndNode + virtual void OutputEndNode( const SwEndNode& ); + + /// Output SwGrfNode + virtual void OutputGrfNode( const SwGrfNode& ) = 0; + + /// Output SwOLENode + virtual void OutputOLENode( const SwOLENode& ) = 0; + + /// Output SwSectionNode + virtual void OutputSectionNode( const SwSectionNode& ); + + virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum ) = 0; + + /// Call the right (virtual) function according to the type of the item. + /// + /// One of OutputTextNode(), OutputGrfNode(), or OutputOLENode() + void OutputContentNode( const SwCntntNode& ); + +public: + MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam ); + virtual ~MSWordExportBase(); + + // TODO move as much as possible here from WW8Export! ;-) + + static void CorrectTabStopInSet( SfxItemSet& rSet, USHORT nAbsLeft ); + +private: + /// No copying. + MSWordExportBase( const MSWordExportBase& ); + /// No copying. + MSWordExportBase& operator=( const MSWordExportBase& ); +}; + +/// The writer class that gets called for the WW8 filter. +class SwWW8Writer: public StgWriter +{ +// friends to get access to m_pExport +// FIXME avoid that, this is probably not what we want +// (if yes, remove the friends, and provide here a GetExport() method) +friend void WW8_WrtRedlineAuthor::Write(Writer &rWrt); + + bool m_bWrtWW8; + WW8Export *m_pExport; + SfxMedium *mpMedium; + +public: + SwWW8Writer( const String& rFltName, const String& rBaseURL ); + virtual ~SwWW8Writer(); + + virtual ULONG WriteStorage(); + virtual ULONG WriteMedium( SfxMedium& ); + + // TODO most probably we want to be able to get these in + // MSExportFilterBase + using Writer::getIDocumentSettingAccess; + +public: +#if 1 + /// Prefer ww::bytes to WW8Bytes, migrate away from the other ones. + static void InsUInt16(ww::bytes &rO, sal_uInt16 n); + static void InsUInt32(ww::bytes &rO, sal_uInt32 n); + static void InsAsString16(ww::bytes &rO, const String& rStr); + static void InsAsString8(ww::bytes & O, const String& rStr, + rtl_TextEncoding eCodeSet); +#endif + + static void InsUInt16( WW8Bytes& rO, UINT16 ); + static void InsUInt32( WW8Bytes& rO, UINT32 ); + static void InsAsString16( WW8Bytes& rO, const String& ); + static void InsAsString8( WW8Bytes& rO, const String& rStr, + rtl_TextEncoding eCodeSet ); + + static ULONG FillUntil( SvStream& rStrm, ULONG nEndPos = 0 ); + static void FillCount( SvStream& rStrm, ULONG nCount ); + + static void WriteShort( SvStream& rStrm, INT16 nVal ) { rStrm << nVal; } + static void WriteShort( SvStream& rStrm, ULONG nPos, INT16 nVal ); + + static void WriteLong( SvStream& rStrm, INT32 nVal ) { rStrm << nVal; } + static void WriteLong( SvStream& rStrm, ULONG nPos, INT32 nVal ); + + static void WriteString16(SvStream& rStrm, const String& rStr, + bool bAddZero); + static void WriteString8(SvStream& rStrm, const String& rStr, + bool bAddZero, rtl_TextEncoding eCodeSet); + + static void WriteString_xstz(SvStream& rStrm, const String& rStr, bool bAddZero); + + String GetPassword(); + + using StgWriter::Write; virtual ULONG Write( SwPaM&, SfxMedium&, const String* = 0 ); - virtual ULONG Write( SwPaM&, const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&, const String* = 0, SfxMedium* = 0 ); - virtual ULONG Write( SwPaM&, SotStorage&, const String* = 0 ); - virtual ULONG Write( SwPaM&, SvStream&, const String* = 0 ); +private: + /// No copying. + SwWW8Writer(const SwWW8Writer&); + /// No copying. + SwWW8Writer& operator=(const SwWW8Writer&); +}; + +/// Exporter of the binary Word file formats. +class WW8Export : public MSWordExportBase +{ +public: + WW8Bytes* pO; ///< Buffer + WW8Bytes* mpTableAt; ///< Additional buffer for the output of the tables + sal_uInt16 mnTableStdAtLen; ///< Standard length of mpTableAt + + SvStream *pTableStrm, *pDataStrm; ///< Streams for WW97 Export + + WW8Fib* pFib; ///< File Information Block + WW8Dop* pDop; ///< DOcument Properties + WW8_WrPlcFtnEdn *pFtn; ///< Footnotes - structure to remember them, and output + WW8_WrPlcFtnEdn *pEdn; ///< Endnotes - structure to remember them, and output + WW8_WrPlcSepx* pSepx; ///< Sections/headers/footers + + BYTE bWrtWW8 : 1; ///< Write WW95 (false) or WW97 (true) file format + +protected: + SwWW8Writer *m_pWriter; ///< Pointer to the writer + WW8AttributeOutput *m_pAttrOutput; ///< Converting attributes to stream data + +public: + /// Access to the attribute output class. + virtual AttributeOutputBase& AttrOutput() const; + + /// Access to the sections/headers/footres. + virtual MSWordSections& Sections() const; + + /// False for WW6, true for WW8. + virtual bool HackIsWW8OrHigher() const { return bWrtWW8; } + +private: + /// Format-dependant part of the actual export. + virtual void ExportDocument_Impl(); + + void PrepareStorage(); + void WriteFkpPlcUsw(); + void WriteMainText(); + void StoreDoc1(); + void Out_WwNumLvl( BYTE nWwLevel ); + void BuildAnlvBulletBase( WW8_ANLV& rAnlv, BYTE*& rpCh, USHORT& rCharLen, + const SwNumFmt& rFmt ); + static void BuildAnlvBase( WW8_ANLV& rAnlv, BYTE*& rpCh, USHORT& rCharLen, + const SwNumRule& rRul, const SwNumFmt& rFmt, BYTE nSwLevel ); + + void Out_BorderLine(WW8Bytes& rO, const SvxBorderLine* pLine, + USHORT nDist, sal_uInt16 nSprmNo, bool bShadow); + + /// Output the numbering table. + virtual void WriteNumbering(); + + void OutOverrideListTab(); + void OutListNamesTab(); + + void RestoreMacroCmds(); + + void InitFontTable(); + + void DoComboBox(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPropSet); + void DoCheckBox(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPropSet); + +public: + virtual void OutputOlst( const SwNumRule& rRule ); + + /// Setup the pA's info. + virtual void SetupSectionPositions( WW8_PdAttrDesc* pA ); + + void Out_SwNumLvl( BYTE nSwLevel ); + void Out_NumRuleAnld( const SwNumRule& rRul, const SwNumFmt& rFmt, + BYTE nSwLevel ); + + bool MiserableFormFieldExportHack(const SwFrmFmt& rFrmFmt); SvxMSExportOLEObjects& GetOLEExp() { return *pOLEExp; } SwMSConvertControls& GetOCXExp() { return *pOCXExp; } WW8OleMaps& GetOLEMap() { return *pOleMap; } void ExportDopTypography(WW8DopTypography &rTypo); - const SfxPoolItem* HasItem( USHORT nWhich ) const; - const SfxPoolItem& GetItem( USHORT nWhich ) const; - - USHORT GetId( const SwTxtFmtColl& rColl ) const; - USHORT GetId( const SwCharFmt& rFmt ) const; - USHORT GetId( const SwNumRule& rNumRule ) const; - USHORT GetId( const SwTOXType& rTOXType ); + using MSWordExportBase::GetId; USHORT GetId( const SvxFontItem& rFont) { return maFontHelper.GetId(rFont); } - void OutRedline( const SwRedlineData& rRedline ); USHORT AddRedlineAuthor( USHORT nId ); - void StartTOX( const SwSection& rSect ); - void EndTOX( const SwSection& rSect ); - - void WriteSpecialText( ULONG nStart, ULONG nEnd, BYTE nTTyp ); - void WriteKFTxt1( const SwFmtCntnt& rCntnt ); void WriteFtnBegin( const SwFmtFtn& rFtn, WW8Bytes* pO = 0 ); void WritePostItBegin( WW8Bytes* pO = 0 ); - short TrueFrameDirection(const SwFrmFmt &rFlyFmt) const; - short GetCurrentPageDirection() const; const SvxBrushItem* GetCurrentPageBgBrush() const; SvxBrushItem TrueFrameBgBrush(const SwFrmFmt &rFlyFmt) const; - void OutWW8FlyFrmsInCntnt( const SwTxtNode& rNd ); - void OutWW8FlyFrm(const sw::Frame& rFmt, const Point& rNdTopLeft); - void OutFlyFrm(const sw::Frame& rFmt); + + /// Output all textframes anchored as character for the winword 7- format. + void OutWW6FlyFrmsInCntnt( const SwTxtNode& rNd ); + void AppendFlyInFlys(const sw::Frame& rFrmFmt, const Point& rNdTopLeft); void WriteOutliner(const OutlinerParaObject& rOutliner, BYTE nTyp); void WriteSdrTextObj(const SdrObject& rObj, BYTE nTyp); - void OutWW8TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableInfoRow(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableDefinition(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableDefaultBorders(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableBackgrounds(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableHeight(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableCanSplit(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableBidi(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableVerticalCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo); - void OutWW8TableNodeInfo(ww8::WW8TableNodeInfo::Pointer_t pNodeInfo); - void OutWW8_TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner); - void OutWW8TableOrientation(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner); UINT32 GetSdrOrdNum( const SwFrmFmt& rFmt ) const; void CreateEscher(); void WriteEscher(); bool Out_SwNum(const SwTxtNode* pNd); - void Out_SwFmt(const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, - bool bFlyFmt = false); - bool GetNumberFmt(const SwField& rFld, String& rStr); - void OutField(const SwField* pFld, ww::eField eFldType, - const String& rFldCmd, BYTE nMode = nsFieldFlags::WRITEFIELD_ALL); + + /// Write the field + virtual void OutputField( const SwField* pFld, ww::eField eFldType, + const String& rFldCmd, BYTE nMode = nsFieldFlags::WRITEFIELD_ALL ); + void StartCommentOutput( const String& rName ); void EndCommentOutput( const String& rName ); void OutGrf(const sw::Frame &rFrame); bool TestOleNeedsGraphic(const SwAttrSet& rSet, SvStorageRef xOleStg, SvStorageRef xObjStg, String &rStorageName, SwOLENode *pOLENd); - void AppendBookmarks( const SwTxtNode& rNd, xub_StrLen nAktPos, - xub_StrLen nLen ); - void AppendBookmark( const String& rName, USHORT nOffset = 0 ); - String GetBookmarkName( USHORT nTyp, const String* pNm, USHORT nSeqNo ); + + virtual void AppendBookmarks( const SwTxtNode& rNd, xub_StrLen nAktPos, xub_StrLen nLen ); + virtual void AppendBookmark( const rtl::OUString& rName, bool bSkip = false ); void MoveFieldMarks(ULONG nFrom, ULONG nTo); - bool HasRefToObject(USHORT nTyp, const String* pNm, USHORT nSeqNo); void WriteAsStringTable(const ::std::vector<String>&, INT32& rfcSttbf, INT32& rlcbSttbf, USHORT nExtraLen = 0); - void WriteText(); - void WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t()); + + virtual ULONG ReplaceCr( BYTE nChar ); + + virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() ); void WriteChar( sal_Unicode c ); - void WriteRowEnd(sal_uInt32 nDepth = 1); #if 0 USHORT StartTableFromFrmFmt(WW8Bytes &rAt, const SwFrmFmt *pFmt, SwTwips &rPageSize); @@ -614,8 +999,6 @@ public: void OutSwString(const String&, xub_StrLen nStt, xub_StrLen nLen, bool bUnicode, rtl_TextEncoding eChrSet); - ULONG ReplaceCr( BYTE nChar ); - WW8_CP Fc2Cp( ULONG nFc ) const { return pPiece->Fc2Cp( nFc ); } // einige z.T. static halb-interne Funktions-Deklarationen @@ -625,24 +1008,14 @@ public: inline bool IsUnicode() const { return pPiece->IsUnicode(); } - const SfxItemSet* GetCurItemSet() const { return pISet; } - void SetCurItemSet( const SfxItemSet* pS ) { pISet = pS; } + virtual void SectionBreaksAndFrames( const SwTxtNode& rNode ); - void ExportPoolItemsToCHP(sw::PoolItems &rItems, USHORT nScript); - void Out_SfxItemSet(const SfxItemSet& rSet, bool bPapFmt, bool bChpFmt, - USHORT nScript); - void Out_SfxBreakItems(const SfxItemSet *pSet, const SwNode& rNd); - bool SetAktPageDescFromNode(const SwNode &rNd); - // --> OD 2007-05-29 #i76300# - // return value indicates, if a follow page desc is written. - bool Out_FollowPageDesc( const SfxItemSet* pSet, - const SwTxtNode* pNd ); - // helper method for <Out_SfxBreakItems(..)> and <Out_FollowPageDesc(..)> - void PrepareNewPageDesc( const SfxItemSet* pSet, - const SwNode& rNd, - const SwFmtPageDesc* pNewPgDescFmt = 0, - const SwPageDesc* pNewPgDesc = 0 ); - // <-- + /// Helper method for OutputSectionBreaks() and OutputFollowPageDesc(). + // OD 2007-05-29 #i76300# + virtual void PrepareNewPageDesc( const SfxItemSet* pSet, + const SwNode& rNd, + const SwFmtPageDesc* pNewPgDescFmt = 0, + const SwPageDesc* pNewPgDesc = 0 ); void Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow); void Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem& rBox ); @@ -651,56 +1024,31 @@ public: WW8_BRC TranslateBorderLine(const SvxBorderLine& pLine, USHORT nDist, bool bShadow); - void ExportOutlineNumbering(BYTE nLvl, const SwNumFmt &rNFmt, - const SwFmt &rFmt); // --> OD 2007-06-04 #i77805# // new return value indicates, if an inherited outline numbering is suppressed - bool DisallowInheritingOutlineNumbering(const SwFmt &rFmt); + virtual bool DisallowInheritingOutlineNumbering(const SwFmt &rFmt); // <-- unsigned int GetHdFtIndex() const { return mnHdFtIndex; } void SetHdFtIndex(unsigned int nHdFtIndex) { mnHdFtIndex = nHdFtIndex; } + void IncrementHdFtIndex() { ++mnHdFtIndex; } static long GetDTTM( const DateTime& rDT ); + /// Convert the SVX numbering type to id static BYTE GetNumId( USHORT eNumType ); - static void CorrTabStopInSet( SfxItemSet& rSet, USHORT nAbsLeft ); - - static ULONG FillUntil( SvStream& rStrm, ULONG nEndPos = 0 ); - static void FillCount( SvStream& rStrm, ULONG nCount ); - static void WriteShort( SvStream& rStrm, INT16 nVal ) { rStrm << nVal; } - static void WriteShort( SvStream& rStrm, ULONG nPos, INT16 nVal ); + /// Guess the script (asian/western). + virtual bool CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich ); - static void WriteLong( SvStream& rStrm, INT32 nVal ) { rStrm << nVal; } - static void WriteLong( SvStream& rStrm, ULONG nPos, INT32 nVal ); - - static void WriteString16(SvStream& rStrm, const String& rStr, - bool bAddZero); - static void WriteString8(SvStream& rStrm, const String& rStr, - bool bAddZero, rtl_TextEncoding eCodeSet); - - static void WriteString_xstz(SvStream& rStrm, const String& rStr, bool bAddZero); -#if 1 - //Prefer ww::bytes to WW8Bytes, migrate away from the other ones. - static void InsUInt16(ww::bytes &rO, sal_uInt16 n); - static void InsUInt32(ww::bytes &rO, sal_uInt32 n); - static void InsAsString16(ww::bytes &rO, const String& rStr); - static void InsAsString8(ww::bytes & O, const String& rStr, - rtl_TextEncoding eCodeSet); -#endif - - static void InsUInt16( WW8Bytes& rO, UINT16 ); - static void InsUInt32( WW8Bytes& rO, UINT32 ); - static void InsAsString16( WW8Bytes& rO, const String& ); - static void InsAsString8( WW8Bytes& rO, const String& rStr, - rtl_TextEncoding eCodeSet ); - bool CollapseScriptsforWordOk(USHORT nScript, USHORT nWhich); USHORT DupNumRuleWithLvlStart(const SwNumRule *pRule,BYTE nLvl,USHORT nVal); SwTwips CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const; + + /// Nasty swap for bidi if neccessary bool MiserableRTLFrmFmtHack(SwTwips &rLeft, SwTwips &rRight, const sw::Frame &rFrmFmt); + void InsUInt16( UINT16 n ) { SwWW8Writer::InsUInt16( *pO, n ); } void InsUInt32( UINT32 n ) { SwWW8Writer::InsUInt32( *pO, n ); } void InsAsString16( const String& rStr ) @@ -709,41 +1057,55 @@ public: { SwWW8Writer::InsAsString8( *pO, rStr, eCodeSet ); } void WriteStringAsPara( const String& rTxt, USHORT nStyleId = 0 ); - // nach aussen interessant - - SwWW8Writer( const String& rFltName, const String& rBaseURL ); - virtual ~SwWW8Writer(); + /// Setup the exporter. + WW8Export( SwWW8Writer *pWriter, + SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam, + bool bIsWW8 ); + virtual ~WW8Export(); - // fuer WW8SaveData - SwPaM* GetEndPaM() { return pOrigPam; } - void SetEndPaM( SwPaM* pPam ) { pOrigPam = pPam; } - - void DoComboBox(const rtl::OUString &rName, + virtual void DoComboBox(const rtl::OUString &rName, const rtl::OUString &rHelp, const rtl::OUString &ToolTip, const rtl::OUString &rSelected, com::sun::star::uno::Sequence<rtl::OUString> &rListItems); - void DoFormText(const SwInputField * pFld); + virtual void DoFormText(const SwInputField * pFld); - static bool NoPageBreakSection(const SfxItemSet *pSet); - void push_charpropstart(xub_StrLen nPos); - void pop_charpropstart(); - xub_StrLen top_charpropstart() const; void GetCurrentItems(WW8Bytes &rItems) const; - void SetHdFtPageRoot(const SwTxtNode *pNd) { mpTopNodeOfHdFtPage = pNd; } - const SwTxtNode *GetHdFtPageRoot() const { return mpTopNodeOfHdFtPage; } - void AddLinkTarget(const String& rURL); - void CollectOutlineBookmarks(const SwDoc &rDoc); - void AddBookmark(String sBkmkName); + /// Write the data of the form field + virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ); - void WriteFormData(const ::sw::mark::IFieldmark& rFieldmark); + /// Fields. WW8_WrPlcFld* CurrentFieldPlc() const; + + SwWW8Writer& GetWriter() const { return *m_pWriter; } + SvStream& Strm() const { return m_pWriter->Strm(); } + + /// Remember some of the memebers so that we can recurse in WriteText(). + virtual void SaveData( ULONG nStt, ULONG nEnd ); + + /// Restore what was saved in SaveData(). + virtual void RestoreData(); + + /// Output the actual headers and footers. + virtual void WriteHeadersFooters( BYTE nHeadFootFlags, + const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt ); + +protected: + /// Output SwGrfNode + virtual void OutputGrfNode( const SwGrfNode& ); + + /// Output SwOLENode + virtual void OutputOLENode( const SwOLENode& ); + + virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum ); + private: - //No copying - SwWW8Writer(const SwWW8Writer&); - SwWW8Writer& operator=(const SwWW8Writer&); + /// No copying. + WW8Export(const WW8Export&); + /// No copying. + WW8Export& operator=(const WW8Export&); }; class WW8_WrPlcSubDoc // Doppel-Plc fuer Foot-/Endnotes und Postits @@ -760,8 +1122,8 @@ protected: WW8_WrPlcSubDoc(); virtual ~WW8_WrPlcSubDoc(); - bool WriteGenericTxt(SwWW8Writer& rWrt, BYTE nTTyp, WW8_CP& rCount); - void WriteGenericPlc( SwWW8Writer& rWrt, BYTE nTTyp, WW8_FC& rTxtStt, + bool WriteGenericTxt( WW8Export& rWrt, BYTE nTTyp, WW8_CP& rCount ); + void WriteGenericPlc( WW8Export& rWrt, BYTE nTTyp, WW8_FC& rTxtStt, sal_Int32& rTxtCnt, WW8_FC& rRefStt, sal_Int32& rRefCnt ) const; virtual const SvULongs* GetShapeIdArr() const; @@ -779,8 +1141,8 @@ private: public: WW8_WrPlcFtnEdn( BYTE nTTyp ) : nTyp( nTTyp ) {} - bool WriteTxt(SwWW8Writer& rWrt); - void WritePlc( SwWW8Writer& rWrt ) const; + bool WriteTxt( WW8Export& rWrt ); + void WritePlc( WW8Export& rWrt ) const; void Append( WW8_CP nCp, const SwFmtFtn& rFtn ); }; @@ -795,8 +1157,8 @@ public: WW8_WrPlcPostIt() {} void Append( WW8_CP nCp, const SwPostItField& rPostIt ); - bool WriteTxt(SwWW8Writer& rWrt); - void WritePlc( SwWW8Writer& rWrt ) const; + bool WriteTxt( WW8Export& rWrt ); + void WritePlc( WW8Export& rWrt ) const; }; class WW8_WrPlcTxtBoxes : public WW8_WrPlcSubDoc // Doppel-Plc fuer Textboxen @@ -812,8 +1174,8 @@ private: public: WW8_WrPlcTxtBoxes( BYTE nTTyp ) : nTyp( nTTyp ) {} - bool WriteTxt(SwWW8Writer& rWrt); - void WritePlc( SwWW8Writer& rWrt ) const; + bool WriteTxt( WW8Export& rWrt ); + void WritePlc( WW8Export& rWrt ) const; void Append( const SdrObject& rObj, UINT32 nShapeId ); USHORT Count() const { return aCntnt.Count(); } USHORT GetPos( const VoidPtr& p ) const { return aCntnt.GetPos( p ); } @@ -825,7 +1187,7 @@ SV_DECL_PTRARR( WW8_WrFkpPtrs, WW8_FkpPtr, 4, 4 ) class WW8_WrPlcPn // Plc fuer Page Numbers { private: - SwWW8Writer& rWrt; + WW8Export& rWrt; WW8_WrFkpPtrs aFkps; // PTRARR USHORT nFkpStartPage; ePLCFT ePlc; @@ -836,7 +1198,7 @@ private: WW8_WrPlcPn(const WW8_WrPlcPn&); WW8_WrPlcPn& operator=(const WW8_WrPlcPn&); public: - WW8_WrPlcPn( SwWW8Writer& rWrt, ePLCFT ePl, WW8_FC nStartFc ); + WW8_WrPlcPn( WW8Export& rWrt, ePLCFT ePl, WW8_FC nStartFc ); ~WW8_WrPlcPn(); void AppendFkpEntry(WW8_FC nEndFc,short nVarLen = 0,const BYTE* pSprms = 0); void WriteFkps(); @@ -881,7 +1243,7 @@ public: WW8_WrPlcFld( USHORT nStructSz, BYTE nTTyp ) : WW8_WrPlc1( nStructSz ), nTxtTyp( nTTyp ), nResults(0) {} - bool Write( SwWW8Writer& rWrt ); + bool Write( WW8Export& rWrt ); void ResultAdded() { ++nResults; } USHORT ResultCount() const { return nResults; } }; @@ -895,7 +1257,7 @@ private: public: WW8_WrMagicTable() : WW8_WrPlc1( 4 ) {Append(0,0);} void Append( WW8_CP nCp, ULONG nData ); - bool Write(SwWW8Writer& rWrt); + bool Write( WW8Export& rWrt ); }; class GraphicDetails @@ -924,7 +1286,9 @@ public: class SwWW8WrGrf { private: - SwWW8Writer& rWrt; // SwWW8Writer fuer Zugriff auf die Vars + /// for access to the variables + WW8Export& rWrt; + std::vector<GraphicDetails> maDetails; typedef std::vector<GraphicDetails>::iterator myiter; USHORT mnIdx; // Index in File-Positionen @@ -940,102 +1304,76 @@ private: SwWW8WrGrf(const SwWW8WrGrf&); SwWW8WrGrf& operator=(const SwWW8WrGrf&); public: - SwWW8WrGrf(SwWW8Writer& rW) : rWrt(rW), mnIdx(0) {} + SwWW8WrGrf( WW8Export& rW ) : rWrt( rW ), mnIdx( 0 ) {} void Insert(const sw::Frame &rFly); void Write(); ULONG GetFPos() { return (mnIdx < maDetails.size()) ? maDetails[mnIdx++].mnPos : 0; } }; -// The class WW8_AttrIter is a helper class to build the Fkp.chpx. This -// class may be overloaded for output the SwTxtAttrs and the -// EditEngineTxtAttrs. -class WW8_AttrIter +/** The class MSWordAttrIter is a helper class to build the Fkp.chpx. + This class may be overloaded for output the SwTxtAttrs and the + EditEngineTxtAttrs. +*/ +class MSWordAttrIter { private: - WW8_AttrIter* pOld; + MSWordAttrIter* pOld; //No copying - WW8_AttrIter(const WW8_AttrIter&); - WW8_AttrIter& operator=(const WW8_AttrIter&); + MSWordAttrIter(const MSWordAttrIter&); + MSWordAttrIter& operator=(const MSWordAttrIter&); protected: - SwWW8Writer& rWrt; + MSWordExportBase& m_rExport; public: - WW8_AttrIter( SwWW8Writer& rWrt ); - virtual ~WW8_AttrIter(); + MSWordAttrIter( MSWordExportBase& rExport ); + virtual ~MSWordAttrIter(); virtual const SfxPoolItem* HasTextItem( USHORT nWhich ) const = 0; virtual const SfxPoolItem& GetItem( USHORT nWhich ) const = 0; - void StartURL(const String &rUrl, const String &rTarget); - void EndURL(); }; -class WW8WrtStyle +/// Class to collect and output the styles table. +class MSWordStyles { - SwWW8Writer& rWrt; + MSWordExportBase& m_rExport; SwFmt** pFmtA; - USHORT nPOPosStdLen1, nPOPosStdLen2; USHORT nUsedSlots; - void BuildStyleTab(); - void BuildUpx(const SwFmt* pFmt, bool bPap, USHORT nPos, - bool bInsDefCharSiz); - USHORT Build_GetWWSlot( const SwFmt& rFmt ); - USHORT GetWWId( const SwFmt& rFmt ) const; - void Set1StyleDefaults(const SwFmt& rFmt, bool bPap); - void Out1Style( SwFmt* pFmt, USHORT nPos ); + /// Create the style table, called from the constructor. + void BuildStylesTable(); - void WriteStyle( SvStream& rStrm ); - void SkipOdd(); - void BuildStd(const String& rName, bool bPapFmt, short nWwBase, - short nWwNext, USHORT nWwId); - //No copying - WW8WrtStyle(const WW8WrtStyle&); - WW8WrtStyle& operator=(const WW8WrtStyle&); -public: - WW8WrtStyle( SwWW8Writer& rWr ); - ~WW8WrtStyle(); + /// Get slot number during building the style table. + USHORT BuildGetSlot( const SwFmt& rFmt ); - void OutStyleTab(); - USHORT Sty_GetWWSlot( const SwFmt& rFmt ) const; - SwFmt* GetSwFmt(){return (*pFmtA);} -}; + /// Return information about one style. + void GetStyleData( SwFmt* pFmt, bool& bFmtColl, USHORT& nBase, USHORT& nNext ); -class WW8SaveData -{ -private: - //No copying - WW8SaveData(const WW8SaveData&); - WW8SaveData& operator=(const WW8SaveData &); -public: - SwWW8Writer& rWrt; - Point* pOldFlyOffset; - RndStdIds eOldAnchorType; - WW8Bytes* pOOld; - SwPaM* pOldPam, *pOldEnd; - const sw::Frame* pOldFlyFmt; - const SwPageDesc* pOldPageDesc; + /// Outputs attributes of one style. + void WriteProperties( const SwFmt* pFmt, bool bPap, USHORT nPos, bool bInsDefCharSiz ); - BYTE bOldWriteAll : 1; - BYTE bOldOutTable : 1; - BYTE bOldIsInTable: 1; - BYTE bOldFlyFrmAttrs : 1; - BYTE bOldStartTOX : 1; - BYTE bOldInWriteTOX : 1; - // bOutPageDesc muss nicht gesichert werden, da es nur nicht waehrend der - // Ausgabe von Spezial-Texten veraendert wird. + USHORT GetWWId( const SwFmt& rFmt ) const; - WW8SaveData( SwWW8Writer&, ULONG nStt, ULONG nEnd ); - ~WW8SaveData(); -}; + void SetStyleDefaults( const SwFmt& rFmt, bool bPap ); + + /// Outputs one style - called (in a loop) from OutputStylesTable(). + void OutputStyle( SwFmt* pFmt, USHORT nPos ); + + // No copying + MSWordStyles( const MSWordStyles& ); + MSWordStyles& operator=( const MSWordStyles& ); -// einige halb-interne Funktions-Deklarationen fuer die Node-Tabelle +public: + MSWordStyles( MSWordExportBase& rExport ); + ~MSWordStyles(); + + /// Output the styles table. + void OutputStylesTable(); -Writer& OutWW8_SwGrfNode( Writer& rWrt, SwCntntNode& rNode ); -Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ); -Writer& OutWW8_SwSectionNode(Writer& rWrt, SwSectionNode& rSectionNode ); + /// Get id of the style (rFmt). + USHORT GetSlot( const SwFmt& rFmt ) const; -Writer& OutWW8_SwFmtHoriOrient( Writer& rWrt, const SfxPoolItem& rHt ); -Writer& OutWW8_SwFmtVertOrient( Writer& rWrt, const SfxPoolItem& rHt ); + SwFmt* GetSwFmt() { return (*pFmtA); } +}; sal_Int16 GetWordFirstLineOffset(const SwNumFmt &rFmt); //A bit of a bag on the side for now @@ -1052,12 +1390,20 @@ public: WW8SHDLong() : m_cvFore(0), m_cvBack(0), m_ipat(0) {} virtual ~WW8SHDLong() {} - void Write(SwWW8Writer & rWriter); + void Write(WW8Export & rExport); void setCvFore(sal_uInt32 cvFore) { m_cvFore = cvFore; } void setCvBack(sal_uInt32 cvBack) { m_cvBack = cvBack; } void setIPat(sal_uInt16 ipat) { m_ipat = ipat; } }; +/// For the output of sections. +struct WW8_PdAttrDesc +{ + BYTE* pData; + USHORT nLen; + WW8_FC nSepxFcPos; +}; + #endif // _WRTWW8_HXX /* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/wrtww8gr.cxx b/sw/source/filter/ww8/wrtww8gr.cxx index ba6c8a44a260..aaafe0ee49fc 100644 --- a/sw/source/filter/ww8/wrtww8gr.cxx +++ b/sw/source/filter/ww8/wrtww8gr.cxx @@ -42,13 +42,8 @@ #include <svtools/embedhlp.hxx> -#ifndef _VIRDEV_HXX //autogen #include <vcl/virdev.hxx> -#endif -#ifndef _APP_HXX //autogen #include <vcl/svapp.hxx> -#endif - #include <hintids.hxx> #include <svx/boxitem.hxx> @@ -70,6 +65,8 @@ #include <fmtfsize.hxx> #include <fmtornt.hxx> +#include <writerfilter/doctok/sprmids.hxx> + #include <doc.hxx> #include "writerhelper.hxx" #include "writerwordglue.hxx" @@ -98,20 +95,20 @@ using namespace nsFieldFlags; // in der Graf-Klasse der GrfNode-Ptr gemerkt ( fuers spaetere Ausgeben der // Grafiken und Patchen der PicLocFc-Attribute ) -Writer& OutWW8_SwGrfNode( Writer& rWrt, SwCntntNode& /*rNode*/ ) +void WW8Export::OutputGrfNode( const SwGrfNode& /*rNode*/ ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - ASSERT(rWW8Wrt.mpParentFrame, "frame not set!"); - if (rWW8Wrt.mpParentFrame) +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "WW8Export::OutputGrfNode( const SwGrfNode& )\n" ); +#endif + ASSERT( mpParentFrame, "frame not set!" ); + if ( mpParentFrame ) { - rWW8Wrt.OutGrf(*rWW8Wrt.mpParentFrame); - rWW8Wrt.pFib->fHasPic = 1; + OutGrf( *mpParentFrame ); + pFib->fHasPic = 1; } - - return rWrt; } -bool SwWW8Writer::TestOleNeedsGraphic(const SwAttrSet& rSet, +bool WW8Export::TestOleNeedsGraphic(const SwAttrSet& rSet, SvStorageRef xOleStg, SvStorageRef xObjStg, String &rStorageName, SwOLENode *pOLENd) { @@ -220,9 +217,11 @@ bool SwWW8Writer::TestOleNeedsGraphic(const SwAttrSet& rSet, #endif } -Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ) +void WW8Export::OutputOLENode( const SwOLENode& rOLENode ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "WW8Export::OutputOLENode( const SwOLENode& rOLENode )\n" ); +#endif BYTE *pSpecOLE; BYTE *pDataAdr; short nSize; @@ -237,7 +236,7 @@ Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ) 118, 1 // sprmCFObj }; - if( rWW8Wrt.bWrtWW8 ) + if ( bWrtWW8 ) { pSpecOLE = aSpecOLE_WW8; nSize = sizeof( aSpecOLE_WW8 ); @@ -248,15 +247,14 @@ Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ) nSize = sizeof( aSpecOLE_WW6 ); } pDataAdr = pSpecOLE + 2; //WW6 sprm is 1 but has 1 byte len as well. - SwOLENode *pOLENd = rNode.GetOLENode(); - SvStorageRef xObjStg = rWW8Wrt.GetStorage().OpenSotStorage( + SvStorageRef xObjStg = GetWriter().GetStorage().OpenSotStorage( CREATE_CONST_ASC(SL::aObjectPool), STREAM_READWRITE | STREAM_SHARE_DENYALL ); if( xObjStg.Is() ) { - uno::Reference < embed::XEmbeddedObject > xObj(pOLENd->GetOLEObj().GetOleRef()); + uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef()); if( xObj.is() ) { embed::XEmbeddedObject *pObj = xObj.get(); @@ -265,7 +263,7 @@ Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ) WW8OleMap *pMap = new WW8OleMap(nPictureId); bool bDuplicate = false; - WW8OleMaps &rOleMap = rWW8Wrt.GetOLEMap(); + WW8OleMaps &rOleMap = GetOLEMap(); USHORT nPos; if ( rOleMap.Seek_Entry(pMap, &nPos) ) { @@ -287,9 +285,9 @@ Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ) */ if (!bDuplicate) { - sal_Int64 nAspect = pOLENd->GetAspect(); + sal_Int64 nAspect = rOLENode.GetAspect(); svt::EmbeddedObjectRef aObjRef( xObj, nAspect ); - rWW8Wrt.GetOLEExp().ExportOLEObject( aObjRef, *xOleStg ); + GetOLEExp().ExportOLEObject( aObjRef, *xOleStg ); if ( nAspect == embed::Aspects::MSOLE_ICON ) { ::rtl::OUString aObjInfo( RTL_CONSTASCII_USTRINGPARAM( "\3ObjInfo" ) ); @@ -312,10 +310,10 @@ Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ) sServer += xOleStg->GetUserName(); sServer += ' '; - rWW8Wrt.OutField(0, ww::eEMBED, sServer, WRITEFIELD_START | + OutputField(0, ww::eEMBED, sServer, WRITEFIELD_START | WRITEFIELD_CMD_START | WRITEFIELD_CMD_END); - rWW8Wrt.pChpPlc->AppendFkpEntry( rWrt.Strm().Tell(), + pChpPlc->AppendFkpEntry( Strm().Tell(), nSize, pSpecOLE ); bool bEndCR = true; @@ -330,22 +328,22 @@ Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ) */ bool bGraphicNeeded = false; - if (rWW8Wrt.mpParentFrame) + if (mpParentFrame) { bGraphicNeeded = true; - if (rWW8Wrt.mpParentFrame->IsInline()) + if (mpParentFrame->IsInline()) { const SwAttrSet& rSet = - rWW8Wrt.mpParentFrame->GetFrmFmt().GetAttrSet(); + mpParentFrame->GetFrmFmt().GetAttrSet(); bEndCR = false; - bGraphicNeeded = rWW8Wrt.TestOleNeedsGraphic(rSet, - xOleStg, xObjStg, sStorageName, pOLENd); + bGraphicNeeded = TestOleNeedsGraphic(rSet, + xOleStg, xObjStg, sStorageName, const_cast<SwOLENode*>(&rOLENode)); } } if (!bGraphicNeeded) - rWW8Wrt.WriteChar(0x1); + WriteChar(0x1); else { /* @@ -355,26 +353,25 @@ Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode ) has no place to find the dimensions of the ole object, and will not be able to draw it */ - rWW8Wrt.OutGrf(*rWW8Wrt.mpParentFrame); + OutGrf(*mpParentFrame); } - rWW8Wrt.OutField(0, ww::eEMBED, aEmptyStr, + OutputField(0, ww::eEMBED, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE); if (bEndCR) //No newline in inline case - rWW8Wrt.WriteCR(); + WriteCR(); } } } - return rWrt; } -void SwWW8Writer::OutGrf(const sw::Frame &rFrame) +void WW8Export::OutGrf(const sw::Frame &rFrame) { // GrfNode fuer spaeteres rausschreiben der Grafik merken pGrf->Insert(rFrame); - pChpPlc->AppendFkpEntry( pStrm->Tell(), pO->Count(), pO->GetData() ); + pChpPlc->AppendFkpEntry( Strm().Tell(), pO->Count(), pO->GetData() ); pO->Remove( 0, pO->Count() ); // leeren // --> OD 2007-06-06 #i29408# @@ -395,7 +392,7 @@ void SwWW8Writer::OutGrf(const sw::Frame &rFrame) } sStr.APPEND_CONST_ASC("\" \\d"); - OutField( 0, ww::eINCLUDEPICTURE, sStr, + OutputField( 0, ww::eINCLUDEPICTURE, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START | WRITEFIELD_CMD_END ); } // <-- @@ -431,7 +428,7 @@ void SwWW8Writer::OutGrf(const sw::Frame &rFrame) nHeight-=nFontHeight/20; if (bWrtWW8) - Set_UInt16( pArr, 0x4845 ); + Set_UInt16( pArr, NS_sprm::LN_CHpsPos ); else Set_UInt8( pArr, 101 ); Set_UInt16( pArr, -((INT16)nHeight)); @@ -448,7 +445,7 @@ void SwWW8Writer::OutGrf(const sw::Frame &rFrame) // sprmCPicLocation if( bWrtWW8 ) - Set_UInt16( pArr, 0x6a03 ); + Set_UInt16( pArr, NS_sprm::LN_CPicLocation ); else { Set_UInt8( pArr, 68 ); @@ -461,7 +458,7 @@ void SwWW8Writer::OutGrf(const sw::Frame &rFrame) static BYTE nAttrMagicIdx = 0; --pArr; Set_UInt8( pArr, nAttrMagicIdx++ ); - pChpPlc->AppendFkpEntry( pStrm->Tell(), static_cast< short >(pArr - aArr), aArr ); + pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr ); // --> OD 2007-04-23 #i75464# // Check, if graphic isn't exported as-character anchored. @@ -479,17 +476,17 @@ void SwWW8Writer::OutGrf(const sw::Frame &rFrame) bool bOldGrf = bOutGrf; bOutGrf = true; - Out_SwFmt(rFrame.GetFrmFmt(), false, false, true); // Fly-Attrs + OutputFormat( rFrame.GetFrmFmt(), false, false, true ); // Fly-Attrs bOutGrf = bOldGrf; - pPapPlc->AppendFkpEntry( pStrm->Tell(), pO->Count(), pO->GetData() ); + pPapPlc->AppendFkpEntry( Strm().Tell(), pO->Count(), pO->GetData() ); pO->Remove( 0, pO->Count() ); // leeren } // --> OD 2007-06-06 #i29408# // linked, as-character anchored graphics have to be exported as fields. else if ( pGrfNd && pGrfNd->IsLinkedFile() ) { - OutField( 0, ww::eINCLUDEPICTURE, String(), WRITEFIELD_CLOSE ); + OutputField( 0, ww::eINCLUDEPICTURE, String(), WRITEFIELD_CLOSE ); } // <-- } diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index b3e13520a14d..2b8c24555989 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -33,23 +33,19 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ /* - * Dieses File enthaelt alle Ausgabe-Funktionen des WW8-Writers; - * fuer alle Nodes, Attribute, Formate und Chars. + * This file contains methods for the WW8 output + * (nodes, attributes, formats und chars). */ - #include <hintids.hxx> -#ifndef _APP_HXX //autogen #include <vcl/svapp.hxx> -#endif #include <vcl/salbtype.hxx> #include <svtools/zformat.hxx> #include <svtools/itemiter.hxx> +#include <svtools/whiter.hxx> #include <svx/fontitem.hxx> -#ifndef _SVX_TSTPITEM_HXX //autogen #include <svx/tstpitem.hxx> -#endif #include <svx/adjitem.hxx> #include <svx/spltitem.hxx> #include <svx/widwitem.hxx> @@ -104,15 +100,15 @@ #include <txtfld.hxx> #include <txtftn.hxx> #include <poolfmt.hxx> -#include <doc.hxx> // Doc fuer Fussnoten +#include <doc.hxx> // Doc for footnotes #include <pam.hxx> #include <paratr.hxx> -#include <fldbas.hxx> // fuer SwField ... -#include <docufld.hxx> // fuer SwField ... +#include <fldbas.hxx> // for SwField +#include <docufld.hxx> // for SwField #include <expfld.hxx> -#include <pagedesc.hxx> // fuer SwPageDesc... -#include <flddat.hxx> // fuer Datum-Felder -#include <ndtxt.hxx> // fuer Numrules +#include <pagedesc.hxx> // for SwPageDesc +#include <flddat.hxx> // for Date fields +#include <ndtxt.hxx> // for Numrules #include <fmthbsh.hxx> #include <swrect.hxx> #include <reffld.hxx> @@ -124,15 +120,15 @@ #include <tox.hxx> #include <fmtftntx.hxx> #include <breakit.hxx> -#ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_ #include <com/sun/star/i18n/ScriptType.hdl> -#endif #include <unotools/localedatawrapper.hxx> #include <tgrditem.hxx> #include <flddropdown.hxx> #include <chpfld.hxx> #include <fmthdft.hxx> +#include <writerfilter/doctok/sprmids.hxx> + #if OSL_DEBUG_LEVEL > 1 # include <fmtcntnt.hxx> #endif @@ -140,6 +136,7 @@ #include "writerwordglue.hxx" #include "wrtww8.hxx" #include "ww8par.hxx" +#include "ww8attributeoutput.hxx" #include "fields.hxx" #include <vcl/outdev.hxx> #include <i18npool/mslangid.hxx> @@ -148,7 +145,6 @@ using namespace ::com::sun::star; using namespace nsFieldFlags; using namespace nsSwDocInfoSubType; - /* * um nicht immer wieder nach einem Update festzustellen, das irgendwelche * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle @@ -175,30 +171,17 @@ using namespace nsSwDocInfoSubType; using namespace sw::util; using namespace sw::types; -//------------------------------------------------------------ -// Forward-Declarationen -//------------------------------------------------------------ -static Writer& OutWW8_SwFmtBreak( Writer& rWrt, const SfxPoolItem& rHt ); -static Writer& OutWW8_SwNumRuleItem( Writer& rWrt, const SfxPoolItem& rHt ); -/* -Sadly word does not have two different sizes for asian font size and western -font size, it has two different fonts, but not sizes, so we have to use our -guess as to the script used and disable the export of one type. The same -occurs for font weight and posture (bold and italic) - -In addition WW7- has only one character language identifier while WW8+ has two -*/ -bool SwWW8Writer::CollapseScriptsforWordOk(USHORT nScript, USHORT nWhich) +bool WW8Export::CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich ) { bool bRet = true; - if (nScript == i18n::ScriptType::ASIAN) + if ( nScript == i18n::ScriptType::ASIAN ) { //for asian in ww8, there is only one fontsize //and one fontstyle (posture/weight) for ww6 //there is the additional problem that there //is only one font setting for all three scripts - switch (nWhich) + switch ( nWhich ) { case RES_CHRATR_FONTSIZE: case RES_CHRATR_POSTURE: @@ -217,14 +200,14 @@ bool SwWW8Writer::CollapseScriptsforWordOk(USHORT nScript, USHORT nWhich) break; } } - else if (nScript == i18n::ScriptType::COMPLEX) + else if ( nScript == i18n::ScriptType::COMPLEX ) { //Complex is ok in ww8, but for ww6 there is only //one font, one fontsize, one fontsize (weight/posture) //and only one language - if (bWrtWW8 == 0) + if ( bWrtWW8 == 0 ) { - switch (nWhich) + switch ( nWhich ) { case RES_CHRATR_CJK_FONT: case RES_CHRATR_CJK_FONTSIZE: @@ -249,7 +232,7 @@ bool SwWW8Writer::CollapseScriptsforWordOk(USHORT nScript, USHORT nWhich) //and one fontstyle (posture/weight) for ww6 //there is the additional problem that there //is only one font setting for all three scripts - switch (nWhich) + switch ( nWhich ) { case RES_CHRATR_CJK_FONTSIZE: case RES_CHRATR_CJK_POSTURE: @@ -262,7 +245,7 @@ bool SwWW8Writer::CollapseScriptsforWordOk(USHORT nScript, USHORT nWhich) case RES_CHRATR_CTL_LANGUAGE: case RES_CHRATR_CTL_POSTURE: case RES_CHRATR_CTL_WEIGHT: - if (bWrtWW8 == 0) + if ( bWrtWW8 == 0 ) bRet = false; default: break; @@ -275,19 +258,16 @@ bool SwWW8Writer::CollapseScriptsforWordOk(USHORT nScript, USHORT nWhich) // Hilfsroutinen fuer Styles //------------------------------------------------------------ -void SwWW8Writer::ExportPoolItemsToCHP(sw::PoolItems &rItems, USHORT nScript) +void MSWordExportBase::ExportPoolItemsToCHP( sw::PoolItems &rItems, USHORT nScript ) { sw::cPoolItemIter aEnd = rItems.end(); - for (sw::cPoolItemIter aI = rItems.begin(); aI != aEnd; ++aI) + for ( sw::cPoolItemIter aI = rItems.begin(); aI != aEnd; ++aI ) { const SfxPoolItem *pItem = aI->second; USHORT nWhich = pItem->Which(); - if (!isCHRATR(nWhich) && !isTXTATR(nWhich)) - continue; - if (FnAttrOut pOut = aWW8AttrFnTab[nWhich - RES_CHRATR_BEGIN]) + if ( ( isCHRATR( nWhich ) || isTXTATR( nWhich ) ) && CollapseScriptsforWordOk( nScript, nWhich ) ) { - if (SwWW8Writer::CollapseScriptsforWordOk(nScript, nWhich)) - (*pOut)(*this, *pItem); + AttrOutput().OutputItem( *pItem ); } } } @@ -297,71 +277,62 @@ void SwWW8Writer::ExportPoolItemsToCHP(sw::PoolItems &rItems, USHORT nScript) * - gebe die Attribute aus; ohne Parents! */ -void SwWW8Writer::Out_SfxItemSet(const SfxItemSet& rSet, bool bPapFmt, - bool bChpFmt, USHORT nScript) +void MSWordExportBase::OutputItemSet( const SfxItemSet& rSet, bool bPapFmt, bool bChpFmt, USHORT nScript ) { - if (rSet.Count()) + if ( rSet.Count() ) { const SfxPoolItem* pItem; - FnAttrOut pOut; - pISet = &rSet; // fuer Doppel-Attribute - //If frame dir is set, but not adjust, then force adjust as well - if (bPapFmt && SFX_ITEM_SET == rSet.GetItemState(RES_FRAMEDIR, false)) + // If frame dir is set, but not adjust, then force adjust as well + if ( bPapFmt && SFX_ITEM_SET == rSet.GetItemState( RES_FRAMEDIR, false ) ) { - //No explicit adjust set ? - if (SFX_ITEM_SET != rSet.GetItemState(RES_PARATR_ADJUST, false)) + // No explicit adjust set ? + if ( SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_ADJUST, false ) ) { - if (0 != (pItem = rSet.GetItem(RES_PARATR_ADJUST))) + if ( 0 != ( pItem = rSet.GetItem( RES_PARATR_ADJUST ) ) ) { // then set the adjust used by the parent format - pOut = aWW8AttrFnTab[ static_cast< USHORT >(RES_PARATR_ADJUST) - RES_CHRATR_BEGIN]; - (*pOut)( *this, *pItem ); + AttrOutput().OutputItem( *pItem ); } } } - if (bPapFmt && SFX_ITEM_SET == rSet.GetItemState(RES_PARATR_NUMRULE, - false, &pItem)) + if ( bPapFmt && SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, false, &pItem ) ) { - pOut = aWW8AttrFnTab[ static_cast< USHORT >(RES_PARATR_NUMRULE) - RES_CHRATR_BEGIN ]; - (*pOut)( *this, *pItem ); + AttrOutput().OutputItem( *pItem ); + // switch off the numerbering? - if( !((SwNumRuleItem*)pItem)->GetValue().Len() && SFX_ITEM_SET - != rSet.GetItemState( RES_LR_SPACE, false) && SFX_ITEM_SET - == rSet.GetItemState( RES_LR_SPACE, true, &pItem ) ) + if ( !( (SwNumRuleItem*)pItem )->GetValue().Len() && + SFX_ITEM_SET != rSet.GetItemState( RES_LR_SPACE, false) && + SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, true, &pItem ) ) { // the set the LR-Space of the parentformat! - pOut = aWW8AttrFnTab[ static_cast< USHORT >(RES_LR_SPACE) - RES_CHRATR_BEGIN ]; - (*pOut)( *this, *pItem ); + AttrOutput().OutputItem( *pItem ); } } sw::PoolItems aItems; - GetPoolItems(rSet, aItems); - if (bChpFmt) + GetPoolItems( rSet, aItems ); + if ( bChpFmt ) ExportPoolItemsToCHP(aItems, nScript); - if (bPapFmt) + if ( bPapFmt ) { sw::cPoolItemIter aEnd = aItems.end(); - for (sw::cPoolItemIter aI = aItems.begin(); aI != aEnd; ++aI) + for ( sw::cPoolItemIter aI = aItems.begin(); aI != aEnd; ++aI ) { pItem = aI->second; USHORT nWhich = pItem->Which(); - if (nWhich < RES_PARATR_BEGIN || nWhich >= RES_FRMATR_END || nWhich == RES_PARATR_NUMRULE) - continue; - pOut = aWW8AttrFnTab[nWhich - RES_CHRATR_BEGIN]; - if( 0 != pOut ) - (*pOut)(*this, *pItem); + if ( nWhich >= RES_PARATR_BEGIN && nWhich < RES_FRMATR_END && nWhich != RES_PARATR_NUMRULE) + AttrOutput().OutputItem( *pItem ); } } pISet = 0; // fuer Doppel-Attribute } } -void SwWW8Writer::GatherChapterFields() +void MSWordExportBase::GatherChapterFields() { //If the header/footer contains a chapter field SwClientIter aIter(*pDoc->GetSysFldType(RES_CHAPTERFLD)); @@ -378,20 +349,20 @@ void SwWW8Writer::GatherChapterFields() } } -bool SwWW8Writer::CntntContainsChapterField(const SwFmtCntnt &rCntnt) const +bool MSWordExportBase::CntntContainsChapterField(const SwFmtCntnt &rCntnt) const { bool bRet = false; - if (const SwNodeIndex* pSttIdx = rCntnt.GetCntntIdx()) + if ( const SwNodeIndex* pSttIdx = rCntnt.GetCntntIdx() ) { - SwNodeIndex aIdx(*pSttIdx, 1); - SwNodeIndex aEnd(*pSttIdx->GetNode().EndOfSectionNode()); + SwNodeIndex aIdx( *pSttIdx, 1 ); + SwNodeIndex aEnd( *pSttIdx->GetNode().EndOfSectionNode() ); ULONG nStart = aIdx.GetIndex(); ULONG nEnd = aEnd.GetIndex(); //If the header/footer contains a chapter field mycCFIter aIEnd = maChapterFieldLocs.end(); - for (mycCFIter aI = maChapterFieldLocs.begin(); aI != aIEnd; ++aI) + for ( mycCFIter aI = maChapterFieldLocs.begin(); aI != aIEnd; ++aI ) { - if ((nStart <= *aI) && (*aI <= nEnd)) + if ( ( nStart <= *aI ) && ( *aI <= nEnd ) ) { bRet = true; break; @@ -401,22 +372,25 @@ bool SwWW8Writer::CntntContainsChapterField(const SwFmtCntnt &rCntnt) const return bRet; } -bool SwWW8Writer::FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const +bool MSWordExportBase::FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const { - if (maChapterFieldLocs.empty()) + if ( maChapterFieldLocs.empty() ) return false; - bool bRet = false; const SwFrmFmt *pFmt = 0; - if (0 != (pFmt = rFmt.GetHeader().GetHeaderFmt())) - bRet = CntntContainsChapterField(pFmt->GetCntnt()); - if (!bRet && 0 != (pFmt = rFmt.GetFooter().GetFooterFmt())) - bRet = CntntContainsChapterField(pFmt->GetCntnt()); - return bRet; + pFmt = rFmt.GetHeader().GetHeaderFmt(); + if ( pFmt && CntntContainsChapterField( pFmt->GetCntnt() ) ) + return true; + + pFmt = rFmt.GetFooter().GetFooterFmt(); + if ( pFmt && CntntContainsChapterField( pFmt->GetCntnt() ) ) + return true; + + return false; } -bool SwWW8Writer::SetAktPageDescFromNode(const SwNode &rNd) +bool MSWordExportBase::SetAktPageDescFromNode(const SwNode &rNd) { bool bNewPageDesc = false; const SwPageDesc* pCurrent = SwPageDesc::GetPageDescOfNode(rNd); @@ -453,13 +427,9 @@ bool SwWW8Writer::SetAktPageDescFromNode(const SwNode &rNd) // Es duerfen nur Funktionen gerufen werden, die nicht in den // Ausgabebereich pO schreiben, da dieser nur einmal fuer CHP und PAP existiert // und damit im falschen landen wuerden. -void SwWW8Writer::Out_SfxBreakItems(const SfxItemSet *pSet, const SwNode& rNd) +void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode& rNd ) { - bool bAllowOutputPageDesc = false; - if (!bStyDef && !bOutKF && !bInWriteEscher && !bOutPageDescs) - bAllowOutputPageDesc = true; - - if (!bAllowOutputPageDesc) + if ( bStyDef || bOutKF || bInWriteEscher || bOutPageDescs ) return; bBreakBefore = true; @@ -474,17 +444,17 @@ void SwWW8Writer::Out_SfxBreakItems(const SfxItemSet *pSet, const SwNode& rNd) //section. bool bBreakSet = false; - if (pSet && pSet->Count()) + if ( pSet && pSet->Count() ) { - if (SFX_ITEM_SET == pSet->GetItemState(RES_PAGEDESC, false, &pItem) - && ((SwFmtPageDesc*)pItem)->GetRegisteredIn()) + if ( SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, false, &pItem ) + && ( (SwFmtPageDesc*)pItem )->GetRegisteredIn() ) { bBreakSet = true; bNewPageDesc = true; pPgDesc = (const SwFmtPageDesc*)pItem; pAktPageDesc = pPgDesc->GetPageDesc(); } - else if (SFX_ITEM_SET == pSet->GetItemState(RES_BREAK, false, &pItem)) + else if ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, false, &pItem ) ) { // --> FME 2007-05-30 #146867# Word does not like hard break attributes in some table cells bool bRemoveHardBreakInsideTable = false; @@ -521,7 +491,7 @@ void SwWW8Writer::Out_SfxBreakItems(const SfxItemSet *pSet, const SwNode& rNd) done when it happens when we get a new pagedesc because we overflow from the first page style. */ - if (pAktPageDesc) + if ( pAktPageDesc ) { // --> OD 2007-05-30 #i76301# // assure that there is a page break before set at the node. @@ -529,12 +499,12 @@ void SwWW8Writer::Out_SfxBreakItems(const SfxItemSet *pSet, const SwNode& rNd) if ( pBreak && pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE ) { - bNewPageDesc = SetAktPageDescFromNode(rNd); + bNewPageDesc = SetAktPageDescFromNode( rNd ); } // <-- } - if (!bNewPageDesc) - OutWW8_SwFmtBreak( *this, *pItem ); + if ( !bNewPageDesc ) + AttrOutput().OutputItem( *pItem ); } } } @@ -547,72 +517,41 @@ void SwWW8Writer::Out_SfxBreakItems(const SfxItemSet *pSet, const SwNode& rNd) that moves onto a new page because of layout, but that would be insane. */ bool bHackInBreak = false; - if (!bBreakSet) + if ( !bBreakSet ) { - if (const SwCntntNode *pNd = rNd.GetCntntNode()) + if ( const SwCntntNode *pNd = rNd.GetCntntNode() ) { const SvxFmtBreakItem &rBreak = - ItemGet<SvxFmtBreakItem>(*pNd, RES_BREAK); - if (rBreak.GetBreak() == SVX_BREAK_PAGE_BEFORE) + ItemGet<SvxFmtBreakItem>( *pNd, RES_BREAK ); + if ( rBreak.GetBreak() == SVX_BREAK_PAGE_BEFORE ) bHackInBreak = true; else { // Even a pagedesc item is set, the break item can be set 'NONE', // but a pagedesc item is an implicit page break before... const SwFmtPageDesc &rPageDesc = ItemGet<SwFmtPageDesc>( *pNd, RES_PAGEDESC ); - if( rPageDesc.GetRegisteredIn() ) + if ( rPageDesc.GetRegisteredIn() ) bHackInBreak = true; } } } - if (bHackInBreak) + if ( bHackInBreak ) { - ASSERT(pAktPageDesc, "should not be possible"); - if (pAktPageDesc) - bNewPageDesc = SetAktPageDescFromNode(rNd); + ASSERT( pAktPageDesc, "should not be possible" ); + if ( pAktPageDesc ) + bNewPageDesc = SetAktPageDescFromNode( rNd ); } - if (bNewPageDesc && pAktPageDesc) + if ( bNewPageDesc && pAktPageDesc ) { - // --> OD 2007-05-29 #i76300# - // code moved code to method <SwWW8Writer::PrepareNewPageDesc(..)> -// // Die PageDescs werden beim Auftreten von PageDesc-Attributen nur in -// // WW8Writer::pSepx mit der entsprechenden Position eingetragen. Das -// // Aufbauen und die Ausgabe der am PageDesc haengenden Attribute und -// // Kopf/Fusszeilen passiert nach dem Haupttext und seinen Attributen. - -// ULONG nFcPos = ReplaceCr(0x0c); // Page/Section-Break - -// const SwSectionFmt *pFmt = 0; -// const SwSectionNode* pSect = rNd.FindSectionNode(); -// if (pSect && CONTENT_SECTION == pSect->GetSection().GetType()) -// pFmt = pSect->GetSection().GetFmt(); - -// // tatsaechlich wird hier NOCH NICHTS ausgegeben, sondern -// // nur die Merk-Arrays aCps, aSects entsprechend ergaenzt -// if (nFcPos) -// { -// const SwFmtLineNumber *pNItem = 0; -// if (pSet) -// pNItem = &(ItemGet<SwFmtLineNumber>(*pSet,RES_LINENUMBER)); -// else if (const SwCntntNode *pNd = rNd.GetCntntNode()) -// pNItem = &(ItemGet<SwFmtLineNumber>(*pNd,RES_LINENUMBER)); -// ULONG nLnNm = pNItem ? pNItem->GetStartValue() : 0; - -// if (pPgDesc) -// pSepx->AppendSep(Fc2Cp(nFcPos), *pPgDesc, rNd, pFmt, nLnNm); -// else -// pSepx->AppendSep(Fc2Cp(nFcPos), pAktPageDesc, rNd, pFmt, nLnNm); -// } PrepareNewPageDesc( pSet, rNd, pPgDesc, pAktPageDesc ); } bBreakBefore = false; } // --> OD 2007-05-29 #i76300# -bool SwWW8Writer::Out_FollowPageDesc( const SfxItemSet* pSet, - const SwTxtNode* pNd ) +bool MSWordExportBase::OutputFollowPageDesc( const SfxItemSet* pSet, const SwTxtNode* pNd ) { bool bRet = false; @@ -627,8 +566,35 @@ bool SwWW8Writer::Out_FollowPageDesc( const SfxItemSet* pSet, return bRet; } -// initial version by extracting corresponding code from method <SwWW8Writer::Out_SfxBreakItems(..)> -void SwWW8Writer::PrepareNewPageDesc( const SfxItemSet*pSet, +const SwSectionFmt* MSWordExportBase::GetSectionFormat( const SwNode& rNd ) const +{ + const SwSectionFmt* pFmt = NULL; + const SwSectionNode* pSect = rNd.FindSectionNode(); + if ( pSect && + CONTENT_SECTION == pSect->GetSection().GetType() ) + { + pFmt = pSect->GetSection().GetFmt(); + } + + return pFmt; +} + +ULONG MSWordExportBase::GetSectionLineNo( const SfxItemSet* pSet, const SwNode& rNd ) const +{ + const SwFmtLineNumber* pNItem = 0; + if ( pSet ) + { + pNItem = &( ItemGet<SwFmtLineNumber>( *pSet, RES_LINENUMBER ) ); + } + else if ( const SwCntntNode *pNd = rNd.GetCntntNode() ) + { + pNItem = &( ItemGet<SwFmtLineNumber>( *pNd, RES_LINENUMBER ) ); + } + + return pNItem? pNItem->GetStartValue() : 0; +} + +void WW8Export::PrepareNewPageDesc( const SfxItemSet*pSet, const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt, const SwPageDesc* pNewPgDesc ) @@ -638,63 +604,45 @@ void SwWW8Writer::PrepareNewPageDesc( const SfxItemSet*pSet, // Aufbauen und die Ausgabe der am PageDesc haengenden Attribute und // Kopf/Fusszeilen passiert nach dem Haupttext und seinen Attributen. - ULONG nFcPos = ReplaceCr(0x0c); // Page/Section-Break - - const SwSectionFmt* pFmt = 0; - const SwSectionNode* pSect = rNd.FindSectionNode(); - if ( pSect && - CONTENT_SECTION == pSect->GetSection().GetType() ) - { - pFmt = pSect->GetSection().GetFmt(); - } + ULONG nFcPos = ReplaceCr( msword::PageBreak ); // Page/Section-Break // tatsaechlich wird hier NOCH NICHTS ausgegeben, sondern // nur die Merk-Arrays aCps, aSects entsprechend ergaenzt - if ( nFcPos ) - { - const SwFmtLineNumber* pNItem = 0; - if ( pSet ) - { - pNItem = &(ItemGet<SwFmtLineNumber>(*pSet,RES_LINENUMBER)); - } - else if (const SwCntntNode *pNd = rNd.GetCntntNode()) - { - pNItem = &(ItemGet<SwFmtLineNumber>(*pNd,RES_LINENUMBER)); - } - const ULONG nLnNm = pNItem ? pNItem->GetStartValue() : 0; + if ( !nFcPos ) + return; - if ( pNewPgDescFmt ) - { - pSepx->AppendSep(Fc2Cp(nFcPos), *pNewPgDescFmt, rNd, pFmt, nLnNm); - } - else if ( pNewPgDesc ) - { - pSepx->AppendSep(Fc2Cp(nFcPos), pNewPgDesc, rNd, pFmt, nLnNm); - } - else - { - ASSERT( false, "<SwWW8Writer::PrepareNewPageDesc(..)> - misusage: neither page desc format nor page desc provided." ); - } + const SwSectionFmt* pFmt = GetSectionFormat( rNd ); + const ULONG nLnNm = GetSectionLineNo( pSet, rNd ); + + ASSERT( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." ); + + if ( pNewPgDescFmt ) + { + pSepx->AppendSep( Fc2Cp( nFcPos ), *pNewPgDescFmt, rNd, pFmt, nLnNm ); + } + else if ( pNewPgDesc ) + { + pSepx->AppendSep( Fc2Cp( nFcPos ), pNewPgDesc, rNd, pFmt, nLnNm ); } } -// <-- - -void SwWW8Writer::CorrTabStopInSet(SfxItemSet& rSet, USHORT nAbsLeft) +void MSWordExportBase::CorrectTabStopInSet( SfxItemSet& rSet, USHORT nAbsLeft ) { const SvxTabStopItem *pItem = - sw::util::HasItem<SvxTabStopItem>(rSet, RES_PARATR_TABSTOP); + sw::util::HasItem<SvxTabStopItem>( rSet, RES_PARATR_TABSTOP ); - if (pItem) + if ( pItem ) { // dann muss das fuer die Ausgabe korrigiert werden SvxTabStopItem aTStop(*pItem); - for(USHORT nCnt = 0; nCnt < aTStop.Count(); ++nCnt) + for ( USHORT nCnt = 0; nCnt < aTStop.Count(); ++nCnt ) { SvxTabStop& rTab = (SvxTabStop&)aTStop[ nCnt ]; - if( SVX_TAB_ADJUST_DEFAULT != rTab.GetAdjustment() && + if ( SVX_TAB_ADJUST_DEFAULT != rTab.GetAdjustment() && rTab.GetTabPos() >= nAbsLeft ) + { rTab.GetTabPos() -= nAbsLeft; + } else { aTStop.Remove( nCnt ); @@ -705,7 +653,7 @@ void SwWW8Writer::CorrTabStopInSet(SfxItemSet& rSet, USHORT nAbsLeft) } } -BYTE SwWW8Writer::GetNumId( USHORT eNumType ) +BYTE WW8Export::GetNumId( USHORT eNumType ) { BYTE nRet = 0; switch( eNumType ) @@ -726,26 +674,25 @@ BYTE SwWW8Writer::GetNumId( USHORT eNumType ) return nRet; } -void SwWW8Writer::ExportOutlineNumbering(BYTE nLvl, const SwNumFmt &rNFmt, - const SwFmt &rFmt) +void WW8AttributeOutput::OutlineNumbering( BYTE nLvl, const SwNumFmt &rNFmt, const SwFmt &rFmt ) { - if (nLvl >= WW8ListManager::nMaxLevel) + if ( nLvl >= WW8ListManager::nMaxLevel ) nLvl = WW8ListManager::nMaxLevel-1; - if( bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { // write sprmPOutLvl sprmPIlvl and sprmPIlfo - SwWW8Writer::InsUInt16( *pO, 0x2640 ); - pO->Insert( nLvl, pO->Count() ); - SwWW8Writer::InsUInt16( *pO, 0x260a ); - pO->Insert( nLvl, pO->Count() ); - SwWW8Writer::InsUInt16( *pO, 0x460b ); - SwWW8Writer::InsUInt16( *pO, 1 + GetId( - *pDoc->GetOutlineNumRule() ) ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_POutLvl ); + m_rWW8Export.pO->Insert( nLvl, m_rWW8Export.pO->Count() ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlvl ); + m_rWW8Export.pO->Insert( nLvl, m_rWW8Export.pO->Count() ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlfo ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, + 1 + m_rWW8Export.GetId( *m_rWW8Export.pDoc->GetOutlineNumRule() ) ); } else { - Out_SwNumLvl( nLvl ); + m_rWW8Export.Out_SwNumLvl( nLvl ); // --> OD 2008-06-03 #i86652# // if (rNFmt.GetAbsLSpace()) if ( rNFmt.GetPositionAndSpaceMode() == @@ -753,22 +700,25 @@ void SwWW8Writer::ExportOutlineNumbering(BYTE nLvl, const SwNumFmt &rNFmt, rNFmt.GetAbsLSpace() ) // <-- { - SwNumFmt aNumFmt(rNFmt); + SwNumFmt aNumFmt( rNFmt ); const SvxLRSpaceItem& rLR = - ItemGet<SvxLRSpaceItem>(rFmt, RES_LR_SPACE); - aNumFmt.SetAbsLSpace(writer_cast<short>( - aNumFmt.GetAbsLSpace() + rLR.GetLeft())); - Out_NumRuleAnld( *pDoc->GetOutlineNumRule(), - aNumFmt, nLvl ); + ItemGet<SvxLRSpaceItem>( rFmt, RES_LR_SPACE ); + + aNumFmt.SetAbsLSpace( writer_cast<short>( + aNumFmt.GetAbsLSpace() + rLR.GetLeft() ) ); + m_rWW8Export.Out_NumRuleAnld( + *m_rWW8Export.pDoc->GetOutlineNumRule(), + aNumFmt, nLvl ); } else - Out_NumRuleAnld( *pDoc->GetOutlineNumRule(), - rNFmt, nLvl ); + m_rWW8Export.Out_NumRuleAnld( + *m_rWW8Export.pDoc->GetOutlineNumRule(), + rNFmt, nLvl ); } } // --> OD 2007-06-04 #i77805# -bool SwWW8Writer::DisallowInheritingOutlineNumbering(const SwFmt &rFmt) +bool WW8Export::DisallowInheritingOutlineNumbering(const SwFmt &rFmt) { bool bRet( false ); @@ -787,9 +737,9 @@ bool SwWW8Writer::DisallowInheritingOutlineNumbering(const SwFmt &rFmt) { //<-end,zhaojianwei if (bWrtWW8) { - SwWW8Writer::InsUInt16(*pO, 0x2640); + SwWW8Writer::InsUInt16(*pO, NS_sprm::LN_POutLvl); pO->Insert(BYTE(9), pO->Count()); - SwWW8Writer::InsUInt16(*pO, 0x460b); + SwWW8Writer::InsUInt16(*pO, NS_sprm::LN_PIlfo); SwWW8Writer::InsUInt16(*pO, 0); bRet = true; @@ -803,8 +753,7 @@ bool SwWW8Writer::DisallowInheritingOutlineNumbering(const SwFmt &rFmt) } // <-- -void SwWW8Writer::Out_SwFmt(const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, - bool bFlyFmt) +void MSWordExportBase::OutputFormat( const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, bool bFlyFmt ) { bool bCallOutSet = true; const SwModify* pOldMod = pOutFmtNode; @@ -825,9 +774,9 @@ void SwWW8Writer::Out_SwFmt(const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, //if outline numbered // if Write StyleDefinition then write the OutlineRule - const SwNumFmt& rNFmt = pDoc->GetOutlineNumRule()->Get(static_cast<USHORT>(nLvl)); - if (bStyDef) - ExportOutlineNumbering(static_cast<BYTE>(nLvl), rNFmt, rFmt); + const SwNumFmt& rNFmt = pDoc->GetOutlineNumRule()->Get( static_cast<USHORT>( nLvl ) ); + if ( bStyDef ) + AttrOutput().OutlineNumbering( static_cast< BYTE >( nLvl ), rNFmt, rFmt ); // --> OD 2008-06-03 #i86652# // if (rNFmt.GetAbsLSpace()) @@ -844,8 +793,8 @@ void SwWW8Writer::Out_SwFmt(const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, aLR.SetTxtFirstLineOfst( GetWordFirstLineOffset(rNFmt)); aSet.Put( aLR ); - SwWW8Writer::CorrTabStopInSet( aSet, rNFmt.GetAbsLSpace() ); - Out_SfxItemSet( aSet, bPapFmt, bChpFmt, + CorrectTabStopInSet( aSet, rNFmt.GetAbsLSpace() ); + OutputItemSet( aSet, bPapFmt, bChpFmt, i18n::ScriptType::LATIN); bCallOutSet = false; } @@ -863,7 +812,7 @@ void SwWW8Writer::Out_SwFmt(const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, SvxLRSpaceItem aLR( ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE)); aSet.Put( aLR ); - Out_SfxItemSet( aSet, bPapFmt, bChpFmt, + OutputItemSet( aSet, bPapFmt, bChpFmt, com::sun::star::i18n::ScriptType::LATIN); bCallOutSet = false; } @@ -903,7 +852,7 @@ void SwWW8Writer::Out_SwFmt(const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, bOutFlyFrmAttrs = true; //script doesn't matter if not exporting chp - Out_SfxItemSet(aSet, true, false, + OutputItemSet(aSet, true, false, i18n::ScriptType::LATIN); bOutFlyFrmAttrs = false; @@ -917,55 +866,64 @@ void SwWW8Writer::Out_SwFmt(const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, } if( bCallOutSet ) - Out_SfxItemSet( rFmt.GetAttrSet(), bPapFmt, bChpFmt, + OutputItemSet( rFmt.GetAttrSet(), bPapFmt, bChpFmt, i18n::ScriptType::LATIN); pOutFmtNode = pOldMod; } -bool SwWW8Writer::HasRefToObject(USHORT nTyp, const String* pNm, USHORT nSeqNo) +bool MSWordExportBase::HasRefToObject( USHORT nTyp, const String* pName, USHORT nSeqNo ) { - bool bFnd = false; const SwTxtNode* pNd; - SwClientIter aIter( *pDoc->GetSysFldType( RES_GETREFFLD )); - for( SwFmtFld* pFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld )); - pFld && !bFnd; pFld = (SwFmtFld*)aIter.Next() ) - if( pFld->GetTxtFld() && nTyp == pFld->GetFld()->GetSubType() && - 0 != ( pNd = pFld->GetTxtFld()->GetpTxtNode() ) && - pNd->GetNodes().IsDocNodes() ) + SwClientIter aIter( *pDoc->GetSysFldType( RES_GETREFFLD ) ); + for ( SwFmtFld* pFld = static_cast< SwFmtFld* >( aIter.First( TYPE( SwFmtFld ) ) ); + pFld; + pFld = static_cast< SwFmtFld* >( aIter.Next() ) ) + { + if ( pFld->GetTxtFld() && nTyp == pFld->GetFld()->GetSubType() && + 0 != ( pNd = pFld->GetTxtFld()->GetpTxtNode() ) && + pNd->GetNodes().IsDocNodes() ) { - const SwGetRefField& rRFld = *(SwGetRefField*)pFld->GetFld(); - switch( nTyp ) + const SwGetRefField& rRFld = *static_cast< SwGetRefField* >( pFld->GetFld() ); + switch ( nTyp ) { - case REF_BOOKMARK: - case REF_SETREFATTR: - bFnd = (*pNm == rRFld.GetSetRefName()) ? true : false; - break; - case REF_FOOTNOTE: - case REF_ENDNOTE: - bFnd = (nSeqNo == rRFld.GetSeqNo()) ? true : false; - break; - case REF_SEQUENCEFLD: break; // ??? - case REF_OUTLINE: break; // ??? + case REF_BOOKMARK: + case REF_SETREFATTR: + if ( pName && *pName == rRFld.GetSetRefName() ) + return true; + break; + case REF_FOOTNOTE: + case REF_ENDNOTE: + if ( nSeqNo == rRFld.GetSeqNo() ) + return true; + break; + case REF_SEQUENCEFLD: + break; // ??? + case REF_OUTLINE: + break; // ??? } } + } - return bFnd; + return false; } -String SwWW8Writer::GetBookmarkName( USHORT nTyp, const String* pNm, - USHORT nSeqNo ) +String MSWordExportBase::GetBookmarkName( USHORT nTyp, const String* pName, USHORT nSeqNo ) { String sRet; - switch( nTyp ) + switch ( nTyp ) { case REF_SETREFATTR: - sRet.APPEND_CONST_ASC( "Ref_" ); - sRet += *pNm; + if ( pName ) + { + sRet.APPEND_CONST_ASC( "Ref_" ); + sRet += *pName; + } break; case REF_SEQUENCEFLD: break; // ??? case REF_BOOKMARK: - sRet = *pNm; + if ( pName ) + sRet = *pName; break; case REF_OUTLINE: break; // ??? @@ -986,238 +944,307 @@ String SwWW8Writer::GetBookmarkName( USHORT nTyp, const String* pNm, //----------------------------------------------------------------------- /* */ /* File CHRATR.HXX: */ +void WW8AttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ) +{ + if ( m_rWW8Export.bWrtWW8 && bIsRTL ) + { + m_rWW8Export.InsUInt16( NS_sprm::LN_CFBiDi ); + m_rWW8Export.pO->Insert( (BYTE)1, m_rWW8Export.pO->Count() ); + } + + // #i46087# patch from james_clark; complex texts needs the undocumented SPRM CComplexScript with param 0x81. + if ( m_rWW8Export.bWrtWW8 && nScript == i18n::ScriptType::COMPLEX && !bIsRTL ) + { + m_rWW8Export.InsUInt16( NS_sprm::LN_CComplexScript ); + m_rWW8Export.pO->Insert( (BYTE)0x81, m_rWW8Export.pO->Count() ); + m_rWW8Export.pDop->bUseThaiLineBreakingRules = true; + } +} + +void WW8AttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) +{ + m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() ); + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete + + if ( pTextNodeInfoInner.get() != NULL ) + { + if ( pTextNodeInfoInner->isEndOfLine() ) + { + TableRowEnd( pTextNodeInfoInner->getDepth() ); + + SVBT16 nSty; + ShortToSVBT16( m_rWW8Export.nStyleBeforeFly, nSty ); + m_rWW8Export.pO->Insert( (BYTE*)&nSty, 2, m_rWW8Export.pO->Count() ); // Style # + TableInfoRow( pTextNodeInfoInner ); + m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), + m_rWW8Export.pO->GetData() ); + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete + } + } +} -static Writer& OutWW8_SwBoldUSW(Writer& rWrt, BYTE nId, bool bVal) +void WW8AttributeOutput::StartRunProperties() { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16(8 == nId ? 0x2a53 : 0x0835 + nId); + WW8_WrPlcFld* pCurrentFields = m_rWW8Export.CurrentFieldPlc(); + m_nFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0; +} + +void WW8AttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData ) +{ + Redline( pRedlineData ); + + WW8_WrPlcFld* pCurrentFields = m_rWW8Export.CurrentFieldPlc(); + USHORT nNewFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0; + + bool bExportedFieldResult = ( m_nFieldResults != nNewFieldResults ); + + // If we have exported a field result, then we will have been forced to + // split up the text into a 0x13, 0x14, <result> 0x15 sequence with the + // properties forced out at the end of the result, so the 0x15 itself + // should remain clean of all other attributes to avoid #iXXXXX# + if ( !bExportedFieldResult ) + { + m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), + m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() ); + } + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete +} + +void WW8AttributeOutput::RunText( const String& rText, rtl_TextEncoding eCharSet ) +{ + RawText( rText, m_rWW8Export.bWrtWW8, eCharSet ); +} + +void WW8AttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet ) +{ + m_rWW8Export.OutSwString( rText, 0, rText.Len(), bForceUnicode, eCharSet ); +} + +void WW8AttributeOutput::OutputFKP() +{ + if ( m_rWW8Export.pO->Count() ) + { + m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), + m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() ); + m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete + } +} + +void WW8AttributeOutput::ParagraphStyle( USHORT nStyle ) +{ + ASSERT( !m_rWW8Export.pO->Count(), " pO ist am ZeilenEnde nicht leer" ); + + SVBT16 nSty; + ShortToSVBT16( nStyle, nSty ); + m_rWW8Export.pO->Insert( (BYTE*)&nSty, 2, m_rWW8Export.pO->Count() ); // Style # +} + +void WW8AttributeOutput::OutputWW8Attribute( BYTE nId, bool bVal ) +{ + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( 8 == nId ? NS_sprm::LN_CFDStrike : NS_sprm::LN_CFBold + nId ); else if (8 == nId ) - return rWrt; // das Attribut gibt es im WW6 nicht + return; // no such attribute in WW6 else - rWrtWW8.pO->Insert( 85 + nId, rWrtWW8.pO->Count() ); - rWrtWW8.pO->Insert( bVal ? 1 : 0, rWrtWW8.pO->Count() ); - return rWrt; + m_rWW8Export.pO->Insert( 85 + nId, m_rWW8Export.pO->Count() ); + + m_rWW8Export.pO->Insert( bVal ? 1 : 0, m_rWW8Export.pO->Count() ); } -static Writer& OutWW8_SwBoldBiDiUSW(Writer& rWrt, BYTE nId, bool bVal) +void WW8AttributeOutput::OutputWW8AttributeCTL( BYTE nId, bool bVal ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - ASSERT(nId <= 1, "out of range"); - if (!rWrtWW8.bWrtWW8 || nId > 1) - return rWrt; + ASSERT( nId <= 1, "out of range" ); + if ( !m_rWW8Export.bWrtWW8 || nId > 1 ) + return; - rWrtWW8.InsUInt16(0x085C + nId); - rWrtWW8.pO->Insert(bVal ? 1 : 0, rWrtWW8.pO->Count()); - return rWrt; + m_rWW8Export.InsUInt16( NS_sprm::LN_CFBoldBi + nId ); + m_rWW8Export.pO->Insert( bVal ? 1 : 0, m_rWW8Export.pO->Count() ); } -static Writer& OutWW8_SwFont( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharFont( const SvxFontItem& rFont ) { - const SvxFontItem& rAttr = (const SvxFontItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - USHORT nFontID= rWrtWW8.GetId(rAttr); + USHORT nFontID = m_rWW8Export.GetId( rFont ); - if( rWrtWW8.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { - rWrtWW8.InsUInt16( 0x4a4f ); - rWrtWW8.InsUInt16( nFontID ); - rWrtWW8.InsUInt16( 0x4a51 ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc0 ); + m_rWW8Export.InsUInt16( nFontID ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc2 ); } else - rWrtWW8.pO->Insert( 93, rWrtWW8.pO->Count() ); - rWrtWW8.InsUInt16( nFontID ); - return rWrt; + m_rWW8Export.pO->Insert( 93, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( nFontID ); } -static Writer& OutWW8_SwCTLFont(Writer& rWrt, const SfxPoolItem& rHt) +void WW8AttributeOutput::CharFontCTL( const SvxFontItem& rFont ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (rWrtWW8.bWrtWW8) + if ( m_rWW8Export.bWrtWW8 ) { - rWrtWW8.InsUInt16(0x4A5E); - rWrtWW8.InsUInt16(rWrtWW8.GetId((const SvxFontItem&)rHt)); + m_rWW8Export.InsUInt16( NS_sprm::LN_CFtcBi ); + m_rWW8Export.InsUInt16( m_rWW8Export.GetId( rFont ) ); } - return rWrt; } -static Writer& OutWW8_SwCJKFont( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharFontCJK( const SvxFontItem& rFont ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { - rWrtWW8.InsUInt16( 0x4a50 ); - rWrtWW8.InsUInt16(rWrtWW8.GetId((const SvxFontItem&)rHt)); + m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc1 ); + m_rWW8Export.InsUInt16( m_rWW8Export.GetId( rFont ) ); } - return rWrt; } -static Writer& OutWW8_SwBiDiWeight( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight ) { //Can only export in 8+, in 7- export as normal varient and expect that //upperlevel code has blocked exporting clobbering attributes - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (rWrtWW8.bWrtWW8) + if (m_rWW8Export.bWrtWW8) { - OutWW8_SwBoldBiDiUSW(rWrt, 0, - WEIGHT_BOLD == ((const SvxWeightItem&)rHt).GetWeight()); + OutputWW8AttributeCTL( 0, WEIGHT_BOLD == rWeight.GetWeight()); } else { - OutWW8_SwBoldUSW(rWrt, 0, - WEIGHT_BOLD == ((const SvxWeightItem&)rHt).GetWeight()); + OutputWW8Attribute( 0, WEIGHT_BOLD == rWeight.GetWeight()); } - return rWrt; } -static Writer& OutWW8_SwBiDiPosture( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture ) { - //Can only export in 8+, in 7- export as normal varient and expect that - //upperlevel code has blocked exporting clobbering attributes - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (rWrtWW8.bWrtWW8) + // Can only export in 8+, in 7- export as normal varient and expect that + // upperlevel code has blocked exporting clobbering attributes + if (m_rWW8Export.bWrtWW8) { - OutWW8_SwBoldBiDiUSW( rWrt, 1, - ITALIC_NONE != ((const SvxPostureItem&)rHt).GetPosture() ); + OutputWW8AttributeCTL( 1, ITALIC_NONE != rPosture.GetPosture() ); } else { - OutWW8_SwBoldUSW( rWrt, 1, - ITALIC_NONE != ((const SvxPostureItem&)rHt).GetPosture() ); + OutputWW8Attribute( 1, ITALIC_NONE != rPosture.GetPosture() ); } - return rWrt; } -static Writer& OutWW8_SwPosture( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharPosture( const SvxPostureItem& rPosture ) { - return OutWW8_SwBoldUSW( rWrt, 1, - ITALIC_NONE != ((const SvxPostureItem&)rHt).GetPosture() ); + OutputWW8Attribute( 1, ITALIC_NONE != rPosture.GetPosture() ); } -static Writer& OutWW8_SwWeight( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharWeight( const SvxWeightItem& rWeight ) { - return OutWW8_SwBoldUSW( rWrt, 0, - WEIGHT_BOLD == ((const SvxWeightItem&)rHt).GetWeight() ); + OutputWW8Attribute( 0, WEIGHT_BOLD == rWeight.GetWeight() ); } -// Shadowed und Contour gibts in WW-UI nicht. JP: ?? -static Writer& OutWW8_SwContour( Writer& rWrt, const SfxPoolItem& rHt ) +// Shadowed und Contour are not in WW-UI. JP: ?? +void WW8AttributeOutput::CharContour( const SvxContourItem& rContour ) { - return OutWW8_SwBoldUSW(rWrt, 3, - ((const SvxContourItem&)rHt).GetValue() ? true : false); + OutputWW8Attribute( 3, rContour.GetValue() ? true : false); } -static Writer& OutWW8_SwShadow( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharShadow( const SvxShadowedItem& rShadow ) { - return OutWW8_SwBoldUSW(rWrt, 4, - ((const SvxShadowedItem&)rHt).GetValue() ? true : false); + OutputWW8Attribute( 4, rShadow.GetValue() ? true : false); } -static Writer& OutWW8_SwKerning( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharKerning( const SvxKerningItem& rKerning ) { - const SvxKerningItem& rAttr = (const SvxKerningItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x8840 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CDxaSpace ); else - rWrtWW8.pO->Insert( 96, rWrtWW8.pO->Count() ); - rWrtWW8.InsUInt16( rAttr.GetValue() ); - return rWrt; + m_rWW8Export.pO->Insert( 96, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( rKerning.GetValue() ); } -static Writer& OutWW8_SvxAutoKern( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharAutoKern( const SvxAutoKernItem& rAutoKern ) { - const SvxAutoKernItem& rAttr = (const SvxAutoKernItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x484B ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsKern ); else - rWrtWW8.pO->Insert( 107, rWrtWW8.pO->Count() ); - rWrtWW8.InsUInt16( rAttr.GetValue() ? 1 : 0 ); - return rWrt; + m_rWW8Export.pO->Insert( 107, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( rAutoKern.GetValue() ? 1 : 0 ); } -static Writer& OutWW8_SwAnimatedText( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink ) { - const SvxBlinkItem& rAttr = (const SvxBlinkItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { - rWrtWW8.InsUInt16( 0x2859 ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CSfxText ); // At the moment the only animated text effect we support is blinking - rWrtWW8.InsUInt16( rAttr.GetValue() ? 2 : 0 ); + m_rWW8Export.InsUInt16( rBlink.GetValue() ? 2 : 0 ); } - return rWrt; } - -static Writer& OutWW8_SwCrossedOut( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossed ) { - FontStrikeout eSt = ((const SvxCrossedOutItem&)rHt).GetStrikeout(); - if( STRIKEOUT_DOUBLE == eSt ) - return OutWW8_SwBoldUSW(rWrt, 8, true); - if( STRIKEOUT_NONE != eSt ) - return OutWW8_SwBoldUSW(rWrt, 2, true); + FontStrikeout eSt = rCrossed.GetStrikeout(); + if ( STRIKEOUT_DOUBLE == eSt ) + { + OutputWW8Attribute( 8, true ); + return; + } + if ( STRIKEOUT_NONE != eSt ) + { + OutputWW8Attribute( 2, true ); + return; + } - // dann auch beide ausschalten! - OutWW8_SwBoldUSW(rWrt, 8, false); - return OutWW8_SwBoldUSW(rWrt, 2, false); + // otherwise both off + OutputWW8Attribute( 8, false ); + OutputWW8Attribute( 2, false ); } -static Writer& OutWW8_SwCaseMap( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap ) { - USHORT eSt = ((const SvxCaseMapItem&)rHt).GetValue(); - switch (eSt) + USHORT eSt = rCaseMap.GetValue(); + switch ( eSt ) { case SVX_CASEMAP_KAPITAELCHEN: - return OutWW8_SwBoldUSW(rWrt, 5, true); + OutputWW8Attribute( 5, true ); + return; case SVX_CASEMAP_VERSALIEN: - return OutWW8_SwBoldUSW(rWrt, 6, true); + OutputWW8Attribute( 6, true ); + return; case SVX_CASEMAP_TITEL: - //NO such feature in word + // no such feature in word break; default: - // dann auch beide ausschalten! - OutWW8_SwBoldUSW(rWrt, 5, false); - return OutWW8_SwBoldUSW(rWrt, 6, false); + // otherwise both off + OutputWW8Attribute( 5, false ); + OutputWW8Attribute( 6, false ); + return; } - return rWrt; } -static Writer& OutWW8_SvxCharHidden(Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden ) { - OutWW8_SwBoldUSW(rWrt, 7, (item_cast<SvxCharHiddenItem>(rHt)).GetValue()); - return rWrt; + OutputWW8Attribute( 7, rHidden.GetValue() ); } -static Writer& OutWW8_SwUnderline( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline ) { - const SvxUnderlineItem& rAttr = (const SvxUnderlineItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x2A3E ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CKul ); else - rWrtWW8.pO->Insert( 94, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( 94, m_rWW8Export.pO->Count() ); - const SfxPoolItem* pItem = ((SwWW8Writer&)rWrt).HasItem( - RES_CHRATR_WORDLINEMODE ); + const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_CHRATR_WORDLINEMODE ); bool bWord = false; if (pItem) bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false; - // WW95 - parameters: 0 = none, 1 = single, 2 = by Word, - // 3 = double, 4 = dotted, 5 = hidden - // WW97 - additional parameters: - // 6 = thick, 7 = dash, 8 = dot(not used) - // 9 = dotdash 10 = dotdotdash, 11 = wave + // WW95 - parameters: 0 = none, 1 = single, 2 = by Word, + // 3 = double, 4 = dotted, 5 = hidden + // WW97 - additional parameters: + // 6 = thick, 7 = dash, 8 = dot(not used) + // 9 = dotdash 10 = dotdotdash, 11 = wave BYTE b = 0; - switch (rAttr.GetLineStyle()) + switch ( rUnderline.GetLineStyle() ) { case UNDERLINE_SINGLE: b = ( bWord ) ? 2 : 1; break; case UNDERLINE_BOLD: - b = rWrtWW8.bWrtWW8 ? 6 : 1; + b = m_rWW8Export.bWrtWW8 ? 6 : 1; break; case UNDERLINE_DOUBLE: b = 3; @@ -1226,286 +1253,265 @@ static Writer& OutWW8_SwUnderline( Writer& rWrt, const SfxPoolItem& rHt ) b = 4; break; case UNDERLINE_DASH: - b = rWrtWW8.bWrtWW8 ? 7 : 4; + b = m_rWW8Export.bWrtWW8 ? 7 : 4; break; case UNDERLINE_DASHDOT: - b = rWrtWW8.bWrtWW8 ? 9 : 4; + b = m_rWW8Export.bWrtWW8 ? 9 : 4; break; case UNDERLINE_DASHDOTDOT: - b = rWrtWW8.bWrtWW8 ? 10 : 4; + b = m_rWW8Export.bWrtWW8 ? 10 : 4; break; case UNDERLINE_WAVE: - b = rWrtWW8.bWrtWW8 ? 11 : 3; + b = m_rWW8Export.bWrtWW8 ? 11 : 3; break; // ------------ new in WW2000 ------------------------------------- case UNDERLINE_BOLDDOTTED: - b = rWrtWW8.bWrtWW8 ? 20 : 4; + b = m_rWW8Export.bWrtWW8 ? 20 : 4; break; case UNDERLINE_BOLDDASH: - b = rWrtWW8.bWrtWW8 ? 23 : 4; + b = m_rWW8Export.bWrtWW8 ? 23 : 4; break; case UNDERLINE_LONGDASH: - b = rWrtWW8.bWrtWW8 ? 39 : 4; + b = m_rWW8Export.bWrtWW8 ? 39 : 4; break; case UNDERLINE_BOLDLONGDASH: - b = rWrtWW8.bWrtWW8 ? 55 : 4; + b = m_rWW8Export.bWrtWW8 ? 55 : 4; break; case UNDERLINE_BOLDDASHDOT: - b = rWrtWW8.bWrtWW8 ? 25 : 4; + b = m_rWW8Export.bWrtWW8 ? 25 : 4; break; case UNDERLINE_BOLDDASHDOTDOT: - b = rWrtWW8.bWrtWW8 ? 26 : 4; + b = m_rWW8Export.bWrtWW8 ? 26 : 4; break; case UNDERLINE_BOLDWAVE: - b = rWrtWW8.bWrtWW8 ? 27 : 3; + b = m_rWW8Export.bWrtWW8 ? 27 : 3; break; case UNDERLINE_DOUBLEWAVE: - b = rWrtWW8.bWrtWW8 ? 43 : 3; + b = m_rWW8Export.bWrtWW8 ? 43 : 3; break; case UNDERLINE_NONE: b = 0; break; default: - ASSERT(rAttr.GetLineStyle() == UNDERLINE_NONE, "Unhandled underline type"); + ASSERT( rUnderline.GetLineStyle() == UNDERLINE_NONE, "Unhandled underline type" ); break; } - rWrtWW8.pO->Insert(b, rWrtWW8.pO->Count()); - return rWrt; + m_rWW8Export.pO->Insert( b, m_rWW8Export.pO->Count() ); } -static Writer& OutWW8_SwLanguage( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage ) { USHORT nId = 0; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (rWrtWW8.bWrtWW8) + if ( m_rWW8Export.bWrtWW8 ) { - switch (rHt.Which()) + switch ( rLanguage.Which() ) { case RES_CHRATR_LANGUAGE: - nId = 0x486D; + nId = NS_sprm::LN_CRgLid0; break; case RES_CHRATR_CJK_LANGUAGE: - nId = 0x486E; + nId = NS_sprm::LN_CRgLid1; break; case RES_CHRATR_CTL_LANGUAGE: - nId = 0x485F; + nId = NS_sprm::LN_CLidBi; break; } } else nId = 97; - if (nId) + if ( nId ) { - if (rWrtWW8.bWrtWW8) // use sprmCRgLid0 rather than sprmCLid - rWrtWW8.InsUInt16(nId); + if ( m_rWW8Export.bWrtWW8 ) // use sprmCRgLid0 rather than sprmCLid + m_rWW8Export.InsUInt16( nId ); else - rWrtWW8.pO->Insert((BYTE)nId, rWrtWW8.pO->Count()); - rWrtWW8.InsUInt16(((const SvxLanguageItem&)rHt).GetLanguage()); + m_rWW8Export.pO->Insert( (BYTE)nId, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( rLanguage.GetLanguage() ); - //unknown as to exactly why, but this seems to shadow the other - //paramater in word 2000 and without it spellchecking doesn't work - if (nId == 0x486D) + // unknown as to exactly why, but this seems to shadow the other + // paramater in word 2000 and without it spellchecking doesn't work + if ( nId == NS_sprm::LN_CRgLid0 ) { - rWrtWW8.InsUInt16(0x4873); - rWrtWW8.InsUInt16(((const SvxLanguageItem&)rHt).GetLanguage()); + m_rWW8Export.InsUInt16( 0x4873 ); + m_rWW8Export.InsUInt16( rLanguage.GetLanguage() ); } - else if (nId == 0x485F) + else if ( nId == NS_sprm::LN_CLidBi ) { - rWrtWW8.InsUInt16(0x4874); - rWrtWW8.InsUInt16(((const SvxLanguageItem&)rHt).GetLanguage()); + m_rWW8Export.InsUInt16( 0x4874 ); + m_rWW8Export.InsUInt16( rLanguage.GetLanguage() ); } } - return rWrt; } -static Writer& OutWW8_SwEscapement( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement ) { - const SvxEscapementItem& rAttr = (const SvxEscapementItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - BYTE b = 0xFF; - short nEsc = rAttr.GetEsc(), nProp = rAttr.GetProp(); - if( !nEsc ) + short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp(); + if ( !nEsc ) { b = 0; nEsc = 0; nProp = 100; } - else if( DFLT_ESC_PROP == nProp ) + else if ( DFLT_ESC_PROP == nProp ) { - if( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc ) + if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc ) b = 2; - else if( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc ) + else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc ) b = 1; } - if( 0xFF != b ) + if ( 0xFF != b ) { - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x2A48 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CIss ); else - rWrtWW8.pO->Insert( 104, rWrtWW8.pO->Count() ); - rWrtWW8.pO->Insert( b, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( 104, m_rWW8Export.pO->Count() ); + + m_rWW8Export.pO->Insert( b, m_rWW8Export.pO->Count() ); } - if( 0 == b || 0xFF == b ) + if ( 0 == b || 0xFF == b ) { - long nHeight = ((SvxFontHeightItem&)rWrtWW8.GetItem( + long nHeight = ((SvxFontHeightItem&)m_rWW8Export.GetItem( RES_CHRATR_FONTSIZE )).GetHeight(); - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x4845 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsPos ); else - rWrtWW8.pO->Insert( 101, rWrtWW8.pO->Count() ); - rWrtWW8.InsUInt16( (short)(( nHeight * nEsc + 500 ) / 1000 )); + m_rWW8Export.pO->Insert( 101, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( (short)(( nHeight * nEsc + 500 ) / 1000 )); if( 100 != nProp || !b ) { - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x4A43 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CHps ); else - rWrtWW8.pO->Insert( 99, rWrtWW8.pO->Count() ); - rWrtWW8.InsUInt16( - msword_cast<sal_uInt16>((nHeight * nProp + 500 ) / 1000)); + m_rWW8Export.pO->Insert( 99, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( + msword_cast<sal_uInt16>((nHeight * nProp + 500 ) / 1000)); } } - return rWrt; } -static Writer& OutWW8_SwSize( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharFontSize( const SvxFontHeightItem& rHeight ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; USHORT nId = 0; - if (rWrtWW8.bWrtWW8) + if ( m_rWW8Export.bWrtWW8 ) { - switch (rHt.Which()) + switch ( rHeight.Which() ) { case RES_CHRATR_FONTSIZE: case RES_CHRATR_CJK_FONTSIZE: - nId = 0x4A43; + nId = NS_sprm::LN_CHps; break; case RES_CHRATR_CTL_FONTSIZE: - nId = 0x4A61; + nId = NS_sprm::LN_CHpsBi; break; } } else nId = 99; - if( nId ) + if ( nId ) { - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( nId ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( nId ); else - rWrtWW8.pO->Insert( (BYTE)nId, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( (BYTE)nId, m_rWW8Export.pO->Count() ); - const SvxFontHeightItem& rAttr = (const SvxFontHeightItem&)rHt; - rWrtWW8.InsUInt16( (UINT16)(( rAttr.GetHeight() + 5 ) / 10 ) ); + m_rWW8Export.InsUInt16( (UINT16)(( rHeight.GetHeight() + 5 ) / 10 ) ); } - return rWrt; } -static Writer& OutWW8_ScaleWidth( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { - rWrtWW8.InsUInt16( 0x4852 ); - rWrtWW8.InsUInt16( ((SvxCharScaleWidthItem&)rHt).GetValue() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CCharScale ); + m_rWW8Export.InsUInt16( rScaleWidth.GetValue() ); } - return rWrt; } -static Writer& OutWW8_Relief( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharRelief( const SvxCharReliefItem& rRelief ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { - const SvxCharReliefItem& rAttr = (const SvxCharReliefItem&)rHt; USHORT nId; - switch ( rAttr.GetValue() ) + switch ( rRelief.GetValue() ) { - case RELIEF_EMBOSSED: nId = 0x858; break; - case RELIEF_ENGRAVED: nId = 0x854; break; - default: nId = 0; break; + case RELIEF_EMBOSSED: nId = NS_sprm::LN_CFEmboss; break; + case RELIEF_ENGRAVED: nId = NS_sprm::LN_CFImprint; break; + default: nId = 0; break; } if( nId ) { - rWrtWW8.InsUInt16( nId ); - rWrtWW8.pO->Insert( (BYTE)0x81, rWrtWW8.pO->Count() ); + m_rWW8Export.InsUInt16( nId ); + m_rWW8Export.pO->Insert( (BYTE)0x81, m_rWW8Export.pO->Count() ); } else { // switch both flags off - rWrtWW8.InsUInt16( 0x858 ); - rWrtWW8.pO->Insert( (BYTE)0x0, rWrtWW8.pO->Count() ); - rWrtWW8.InsUInt16( 0x854 ); - rWrtWW8.pO->Insert( (BYTE)0x0, rWrtWW8.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CFEmboss ); + m_rWW8Export.pO->Insert( (BYTE)0x0, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CFImprint ); + m_rWW8Export.pO->Insert( (BYTE)0x0, m_rWW8Export.pO->Count() ); } } - return rWrt; } - -static Writer& OutWW8_CharRotate( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharRotate( const SvxCharRotateItem& rRotate ) { // #i28331# - check that a Value is set - if((static_cast<const SvxCharRotateItem&>(rHt)).GetValue()) + if ( !rRotate.GetValue() ) + return; + + if ( m_rWW8Export.bWrtWW8 && !m_rWW8Export.bIsInTable ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 && !rWrtWW8.bIsInTable ) - { - // #i36867 In word the text in a table is rotated via the TC or 0x7629 - // This means you can only rotate all or none of the text adding 0xCA78 - // here corrupts the table, hence !rWrtWW8.bIsInTable - const SvxCharRotateItem& rAttr = (const SvxCharRotateItem&)rHt; - - rWrtWW8.InsUInt16( 0xCA78 ); - rWrtWW8.pO->Insert( (BYTE)0x06, rWrtWW8.pO->Count() ); //len 6 - rWrtWW8.pO->Insert( (BYTE)0x01, rWrtWW8.pO->Count() ); - - rWrtWW8.InsUInt16( rAttr.IsFitToLine() ? 1 : 0 ); - static const BYTE aZeroArr[ 3 ] = { 0, 0, 0 }; - rWrtWW8.pO->Insert( aZeroArr, 3, rWrtWW8.pO->Count() ); - } + // #i36867 In word the text in a table is rotated via the TC or NS_sprm::LN_TTextFlow + // This means you can only rotate all or none of the text adding NS_sprm::LN_CEastAsianLayout + // here corrupts the table, hence !m_rWW8Export.bIsInTable + + m_rWW8Export.InsUInt16( NS_sprm::LN_CEastAsianLayout ); + m_rWW8Export.pO->Insert( (BYTE)0x06, m_rWW8Export.pO->Count() ); //len 6 + m_rWW8Export.pO->Insert( (BYTE)0x01, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( rRotate.IsFitToLine() ? 1 : 0 ); + static const BYTE aZeroArr[ 3 ] = { 0, 0, 0 }; + m_rWW8Export.pO->Insert( aZeroArr, 3, m_rWW8Export.pO->Count() ); } - return rWrt; } - -static Writer& OutWW8_EmphasisMark( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) + if ( m_rWW8Export.bWrtWW8 ) { BYTE nVal; - switch ( ((const SvxEmphasisMarkItem&)rHt).GetValue() ) + switch ( rEmphasisMark.GetValue() ) { - case EMPHASISMARK_NONE: nVal = 0; break; - case EMPHASISMARK_SIDE_DOTS: nVal = 2; break; - case EMPHASISMARK_CIRCLE_ABOVE: nVal = 3; break; - case EMPHASISMARK_DOTS_BELOW: nVal = 4; break; -// case 1: - default: nVal = 1; break; + case EMPHASISMARK_NONE: nVal = 0; break; + case EMPHASISMARK_SIDE_DOTS: nVal = 2; break; + case EMPHASISMARK_CIRCLE_ABOVE: nVal = 3; break; + case EMPHASISMARK_DOTS_BELOW: nVal = 4; break; + // case 1: + default: nVal = 1; break; } - rWrtWW8.InsUInt16( 0x2A34 ); - rWrtWW8.pO->Insert( nVal, rWrtWW8.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CKcd ); + m_rWW8Export.pO->Insert( nVal, m_rWW8Export.pO->Count() ); } - return rWrt; } - // TransCol uebersetzt SW-Farben in WW. Heraus kommt die bei WW fuer // Text- und Hintergrundfarbe benutzte Codierung. // Gibt es keine direkte Entsprechung, dann wird versucht, eine moeglichst // aehnliche WW-Farbe zu finden. // return: 5-Bit-Wert ( 0..16 ) -BYTE SwWW8Writer::TransCol( const Color& rCol ) +BYTE WW8Export::TransCol( const Color& rCol ) { BYTE nCol = 0; // ->Auto switch( rCol.GetColor() ) @@ -1554,7 +1560,7 @@ BYTE SwWW8Writer::TransCol( const Color& rCol ) // Return: Echte Brush ( nicht transparent ) // auch bei Transparent wird z.B. fuer Tabellen eine transparente Brush // geliefert -bool SwWW8Writer::TransBrush(const Color& rCol, WW8_SHD& rShd) +bool WW8Export::TransBrush(const Color& rCol, WW8_SHD& rShd) { if( rCol.GetTransparency() ) rShd = WW8_SHD(); // alles Nullen : transparent @@ -1574,77 +1580,66 @@ sal_uInt32 SuitableBGColor(sal_uInt32 nIn) return wwUtility::RGBToBGR(nIn); } -static Writer& OutWW8_SwColor( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharColor( const SvxColorItem& rColor ) { - const SvxColorItem& rAttr = (const SvxColorItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (rWrtWW8.bWrtWW8) - rWrtWW8.InsUInt16(0x2A42); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CIco ); else - rWrtWW8.pO->Insert(98, rWrtWW8.pO->Count()); + m_rWW8Export.pO->Insert( 98, m_rWW8Export.pO->Count() ); - BYTE nColour = rWrtWW8.TransCol(rAttr.GetValue()); - rWrtWW8.pO->Insert(nColour, rWrtWW8.pO->Count()); + BYTE nColor = m_rWW8Export.TransCol( rColor.GetValue() ); + m_rWW8Export.pO->Insert( nColor, m_rWW8Export.pO->Count() ); - if (rWrtWW8.bWrtWW8 && nColour) + if ( m_rWW8Export.bWrtWW8 && nColor ) { - rWrtWW8.InsUInt16(0x6870); - rWrtWW8.InsUInt32(wwUtility::RGBToBGR(rAttr.GetValue().GetColor())); + m_rWW8Export.InsUInt16( 0x6870 ); + m_rWW8Export.InsUInt32( wwUtility::RGBToBGR( rColor.GetValue().GetColor() ) ); } - return rWrt; } -static Writer& OutWW8_SwFmtCharBackground( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharBackground( const SvxBrushItem& rBrush ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - - if( rWW8Wrt.bWrtWW8 ) // nur WW8 kann ZeichenHintergrund + if( m_rWW8Export.bWrtWW8 ) // nur WW8 kann ZeichenHintergrund { - const SvxBrushItem& rBack = (const SvxBrushItem&)rHt; WW8_SHD aSHD; - rWW8Wrt.TransBrush(rBack.GetColor(), aSHD); + m_rWW8Export.TransBrush( rBrush.GetColor(), aSHD ); // sprmCShd - rWW8Wrt.InsUInt16( 0x4866 ); - rWW8Wrt.InsUInt16( aSHD.GetValue() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CShd ); + m_rWW8Export.InsUInt16( aSHD.GetValue() ); //Quite a few unknowns, some might be transparency or something //of that nature... - rWW8Wrt.InsUInt16(0xCA71); - rWW8Wrt.pO->Insert(10, rWW8Wrt.pO->Count()); - rWW8Wrt.InsUInt32(0xFF000000); - rWW8Wrt.InsUInt32(SuitableBGColor(rBack.GetColor().GetColor())); - rWW8Wrt.InsUInt16(0x0000); + m_rWW8Export.InsUInt16( 0xCA71 ); + m_rWW8Export.pO->Insert( 10, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt32( 0xFF000000 ); + m_rWW8Export.InsUInt32( SuitableBGColor( rBrush.GetColor().GetColor() ) ); + m_rWW8Export.InsUInt16( 0x0000); } - return rWrt; } -static Writer& OutSwFmtINetFmt( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::TextINetFormat( const SwFmtINetFmt& rINet ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - const SwFmtINetFmt& rINet = (SwFmtINetFmt&)rHt; - - if( rINet.GetValue().Len() ) + if ( rINet.GetValue().Len() ) { USHORT nId; const String& rStr = rINet.GetINetFmt(); - if( rStr.Len() ) + if ( rStr.Len() ) nId = rINet.GetINetFmtId(); else nId = RES_POOLCHR_INET_NORMAL; const SwCharFmt* pFmt = IsPoolUserFmt( nId ) - ? rWrt.pDoc->FindCharFmtByName( rStr ) - : rWrt.pDoc->GetCharFmtFromPool( nId ); + ? m_rWW8Export.pDoc->FindCharFmtByName( rStr ) + : m_rWW8Export.pDoc->GetCharFmtFromPool( nId ); - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x4A30 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd ); else - rWrtWW8.pO->Insert( 80, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( 80, m_rWW8Export.pO->Count() ); - rWrtWW8.InsUInt16( rWrtWW8.GetId( *pFmt ) ); + m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pFmt ) ); } - return rWrt; } // --> OD 2005-06-08 #i43956# - add optional parameter <pLinkStr> @@ -1652,7 +1647,7 @@ static Writer& OutSwFmtINetFmt( Writer& rWrt, const SfxPoolItem& rHt ) // - it contains the name of the link target, which is a bookmark. // --> OD 2008-08-14 #158418# - add optional parameter <bIncludeEmptyPicLocation> // It is needed to write an empty picture location for page number field separators -static void InsertSpecialChar( SwWW8Writer& rWrt, BYTE c, +static void InsertSpecialChar( WW8Export& rWrt, BYTE c, String* pLinkStr = 0L, bool bIncludeEmptyPicLocation = false ) { @@ -1672,7 +1667,7 @@ static void InsertSpecialChar( SwWW8Writer& rWrt, BYTE c, if ( bIncludeEmptyPicLocation && ( c == 0x13 || c == 0x14 || c == 0x15 ) ) { - SwWW8Writer::InsUInt16( aItems, 0x6a03 ); + SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CPicLocation ); SwWW8Writer::InsUInt32( aItems, 0x00000000 ); } // <-- @@ -1714,11 +1709,11 @@ static void InsertSpecialChar( SwWW8Writer& rWrt, BYTE c, rStrm.Seek( nCurrPos ); // write attributes of hyperlink character 0x01 - SwWW8Writer::InsUInt16( aItems, 0x0802 ); //sprmCFFldVanish + SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFFldVanish ); aItems.Insert( (BYTE)0x81, aItems.Count() ); - SwWW8Writer::InsUInt16( aItems, 0x6a03 ); + SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CPicLocation ); SwWW8Writer::InsUInt32( aItems, nLinkPosInDataStrm ); - SwWW8Writer::InsUInt16( aItems, 0x0806 ); + SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFData ); aItems.Insert( (BYTE)0x01, aItems.Count() ); } @@ -1729,7 +1724,7 @@ static void InsertSpecialChar( SwWW8Writer& rWrt, BYTE c, // fSpec-Attribute true if( rWrt.bWrtWW8 ) { - SwWW8Writer::InsUInt16( aItems, 0x855 ); //sprmCFSpec + SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFSpec ); aItems.Insert( 1, aItems.Count() ); } else @@ -1752,7 +1747,7 @@ String lcl_GetExpandedField(const SwField &rFld) return sRet; } -WW8_WrPlcFld* SwWW8Writer::CurrentFieldPlc() const +WW8_WrPlcFld* WW8Export::CurrentFieldPlc() const { WW8_WrPlcFld* pFldP = NULL; switch (nTxtTyp) @@ -1784,8 +1779,8 @@ WW8_WrPlcFld* SwWW8Writer::CurrentFieldPlc() const return pFldP; } -void SwWW8Writer::OutField(const SwField* pFld, ww::eField eFldType, - const String& rFldCmd, BYTE nMode) +void WW8Export::OutputField( const SwField* pFld, ww::eField eFldType, + const String& rFldCmd, BYTE nMode ) { bool bUnicode = IsUnicode(); WW8_WrPlcFld* pFldP = CurrentFieldPlc(); @@ -1891,16 +1886,16 @@ void SwWW8Writer::OutField(const SwField* pFld, ww::eField eFldType, BYTE aArr[12]; BYTE *pArr = aArr; - if( bWrtWW8 ) + if ( bWrtWW8 ) { - Set_UInt16(pArr, 0x6a03); //sprmCPicLocation - Set_UInt32(pArr, 0x0); + Set_UInt16( pArr, NS_sprm::LN_CPicLocation ); + Set_UInt32( pArr, 0x0 ); - Set_UInt16( pArr, 0x855 );//sprmCFSpec + Set_UInt16( pArr, NS_sprm::LN_CFSpec ); Set_UInt8( pArr, 1 ); - Set_UInt16( pArr, 0x875 );//sprmCFNoProof - Set_UInt8(pArr, 1); + Set_UInt16( pArr, NS_sprm::LN_CFNoProof ); + Set_UInt8( pArr, 1 ); } else { @@ -1910,7 +1905,7 @@ void SwWW8Writer::OutField(const SwField* pFld, ww::eField eFldType, Set_UInt8( pArr, 117 ); //sprmCFSpec Set_UInt8( pArr, 1 ); } - pChpPlc->AppendFkpEntry( pStrm->Tell(), static_cast< short >(pArr - aArr), aArr ); + pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr ); } } } @@ -1938,25 +1933,25 @@ void SwWW8Writer::OutField(const SwField* pFld, ww::eField eFldType, } } -void SwWW8Writer::StartCommentOutput(const String& rName) +void WW8Export::StartCommentOutput(const String& rName) { String sStr(FieldString(ww::eQUOTE)); sStr.APPEND_CONST_ASC("["); sStr += rName; sStr.APPEND_CONST_ASC("] "); - OutField(0, ww::eQUOTE, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START); + OutputField(0, ww::eQUOTE, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START); } -void SwWW8Writer::EndCommentOutput(const String& rName) +void WW8Export::EndCommentOutput(const String& rName) { String sStr(CREATE_CONST_ASC(" [")); sStr += rName; sStr.APPEND_CONST_ASC("] "); - OutField(0, ww::eQUOTE, sStr, WRITEFIELD_CMD_END | WRITEFIELD_END | + OutputField(0, ww::eQUOTE, sStr, WRITEFIELD_CMD_END | WRITEFIELD_END | WRITEFIELD_CLOSE); } -USHORT SwWW8Writer::GetId( const SwTOXType& rTOXType ) +USHORT MSWordExportBase::GetId( const SwTOXType& rTOXType ) { void* p = (void*)&rTOXType; USHORT nRet = aTOXArr.GetPos( p ); @@ -2052,9 +2047,9 @@ bool lcl_IsHyperlinked(const SwForm& rForm, USHORT nTOXLvl) return bRes; } -void SwWW8Writer::StartTOX( const SwSection& rSect ) +void AttributeOutputBase::StartTOX( const SwSection& rSect ) { - if (const SwTOXBase* pTOX = rSect.GetTOXBase()) + if ( const SwTOXBase* pTOX = rSect.GetTOXBase() ) { static const sal_Char sEntryEnd[] = "\" "; @@ -2136,7 +2131,7 @@ void SwWW8Writer::StartTOX( const SwSection& rSect ) if( TOX_USER == pTOX->GetType() ) { sStr += '\"'; - sStr += (sal_Char)('A' + GetId( *pTOX->GetTOXType())); + sStr += (sal_Char)( 'A' + GetExport( ).GetId( *pTOX->GetTOXType() ) ); sStr.AppendAscii( sEntryEnd ); } } @@ -2151,7 +2146,7 @@ void SwWW8Writer::StartTOX( const SwSection& rSect ) // // (ignoring headline styles 1-9) // //BYTE nLvl = 0, nMinLvl = 0; //#outline level, removed by zhaojianwei // int nLvl = 0, nMinLvl = 0; //<-end,add by zhaojianwei -// const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls(); +// const SwTxtFmtColls& rColls = *GetExport().pDoc->GetTxtFmtColls(); // const SwTxtFmtColl* pColl; // for( n = rColls.Count(); n; ) // { @@ -2307,26 +2302,26 @@ void SwWW8Writer::StartTOX( const SwSection& rSect ) if( sStr.Len() ) { - bInWriteTOX = true; - OutField(0, eCode, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START | - WRITEFIELD_CMD_END); + GetExport( ).bInWriteTOX = true; + GetExport( ).OutputField( 0, eCode, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START | + WRITEFIELD_CMD_END ); } } - bStartTOX = false; + GetExport( ).bStartTOX = false; } -void SwWW8Writer::EndTOX( const SwSection& rSect ) +void AttributeOutputBase::EndTOX( const SwSection& rSect ) { const SwTOXBase* pTOX = rSect.GetTOXBase(); - if( pTOX ) + if ( pTOX ) { ww::eField eCode = TOX_INDEX == pTOX->GetType() ? ww::eINDEX : ww::eTOC; - OutField(0, eCode, aEmptyStr, WRITEFIELD_CLOSE); + GetExport( ).OutputField( 0, eCode, aEmptyStr, WRITEFIELD_CLOSE ); } - bInWriteTOX = false; + GetExport( ).bInWriteTOX = false; } -bool SwWW8Writer::GetNumberFmt(const SwField& rFld, String& rStr) +bool MSWordExportBase::GetNumberFmt(const SwField& rFld, String& rStr) { // Returns a date or time format string by using the US NfKeywordTable bool bHasFmt = false; @@ -2361,7 +2356,7 @@ bool SwWW8Writer::GetNumberFmt(const SwField& rFld, String& rStr) return bHasFmt; } -void WW8_GetNumberPara( String& rStr, const SwField& rFld ) +void AttributeOutputBase::GetNumberPara( String& rStr, const SwField& rFld ) { switch(rFld.GetFormat()) { @@ -2391,14 +2386,14 @@ void WW8_GetNumberPara( String& rStr, const SwField& rFld ) } } -void SwWW8Writer::WritePostItBegin( WW8Bytes* pOut ) +void WW8Export::WritePostItBegin( WW8Bytes* pOut ) { BYTE aArr[ 3 ]; BYTE* pArr = aArr; // sprmCFSpec true if( bWrtWW8 ) - Set_UInt16( pArr, 0x855 ); //sprmCFSpec + Set_UInt16( pArr, NS_sprm::LN_CFSpec ); else Set_UInt8( pArr, 117 ); //sprmCFSpec Set_UInt8( pArr, 1 ); @@ -2420,46 +2415,128 @@ String FieldString(ww::eField eIndex) return sRet; } -void OutWW8_RefField(SwWW8Writer& rWW8Wrt, const SwField &rFld, - const String &rRef) +void WW8AttributeOutput::HiddenField( const SwField& rFld ) { - String sStr(FieldString(ww::eREF)); - sStr.APPEND_CONST_ASC("\""); - sStr += rRef; - sStr.APPEND_CONST_ASC( "\" " ); - rWW8Wrt.OutField(&rFld, ww::eREF, sStr, WRITEFIELD_START | + String sExpand(rFld.GetPar2()); + + //replace LF 0x0A with VT 0x0B + sExpand.SearchAndReplaceAll(0x0A, 0x0B); + m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell()); + if (m_rWW8Export.IsUnicode()) + { + SwWW8Writer::WriteString16(m_rWW8Export.Strm(), sExpand, false); + static BYTE aArr[] = + { + 0x3C, 0x08, 0x1 + }; + m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell(), sizeof(aArr), aArr); + } + else + { + SwWW8Writer::WriteString8(m_rWW8Export.Strm(), sExpand, false, + RTL_TEXTENCODING_MS_1252); + static BYTE aArr[] = + { + 92, 0x1 + }; + m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell(), sizeof(aArr), aArr); + } +} + +void WW8AttributeOutput::SetField( const SwField& rFld, ww::eField eType, const String& rCmd ) +{ + const SwSetExpField* pSet=(const SwSetExpField*)(&rFld); + const String &rVar = pSet->GetPar2(); + + ULONG nFrom = m_rWW8Export.Fc2Cp(m_rWW8Export.Strm().Tell()); + + GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_START | WRITEFIELD_CMD_START | WRITEFIELD_CMD_END); - String sVar = lcl_GetExpandedField(rFld); - if (sVar.Len()) + + /* + Is there a bookmark at the start position of this field, if so + move it to the 0x14 of the result of the field. This is what word + does. MoveFieldMarks moves any bookmarks at this position to + the beginning of the field result, and marks the bookmark as a + fieldbookmark which is to be ended before the field end mark + instead of after it like a normal bookmark. + */ + m_rWW8Export.MoveFieldMarks(nFrom,m_rWW8Export.Fc2Cp(m_rWW8Export.Strm().Tell())); + + if (rVar.Len()) { - if (rWW8Wrt.IsUnicode()) - SwWW8Writer::WriteString16(rWW8Wrt.Strm(), sVar, false); + if (m_rWW8Export.IsUnicode()) + SwWW8Writer::WriteString16(m_rWW8Export.Strm(), rVar, false); else { - SwWW8Writer::WriteString8(rWW8Wrt.Strm(), sVar, false, + SwWW8Writer::WriteString8(m_rWW8Export.Strm(), rVar, false, RTL_TEXTENCODING_MS_1252); } } - rWW8Wrt.OutField(&rFld, ww::eREF, sStr, WRITEFIELD_CLOSE); + GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_CLOSE); +} + +void WW8AttributeOutput::PostitField( const SwField* pFld ) +{ + const SwPostItField& rPFld = *(SwPostItField*)pFld; + m_rWW8Export.pAtn->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), rPFld ); + m_rWW8Export.WritePostItBegin( m_rWW8Export.pO ); +} + +bool WW8AttributeOutput::DropdownField( const SwField* pFld ) +{ + bool bExpand = true; + if ( m_rWW8Export.bWrtWW8 ) + { + const SwDropDownField& rFld2 = *(SwDropDownField*)pFld; + uno::Sequence<rtl::OUString> aItems = + rFld2.GetItemSequence(); + GetExport().DoComboBox(rFld2.GetName(), + rFld2.GetHelp(), + rFld2.GetToolTip(), + rFld2.GetSelectedItem(), aItems); + bExpand = false; + } + return bExpand; } -void WriteExpand(SwWW8Writer& rWW8Wrt, const SwField &rFld) +void WW8AttributeOutput::RefField( const SwField &rFld, const String &rRef) { - String sExpand(lcl_GetExpandedField(rFld)); - if (rWW8Wrt.IsUnicode()) - SwWW8Writer::WriteString16(rWW8Wrt.Strm(), sExpand, false); + String sStr( FieldString( ww::eREF ) ); + sStr.APPEND_CONST_ASC( "\"" ); + sStr += rRef; + sStr.APPEND_CONST_ASC( "\" " ); + m_rWW8Export.OutputField( &rFld, ww::eREF, sStr, WRITEFIELD_START | + WRITEFIELD_CMD_START | WRITEFIELD_CMD_END ); + String sVar = lcl_GetExpandedField( rFld ); + if ( sVar.Len() ) + { + if ( m_rWW8Export.IsUnicode() ) + SwWW8Writer::WriteString16( m_rWW8Export.Strm(), sVar, false ); + else + { + SwWW8Writer::WriteString8( m_rWW8Export.Strm(), sVar, false, + RTL_TEXTENCODING_MS_1252 ); + } + } + m_rWW8Export.OutputField( &rFld, ww::eREF, sStr, WRITEFIELD_CLOSE ); +} + +void WW8AttributeOutput::WriteExpand( const SwField* pFld ) +{ + String sExpand( lcl_GetExpandedField( *pFld ) ); + if ( m_rWW8Export.IsUnicode() ) + SwWW8Writer::WriteString16( m_rWW8Export.Strm(), sExpand, false ); else { - SwWW8Writer::WriteString8(rWW8Wrt.Strm(), sExpand, false, - RTL_TEXTENCODING_MS_1252); + SwWW8Writer::WriteString8( m_rWW8Export.Strm(), sExpand, false, + RTL_TEXTENCODING_MS_1252 ); } } -static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) +void AttributeOutputBase::TextField( const SwFmtFld& rField ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - const SwFmtFld& rFld = (SwFmtFld&)rHt; - const SwField* pFld = rFld.GetFld(); + const SwField* pFld = rField.GetFld(); String sStr; // fuer optionale Parameter bool bWriteExpand = false; USHORT nSubType = pFld->GetSubType(); @@ -2470,7 +2547,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) if (nSubType == nsSwGetSetExpType::GSE_STRING) { const SwGetExpField *pGet=(const SwGetExpField*)(pFld); - OutWW8_RefField(rWW8Wrt, *pGet, pGet->GetFormula()); + RefField( *pGet, pGet->GetFormula() ); } else bWriteExpand = true; @@ -2483,8 +2560,8 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) sStr += pFld->GetTyp()->GetName(); sStr.APPEND_CONST_ASC( "\" " ); - ::WW8_GetNumberPara( sStr, *pFld ); - rWW8Wrt.OutField(pFld, ww::eSEQ, sStr); + GetNumberPara( sStr, *pFld ); + GetExport().OutputField(pFld, ww::eSEQ, sStr); } else if (nSubType & nsSwGetSetExpType::GSE_STRING) { @@ -2514,69 +2591,44 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) bShowAsWell = (nSubType & nsSwExtendedSubType::SUB_INVISIBLE) ? false : true; } - ULONG nFrom = rWW8Wrt.Fc2Cp(rWrt.Strm().Tell()); - - rWW8Wrt.OutField(pFld, eFieldNo, sStr, WRITEFIELD_START | - WRITEFIELD_CMD_START | WRITEFIELD_CMD_END); - - /* - Is there a bookmark at the start position of this field, if so - move it to the 0x14 of the result of the field. This is what word - does. MoveFieldMarks moves any bookmarks at this position to - the beginning of the field result, and marks the bookmark as a - fieldbookmark which is to be ended before the field end mark - instead of after it like a normal bookmark. - */ - rWW8Wrt.MoveFieldMarks(nFrom,rWW8Wrt.Fc2Cp(rWrt.Strm().Tell())); - - if (rVar.Len()) - { - if (rWW8Wrt.IsUnicode()) - SwWW8Writer::WriteString16(rWrt.Strm(), rVar, false); - else - { - SwWW8Writer::WriteString8(rWrt.Strm(), rVar, false, - RTL_TEXTENCODING_MS_1252); - } - } - rWW8Wrt.OutField(pFld, eFieldNo, sStr, WRITEFIELD_CLOSE); + SetField( *pFld, eFieldNo, sStr ); if (bShowAsWell) - OutWW8_RefField(rWW8Wrt, *pSet, pSet->GetPar1()); + RefField( *pSet, pSet->GetPar1() ); } else bWriteExpand = true; break; case RES_PAGENUMBERFLD: sStr = FieldString(ww::ePAGE); - ::WW8_GetNumberPara(sStr, *pFld); - rWW8Wrt.OutField(pFld, ww::ePAGE, sStr); + GetNumberPara(sStr, *pFld); + GetExport().OutputField(pFld, ww::ePAGE, sStr); break; case RES_FILENAMEFLD: sStr = FieldString(ww::eFILENAME); if (pFld->GetFormat() == FF_PATHNAME) sStr.APPEND_CONST_ASC("\\p "); - rWW8Wrt.OutField(pFld, ww::eFILENAME, sStr); + GetExport().OutputField(pFld, ww::eFILENAME, sStr); break; case RES_DBNAMEFLD: { sStr = FieldString(ww::eDATABASE); - SwDBData aData = rWrt.pDoc->GetDBData(); + SwDBData aData = GetExport().pDoc->GetDBData(); sStr += String(aData.sDataSource); sStr += DB_DELIM; sStr += String(aData.sCommand); - rWW8Wrt.OutField(pFld, ww::eDATABASE, sStr); + GetExport().OutputField(pFld, ww::eDATABASE, sStr); } break; case RES_AUTHORFLD: { ww::eField eFld = (AF_SHORTCUT & nSubType ? ww::eUSERINITIALS : ww::eUSERNAME); - rWW8Wrt.OutField(pFld, eFld, FieldString(eFld)); + GetExport().OutputField(pFld, eFld, FieldString(eFld)); } break; case RES_TEMPLNAMEFLD: - rWW8Wrt.OutField(pFld, ww::eTEMPLATE, FieldString(ww::eTEMPLATE)); + GetExport().OutputField(pFld, ww::eTEMPLATE, FieldString(ww::eTEMPLATE)); break; case RES_DOCINFOFLD: // Last printed, last edited,... if( DI_SUB_FIXED & nSubType ) @@ -2604,25 +2656,25 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) case DI_CREATE: if (DI_SUB_AUTHOR == (nSubType & DI_SUB_MASK)) eFld = ww::eAUTHOR; - else if (rWW8Wrt.GetNumberFmt(*pFld, sStr)) + else if (GetExport().GetNumberFmt(*pFld, sStr)) eFld = ww::eCREATEDATE; break; case DI_CHANGE: if (DI_SUB_AUTHOR == (nSubType & DI_SUB_MASK)) eFld = ww::eLASTSAVEDBY; - else if (rWW8Wrt.GetNumberFmt(*pFld, sStr)) + else if (GetExport().GetNumberFmt(*pFld, sStr)) eFld = ww::eSAVEDATE; break; case DI_PRINT: if (DI_SUB_AUTHOR != (nSubType & DI_SUB_MASK) && - rWW8Wrt.GetNumberFmt(*pFld, sStr)) + GetExport().GetNumberFmt(*pFld, sStr)) eFld = ww::ePRINTDATE; break; case DI_EDIT: if( DI_SUB_AUTHOR != (nSubType & DI_SUB_MASK ) && - rWW8Wrt.GetNumberFmt( *pFld, sStr )) + GetExport().GetNumberFmt( *pFld, sStr )) eFld = ww::eSAVEDATE; break; case DI_CUSTOM: @@ -2653,20 +2705,20 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) if (eFld != ww::eNONE) { sStr.Insert(FieldString(eFld), 0); - rWW8Wrt.OutField(pFld, eFld, sStr); + GetExport().OutputField(pFld, eFld, sStr); } else bWriteExpand = true; } break; case RES_DATETIMEFLD: - if (FIXEDFLD & nSubType || !rWW8Wrt.GetNumberFmt(*pFld, sStr)) + if (FIXEDFLD & nSubType || !GetExport().GetNumberFmt(*pFld, sStr)) bWriteExpand = true; else { ww::eField eFld = (DATEFLD & nSubType) ? ww::eDATE : ww::eTIME; sStr.Insert(FieldString(eFld), 0); - rWW8Wrt.OutField(pFld, eFld, sStr); + GetExport().OutputField(pFld, eFld, sStr); } break; case RES_DOCSTATFLD: @@ -2689,8 +2741,8 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) if (eFld != ww::eNONE) { sStr = FieldString(eFld); - ::WW8_GetNumberPara(sStr, *pFld); - rWW8Wrt.OutField(pFld, eFld, sStr); + GetNumberPara(sStr, *pFld); + GetExport().OutputField(pFld, eFld, sStr); } else bWriteExpand = true; @@ -2719,7 +2771,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) if (eFld != ww::eNONE) { sStr = FieldString(eFld); - rWW8Wrt.OutField(pFld, eFld, sStr); + GetExport().OutputField(pFld, eFld, sStr); } else bWriteExpand = true; @@ -2727,11 +2779,9 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) break; case RES_POSTITFLD: //Sadly only possible for word in main document text - if (rWW8Wrt.nTxtTyp == TXT_MAINTEXT) + if (GetExport().nTxtTyp == TXT_MAINTEXT) { - const SwPostItField& rPFld = *(SwPostItField*)pFld; - rWW8Wrt.pAtn->Append( rWW8Wrt.Fc2Cp( rWrt.Strm().Tell() ), rPFld ); - rWW8Wrt.WritePostItBegin( rWW8Wrt.pO ); + PostitField( pFld ); } break; case RES_INPUTFLD: @@ -2740,7 +2790,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) dynamic_cast<const SwInputField *>(pFld); if (pInputField->isFormField()) - rWW8Wrt.DoFormText(pInputField); + GetExport().DoFormText(pInputField); else { sStr = FieldString(ww::eFILLIN); @@ -2749,7 +2799,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) sStr += pFld->GetPar2(); sStr += '\"'; - rWW8Wrt.OutField(pFld, ww::eFILLIN, sStr); + GetExport().OutputField(pFld, ww::eFILLIN, sStr); } } break; @@ -2772,7 +2822,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) break; } sStr = FieldString(eFld); - sStr += rWW8Wrt.GetBookmarkName(nSubType, + sStr += GetExport().GetBookmarkName(nSubType, &rRFld.GetSetRefName(), 0); break; case REF_FOOTNOTE: @@ -2792,7 +2842,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) break; } sStr = FieldString(eFld); - sStr += rWW8Wrt.GetBookmarkName(nSubType, 0, + sStr += GetExport().GetBookmarkName(nSubType, 0, rRFld.GetSeqNo()); break; } @@ -2811,7 +2861,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) break; } sStr.APPEND_CONST_ASC(" \\h "); // insert hyperlink - rWW8Wrt.OutField(pFld, eFld, sStr); + GetExport().OutputField(pFld, eFld, sStr); } else bWriteExpand = true; @@ -2838,7 +2888,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) else nScript = i18n::ScriptType::ASIAN; - long nHeight = ((SvxFontHeightItem&)(((SwWW8Writer&)rWrt).GetItem( + long nHeight = ((SvxFontHeightItem&)(GetExport().GetItem( GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript)))).GetHeight();; nHeight = (nHeight + 10) / 20; //Font Size in points; @@ -2861,31 +2911,20 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) sStr.Append('('); sStr += String(pFld->GetPar1(),nAbove,pFld->GetPar1().Len()-nAbove); sStr.APPEND_CONST_ASC("))"); - rWW8Wrt.OutField(pFld, ww::eEQ, sStr); + GetExport().OutputField(pFld, ww::eEQ, sStr); } break; case RES_DROPDOWN: - if (rWW8Wrt.bWrtWW8) - { - const SwDropDownField& rFld2 = *(SwDropDownField*)pFld; - uno::Sequence<rtl::OUString> aItems = - rFld2.GetItemSequence(); - rWW8Wrt.DoComboBox(rFld2.GetName(), - rFld2.GetHelp(), - rFld2.GetToolTip(), - rFld2.GetSelectedItem(), aItems); - } - else - bWriteExpand = true; + bWriteExpand = DropdownField( pFld ); break; case RES_CHAPTERFLD: bWriteExpand = true; - if (rWW8Wrt.bOutKF && rFld.GetTxtFld()) + if (GetExport().bOutKF && rField.GetTxtFld()) { - const SwTxtNode *pTxtNd = rWW8Wrt.GetHdFtPageRoot(); + const SwTxtNode *pTxtNd = GetExport().GetHdFtPageRoot(); if (!pTxtNd) { - if (const SwNode *pNd = rWW8Wrt.pCurPam->GetNode()) + if (const SwNode *pNd = GetExport().pCurPam->GetNode()) pTxtNd = pNd->GetTxtNode(); } @@ -2893,7 +2932,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) { SwChapterField aCopy(*(const SwChapterField*)pFld); aCopy.ChangeExpansion(*pTxtNd, false); - WriteExpand(rWW8Wrt, aCopy); + WriteExpand( &aCopy ); bWriteExpand = false; } } @@ -2903,28 +2942,7 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) String sExpand(pFld->GetPar2()); if (sExpand.Len()) { - //replace LF 0x0A with VT 0x0B - sExpand.SearchAndReplaceAll(0x0A, 0x0B); - rWW8Wrt.pChpPlc->AppendFkpEntry(rWW8Wrt.Strm().Tell()); - if (rWW8Wrt.IsUnicode()) - { - SwWW8Writer::WriteString16(rWW8Wrt.Strm(), sExpand, false); - static BYTE aArr[] = - { - 0x3C, 0x08, 0x1 - }; - rWW8Wrt.pChpPlc->AppendFkpEntry(rWW8Wrt.Strm().Tell(), sizeof(aArr), aArr); - } - else - { - SwWW8Writer::WriteString8(rWW8Wrt.Strm(), sExpand, false, - RTL_TEXTENCODING_MS_1252); - static BYTE aArr[] = - { - 92, 0x1 - }; - rWW8Wrt.pChpPlc->AppendFkpEntry(rWW8Wrt.Strm().Tell(), sizeof(aArr), aArr); - } + HiddenField( *pFld ); } } break; @@ -2934,27 +2952,23 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt ) } if (bWriteExpand) - WriteExpand(rWW8Wrt, *pFld); - - return rWrt; + WriteExpand( pFld ); } -static Writer& OutWW8_SwFlyCntnt( Writer& rWrt, const SfxPoolItem& rHt ) +void AttributeOutputBase::TextFlyContent( const SwFmtFlyCnt& rFlyContent ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (rWrtWW8.pOutFmtNode && rWrtWW8.pOutFmtNode->ISA(SwCntntNode)) + if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwCntntNode ) ) { - SwTxtNode* pTxtNd = (SwTxtNode*)rWrtWW8.pOutFmtNode; + SwTxtNode* pTxtNd = (SwTxtNode*)GetExport().pOutFmtNode; Point aLayPos; - aLayPos = pTxtNd->FindLayoutRect(false, &aLayPos).Pos(); + aLayPos = pTxtNd->FindLayoutRect( false, &aLayPos ).Pos(); - SwPosition aPos(*pTxtNd); - sw::Frame aFrm(*((const SwFmtFlyCnt&)rHt).GetFrmFmt(), aPos); + SwPosition aPos( *pTxtNd ); + sw::Frame aFrm( *rFlyContent.GetFrmFmt(), aPos ); - rWrtWW8.OutWW8FlyFrm(aFrm, aLayPos); + OutputFlyFrame_Impl( aFrm, aLayPos ); } - return rWrt; } // TOXMarks fehlen noch @@ -2965,74 +2979,62 @@ static Writer& OutWW8_SwFlyCntnt( Writer& rWrt, const SfxPoolItem& rHt ) // --- // ACK. Dieser Vorschlag passt exakt zu unserer Implementierung des Import, // daher setze ich das gleich mal um. (KHZ, 07/15/2000) -static Writer& OutWW8_SvxHyphenZone( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone ) { -// sprmPFNoAutoHyph - const SvxHyphenZoneItem& rAttr = (const SvxHyphenZoneItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x242A ); + // sprmPFNoAutoHyph + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PFNoAutoHyph ); else - rWrtWW8.pO->Insert( 44, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( 44, m_rWW8Export.pO->Count() ); - rWrtWW8.pO->Insert( rAttr.IsHyphen() ? 0 : 1, rWrtWW8.pO->Count() ); - return rWrt; + m_rWW8Export.pO->Insert( rHyphenZone.IsHyphen() ? 0 : 1, m_rWW8Export.pO->Count() ); } -static Writer& OutWW8_SfxBoolItem( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace ) { USHORT nId = 0; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - switch ( rHt.Which() ) + if ( m_rWW8Export.bWrtWW8 ) + switch ( rScriptSpace.Which() ) { - case RES_PARATR_SCRIPTSPACE: nId = 0x2437; break; - case RES_PARATR_HANGINGPUNCTUATION: nId = 0x2435; break; - case RES_PARATR_FORBIDDEN_RULES: nId = 0x2433; break; + case RES_PARATR_SCRIPTSPACE: nId = NS_sprm::LN_PFAutoSpaceDE; break; + case RES_PARATR_HANGINGPUNCTUATION: nId = NS_sprm::LN_PFOverflowPunct; break; + case RES_PARATR_FORBIDDEN_RULES: nId = NS_sprm::LN_PFKinsoku; break; } - if( nId ) + if ( nId ) { - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( nId ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( nId ); else - rWrtWW8.pO->Insert( (BYTE)nId, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( (BYTE)nId, m_rWW8Export.pO->Count() ); - rWrtWW8.pO->Insert( ((SfxBoolItem&)rHt).GetValue() ? 1 : 0, - rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( rScriptSpace.GetValue() ? 1 : 0, + m_rWW8Export.pO->Count() ); } - return rWrt; } -static Writer& OutWW8_SvxParaGridItem(Writer& rWrt, const SfxPoolItem& rHt) +void WW8AttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid ) { -// sprmPFUsePgsuSettings - - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - //97+ only - if (!rWrtWW8.bWrtWW8) - return rWrt; + // sprmPFUsePgsuSettings + // 97+ only + if ( !m_rWW8Export.bWrtWW8 ) + return; - rWrtWW8.InsUInt16(0x2447); - const SvxParaGridItem& rAttr = (const SvxParaGridItem&)rHt; - rWrtWW8.pO->Insert( rAttr.GetValue(), rWrtWW8.pO->Count() ); - return rWrt; + m_rWW8Export.InsUInt16( NS_sprm::LN_PFUsePgsuSettings ); + m_rWW8Export.pO->Insert( rGrid.GetValue(), m_rWW8Export.pO->Count() ); } -static Writer& OutWW8_SvxParaVertAlignItem(Writer& rWrt, const SfxPoolItem& rHt) +void WW8AttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign ) { -// sprmPWAlignFont - - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - //97+ only - if( !rWrtWW8.bWrtWW8 ) - return rWrt; + // sprmPWAlignFont + // 97+ only + if( !m_rWW8Export.bWrtWW8 ) + return; - rWrtWW8.InsUInt16( 0x4439 ); - const SvxParaVertAlignItem & rAttr = (const SvxParaVertAlignItem&)rHt; + m_rWW8Export.InsUInt16( NS_sprm::LN_PWAlignFont ); - INT16 nVal = rAttr.GetValue(); - switch (nVal) + INT16 nVal = rAlign.GetValue(); + switch ( nVal ) { case SvxParaVertAlignItem::BASELINE: nVal = 2; @@ -3051,25 +3053,23 @@ static Writer& OutWW8_SvxParaVertAlignItem(Writer& rWrt, const SfxPoolItem& rHt) break; default: nVal = 4; - ASSERT(!(&rWrt), "Unknown vert alignment"); + ASSERT( false, "Unknown vert alignment" ); break; } - rWrtWW8.InsUInt16( nVal ); - return rWrt; + m_rWW8Export.InsUInt16( nVal ); } // NoHyphen: ich habe keine Entsprechung in der SW-UI und WW-UI gefunden -static Writer& OutWW8_SwHardBlank( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::TextHardBlank( const SwFmtHardBlank& rHardBlank ) { - ((SwWW8Writer&)rWrt).WriteChar( ((SwFmtHardBlank&)rHt).GetChar() ); - return rWrt; + m_rWW8Export.WriteChar( rHardBlank.GetChar() ); } // RefMark, NoLineBreakHere fehlen noch -void SwWW8Writer::WriteFtnBegin( const SwFmtFtn& rFtn, WW8Bytes* pOutArr ) +void WW8Export::WriteFtnBegin( const SwFmtFtn& rFtn, WW8Bytes* pOutArr ) { WW8Bytes aAttrArr; bool bAutoNum = !rFtn.GetNumStr().Len(); // Auto-Nummer @@ -3107,7 +3107,7 @@ void SwWW8Writer::WriteFtnBegin( const SwFmtFtn& rFtn, WW8Bytes* pOutArr ) ? pInfo->GetAnchorCharFmt( *pDoc ) : pInfo->GetCharFmt( *pDoc ); if( bWrtWW8 ) - SwWW8Writer::InsUInt16( aAttrArr, 0x4a30 ); + SwWW8Writer::InsUInt16( aAttrArr, NS_sprm::LN_CIstd ); else aAttrArr.Insert( 80, aAttrArr.Count() ); SwWW8Writer::InsUInt16( aAttrArr, GetId( *pCFmt ) ); @@ -3151,7 +3151,7 @@ void SwWW8Writer::WriteFtnBegin( const SwFmtFtn& rFtn, WW8Bytes* pOutArr ) pTxtFtn->GetTxtNode().GetAttr( aSet, *pTxtFtn->GetStart(), (*pTxtFtn->GetStart()) + 1 ); - ::OutWW8_SwFont( *this, aSet.Get( RES_CHRATR_FONT )); + m_pAttrOutput->OutputItem( aSet.Get( RES_CHRATR_FONT ) ); pO = pOld; } pChpPlc->AppendFkpEntry( Strm().Tell(), aOutArr.Count(), @@ -3180,84 +3180,81 @@ static bool lcl_IsAtTxtEnd(const SwFmtFtn& rFtn) } -static Writer& OutWW8_SwFtn( Writer& rWrt, const SfxPoolItem& rHt ) +void AttributeOutputBase::TextFootnote( const SwFmtFtn& rFtn ) { - const SwFmtFtn& rFtn = (const SwFmtFtn&)rHt; - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - USHORT nTyp; - WW8_WrPlcFtnEdn* pFtnEnd; - if( rFtn.IsEndNote() ) + if ( rFtn.IsEndNote() ) { - pFtnEnd = rWW8Wrt.pEdn; nTyp = REF_ENDNOTE; - if( rWW8Wrt.bEndAtTxtEnd ) - rWW8Wrt.bEndAtTxtEnd = lcl_IsAtTxtEnd( rFtn ); + if ( GetExport().bEndAtTxtEnd ) + GetExport().bEndAtTxtEnd = lcl_IsAtTxtEnd( rFtn ); } else { - pFtnEnd = rWW8Wrt.pFtn; nTyp = REF_FOOTNOTE; - if( rWW8Wrt.bFtnAtTxtEnd ) - rWW8Wrt.bFtnAtTxtEnd = lcl_IsAtTxtEnd( rFtn ); + if ( GetExport().bFtnAtTxtEnd ) + GetExport().bFtnAtTxtEnd = lcl_IsAtTxtEnd( rFtn ); } // if any reference to this footnote/endnote then insert an internal // Bookmark. String sBkmkNm; - if( rWW8Wrt.HasRefToObject( nTyp, 0, rFtn.GetTxtFtn()->GetSeqRefNo() )) + if ( GetExport().HasRefToObject( nTyp, 0, rFtn.GetTxtFtn()->GetSeqRefNo() )) { - sBkmkNm = rWW8Wrt.GetBookmarkName( nTyp, 0, + sBkmkNm = GetExport().GetBookmarkName( nTyp, 0, rFtn.GetTxtFtn()->GetSeqRefNo() ); - rWW8Wrt.AppendBookmark( sBkmkNm ); + GetExport().AppendBookmark( sBkmkNm ); } + TextFootnote_Impl( rFtn ); - pFtnEnd->Append( rWW8Wrt.Fc2Cp( rWrt.Strm().Tell() ), rFtn ); - rWW8Wrt.WriteFtnBegin( rFtn, rWW8Wrt.pO ); + if ( sBkmkNm.Len() ) + GetExport().AppendBookmark( sBkmkNm ); // FIXME: Why is it added twice? Shouldn't this one go to WW8AttributeOuput::TextFootnote_Impl()? +} - if( sBkmkNm.Len() ) - rWW8Wrt.AppendBookmark( sBkmkNm ); +void WW8AttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFtn ) +{ + WW8_WrPlcFtnEdn* pFtnEnd; + if ( rFtn.IsEndNote() ) + pFtnEnd = m_rWW8Export.pEdn; + else + pFtnEnd = m_rWW8Export.pFtn; - return rWrt; + pFtnEnd->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), rFtn ); + m_rWW8Export.WriteFtnBegin( rFtn, m_rWW8Export.pO ); } -static Writer& OutWW8_SwTxtCharFmt( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt ) { - const SwFmtCharFmt& rAttr = (const SwFmtCharFmt&)rHt; - if( rAttr.GetCharFmt() ) + if( rCharFmt.GetCharFmt() ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x4A30 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd ); else - rWrtWW8.pO->Insert( 80, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( 80, m_rWW8Export.pO->Count() ); - rWrtWW8.InsUInt16( rWrtWW8.GetId( *rAttr.GetCharFmt() ) ); + m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *rCharFmt.GetCharFmt() ) ); } - return rWrt; } /* See ww8par6.cxx Read_DoubleLine for some more info */ -static Writer& OutWW8_SvxTwoLinesItem( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines ) { // #i28331# - check that bOn is set - if((static_cast<const SvxTwoLinesItem&>(rHt)).GetValue()) + if ( rTwoLines.GetValue() ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; //97+ only - if( !rWrtWW8.bWrtWW8 ) - return rWrt; + if( !m_rWW8Export.bWrtWW8 ) + return; - const SvxTwoLinesItem& rAttr = (const SvxTwoLinesItem&)rHt; - rWrtWW8.InsUInt16( 0xCA78 ); - rWrtWW8.pO->Insert( (BYTE)0x06, rWrtWW8.pO->Count() ); //len 6 - rWrtWW8.pO->Insert( (BYTE)0x02, rWrtWW8.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_CEastAsianLayout ); + m_rWW8Export.pO->Insert( (BYTE)0x06, m_rWW8Export.pO->Count() ); //len 6 + m_rWW8Export.pO->Insert( (BYTE)0x02, m_rWW8Export.pO->Count() ); - sal_Unicode cStart = rAttr.GetStartBracket(); - sal_Unicode cEnd = rAttr.GetStartBracket(); + sal_Unicode cStart = rTwoLines.GetStartBracket(); + sal_Unicode cEnd = rTwoLines.GetStartBracket(); /* As per usual we have problems. We can have seperate left and right brackets @@ -3284,43 +3281,39 @@ static Writer& OutWW8_SvxTwoLinesItem( Writer& rWrt, const SfxPoolItem& rHt ) nType = 2; else nType = 1; - rWrtWW8.InsUInt16( nType ); + m_rWW8Export.InsUInt16( nType ); static const BYTE aZeroArr[ 3 ] = { 0, 0, 0 }; - rWrtWW8.pO->Insert( aZeroArr, 3, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( aZeroArr, 3, m_rWW8Export.pO->Count() ); } - return rWrt; } -static Writer& OutWW8_SwNumRuleItem( Writer& rWrt, const SfxPoolItem& rHt ) +void AttributeOutputBase::ParaNumRule( const SwNumRuleItem& rNumRule ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - const SwNumRuleItem& rNumRule = (const SwNumRuleItem&)rHt; - const SwTxtNode* pTxtNd = 0; USHORT nNumId; BYTE nLvl = 0; - if( rNumRule.GetValue().Len() ) + if ( rNumRule.GetValue().Len() ) { - const SwNumRule* pRule = rWrt.pDoc->FindNumRulePtr( + const SwNumRule* pRule = GetExport().pDoc->FindNumRulePtr( rNumRule.GetValue() ); - if( pRule && USHRT_MAX != ( nNumId = rWW8Wrt.GetId( *pRule )) ) + if ( pRule && USHRT_MAX != ( nNumId = GetExport().GetId( *pRule ) ) ) { ++nNumId; - if( rWW8Wrt.pOutFmtNode ) + if ( GetExport().pOutFmtNode ) { - if( rWW8Wrt.pOutFmtNode->ISA( SwCntntNode )) + if ( GetExport().pOutFmtNode->ISA( SwCntntNode ) ) { - pTxtNd = (SwTxtNode*)rWW8Wrt.pOutFmtNode; + pTxtNd = (SwTxtNode*)GetExport().pOutFmtNode; if( pTxtNd->IsCountedInList()) { nLvl = static_cast< BYTE >(pTxtNd->GetActualListLevel()); - if (pTxtNd->IsListRestart()) + if ( pTxtNd->IsListRestart() ) { - USHORT nStartWith = static_cast< USHORT >(pTxtNd->GetActualListStartValue()); - nNumId = rWW8Wrt.DupNumRuleWithLvlStart(pRule,nLvl,nStartWith); - if (USHRT_MAX != nNumId) + USHORT nStartWith = static_cast< USHORT >( pTxtNd->GetActualListStartValue() ); + nNumId = GetExport().DuplicateNumRule( pRule, nLvl, nStartWith ); + if ( USHRT_MAX != nNumId ) ++nNumId; } } @@ -3333,13 +3326,13 @@ static Writer& OutWW8_SwNumRuleItem( Writer& rWrt, const SfxPoolItem& rHt ) nNumId = 0; } } - else if( rWW8Wrt.pOutFmtNode->ISA( SwTxtFmtColl )) + else if ( GetExport().pOutFmtNode->ISA( SwTxtFmtColl ) ) { - const SwTxtFmtColl* pC = (SwTxtFmtColl*)rWW8Wrt.pOutFmtNode; + const SwTxtFmtColl* pC = (SwTxtFmtColl*)GetExport().pOutFmtNode; //if( pC && MAXLEVEL > pC->GetOutlineLevel() ) //#outline level,removed by zhaojianwei // nLvl = pC->GetOutlineLevel(); //<-end, ->add by zhaojianwei - if( pC && pC->IsAssignedToListLevelOfOutlineStyle() ) - nLvl = static_cast<BYTE>(pC->GetAssignedOutlineStyleLevel()); //<-end,zhaojianwei + if ( pC && pC->IsAssignedToListLevelOfOutlineStyle() ) + nLvl = static_cast< BYTE >( pC->GetAssignedOutlineStyleLevel() ); //<-end,zhaojianwei } } } @@ -3349,94 +3342,95 @@ static Writer& OutWW8_SwNumRuleItem( Writer& rWrt, const SfxPoolItem& rHt ) else nNumId = 0; - if (USHRT_MAX != nNumId) + if ( USHRT_MAX != nNumId ) { - if (nLvl >= WW8ListManager::nMaxLevel) - nLvl = WW8ListManager::nMaxLevel-1; - if( rWW8Wrt.bWrtWW8 ) - { - // write sprmPIlvl and sprmPIlfo - SwWW8Writer::InsUInt16( *rWW8Wrt.pO, 0x260a ); - rWW8Wrt.pO->Insert( nLvl, rWW8Wrt.pO->Count() ); - SwWW8Writer::InsUInt16( *rWW8Wrt.pO, 0x460b ); - SwWW8Writer::InsUInt16( *rWW8Wrt.pO, nNumId ); - } - else if( pTxtNd && rWW8Wrt.Out_SwNum( pTxtNd ) ) // NumRules - rWW8Wrt.pSepx->SetNum( pTxtNd ); + if ( nLvl >= WW8ListManager::nMaxLevel ) + nLvl = WW8ListManager::nMaxLevel - 1; + + ParaNumRule_Impl( pTxtNd, nLvl, nNumId ); + } +} + +void WW8AttributeOutput::ParaNumRule_Impl( const SwTxtNode* pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId ) +{ + if ( m_rWW8Export.bWrtWW8 ) + { + // write sprmPIlvl and sprmPIlfo + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlvl ); + m_rWW8Export.pO->Insert( ::sal::static_int_cast<BYTE>(nLvl), m_rWW8Export.pO->Count() ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlfo ); + SwWW8Writer::InsUInt16( *m_rWW8Export.pO, ::sal::static_int_cast<UINT16>(nNumId) ); } - return rWrt; + else if ( pTxtNd && m_rWW8Export.Out_SwNum( pTxtNd ) ) // NumRules + m_rWW8Export.pSepx->SetNum( pTxtNd ); } /* File FRMATR.HXX */ -static Writer& OutWW8_SwFrmSize( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - const SwFmtFrmSize& rSz = (const SwFmtFrmSize&)rHt; - - if( rWW8Wrt.bOutFlyFrmAttrs ) // Flys + if( m_rWW8Export.bOutFlyFrmAttrs ) // Flys { - if( rWW8Wrt.bOutGrf ) - return rWrt; // Fly um Grafik -> Auto-Groesse + if( m_rWW8Export.bOutGrf ) + return; // Fly um Grafik -> Auto-Groesse //???? was ist bei Prozentangaben ??? - if( rSz.GetWidth() && rSz.GetWidthSizeType() == ATT_FIX_SIZE) + if ( rSize.GetWidth() && rSize.GetWidthSizeType() == ATT_FIX_SIZE) { //"sprmPDxaWidth" - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x841A ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaWidth ); else - rWW8Wrt.pO->Insert( 28, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( (USHORT)rSz.GetWidth() ); + m_rWW8Export.pO->Insert( 28, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( (USHORT)rSize.GetWidth() ); } - if( rSz.GetHeight() ) + if ( rSize.GetHeight() ) { // sprmPWHeightAbs - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x442B ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PWHeightAbs ); else - rWW8Wrt.pO->Insert( 45, rWW8Wrt.pO->Count() ); + m_rWW8Export.pO->Insert( 45, m_rWW8Export.pO->Count() ); USHORT nH = 0; - switch( rSz.GetHeightSizeType() ) + switch ( rSize.GetHeightSizeType() ) { - case ATT_VAR_SIZE: break; - case ATT_FIX_SIZE: nH = (USHORT)rSz.GetHeight() & 0x7fff; break; - default: nH = (USHORT)rSz.GetHeight() | 0x8000; break; + case ATT_VAR_SIZE: break; + case ATT_FIX_SIZE: nH = (USHORT)rSize.GetHeight() & 0x7fff; break; + default: nH = (USHORT)rSize.GetHeight() | 0x8000; break; } - rWW8Wrt.InsUInt16( nH ); + m_rWW8Export.InsUInt16( nH ); } } - else if( rWW8Wrt.bOutPageDescs ) // PageDesc : Breite + Hoehe + else if( m_rWW8Export.bOutPageDescs ) // PageDesc : Breite + Hoehe { - if( rWW8Wrt.pAktPageDesc->GetLandscape() ) + if( m_rWW8Export.pAktPageDesc->GetLandscape() ) { /*sprmSBOrientation*/ - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x301d ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SBOrientation ); else - rWW8Wrt.pO->Insert( 162, rWW8Wrt.pO->Count() ); - rWW8Wrt.pO->Insert( 2, rWW8Wrt.pO->Count() ); + m_rWW8Export.pO->Insert( 162, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( 2, m_rWW8Export.pO->Count() ); } /*sprmSXaPage*/ - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0xB01F ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SXaPage ); else - rWW8Wrt.pO->Insert( 164, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( - msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSz.GetWidth()))); + m_rWW8Export.pO->Insert( 164, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( + msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSize.GetWidth()))); /*sprmSYaPage*/ - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0xB020 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SYaPage ); else - rWW8Wrt.pO->Insert( 165, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( - msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSz.GetHeight()))); + m_rWW8Export.pO->Insert( 165, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( + msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSize.GetHeight()))); } - return rWrt; } // FillOrder fehlt noch @@ -3446,7 +3440,7 @@ static Writer& OutWW8_SwFrmSize( Writer& rWrt, const SfxPoolItem& rHt ) // direkt nach Schreiben des CR gerufen werden. // Rueckgabe: FilePos des ersetzten CRs + 1 oder 0 fuer nicht ersetzt -ULONG SwWW8Writer::ReplaceCr( BYTE nChar ) +ULONG WW8Export::ReplaceCr( BYTE nChar ) { // Bug #49917# ASSERT( nChar, "gegen 0 ersetzt bringt WW97/95 zum Absturz" ); @@ -3527,12 +3521,12 @@ ULONG SwWW8Writer::ReplaceCr( BYTE nChar ) return nRetPos; } -void SwWW8Writer::WriteRowEnd(sal_uInt32 nDepth) +void WW8AttributeOutput::TableRowEnd(sal_uInt32 nDepth) { - if (nDepth == 1) - WriteChar( (BYTE)0x07 ); - else if (nDepth > 1) - WriteChar( (BYTE)0x0d ); + if ( nDepth == 1 ) + m_rWW8Export.WriteChar( (BYTE)0x07 ); + else if ( nDepth > 1 ) + m_rWW8Export.WriteChar( (BYTE)0x0d ); //Technically in a word document this is a different value for a row ends //that are not row ends directly after a cell with a graphic. But it @@ -3540,55 +3534,50 @@ void SwWW8Writer::WriteRowEnd(sal_uInt32 nDepth) //pMagicTable->Append(Fc2Cp(Strm().Tell()),0x1B6); } -static Writer& OutWW8_SwFmtPageDesc(Writer& rWrt, const SfxPoolItem& rHt) +void AttributeOutputBase::FormatPageDescription( const SwFmtPageDesc& rPageDesc ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - if (rWW8Wrt.bStyDef && rWW8Wrt.pOutFmtNode && rWW8Wrt.pOutFmtNode->ISA(SwTxtFmtColl)) + if ( GetExport().bStyDef && GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwTxtFmtColl ) ) { - const SwFmtPageDesc &rPgDesc = (const SwFmtPageDesc&)rHt; - const SwTxtFmtColl* pC = (SwTxtFmtColl*)rWW8Wrt.pOutFmtNode; - if ((SFX_ITEM_SET != pC->GetItemState(RES_BREAK, false)) && rPgDesc.GetRegisteredIn()) - OutWW8_SwFmtBreak(rWrt, SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK)); + const SwTxtFmtColl* pC = (SwTxtFmtColl*)GetExport().pOutFmtNode; + if ( (SFX_ITEM_SET != pC->GetItemState( RES_BREAK, false ) ) && rPageDesc.GetRegisteredIn() ) + FormatBreak( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) ); } - return rWrt; +} + +void WW8AttributeOutput::PageBreakBefore( bool bBreak ) +{ + // sprmPPageBreakBefore/sprmPFPageBreakBefore + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PFPageBreakBefore ); + else + m_rWW8Export.pO->Insert( 9, m_rWW8Export.pO->Count() ); + + m_rWW8Export.pO->Insert( bBreak ? 1 : 0, m_rWW8Export.pO->Count() ); } // Breaks schreiben nichts in das Ausgabe-Feld rWrt.pO, // sondern nur in den Text-Stream ( Bedingung dafuer, dass sie von Out_Break... // gerufen werden duerfen ) -static Writer& OutWW8_SwFmtBreak( Writer& rWrt, const SfxPoolItem& rHt ) +void AttributeOutputBase::FormatBreak( const SvxFmtBreakItem& rBreak ) { -/*UMSTELLEN*/ - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - const SvxFmtBreakItem &rBreak = (const SvxFmtBreakItem&)rHt; - - if( rWW8Wrt.bStyDef ) + if ( GetExport().bStyDef ) { - switch( rBreak.GetBreak() ) + switch ( rBreak.GetBreak() ) { -//JP 21.06.99: column breaks does never change to pagebreaks -// case SVX_BREAK_COLUMN_BEFORE: -// case SVX_BREAK_COLUMN_BOTH: - case SVX_BREAK_NONE: - case SVX_BREAK_PAGE_BEFORE: - case SVX_BREAK_PAGE_BOTH: - // sprmPPageBreakBefore/sprmPFPageBreakBefore - if (rWW8Wrt.bWrtWW8) - rWW8Wrt.InsUInt16(0x2407); - else - rWW8Wrt.pO->Insert(9, rWW8Wrt.pO->Count()); - rWW8Wrt.pO->Insert(rBreak.GetValue() ? 1 : 0, - rWW8Wrt.pO->Count()); - break; - default: - break; + // JP 21.06.99: column breaks never change to pagebreaks + // case SVX_BREAK_COLUMN_BEFORE: + // case SVX_BREAK_COLUMN_BOTH: + case SVX_BREAK_NONE: + case SVX_BREAK_PAGE_BEFORE: + case SVX_BREAK_PAGE_BOTH: + PageBreakBefore( rBreak.GetValue() ); + break; + default: + break; } } - else if (!rWW8Wrt.mpParentFrame) + else if ( !GetExport().mpParentFrame ) { - static const BYTE cColBreak = 0xe; - static const BYTE cPageBreak = 0xc; - BYTE nC = 0; bool bBefore = false; // --> OD 2007-05-29 #i76300# @@ -3596,95 +3585,83 @@ static Writer& OutWW8_SwFmtBreak( Writer& rWrt, const SfxPoolItem& rHt ) bool bCheckForFollowPageDesc = false; // <-- - switch( rBreak.GetBreak() ) + switch ( rBreak.GetBreak() ) { - case SVX_BREAK_NONE: // Ausgeschaltet - if( !rWW8Wrt.bBreakBefore ) - { - // sprmPPageBreakBefore/sprmPFPageBreakBefore - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x2407 ); - else - rWW8Wrt.pO->Insert( 9, rWW8Wrt.pO->Count() ); - rWW8Wrt.pO->Insert( (BYTE)0, rWW8Wrt.pO->Count() ); - } - return rWrt; + case SVX_BREAK_NONE: // Ausgeschaltet + if ( !GetExport().bBreakBefore ) + PageBreakBefore( false ); + return; - case SVX_BREAK_COLUMN_BEFORE: // ColumnBreak - bBefore = true; + case SVX_BREAK_COLUMN_BEFORE: // ColumnBreak + bBefore = true; // no break; - case SVX_BREAK_COLUMN_AFTER: - case SVX_BREAK_COLUMN_BOTH: - ASSERT (rWW8Wrt.pSepx, "how come this is 0"); - if (rWW8Wrt.pSepx && - rWW8Wrt.pSepx->CurrentNoColumns(*rWW8Wrt.pDoc) > 1) - { - nC = cColBreak; - } - break; + case SVX_BREAK_COLUMN_AFTER: + case SVX_BREAK_COLUMN_BOTH: + if ( GetExport().Sections().CurrentNumberOfColumns( *GetExport().pDoc ) > 1 ) + { + nC = msword::ColumnBreak; + } + break; - case SVX_BREAK_PAGE_BEFORE: // PageBreak - // From now on(fix for #i77900#) we prefer to save a page break as - // paragraph attribute, this has to be done after the export of the - // paragraph ( => !rWW8Wrt.bBreakBefore ) - if( !rWW8Wrt.bBreakBefore ) - { - // sprmPPageBreakBefore/sprmPFPageBreakBefore - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x2407 ); - else - rWW8Wrt.pO->Insert( 9, rWW8Wrt.pO->Count() ); - rWW8Wrt.pO->Insert( (BYTE)1, rWW8Wrt.pO->Count() ); - } - break; - case SVX_BREAK_PAGE_AFTER: - case SVX_BREAK_PAGE_BOTH: - nC = cPageBreak; - // --> OD 2007-05-29 #i76300# - // check for follow page description, if current writing attributes - // of a paragraph. - if ( dynamic_cast<const SwTxtNode*>(rWW8Wrt.pOutFmtNode) && - rWW8Wrt.GetCurItemSet() ) - { - bCheckForFollowPageDesc = true; - } - // <-- - break; - default: - break; + case SVX_BREAK_PAGE_BEFORE: // PageBreak + // From now on(fix for #i77900#) we prefer to save a page break as + // paragraph attribute, this has to be done after the export of the + // paragraph ( => !GetExport().bBreakBefore ) + if ( !GetExport().bBreakBefore ) + PageBreakBefore( true ); + break; + + case SVX_BREAK_PAGE_AFTER: + case SVX_BREAK_PAGE_BOTH: + nC = msword::PageBreak; + // --> OD 2007-05-29 #i76300# + // check for follow page description, if current writing attributes + // of a paragraph. + if ( dynamic_cast< const SwTxtNode* >( GetExport().pOutFmtNode ) && + GetExport().GetCurItemSet() ) + { + bCheckForFollowPageDesc = true; + } + // <-- + break; + + default: + break; } - if ( (bBefore == rWW8Wrt.bBreakBefore ) && nC ) // #49917# + if ( ( bBefore == GetExport().bBreakBefore ) && nC ) // #49917# { // --> OD 2007-05-29 #i76300# - bool bFollowPageDescWritten( false ); + bool bFollowPageDescWritten = false; if ( bCheckForFollowPageDesc && !bBefore ) { bFollowPageDescWritten = - rWW8Wrt.Out_FollowPageDesc( rWW8Wrt.GetCurItemSet(), - dynamic_cast<const SwTxtNode*>(rWW8Wrt.pOutFmtNode) ); + GetExport().OutputFollowPageDesc( GetExport().GetCurItemSet(), + dynamic_cast<const SwTxtNode*>( GetExport().pOutFmtNode ) ); } if ( !bFollowPageDescWritten ) { - rWW8Wrt.ReplaceCr( nC ); + SectionBreak( nC ); } // <-- } } - return rWrt; } -static Writer& OutWW8_SwTextGrid( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::SectionBreak( BYTE nC, const WW8_SepInfo* /*pSectionInfo*/ ) +{ + m_rWW8Export.ReplaceCr( nC ); +} + +void WW8AttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (rWrtWW8.bOutPageDescs && rWrtWW8.bWrtWW8) + if ( m_rWW8Export.bOutPageDescs && m_rWW8Export.bWrtWW8 ) { - const SwTextGridItem& rItem = (const SwTextGridItem&)rHt; - UINT16 nGridType=0; - switch (rItem.GetGridType()) + UINT16 nGridType = 0; + switch ( rGrid.GetGridType() ) { default: - ASSERT(!(&rWrt), "Unknown grid type"); + ASSERT(false, "Unknown grid type"); case GRID_NONE: nGridType = 0; break; @@ -3692,103 +3669,86 @@ static Writer& OutWW8_SwTextGrid( Writer& rWrt, const SfxPoolItem& rHt ) nGridType = 2; break; case GRID_LINES_CHARS: - { - if(rItem.IsSnapToChars()) - { - nGridType = 3; - } - else - { - nGridType = 1; - } - } + if ( rGrid.IsSnapToChars() ) + nGridType = 3; + else + nGridType = 1; break; } - rWrtWW8.InsUInt16(0x5032); - rWrtWW8.InsUInt16(nGridType); + m_rWW8Export.InsUInt16( NS_sprm::LN_SClm ); + m_rWW8Export.InsUInt16( nGridType ); - UINT16 nHeight = rItem.GetBaseHeight() + rItem.GetRubyHeight(); - rWrtWW8.InsUInt16(0x9031); - rWrtWW8.InsUInt16(nHeight); - sal_uInt32 nPageCharSize = ItemGet<SvxFontHeightItem>(*(rWrtWW8.pStyles->GetSwFmt()), + UINT16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight(); + m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaLinePitch ); + m_rWW8Export.InsUInt16( nHeight ); + sal_uInt32 nPageCharSize = ItemGet<SvxFontHeightItem>(*(m_rWW8Export.pStyles->GetSwFmt()), RES_CHRATR_CJK_FONTSIZE).GetHeight(); - INT32 nCharWidth = rItem.GetBaseWidth() - nPageCharSize; - INT32 nFraction = 0; - nFraction = nCharWidth%20; - if( nCharWidth < 0 ) + INT32 nCharWidth = rGrid.GetBaseWidth() - nPageCharSize; + INT32 nFraction = 0; + nFraction = nCharWidth % 20; + if ( nCharWidth < 0 ) nFraction = 20 + nFraction; - nFraction = ((nFraction)*0xFFF)/20; - nFraction = (nFraction & 0x00000FFF); + nFraction = ( nFraction * 0xFFF ) / 20; + nFraction = ( nFraction & 0x00000FFF ); - INT32 nMain = 0; - nMain = nCharWidth/20; - if( nCharWidth < 0 ) + INT32 nMain = 0; + nMain = nCharWidth / 20; + if ( nCharWidth < 0 ) nMain -= 1; - nMain = nMain * 0x1000; - nMain = (nMain & 0xFFFFF000); + nMain = nMain * 0x1000; + nMain = ( nMain & 0xFFFFF000 ); - UINT32 nCharSpace = nFraction + nMain; - rWrtWW8.InsUInt16(0x7030); - rWrtWW8.InsUInt32(nCharSpace); + UINT32 nCharSpace = nFraction + nMain; + m_rWW8Export.InsUInt16( NS_sprm::LN_SDxtCharSpace ); + m_rWW8Export.InsUInt32( nCharSpace ); } - return rWrt; } -static Writer& OutWW8_SvxPaperBin( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatPaperBin( const SvxPaperBinItem& rPaperBin ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - const SvxPaperBinItem& rItem = (const SvxPaperBinItem&)rHt; - - if( rWrtWW8.bOutPageDescs ) + if ( m_rWW8Export.bOutPageDescs ) { USHORT nVal; - switch( rItem.GetValue() ) + switch ( rPaperBin.GetValue() ) { - case 0: nVal = 15; break; // Automatically select - case 1: nVal = 1; break; // Upper paper tray - case 2: nVal = 4; break; // Manual paper feed - default: nVal = 0; break; + case 0: nVal = 15; break; // Automatically select + case 1: nVal = 1; break; // Upper paper tray + case 2: nVal = 4; break; // Manual paper feed + default: nVal = 0; break; } - if( nVal ) + if ( nVal ) { - // sprmSDmBinFirst 0x5007 word - // sprmSDmBinOther 0x5008 word - BYTE nOff = rWrtWW8.bOutFirstPage ? 0 : 1; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x5007 + nOff ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( m_rWW8Export.bOutFirstPage? NS_sprm::LN_SDmBinFirst: NS_sprm::LN_SDmBinOther ); else - rWrtWW8.pO->Insert( 140 + nOff, rWrtWW8.pO->Count() ); - rWrtWW8.InsUInt16( nVal ); + m_rWW8Export.pO->Insert( m_rWW8Export.bOutFirstPage? 140: 141, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( nVal ); } } - return rWrt; } -static Writer& OutWW8_SwFmtLRSpace( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLR ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - const SvxLRSpaceItem & rLR = (const SvxLRSpaceItem&) rHt; - - // Flys fehlen noch ( siehe RTF ) - if( rWW8Wrt.bOutFlyFrmAttrs ) // Flys + if ( m_rWW8Export.bOutFlyFrmAttrs ) // Flys { // sprmPDxaFromText10 - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x4622 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaFromText10 ); else - rWW8Wrt.pO->Insert( 49, rWW8Wrt.pO->Count() ); + m_rWW8Export.pO->Insert( 49, m_rWW8Export.pO->Count() ); // Mittelwert nehmen, da WW nur 1 Wert kennt - rWW8Wrt.InsUInt16( (USHORT) ( ( rLR.GetLeft() + rLR.GetRight() ) / 2 ) ); + m_rWW8Export.InsUInt16( (USHORT) ( ( rLR.GetLeft() + rLR.GetRight() ) / 2 ) ); } - else if( rWW8Wrt.bOutPageDescs ) // PageDescs + else if ( m_rWW8Export.bOutPageDescs ) // PageDescs { USHORT nLDist, nRDist; - const SfxPoolItem* pItem = ((SwWW8Writer&)rWrt).HasItem( RES_BOX ); - if( pItem ) + const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_BOX ); + if ( pItem ) { nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT ); nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT ); @@ -3799,249 +3759,235 @@ static Writer& OutWW8_SwFmtLRSpace( Writer& rWrt, const SfxPoolItem& rHt ) nRDist = nRDist + (USHORT)rLR.GetRight(); // sprmSDxaLeft - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0xB021 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaLeft ); else - rWW8Wrt.pO->Insert( 166, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( nLDist ); + m_rWW8Export.pO->Insert( 166, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( nLDist ); + // sprmSDxaRight - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0xB022 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaRight ); else - rWW8Wrt.pO->Insert( 167, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( nRDist ); + m_rWW8Export.pO->Insert( 167, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( nRDist ); } else { // normale Absaetze // sprmPDxaLeft - if( rWW8Wrt.bWrtWW8 ) + if( m_rWW8Export.bWrtWW8 ) { - rWW8Wrt.InsUInt16( 0x845E ); //asian version ? - rWW8Wrt.InsUInt16( (USHORT)rLR.GetTxtLeft() ); - + m_rWW8Export.InsUInt16( 0x845E ); //asian version ? + m_rWW8Export.InsUInt16( (USHORT)rLR.GetTxtLeft() ); } else { - rWW8Wrt.pO->Insert( 17, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( (USHORT)rLR.GetTxtLeft() ); + m_rWW8Export.pO->Insert( 17, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( (USHORT)rLR.GetTxtLeft() ); } + // sprmPDxaRight - if( rWW8Wrt.bWrtWW8 ) + if( m_rWW8Export.bWrtWW8 ) { - rWW8Wrt.InsUInt16( 0x845D ); //asian version ? - rWW8Wrt.InsUInt16( (USHORT)rLR.GetRight() ); + m_rWW8Export.InsUInt16( 0x845D ); //asian version ? + m_rWW8Export.InsUInt16( (USHORT)rLR.GetRight() ); } else { - rWW8Wrt.pO->Insert( 16, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( (USHORT)rLR.GetRight() ); + m_rWW8Export.pO->Insert( 16, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( (USHORT)rLR.GetRight() ); } + // sprmPDxaLeft1 - if( rWW8Wrt.bWrtWW8 ) + if( m_rWW8Export.bWrtWW8 ) { - rWW8Wrt.InsUInt16( 0x8460 ); //asian version ? - rWW8Wrt.InsUInt16( rLR.GetTxtFirstLineOfst() ); + m_rWW8Export.InsUInt16( 0x8460 ); //asian version ? + m_rWW8Export.InsUInt16( rLR.GetTxtFirstLineOfst() ); } else { - rWW8Wrt.pO->Insert( 19, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( rLR.GetTxtFirstLineOfst() ); + m_rWW8Export.pO->Insert( 19, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( rLR.GetTxtFirstLineOfst() ); } } - return rWrt; } -static Writer& OutWW8_SwFmtULSpace( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatULSpace( const SvxULSpaceItem& rUL ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - const SvxULSpaceItem & rUL = (const SvxULSpaceItem&) rHt; - // Flys fehlen noch ( siehe RTF ) - if( rWW8Wrt.bOutFlyFrmAttrs ) // Flys + if ( m_rWW8Export.bOutFlyFrmAttrs ) // Flys { // sprmPDyaFromText - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x842E ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaFromText ); else - rWW8Wrt.pO->Insert( 48, rWW8Wrt.pO->Count() ); + m_rWW8Export.pO->Insert( 48, m_rWW8Export.pO->Count() ); // Mittelwert nehmen, da WW nur 1 Wert kennt - rWW8Wrt.InsUInt16( (USHORT) ( ( rUL.GetUpper() + rUL.GetLower() ) / 2 ) ); + m_rWW8Export.InsUInt16( (USHORT) ( ( rUL.GetUpper() + rUL.GetLower() ) / 2 ) ); } - else if( rWW8Wrt.bOutPageDescs ) // Page-UL + else if ( m_rWW8Export.bOutPageDescs ) // Page-UL { - ASSERT(rWW8Wrt.GetCurItemSet(), "Impossible"); - if (!rWW8Wrt.GetCurItemSet()) - return rWrt; + ASSERT( m_rWW8Export.GetCurItemSet(), "Impossible" ); + if ( !m_rWW8Export.GetCurItemSet() ) + return; - HdFtDistanceGlue aDistances(*rWW8Wrt.GetCurItemSet()); + HdFtDistanceGlue aDistances( *m_rWW8Export.GetCurItemSet() ); - if (aDistances.HasHeader()) + if ( aDistances.HasHeader() ) { //sprmSDyaHdrTop - if (rWW8Wrt.bWrtWW8) - rWW8Wrt.InsUInt16(0xB017); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaHdrTop ); else - rWW8Wrt.pO->Insert(156, rWW8Wrt.pO->Count()); - rWW8Wrt.InsUInt16(aDistances.dyaHdrTop); + m_rWW8Export.pO->Insert( 156, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( aDistances.dyaHdrTop ); } // sprmSDyaTop - if (rWW8Wrt.bWrtWW8) - rWW8Wrt.InsUInt16(0x9023); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaTop ); else - rWW8Wrt.pO->Insert(168, rWW8Wrt.pO->Count()); - rWW8Wrt.InsUInt16(aDistances.dyaTop); + m_rWW8Export.pO->Insert( 168, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( aDistances.dyaTop ); - if (aDistances.HasFooter()) + if ( aDistances.HasFooter() ) { //sprmSDyaHdrBottom - if (rWW8Wrt.bWrtWW8) - rWW8Wrt.InsUInt16(0xB018); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaHdrBottom ); else - rWW8Wrt.pO->Insert(157, rWW8Wrt.pO->Count()); - rWW8Wrt.InsUInt16(aDistances.dyaHdrBottom); + m_rWW8Export.pO->Insert( 157, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( aDistances.dyaHdrBottom ); } //sprmSDyaBottom - if (rWW8Wrt.bWrtWW8) - rWW8Wrt.InsUInt16(0x9024); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaBottom ); else - rWW8Wrt.pO->Insert(169, rWW8Wrt.pO->Count()); - rWW8Wrt.InsUInt16(aDistances.dyaBottom); + m_rWW8Export.pO->Insert( 169, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( aDistances.dyaBottom ); } else { // sprmPDyaBefore - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0xA413 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaBefore ); else - rWW8Wrt.pO->Insert( 21, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( rUL.GetUpper() ); + m_rWW8Export.pO->Insert( 21, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( rUL.GetUpper() ); // sprmPDyaAfter - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0xA414 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaAfter ); else - rWW8Wrt.pO->Insert( 22, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( rUL.GetLower() ); + m_rWW8Export.pO->Insert( 22, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( rUL.GetLower() ); } - return rWrt; } // Print, Opaque, Protect fehlen noch -static Writer& OutWW8_SwFmtSurround( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatSurround( const SwFmtSurround& rSurround ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - if( rWW8Wrt.bOutFlyFrmAttrs ) + if ( m_rWW8Export.bOutFlyFrmAttrs ) { - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x2423 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PWr ); else - rWW8Wrt.pO->Insert( 37, rWW8Wrt.pO->Count() ); + m_rWW8Export.pO->Insert( 37, m_rWW8Export.pO->Count() ); - rWW8Wrt.pO->Insert( (SURROUND_NONE != - ((const SwFmtSurround&) rHt).GetSurround() ) - ? 2 : 1, rWW8Wrt.pO->Count() ); + m_rWW8Export.pO->Insert( + ( SURROUND_NONE != rSurround.GetSurround() ) ? 2 : 1, + m_rWW8Export.pO->Count() ); } - return rWrt; } -Writer& OutWW8_SwFmtVertOrient( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - //!!!! Ankertyp und entsprechende Umrechnung fehlt noch - if( rWW8Wrt.bOutFlyFrmAttrs ) + if ( m_rWW8Export.bOutFlyFrmAttrs ) { - const SwFmtVertOrient& rFlyVert = (const SwFmtVertOrient&) rHt; - short nPos; switch( rFlyVert.GetVertOrient() ) { - case text::VertOrientation::NONE: - nPos = (short)rFlyVert.GetPos(); - break; - case text::VertOrientation::CENTER: - case text::VertOrientation::LINE_CENTER: - nPos = -8; - break; - case text::VertOrientation::BOTTOM: - case text::VertOrientation::LINE_BOTTOM: - nPos = -12; - break; - case text::VertOrientation::TOP: - case text::VertOrientation::LINE_TOP: - default: - nPos = -4; - break; + case text::VertOrientation::NONE: + nPos = (short)rFlyVert.GetPos(); + break; + case text::VertOrientation::CENTER: + case text::VertOrientation::LINE_CENTER: + nPos = -8; + break; + case text::VertOrientation::BOTTOM: + case text::VertOrientation::LINE_BOTTOM: + nPos = -12; + break; + case text::VertOrientation::TOP: + case text::VertOrientation::LINE_TOP: + default: + nPos = -4; + break; } // sprmPDyaAbs - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x8419 ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaAbs ); else - rWW8Wrt.pO->Insert( 27, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( nPos ); + m_rWW8Export.pO->Insert( 27, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( nPos ); } - return rWrt; } -Writer& OutWW8_SwFmtHoriOrient( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - if (!rWW8Wrt.mpParentFrame) + if ( !m_rWW8Export.mpParentFrame ) { - ASSERT(rWW8Wrt.mpParentFrame, "HoriOrient without mpParentFrame !!"); - return rWrt; + ASSERT( m_rWW8Export.mpParentFrame, "HoriOrient without mpParentFrame !!" ); + return; } //!!!! Ankertyp und entsprechende Umrechnung fehlt noch - if( rWW8Wrt.bOutFlyFrmAttrs ) + if ( m_rWW8Export.bOutFlyFrmAttrs ) { - const SwFmtHoriOrient& rFlyHori = (const SwFmtHoriOrient&) rHt; - short nPos; switch( rFlyHori.GetHoriOrient() ) { - case text::HoriOrientation::NONE: { - nPos = (short)rFlyHori.GetPos(); - if( !nPos ) - nPos = 1; // WW: 0 ist reserviert - } - break; - - case text::HoriOrientation::LEFT: nPos = rFlyHori.IsPosToggle() ? -12 : 0; - break; - case text::HoriOrientation::RIGHT: nPos = rFlyHori.IsPosToggle() ? -16 : -8; - break; - case text::HoriOrientation::CENTER: - case text::HoriOrientation::FULL: // FULL nur fuer Tabellen - default: nPos = -4; break; + case text::HoriOrientation::NONE: + nPos = (short)rFlyHori.GetPos(); + if( !nPos ) + nPos = 1; // WW: 0 ist reserviert + break; + case text::HoriOrientation::LEFT: + nPos = rFlyHori.IsPosToggle() ? -12 : 0; + break; + case text::HoriOrientation::RIGHT: + nPos = rFlyHori.IsPosToggle() ? -16 : -8; + break; + case text::HoriOrientation::CENTER: + case text::HoriOrientation::FULL: // FULL nur fuer Tabellen + default: + nPos = -4; + break; } // sprmPDxaAbs - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x8418 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaAbs ); else - rWW8Wrt.pO->Insert( 26, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( nPos ); + m_rWW8Export.pO->Insert( 26, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt16( nPos ); } - return rWrt; } -static Writer& OutWW8_SwFmtAnchor( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatAnchor( const SwFmtAnchor& rAnchor ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - ASSERT(rWW8Wrt.mpParentFrame, "Anchor without mpParentFrame !!"); + ASSERT( m_rWW8Export.mpParentFrame, "Anchor without mpParentFrame !!" ); - if( rWW8Wrt.bOutFlyFrmAttrs ) + if ( m_rWW8Export.bOutFlyFrmAttrs ) { - const SwFmtAnchor& rAnchor = (const SwFmtAnchor&) rHt; BYTE nP = 0; - switch( rAnchor.GetAnchorId() ) + switch ( rAnchor.GetAnchorId() ) { case FLY_PAGE: // Vert: Page | Horz: Page @@ -4060,48 +4006,43 @@ static Writer& OutWW8_SwFmtAnchor( Writer& rWrt, const SfxPoolItem& rHt ) } // sprmPPc - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x261B ); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PPc ); else - rWW8Wrt.pO->Insert( 29, rWW8Wrt.pO->Count() ); - rWW8Wrt.pO->Insert( nP, rWW8Wrt.pO->Count() ); + m_rWW8Export.pO->Insert( 29, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( nP, m_rWW8Export.pO->Count() ); } - return rWrt; } -static Writer& OutWW8_SwFmtBackground( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatBackground( const SvxBrushItem& rBrush ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - - if( !rWW8Wrt.bOutPageDescs ) // WW kann keinen Hintergrund - { // in Section - const SvxBrushItem& rBack = (const SvxBrushItem&)rHt; + // WW cannot have background in a section + if ( !m_rWW8Export.bOutPageDescs ) + { WW8_SHD aSHD; - rWW8Wrt.TransBrush(rBack.GetColor(), aSHD); + m_rWW8Export.TransBrush( rBrush.GetColor(), aSHD ); // sprmPShd - if (rWW8Wrt.bWrtWW8) - rWW8Wrt.InsUInt16(0x442D); + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PShd ); else - rWW8Wrt.pO->Insert(47, rWW8Wrt.pO->Count()); - rWW8Wrt.InsUInt16( aSHD.GetValue() ); + m_rWW8Export.pO->Insert(47, m_rWW8Export.pO->Count()); + m_rWW8Export.InsUInt16( aSHD.GetValue() ); - //Quite a few unknowns, some might be transparency or something - //of that nature... - if (rWW8Wrt.bWrtWW8) + // Quite a few unknowns, some might be transparency or something + // of that nature... + if ( m_rWW8Export.bWrtWW8 ) { - rWW8Wrt.InsUInt16(0xC64D); - rWW8Wrt.pO->Insert(10, rWW8Wrt.pO->Count()); - rWW8Wrt.InsUInt32(0xFF000000); - rWW8Wrt.InsUInt32(SuitableBGColor( - rBack.GetColor().GetColor())); - rWW8Wrt.InsUInt16(0x0000); + m_rWW8Export.InsUInt16( 0xC64D ); + m_rWW8Export.pO->Insert( 10, m_rWW8Export.pO->Count() ); + m_rWW8Export.InsUInt32( 0xFF000000 ); + m_rWW8Export.InsUInt32( SuitableBGColor( rBrush.GetColor().GetColor() ) ); + m_rWW8Export.InsUInt16( 0x0000 ); } } - return rWrt; } -WW8_BRC SwWW8Writer::TranslateBorderLine(const SvxBorderLine& rLine, +WW8_BRC WW8Export::TranslateBorderLine(const SvxBorderLine& rLine, USHORT nDist, bool bShadow) { // M.M. This function writes out border lines to the word format similar to @@ -4184,12 +4125,14 @@ WW8_BRC SwWW8Writer::TranslateBorderLine(const SvxBorderLine& rLine, // auch fuer die Tabellen-Umrandungen zu benutzen. // Wenn nSprmNo == 0, dann wird der Opcode nicht ausgegeben. // bShadow darf bei Tabellenzellen *nicht* gesetzt sein ! -void SwWW8Writer::Out_BorderLine(WW8Bytes& rO, const SvxBorderLine* pLine, - USHORT nDist, USHORT nOffset, bool bShadow) +void WW8Export::Out_BorderLine(WW8Bytes& rO, const SvxBorderLine* pLine, + USHORT nDist, sal_uInt16 nSprmNo, bool bShadow) { - ASSERT( (nOffset <= 3) || USHRT_MAX == nOffset || - ((0x702b - 0x6424) <= nOffset && nOffset <= (0x702e - 0x6424)), - "SprmOffset ausserhalb des Bereichs" ); + ASSERT( ( nSprmNo == 0 ) || + ( nSprmNo >= 38 && nSprmNo <= 41 ) || + ( nSprmNo >= NS_sprm::LN_PBrcTop && nSprmNo <= NS_sprm::LN_PBrcRight ) || + ( nSprmNo >= NS_sprm::LN_SBrcTop && nSprmNo <= NS_sprm::LN_SBrcRight ), + "Sprm for border out is of range" ); WW8_BRC aBrc; @@ -4198,68 +4141,70 @@ void SwWW8Writer::Out_BorderLine(WW8Bytes& rO, const SvxBorderLine* pLine, if( bWrtWW8 ) { -// WW97-SprmIds -// 0x6424, sprmPBrcTop pap.brcTop;BRC;long; !!!! -// 0x6425, sprmPBrcLeft -// 0x6426, sprmPBrcBottom -// 0x6427, sprmPBrcRight - if( USHRT_MAX != nOffset ) // mit OpCode-Ausgabe ? - SwWW8Writer::InsUInt16( rO, 0x6424 + nOffset ); + // WW97-SprmIds + if ( nSprmNo != 0 ) + SwWW8Writer::InsUInt16( rO, nSprmNo ); rO.Insert( aBrc.aBits1, 2, rO.Count() ); rO.Insert( aBrc.aBits2, 2, rO.Count() ); } else { -// WW95-SprmIds -// 38, sprmPBrcTop - pap.brcTop BRC short !!! -// 39, sprmPBrcLeft -// 40, sprmPBrcBottom -// 41, sprmPBrcRight - if( USHRT_MAX != nOffset ) // mit OpCode-Ausgabe ? - rO.Insert( (BYTE)( 38 + nOffset ), rO.Count() ); + // WW95-SprmIds + if ( nSprmNo != 0 ) + rO.Insert( (BYTE)( nSprmNo ), rO.Count() ); rO.Insert( aBrc.aBits1, 2, rO.Count() ); } } -// OutWW8_SwFmtBox1() ist fuer alle Boxen ausser in Tabellen. +// FormatBox1() ist fuer alle Boxen ausser in Tabellen. // es wird pO des WW8Writers genommen -void SwWW8Writer::Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow) +void WW8Export::Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow) { - USHORT nOffset = 0; - if( bOutPageDescs ) - { - if( !bWrtWW8 ) - return ; // WW95 kennt keine Seitenumrandung - -// WW97-SprmIds -// 0x702b, sprmSBrcTop pap.brcTop;BRC;long; !!!! -// 0x702c, sprmSBrcLeft -// 0x702d, sprmSBrcBottom -// 0x702e, sprmSBrcRight - nOffset = (0x702b - 0x6424); - } + if ( bOutPageDescs && !bWrtWW8 ) + return; // no page ouline in WW6 static const USHORT aBorders[] = { BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT }; + static const sal_uInt16 aPBrc[] = + { + NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft, NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight + }; + static const sal_uInt16 aSBrc[] = + { + NS_sprm::LN_SBrcTop, NS_sprm::LN_SBrcLeft, NS_sprm::LN_SBrcBottom, NS_sprm::LN_SBrcRight + }; + static const sal_uInt16 aWW6PBrc[] = + { + 38, 39, 40, 41 + }; + const USHORT* pBrd = aBorders; for( USHORT i = 0; i < 4; ++i, ++pBrd ) { const SvxBorderLine* pLn = rBox.GetLine( *pBrd ); - Out_BorderLine( *pO, pLn, rBox.GetDistance( *pBrd ), nOffset+i, - bShadow ); + + sal_uInt16 nSprmNo = 0; + if ( !bWrtWW8 ) + nSprmNo = aWW6PBrc[i]; + else if ( bOutPageDescs ) + nSprmNo = aSBrc[i]; + else + nSprmNo = aPBrc[i]; + + Out_BorderLine( *pO, pLn, rBox.GetDistance( *pBrd ), nSprmNo, bShadow ); } } -// OutWW8_SwFmtBox2() ist fuer TC-Strukturen in Tabellen. Der Sprm-Opcode +// FormatBox2() ist fuer TC-Strukturen in Tabellen. Der Sprm-Opcode // wird nicht geschrieben, da es in der TC-Structur ohne Opcode gepackt ist. // dxpSpace wird immer 0, da WW das in Tabellen so verlangt // ( Tabellenumrandungen fransen sonst aus ) // Ein WW8Bytes-Ptr wird als Ausgabe-Parameter uebergeben -void SwWW8Writer::Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem& rBox ) +void WW8Export::Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem& rBox ) { // moeglich und vielleicht besser waere 0xffff static const USHORT aBorders[] = @@ -4270,32 +4215,30 @@ void SwWW8Writer::Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem& rBox ) for( int i = 0; i < 4; ++i, ++pBrd ) { const SvxBorderLine* pLn = rBox.GetLine( *pBrd ); - Out_BorderLine(rO, pLn, 0, USHRT_MAX, false); + Out_BorderLine(rO, pLn, 0, 0, false); } } -static Writer& OutWW8_SwFmtBox( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatBox( const SvxBoxItem& rBox ) { - // Fly um Grafik-> keine Umrandung hier, da - // der GrafikHeader bereits die Umrandung hat - SwWW8Writer& rWW8Wrt = ((SwWW8Writer&)rWrt); - if( !rWW8Wrt.bOutGrf ) + // Fly um Grafik-> keine Umrandung hier, da + // der GrafikHeader bereits die Umrandung hat + if ( !m_rWW8Export.bOutGrf ) { bool bShadow = false; - const SfxPoolItem* pItem = ((SwWW8Writer&)rWrt).HasItem( RES_SHADOW ); - if( pItem ) + const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_SHADOW ); + if ( pItem ) { const SvxShadowItem* p = (const SvxShadowItem*)pItem; bShadow = ( p->GetLocation() != SVX_SHADOW_NONE ) && ( p->GetWidth() != 0 ); } - rWW8Wrt.Out_SwFmtBox( (SvxBoxItem&)rHt, bShadow ); + m_rWW8Export.Out_SwFmtBox( rBox, bShadow ); } - return rWrt; } -SwTwips SwWW8Writer::CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const +SwTwips WW8Export::CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const { const SwFrmFmt* pFmt = pAktPageDesc ? &pAktPageDesc->GetMaster() : &const_cast<const SwDoc *>(pDoc)->GetPageDesc(0).GetMaster(); @@ -4307,28 +4250,109 @@ SwTwips SwWW8Writer::CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const return nPageSize; } -static Writer& OutWW8_SwFmtCol( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatColumns_Impl( USHORT nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize ) +{ + // CColumns + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SCcolumns ); + else + m_rWW8Export.pO->Insert( 144, m_rWW8Export.pO->Count( ) ); + m_rWW8Export.InsUInt16( nCols - 1 ); + + // DxaColumns + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColumns ); + else + m_rWW8Export.pO->Insert( 145, m_rWW8Export.pO->Count( ) ); + m_rWW8Export.InsUInt16( rCol.GetGutterWidth( true ) ); + + // LBetween + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SLBetween ); + else + m_rWW8Export.pO->Insert( 158, m_rWW8Export.pO->Count( ) ); + m_rWW8Export.pO->Insert( COLADJ_NONE == rCol.GetLineAdj( )? 0 : 1, + m_rWW8Export.pO->Count( ) ); + + const SwColumns & rColumns = rCol.GetColumns( ); + + // FEvenlySpaced + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SFEvenlySpaced ); + else + m_rWW8Export.pO->Insert( 138, m_rWW8Export.pO->Count( ) ); + m_rWW8Export.pO->Insert( bEven ? 1 : 0, m_rWW8Export.pO->Count( ) ); + +#if 0 + // FIXME what's the use of this code + if ( bEven ) + { + USHORT nSpace = rColumns[0]->GetRight() + rColumns[1]->GetLeft(); + for ( n = 2; n < nCols; n++ ) + { + short nDiff = nSpace - ( rColumns[n - 1]->GetRight() + + rColumns[n]->GetLeft() ); + if (nDiff > 10 || nDiff < -10) + { + // Toleranz: 10 tw + bEven = false; + break; + } + } + } +#endif + + if ( !bEven ) + { + for ( USHORT n = 0; n < nCols; ++n ) + { + //sprmSDxaColWidth + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColWidth ); + else + m_rWW8Export.pO->Insert( 136, m_rWW8Export.pO->Count( ) ); + m_rWW8Export.pO->Insert( ( BYTE ) n, m_rWW8Export.pO->Count( ) ); + m_rWW8Export.InsUInt16( rCol. + CalcPrtColWidth( n, + ( USHORT ) nPageSize ) ); + + if ( n + 1 != nCols ) + { + //sprmSDxaColSpacing + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColSpacing ); + else + m_rWW8Export.pO->Insert( 137, + m_rWW8Export.pO->Count( ) ); + m_rWW8Export.pO->Insert( ( BYTE ) n, + m_rWW8Export.pO->Count( ) ); + m_rWW8Export.InsUInt16( rColumns[n]->GetRight( ) + + rColumns[n + 1]->GetLeft( ) ); + } + } + } +} + +void AttributeOutputBase::FormatColumns( const SwFmtCol& rCol ) { - const SwFmtCol& rCol = (const SwFmtCol&)rHt; const SwColumns& rColumns = rCol.GetColumns(); - SwWW8Writer& rWW8Wrt = ((SwWW8Writer&)rWrt); USHORT nCols = rColumns.Count(); - if (1 < nCols && !rWW8Wrt.bOutFlyFrmAttrs) + if ( 1 < nCols && !GetExport( ).bOutFlyFrmAttrs ) { // dann besorge mal die Seitenbreite ohne Raender !! - const SwFrmFmt* pFmt = rWW8Wrt.pAktPageDesc ? &rWW8Wrt.pAktPageDesc->GetMaster() : &const_cast<const SwDoc *>(rWW8Wrt.pDoc)->GetPageDesc(0).GetMaster(); + const SwFrmFmt* pFmt = GetExport( ).pAktPageDesc ? &GetExport( ).pAktPageDesc->GetMaster() : &const_cast<const SwDoc *>(GetExport( ).pDoc)->GetPageDesc(0).GetMaster(); const SvxFrameDirectionItem &frameDirection = pFmt->GetFrmDir(); SwTwips nPageSize; - if (frameDirection.GetValue() == FRMDIR_VERT_TOP_RIGHT || frameDirection.GetValue() == FRMDIR_VERT_TOP_LEFT) + if ( frameDirection.GetValue() == FRMDIR_VERT_TOP_RIGHT || frameDirection.GetValue() == FRMDIR_VERT_TOP_LEFT ) { const SvxULSpaceItem &rUL = pFmt->GetULSpace(); nPageSize = pFmt->GetFrmSize().GetHeight(); nPageSize -= rUL.GetUpper() + rUL.GetLower(); const SwFmtHeader *header = dynamic_cast<const SwFmtHeader *>(pFmt->GetAttrSet().GetItem(RES_HEADER)); - if (header) + if ( header ) { const SwFrmFmt *headerFmt = header->GetHeaderFmt(); if (headerFmt) @@ -4337,10 +4361,10 @@ static Writer& OutWW8_SwFmtCol( Writer& rWrt, const SfxPoolItem& rHt ) } } const SwFmtFooter *footer = dynamic_cast<const SwFmtFooter *>(pFmt->GetAttrSet().GetItem(RES_FOOTER)); - if (footer) + if ( footer ) { const SwFrmFmt *footerFmt = footer->GetFooterFmt(); - if (footerFmt) + if ( footerFmt ) { nPageSize -= footerFmt->GetFrmSize().GetHeight(); } @@ -4353,144 +4377,70 @@ static Writer& OutWW8_SwFmtCol( Writer& rWrt, const SfxPoolItem& rHt ) nPageSize -= rLR.GetLeft() + rLR.GetRight(); } - // CColumns - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x500b ); - else - rWW8Wrt.pO->Insert( 144, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( nCols - 1 ); - - // DxaColumns - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x900c ); - else - rWW8Wrt.pO->Insert( 145, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16(rCol.GetGutterWidth(true)); - - // LBetween - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x3019 ); - else - rWW8Wrt.pO->Insert( 158, rWW8Wrt.pO->Count() ); - rWW8Wrt.pO->Insert( COLADJ_NONE == rCol.GetLineAdj() ? 0 : 1, - rWW8Wrt.pO->Count() ); - // Nachsehen, ob alle Spalten gleich sind bool bEven = true; USHORT n; USHORT nColWidth = rCol.CalcPrtColWidth( 0, (USHORT)nPageSize ); - for (n = 1; n < nCols; n++) + for ( n = 1; n < nCols; n++ ) { short nDiff = nColWidth - rCol.CalcPrtColWidth( n, (USHORT)nPageSize ); - if( nDiff > 10 || nDiff < -10 ) // Toleranz: 10 tw + if ( nDiff > 10 || nDiff < -10 ) // Toleranz: 10 tw { bEven = false; break; } } - if (bEven) - { - USHORT nSpace = rColumns[0]->GetRight() + rColumns[1]->GetLeft(); - for( n = 2; n < nCols; n++ ) - { - short nDiff = nSpace - ( rColumns[n - 1]->GetRight() - + rColumns[n]->GetLeft() ); - if (nDiff > 10 || nDiff < -10) - { - // Toleranz: 10 tw - bEven = false; - break; - } - } - } - - // FEvenlySpaced - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0x3005 ); - else - rWW8Wrt.pO->Insert( 138, rWW8Wrt.pO->Count() ); - rWW8Wrt.pO->Insert( bEven ? 1 : 0, rWW8Wrt.pO->Count() ); - - if( !bEven ) - { - for (n = 0; n < nCols; ++n) - { - //sprmSDxaColWidth - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0xF203 ); - else - rWW8Wrt.pO->Insert( 136, rWW8Wrt.pO->Count() ); - rWW8Wrt.pO->Insert( (BYTE)n, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16(rCol.CalcPrtColWidth(n, (USHORT)nPageSize)); - if( n+1 != nCols ) - { - //sprmSDxaColSpacing - if( rWW8Wrt.bWrtWW8 ) - rWW8Wrt.InsUInt16( 0xF204 ); - else - rWW8Wrt.pO->Insert( 137, rWW8Wrt.pO->Count() ); - rWW8Wrt.pO->Insert( (BYTE)n, rWW8Wrt.pO->Count() ); - rWW8Wrt.InsUInt16( rColumns[ n ]->GetRight() + - rColumns[ n + 1 ]->GetLeft() ); - } - } - } + FormatColumns_Impl( nCols, rCol, bEven, nPageSize ); } - return rWrt; } -// "Absaetze zusammenhalten" -static Writer& OutWW8_SvxFmtKeep( Writer& rWrt, const SfxPoolItem& rHt ) +// "Paragraphs together" +void WW8AttributeOutput::FormatKeep( const SvxFmtKeepItem& rKeep ) { -// sprmFKeepFollow - const SvxFmtKeepItem& rAttr = (const SvxFmtKeepItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x2406 ); + // sprmFKeepFollow + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PFKeepFollow ); else - rWrtWW8.pO->Insert( 8, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( 8, m_rWW8Export.pO->Count() ); - rWrtWW8.pO->Insert( rAttr.GetValue() ? 1 : 0, rWrtWW8.pO->Count() ); - return rWrt; + m_rWW8Export.pO->Insert( rKeep.GetValue() ? 1 : 0, m_rWW8Export.pO->Count() ); } - // exclude a paragraph from Line Numbering -static Writer& OutWW8_SwFmtLineNumber( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering ) { -// sprmPFNoLineNumb - const SwFmtLineNumber& rAttr = (const SwFmtLineNumber&)rHt; - - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x240C ); + // sprmPFNoLineNumb + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PFNoLineNumb ); else - rWrtWW8.pO->Insert( 14, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( 14, m_rWW8Export.pO->Count() ); - rWrtWW8.pO->Insert( rAttr.IsCount() ? 0 : 1, rWrtWW8.pO->Count() ); - - return rWrt; + m_rWW8Export.pO->Insert( rNumbering.IsCount() ? 0 : 1, m_rWW8Export.pO->Count() ); } /* File PARATR.HXX */ -static Writer& OutWW8_SvxLineSpacing( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti ) { -// sprmPDyaLine - const SvxLineSpacingItem& rAttr = (const SvxLineSpacingItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x6412 ); + // sprmPDyaLine + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaLine ); else - rWrtWW8.pO->Insert( 20, rWrtWW8.pO->Count() ); + m_rWW8Export.pO->Insert( 20, m_rWW8Export.pO->Count() ); + + m_rWW8Export.InsUInt16( nSpace ); + m_rWW8Export.InsUInt16( nMulti ); +} +void AttributeOutputBase::ParaLineSpacing( const SvxLineSpacingItem& rSpacing ) +{ short nSpace = 240, nMulti = 0; - switch (rAttr.GetLineSpaceRule()) + switch ( rSpacing.GetLineSpaceRule() ) { default: break; @@ -4498,68 +4448,63 @@ static Writer& OutWW8_SvxLineSpacing( Writer& rWrt, const SfxPoolItem& rHt ) case SVX_LINE_SPACE_FIX: case SVX_LINE_SPACE_MIN: { - switch (rAttr.GetInterLineSpaceRule()) + switch ( rSpacing.GetInterLineSpaceRule() ) { case SVX_INTER_LINE_SPACE_FIX: // unser Durchschuss { // gibt es aber nicht in WW - also wie kommt man an // die MaxLineHeight heran? - nSpace = (short)rAttr.GetInterLineSpace(); + nSpace = (short)rSpacing.GetInterLineSpace(); sal_uInt16 nScript = i18n::ScriptType::LATIN; const SwAttrSet *pSet = 0; - if (rWrtWW8.pOutFmtNode && rWrtWW8.pOutFmtNode->ISA(SwFmt)) + if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwFmt ) ) { - const SwFmt *pFmt = (const SwFmt*)(rWrtWW8.pOutFmtNode); + const SwFmt *pFmt = (const SwFmt*)( GetExport().pOutFmtNode ); pSet = &pFmt->GetAttrSet(); } - else if (rWrtWW8.pOutFmtNode && - rWrtWW8.pOutFmtNode->ISA(SwTxtNode)) + else if ( GetExport().pOutFmtNode && GetExport().pOutFmtNode->ISA( SwTxtNode ) ) { - const SwTxtNode* pNd = - (const SwTxtNode*)rWrtWW8.pOutFmtNode; + const SwTxtNode* pNd = (const SwTxtNode*)GetExport().pOutFmtNode; pSet = &pNd->GetSwAttrSet(); - if (pBreakIt->xBreak.is()) + if ( pBreakIt->xBreak.is() ) { nScript = pBreakIt->xBreak-> getScriptType(pNd->GetTxt(), 0); } } - ASSERT(pSet, "No attrset for lineheight :-("); - if (pSet) + ASSERT( pSet, "No attrset for lineheight :-(" ); + if ( pSet ) { - nSpace = nSpace + (short)(AttrSetToLineHeight(*rWrtWW8.pDoc, - *pSet, *Application::GetDefaultDevice(), nScript)); + nSpace = nSpace + (short)( AttrSetToLineHeight( *GetExport().pDoc, + *pSet, *Application::GetDefaultDevice(), nScript ) ); } } break; case SVX_INTER_LINE_SPACE_PROP: - nSpace = (short)(( 240L * rAttr.GetPropLineSpace() ) / 100L ); + nSpace = (short)( ( 240L * rSpacing.GetPropLineSpace() ) / 100L ); nMulti = 1; break; default: // z.B. Minimum oder FIX? - if( SVX_LINE_SPACE_FIX == rAttr.GetLineSpaceRule() ) - nSpace = -(short)rAttr.GetLineHeight(); + if ( SVX_LINE_SPACE_FIX == rSpacing.GetLineSpaceRule() ) + nSpace = -(short)rSpacing.GetLineHeight(); else - nSpace = (short)rAttr.GetLineHeight(); + nSpace = (short)rSpacing.GetLineHeight(); break; } } break; } - rWrtWW8.InsUInt16(nSpace); - rWrtWW8.InsUInt16(nMulti); - return rWrt; + ParaLineSpacing_Impl( nSpace, nMulti ); } -static Writer& OutWW8_SvxAdjust(Writer& rWrt, const SfxPoolItem& rHt) +void WW8AttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust ) { -// sprmPJc - const SvxAdjustItem& rAttr = (const SvxAdjustItem&)rHt; + // sprmPJc BYTE nAdj = 255; BYTE nAdjBiDi = 255; - switch(rAttr.GetAdjust()) + switch ( rAdjust.GetAdjust() ) { case SVX_ADJUST_LEFT: nAdj = 0; @@ -4577,101 +4522,99 @@ static Writer& OutWW8_SvxAdjust(Writer& rWrt, const SfxPoolItem& rHt) nAdj = nAdjBiDi = 1; break; default: - return rWrt; // not a supported Attribut + return; // not a supported Attribut } - if (255 != nAdj) // supported Attribut? + if ( 255 != nAdj ) // supported Attribut? { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (rWrtWW8.bWrtWW8) + if ( m_rWW8Export.bWrtWW8 ) { - rWrtWW8.InsUInt16(0x2403); - rWrtWW8.pO->Insert(nAdj, rWrtWW8.pO->Count()); + m_rWW8Export.InsUInt16( NS_sprm::LN_PJc ); + m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() ); /* Sadly for left to right paragraphs both these values are the same, for right to left paragraphs the bidi one is the reverse of the normal one. */ - rWrtWW8.InsUInt16(0x2461); //bidi version ? - bool bBiDiSwap=false; - if (rWrtWW8.pOutFmtNode) + m_rWW8Export.InsUInt16( NS_sprm::LN_PJcExtra ); //bidi version ? + bool bBiDiSwap = false; + if ( m_rWW8Export.pOutFmtNode ) { short nDirection = FRMDIR_HORI_LEFT_TOP; - if (rWrtWW8.pOutFmtNode->ISA(SwTxtNode)) + if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtNode ) ) { - SwPosition aPos(*(const SwCntntNode*)rWrtWW8.pOutFmtNode); - nDirection = rWrtWW8.pDoc->GetTextDirection(aPos); + SwPosition aPos(*(const SwCntntNode*)m_rWW8Export.pOutFmtNode); + nDirection = m_rWW8Export.pDoc->GetTextDirection(aPos); } - else if (rWrtWW8.pOutFmtNode->ISA(SwTxtFmtColl)) + else if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtFmtColl ) ) { const SwTxtFmtColl* pC = - (const SwTxtFmtColl*)rWrtWW8.pOutFmtNode; + (const SwTxtFmtColl*)m_rWW8Export.pOutFmtNode; const SvxFrameDirectionItem &rItem = ItemGet<SvxFrameDirectionItem>(*pC, RES_FRAMEDIR); nDirection = rItem.GetValue(); } - if ((nDirection == FRMDIR_HORI_RIGHT_TOP) - || (nDirection == FRMDIR_ENVIRONMENT && Application::GetSettings().GetLayoutRTL())) - bBiDiSwap=true; + if ( ( nDirection == FRMDIR_HORI_RIGHT_TOP ) || + ( nDirection == FRMDIR_ENVIRONMENT && Application::GetSettings().GetLayoutRTL() ) ) + { + bBiDiSwap = true; + } } - if (bBiDiSwap) - rWrtWW8.pO->Insert(nAdjBiDi, rWrtWW8.pO->Count()); + if ( bBiDiSwap ) + m_rWW8Export.pO->Insert( nAdjBiDi, m_rWW8Export.pO->Count() ); else - rWrtWW8.pO->Insert(nAdj, rWrtWW8.pO->Count()); + m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() ); } else { - rWrtWW8.pO->Insert(5, rWrtWW8.pO->Count()); - rWrtWW8.pO->Insert(nAdj, rWrtWW8.pO->Count()); + m_rWW8Export.pO->Insert( 5, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() ); } } - return rWrt; } -static Writer& OutWW8_SvxFrameDirection( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection ) { - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if (!rWrtWW8.bWrtWW8) //8+ only - return rWrt; + if ( !m_rWW8Export.bWrtWW8 ) //8+ only + return; - const SvxFrameDirectionItem& rItem = (const SvxFrameDirectionItem&)rHt; UINT16 nTextFlow=0; bool bBiDi = false; - short nDir = rItem.GetValue(); + short nDir = rDirection.GetValue(); - if (nDir == FRMDIR_ENVIRONMENT) + if ( nDir == FRMDIR_ENVIRONMENT ) { - if (rWrtWW8.bOutPageDescs) - nDir = rWrtWW8.GetCurrentPageDirection(); - else if (rWrtWW8.pOutFmtNode) + if ( m_rWW8Export.bOutPageDescs ) + nDir = m_rWW8Export.GetCurrentPageDirection(); + else if ( m_rWW8Export.pOutFmtNode ) { - if (rWrtWW8.bOutFlyFrmAttrs) //frame + if ( m_rWW8Export.bOutFlyFrmAttrs ) //frame { - nDir = rWrtWW8.TrueFrameDirection( - *(const SwFrmFmt*)rWrtWW8.pOutFmtNode); + nDir = m_rWW8Export.TrueFrameDirection( + *(const SwFrmFmt*)m_rWW8Export.pOutFmtNode ); } - else if (rWrtWW8.pOutFmtNode->ISA(SwCntntNode)) //pagagraph + else if ( m_rWW8Export.pOutFmtNode->ISA( SwCntntNode ) ) //pagagraph { const SwCntntNode* pNd = - (const SwCntntNode*)rWrtWW8.pOutFmtNode; - SwPosition aPos(*pNd); - nDir = rWrt.pDoc->GetTextDirection(aPos); + (const SwCntntNode*)m_rWW8Export.pOutFmtNode; + SwPosition aPos( *pNd ); + nDir = m_rWW8Export.pDoc->GetTextDirection( aPos ); } - else if (rWrtWW8.pOutFmtNode->ISA(SwTxtFmtColl)) + else if ( m_rWW8Export.pOutFmtNode->ISA( SwTxtFmtColl ) ) nDir = FRMDIR_HORI_LEFT_TOP; //what else can we do :-( } - if (nDir == FRMDIR_ENVIRONMENT) + if ( nDir == FRMDIR_ENVIRONMENT ) nDir = FRMDIR_HORI_LEFT_TOP; //Set something } - switch (nDir) + switch ( nDir ) { default: //Can't get an unknown type here - ASSERT(!(&rWrt), "Unknown frame direction"); + ASSERT(false, "Unknown frame direction"); case FRMDIR_HORI_LEFT_TOP: nTextFlow = 0; break; @@ -4685,49 +4628,42 @@ static Writer& OutWW8_SvxFrameDirection( Writer& rWrt, const SfxPoolItem& rHt ) break; } - if (rWrtWW8.bOutPageDescs) + if ( m_rWW8Export.bOutPageDescs ) { - rWrtWW8.InsUInt16(0x5033); - rWrtWW8.InsUInt16(nTextFlow); - rWrtWW8.InsUInt16(0x3228); - rWrtWW8.pO->Insert(bBiDi, rWrtWW8.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_STextFlow ); + m_rWW8Export.InsUInt16( nTextFlow ); + m_rWW8Export.InsUInt16( NS_sprm::LN_SFBiDi ); + m_rWW8Export.pO->Insert( bBiDi, m_rWW8Export.pO->Count() ); } - else if (!rWrtWW8.bOutFlyFrmAttrs) //paragraph/style + else if ( !m_rWW8Export.bOutFlyFrmAttrs ) //paragraph/style { - rWrtWW8.InsUInt16(0x2441); - rWrtWW8.pO->Insert(bBiDi, rWrtWW8.pO->Count() ); + m_rWW8Export.InsUInt16( NS_sprm::LN_PFBiDi ); + m_rWW8Export.pO->Insert( bBiDi, m_rWW8Export.pO->Count() ); } - return rWrt; } -// "Absaetze trennen" -static Writer& OutWW8_SvxFmtSplit( Writer& rWrt, const SfxPoolItem& rHt ) +// "Separate paragraphs" +void WW8AttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit ) { -// sprmPFKeep - const SvxFmtSplitItem& rAttr = (const SvxFmtSplitItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x2405 ); + // sprmPFKeep + if ( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PFKeep ); else - rWrtWW8.pO->Insert( 7, rWrtWW8.pO->Count() ); - rWrtWW8.pO->Insert( rAttr.GetValue() ? 0 : 1, rWrtWW8.pO->Count() ); - return rWrt; + m_rWW8Export.pO->Insert( 7, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( rSplit.GetValue() ? 0 : 1, m_rWW8Export.pO->Count() ); } // Es wird nur das Item "SvxWidowItem" und nicht die Orphans uebersetzt, // da es fuer beides im WW nur ein Attribut "Absatzkontrolle" gibt und // im SW wahrscheinlich vom Anwender immer Beide oder keiner gesetzt werden. -static Writer& OutWW8_SvxWidows( Writer& rWrt, const SfxPoolItem& rHt ) +void WW8AttributeOutput::ParaWidows( const SvxWidowsItem& rWidows ) { // sprmPFWidowControl - const SvxWidowsItem& rAttr = (const SvxWidowsItem&)rHt; - SwWW8Writer& rWrtWW8 = (SwWW8Writer&)rWrt; - if( rWrtWW8.bWrtWW8 ) - rWrtWW8.InsUInt16( 0x2431 ); + if( m_rWW8Export.bWrtWW8 ) + m_rWW8Export.InsUInt16( NS_sprm::LN_PFWidowControl ); else - rWrtWW8.pO->Insert( 51, rWrtWW8.pO->Count() ); - rWrtWW8.pO->Insert( rAttr.GetValue() ? 1 : 0, rWrtWW8.pO->Count() ); - return rWrt; + m_rWW8Export.pO->Insert( 51, m_rWW8Export.pO->Count() ); + m_rWW8Export.pO->Insert( rWidows.GetValue() ? 1 : 0, m_rWW8Export.pO->Count() ); } @@ -4744,7 +4680,7 @@ public: void Add(const SvxTabStop &rTS, long nAdjustment); void Del(const SvxTabStop &rTS, long nAdjustment); - void PutAll(SwWW8Writer& rWW8Wrt); + void PutAll(WW8Export& rWW8Wrt); }; SwWW8WrTabu::SwWW8WrTabu(sal_uInt16 nDelMax, sal_uInt16 nAddMax) @@ -4822,8 +4758,8 @@ void SwWW8WrTabu::Del(const SvxTabStop &rTS, long nAdjustment) ++nDel; } -// PutAll( SwWW8Writer& rWW8Wrt ) schreibt das Attribut nach rWrt.pO -void SwWW8WrTabu::PutAll(SwWW8Writer& rWrt) +// PutAll( WW8Export& rWW8Wrt ) schreibt das Attribut nach rWrt.pO +void SwWW8WrTabu::PutAll(WW8Export& rWrt) { if (!nAdd && !nDel) //It its a no-op return; @@ -4839,7 +4775,7 @@ void SwWW8WrTabu::PutAll(SwWW8Writer& rWrt) nSiz = 255; if (rWrt.bWrtWW8) - rWrt.InsUInt16(0xC60D); + rWrt.InsUInt16(NS_sprm::LN_PChgTabsPapx); else rWrt.pO->Insert(15, rWrt.pO->Count()); // cch eintragen @@ -4854,8 +4790,8 @@ void SwWW8WrTabu::PutAll(SwWW8Writer& rWrt) } -static void OutWW8_SwTabStopAdd(Writer& rWrt, const SvxTabStopItem& rTStops, - long nLParaMgn) +static void ParaTabStopAdd( WW8Export& rWrt, const SvxTabStopItem& rTStops, + long nLParaMgn ) { SwWW8WrTabu aTab( 0, rTStops.Count()); @@ -4866,7 +4802,7 @@ static void OutWW8_SwTabStopAdd(Writer& rWrt, const SvxTabStopItem& rTStops, if (SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment()) aTab.Add(rTS, nLParaMgn); } - aTab.PutAll( (SwWW8Writer&)rWrt ); + aTab.PutAll( rWrt ); } bool lcl_IsEqual(long nOneLeft, const SvxTabStop &rOne, @@ -4880,8 +4816,8 @@ bool lcl_IsEqual(long nOneLeft, const SvxTabStop &rOne, ); } -static void OutWW8_SwTabStopDelAdd(Writer& rWrt, const SvxTabStopItem& rTStyle, - long nLStypeMgn, const SvxTabStopItem& rTNew, long nLParaMgn) +static void ParaTabStopDelAdd( WW8Export& rWrt, const SvxTabStopItem& rTStyle, + long nLStypeMgn, const SvxTabStopItem& rTNew, long nLParaMgn ) { SwWW8WrTabu aTab(rTStyle.Count(), rTNew.Count()); @@ -4952,54 +4888,50 @@ static void OutWW8_SwTabStopDelAdd(Writer& rWrt, const SvxTabStopItem& rTStyle, } } while( 1 ); - aTab.PutAll( (SwWW8Writer&)rWrt ); + aTab.PutAll( rWrt ); } -static Writer& OutWW8_SwTabStop(Writer& rWrt, const SfxPoolItem& rHt) +void WW8AttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStops ) { - SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt; - const SvxTabStopItem & rTStops = (const SvxTabStopItem&)rHt; - bool bTabsRelativeToIndex = rWW8Wrt.pCurPam->GetDoc()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT); + bool bTabsRelativeToIndex = m_rWW8Export.pCurPam->GetDoc()->get( IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT ); long nCurrentLeft = 0; - if (bTabsRelativeToIndex) + if ( bTabsRelativeToIndex ) { - const SfxPoolItem* pLR = rWW8Wrt.HasItem( RES_LR_SPACE ); + const SfxPoolItem* pLR = m_rWW8Export.HasItem( RES_LR_SPACE ); - if (pLR != NULL) + if ( pLR != NULL ) nCurrentLeft = ((const SvxLRSpaceItem*)pLR)->GetTxtLeft(); } - // --> FLR 2009-03-17 #i100264# - if (rWW8Wrt.bStyDef - && rWW8Wrt.pCurrentStyle!=NULL - && rWW8Wrt.pCurrentStyle->DerivedFrom()!=NULL) - { - SvxTabStopItem aTabs(0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP); - const SwFmt *pParentStyle=rWW8Wrt.pCurrentStyle->DerivedFrom(); - const SvxTabStopItem* pParentTabs=HasItem<SvxTabStopItem>(pParentStyle->GetAttrSet(), RES_PARATR_TABSTOP); - if (pParentTabs) + if ( m_rWW8Export.bStyDef && + m_rWW8Export.pCurrentStyle != NULL && + m_rWW8Export.pCurrentStyle->DerivedFrom() != NULL ) + { + SvxTabStopItem aTabs( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ); + const SwFmt *pParentStyle = m_rWW8Export.pCurrentStyle->DerivedFrom(); + const SvxTabStopItem* pParentTabs = HasItem<SvxTabStopItem>( pParentStyle->GetAttrSet(), RES_PARATR_TABSTOP ); + if ( pParentTabs ) { - aTabs.Insert(pParentTabs); + aTabs.Insert( pParentTabs ); } - OutWW8_SwTabStopDelAdd(rWW8Wrt, aTabs, 0, rTStops, 0); - return rWrt; + ParaTabStopDelAdd( m_rWW8Export, aTabs, 0, rTabStops, 0 ); + return; } // <-- - // StyleDef -> "einfach" eintragen || keine Style-Attrs -> dito const SvxTabStopItem* pStyleTabs = 0; - if (!rWW8Wrt.bStyDef && rWW8Wrt.pStyAttr) + if ( !m_rWW8Export.bStyDef && m_rWW8Export.pStyAttr ) { pStyleTabs = - HasItem<SvxTabStopItem>(*rWW8Wrt.pStyAttr, RES_PARATR_TABSTOP); + HasItem<SvxTabStopItem>( *m_rWW8Export.pStyAttr, RES_PARATR_TABSTOP ); } - if (!pStyleTabs) - OutWW8_SwTabStopAdd(rWW8Wrt, rTStops, nCurrentLeft); + if ( !pStyleTabs ) + ParaTabStopAdd(m_rWW8Export, rTabStops, nCurrentLeft); else { long nStyleLeft = 0; @@ -5007,175 +4939,282 @@ static Writer& OutWW8_SwTabStop(Writer& rWrt, const SfxPoolItem& rHt) if (bTabsRelativeToIndex) { const SvxLRSpaceItem &rStyleLR = - ItemGet<SvxLRSpaceItem>(*rWW8Wrt.pStyAttr, RES_LR_SPACE); + ItemGet<SvxLRSpaceItem>(*m_rWW8Export.pStyAttr, RES_LR_SPACE); nStyleLeft = rStyleLR.GetTxtLeft(); } - OutWW8_SwTabStopDelAdd(rWW8Wrt, *pStyleTabs, nStyleLeft, rTStops, + ParaTabStopDelAdd(m_rWW8Export, *pStyleTabs, nStyleLeft, rTabStops, nCurrentLeft); } - return rWrt; } //----------------------------------------------------------------------- -/* - * lege hier die Tabellen fuer die WW-Funktions-Pointer auf - * die Ausgabe-Funktionen an. - * Es sind lokale Strukturen, die nur innerhalb - * bekannt sein muessen. - */ +void AttributeOutputBase::OutputItem( const SfxPoolItem& rHt ) +{ + // FIXME maybe use 'item_cast', like 'item_cast<SvxCharHiddenItem>( rHt )'? + switch ( rHt.Which() ) + { + case RES_CHRATR_CASEMAP: + CharCaseMap( static_cast< const SvxCaseMapItem& >( rHt ) ); + break; + case RES_CHRATR_COLOR: + CharColor( static_cast< const SvxColorItem& >( rHt ) ); + break; + case RES_CHRATR_CONTOUR: + CharContour( static_cast< const SvxContourItem& >( rHt ) ); + break; + case RES_CHRATR_CROSSEDOUT: + CharCrossedOut( static_cast< const SvxCrossedOutItem& >( rHt ) ); + break; + case RES_CHRATR_ESCAPEMENT: + CharEscapement( static_cast< const SvxEscapementItem& >( rHt ) ); + break; + case RES_CHRATR_FONT: + CharFont( static_cast< const SvxFontItem& >( rHt ) ); + break; + case RES_CHRATR_FONTSIZE: + CharFontSize( static_cast< const SvxFontHeightItem& >( rHt ) ); + break; + case RES_CHRATR_KERNING: + CharKerning( static_cast< const SvxKerningItem& >( rHt ) ); + break; + case RES_CHRATR_LANGUAGE: + CharLanguage( static_cast< const SvxLanguageItem& >( rHt ) ); + break; + case RES_CHRATR_POSTURE: + CharPosture( static_cast< const SvxPostureItem& >( rHt ) ); + break; + case RES_CHRATR_SHADOWED: + CharShadow( static_cast< const SvxShadowedItem& >( rHt ) ); + break; + case RES_CHRATR_UNDERLINE: + CharUnderline( static_cast< const SvxUnderlineItem& >( rHt ) ); + break; + case RES_CHRATR_WEIGHT: + CharWeight( static_cast< const SvxWeightItem& >( rHt ) ); + break; + case RES_CHRATR_AUTOKERN: + CharAutoKern( static_cast< const SvxAutoKernItem& >( rHt ) ); + break; + case RES_CHRATR_BLINK: + CharAnimatedText( static_cast< const SvxBlinkItem& >( rHt ) ); + break; + case RES_CHRATR_BACKGROUND: + CharBackground( static_cast< const SvxBrushItem& >( rHt ) ); + break; -SwAttrFnTab aWW8AttrFnTab = { -/* RES_CHRATR_CASEMAP */ OutWW8_SwCaseMap, -/* RES_CHRATR_CHARSETCOLOR */ 0, -/* RES_CHRATR_COLOR */ OutWW8_SwColor, -/* RES_CHRATR_CONTOUR */ OutWW8_SwContour, -/* RES_CHRATR_CROSSEDOUT */ OutWW8_SwCrossedOut, -/* RES_CHRATR_ESCAPEMENT */ OutWW8_SwEscapement, -/* RES_CHRATR_FONT */ OutWW8_SwFont, -/* RES_CHRATR_FONTSIZE */ OutWW8_SwSize, -/* RES_CHRATR_KERNING */ OutWW8_SwKerning, -/* RES_CHRATR_LANGUAGE */ OutWW8_SwLanguage, -/* RES_CHRATR_POSTURE */ OutWW8_SwPosture, -/* RES_CHRATR_PROPORTIONALFONTSIZE*/0, -/* RES_CHRATR_SHADOWED */ OutWW8_SwShadow, -/* RES_CHRATR_UNDERLINE */ OutWW8_SwUnderline, -/* RES_CHRATR_WEIGHT */ OutWW8_SwWeight, -/* RES_CHRATR_WORDLINEMODE */ 0, // Wird bei Underline mitbehandelt -/* RES_CHRATR_AUTOKERN */ OutWW8_SvxAutoKern, -/* RES_CHRATR_BLINK */ OutWW8_SwAnimatedText, // neu: blinkender Text -/* RES_CHRATR_NOHYPHEN */ 0, // Neu: nicht trennen -/* RES_CHRATR_NOLINEBREAK */ 0, // Neu: nicht umbrechen -/* RES_CHRATR_BACKGROUND */ OutWW8_SwFmtCharBackground, -/* RES_CHRATR_CJK_FONT */ OutWW8_SwCJKFont, -/* RES_CHRATR_CJK_FONTSIZE */ OutWW8_SwSize, -/* RES_CHRATR_CJK_LANGUAGE */ OutWW8_SwLanguage, -/* RES_CHRATR_CJK_POSTURE */ OutWW8_SwPosture, -/* RES_CHRATR_CJK_WEIGHT */ OutWW8_SwWeight, -/* RES_CHRATR_CTL_FONT */ OutWW8_SwCTLFont, -/* RES_CHRATR_CTL_FONTSIZE */ OutWW8_SwSize, -/* RES_CHRATR_CTL_LANGUAGE */ OutWW8_SwLanguage, -/* RES_CHRATR_CTL_POSTURE */ OutWW8_SwBiDiPosture, -/* RES_CHRATR_CTL_WEIGHT */ OutWW8_SwBiDiWeight, -/* RES_CHRATR_WRITING_DIRECTION */ OutWW8_CharRotate, -/* RES_CHRATR_EMPHASIS_MARK*/ OutWW8_EmphasisMark, -/* RES_TXTATR_TWO_LINES */ OutWW8_SvxTwoLinesItem, -/* RES_CHRATR_DUMMY4 */ OutWW8_ScaleWidth, -/* RES_CHRATR_RELIEF*/ OutWW8_Relief, -/* RES_CHRATR_HIDDEN */ OutWW8_SvxCharHidden, -/* RES_CHRATR_OVERLINE */ 0, -/* RES_CHRATR_DUMMY1 */ 0, -/* RES_CHRATR_DUMMY2 */ 0, - -/* RES_TXTATR_DUMMY4 */ 0, -/* RES_TXTATR_INETFMT */ OutSwFmtINetFmt, -/* RES_TXTATR_REFMARK */ 0, // handled by SwAttrIter -/* RES_TXTATR_TOXMARK */ 0, // handled by SwAttrIter -/* RES_TXTATR_CHARFMT */ OutWW8_SwTxtCharFmt, -/* RES_TXTATR_DUMMY5*/ 0, -/* RES_TXTATR_CJK_RUBY */ 0, // handled by SwAttrIter -/* RES_TXTATR_UNKNOWN_CONTAINER */ 0, -/* RES_TXTATR_DUMMY6 */ 0, -/* RES_TXTATR_DUMMY7 */ 0, - -/* RES_TXTATR_FIELD */ OutWW8_SwField, -/* RES_TXTATR_FLYCNT */ OutWW8_SwFlyCntnt, -/* RES_TXTATR_FTN */ OutWW8_SwFtn, -/* RES_TXTATR_SOFTHYPH */ 0, // old attr. - coded now by character -/* RES_TXTATR_HARDBLANK */ OutWW8_SwHardBlank, -/* RES_TXTATR_DUMMY1 */ 0, // Dummy: -/* RES_TXTATR_DUMMY2 */ 0, // Dummy: - -/* RES_PARATR_LINESPACING */ OutWW8_SvxLineSpacing, -/* RES_PARATR_ADJUST */ OutWW8_SvxAdjust, -/* RES_PARATR_SPLIT */ OutWW8_SvxFmtSplit, -/* RES_PARATR_ORPHANS */ 0, // OutW4W_SwOrphans, // kann WW nicht unabhaengig von Widows -/* RES_PARATR_WIDOWS */ OutWW8_SvxWidows, -/* RES_PARATR_TABSTOP */ OutWW8_SwTabStop, -/* RES_PARATR_HYPHENZONE*/ OutWW8_SvxHyphenZone, -/* RES_PARATR_DROP */ 0, -/* RES_PARATR_REGISTER */ 0, // neu: Registerhaltigkeit -/* RES_PARATR_NUMRULE */ OutWW8_SwNumRuleItem, -/* RES_PARATR_SCRIPTSPACE */ OutWW8_SfxBoolItem, -/* RES_PARATR_HANGINGPUNCTUATION */ OutWW8_SfxBoolItem, -/* RES_PARATR_FORBIDDEN_RULES */ OutWW8_SfxBoolItem, -/* RES_PARATR_VERTALIGN */ OutWW8_SvxParaVertAlignItem, -/* RES_PARATR_SNAPTOGRID*/ OutWW8_SvxParaGridItem, -/* RES_PARATR_CONNECT_TO_BORDER */ 0, // new -/* RES_PARATR_OUTLINELEVEL */ 0, // new - 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, // OutW4W_SwFillOrder, -/* RES_FRM_SIZE */ OutWW8_SwFrmSize, -/* RES_PAPER_BIN */ OutWW8_SvxPaperBin, -/* RES_LR_SPACE */ OutWW8_SwFmtLRSpace, -/* RES_UL_SPACE */ OutWW8_SwFmtULSpace, -/* RES_PAGEDESC */ OutWW8_SwFmtPageDesc, -/* RES_BREAK */ OutWW8_SwFmtBreak, -/* RES_CNTNT */ 0, /* 0, // OutW4W_??? */ -/* RES_HEADER */ 0, // wird bei der PageDesc ausgabe beachtet -/* RES_FOOTER */ 0, // wird bei der PageDesc ausgabe beachtet -/* RES_PRINT */ 0, // OutW4W_SwFmtPrint, -/* RES_OPAQUE */ 0, // OutW4W_SwFmtOpaque, // kann WW nicht -/* RES_PROTECT */ 0, // OutW4W_SwFmtProtect, -/* RES_SURROUND */ OutWW8_SwFmtSurround, -/* RES_VERT_ORIENT */ OutWW8_SwFmtVertOrient, -/* RES_HORI_ORIENT */ OutWW8_SwFmtHoriOrient, -/* RES_ANCHOR */ OutWW8_SwFmtAnchor, -/* RES_BACKGROUND */ OutWW8_SwFmtBackground, -/* RES_BOX */ OutWW8_SwFmtBox, -/* RES_SHADOW */ 0, // Wird bei SwFmtBox mitbehandelt -/* RES_FRMMACRO */ 0, /* 0, // OutW4W_??? */ -/* RES_COL */ OutWW8_SwFmtCol, -/* RES_KEEP */ OutWW8_SvxFmtKeep, -/* RES_URL */ 0, // URL -/* RES_EDIT_IN_READONLY */ 0, -/* RES_LAYOUT_SPLIT */ 0, -/* RES_CHAIN */ 0, -/* RES_TEXTGRID*/ OutWW8_SwTextGrid, -/* RES_LINENUMBER */ OutWW8_SwFmtLineNumber, // Line Numbering -/* RES_FTN_AT_TXTEND*/ 0, // Dummy: -/* RES_END_AT_TXTEND*/ 0, // Dummy: -/* RES_COLUMNBALANCE*/ 0, // Dummy: -/* RES_FRAMEDIR*/ OutWW8_SvxFrameDirection, -/* 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, // OutW4W_SwMirrorGrf, -/* RES_GRFATR_CROPGRF */ 0, // OutW4W_SwCropGrf -/* 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, - -/* RES_UNKNOWNATR_CONTAINER */ 0 -}; + case RES_CHRATR_CJK_FONT: + CharFontCJK( static_cast< const SvxFontItem& >( rHt ) ); + break; + case RES_CHRATR_CJK_FONTSIZE: + CharFontSizeCJK( static_cast< const SvxFontHeightItem& >( rHt ) ); + break; + case RES_CHRATR_CJK_LANGUAGE: + CharLanguageCJK( static_cast< const SvxLanguageItem& >( rHt ) ); + break; + case RES_CHRATR_CJK_POSTURE: + CharPostureCJK( static_cast< const SvxPostureItem& >( rHt ) ); + break; + case RES_CHRATR_CJK_WEIGHT: + CharWeightCJK( static_cast< const SvxWeightItem& >( rHt ) ); + break; + + case RES_CHRATR_CTL_FONT: + CharFontCTL( static_cast< const SvxFontItem& >( rHt ) ); + break; + case RES_CHRATR_CTL_FONTSIZE: + CharFontSizeCTL( static_cast< const SvxFontHeightItem& >( rHt ) ); + break; + case RES_CHRATR_CTL_LANGUAGE: + CharLanguageCTL( static_cast< const SvxLanguageItem& >( rHt ) ); + break; + case RES_CHRATR_CTL_POSTURE: + CharPostureCTL( static_cast< const SvxPostureItem& >( rHt ) ); + break; + case RES_CHRATR_CTL_WEIGHT: + CharWeightCTL( static_cast< const SvxWeightItem& >( rHt ) ); + break; + + case RES_CHRATR_ROTATE: + CharRotate( static_cast< const SvxCharRotateItem& >( rHt ) ); + break; + case RES_CHRATR_EMPHASIS_MARK: + CharEmphasisMark( static_cast< const SvxEmphasisMarkItem& >( rHt ) ); + break; + case RES_CHRATR_TWO_LINES: + CharTwoLines( static_cast< const SvxTwoLinesItem& >( rHt ) ); + break; + case RES_CHRATR_SCALEW: + CharScaleWidth( static_cast< const SvxCharScaleWidthItem& >( rHt ) ); + break; + case RES_CHRATR_RELIEF: + CharRelief( static_cast< const SvxCharReliefItem& >( rHt ) ); + break; + case RES_CHRATR_HIDDEN: + CharHidden( static_cast< const SvxCharHiddenItem& >( rHt ) ); + break; + + case RES_TXTATR_INETFMT: + TextINetFormat( static_cast< const SwFmtINetFmt& >( rHt ) ); + break; + case RES_TXTATR_CHARFMT: + TextCharFormat( static_cast< const SwFmtCharFmt& >( rHt ) ); + break; + case RES_TXTATR_FIELD: + TextField( static_cast< const SwFmtFld& >( rHt ) ); + break; + case RES_TXTATR_FLYCNT: + TextFlyContent( static_cast< const SwFmtFlyCnt& >( rHt ) ); + break; + case RES_TXTATR_FTN: + TextFootnote( static_cast< const SwFmtFtn& >( rHt ) ); + break; + case RES_TXTATR_HARDBLANK: + TextHardBlank( static_cast< const SwFmtHardBlank& >( rHt ) ); + break; + + case RES_PARATR_LINESPACING: + ParaLineSpacing( static_cast< const SvxLineSpacingItem& >( rHt ) ); + break; + case RES_PARATR_ADJUST: + ParaAdjust( static_cast< const SvxAdjustItem& >( rHt ) ); + break; + case RES_PARATR_SPLIT: + ParaSplit( static_cast< const SvxFmtSplitItem& >( rHt ) ); + break; + case RES_PARATR_WIDOWS: + ParaWidows( static_cast< const SvxWidowsItem& >( rHt ) ); + break; + case RES_PARATR_TABSTOP: + ParaTabStop( static_cast< const SvxTabStopItem& >( rHt ) ); + break; + case RES_PARATR_HYPHENZONE: + ParaHyphenZone( static_cast< const SvxHyphenZoneItem& >( rHt ) ); + break; + case RES_PARATR_NUMRULE: + ParaNumRule( static_cast< const SwNumRuleItem& >( rHt ) ); + break; + case RES_PARATR_SCRIPTSPACE: + ParaScriptSpace( static_cast< const SfxBoolItem& >( rHt ) ); + break; + case RES_PARATR_HANGINGPUNCTUATION: + ParaHangingPunctuation( static_cast< const SfxBoolItem& >( rHt ) ); + break; + case RES_PARATR_FORBIDDEN_RULES: + ParaForbiddenRules( static_cast< const SfxBoolItem& >( rHt ) ); + break; + case RES_PARATR_VERTALIGN: + ParaVerticalAlign( static_cast< const SvxParaVertAlignItem& >( rHt ) ); + break; + case RES_PARATR_SNAPTOGRID: + ParaSnapToGrid( static_cast< const SvxParaGridItem& >( rHt ) ); + break; + + case RES_FRM_SIZE: + FormatFrameSize( static_cast< const SwFmtFrmSize& >( rHt ) ); + break; + case RES_PAPER_BIN: + FormatPaperBin( static_cast< const SvxPaperBinItem& >( rHt ) ); + break; + case RES_LR_SPACE: + FormatLRSpace( static_cast< const SvxLRSpaceItem& >( rHt ) ); + break; + case RES_UL_SPACE: + FormatULSpace( static_cast< const SvxULSpaceItem& >( rHt ) ); + break; + case RES_PAGEDESC: + FormatPageDescription( static_cast< const SwFmtPageDesc& >( rHt ) ); + break; + case RES_BREAK: + FormatBreak( static_cast< const SvxFmtBreakItem& >( rHt ) ); + break; + case RES_SURROUND: + FormatSurround( static_cast< const SwFmtSurround& >( rHt ) ); + break; + case RES_VERT_ORIENT: + FormatVertOrientation( static_cast< const SwFmtVertOrient& >( rHt ) ); + break; + case RES_HORI_ORIENT: + FormatHorizOrientation( static_cast< const SwFmtHoriOrient& >( rHt ) ); + break; + case RES_ANCHOR: + FormatAnchor( static_cast< const SwFmtAnchor& >( rHt ) ); + break; + case RES_BACKGROUND: + FormatBackground( static_cast< const SvxBrushItem& >( rHt ) ); + break; + case RES_BOX: + FormatBox( static_cast< const SvxBoxItem& >( rHt ) ); + break; + case RES_COL: + FormatColumns( static_cast< const SwFmtCol& >( rHt ) ); + break; + case RES_KEEP: + FormatKeep( static_cast< const SvxFmtKeepItem& >( rHt ) ); + break; + case RES_TEXTGRID: + FormatTextGrid( static_cast< const SwTextGridItem& >( rHt ) ); + break; + case RES_LINENUMBER: + FormatLineNumbering( static_cast< const SwFmtLineNumber& >( rHt ) ); + break; + case RES_FRAMEDIR: + FormatFrameDirection( static_cast< const SvxFrameDirectionItem& >( rHt ) ); + break; + + default: +#if OSL_DEBUG_LEVEL > 0 + fprintf( stderr, "Unhandled SfxPoolItem with id %d.\n", rHt.Which() ); +#endif + break; + } +} + +void AttributeOutputBase::OutputStyleItemSet( const SfxItemSet& rSet, BOOL bDeep, BOOL bTestForDefault ) +{ + // based on OutputItemSet() from wrt_fn.cxx + + const SfxItemPool& rPool = *rSet.GetPool(); + const SfxItemSet* pSet = &rSet; + if ( !pSet->Count() ) + { + if ( !bDeep ) + return; + + while ( 0 != ( pSet = pSet->GetParent() ) && !pSet->Count() ) + ; + + if ( !pSet ) + return; + } + + const SfxPoolItem* pItem; + if ( !bDeep || !pSet->GetParent() ) + { + ASSERT( rSet.Count(), "Wurde doch schon behandelt oder?" ); + SfxItemIter aIter( *pSet ); + pItem = aIter.GetCurItem(); + do { + OutputItem( *pItem ); + } while ( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) ); + } + else + { + SfxWhichIter aIter( *pSet ); + USHORT nWhich = aIter.FirstWhich(); + while ( nWhich ) + { + if ( SFX_ITEM_SET == pSet->GetItemState( nWhich, bDeep, &pItem ) && + ( !bTestForDefault || + *pItem != rPool.GetDefaultItem( nWhich ) || + ( pSet->GetParent() && *pItem != pSet->GetParent()->Get( nWhich ) ) ) ) + { + OutputItem( *pItem ); + } + nWhich = aIter.NextWhich(); + } + } +} /* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx new file mode 100644 index 000000000000..cff22353d60c --- /dev/null +++ b/sw/source/filter/ww8/ww8attributeoutput.hxx @@ -0,0 +1,459 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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 _WW8ATTRIBUTEOUTPUT_HXX_ +#define _WW8ATTRIBUTEOUTPUT_HXX_ + +#include "attributeoutputbase.hxx" +#include "wrtww8.hxx" + +class WW8AttributeOutput : public AttributeOutputBase +{ +public: + /// Export the state of RTL/CJK. + virtual void RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ); + + /// Start of the paragraph. + virtual void StartParagraph( ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/ ) {} + + /// End of the paragraph. + virtual void EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ); + + /// Called before we start outputting the attributes. + virtual void StartParagraphProperties( const SwTxtNode& /*rNode*/ ) {} + + /// Called after we end outputting the attributes. + virtual void EndParagraphProperties() {} + + /// Empty paragraph. + virtual void EmptyParagraph(); + + /// Start of the text run. + /// + /// No-op for binary filters. + virtual void StartRun( const SwRedlineData* /*pRedlineData*/ ) {} + + /// End of the text run. + /// + /// No-op for binary filters. + virtual void EndRun() {} + + /// Before we start outputting the attributes. + virtual void StartRunProperties(); + + /// After we end outputting the attributes. + virtual void EndRunProperties( const SwRedlineData* pRedlineData ); + + /// Output text. + virtual void RunText( const String& rText, rtl_TextEncoding eCharSet ); + + /// Output text (without markup). + virtual void RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet ); + + /// Output ruby start. + virtual void StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby ); + + /// Output ruby end. + virtual void EndRuby(); + + /// Output URL start. + virtual bool StartURL( const String &rUrl, const String &rTarget ); + + /// Output URL end. + virtual bool EndURL(); + + virtual void FieldVanish( const String& rTxt, ww::eField eType ); + + /// Output redlining. + virtual void Redline( const SwRedlineData* pRedline ); + + virtual void FormatDrop( const SwTxtNode& rNode, const SwFmtDrop &rSwFmtDrop, USHORT nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ); + + /// Output FKP (Formatted disK Page) - necessary for binary formats only. + /// FIXME having it in AttributeOutputBase is probably a hack, it + /// should be in WW8AttributeOutput only... + virtual void OutputFKP(); + + /// Output style. + virtual void ParagraphStyle( USHORT nStyle ); + + virtual void TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo ); + + virtual void TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo ); + + virtual void TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner ); + + virtual void TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ); + + virtual void TableRowEnd( sal_uInt32 nDepth = 1 ); + + /// Start of the styles table. + virtual void StartStyles(); + + /// End of the styles table. + virtual void EndStyles( USHORT nNumberOfStyles ); + + /// Write default style. + virtual void DefaultStyle( USHORT nStyle ); + + /// Start of a style in the styles table. + virtual void StartStyle( const String& rName, bool bPapFmt, + USHORT nBase, USHORT nNext, USHORT nWwIdi, USHORT nId ); + + /// End of a style in the styles table. + virtual void EndStyle(); + + /// Start of (paragraph or run) properties of a style. + virtual void StartStyleProperties( bool bParProp, USHORT nStyle ); + + /// End of (paragraph or run) properties of a style. + virtual void EndStyleProperties( bool bParProp ); + + /// Numbering rule and Id. + virtual void OutlineNumbering( BYTE nLvl, const SwNumFmt &rNFmt, const SwFmt &rFmt ); + + /// Page break + /// As a paragraph property - the paragraph should be on the next page. + virtual void PageBreakBefore( bool bBreak ); + + /// Write a section break + /// msword::ColumnBreak or msword::PageBreak + virtual void SectionBreak( BYTE nC, const WW8_SepInfo* pSectionInfo = NULL ); + + /// Start of the section properties. + virtual void StartSection(); + + /// End of the section properties. + /// + /// No-op for binary filters. + virtual void EndSection() {} + + /// Protection of forms. + virtual void SectionFormProtection( bool bProtected ); + + /// Numbering of the lines in the document. + virtual void SectionLineNumbering( ULONG nRestartNo, const SwLineNumberInfo& rLnNumInfo ); + + /// Has different headers/footers for the title page. + virtual void SectionTitlePage(); + + /// Description of the page borders. + virtual void SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* pFirstPageFmt ); + + /// Columns populated from right/numbers on the right side? + virtual void SectionBiDi( bool bBiDi ); + + /// The style of the page numbers. + /// + /// nPageRestartNumberr being 0 means no restart. + virtual void SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber ); + + /// The type of breaking. + virtual void SectionType( BYTE nBreakCode ); + + /// Special header/footer flags, needed for old versions only. + virtual void SectionWW6HeaderFooterFlags( BYTE nHeadFootFlags ); + + /// Definition of a numbering instance. + virtual void NumberingDefinition( USHORT nId, const SwNumRule &rRule ); + + /// All the numbering level information. + virtual void NumberingLevel( BYTE nLevel, + USHORT nStart, + USHORT nNumberingType, + SvxAdjust eAdjust, + const BYTE *pNumLvlPos, + BYTE nFollow, + const wwFont *pFont, + const SfxItemSet *pOutSet, + sal_Int16 nIndentAt, + sal_Int16 nFirstLineIndex, + sal_Int16 nListTabPos, + const String &rNumberingString ); + +protected: + /// Output frames - the implementation. + void OutputFlyFrame_Impl( const sw::Frame& rFmt, const Point& rNdTopLeft ); + + /// Sfx item Sfx item RES_CHRATR_CASEMAP + virtual void CharCaseMap( const SvxCaseMapItem& ); + + /// Sfx item Sfx item RES_CHRATR_COLOR + virtual void CharColor( const SvxColorItem& ); + + /// Sfx item Sfx item RES_CHRATR_CONTOUR + virtual void CharContour( const SvxContourItem& ); + + /// Sfx item RES_CHRATR_CROSSEDOUT + virtual void CharCrossedOut( const SvxCrossedOutItem& rHt ); + + /// Sfx item RES_CHRATR_ESCAPEMENT + virtual void CharEscapement( const SvxEscapementItem& ); + + /// Sfx item RES_CHRATR_FONT + virtual void CharFont( const SvxFontItem& ); + + /// Sfx item RES_CHRATR_FONTSIZE + virtual void CharFontSize( const SvxFontHeightItem& ); + + /// Sfx item RES_CHRATR_KERNING + virtual void CharKerning( const SvxKerningItem& ); + + /// Sfx item RES_CHRATR_LANGUAGE + virtual void CharLanguage( const SvxLanguageItem& ); + + /// Sfx item RES_CHRATR_POSTURE + virtual void CharPosture( const SvxPostureItem& ); + + /// Sfx item RES_CHRATR_SHADOWED + virtual void CharShadow( const SvxShadowedItem& ); + + /// Sfx item RES_CHRATR_UNDERLINE + virtual void CharUnderline( const SvxUnderlineItem& ); + + /// Sfx item RES_CHRATR_WEIGHT + virtual void CharWeight( const SvxWeightItem& ); + + /// Sfx item RES_CHRATR_AUTOKERN + virtual void CharAutoKern( const SvxAutoKernItem& ); + + /// Sfx item RES_CHRATR_BLINK + virtual void CharAnimatedText( const SvxBlinkItem& ); + + /// Sfx item RES_CHRATR_BACKGROUND + virtual void CharBackground( const SvxBrushItem& ); + + /// Sfx item RES_CHRATR_CJK_FONT + virtual void CharFontCJK( const SvxFontItem& ); + + /// Sfx item RES_CHRATR_CJK_FONTSIZE + virtual void CharFontSizeCJK( const SvxFontHeightItem& rHt ) { CharFontSize( rHt ); } + + /// Sfx item RES_CHRATR_CJK_LANGUAGE + virtual void CharLanguageCJK( const SvxLanguageItem& rHt ) { CharLanguage( rHt ); } + + /// Sfx item RES_CHRATR_CJK_POSTURE + virtual void CharPostureCJK( const SvxPostureItem& rHt ) { CharPosture( rHt ); } + + /// Sfx item RES_CHRATR_CJK_WEIGHT + virtual void CharWeightCJK( const SvxWeightItem& rHt ) { CharWeight( rHt ); } + + /// Sfx item RES_CHRATR_CTL_FONT + virtual void CharFontCTL( const SvxFontItem& ); + + /// Sfx item RES_CHRATR_CTL_FONTSIZE + virtual void CharFontSizeCTL( const SvxFontHeightItem& rHt ) { CharFontSize( rHt ); } + + /// Sfx item RES_CHRATR_CTL_LANGUAGE + virtual void CharLanguageCTL( const SvxLanguageItem& rHt ) { CharLanguage( rHt ); } + + /// Sfx item RES_CHRATR_CTL_POSTURE + virtual void CharPostureCTL( const SvxPostureItem& ); + + /// Sfx item RES_CHRATR_CTL_WEIGHT + virtual void CharWeightCTL( const SvxWeightItem& ); + + /// Sfx item RES_CHRATR_ROTATE + virtual void CharRotate( const SvxCharRotateItem& ); + + /// Sfx item RES_CHRATR_EMPHASIS_MARK + virtual void CharEmphasisMark( const SvxEmphasisMarkItem& rHt ); + + /// Sfx item RES_CHRATR_TWO_LINES + virtual void CharTwoLines( const SvxTwoLinesItem& ); + + /// Sfx item RES_CHRATR_SCALEW + virtual void CharScaleWidth( const SvxCharScaleWidthItem& ); + + /// Sfx item RES_CHRATR_RELIEF + virtual void CharRelief( const SvxCharReliefItem& ); + + /// Sfx item RES_CHRATR_HIDDEN + virtual void CharHidden( const SvxCharHiddenItem& ); + + /// Sfx item RES_TXTATR_INETFMT + virtual void TextINetFormat( const SwFmtINetFmt& ); + + /// Sfx item RES_TXTATR_CHARFMT + virtual void TextCharFormat( const SwFmtCharFmt& ); + + /// Sfx item RES_TXTATR_FTN + virtual void TextFootnote_Impl( const SwFmtFtn& ); + + /// Sfx item RES_TXTATR_HARDBLANK + virtual void TextHardBlank( const SwFmtHardBlank& ); + + /// Sfx item RES_PARATR_LINESPACING + virtual void ParaLineSpacing_Impl( short nSpace, short nMulti ); + + /// Sfx item RES_PARATR_ADJUST + virtual void ParaAdjust( const SvxAdjustItem& rHt ); + + /// Sfx item RES_PARATR_SPLIT + virtual void ParaSplit( const SvxFmtSplitItem& ); + + /// Sfx item RES_PARATR_WIDOWS + virtual void ParaWidows( const SvxWidowsItem& rHt ); + + /// Sfx item RES_PARATR_TABSTOP + virtual void ParaTabStop( const SvxTabStopItem& rHt ); + + /// Sfx item RES_PARATR_HYPHENZONE + virtual void ParaHyphenZone( const SvxHyphenZoneItem& ); + + /// Sfx item RES_PARATR_NUMRULE + virtual void ParaNumRule_Impl( const SwTxtNode *pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId ); + + /// Sfx item RES_PARATR_SCRIPTSPACE + virtual void ParaScriptSpace( const SfxBoolItem& ); + + /// Sfx item RES_PARATR_VERTALIGN + virtual void ParaVerticalAlign( const SvxParaVertAlignItem& ); + + /// Sfx item RES_PARATR_SNAPTOGRID + virtual void ParaSnapToGrid( const SvxParaGridItem& ); + + /// Sfx item RES_FRM_SIZE + virtual void FormatFrameSize( const SwFmtFrmSize& ); + + /// Sfx item RES_PAPER_BIN + virtual void FormatPaperBin( const SvxPaperBinItem& ); + + /// Sfx item RES_LR_SPACE + virtual void FormatLRSpace( const SvxLRSpaceItem& ); + + /// Sfx item RES_UL_SPACE + virtual void FormatULSpace( const SvxULSpaceItem& rHt ); + + /// Sfx item RES_SURROUND + virtual void FormatSurround( const SwFmtSurround& ); + + /// Sfx item RES_VERT_ORIENT + virtual void FormatVertOrientation( const SwFmtVertOrient& ); + + /// Sfx item RES_HORI_ORIENT + virtual void FormatHorizOrientation( const SwFmtHoriOrient& ); + + /// Sfx item RES_ANCHOR + virtual void FormatAnchor( const SwFmtAnchor& ); + + /// Sfx item RES_BACKGROUND + virtual void FormatBackground( const SvxBrushItem& ); + + /// Sfx item RES_BOX + virtual void FormatBox( const SvxBoxItem& ); + + /// Sfx item RES_COL + virtual void FormatColumns_Impl( USHORT nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize ); + + /// Sfx item RES_KEEP + virtual void FormatKeep( const SvxFmtKeepItem& ); + + /// Sfx item RES_TEXTGRID + virtual void FormatTextGrid( const SwTextGridItem& ); + + /// Sfx item RES_LINENUMBER + virtual void FormatLineNumbering( const SwFmtLineNumber& ); + + /// Sfx item RES_FRAMEDIR + virtual void FormatFrameDirection( const SvxFrameDirectionItem& ); + + /// Write the expanded field + virtual void WriteExpand( const SwField* pFld ); + + virtual void RefField ( const SwField& rFld, const String& rRef ); + virtual void HiddenField( const SwField& rFld ); + virtual void SetField( const SwField& rFld, ww::eField eType, const String& rCmd ); + virtual void PostitField( const SwField* pFld ); + virtual bool DropdownField( const SwField* pFld ); + + virtual bool AnalyzeURL( const String& rURL, const String& rTarget, String* pLinkURL, String* pMark ); + + /// Reference to the export, where to get the data from + WW8Export &m_rWW8Export; + + /// For output of styles. + /// + /// We have to remember these positions between the StartStyle() and + /// EndStyle(). + USHORT nPOPosStdLen1, nPOPosStdLen2; + + /// For output of styles. + /// + /// We have to remember this position between StartStyleProperties() and + /// EndStyleProperties(). + USHORT m_nStyleStartSize, m_nStyleLenPos; + + /// For output of styles. + /// + /// Used between StartStyles() and EndStyles(). + ULONG m_nStyAnzPos; + + /// For output of run properties. + /// + /// We have to remember the number of field results, and do not export end + /// of the field results if we were forced to split text. + USHORT m_nFieldResults; + +public: + WW8AttributeOutput( WW8Export &rWW8Export ) : AttributeOutputBase(), m_rWW8Export( rWW8Export ) {} + virtual ~WW8AttributeOutput() {} + + /// Return the right export class. + virtual MSWordExportBase& GetExport() { return m_rWW8Export; } + +protected: + /// Output the bold etc. attributes + void OutputWW8Attribute( BYTE nId, bool bVal ); + + /// Output the bold etc. attributes, the Complex Text Layout version + void OutputWW8AttributeCTL( BYTE nId, bool bVal ); + +}; + +#endif // _WW8ATTRIBUTEOUTPUT_HXX_ + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 82682078e294..e279447878c8 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -2720,12 +2720,8 @@ bool SwWW8ImplReader::ReadChar(long nPosCp, long nCpOfs) break; // Auto-Fussnoten-Nummer #if OSL_DEBUG_LEVEL > 1 default: - { - String sUnknown( '<' ); - sUnknown += String::CreateFromInt32( nWCharVal ); - sUnknown += '>'; - rDoc.Insert( *pPaM, sUnknown, true ); - } + ::std::clog << "<unknownValue val=\"" << nWCharVal << "\">" << ::std::endl; + break; #endif } diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index 15118e9abdb0..777b2e0055c3 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -54,12 +54,11 @@ #include <utility> #endif -#ifndef SW_TRACER #include "tracer.hxx" -#endif #include "ww8struc.hxx" // WW8_BRC #include "ww8scan.hxx" // WW8Fib #include "ww8glsy.hxx" +#include "wrtww8.hxx" #include "../inc/msfilter.hxx" class SwDoc; @@ -576,7 +575,7 @@ public: const ::com::sun::star::awt::Size& rSize, com::sun::star::uno::Reference < com::sun::star::drawing::XShape > *pShape,BOOL bFloatingCtrl); - bool ExportControl(Writer &rWrt, const SdrObject *pObj); + bool ExportControl(WW8Export &rWrt, const SdrObject *pObj); }; class SwMSDffManager : public SvxMSDffManager diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx index 30bf841bdcdd..2bcf97819f21 100644 --- a/sw/source/filter/ww8/ww8scan.hxx +++ b/sw/source/filter/ww8/ww8scan.hxx @@ -79,13 +79,13 @@ namespace SL DEFCONSTSTRINGARRAY(MSMacroCmds); } -/* - winword strings are typically Belt and Braces strings preceeded with a - pascal style count, and ending with a c style 0 terminator. 16bit chars - and count for ww8+ and 8bit chars and count for ww7-. The count and 0 - can be checked for integrity to catch errors (e.g. lotus created documents) - where in error 8bit strings are used instead of 16bits strings for style - names. +/** + winword strings are typically Belt and Braces strings preceeded with a + pascal style count, and ending with a c style 0 terminator. 16bit chars + and count for ww8+ and 8bit chars and count for ww7-. The count and 0 + can be checked for integrity to catch errors (e.g. lotus created documents) + where in error 8bit strings are used instead of 16bits strings for style + names. */ template<class C> class wwString { @@ -98,7 +98,7 @@ typedef wwString<sal_uInt16> ww8String; struct SprmInfo { - sal_uInt16 nId; //A ww8 sprm is hardcoded as 16bits + sal_uInt16 nId; ///< A ww8 sprm is hardcoded as 16bits unsigned int nLen : 6; unsigned int nVari : 2; }; @@ -114,8 +114,10 @@ struct SprmInfoHash typedef ww::WrappedHash<SprmInfo, SprmInfoHash> wwSprmSearcher; typedef ww::WrappedHash<sal_uInt16> wwSprmSequence; -//wwSprmParser knows how to take a sequence of bytes and split it up into -//sprms and their arguments +/** + wwSprmParser knows how to take a sequence of bytes and split it up into + sprms and their arguments +*/ class wwSprmParser { private: @@ -134,20 +136,20 @@ private: public: //7- ids are very different to 8+ ones wwSprmParser(ww::WordVersion eVersion); - //Return the SPRM id at the beginning of this byte sequence + /// Return the SPRM id at the beginning of this byte sequence sal_uInt16 GetSprmId(const sal_uInt8* pSp) const; USHORT GetSprmSize(sal_uInt16 nId, const sal_uInt8* pSprm) const; - //Get known len of a sprms head, the bytes of the sprm id + any bytes - //reserved to hold a variable length + /// Get known len of a sprms head, the bytes of the sprm id + any bytes + /// reserved to hold a variable length USHORT DistanceToData(sal_uInt16 nId) const; - //Get len of a sprms data area, ignoring the bytes of the sprm id and - //ignoring any len bytes. Reports the remaining data after those bytes + /// Get len of a sprms data area, ignoring the bytes of the sprm id and + /// ignoring any len bytes. Reports the remaining data after those bytes USHORT GetSprmTailLen(sal_uInt16 nId, const sal_uInt8 * pSprm) const; - //The minimum acceptable sprm len possible for this type of parser + /// The minimum acceptable sprm len possible for this type of parser int MinSprmLen() const { return (IsSevenMinus(meVersion)) ? 2 : 3; } inline int getVersion() const { return meVersion; } //cmc, I'm dubious about the usage of this, how can it be 0 @@ -164,14 +166,14 @@ class WW8PLCFx_PCD; String WW8ReadPString( SvStream& rStrm, rtl_TextEncoding eEnc, bool bAtEndSeekRel1 = true); -/* +/** The following method reads a 2Byte unicode string. If bAtEndSeekRel1 is set, exactly ONE byte is skipped If nChars is set then that number of characters (not bytes) is read, if its not set, the first character read is the length */ String WW8Read_xstz(SvStream& rStrm, USHORT nChars, bool bAtEndSeekRel1); -/* +/** reads array of strings (see MS documentation: STring TaBle stored in File) returns NOT the original pascal strings but an array of converted char* @@ -183,23 +185,23 @@ void WW8ReadSTTBF(bool bVer8, SvStream& rStrm, UINT32 nStart, INT32 nLen, struct WW8FieldDesc { - long nLen; // Gesamtlaenge ( zum Text ueberlesen ) - WW8_CP nSCode; // Anfang Befehlscode - WW8_CP nLCode; // Laenge - WW8_CP nSRes; // Anfang Ergebnis - WW8_CP nLRes; // Laenge ( == 0, falls kein Ergebnis ) - USHORT nId; // WW-Id fuer Felder - BYTE nOpt; // WW-Flags ( z.B.: vom User geaendert ) - BYTE bCodeNest:1; // Befehl rekursiv verwendet - BYTE bResNest:1; // Befehl in Resultat eingefuegt + long nLen; ///< Gesamtlaenge ( zum Text ueberlesen ) + WW8_CP nSCode; ///< Anfang Befehlscode + WW8_CP nLCode; ///< Laenge + WW8_CP nSRes; ///< Anfang Ergebnis + WW8_CP nLRes; ///< Laenge ( == 0, falls kein Ergebnis ) + USHORT nId; ///< WW-Id fuer Felder + BYTE nOpt; ///< WW-Flags ( z.B.: vom User geaendert ) + BYTE bCodeNest:1; ///< Befehl rekursiv verwendet + BYTE bResNest:1; ///< Befehl in Resultat eingefuegt }; struct WW8PLCFxSave1 { ULONG nPLCFxPos; - ULONG nPLCFxPos2; // fuer PLCF_Cp_Fkp: PieceIter-Pos + ULONG nPLCFxPos2; ///< fuer PLCF_Cp_Fkp: PieceIter-Pos long nPLCFxMemOfs; - WW8_CP nStartCp; // for cp based iterator like PAP and CHP + WW8_CP nStartCp; ///< for cp based iterator like PAP and CHP long nCpOfs; WW8_FC nStartFC; WW8_CP nAttrStart; @@ -207,17 +209,17 @@ struct WW8PLCFxSave1 bool bLineEnd; }; -/* +/** u.a. fuer Felder, also genausoviele Attr wie Positionen, falls Ctor-Param bNoEnd = false */ class WW8PLCFspecial // Iterator fuer PLCFs { private: - INT32* pPLCF_PosArray; // Pointer auf Pos-Array und auf ganze Struktur - BYTE* pPLCF_Contents; // Pointer auf Inhalts-Array-Teil des Pos-Array - long nIMax; // Anzahl der Elemente - long nIdx; // Merker, wo wir gerade sind + INT32* pPLCF_PosArray; ///< Pointer auf Pos-Array und auf ganze Struktur + BYTE* pPLCF_Contents; ///< Pointer auf Inhalts-Array-Teil des Pos-Array + long nIMax; ///< Anzahl der Elemente + long nIdx; ///< Merker, wo wir gerade sind long nStru; public: WW8PLCFspecial( SvStream* pSt, long nFilePos, long nPLCF, @@ -246,7 +248,7 @@ public: WW8PLCFspecial& operator --( int ) { nIdx--; return *this; } }; -/* simple Iterator for SPRMs */ +/** simple Iterator for SPRMs */ class WW8SprmIter { private: @@ -463,7 +465,7 @@ public: } }; -/* +/** Iterator for Piece Table Exceptions of Fkps works only with FCs, not with CPs ! ( Low-Level ) */ @@ -587,7 +589,7 @@ public: bool HasFkp() const { return (0 != pFkp); } }; -// Iterator fuer Piece Table Exceptions of Fkps arbeitet auf CPs (High-Level) +/// Iterator fuer Piece Table Exceptions of Fkps arbeitet auf CPs (High-Level) class WW8PLCFx_Cp_FKP : public WW8PLCFx_Fc_FKP { private: @@ -619,7 +621,7 @@ public: virtual void Restore( const WW8PLCFxSave1& rSave ); }; -// Iterator for Piece Table Exceptions of Sepx +/// Iterator for Piece Table Exceptions of Sepx class WW8PLCFx_SEPX : public WW8PLCFx { private: @@ -652,7 +654,7 @@ public: BYTE*& p1, BYTE*& p2, BYTE*& p3, BYTE*& p4 ) const; }; -// Iterator fuer Fuss-/Endnoten und Anmerkungen +/// Iterator fuer Fuss-/Endnoten und Anmerkungen class WW8PLCFx_SubDoc : public WW8PLCFx { private: @@ -684,7 +686,7 @@ public: long Count() const { return ( pRef ) ? pRef->GetIMax() : 0; } }; -// Iterator fuer Fuss- und Endnoten +/// Iterator for footnotes and endnotes class WW8PLCFx_FLD : public WW8PLCFx { private: @@ -709,7 +711,7 @@ public: enum eBookStatus { BOOK_NORMAL = 0, BOOK_IGNORE = 0x1, BOOK_FIELD = 0x2 }; -// Iterator for Booknotes +/// Iterator for Booknotes class WW8PLCFx_Book : public WW8PLCFx { private: @@ -978,7 +980,8 @@ public: }; -/* +/** FIB - the File Information Block + The FIB contains a "magic word" and pointers to the various other parts of the file, as well as information about the length of the file. The FIB starts at the beginning of the file. @@ -986,7 +989,7 @@ public: class WW8Fib { public: - /* + /** Program-Version asked for by us: in Ctor we check if it matches the value of nFib @@ -1497,7 +1500,8 @@ namespace nsHdFtFlags const HdFtFlags WW8_FOOTER_FIRST = 0x20; } -class WW8Dop // Document Properties +/// Document Properties +class WW8Dop { public: /* Error Status */ diff --git a/sw/source/filter/ww8/ww8struc.hxx b/sw/source/filter/ww8/ww8struc.hxx index 622a197b0295..aa4113484f68 100644 --- a/sw/source/filter/ww8/ww8struc.hxx +++ b/sw/source/filter/ww8/ww8struc.hxx @@ -165,15 +165,17 @@ typedef sal_Int32 WW8_CP; const WW8_FC WW8_FC_MAX = SAL_MAX_INT32; const WW8_CP WW8_CP_MAX = SAL_MAX_INT32; -// STD: STyle Definition -// The STD contains the entire definition of a style. -// It has two parts, a fixed-length base (cbSTDBase bytes long) -// and a variable length remainder holding the name, and the upx and upe -// arrays (a upx and upe for each type stored in the style, std.cupx) -// Note that new fields can be added to the BASE of the STD without -// invalidating the file format, because the STSHI contains the length -// that is stored in the file. When reading STDs from an older version, -// new fields will be zero. +/** STD - STyle Definition + + The STD contains the entire definition of a style. + It has two parts, a fixed-length base (cbSTDBase bytes long) + and a variable length remainder holding the name, and the upx and upe + arrays (a upx and upe for each type stored in the style, std.cupx) + Note that new fields can be added to the BASE of the STD without + invalidating the file format, because the STSHI contains the length + that is stored in the file. When reading STDs from an older version, + new fields will be zero. +*/ struct WW8_STD { // Base part of STD: @@ -203,9 +205,7 @@ struct WW8_STD // char grupe[]; }; -/* - Basis zum Einlesen UND zum Arbeiten (wird jeweils unter - schiedlich beerbt) +/** Basis zum Einlesen UND zum Arbeiten (wird jeweils unter schiedlich beerbt) */ struct WW8_FFN_BASE // Font Descriptor { @@ -223,8 +223,7 @@ struct WW8_FFN_BASE // Font Descriptor BYTE ibszAlt; // 0x5 index into ffn.szFfn to the name of the alternate font }; -/* - Hiermit arbeiten wir im Parser (und Dumper) +/** Hiermit arbeiten wir im Parser (und Dumper) */ struct WW8_FFN : public WW8_FFN_BASE { |