1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX
21 #define INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX
23 #include <sot/storage.hxx>
24 #include <tools/solar.h>
25 #include <tools/gen.hxx>
26 #include <editeng/editdata.hxx>
28 #include <shellio.hxx>
30 #include "ww8struc.hxx"
31 #include "ww8scan.hxx"
34 #include "writerhelper.hxx"
35 #include <msfilter.hxx>
37 #include "WW8TableInfo.hxx"
40 #include <vcl/graph.hxx>
43 #include <o3tl/typed_flags_set.hxx>
44 #include <o3tl/sorted_vector.hxx>
55 // some forward declarations
62 namespace editeng
{ class SvxBorderLine
; }
64 class AttributeOutputBase
;
65 class DocxAttributeOutput
;
66 class RtfAttributeOutput
;
70 namespace vcl
{ class Font
; }
71 class MSWordExportBase
;
83 class SwFormatContent
;
84 class SwFormatFootnote
;
91 class SwFormatPageDesc
;
95 class SwSectionFormat
;
99 class SwTextFormatColl
;
104 class WW8AttributeOutput
;
106 class MSWordAttrIter
;
110 class WW8_WrPlcField
;
111 class WW8_WrMagicTable
;
112 class WW8_WrPlcFootnoteEdn
;
114 class WW8_WrPlcAnnotations
;
115 class WW8_WrtFactoids
;
116 class MSWordSections
;
117 class WW8_WrPlcTextBoxes
;
118 class WW8_WrPct
; // administration
119 class WW8_WrtBookmarks
;
120 class WW8_WrtRedlineAuthor
;
121 class SvxMSExportOLEObjects
;
122 class SwMSConvertControls
;
124 struct WW8_PdAttrDesc
;
126 namespace sw::mark
{ class IFieldmark
; }
127 namespace com::sun::star::embed
{ class XEmbeddedObject
; }
129 typedef std::map
<const css::embed::XEmbeddedObject
*, sal_Int32
> WW8OleMap
;
130 typedef o3tl::sorted_vector
< sal_Int32
> SwSoftPageBreakList
;
132 #define GRF_MAGIC_1 0x12 // 3 magic bytes for PicLocFc attribute
133 #define GRF_MAGIC_2 0x34
134 #define GRF_MAGIC_3 0x56
135 #define GRF_MAGIC_321 0x563412L
137 #define OLE_PREVIEW_AS_EMF //If we want to export ole2 previews as emf in ww8+
139 enum class FieldFlags
: sal_uInt8
// for InsertField- Method
150 template<> struct typed_flags
<FieldFlags
> : is_typed_flags
<FieldFlags
, 0x37> {};
153 enum TextTypes
//enums for TextTypes
155 TXT_MAINTEXT
= 0, /*TXT_FTNEDN = 1,*/ TXT_HDFT
= 2, TXT_FTN
= 3,
156 TXT_EDN
= 4, TXT_ATN
= 5, TXT_TXTBOX
= 6, TXT_HFTXTBOX
= 7
160 enum to state the present state of the fly
162 enum FlyProcessingState
172 const SwPageDesc
* pPageDesc
;
173 const SwSectionFormat
* pSectionFormat
;
175 sal_uLong nLnNumRestartNo
;
176 ::std::optional
<sal_uInt16
> oPgRestartNo
;
177 bool bIsFirstParagraph
;
179 WW8_SepInfo( const SwPageDesc
* pPD
, const SwSectionFormat
* pFormat
,
180 sal_uLong nLnRestart
, ::std::optional
<sal_uInt16
> oPgRestart
= std::nullopt
,
181 const SwNode
* pNd
= nullptr, bool bIsFirstPara
= false )
182 : pPageDesc( pPD
), pSectionFormat( pFormat
), pPDNd( pNd
),
183 nLnNumRestartNo( nLnRestart
), oPgRestartNo( oPgRestart
),
184 bIsFirstParagraph( bIsFirstPara
)
187 bool IsProtected() const;
190 /// Class to collect and output the sections/headers/footers.
191 // Plc for PageDescs -> Sepx ( Section Extensions )
195 bool mbDocumentIsProtected
;
196 std::vector
<WW8_SepInfo
> aSects
;
198 void CheckForFacinPg( const WW8Export
& rWrt
) const;
199 void NeedsDocumentProtected(const WW8_SepInfo
&rInfo
);
202 MSWordSections( const MSWordSections
& );
203 MSWordSections
& operator=( const MSWordSections
& );
205 explicit MSWordSections( MSWordExportBase
& rExport
);
206 virtual ~MSWordSections();
208 virtual bool HeaderFooterWritten();
210 void AppendSection( const SwPageDesc
* pPd
,
211 const SwSectionFormat
* pSectionFormat
,
212 sal_uLong nLnNumRestartNo
,
213 bool bIsFirstParagraph
= false );
214 void AppendSection( const SwFormatPageDesc
& rPd
,
216 const SwSectionFormat
* pSectionFormat
,
217 sal_uLong nLnNumRestartNo
);
219 /// Number of columns based on the most recent WW8_SepInfo.
220 sal_uInt16
CurrentNumberOfColumns( const SwDoc
&rDoc
) const;
222 /// Number of columns of the provided WW8_SepInfo.
223 static sal_uInt16
NumberOfColumns( const SwDoc
&rDoc
, const WW8_SepInfo
& rInfo
);
225 bool DocumentIsProtected() const { return mbDocumentIsProtected
; }
227 /// The most recent WW8_SepInfo.
228 const WW8_SepInfo
* CurrentSectionInfo();
230 static void SetHeaderFlag( sal_uInt8
& rHeadFootFlags
, const SwFormat
& rFormat
,
232 static void SetFooterFlag( sal_uInt8
& rHeadFootFlags
, const SwFormat
& rFormat
,
235 /// Should we output borders?
236 static bool HasBorderItem( const SwFormat
& rFormat
);
239 class WW8_WrPlcSepx
: public MSWordSections
241 std::vector
<WW8_CP
> aCps
;
242 std::vector
< std::shared_ptr
<WW8_PdAttrDesc
> > m_SectionAttributes
;
243 // hack to prevent adding sections in endnotes
244 bool m_bHeaderFooterWritten
;
245 std::unique_ptr
<WW8_WrPlc0
> pTextPos
; // Position of the headers/footers
247 WW8_WrPlcSepx( const WW8_WrPlcSepx
& ) = delete;
248 WW8_WrPlcSepx
& operator=( const WW8_WrPlcSepx
& ) = delete;
251 explicit WW8_WrPlcSepx( MSWordExportBase
& rExport
);
252 virtual ~WW8_WrPlcSepx() override
;
254 virtual bool HeaderFooterWritten() override
; // override
256 void AppendSep( WW8_CP nStartCp
,
257 const SwPageDesc
* pPd
,
258 const SwSectionFormat
* pSectionFormat
,
259 sal_uLong nLnNumRestartNo
);
260 void AppendSep( WW8_CP nStartCp
, const SwFormatPageDesc
& rPd
,
262 const SwSectionFormat
* pSectionFormat
,
263 sal_uLong nLnNumRestartNo
);
264 void Finish( WW8_CP nEndCp
) { aCps
.push_back( nEndCp
); }
266 bool WriteKFText( WW8Export
& rWrt
);
267 void WriteSepx( SvStream
& rStrm
) const;
268 void WritePlcSed( WW8Export
& rWrt
) const;
269 void WritePlcHdd( WW8Export
& rWrt
) const;
272 void WriteFootnoteEndText( WW8Export
& rWrt
, sal_uLong nCpStt
);
274 void OutHeaderFooter(WW8Export
& rWrt
, bool bHeader
,
275 const SwFormat
& rFormat
, sal_uLong
& rCpPos
, sal_uInt8 nHFFlags
, sal_uInt8 nFlag
, sal_uInt8 nBreakCode
);
278 // class WW8_WrPct to construct the piece table
281 std::vector
<std::unique_ptr
<WW8_WrPc
>> m_Pcts
;
284 explicit WW8_WrPct(WW8_FC nStartFc
);
286 void AppendPc(WW8_FC nStartFc
);
287 void WritePc( WW8Export
& rWrt
);
289 WW8_CP
Fc2Cp( sal_uLong nFc
) const;
292 /// Collects and outputs fonts.
295 //In some future land the stream could be converted to a nice stream interface
296 //and we could have harmony
298 sal_uInt8 maWW8_FFN
[6] = {};
304 rtl_TextEncoding meChrSet
;
306 wwFont( const OUString
&rFamilyName
, FontPitch ePitch
, FontFamily eFamily
,
307 rtl_TextEncoding eChrSet
);
308 void Write( SvStream
*pTableStram
) const;
309 void WriteDocx( DocxAttributeOutput
* rAttrOutput
) const;
310 void WriteRtf( const RtfAttributeOutput
* rAttrOutput
) const;
311 OUString
const & GetFamilyName() const { return msFamilyNm
; }
312 friend bool operator < (const wwFont
&r1
, const wwFont
&r2
);
318 /// Keep track of fonts that need to be exported.
319 std::map
<wwFont
, sal_uInt16
> maFonts
;
321 /// Convert from fast insertion map to linear vector in the order that we want to write.
322 std::vector
< const wwFont
* > AsVector() const;
325 wwFontHelper() : bLoadAllFonts(false) {}
326 /// rDoc used only to get the initial standard font(s) in use.
327 void InitFontTable(const SwDoc
& rDoc
);
328 sal_uInt16
GetId(const SvxFontItem
& rFont
);
329 sal_uInt16
GetId(const wwFont
& rFont
);
330 void WriteFontTable( SvStream
*pTableStream
, WW8Fib
& pFib
);
331 void WriteFontTable( DocxAttributeOutput
& rAttrOutput
);
332 void WriteFontTable( const RtfAttributeOutput
& rAttrOutput
);
334 /// If true, all fonts are loaded before processing the document.
335 bool bLoadAllFonts
: 1;
341 WW8_CP mnCp
; // CP-Pos of references
342 sal_uInt32 mnShapeId
; // ShapeId for the SwFrameFormats
343 ww8::Frame maContent
; // the frame itself
344 Point maParentPos
; // Points
345 sal_Int32 mnThick
; // Border Thicknesses
346 SvxFrameDirection mnDirection
; // If BiDi or not
347 unsigned int mnHdFtIndex
; // 0 for main text, +1 for each subsequent
350 DrawObj(const ww8::Frame
&rContent
, WW8_CP nCp
, Point aParentPos
, SvxFrameDirection nDir
,
351 unsigned int nHdFtIndex
)
352 : mnCp(nCp
), mnShapeId(0), maContent(rContent
), maParentPos(aParentPos
),
353 mnThick(0), mnDirection(nDir
), mnHdFtIndex(nHdFtIndex
) {}
354 void SetShapeDetails(sal_uInt32 nId
, sal_Int32 nThick
);
357 typedef std::vector
<DrawObj
> DrawObjVector
;
358 typedef std::vector
<DrawObj
*> DrawObjPointerVector
;
360 class PlcDrawObj
// PC for DrawObjects and Text-/OLE-/GRF-Boxes
363 DrawObjVector maDrawObjs
; // vector of drawobjs
365 virtual void RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
366 sal_uInt32 nLen
) const = 0;
367 virtual WW8_CP
GetCpOffset(const WW8Fib
&rFib
) const = 0;
370 void WritePlc( WW8Export
& rWrt
) const;
371 bool Append( WW8Export
const &, WW8_CP nCp
, const ww8::Frame
& rFormat
,
372 const Point
& rNdTopLeft
);
373 int size() { return maDrawObjs
.size(); };
374 DrawObjVector
&GetObjArr() { return maDrawObjs
; }
375 virtual ~PlcDrawObj();
377 PlcDrawObj(const PlcDrawObj
&) = delete;
378 PlcDrawObj
& operator=(const PlcDrawObj
&) = delete;
381 class MainTextPlcDrawObj
: public PlcDrawObj
384 MainTextPlcDrawObj() {}
386 virtual void RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
387 sal_uInt32 nLen
) const override
;
388 virtual WW8_CP
GetCpOffset(const WW8Fib
&) const override
;
390 MainTextPlcDrawObj(const MainTextPlcDrawObj
&) = delete;
391 MainTextPlcDrawObj
& operator=(const MainTextPlcDrawObj
&) = delete;
394 class HdFtPlcDrawObj
: public PlcDrawObj
399 virtual void RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
400 sal_uInt32 nLen
) const override
;
401 virtual WW8_CP
GetCpOffset(const WW8Fib
&rFib
) const override
;
403 HdFtPlcDrawObj(const HdFtPlcDrawObj
&) = delete;
404 HdFtPlcDrawObj
& operator=(const HdFtPlcDrawObj
&) = delete;
407 typedef std::pair
<OUString
, sal_uLong
> aBookmarkPair
;
409 class WW8_WrtRedlineAuthor
: public sw::util::WrtRedlineAuthor
412 virtual void Write(Writer
&rWrt
) override
;
415 /** Structure that is used to save some of the WW8Export/DocxExport data.
417 It is used to be able to recurse inside of the WW8Export/DocxExport (eg.
418 for the needs of the tables) - you need to tall WriteText() from there with
419 new values of PaM etc.
421 It must contain all the stuff that might be saved either in WW8Export or in
422 DocxExport, because it makes no sense to do it abstract, and specialize it
423 for each of the cases. If you implement other *Export, just add the needed
424 members here, and store them in the appropriate SaveData() method.
426 struct MSWordSaveData
428 Point
* pOldFlyOffset
;
429 RndStdIds eOldAnchorType
;
430 std::unique_ptr
<ww::bytes
> pOOld
; ///< WW8Export only
431 std::shared_ptr
<SwUnoCursor
> pOldPam
;
433 sal_uLong nOldStart
, nOldEnd
;
434 const ww8::Frame
* pOldFlyFormat
;
435 const SwPageDesc
* pOldPageDesc
;
437 bool bOldWriteAll
: 1; ///< WW8Export only
438 bool bOldOutTable
: 1;
439 bool bOldFlyFrameAttrs
: 1;
440 bool bOldStartTOX
: 1;
441 bool bOldInWriteTOX
: 1;
442 // m_bOutPageDescs does not have to be saved in MSWordExportBase::SaveData
443 // since it is only modified when outputting special texts.
446 /// Base class for WW8Export and DocxExport
447 class MSWordExportBase
450 wwFontHelper m_aFontHelper
;
451 std::vector
<sal_uLong
> m_aChapterFieldLocs
;
453 std::vector
<const SwTOXType
*> m_aTOXArr
;
454 const SfxItemSet
* m_pISet
; // for double attributes
455 const SwFrameFormat
* m_pFirstPageFormat
= nullptr;
456 WW8_WrPct
* m_pPiece
; // Pointer to Piece-Table
457 std::unique_ptr
<SwNumRuleTable
> m_pUsedNumTable
; // all used NumRules
458 /// overriding numdef index -> (existing numdef index, abstractnumdef index)
459 std::map
<size_t, std::pair
<size_t, size_t>> m_OverridingNums
;
460 /// list-id -> abstractnumdef index
461 std::map
<OUString
, size_t> m_Lists
;
463 /// Map of maps for list levels overrides
464 /// listid -> level number -> restart value
465 std::map
< size_t, std::map
<size_t, size_t> > m_ListLevelOverrides
;
467 const SwTextNode
*m_pTopNodeOfHdFtPage
; ///< Top node of host page when in hd/ft
468 std::stack
< sal_Int32
> m_aCurrentCharPropStarts
; ///< To remember the position in a run.
469 WW8_WrtBookmarks
* m_pBkmks
;
470 WW8_WrtRedlineAuthor
* m_pRedlAuthors
;
471 std::shared_ptr
<NfKeywordTable
> m_pKeyMap
;
472 std::unique_ptr
<SvxMSExportOLEObjects
> m_pOLEExp
;
473 std::unique_ptr
<SwMSConvertControls
> m_pOCXExp
;
474 WW8OleMap m_aOleMap
; // To remember all already exported ole objects
475 ww8::WW8TableInfo::Pointer_t m_pTableInfo
;
477 sal_uInt16 m_nCharFormatStart
;
478 sal_uInt16 m_nFormatCollStart
;
479 sal_uInt16 m_nStyleBeforeFly
; ///< style number of the node
480 ///< to which the Fly is connected
481 sal_uInt16 m_nLastFormatId
; ///< Style of last TextNode in normal range
482 sal_uInt16 m_nUniqueList
; ///< current number for creating unique list names
483 unsigned int m_nHdFtIndex
;
485 RedlineFlags m_nOrigRedlineFlags
; ///< Remember the original redline mode
486 bool m_bOrigShowChanges
; ///< Remember the original Show Changes mode
489 /* implicit bookmark vector containing pairs of node indexes and bookmark names */
490 std::vector
<aBookmarkPair
> m_aImplicitBookmarks
;
491 ww8::Frames m_aFrames
; // The floating frames in this document
492 const SwPageDesc
*m_pCurrentPageDesc
;
493 bool m_bFirstTOCNodeWithSection
;
494 std::unique_ptr
<WW8_WrPlcPn
> m_pPapPlc
;
495 std::unique_ptr
<WW8_WrPlcPn
> m_pChpPlc
;
496 MSWordAttrIter
* m_pChpIter
;
497 std::unique_ptr
<MSWordStyles
> m_pStyles
;
498 WW8_WrPlcAnnotations
* m_pAtn
;
499 std::unique_ptr
<WW8_WrtFactoids
> m_pFactoids
;
500 WW8_WrPlcTextBoxes
*m_pTextBxs
, *m_pHFTextBxs
;
502 struct LinkedTextboxInfo
//help analyze textbox flow links
508 LinkedTextboxInfo(): nId(0), nSeq(0) {}
510 std::map
<OUString
,LinkedTextboxInfo
> m_aLinkedTextboxesHelper
;
511 bool m_bLinkedTextboxesHelperInitialized
= false;
512 sal_Int32 m_nLinkedTextboxesChainId
=0;
514 const ww8::Frame
*m_pParentFrame
; // If set we are exporting content inside
515 // a frame, e.g. a graphic node
517 Point
* m_pFlyOffset
; // for adjusting of character-bound Fly in the Writer,
518 RndStdIds m_eNewAnchorType
; // that is paragraph-bound in the WW.
520 std::unique_ptr
<WW8_WrPlcField
> m_pFieldMain
; // fields in MainText
521 std::unique_ptr
<WW8_WrPlcField
> m_pFieldHdFt
; // fields in Header/Footer
522 std::unique_ptr
<WW8_WrPlcField
> m_pFieldFootnote
; // fields in FootNotes
523 std::unique_ptr
<WW8_WrPlcField
> m_pFieldEdn
; // fields in EndNotes
524 std::unique_ptr
<WW8_WrPlcField
> m_pFieldAtn
; // fields in Annotations
525 std::unique_ptr
<WW8_WrPlcField
> m_pFieldTextBxs
; // fields in textboxes
526 std::unique_ptr
<WW8_WrPlcField
> m_pFieldHFTextBxs
; // fields in header/footer textboxes
527 std::unique_ptr
<WW8_WrMagicTable
> m_pMagicTable
; // keeps track of table cell positions, and
528 // marks those that contain graphics,
529 // which is required to make word display
530 // graphics inside tables
531 std::unique_ptr
<SwWW8WrGrf
> m_pGrf
;
532 const SwAttrSet
* m_pStyAttr
; // StyleAttr for Tabs
533 const sw::BroadcastingModify
* m_pOutFormatNode
; // write Format or Node
534 const SwFormat
*m_pCurrentStyle
; // iff bStyDef=true, then this store the current style
536 MainTextPlcDrawObj
*m_pSdrObjs
; // Draw-/Fly-Objects
537 HdFtPlcDrawObj
*m_pHFSdrObjs
; // Draw-/Fly-Objects in header or footer
539 SwEscherEx
* m_pEscher
; // escher export class
540 // #i43447# - removed
541 // SwTwips nFlyWidth, nFlyHeight; // for adaptation of graphics
543 sal_uInt8 m_nTextTyp
;
545 bool m_bStyDef
: 1; // should Style be written?
546 bool m_bBreakBefore
: 1; // Breaks are being written 2 times
547 bool m_bOutKF
: 1; // Header/Footer texts are being written
548 bool m_bOutFlyFrameAttrs
: 1; // Frame-attr of Flys are being written
549 bool m_bOutPageDescs
: 1; ///< PageDescs (section properties) are being written
550 bool m_bOutFirstPage
: 1; // write Attrset of FirstPageDesc
551 bool m_bOutTable
: 1; // table is being written
552 // ( is reset e.g. for Flys in a table )
553 bool m_bOutGrf
: 1; // graphics are being written
554 bool m_bInWriteEscher
: 1; // in write textboxes
555 bool m_bStartTOX
: 1; // true: a TOX is started
556 bool m_bInWriteTOX
: 1; // true: all content are in a TOX
557 bool m_bFootnoteAtTextEnd
: 1; // true: all FTN at Textend
558 bool m_bEndAtTextEnd
: 1; // true: all END at Textend
561 bool m_bSubstituteBullets
: 1; // true: SubstituteBullet() gets called
562 bool m_bTabInTOC
: 1; //true for TOC field flag 'w'
564 bool m_bHideTabLeaderAndPageNumbers
: 1 ; // true: the 'z' field of TOC is set.
565 bool m_bExportModeRTF
;
566 /// Is font size written already as part of the current character properties?
567 bool m_bFontSizeWritten
;
568 bool m_bAddFootnoteTab
; // only one aesthetic spacing tab per footnote
571 sal_uLong m_nCurStart
, m_nCurEnd
;
572 std::shared_ptr
<SwUnoCursor
> & m_pCurPam
;
575 /// Stack to remember the nesting (see MSWordSaveData for more)
576 std::stack
< MSWordSaveData
> m_aSaveData
;
578 /// Used to split the runs according to the bookmarks start and ends
579 typedef std::vector
< ::sw::mark::IMark
* > IMarkVector
;
580 IMarkVector m_rSortedBookmarksStart
;
581 IMarkVector m_rSortedBookmarksEnd
;
582 IMarkVector m_rSortedAnnotationMarksStart
;
583 IMarkVector m_rSortedAnnotationMarksEnd
;
586 /// The main function to export the document.
587 ErrCode
ExportDocument( bool bWriteAll
);
589 /// Iterate through the nodes and call the appropriate OutputNode() on them.
592 /// Return whether currently exported node is in table.
593 bool IsInTable() const;
595 /// Set the pCurPam appropriately and call WriteText().
597 /// Used to export paragraphs in footnotes/endnotes/etc.
598 void WriteSpecialText( sal_uLong nStart
, sal_uLong nEnd
, sal_uInt8 nTTyp
);
600 /// Export the pool items to attributes (through an attribute output class).
601 void ExportPoolItemsToCHP( ww8::PoolItems
&rItems
, sal_uInt16 nScript
, const SvxFontItem
*pFont
, bool bWriteCombChars
= false );
603 /// Return the numeric id of the numbering rule
604 sal_uInt16
GetNumberingId( const SwNumRule
& rNumRule
);
606 /// Return the numeric id of the style.
607 sal_uInt16
GetId( const SwTextFormatColl
& rColl
) const;
609 /// Return the numeric id of the style.
610 sal_uInt16
GetId( const SwCharFormat
* pFormat
) const;
612 sal_uInt16
GetId( const SwTOXType
& rTOXType
);
614 /// Return the numeric id of the font (and add it to the font list if needed)
615 sal_uInt16
GetId( const SvxFontItem
& rFont
)
617 return m_aFontHelper
.GetId(rFont
);
620 void GetId( const wwFont
& rFont
)
622 m_aFontHelper
.GetId(rFont
);
625 const SfxPoolItem
& GetItem( sal_uInt16 nWhich
) const;
626 template<class T
> const T
& GetItem( TypedWhichId
<T
> nWhich
) const
628 return static_cast<const T
&>(GetItem(sal_uInt16(nWhich
)));
631 /// Find the reference.
632 bool HasRefToAttr(const OUString
& rName
);
633 bool HasRefToFootOrEndnote(const bool isEndNote
, const sal_uInt16 nSeqNo
);
635 /// Find the bookmark name.
636 static OUString
GetBookmarkName( sal_uInt16 nTyp
, const OUString
* pName
, sal_uInt16 nSeqNo
);
638 /// Use OutputItem() on an item set according to the parameters.
639 void OutputItemSet( const SfxItemSet
& rSet
, bool bPapFormat
, bool bChpFormat
, sal_uInt16 nScript
, bool bExportParentItemSet
);
641 SvxFrameDirection
GetDefaultFrameDirection( ) const;
644 SvxFrameDirection
TrueFrameDirection( const SwFrameFormat
& rFlyFormat
) const;
647 SvxFrameDirection
GetCurrentPageDirection() const;
649 /// In case of numbering restart.
651 /// List is set to restart at a particular value so for export make a
652 /// completely new list based on this one and export that instead,
653 /// which duplicates words behaviour in this respect.
654 sal_uInt16
DuplicateNumRule(const SwNumRule
* pRule
, sal_uInt8 nLevel
, sal_uInt16 nVal
);
655 SwNumRule
* DuplicateNumRuleImpl(const SwNumRule
*pRule
);
657 /// check if a new abstractNum is needed for this list
658 sal_uInt16
DuplicateAbsNum(OUString
const& rListId
,
659 SwNumRule
const& rAbstractRule
);
662 /// Create a overriding numbering definition (if it does not yet exist)
663 /// @return index of the overriding numbering definition
664 sal_uInt16
OverrideNumRule(SwNumRule
const& rExistingRule
,
665 OUString
const& rListId
,
666 SwNumRule
const& rAbstractRule
);
668 /// Store list level overrides (restart of list)
669 void AddListLevelOverride(sal_uInt16 nListId
,
670 sal_uInt16 nLevelNum
,
671 sal_uInt16 nStartAt
);
673 /// Access to the attribute output class.
674 virtual AttributeOutputBase
& AttrOutput() const = 0;
676 /// Access to the sections/headers/footres.
677 virtual MSWordSections
& Sections() const = 0;
679 /// Determines if the import filter already quoted fields or not.
680 virtual bool FieldsQuoted() const = 0;
682 /// Determines the Section Breaks are to be added for TOX Section
683 virtual bool AddSectionBreaksForTOX() const = 0;
685 /// Used to filter out attributes that can be e.g. written to .doc but not to .docx
686 virtual bool ignoreAttributeForStyleDefaults( sal_uInt16
/*nWhich*/ ) const { return false; }
688 /// If saving page break is preferred as a paragraph attribute (yes) or as a special character (no).
689 virtual bool PreferPageBreakBefore() const = 0;
691 /// Guess the script (asian/western).
693 /// Sadly word does not have two different sizes for asian font size and
694 /// western font size, it has two different fonts, but not sizes, so we
695 /// have to use our guess as to the script used and disable the export of
696 /// one type. The same occurs for font weight and posture (bold and
699 /// In addition WW7- has only one character language identifier while WW8+
701 virtual bool CollapseScriptsforWordOk( sal_uInt16 nScript
, sal_uInt16 nWhich
) = 0;
703 virtual void AppendBookmarks( const SwTextNode
& rNd
, sal_Int32 nCurrentPos
, sal_Int32 nLen
) = 0;
705 virtual void AppendBookmark( const OUString
& rName
) = 0;
707 virtual void AppendAnnotationMarks( const SwWW8AttrIter
& rAttrs
, sal_Int32 nCurrentPos
, sal_Int32 nLen
) = 0;
709 virtual void AppendSmartTags(SwTextNode
& /*rTextNode*/) { }
711 //For i120928,add this interface to export graphic of bullet
712 virtual void ExportGrfBullet(const SwTextNode
& rNd
) = 0;
714 // FIXME probably a hack...
715 virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner
= ww8::WW8TableNodeInfoInner::Pointer_t() ) = 0;
717 // FIXME definitely a hack, must not be here - it can't do anything
719 virtual void WriteChar( sal_Unicode c
) = 0;
721 /// Output attributes.
722 void OutputFormat( const SwFormat
& rFormat
, bool bPapFormat
, bool bChpFormat
, bool bFlyFormat
= false );
724 /// Getter for pISet.
725 const SfxItemSet
* GetCurItemSet() const { return m_pISet
; }
727 /// Setter for pISet.
728 void SetCurItemSet( const SfxItemSet
* pS
) { m_pISet
= pS
; }
730 /// Remember some of the members so that we can recurse in WriteText().
731 virtual void SaveData( sal_uLong nStt
, sal_uLong nEnd
);
733 /// Restore what was saved in SaveData().
734 virtual void RestoreData();
736 /// The return value indicates, if a follow page desc is written.
737 bool OutputFollowPageDesc( const SfxItemSet
* pSet
,
738 const SwTextNode
* pNd
);
740 /// Write header/footer text.
741 void WriteHeaderFooterText( const SwFormat
& rFormat
, bool bHeader
);
743 /// Format of the section.
744 static const SwSectionFormat
* GetSectionFormat( const SwNode
& rNd
);
746 /// Line number of the section start.
747 static sal_uLong
GetSectionLineNo( const SfxItemSet
* pSet
, const SwNode
& rNd
);
749 /// Start new section.
750 void OutputSectionBreaks( const SfxItemSet
*pSet
, const SwNode
& rNd
, bool isCellOpen
= false );
752 /// Write section properties.
754 /// pA is ignored for docx.
755 void SectionProperties( const WW8_SepInfo
& rSectionInfo
, WW8_PdAttrDesc
* pA
= nullptr );
757 /// Output the numbering table.
758 virtual void WriteNumbering() = 0;
760 /// Write static data of SwNumRule - LSTF
761 void NumberingDefinitions();
763 /// Write all Levels for all SwNumRules - LVLF
764 void AbstractNumberingDefinitions();
766 /// Write one numbering level
767 void NumberingLevel(SwNumRule
const& rRule
, sal_uInt8 nLvl
);
769 // Convert the bullet according to the font.
770 void SubstituteBullet( OUString
& rNumStr
, rtl_TextEncoding
& rChrSet
,
771 OUString
& rFontName
) const;
773 /// Setup the pA's info.
774 virtual void SetupSectionPositions( WW8_PdAttrDesc
* /*pA*/ ) {}
776 /// Top node of host page when in header/footer.
777 void SetHdFtPageRoot( const SwTextNode
*pNd
) { m_pTopNodeOfHdFtPage
= pNd
; }
779 /// Top node of host page when in header/footer.
780 const SwTextNode
*GetHdFtPageRoot() const { return m_pTopNodeOfHdFtPage
; }
782 /// Output the actual headers and footers.
783 virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags
,
784 const SwFrameFormat
& rFormat
, const SwFrameFormat
& rLeftFormat
, const SwFrameFormat
& rFirstPageFormat
,
785 sal_uInt8 nBreakCode
) = 0;
788 virtual void OutputField( const SwField
* pField
, ww::eField eFieldType
,
789 const OUString
& rFieldCmd
, FieldFlags nMode
= FieldFlags::All
) = 0;
791 /// Write the data of the form field
792 virtual void WriteFormData( const ::sw::mark::IFieldmark
& rFieldmark
) = 0;
793 virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark
& rFieldmark
) = 0;
795 virtual void DoComboBox(const OUString
&rName
,
796 const OUString
&rHelp
,
797 const OUString
&ToolTip
,
798 const OUString
&rSelected
,
799 const css::uno::Sequence
<OUString
> &rListItems
) = 0;
801 virtual void DoFormText(const SwInputField
* pField
) = 0;
803 static bool NoPageBreakSection( const SfxItemSet
*pSet
);
805 // Compute the number format for WW dates
806 bool GetNumberFormat(const SwField
& rField
, OUString
& rStr
);
808 virtual sal_uLong
ReplaceCr( sal_uInt8 nChar
) = 0;
810 const SfxPoolItem
* HasItem( sal_uInt16 nWhich
) const;
812 /// Returns the index of a picture bullet, used in numberings.
813 int GetGrfIndex(const SvxBrushItem
& rBrush
);
815 enum ExportFormat
{ DOC
= 0, RTF
= 1, DOCX
= 2};
816 virtual ExportFormat
GetExportFormat() const = 0;
819 /// Format-dependent part of the actual export.
820 virtual ErrCode
ExportDocument_Impl() = 0;
822 /// Get the next position in the text node to output
823 sal_Int32
GetNextPos( SwWW8AttrIter
const * pAttrIter
, const SwTextNode
& rNode
, sal_Int32 nCurrentPos
);
825 /// Update the information for GetNextPos().
826 void UpdatePosition( SwWW8AttrIter
* pAttrIter
, sal_Int32 nCurrentPos
);
828 /// Output SwTextNode
829 virtual void OutputTextNode( SwTextNode
& );
831 /// Setup the chapter fields (maChapterFieldLocs).
832 void GatherChapterFields();
834 void AddLinkTarget( const OUString
& rURL
);
835 void CollectOutlineBookmarks( const SwDoc
&rDoc
);
837 bool SetCurrentPageDescFromNode(const SwNode
&rNd
);
838 bool ContentContainsChapterField(const SwFormatContent
&rContent
) const;
839 bool FormatHdFtContainsChapterField(const SwFrameFormat
&rFormat
) const;
841 virtual void SectionBreaksAndFrames( const SwTextNode
& rNode
) = 0;
843 virtual void PrepareNewPageDesc( const SfxItemSet
* pSet
,
845 const SwFormatPageDesc
* pNewPgDescFormat
,
846 const SwPageDesc
* pNewPgDesc
) = 0;
848 /// Return value indicates if an inherited outline numbering is suppressed.
849 virtual bool DisallowInheritingOutlineNumbering(const SwFormat
&rFormat
) = 0;
851 /// Output SwStartNode
852 void OutputStartNode( const SwStartNode
& );
855 virtual void OutputEndNode( const SwEndNode
& );
858 virtual void OutputGrfNode( const SwGrfNode
& ) = 0;
861 virtual void OutputOLENode( const SwOLENode
& ) = 0;
863 virtual void OutputLinkedOLE( const OUString
& ) = 0;
865 /// Output SwSectionNode
866 void OutputSectionNode( const SwSectionNode
& );
867 static void UpdateTocSectionNodeProperties(const SwSectionNode
& rSectionNode
);
869 virtual void AppendSection( const SwPageDesc
*pPageDesc
, const SwSectionFormat
* pFormat
, sal_uLong nLnNum
) = 0;
871 /// Call the right (virtual) function according to the type of the item.
873 /// One of OutputTextNode(), OutputGrfNode(), or OutputOLENode()
874 void OutputContentNode( SwContentNode
& );
876 /// Find the nearest bookmark from the current position.
878 /// Returns false when there is no bookmark.
879 bool NearestBookmark( sal_Int32
& rNearest
, const sal_Int32 nCurrentPos
, bool bNextPositionOnly
);
881 void GetSortedBookmarks( const SwTextNode
& rNd
, sal_Int32 nCurrentPos
, sal_Int32 nLen
);
883 bool GetBookmarks( const SwTextNode
& rNd
, sal_Int32 nStt
, sal_Int32 nEnd
,
886 /// Find the nearest annotation mark from the current position.
888 void NearestAnnotationMark( sal_Int32
& rNearest
, const sal_Int32 nCurrentPos
, bool bNextPositionOnly
);
890 void GetSortedAnnotationMarks( const SwWW8AttrIter
& rAttrs
, sal_Int32 nCurrentPos
, sal_Int32 nLen
);
892 bool GetAnnotationMarks( const SwWW8AttrIter
& rAttrs
, sal_Int32 nStt
, sal_Int32 nEnd
,
895 const NfKeywordTable
& GetNfKeywordTable();
897 void SetCurPam(sal_uLong nStt
, sal_uLong nEnd
);
899 /// Get background color of the document, if there is one.
900 std::unique_ptr
<SvxBrushItem
> getBackground();
901 /// Populates m_vecBulletPic with all the bullet graphics used by numberings.
902 int CollectGrfsOfBullets();
903 /// Write the numbering picture bullets.
904 void BulletDefinitions();
906 bool NeedSectionBreak( const SwNode
& rNd
) const;
907 bool NeedTextNodeSplit( const SwTextNode
& rNd
, SwSoftPageBreakList
& pList
) const;
909 std::vector
<const Graphic
*> m_vecBulletPic
; ///< Vector to record all the graphics of bullets
912 MSWordExportBase(SwDoc
& rDocument
, std::shared_ptr
<SwUnoCursor
> & pCurrentPam
, SwPaM
* pOriginalPam
);
913 virtual ~MSWordExportBase();
915 // TODO move as much as possible here from WW8Export! ;-)
917 static void CorrectTabStopInSet( SfxItemSet
& rSet
, sal_Int32 nAbsLeft
);
920 MSWordExportBase( const MSWordExportBase
& ) = delete;
921 MSWordExportBase
& operator=( const MSWordExportBase
& ) = delete;
924 /// The writer class that gets called for the WW8 filter.
925 class SwWW8Writer
: public StgWriter
927 // friends to get access to m_pExport
928 // FIXME avoid that, this is probably not what we want
929 // (if yes, remove the friends, and provide here a GetExport() method)
930 friend void WW8_WrtRedlineAuthor::Write(Writer
&rWrt
);
932 WW8Export
*m_pExport
;
936 SwWW8Writer(const OUString
& rFltName
, const OUString
& rBaseURL
);
937 virtual ~SwWW8Writer() override
;
939 virtual ErrCode
WriteStorage() override
;
940 virtual ErrCode
WriteMedium( SfxMedium
& ) override
;
942 // TODO most probably we want to be able to get these in
943 // MSExportFilterBase
944 using Writer::getIDocumentSettingAccess
;
947 static void InsUInt16(ww::bytes
&rO
, sal_uInt16 n
);
948 static void InsUInt32(ww::bytes
&rO
, sal_uInt32 n
);
949 static void InsAsString16(ww::bytes
&rO
, const OUString
& rStr
);
950 static void InsAsString8(ww::bytes
& O
, const OUString
& rStr
,
951 rtl_TextEncoding eCodeSet
);
953 static sal_uLong
FillUntil( SvStream
& rStrm
, sal_uLong nEndPos
= 0 );
954 static void FillCount( SvStream
& rStrm
, sal_uLong nCount
);
956 static void WriteShort( SvStream
& rStrm
, sal_Int16 nVal
) { rStrm
.WriteInt16( nVal
); }
957 static void WriteShort( SvStream
& rStrm
, sal_uLong nPos
, sal_Int16 nVal
);
959 static void WriteLong( SvStream
& rStrm
, sal_Int32 nVal
) { rStrm
.WriteInt32( nVal
); }
960 static void WriteLong( SvStream
& rStrm
, sal_uLong nPos
, sal_Int32 nVal
);
962 static void WriteString16(SvStream
& rStrm
, const OUString
& rStr
,
964 static void WriteString8(SvStream
& rStrm
, const OUString
& rStr
,
965 bool bAddZero
, rtl_TextEncoding eCodeSet
);
967 static void WriteString_xstz(SvStream
& rStrm
, const OUString
& rStr
, bool bAddZero
);
969 bool InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97
& rCodec
);
971 using StgWriter::Write
;
972 virtual ErrCode
Write( SwPaM
&, SfxMedium
&, const OUString
* ) override
;
973 //Seems not an expected to provide method to access the private member
974 SfxMedium
* GetMedia() { return mpMedium
; }
977 SwWW8Writer(const SwWW8Writer
&) = delete;
978 SwWW8Writer
& operator=(const SwWW8Writer
&) = delete;
979 ErrCode
WriteStorageImpl();
982 /// Exporter of the binary Word file formats.
983 class WW8Export
: public MSWordExportBase
986 std::unique_ptr
<ww::bytes
> pO
; ///< Buffer
988 SvStream
*pTableStrm
, *pDataStrm
; ///< Streams for WW97 Export
990 std::unique_ptr
<WW8Fib
> pFib
; ///< File Information Block
991 std::unique_ptr
<WW8Dop
> pDop
; ///< Document Properties
992 std::unique_ptr
<WW8_WrPlcFootnoteEdn
> pFootnote
; ///< Footnotes - structure to remember them, and output
993 std::unique_ptr
<WW8_WrPlcFootnoteEdn
> pEdn
; ///< Endnotes - structure to remember them, and output
994 std::unique_ptr
<WW8_WrPlcSepx
> pSepx
; ///< Sections/headers/footers
996 bool m_bDot
; ///< Template or document.
999 SwWW8Writer
*m_pWriter
; ///< Pointer to the writer
1000 std::unique_ptr
<WW8AttributeOutput
> m_pAttrOutput
; ///< Converting attributes to stream data
1003 tools::SvRef
<SotStorage
> xEscherStg
; /// memory leak #i120098#, to hold the reference to unnamed SotStorage obj
1006 /// Access to the attribute output class.
1007 virtual AttributeOutputBase
& AttrOutput() const override
;
1009 /// Access to the sections/headers/footres.
1010 virtual MSWordSections
& Sections() const override
;
1012 virtual bool PreferPageBreakBefore() const override
{ return true; }
1014 virtual bool FieldsQuoted() const override
{ return false; }
1016 virtual bool AddSectionBreaksForTOX() const override
{ return false; }
1018 /// Format-dependent part of the actual export.
1019 virtual ErrCode
ExportDocument_Impl() override
;
1021 void PrepareStorage();
1022 void WriteFkpPlcUsw();
1023 void WriteMainText();
1026 /// Output the numbering table.
1027 virtual void WriteNumbering() override
;
1029 void OutOverrideListTab();
1030 void OutListNamesTab();
1032 void RestoreMacroCmds();
1034 void DoComboBox(css::uno::Reference
<css::beans::XPropertySet
> const & xPropSet
);
1038 /// Setup the pA's info.
1039 virtual void SetupSectionPositions( WW8_PdAttrDesc
* pA
) override
;
1041 bool MiserableFormFieldExportHack(const SwFrameFormat
& rFrameFormat
);
1043 SwMSConvertControls
& GetOCXExp() { return *m_pOCXExp
; }
1044 void ExportDopTypography(WW8DopTypography
&rTypo
);
1046 sal_uInt16
AddRedlineAuthor( std::size_t nId
);
1048 void WriteFootnoteBegin( const SwFormatFootnote
& rFootnote
, ww::bytes
* pO
= nullptr );
1049 void WritePostItBegin( ww::bytes
* pO
= nullptr );
1050 const SvxBrushItem
* GetCurrentPageBgBrush() const;
1051 std::shared_ptr
<SvxBrushItem
> TrueFrameBgBrush(const SwFrameFormat
&rFlyFormat
) const;
1053 void AppendFlyInFlys(const ww8::Frame
& rFrameFormat
, const Point
& rNdTopLeft
);
1054 void WriteOutliner(const OutlinerParaObject
& rOutliner
, sal_uInt8 nTyp
);
1055 void WriteSdrTextObj(const SdrTextObj
& rObj
, sal_uInt8 nTyp
);
1057 sal_uInt32
GetSdrOrdNum( const SwFrameFormat
& rFormat
) const;
1058 void CreateEscher();
1062 virtual void OutputField( const SwField
* pField
, ww::eField eFieldType
,
1063 const OUString
& rFieldCmd
, FieldFlags nMode
= FieldFlags::All
) override
;
1065 void StartCommentOutput( const OUString
& rName
);
1066 void EndCommentOutput( const OUString
& rName
);
1067 void OutGrf(const ww8::Frame
&rFrame
);
1068 bool TestOleNeedsGraphic(const SwAttrSet
& rSet
, tools::SvRef
<SotStorage
> const& xOleStg
,
1069 const tools::SvRef
<SotStorage
>& xObjStg
, OUString
const& rStorageName
,
1072 virtual void AppendBookmarks( const SwTextNode
& rNd
, sal_Int32 nCurrentPos
, sal_Int32 nLen
) override
;
1073 virtual void AppendBookmark( const OUString
& rName
) override
;
1074 void AppendBookmarkEndWithCorrection( const OUString
& rName
);
1076 virtual void AppendAnnotationMarks( const SwWW8AttrIter
& rAttrs
, sal_Int32 nCurrentPos
, sal_Int32 nLen
) override
;
1078 virtual void AppendSmartTags(SwTextNode
& rTextNode
) override
;
1080 virtual void ExportGrfBullet(const SwTextNode
& rNd
) override
;
1081 void OutGrfBullets(const ww8::Frame
&rFrame
);
1083 void MoveFieldMarks(WW8_CP nFrom
, WW8_CP nTo
);
1085 void WriteAsStringTable(const std::vector
<OUString
>&, sal_Int32
& rfcSttbf
,
1086 sal_Int32
& rlcbSttbf
);
1088 virtual sal_uLong
ReplaceCr( sal_uInt8 nChar
) override
;
1090 virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner
= ww8::WW8TableNodeInfoInner::Pointer_t() ) override
;
1091 void WriteChar( sal_Unicode c
) override
;
1093 void OutSwString(const OUString
&, sal_Int32 nStt
, sal_Int32 nLen
);
1095 WW8_CP
Fc2Cp( sal_uLong nFc
) const { return m_pPiece
->Fc2Cp( nFc
); }
1097 // some partly static semi-internal function declarations
1099 void OutSprmBytes( sal_uInt8
* pBytes
, sal_uInt16 nSiz
)
1100 { pO
->insert( pO
->end(), pBytes
, pBytes
+nSiz
); }
1102 virtual void SectionBreaksAndFrames( const SwTextNode
& rNode
) override
;
1104 /// Helper method for OutputSectionBreaks() and OutputFollowPageDesc().
1106 virtual void PrepareNewPageDesc( const SfxItemSet
* pSet
,
1108 const SwFormatPageDesc
* pNewPgDescFormat
,
1109 const SwPageDesc
* pNewPgDesc
) override
;
1111 static void Out_BorderLine(ww::bytes
& rO
, const ::editeng::SvxBorderLine
* pLine
,
1112 sal_uInt16 nDist
, sal_uInt16 nSprmNo
, sal_uInt16 nSprmNoVer9
,
1115 void Out_SwFormatBox(const SvxBoxItem
& rBox
, bool bShadow
);
1116 static void Out_SwFormatTableBox( ww::bytes
& rO
, const SvxBoxItem
* rBox
);
1117 void Out_CellRangeBorders(const SvxBoxItem
* pBox
, sal_uInt8 nStart
,
1119 static bool TransBrush(const Color
& rCol
, WW8_SHD
& rShd
);
1120 static WW8_BRCVer9
TranslateBorderLine(const ::editeng::SvxBorderLine
& pLine
,
1121 sal_uInt16 nDist
, bool bShadow
);
1123 // #i77805# - new return value indicates, if an inherited outline numbering is suppressed
1124 virtual bool DisallowInheritingOutlineNumbering(const SwFormat
&rFormat
) override
;
1126 unsigned int GetHdFtIndex() const { return m_nHdFtIndex
; }
1127 void SetHdFtIndex(unsigned int nHdFtIndex
) { m_nHdFtIndex
= nHdFtIndex
; }
1128 void IncrementHdFtIndex() { ++m_nHdFtIndex
; }
1131 * Converts the SVX numbering type to MSONFC.
1133 * This is used for section, footnote and endnote numbering purposes.
1135 static sal_uInt8
GetNumId( sal_uInt16 eNumType
);
1137 /// Guess the script (asian/western).
1138 virtual bool CollapseScriptsforWordOk( sal_uInt16 nScript
, sal_uInt16 nWhich
) override
;
1140 SwTwips
CurrentPageWidth(SwTwips
&rLeft
, SwTwips
&rRight
) const;
1142 /// Nasty swap for bidi if necessary
1143 void MiserableRTLFrameFormatHack(SwTwips
&rLeft
, SwTwips
&rRight
,
1144 const ww8::Frame
&rFrameFormat
);
1146 void InsUInt16( sal_uInt16 n
) { SwWW8Writer::InsUInt16( *pO
, n
); }
1147 void InsInt16(sal_Int16 n
) { InsUInt16(sal_uInt16(n
)); }
1148 void InsUInt32( sal_uInt32 n
) { SwWW8Writer::InsUInt32( *pO
, n
); }
1149 void WriteStringAsPara( const OUString
& rText
);
1151 /// Setup the exporter.
1152 WW8Export( SwWW8Writer
*pWriter
,
1153 SwDoc
& rDocument
, std::shared_ptr
<SwUnoCursor
> & pCurrentPam
, SwPaM
* pOriginalPam
,
1155 virtual ~WW8Export() override
;
1157 virtual void DoComboBox(const OUString
&rName
,
1158 const OUString
&rHelp
,
1159 const OUString
&ToolTip
,
1160 const OUString
&rSelected
,
1161 const css::uno::Sequence
<OUString
> &rListItems
) override
;
1163 virtual void DoFormText(const SwInputField
* pField
) override
;
1165 void GetCurrentItems(ww::bytes
&rItems
) const;
1167 /// Write the data of the form field
1168 virtual void WriteFormData( const ::sw::mark::IFieldmark
& rFieldmark
) override
;
1169 virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark
& rFieldmark
) override
;
1172 WW8_WrPlcField
* CurrentFieldPlc() const;
1174 SwWW8Writer
& GetWriter() const { return *m_pWriter
; }
1175 SvStream
& Strm() const { return m_pWriter
->Strm(); }
1177 /// Remember some of the members so that we can recurse in WriteText().
1178 virtual void SaveData( sal_uLong nStt
, sal_uLong nEnd
) override
;
1180 /// Restore what was saved in SaveData().
1181 virtual void RestoreData() override
;
1183 /// Output the actual headers and footers.
1184 virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags
,
1185 const SwFrameFormat
& rFormat
, const SwFrameFormat
& rLeftFormat
, const SwFrameFormat
& rFirstPageFormat
,
1186 sal_uInt8 nBreakCode
) override
;
1188 virtual ExportFormat
GetExportFormat() const override
{ return ExportFormat::DOC
; }
1191 /// Output SwGrfNode
1192 virtual void OutputGrfNode( const SwGrfNode
& ) override
;
1194 /// Output SwOLENode
1195 virtual void OutputOLENode( const SwOLENode
& ) override
;
1197 virtual void OutputLinkedOLE( const OUString
& ) override
;
1199 virtual void AppendSection( const SwPageDesc
*pPageDesc
, const SwSectionFormat
* pFormat
, sal_uLong nLnNum
) override
;
1202 WW8Export(const WW8Export
&) = delete;
1203 WW8Export
& operator=(const WW8Export
&) = delete;
1206 class WW8_WrPlcSubDoc
// double Plc for Footnotes/Endnotes and Postits
1209 WW8_WrPlcSubDoc(const WW8_WrPlcSubDoc
&) = delete;
1210 WW8_WrPlcSubDoc
& operator=(const WW8_WrPlcSubDoc
&) = delete;
1212 std::vector
<WW8_CP
> aCps
;
1213 std::vector
<const void*> aContent
; // PTRARR of SwFormatFootnote/PostIts/..
1214 std::vector
<const SwFrameFormat
*> aSpareFormats
; // a backup for aContent: if there's no SdrObject, stores the fmt directly here
1215 std::unique_ptr
<WW8_WrPlc0
> pTextPos
; // positions of the individual texts
1218 virtual ~WW8_WrPlcSubDoc();
1220 bool WriteGenericText( WW8Export
& rWrt
, sal_uInt8 nTTyp
, WW8_CP
& rCount
);
1221 void WriteGenericPlc( WW8Export
& rWrt
, sal_uInt8 nTTyp
, WW8_FC
& rTextStt
,
1222 sal_Int32
& rTextCnt
, WW8_FC
& rRefStt
, sal_Int32
& rRefCnt
) const;
1224 virtual const std::vector
<sal_uInt32
>* GetShapeIdArr() const;
1227 // double Plc for Footnotes/Endnotes
1228 class WW8_WrPlcFootnoteEdn
: public WW8_WrPlcSubDoc
1233 WW8_WrPlcFootnoteEdn(const WW8_WrPlcFootnoteEdn
&) = delete;
1234 WW8_WrPlcFootnoteEdn
& operator=(WW8_WrPlcFootnoteEdn
const &) = delete;
1236 explicit WW8_WrPlcFootnoteEdn( sal_uInt8 nTTyp
) : nTyp( nTTyp
) {}
1238 bool WriteText( WW8Export
& rWrt
);
1239 void WritePlc( WW8Export
& rWrt
) const;
1241 void Append( WW8_CP nCp
, const SwFormatFootnote
& rFootnote
);
1244 struct WW8_Annotation
1246 const OutlinerParaObject
* mpRichText
;
1247 OUString msSimpleText
;
1249 OUString m_sInitials
;
1250 DateTime maDateTime
;
1251 WW8_CP m_nRangeStart
, m_nRangeEnd
;
1252 bool m_bIgnoreEmpty
= true;
1253 WW8_Annotation(const SwPostItField
* pPostIt
, WW8_CP nRangeStart
, WW8_CP nRangeEnd
);
1254 explicit WW8_Annotation(const SwRedlineData
* pRedline
);
1255 /// An annotation has a range if start != end or the m_bIgnoreEmpty flag is cleared.
1256 bool HasRange() const;
1259 class WW8_WrPlcAnnotations
: public WW8_WrPlcSubDoc
// double Plc for Postits
1262 WW8_WrPlcAnnotations(const WW8_WrPlcAnnotations
&) = delete;
1263 WW8_WrPlcAnnotations
& operator=(WW8_WrPlcAnnotations
const &) = delete;
1264 o3tl::sorted_vector
<const SwRedlineData
*> maProcessedRedlines
;
1266 std::map
<const OUString
, std::pair
<WW8_CP
, bool>> m_aRangeStartPositions
;
1268 WW8_WrPlcAnnotations() {}
1269 virtual ~WW8_WrPlcAnnotations() override
;
1271 void AddRangeStartPosition(const OUString
& rName
, WW8_CP nStartCp
, bool bIgnoreEmpty
);
1272 void Append( WW8_CP nCp
, const SwPostItField
* pPostIt
);
1273 void Append( WW8_CP nCp
, const SwRedlineData
* pRedLine
);
1274 bool IsNewRedlineComment( const SwRedlineData
* pRedLine
);
1275 bool WriteText( WW8Export
& rWrt
);
1276 void WritePlc( WW8Export
& rWrt
) const;
1279 class WW8_WrPlcTextBoxes
: public WW8_WrPlcSubDoc
// double Plc for Textboxes
1280 { // Frame/DrawTextboxes!
1283 std::vector
<sal_uInt32
> aShapeIds
; // VARARR of ShapeIds for the SwFrameFormats
1284 virtual const std::vector
<sal_uInt32
>* GetShapeIdArr() const override
;
1286 WW8_WrPlcTextBoxes(const WW8_WrPlcTextBoxes
&) = delete;
1287 WW8_WrPlcTextBoxes
& operator=(WW8_WrPlcTextBoxes
const &) = delete;
1289 explicit WW8_WrPlcTextBoxes( sal_uInt8 nTTyp
) : nTyp( nTTyp
) {}
1291 bool WriteText( WW8Export
& rWrt
);
1292 void WritePlc( WW8Export
& rWrt
) const;
1293 void Append( const SdrObject
& rObj
, sal_uInt32 nShapeId
);
1294 void Append( const SwFrameFormat
* pFormat
, sal_uInt32 nShapeId
);
1295 sal_uInt16
Count() const { return aContent
.size(); }
1296 sal_uInt16
GetPos( const void* p
) const
1298 std::vector
<const void*>::const_iterator it
1299 = std::find( aContent
.begin(), aContent
.end(), p
);
1300 return it
== aContent
.end() ? USHRT_MAX
: it
- aContent
.begin();
1304 class WW8_WrPlcPn
// Plc for Page Numbers
1308 // Plc for Chpx and Papx ( incl PN-Plc )
1309 std::vector
<std::unique_ptr
<WW8_WrFkp
>> m_Fkps
;
1310 sal_uInt16 nFkpStartPage
;
1313 WW8_WrPlcPn(const WW8_WrPlcPn
&) = delete;
1314 WW8_WrPlcPn
& operator=(const WW8_WrPlcPn
&) = delete;
1316 WW8_WrPlcPn( WW8Export
& rWrt
, ePLCFT ePl
, WW8_FC nStartFc
);
1318 void AppendFkpEntry(WW8_FC nEndFc
,short nVarLen
= 0,const sal_uInt8
* pSprms
= nullptr);
1321 sal_uInt8
*CopyLastSprms(sal_uInt8
&rLen
);
1324 // class WW8_WrPlc1 is only used for fields
1328 std::vector
<WW8_CP
> aPos
;
1329 std::unique_ptr
<sal_uInt8
[]> pData
; // content ( structures )
1331 sal_uInt16 nStructSiz
;
1333 WW8_WrPlc1(const WW8_WrPlc1
&) = delete;
1334 WW8_WrPlc1
& operator=(const WW8_WrPlc1
&) = delete;
1336 sal_uInt16
Count() const { return aPos
.size(); }
1337 void Write( SvStream
& rStrm
);
1338 WW8_CP
Prev() const;
1340 explicit WW8_WrPlc1( sal_uInt16 nStructSz
);
1342 void Append( WW8_CP nCp
, const void* pData
);
1343 void Finish( sal_uLong nLastCp
, sal_uLong nStartCp
);
1346 // class WW8_WrPlcField is for fields
1347 class WW8_WrPlcField
: public WW8_WrPlc1
1351 sal_uInt16 nResults
;
1353 WW8_WrPlcField(const WW8_WrPlcField
&) = delete;
1354 WW8_WrPlcField
& operator=(const WW8_WrPlcField
&) = delete;
1356 WW8_WrPlcField( sal_uInt16 nStructSz
, sal_uInt8 nTTyp
)
1357 : WW8_WrPlc1( nStructSz
), nTextTyp( nTTyp
), nResults(0)
1359 void Write( WW8Export
& rWrt
);
1360 void ResultAdded() { ++nResults
; }
1361 sal_uInt16
ResultCount() const { return nResults
; }
1364 class WW8_WrMagicTable
: public WW8_WrPlc1
1367 WW8_WrMagicTable(const WW8_WrMagicTable
&) = delete;
1368 WW8_WrMagicTable
& operator=(const WW8_WrMagicTable
&) = delete;
1370 WW8_WrMagicTable() : WW8_WrPlc1( 4 ) {Append(0,0);}
1371 void Append( WW8_CP nCp
, sal_uLong nData
);
1372 void Write( WW8Export
& rWrt
);
1375 class GraphicDetails
1378 ww8::Frame maFly
; // surrounding FlyFrames
1379 sal_uLong mnPos
; // FilePos of the graphics
1380 sal_uInt16 mnWid
; // Width of the graphics
1381 sal_uInt16 mnHei
; // Height of the graphics
1383 GraphicDetails(const ww8::Frame
&rFly
, sal_uInt16 nWid
, sal_uInt16 nHei
)
1384 : maFly(rFly
), mnPos(0), mnWid(nWid
), mnHei(nHei
)
1387 bool operator==(const GraphicDetails
& rIn
) const
1390 (mnWid
== rIn
.mnWid
) && (mnHei
== rIn
.mnHei
) &&
1391 (maFly
.RefersToSameFrameAs(rIn
.maFly
))
1396 // class SwWW8WrGrf collects graphics and issues them
1400 /// for access to the variables
1403 std::vector
<GraphicDetails
> maDetails
;
1404 sal_uInt16 mnIdx
; // index in file positions
1406 static void WritePICFHeader(SvStream
& rStrm
, const ww8::Frame
&rFly
,
1407 sal_uInt16 mm
, sal_uInt16 nWidth
, sal_uInt16 nHeight
,
1408 const SwAttrSet
* pAttrSet
= nullptr);
1409 void WriteGraphicNode(SvStream
& rStrm
, const GraphicDetails
&rItem
);
1410 void WriteGrfFromGrfNode(SvStream
& rStrm
, const SwGrfNode
&rNd
,
1411 const ww8::Frame
&rFly
, sal_uInt16 nWidth
, sal_uInt16 nHeight
);
1413 static void WritePICBulletFHeader(SvStream
& rStrm
, const Graphic
&rGrf
, sal_uInt16 mm
, sal_uInt16 nWidth
, sal_uInt16 nHeight
);
1414 void WriteGrfForBullet(SvStream
& rStrm
, const Graphic
&rGrf
, sal_uInt16 nWidth
, sal_uInt16 nHeight
);
1416 SwWW8WrGrf(const SwWW8WrGrf
&) = delete;
1417 SwWW8WrGrf
& operator=(const SwWW8WrGrf
&) = delete;
1419 explicit SwWW8WrGrf( WW8Export
& rW
) : rWrt( rW
), mnIdx( 0 ) {}
1420 void Insert(const ww8::Frame
&rFly
);
1423 { return (mnIdx
< maDetails
.size()) ? maDetails
[mnIdx
++].mnPos
: 0; }
1426 /** The class MSWordAttrIter is a helper class to build the Fkp.chpx.
1427 This is a base class to output the SwTextAttrs and the EditEngineTextAttrs.
1429 class MSWordAttrIter
1432 MSWordAttrIter
* pOld
;
1433 MSWordAttrIter(const MSWordAttrIter
&) = delete;
1434 MSWordAttrIter
& operator=(const MSWordAttrIter
&) = delete;
1436 MSWordExportBase
& m_rExport
;
1438 explicit MSWordAttrIter( MSWordExportBase
& rExport
);
1439 virtual ~MSWordAttrIter();
1441 virtual const SfxPoolItem
* HasTextItem( sal_uInt16 nWhich
) const = 0;
1442 virtual const SfxPoolItem
& GetItem( sal_uInt16 nWhich
) const = 0;
1445 /// Used to export formatted text associated to drawings.
1446 class MSWord_SdrAttrIter
: public MSWordAttrIter
1449 const EditTextObject
* pEditObj
;
1450 const SfxItemPool
* pEditPool
;
1451 std::vector
<EECharAttrib
> aTextAtrArr
;
1452 std::vector
<const EECharAttrib
*> aChrTextAtrArr
;
1453 std::vector
<rtl_TextEncoding
> aChrSetArr
;
1455 sal_Int32 nCurrentSwPos
;
1456 sal_Int32 nTmpSwPos
; // for HasItem()
1457 rtl_TextEncoding eNdChrSet
;
1461 sal_Int32
SearchNext( sal_Int32 nStartPos
);
1462 void SetCharSet(const EECharAttrib
& rTextAttr
, bool bStart
);
1464 void SetItemsThatDifferFromStandard(bool bCharAttr
, SfxItemSet
& rSet
);
1466 MSWord_SdrAttrIter(const MSWord_SdrAttrIter
&) = delete;
1467 MSWord_SdrAttrIter
& operator=(const MSWord_SdrAttrIter
&) = delete;
1469 MSWord_SdrAttrIter( MSWordExportBase
& rWr
, const EditTextObject
& rEditObj
,
1471 void NextPara( sal_Int32 nPar
);
1472 void OutParaAttr(bool bCharAttr
, const std::set
<sal_uInt16
>* pWhichsToIgnore
= nullptr);
1473 void OutEEField(const SfxPoolItem
& rHt
);
1475 bool IsTextAttr(sal_Int32 nSwPos
);
1477 void NextPos() { if ( nCurrentSwPos
< SAL_MAX_INT32
) nCurrentSwPos
= SearchNext( nCurrentSwPos
+ 1 ); }
1479 void OutAttr( sal_Int32 nSwPos
);
1480 virtual const SfxPoolItem
* HasTextItem( sal_uInt16 nWhich
) const override
;
1481 virtual const SfxPoolItem
& GetItem( sal_uInt16 nWhich
) const override
;
1482 sal_Int32
WhereNext() const { return nCurrentSwPos
; }
1483 rtl_TextEncoding
GetNextCharSet() const;
1484 rtl_TextEncoding
GetNodeCharSet() const { return eNdChrSet
; }
1487 // class SwWW8AttrIter is a helper for constructing the Fkp.chpx.
1488 // Only character attributes are considered; paragraph attributes do not need this treatment.
1489 // The paragraph and text attributes of the Writer are passed, and
1490 // Where() returns the next position where the attributes change.
1491 // IsTextAtr() tells if, at the position returned by Where(), there is
1492 // an attribute without end and with \xff in the text.
1493 // Using OutAttr(), the attributes on the passed SwPos are returned.
1494 class SwWW8AttrIter
: public MSWordAttrIter
1497 const SwTextNode
& rNd
;
1499 sw::util::CharRuns maCharRuns
;
1500 sw::util::CharRuns::const_iterator maCharRunIter
;
1502 rtl_TextEncoding meChrSet
;
1503 sal_uInt16 mnScript
;
1506 const SwRangeRedline
* pCurRedline
;
1507 sal_Int32 nCurrentSwPos
;
1508 SwRedlineTable::size_type nCurRedlinePos
;
1512 const SwFormatDrop
&mrSwFormatDrop
;
1514 ww8::Frames maFlyFrames
; // #i2916#
1515 ww8::FrameIter maFlyIter
;
1517 sal_Int32
SearchNext( sal_Int32 nStartPos
);
1519 void OutSwFormatRefMark(const SwFormatRefMark
& rAttr
);
1521 void IterToCurrent();
1523 SwWW8AttrIter(const SwWW8AttrIter
&) = delete;
1524 SwWW8AttrIter
& operator=(const SwWW8AttrIter
&) = delete;
1526 void handleToggleProperty(SfxItemSet
& rExportSet
, const SwFormatCharFormat
* pCharFormatItem
, sal_uInt16 nWhich
, const SfxPoolItem
* pValue
);
1528 SwWW8AttrIter( MSWordExportBase
& rWr
, const SwTextNode
& rNd
);
1530 bool IsTextAttr( sal_Int32 nSwPos
) const;
1531 bool IsExportableAttr(sal_Int32 nSwPos
) const;
1532 bool IncludeEndOfParaCRInRedlineProperties(sal_Int32 nPos
) const;
1533 bool IsDropCap( int nSwPos
);
1534 bool RequiresImplicitBookmark();
1536 void NextPos() { if ( nCurrentSwPos
< SAL_MAX_INT32
) nCurrentSwPos
= SearchNext( nCurrentSwPos
+ 1 ); }
1538 void OutAttr( sal_Int32 nSwPos
, bool bWriteCombinedChars
);
1539 virtual const SfxPoolItem
* HasTextItem( sal_uInt16 nWhich
) const override
;
1540 virtual const SfxPoolItem
& GetItem( sal_uInt16 nWhich
) const override
;
1541 int OutAttrWithRange(const SwTextNode
& rNode
, sal_Int32 nPos
);
1542 const SwRedlineData
* GetParagraphLevelRedline( );
1543 const SwRedlineData
* GetRunLevelRedline( sal_Int32 nPos
);
1544 FlyProcessingState
OutFlys(sal_Int32 nSwPos
);
1545 bool HasFlysAt(sal_Int32 nSwPos
) const;
1547 sal_Int32
WhereNext() const { return nCurrentSwPos
; }
1548 sal_uInt16
GetScript() const { return mnScript
; }
1549 bool IsParaRTL() const { return mbParaIsRTL
; }
1550 rtl_TextEncoding
GetCharSet() const { return meChrSet
; }
1551 OUString
GetSnippet(const OUString
&rStr
, sal_Int32 nCurrentPos
,
1552 sal_Int32 nLen
) const;
1553 const SwFormatDrop
& GetSwFormatDrop() const { return mrSwFormatDrop
; }
1555 bool IsWatermarkFrame();
1556 bool IsAnchorLinkedToThisNode( sal_uLong nNodePos
);
1558 void SplitRun( sal_Int32 nSplitEndPos
);
1560 const SwTextNode
& GetNode() const { return rNd
; }
1563 /// Class to collect and output the styles table.
1566 MSWordExportBase
& m_rExport
;
1567 sal_uInt16 m_aHeadingParagraphStyles
[MAXLEVEL
];
1568 std::unique_ptr
<SwFormat
*[]> m_pFormatA
; ///< Slot <-> Character and paragraph style array (0 for list styles).
1569 sal_uInt16 m_nUsedSlots
;
1570 bool m_bListStyles
; ///< If list styles are requested to be exported as well.
1571 std::map
<sal_uInt16
, const SwNumRule
*> m_aNumRules
; ///< Slot <-> List style map.
1573 /// We need to build style id's for DOCX export; ideally we should roundtrip that, but this is good enough.
1574 std::vector
<OString
> m_aStyleIds
;
1576 /// Create the style table, called from the constructor.
1577 void BuildStylesTable();
1579 /// Based on pFormatA, fill in m_aStyleIds with unique, MS-like names.
1580 void BuildStyleIds();
1582 /// Get slot number during building the style table.
1583 sal_uInt16
BuildGetSlot( const SwFormat
& rFormat
);
1584 sal_uInt16
BuildGetSlot( const SwNumRule
& /*rNumRule*/ ) { return m_nUsedSlots
++;}
1586 /// Return information about one style.
1587 void GetStyleData( SwFormat
* pFormat
, bool& bFormatColl
, sal_uInt16
& nBase
, sal_uInt16
& nNext
);
1589 /// Outputs attributes of one style.
1590 void WriteProperties( const SwFormat
* pFormat
, bool bPap
, sal_uInt16 nPos
, bool bInsDefCharSiz
);
1592 static sal_uInt16
GetWWId( const SwFormat
& rFormat
);
1594 void SetStyleDefaults( const SwFormat
& rFormat
, bool bPap
);
1596 /// Outputs one style - called (in a loop) from OutputStylesTable().
1597 void OutputStyle( SwFormat
* pFormat
, sal_uInt16 nPos
);
1598 void OutputStyle( const SwNumRule
* pNumRule
, sal_uInt16 nPos
);
1600 MSWordStyles( const MSWordStyles
& ) = delete;
1601 MSWordStyles
& operator=( const MSWordStyles
& ) = delete;
1604 MSWordStyles( MSWordExportBase
& rExport
, bool bListStyles
= false );
1607 /// Output the styles table.
1608 void OutputStylesTable();
1610 /// Get id of the style (rFormat).
1611 sal_uInt16
GetSlot( const SwFormat
* pFormat
) const;
1613 /// create style id using only ASCII characters of the style name
1614 static OString
CreateStyleId(const OUString
&rName
);
1616 /// Get styleId of the nId-th style (nId is its position in pFormatA).
1617 OString
const & GetStyleId(sal_uInt16 nId
) const;
1619 const SwFormat
* GetSwFormat(sal_uInt16 nId
) const { return m_pFormatA
[nId
]; }
1620 /// Get numbering rule of the nId-th style
1621 const SwNumRule
* GetSwNumRule(sal_uInt16 nId
) const;
1622 sal_uInt16
GetHeadingParagraphStyleId(sal_uInt16 nLevel
) const { return m_aHeadingParagraphStyles
[ nLevel
]; }
1625 #define MSWORD_MAX_STYLES_LIMIT 4091
1627 sal_Int16
GetWordFirstLineOffset(const SwNumFormat
&rFormat
);
1628 // A bit of a bag on the side for now
1629 OUString
FieldString(ww::eField eIndex
);
1630 OUString
BookmarkToWord(const OUString
&rBookmark
);
1634 sal_uInt32 m_cvFore
;
1635 sal_uInt32 m_cvBack
;
1638 WW8SHDLong() : m_cvFore(0), m_cvBack(0) {}
1640 void Write(WW8Export
& rExport
);
1641 void setCvFore(sal_uInt32 cvFore
) { m_cvFore
= cvFore
; }
1642 void setCvBack(sal_uInt32 cvBack
) { m_cvBack
= cvBack
; }
1645 #endif // INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX
1647 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */