build fix
[LibreOffice.git] / sw / source / filter / ww8 / wrtww8.hxx
blobb1d173b78c1da2cd17d66589fdb456c06745469e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
29 #include <wrt_fn.hxx>
31 #include "ww8struc.hxx"
32 #include "ww8scan.hxx"
33 #include "fields.hxx"
34 #include "types.hxx"
35 #include "writerhelper.hxx"
36 #include "../inc/msfilter.hxx"
37 #include <expfld.hxx>
38 #include "WW8TableInfo.hxx"
40 #include <vcl/graph.hxx>
42 #include <boost/optional.hpp>
44 #include <memory>
45 #include <map>
46 #include <vector>
49 class SvxBrushItem;
51 // some forward declarations
52 class SwWW8AttrIter;
53 namespace msfilter
55 class MSCodec_Std97;
58 namespace editeng { class SvxBorderLine; }
60 class AttributeOutputBase;
61 class DocxAttributeOutput;
62 class RtfAttributeOutput;
63 class BitmapPalette;
64 class SwEscherEx;
65 class DateTime;
66 namespace vcl { class Font; }
67 class MSWordExportBase;
68 class SdrObject;
69 class SdrTextObj;
70 class SfxItemSet;
71 class SvStream;
72 class SvxFontItem;
73 class SvxBoxItem;
74 class SwAttrSet;
75 class SwCharFormat;
76 class SwContentNode;
77 class SwField;
78 class SwFormat;
79 class SwFormatContent;
80 class SwFormatFootnote;
81 class SwFrameFormat;
82 class SwGrfNode;
83 class SwModify;
84 class SwNumFormat;
85 class SwNumRule;
86 class SwNumRuleTable;
87 class SwPageDesc;
88 class SwFormatPageDesc;
89 class SwOLENode;
90 class SwPostItField;
91 class SwRedlineData;
92 class SwSectionFormat;
93 class SwSectionNode;
94 class SwTableNode;
95 class SwTOXType;
96 class SwTextFormatColl;
97 class SwTextNode;
98 class SwWW8WrGrf;
99 class SwWW8Writer;
100 class MSWordStyles;
101 class WW8AttributeOutput;
102 class WW8Export;
103 class MSWordAttrIter;
104 class WW8_WrFkp;
105 class WW8_WrPlc0;
106 class WW8_WrPlc1;
107 class WW8_WrPlcField;
108 class WW8_WrMagicTable;
109 class WW8_WrPlcFootnoteEdn;
110 class WW8_WrPlcPn;
111 class WW8_WrPlcAnnotations;
112 class WW8_WrtFactoids;
113 class MSWordSections;
114 class WW8_WrPlcTextBoxes;
115 class WW8_WrPct; // administration
116 class WW8_WrtBookmarks;
117 class WW8_WrtRedlineAuthor;
118 class SvxMSExportOLEObjects;
119 class SwMSConvertControls;
120 class WW8_WrPc;
122 namespace com { namespace sun { namespace star { namespace embed {
123 class XEmbeddedObject;
124 } } } }
125 typedef std::map<const css::embed::XEmbeddedObject*, sal_Int32> WW8OleMap;
126 struct WW8_PdAttrDesc;
127 class SvxBrushItem;
129 #define GRF_MAGIC_1 0x12 // 3 magic bytes for PicLocFc attribute
130 #define GRF_MAGIC_2 0x34
131 #define GRF_MAGIC_3 0x56
132 #define GRF_MAGIC_321 0x563412L
134 #define OLE_PREVIEW_AS_EMF //If we want to export ole2 previews as emf in ww8+
136 typedef sal_uInt8 FieldFlags;
137 namespace nsFieldFlags // for InsertField- Method
139 const FieldFlags WRITEFIELD_START = 0x01;
140 const FieldFlags WRITEFIELD_CMD_START = 0x02;
141 const FieldFlags WRITEFIELD_CMD_END = 0x04;
142 const FieldFlags WRITEFIELD_END = 0x10;
143 const FieldFlags WRITEFIELD_CLOSE = 0x20;
144 const FieldFlags WRITEFIELD_ALL = 0xFF;
147 enum TextTypes //enums for TextTypes
149 TXT_MAINTEXT = 0, /*TXT_FTNEDN = 1,*/ TXT_HDFT = 2, TXT_FTN = 3,
150 TXT_EDN = 4, TXT_ATN = 5, TXT_TXTBOX = 6, TXT_HFTXTBOX= 7
154 enum to state the present state of the fly
156 enum FlyProcessingState
158 FLY_PROCESSED,
159 FLY_POSTPONED,
160 FLY_NOT_PROCESSED
163 struct WW8_SepInfo
165 const SwPageDesc* pPageDesc;
166 const SwSectionFormat* pSectionFormat;
167 const SwNode* pPDNd;
168 sal_uLong nLnNumRestartNo;
169 ::boost::optional<sal_uInt16> oPgRestartNo;
170 bool bIsFirstParagraph;
172 WW8_SepInfo( const SwPageDesc* pPD, const SwSectionFormat* pFormat,
173 sal_uLong nLnRestart, ::boost::optional<sal_uInt16> oPgRestart = boost::none,
174 const SwNode* pNd = nullptr, bool bIsFirstPara = false )
175 : pPageDesc( pPD ), pSectionFormat( pFormat ), pPDNd( pNd ),
176 nLnNumRestartNo( nLnRestart ), oPgRestartNo( oPgRestart ),
177 bIsFirstParagraph( bIsFirstPara )
180 bool IsProtected() const;
183 /// Class to collect and output the sections/headers/footers.
184 // Plc fuer PageDescs -> Sepx ( Section Extensions )
185 class MSWordSections
187 protected:
188 bool mbDocumentIsProtected;
189 std::vector<WW8_SepInfo> aSects;
191 void CheckForFacinPg( WW8Export& rWrt ) const;
192 void NeedsDocumentProtected(const WW8_SepInfo &rInfo);
194 //No copy, no assign
195 MSWordSections( const MSWordSections& );
196 MSWordSections& operator=( const MSWordSections& );
197 public:
198 explicit MSWordSections( MSWordExportBase& rExport );
199 virtual ~MSWordSections();
201 virtual bool HeaderFooterWritten();
203 void AppendSection( const SwPageDesc* pPd,
204 const SwSectionFormat* pSectionFormat,
205 sal_uLong nLnNumRestartNo,
206 bool bIsFirstParagraph = false );
207 void AppendSection( const SwFormatPageDesc& rPd,
208 const SwNode& rNd,
209 const SwSectionFormat* pSectionFormat,
210 sal_uLong nLnNumRestartNo );
212 /// Number of columns based on the most recent WW8_SepInfo.
213 sal_uInt16 CurrentNumberOfColumns( const SwDoc &rDoc ) const;
215 /// Number of columns of the provided WW8_SepInfo.
216 static sal_uInt16 NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo );
218 bool DocumentIsProtected() const { return mbDocumentIsProtected; }
220 /// The most recent WW8_SepInfo.
221 const WW8_SepInfo* CurrentSectionInfo();
223 static void SetHeaderFlag( sal_uInt8& rHeadFootFlags, const SwFormat& rFormat,
224 sal_uInt8 nFlag );
225 static void SetFooterFlag( sal_uInt8& rHeadFootFlags, const SwFormat& rFormat,
226 sal_uInt8 nFlag );
228 /// Should we output borders?
229 static bool HasBorderItem( const SwFormat& rFormat );
232 class WW8_WrPlcSepx : public MSWordSections
234 std::vector<WW8_CP> aCps;
235 std::vector< std::shared_ptr<WW8_PdAttrDesc> > m_SectionAttributes;
236 // hack to prevent adding sections in endnotes
237 bool m_bHeaderFooterWritten;
238 WW8_WrPlc0* pTextPos; // Position of the headers/footers
240 WW8_WrPlcSepx( const WW8_WrPlcSepx& ) = delete;
241 WW8_WrPlcSepx& operator=( const WW8_WrPlcSepx& ) = delete;
243 public:
244 explicit WW8_WrPlcSepx( MSWordExportBase& rExport );
245 virtual ~WW8_WrPlcSepx() override;
247 virtual bool HeaderFooterWritten() override; // override
249 void AppendSep( WW8_CP nStartCp,
250 const SwPageDesc* pPd,
251 const SwSectionFormat* pSectionFormat,
252 sal_uLong nLnNumRestartNo );
253 void AppendSep( WW8_CP nStartCp, const SwFormatPageDesc& rPd,
254 const SwNode& rNd,
255 const SwSectionFormat* pSectionFormat,
256 sal_uLong nLnNumRestartNo );
257 void Finish( WW8_CP nEndCp ) { aCps.push_back( nEndCp ); }
259 bool WriteKFText( WW8Export& rWrt );
260 void WriteSepx( SvStream& rStrm ) const;
261 void WritePlcSed( WW8Export& rWrt ) const;
262 void WritePlcHdd( WW8Export& rWrt ) const;
264 private:
265 void WriteFootnoteEndText( WW8Export& rWrt, sal_uLong nCpStt );
266 public:
267 void OutHeaderFooter(WW8Export& rWrt, bool bHeader,
268 const SwFormat& rFormat, sal_uLong& rCpPos, sal_uInt8 nHFFlags, sal_uInt8 nFlag, sal_uInt8 nBreakCode);
271 // class WW8_WrPct to construct the piece table
272 class WW8_WrPct
274 std::vector<std::unique_ptr<WW8_WrPc>> m_Pcts;
275 WW8_FC nOldFc;
276 public:
277 explicit WW8_WrPct(WW8_FC nStartFc);
278 ~WW8_WrPct();
279 void AppendPc(WW8_FC nStartFc);
280 void WritePc( WW8Export& rWrt );
281 void SetParaBreak();
282 WW8_CP Fc2Cp( sal_uLong nFc ) const;
285 /// Collects and outputs fonts.
286 class wwFont
288 //In some future land the stream could be converted to a nice stream interface
289 //and we could have harmony
290 private:
291 sal_uInt8 maWW8_FFN[6];
292 OUString msFamilyNm;
293 OUString msAltNm;
294 bool mbAlt;
295 FontPitch mePitch;
296 FontFamily meFamily;
297 rtl_TextEncoding meChrSet;
298 public:
299 wwFont( const OUString &rFamilyName, FontPitch ePitch, FontFamily eFamily,
300 rtl_TextEncoding eChrSet);
301 void Write( SvStream *pTableStram ) const;
302 void WriteDocx( DocxAttributeOutput* rAttrOutput ) const;
303 void WriteRtf( const RtfAttributeOutput* rAttrOutput ) const;
304 OUString GetFamilyName() const { return OUString( msFamilyNm ); }
305 friend bool operator < (const wwFont &r1, const wwFont &r2);
308 class wwFontHelper
310 private:
311 /// Keep track of fonts that need to be exported.
312 std::map<wwFont, sal_uInt16> maFonts;
314 /// Convert from fast insertion map to linear vector in the order that we want to write.
315 std::vector< const wwFont* > AsVector() const;
317 public:
318 wwFontHelper() : bLoadAllFonts(false) {}
319 /// rDoc used only to get the initial standard font(s) in use.
320 void InitFontTable(const SwDoc& rDoc);
321 sal_uInt16 GetId(const SvxFontItem& rFont);
322 sal_uInt16 GetId(const wwFont& rFont);
323 void WriteFontTable( SvStream *pTableStream, WW8Fib& pFib );
324 void WriteFontTable( DocxAttributeOutput& rAttrOutput );
325 void WriteFontTable( const RtfAttributeOutput& rAttrOutput );
327 /// If true, all fonts are loaded before processing the document.
328 bool bLoadAllFonts: 1;
331 class DrawObj
333 public:
334 WW8_CP mnCp; // CP-Pos of references
335 sal_uInt32 mnShapeId; // ShapeId for the SwFrameFormats
336 ww8::Frame maContent; // the frame itself
337 Point maParentPos; // Points
338 sal_Int32 mnThick; // Border Thicknesses
339 short mnDirection; // If BiDi or not
340 unsigned int mnHdFtIndex; // 0 for main text, +1 for each subsequent
341 // msword hd/ft
343 DrawObj(const ww8::Frame &rContent, WW8_CP nCp, Point aParentPos, short nDir,
344 unsigned int nHdFtIndex)
345 : mnCp(nCp), mnShapeId(0), maContent(rContent), maParentPos(aParentPos),
346 mnThick(0), mnDirection(nDir), mnHdFtIndex(nHdFtIndex) {}
347 void SetShapeDetails(sal_uInt32 nId, sal_Int32 nThick);
348 DrawObj& operator=(const DrawObj &rOther);
351 typedef std::vector<DrawObj> DrawObjVector;
352 typedef DrawObjVector::const_iterator cDrawObjIter;
354 typedef std::vector<DrawObj *> DrawObjPointerVector;
355 typedef DrawObjPointerVector::iterator DrawObjPointerIter;
357 class PlcDrawObj // PC for DrawObjects and Text-/OLE-/GRF-Boxes
359 private:
360 DrawObjVector maDrawObjs; // vector of drawobjs
361 protected:
362 virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart,
363 sal_uInt32 nLen) const = 0;
364 virtual WW8_CP GetCpOffset(const WW8Fib &rFib) const = 0;
365 public:
366 PlcDrawObj() {}
367 void WritePlc( WW8Export& rWrt ) const;
368 bool Append( WW8Export&, WW8_CP nCp, const ww8::Frame& rFormat,
369 const Point& rNdTopLeft );
370 int size() { return maDrawObjs.size(); };
371 DrawObjVector &GetObjArr() { return maDrawObjs; }
372 virtual ~PlcDrawObj();
373 private:
374 PlcDrawObj(const PlcDrawObj&) = delete;
375 PlcDrawObj& operator=(const PlcDrawObj&) = delete;
378 class MainTextPlcDrawObj : public PlcDrawObj
380 public:
381 MainTextPlcDrawObj() {}
382 private:
383 virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart,
384 sal_uInt32 nLen) const override;
385 virtual WW8_CP GetCpOffset(const WW8Fib &) const override;
386 private:
387 MainTextPlcDrawObj(const MainTextPlcDrawObj&) = delete;
388 MainTextPlcDrawObj& operator=(const MainTextPlcDrawObj&) = delete;
391 class HdFtPlcDrawObj : public PlcDrawObj
393 public:
394 HdFtPlcDrawObj() {}
395 private:
396 virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart,
397 sal_uInt32 nLen) const override;
398 virtual WW8_CP GetCpOffset(const WW8Fib &rFib) const override;
399 private:
400 HdFtPlcDrawObj(const HdFtPlcDrawObj&) = delete;
401 HdFtPlcDrawObj& operator=(const HdFtPlcDrawObj&) = delete;
404 typedef std::pair<OUString, sal_uLong> aBookmarkPair;
406 class WW8_WrtRedlineAuthor : public sw::util::WrtRedlineAuthor
408 public:
409 virtual void Write(Writer &rWrt) override;
412 /** Structure that is used to save some of the WW8Export/DocxExport data.
414 It is used to be able to recurse inside of the WW8Export/DocxExport (eg.
415 for the needs of the tables) - you need to tall WriteText() from there with
416 new values of PaM etc.
418 It must contain all the stuff that might be saved either in WW8Export or in
419 DocxExport, because it makes no sense to do it abstract, and specialize it
420 for each of the cases. If you implement other *Export, just add the needed
421 members here, and store them in the appropriate SaveData() method.
423 struct MSWordSaveData
425 Point* pOldFlyOffset;
426 RndStdIds eOldAnchorType;
427 ww::bytes* pOOld; ///< WW8Export only
428 SwPaM* pOldPam, *pOldEnd;
429 sal_uLong nOldStart, nOldEnd;
430 const ww8::Frame* pOldFlyFormat;
431 const SwPageDesc* pOldPageDesc;
433 bool bOldWriteAll : 1; ///< WW8Export only
434 bool bOldOutTable : 1;
435 bool bOldFlyFrameAttrs : 1;
436 bool bOldStartTOX : 1;
437 bool bOldInWriteTOX : 1;
438 // m_bOutPageDescs does not have to be saved in MSWordExportBase::SaveData
439 // since it is only modified when outputting special texts.
442 /// Base class for WW8Export and DocxExport
443 class MSWordExportBase
445 public:
446 wwFontHelper m_aFontHelper;
447 std::vector<sal_uLong> m_aChapterFieldLocs;
448 typedef std::vector<sal_uLong>::const_iterator mycCFIter;
449 OUString m_aMainStg;
450 std::vector<const SwTOXType*> m_aTOXArr;
451 const SfxItemSet* m_pISet; // for double attributes
452 WW8_WrPct* m_pPiece; // Pointer auf Piece-Table
453 SwNumRuleTable* m_pUsedNumTable; // all used NumRules
454 const SwTextNode *m_pTopNodeOfHdFtPage; ///< Top node of host page when in hd/ft
455 std::map< sal_uInt16, sal_uInt16 > m_aRuleDuplicates; //map to Duplicated numrules
456 std::stack< sal_Int32 > m_aCurrentCharPropStarts; ///< To remember the position in a run.
457 WW8_WrtBookmarks* m_pBkmks;
458 WW8_WrtRedlineAuthor* m_pRedlAuthors;
459 std::shared_ptr<NfKeywordTable> m_pKeyMap;
460 SvxMSExportOLEObjects* m_pOLEExp;
461 SwMSConvertControls* m_pOCXExp;
462 WW8OleMap m_aOleMap; // To remember all already exported ole objects
463 ww8::WW8TableInfo::Pointer_t m_pTableInfo;
465 sal_uInt16 m_nCharFormatStart;
466 sal_uInt16 m_nFormatCollStart;
467 sal_uInt16 m_nStyleBeforeFly; ///< style number of the node
468 ///< to which the Fly is connected
469 sal_uInt16 m_nLastFormatId; ///< Style of last TextNode in normal range
470 sal_uInt16 m_nUniqueList; ///< current number for creating unique list names
471 unsigned int m_nHdFtIndex;
473 RedlineFlags m_nOrigRedlineFlags; ///< Remember the original redline mode
475 public:
476 /* implicit bookmark vector containing pairs of node indexes and bookmark names */
477 std::vector<aBookmarkPair> m_aImplicitBookmarks;
478 ww8::Frames m_aFrames; // The floating frames in this document
479 const SwPageDesc *m_pAktPageDesc;
480 bool m_bPrevTextNodeIsEmpty;
481 WW8_WrPlcPn* m_pPapPlc;
482 WW8_WrPlcPn* m_pChpPlc;
483 MSWordAttrIter* m_pChpIter;
484 MSWordStyles* m_pStyles;
485 WW8_WrPlcAnnotations* m_pAtn;
486 std::unique_ptr<WW8_WrtFactoids> m_pFactoids;
487 WW8_WrPlcTextBoxes *m_pTextBxs, *m_pHFTextBxs;
489 struct LinkedTextboxInfo //help analyze textbox flow links
491 sal_Int32 nId;
492 sal_Int32 nSeq;
493 OUString sNextChain;
494 OUString sPrevChain;
495 LinkedTextboxInfo(): nId(0), nSeq(0) {}
497 std::map<OUString,LinkedTextboxInfo> m_aLinkedTextboxesHelper;
498 bool m_bLinkedTextboxesHelperInitialized = false;
499 sal_Int32 m_nLinkedTextboxesChainId=0;
501 const ww8::Frame *m_pParentFrame; // If set we are exporting content inside
502 // a frame, e.g. a graphic node
504 Point* m_pFlyOffset; // for adjusting of character-bound Fly in the Writer,
505 RndStdIds m_eNewAnchorType; // that is paragraph-bound in the WW.
507 WW8_WrPlcField* m_pFieldMain; // fields in MainText
508 WW8_WrPlcField* m_pFieldHdFt; // fields in Header/Footer
509 WW8_WrPlcField* m_pFieldFootnote; // fields in FootNotes
510 WW8_WrPlcField* m_pFieldEdn; // fields in EndNotes
511 WW8_WrPlcField* m_pFieldAtn; // fields in Annotations
512 WW8_WrPlcField* m_pFieldTextBxs; // fields in textboxes
513 WW8_WrPlcField* m_pFieldHFTextBxs; // fields in header/footer textboxes
514 WW8_WrMagicTable *m_pMagicTable; // keeps track of table cell positions, and
515 // marks those that contain graphics,
516 // which is required to make word display
517 // graphics inside tables
518 SwWW8WrGrf* m_pGrf;
519 const SwAttrSet* m_pStyAttr; // StyleAttr for Tabs
520 const SwModify* m_pOutFormatNode; // write Format or Node
521 const SwFormat *m_pCurrentStyle; // iff bStyDef=true, then this store the current style
523 MainTextPlcDrawObj *m_pSdrObjs; // Draw-/Fly-Objects
524 HdFtPlcDrawObj *m_pHFSdrObjs; // Draw-/Fly-Objects in header or footer
526 SwEscherEx* m_pEscher; // escher export class
527 // #i43447# - removed
528 // SwTwips nFlyWidth, nFlyHeight; // for adaptation of graphics
530 sal_uInt8 m_nTextTyp;
532 bool m_bStyDef : 1; // should Style be written?
533 bool m_bBreakBefore : 1; // Breaks are being written 2 times
534 bool m_bOutKF : 1; // Header/Footer texts are being written
535 bool m_bOutFlyFrameAttrs : 1; // Frame-attr of Flys are being written
536 bool m_bOutPageDescs : 1; ///< PageDescs (section properties) are being written
537 bool m_bOutFirstPage : 1; // write Attrset of FirstPageDesc
538 bool m_bOutTable : 1; // table is being written
539 // ( is reset e.g. for Flys in a table )
540 bool m_bOutGrf : 1; // graphics are being written
541 bool m_bInWriteEscher : 1; // in write textboxes
542 bool m_bStartTOX : 1; // true: a TOX is startet
543 bool m_bInWriteTOX : 1; // true: all content are in a TOX
544 bool m_bFootnoteAtTextEnd : 1; // true: all FTN at Textend
545 bool m_bEndAtTextEnd : 1; // true: all END at Textend
546 bool m_bHasHdr : 1;
547 bool m_bHasFtr : 1;
548 bool m_bSubstituteBullets : 1; // true: SubstituteBullet() gets called
549 bool m_bTabInTOC : 1; //true for TOC field flag 'w'
551 bool m_bHideTabLeaderAndPageNumbers : 1 ; // true: the 'z' field of TOC is set.
552 bool m_bExportModeRTF;
553 /// Is font size written already as part of the current character properties?
554 bool m_bFontSizeWritten;
556 SwDoc *m_pDoc;
557 sal_uLong m_nCurStart, m_nCurEnd;
558 SwPaM *m_pCurPam, *m_pOrigPam;
560 /// Stack to remember the nesting (see MSWordSaveData for more)
561 std::stack< MSWordSaveData > m_aSaveData;
563 /// Used to split the runs according to the bookmarks start and ends
564 typedef std::vector< ::sw::mark::IMark* > IMarkVector;
565 IMarkVector m_rSortedBookmarksStart;
566 IMarkVector m_rSortedBookmarksEnd;
567 IMarkVector m_rSortedAnnotationMarksStart;
568 IMarkVector m_rSortedAnnotationMarksEnd;
570 public:
571 /// The main function to export the document.
572 void ExportDocument( bool bWriteAll );
574 /// Iterate through the nodes and call the appropriate OutputNode() on them.
575 void WriteText();
577 /// Return whether currently exported node is in table.
578 bool IsInTable() const;
580 /// Set the pCurPam appropriately and call WriteText().
582 /// Used to export paragraphs in footnotes/endnotes/etc.
583 void WriteSpecialText( sal_uLong nStart, sal_uLong nEnd, sal_uInt8 nTTyp );
585 /// Export the pool items to attributes (through an attribute output class).
586 void ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16 nScript );
588 /// Return the numeric id of the numbering rule
589 sal_uInt16 GetId( const SwNumRule& rNumRule );
591 /// Return the numeric id of the style.
592 sal_uInt16 GetId( const SwTextFormatColl& rColl ) const;
594 /// Return the numeric id of the style.
595 sal_uInt16 GetId( const SwCharFormat* pFormat ) const;
597 sal_uInt16 GetId( const SwTOXType& rTOXType );
599 /// Return the numeric id of the font (and add it to the font list if needed)
600 sal_uInt16 GetId( const SvxFontItem& rFont)
602 return m_aFontHelper.GetId(rFont);
604 /// @overload
605 void GetId( const wwFont& rFont)
607 m_aFontHelper.GetId(rFont);
610 const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const;
612 /// Find the reference.
613 bool HasRefToObject( sal_uInt16 nTyp, const OUString* pName, sal_uInt16 nSeqNo );
615 /// Find the bookmark name.
616 static OUString GetBookmarkName( sal_uInt16 nTyp, const OUString* pName, sal_uInt16 nSeqNo );
618 /// Use OutputItem() on an item set according to the parameters.
619 void OutputItemSet( const SfxItemSet& rSet, bool bPapFormat, bool bChpFormat, sal_uInt16 nScript, bool bExportParentItemSet );
621 short GetDefaultFrameDirection( ) const;
623 /// Right to left?
624 short TrueFrameDirection( const SwFrameFormat& rFlyFormat ) const;
626 /// Right to left?
627 short GetCurrentPageDirection() const;
629 /// In case of numbering restart.
631 /// List is set to restart at a particular value so for export make a
632 /// completely new list based on this one and export that instead,
633 /// which duplicates words behaviour in this respect.
634 sal_uInt16 DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal );
636 /// Access to the attribute output class.
637 virtual AttributeOutputBase& AttrOutput() const = 0;
639 /// Access to the sections/headers/footres.
640 virtual MSWordSections& Sections() const = 0;
642 /// Determines if column break with one column should be exported or not.
643 virtual bool SupportsOneColumnBreak() const = 0;
645 /// Determines if the import filter already quoted fields or not.
646 virtual bool FieldsQuoted() const = 0;
648 /// Determines the Section Breaks are to be added for TOX Section
649 virtual bool AddSectionBreaksForTOX() const = 0;
651 /// Used to filter out attributes that can be e.g. written to .doc but not to .docx
652 virtual bool ignoreAttributeForStyleDefaults( sal_uInt16 /*nWhich*/ ) const { return false; }
654 /// If saving page break is preferred as a paragraph attribute (yes) or as a special character (no).
655 virtual bool PreferPageBreakBefore() const = 0;
657 /// Text in tables can be postponed except for .doc
658 virtual bool AllowPostponedTextInTable() const { return true; }
660 /// Guess the script (asian/western).
662 /// Sadly word does not have two different sizes for asian font size and
663 /// western font size, it has two different fonts, but not sizes, so we
664 /// have to use our guess as to the script used and disable the export of
665 /// one type. The same occurs for font weight and posture (bold and
666 /// italic).
668 /// In addition WW7- has only one character language identifier while WW8+
669 /// has two
670 virtual bool CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich ) = 0;
672 virtual void AppendBookmarks( const SwTextNode& rNd, sal_Int32 nAktPos, sal_Int32 nLen ) = 0;
674 virtual void AppendBookmark( const OUString& rName ) = 0;
676 virtual void AppendAnnotationMarks( const SwTextNode& rNd, sal_Int32 nAktPos, sal_Int32 nLen ) = 0;
678 virtual void AppendSmartTags(const SwTextNode& /*rTextNode*/) { }
680 //For i120928,add this interface to export graphic of bullet
681 virtual void ExportGrfBullet(const SwTextNode& rNd) = 0;
683 // FIXME probably a hack...
684 virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() ) = 0;
686 // FIXME definitely a hack, must not be here - it can't do anything
687 // sensible for docx
688 virtual void WriteChar( sal_Unicode c ) = 0;
690 /// Output attributes.
691 void OutputFormat( const SwFormat& rFormat, bool bPapFormat, bool bChpFormat, bool bFlyFormat = false );
693 /// Getter for pISet.
694 const SfxItemSet* GetCurItemSet() const { return m_pISet; }
696 /// Setter for pISet.
697 void SetCurItemSet( const SfxItemSet* pS ) { m_pISet = pS; }
699 /// Remember some of the memebers so that we can recurse in WriteText().
700 virtual void SaveData( sal_uLong nStt, sal_uLong nEnd );
702 /// Restore what was saved in SaveData().
703 virtual void RestoreData();
705 /// The return value indicates, if a follow page desc is written.
706 bool OutputFollowPageDesc( const SfxItemSet* pSet,
707 const SwTextNode* pNd );
709 /// Write header/footer text.
710 void WriteHeaderFooterText( const SwFormat& rFormat, bool bHeader);
712 /// Format of the section.
713 static const SwSectionFormat* GetSectionFormat( const SwNode& rNd );
715 /// Line number of the section start.
716 static sal_uLong GetSectionLineNo( const SfxItemSet* pSet, const SwNode& rNd );
718 /// Start new section.
719 void OutputSectionBreaks( const SfxItemSet *pSet, const SwNode& rNd, bool isCellOpen = false, bool isTextNodeEmpty = false);
721 /// Write section properties.
723 /// pA is ignored for docx.
724 void SectionProperties( const WW8_SepInfo& rSectionInfo, WW8_PdAttrDesc* pA = nullptr );
726 /// Output the numbering table.
727 virtual void WriteNumbering() = 0;
729 /// Write static data of SwNumRule - LSTF
730 void NumberingDefinitions();
732 /// Write all Levels for all SwNumRules - LVLF
733 void AbstractNumberingDefinitions();
735 // Convert the bullet according to the font.
736 void SubstituteBullet( OUString& rNumStr, rtl_TextEncoding& rChrSet,
737 OUString& rFontName ) const;
739 /// Setup the pA's info.
740 virtual void SetupSectionPositions( WW8_PdAttrDesc* /*pA*/ ) {}
742 /// Top node of host page when in header/footer.
743 void SetHdFtPageRoot( const SwTextNode *pNd ) { m_pTopNodeOfHdFtPage = pNd; }
745 /// Top node of host page when in header/footer.
746 const SwTextNode *GetHdFtPageRoot() const { return m_pTopNodeOfHdFtPage; }
748 /// Output the actual headers and footers.
749 virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
750 const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const SwFrameFormat& rFirstPageFormat,
751 sal_uInt8 nBreakCode) = 0;
753 /// Write the field
754 virtual void OutputField( const SwField* pField, ww::eField eFieldType,
755 const OUString& rFieldCmd, sal_uInt8 nMode = nsFieldFlags::WRITEFIELD_ALL ) = 0;
757 /// Write the data of the form field
758 virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) = 0;
759 virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark& rFieldmark ) = 0;
761 virtual void DoComboBox(const OUString &rName,
762 const OUString &rHelp,
763 const OUString &ToolTip,
764 const OUString &rSelected,
765 css::uno::Sequence<OUString> &rListItems) = 0;
767 virtual void DoFormText(const SwInputField * pField) = 0;
769 static bool NoPageBreakSection( const SfxItemSet *pSet );
771 // Compute the number format for WW dates
772 bool GetNumberFormat(const SwField& rField, OUString& rStr);
774 virtual sal_uLong ReplaceCr( sal_uInt8 nChar ) = 0;
776 const SfxPoolItem* HasItem( sal_uInt16 nWhich ) const;
778 /// Returns the index of a picture bullet, used in numberings.
779 int GetGrfIndex(const SvxBrushItem& rBrush);
781 protected:
782 /// Format-dependent part of the actual export.
783 virtual void ExportDocument_Impl() = 0;
785 /// Get the next position in the text node to output
786 sal_Int32 GetNextPos( SwWW8AttrIter* pAttrIter, const SwTextNode& rNode, sal_Int32 nAktPos );
788 /// Update the information for GetNextPos().
789 void UpdatePosition( SwWW8AttrIter* pAttrIter, sal_Int32 nAktPos, sal_Int32 nEnd );
791 /// Output SwTextNode
792 virtual void OutputTextNode( const SwTextNode& );
794 /// Setup the chapter fields (maChapterFieldLocs).
795 void GatherChapterFields();
797 void AddLinkTarget( const OUString& rURL );
798 void CollectOutlineBookmarks( const SwDoc &rDoc );
800 bool SetAktPageDescFromNode(const SwNode &rNd);
801 bool ContentContainsChapterField(const SwFormatContent &rContent) const;
802 bool FormatHdFtContainsChapterField(const SwFrameFormat &rFormat) const;
804 virtual void SectionBreaksAndFrames( const SwTextNode& rNode ) = 0;
806 virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
807 const SwNode& rNd,
808 const SwFormatPageDesc* pNewPgDescFormat,
809 const SwPageDesc* pNewPgDesc ) = 0;
811 /// Return value indicates if an inherited outline numbering is suppressed.
812 virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) = 0;
814 /// Output SwStartNode
815 void OutputStartNode( const SwStartNode& );
817 /// Output SwEndNode
818 virtual void OutputEndNode( const SwEndNode& );
820 /// Output SwGrfNode
821 virtual void OutputGrfNode( const SwGrfNode& ) = 0;
823 /// Output SwOLENode
824 virtual void OutputOLENode( const SwOLENode& ) = 0;
826 virtual void OutputLinkedOLE( const OUString& ) = 0;
828 /// Output SwSectionNode
829 void OutputSectionNode( const SwSectionNode& );
831 virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum ) = 0;
833 /// Call the right (virtual) function according to the type of the item.
835 /// One of OutputTextNode(), OutputGrfNode(), or OutputOLENode()
836 void OutputContentNode( const SwContentNode& );
838 /// Find the nearest bookmark from the current position.
840 /// Returns false when there is no bookmark.
841 bool NearestBookmark( sal_Int32& rNearest, const sal_Int32 nAktPos, bool bNextPositionOnly );
843 void GetSortedBookmarks( const SwTextNode& rNd, sal_Int32 nAktPos, sal_Int32 nLen );
845 bool GetBookmarks( const SwTextNode& rNd, sal_Int32 nStt, sal_Int32 nEnd,
846 IMarkVector& rArr );
848 /// Find the nearest annotation mark from the current position.
850 void NearestAnnotationMark( sal_Int32& rNearest, const sal_Int32 nAktPos, bool bNextPositionOnly );
852 void GetSortedAnnotationMarks( const SwTextNode& rNd, sal_Int32 nAktPos, sal_Int32 nLen );
854 bool GetAnnotationMarks( const SwTextNode& rNd, sal_Int32 nStt, sal_Int32 nEnd,
855 IMarkVector& rArr );
857 const NfKeywordTable & GetNfKeywordTable();
859 void SetCurPam(sal_uLong nStt, sal_uLong nEnd);
861 /// Get background color of the document, if there is one.
862 boost::optional<SvxBrushItem> getBackground();
863 /// Populates m_vecBulletPic with all the bullet graphics used by numberings.
864 int CollectGrfsOfBullets();
865 /// Write the numbering picture bullets.
866 void BulletDefinitions();
867 std::vector<const Graphic*> m_vecBulletPic; ///< Vector to record all the graphics of bullets
869 public:
870 MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam );
871 virtual ~MSWordExportBase();
873 // TODO move as much as possible here from WW8Export! ;-)
875 static void CorrectTabStopInSet( SfxItemSet& rSet, sal_uInt16 nAbsLeft );
877 private:
878 MSWordExportBase( const MSWordExportBase& ) = delete;
879 MSWordExportBase& operator=( const MSWordExportBase& ) = delete;
882 /// The writer class that gets called for the WW8 filter.
883 class SwWW8Writer: public StgWriter
885 // friends to get access to m_pExport
886 // FIXME avoid that, this is probably not what we want
887 // (if yes, remove the friends, and provide here a GetExport() method)
888 friend void WW8_WrtRedlineAuthor::Write(Writer &rWrt);
890 WW8Export *m_pExport;
891 SfxMedium *mpMedium;
893 public:
894 SwWW8Writer(const OUString& rFltName, const OUString& rBaseURL);
895 virtual ~SwWW8Writer() override;
897 virtual sal_uLong WriteStorage() override;
898 virtual sal_uLong WriteMedium( SfxMedium& ) override;
900 // TODO most probably we want to be able to get these in
901 // MSExportFilterBase
902 using Writer::getIDocumentSettingAccess;
904 public:
905 static void InsUInt16(ww::bytes &rO, sal_uInt16 n);
906 static void InsUInt32(ww::bytes &rO, sal_uInt32 n);
907 static void InsAsString16(ww::bytes &rO, const OUString& rStr);
908 static void InsAsString8(ww::bytes & O, const OUString& rStr,
909 rtl_TextEncoding eCodeSet);
911 static sal_uLong FillUntil( SvStream& rStrm, sal_uLong nEndPos = 0 );
912 static void FillCount( SvStream& rStrm, sal_uLong nCount );
914 static void WriteShort( SvStream& rStrm, sal_Int16 nVal ) { rStrm.WriteInt16( nVal ); }
915 static void WriteShort( SvStream& rStrm, sal_uLong nPos, sal_Int16 nVal );
917 static void WriteLong( SvStream& rStrm, sal_Int32 nVal ) { rStrm.WriteInt32( nVal ); }
918 static void WriteLong( SvStream& rStrm, sal_uLong nPos, sal_Int32 nVal );
920 static void WriteString16(SvStream& rStrm, const OUString& rStr,
921 bool bAddZero);
922 static void WriteString8(SvStream& rStrm, const OUString& rStr,
923 bool bAddZero, rtl_TextEncoding eCodeSet);
925 static void WriteString_xstz(SvStream& rStrm, const OUString& rStr, bool bAddZero);
927 bool InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec );
929 using StgWriter::Write;
930 virtual sal_uLong Write( SwPaM&, SfxMedium&, const OUString* ) override;
931 //Seems not an expected to provide method to access the private member
932 SfxMedium* GetMedia() { return mpMedium; }
934 private:
935 SwWW8Writer(const SwWW8Writer&) = delete;
936 SwWW8Writer& operator=(const SwWW8Writer&) = delete;
939 /// Exporter of the binary Word file formats.
940 class WW8Export : public MSWordExportBase
942 public:
943 ww::bytes* pO; ///< Buffer
945 SvStream *pTableStrm, *pDataStrm; ///< Streams for WW97 Export
947 WW8Fib* pFib; ///< File Information Block
948 WW8Dop* pDop; ///< DOcument Properties
949 WW8_WrPlcFootnoteEdn *pFootnote; ///< Footnotes - structure to remember them, and output
950 WW8_WrPlcFootnoteEdn *pEdn; ///< Endnotes - structure to remember them, and output
951 WW8_WrPlcSepx* pSepx; ///< Sections/headers/footers
953 bool m_bDot; ///< Template or document.
955 protected:
956 SwWW8Writer *m_pWriter; ///< Pointer to the writer
957 WW8AttributeOutput *m_pAttrOutput; ///< Converting attributes to stream data
959 private:
960 tools::SvRef<SotStorage> xEscherStg; /// memory leak #i120098#, to hold the reference to unnamed SotStorage obj
962 public:
963 /// Access to the attribute output class.
964 virtual AttributeOutputBase& AttrOutput() const override;
966 /// Access to the sections/headers/footres.
967 virtual MSWordSections& Sections() const override;
969 virtual bool PreferPageBreakBefore() const override { return true; }
971 virtual bool AllowPostponedTextInTable() const override { return false; }
973 virtual bool SupportsOneColumnBreak() const override { return false; }
975 virtual bool FieldsQuoted() const override { return false; }
977 virtual bool AddSectionBreaksForTOX() const override { return false; }
978 private:
979 /// Format-dependent part of the actual export.
980 virtual void ExportDocument_Impl() override;
982 void PrepareStorage();
983 void WriteFkpPlcUsw();
984 void WriteMainText();
985 void StoreDoc1();
987 /// Output the numbering table.
988 virtual void WriteNumbering() override;
990 void OutOverrideListTab();
991 void OutListNamesTab();
993 void RestoreMacroCmds();
995 void DoComboBox(css::uno::Reference<css::beans::XPropertySet> const & xPropSet);
997 public:
999 /// Setup the pA's info.
1000 virtual void SetupSectionPositions( WW8_PdAttrDesc* pA ) override;
1002 bool MiserableFormFieldExportHack(const SwFrameFormat& rFrameFormat);
1004 SvxMSExportOLEObjects& GetOLEExp() { return *m_pOLEExp; }
1005 SwMSConvertControls& GetOCXExp() { return *m_pOCXExp; }
1006 void ExportDopTypography(WW8DopTypography &rTypo);
1008 sal_uInt16 AddRedlineAuthor( sal_uInt16 nId );
1010 void WriteFootnoteBegin( const SwFormatFootnote& rFootnote, ww::bytes* pO = nullptr );
1011 void WritePostItBegin( ww::bytes* pO = nullptr );
1012 const SvxBrushItem* GetCurrentPageBgBrush() const;
1013 SvxBrushItem TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const;
1015 void AppendFlyInFlys(const ww8::Frame& rFrameFormat, const Point& rNdTopLeft);
1016 void WriteOutliner(const OutlinerParaObject& rOutliner, sal_uInt8 nTyp);
1017 void WriteSdrTextObj(const SdrTextObj& rObj, sal_uInt8 nTyp);
1019 sal_uInt32 GetSdrOrdNum( const SwFrameFormat& rFormat ) const;
1020 void CreateEscher();
1021 void WriteEscher();
1023 /// Write the field
1024 virtual void OutputField( const SwField* pField, ww::eField eFieldType,
1025 const OUString& rFieldCmd, sal_uInt8 nMode = nsFieldFlags::WRITEFIELD_ALL ) override;
1027 void StartCommentOutput( const OUString& rName );
1028 void EndCommentOutput( const OUString& rName );
1029 void OutGrf(const ww8::Frame &rFrame);
1030 bool TestOleNeedsGraphic(const SwAttrSet& rSet, tools::SvRef<SotStorage> const & xOleStg,
1031 tools::SvRef<SotStorage> xObjStg, OUString &rStorageName, SwOLENode *pOLENd);
1033 virtual void AppendBookmarks( const SwTextNode& rNd, sal_Int32 nAktPos, sal_Int32 nLen ) override;
1034 virtual void AppendBookmark( const OUString& rName ) override;
1036 virtual void AppendAnnotationMarks( const SwTextNode& rNd, sal_Int32 nAktPos, sal_Int32 nLen ) override;
1038 virtual void AppendSmartTags(const SwTextNode& rTextNode) override;
1040 virtual void ExportGrfBullet(const SwTextNode& rNd) override;
1041 void OutGrfBullets(const ww8::Frame &rFrame);
1043 void MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo);
1045 void WriteAsStringTable(const std::vector<OUString>&, sal_Int32& rfcSttbf,
1046 sal_Int32& rlcbSttbf);
1048 virtual sal_uLong ReplaceCr( sal_uInt8 nChar ) override;
1050 virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() ) override;
1051 void WriteChar( sal_Unicode c ) override;
1053 void OutSwString(const OUString&, sal_Int32 nStt, sal_Int32 nLen);
1055 WW8_CP Fc2Cp( sal_uLong nFc ) const { return m_pPiece->Fc2Cp( nFc ); }
1057 // some partly static semi-internal function declarations
1059 void OutSprmBytes( sal_uInt8* pBytes, sal_uInt16 nSiz )
1060 { pO->insert( pO->end(), pBytes, pBytes+nSiz ); }
1062 virtual void SectionBreaksAndFrames( const SwTextNode& rNode ) override;
1064 /// Helper method for OutputSectionBreaks() and OutputFollowPageDesc().
1065 // #i76300#
1066 virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
1067 const SwNode& rNd,
1068 const SwFormatPageDesc* pNewPgDescFormat,
1069 const SwPageDesc* pNewPgDesc ) override;
1071 static void Out_BorderLine(ww::bytes& rO, const ::editeng::SvxBorderLine* pLine,
1072 sal_uInt16 nDist, sal_uInt16 nSprmNo, sal_uInt16 nSprmNoVer9,
1073 bool bShadow);
1075 void Out_SwFormatBox(const SvxBoxItem& rBox, bool bShadow);
1076 static void Out_SwFormatTableBox( ww::bytes& rO, const SvxBoxItem * rBox );
1077 void Out_CellRangeBorders(const SvxBoxItem * pBox, sal_uInt8 nStart,
1078 sal_uInt8 nLimit);
1079 static bool TransBrush(const Color& rCol, WW8_SHD& rShd);
1080 static WW8_BRCVer9 TranslateBorderLine(const ::editeng::SvxBorderLine& pLine,
1081 sal_uInt16 nDist, bool bShadow);
1083 // #i77805# - new return value indicates, if an inherited outline numbering is suppressed
1084 virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) override;
1086 unsigned int GetHdFtIndex() const { return m_nHdFtIndex; }
1087 void SetHdFtIndex(unsigned int nHdFtIndex) { m_nHdFtIndex = nHdFtIndex; }
1088 void IncrementHdFtIndex() { ++m_nHdFtIndex; }
1090 /// Convert the SVX numbering type to id
1091 static sal_uInt8 GetNumId( sal_uInt16 eNumType );
1093 /// Guess the script (asian/western).
1094 virtual bool CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich ) override;
1096 SwTwips CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const;
1098 /// Nasty swap for bidi if necessary
1099 void MiserableRTLFrameFormatHack(SwTwips &rLeft, SwTwips &rRight,
1100 const ww8::Frame &rFrameFormat);
1102 void InsUInt16( sal_uInt16 n ) { SwWW8Writer::InsUInt16( *pO, n ); }
1103 void InsUInt32( sal_uInt32 n ) { SwWW8Writer::InsUInt32( *pO, n ); }
1104 void WriteStringAsPara( const OUString& rText );
1106 /// Setup the exporter.
1107 WW8Export( SwWW8Writer *pWriter,
1108 SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam,
1109 bool bDot );
1110 virtual ~WW8Export() override;
1112 virtual void DoComboBox(const OUString &rName,
1113 const OUString &rHelp,
1114 const OUString &ToolTip,
1115 const OUString &rSelected,
1116 css::uno::Sequence<OUString> &rListItems) override;
1118 virtual void DoFormText(const SwInputField * pField) override;
1120 void GetCurrentItems(ww::bytes &rItems) const;
1122 /// Write the data of the form field
1123 virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) override;
1124 virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark& rFieldmark ) override;
1126 /// Fields.
1127 WW8_WrPlcField* CurrentFieldPlc() const;
1129 SwWW8Writer& GetWriter() const { return *m_pWriter; }
1130 SvStream& Strm() const { return m_pWriter->Strm(); }
1132 /// Remember some of the memebers so that we can recurse in WriteText().
1133 virtual void SaveData( sal_uLong nStt, sal_uLong nEnd ) override;
1135 /// Restore what was saved in SaveData().
1136 virtual void RestoreData() override;
1138 /// Output the actual headers and footers.
1139 virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
1140 const SwFrameFormat& rFormat, const SwFrameFormat& rLeftFormat, const SwFrameFormat& rFirstPageFormat,
1141 sal_uInt8 nBreakCode) override;
1143 protected:
1144 /// Output SwGrfNode
1145 virtual void OutputGrfNode( const SwGrfNode& ) override;
1147 /// Output SwOLENode
1148 virtual void OutputOLENode( const SwOLENode& ) override;
1150 virtual void OutputLinkedOLE( const OUString& ) override;
1152 virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum ) override;
1154 private:
1155 WW8Export(const WW8Export&) = delete;
1156 WW8Export& operator=(const WW8Export&) = delete;
1159 class WW8_WrPlcSubDoc // double Plc for Footnotes/Endnotes and Postits
1161 private:
1162 WW8_WrPlcSubDoc(const WW8_WrPlcSubDoc&) = delete;
1163 WW8_WrPlcSubDoc& operator=(const WW8_WrPlcSubDoc&) = delete;
1164 protected:
1165 std::vector<WW8_CP> aCps;
1166 std::vector<const void*> aContent; // PTRARR of SwFormatFootnote/PostIts/..
1167 std::vector<const SwFrameFormat*> aSpareFormats; // a backup for aContent: if there's no SdrObject, stores the fmt directly here
1168 std::unique_ptr<WW8_WrPlc0> pTextPos; // positions of the individual texts
1170 WW8_WrPlcSubDoc();
1171 virtual ~WW8_WrPlcSubDoc();
1173 bool WriteGenericText( WW8Export& rWrt, sal_uInt8 nTTyp, WW8_CP& rCount );
1174 void WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp, WW8_FC& rTextStt,
1175 sal_Int32& rTextCnt, WW8_FC& rRefStt, sal_Int32& rRefCnt ) const;
1177 virtual const std::vector<sal_uInt32>* GetShapeIdArr() const;
1180 // double Plc for Footnotes/Endnotes
1181 class WW8_WrPlcFootnoteEdn : public WW8_WrPlcSubDoc
1183 private:
1184 sal_uInt8 nTyp;
1186 WW8_WrPlcFootnoteEdn(const WW8_WrPlcFootnoteEdn&) = delete;
1187 WW8_WrPlcFootnoteEdn& operator=(WW8_WrPlcFootnoteEdn &) = delete;
1188 public:
1189 explicit WW8_WrPlcFootnoteEdn( sal_uInt8 nTTyp ) : nTyp( nTTyp ) {}
1191 bool WriteText( WW8Export& rWrt );
1192 void WritePlc( WW8Export& rWrt ) const;
1194 void Append( WW8_CP nCp, const SwFormatFootnote& rFootnote );
1197 struct WW8_Annotation
1199 const OutlinerParaObject* mpRichText;
1200 OUString msSimpleText;
1201 OUString msOwner;
1202 OUString m_sInitials;
1203 DateTime maDateTime;
1204 WW8_CP m_nRangeStart, m_nRangeEnd;
1205 WW8_Annotation(const SwPostItField* pPostIt, WW8_CP nRangeStart, WW8_CP nRangeEnd);
1206 explicit WW8_Annotation(const SwRedlineData* pRedline);
1209 class WW8_WrPlcAnnotations : public WW8_WrPlcSubDoc // double Plc for Postits
1211 private:
1212 WW8_WrPlcAnnotations(const WW8_WrPlcAnnotations&) = delete;
1213 WW8_WrPlcAnnotations& operator=(WW8_WrPlcAnnotations&) = delete;
1214 std::set<const SwRedlineData*> maProcessedRedlines;
1216 std::map<const OUString, WW8_CP> m_aRangeStartPositions;
1217 public:
1218 WW8_WrPlcAnnotations() {}
1219 virtual ~WW8_WrPlcAnnotations() override;
1221 void AddRangeStartPosition(const OUString& rName, WW8_CP nStartCp);
1222 void Append( WW8_CP nCp, const SwPostItField* pPostIt );
1223 void Append( WW8_CP nCp, const SwRedlineData* pRedLine );
1224 bool IsNewRedlineComment( const SwRedlineData* pRedLine );
1225 bool WriteText( WW8Export& rWrt );
1226 void WritePlc( WW8Export& rWrt ) const;
1229 class WW8_WrPlcTextBoxes : public WW8_WrPlcSubDoc // double Plc for Textboxes
1230 { // Frame/DrawTextboxes!
1231 private:
1232 sal_uInt8 nTyp;
1233 std::vector<sal_uInt32> aShapeIds; // VARARR of ShapeIds for the SwFrameFormats
1234 virtual const std::vector<sal_uInt32>* GetShapeIdArr() const override;
1236 WW8_WrPlcTextBoxes(const WW8_WrPlcTextBoxes&) = delete;
1237 WW8_WrPlcTextBoxes& operator=(WW8_WrPlcTextBoxes&) = delete;
1238 public:
1239 explicit WW8_WrPlcTextBoxes( sal_uInt8 nTTyp ) : nTyp( nTTyp ) {}
1241 bool WriteText( WW8Export& rWrt );
1242 void WritePlc( WW8Export& rWrt ) const;
1243 void Append( const SdrObject& rObj, sal_uInt32 nShapeId );
1244 void Append( const SwFrameFormat* pFormat, sal_uInt32 nShapeId );
1245 sal_uInt16 Count() const { return aContent.size(); }
1246 sal_uInt16 GetPos( const void* p ) const
1248 std::vector<const void*>::const_iterator it
1249 = std::find( aContent.begin(), aContent.end(), p );
1250 return it == aContent.end() ? USHRT_MAX : it - aContent.begin();
1254 class WW8_WrPlcPn // Plc for Page Numbers
1256 private:
1257 WW8Export& rWrt;
1258 // Plc for Chpx and Papx ( incl PN-Plc )
1259 std::vector<std::unique_ptr<WW8_WrFkp>> m_Fkps;
1260 sal_uInt16 nFkpStartPage;
1261 ePLCFT ePlc;
1263 WW8_WrPlcPn(const WW8_WrPlcPn&) = delete;
1264 WW8_WrPlcPn& operator=(const WW8_WrPlcPn&) = delete;
1265 public:
1266 WW8_WrPlcPn( WW8Export& rWrt, ePLCFT ePl, WW8_FC nStartFc );
1267 ~WW8_WrPlcPn();
1268 void AppendFkpEntry(WW8_FC nEndFc,short nVarLen = 0,const sal_uInt8* pSprms = nullptr);
1269 void WriteFkps();
1270 void WritePlc();
1271 sal_uInt8 *CopyLastSprms(sal_uInt8 &rLen);
1274 // class WW8_WrPlc1 is only used for fields
1275 class WW8_WrPlc1
1277 private:
1278 std::vector<WW8_CP> aPos;
1279 std::unique_ptr<sal_uInt8[]> pData; // content ( structures )
1280 sal_uLong nDataLen;
1281 sal_uInt16 nStructSiz;
1283 WW8_WrPlc1(const WW8_WrPlc1&) = delete;
1284 WW8_WrPlc1& operator=(const WW8_WrPlc1&) = delete;
1285 protected:
1286 sal_uInt16 Count() const { return aPos.size(); }
1287 void Write( SvStream& rStrm );
1288 WW8_CP Prev() const;
1289 public:
1290 explicit WW8_WrPlc1( sal_uInt16 nStructSz );
1291 ~WW8_WrPlc1();
1292 void Append( WW8_CP nCp, const void* pData );
1293 void Finish( sal_uLong nLastCp, sal_uLong nStartCp );
1296 // class WW8_WrPlcField is for fields
1297 class WW8_WrPlcField : public WW8_WrPlc1
1299 private:
1300 sal_uInt8 nTextTyp;
1301 sal_uInt16 nResults;
1303 WW8_WrPlcField(const WW8_WrPlcField&) = delete;
1304 WW8_WrPlcField& operator=(const WW8_WrPlcField&) = delete;
1305 public:
1306 WW8_WrPlcField( sal_uInt16 nStructSz, sal_uInt8 nTTyp )
1307 : WW8_WrPlc1( nStructSz ), nTextTyp( nTTyp ), nResults(0)
1309 void Write( WW8Export& rWrt );
1310 void ResultAdded() { ++nResults; }
1311 sal_uInt16 ResultCount() const { return nResults; }
1314 class WW8_WrMagicTable : public WW8_WrPlc1
1316 private:
1317 WW8_WrMagicTable(const WW8_WrMagicTable&) = delete;
1318 WW8_WrMagicTable& operator=(const WW8_WrMagicTable&) = delete;
1319 public:
1320 WW8_WrMagicTable() : WW8_WrPlc1( 4 ) {Append(0,0);}
1321 void Append( WW8_CP nCp, sal_uLong nData );
1322 void Write( WW8Export& rWrt );
1325 class GraphicDetails
1327 public:
1328 ww8::Frame maFly; // surrounding FlyFrames
1329 sal_uLong mnPos; // FilePos of the graphics
1330 sal_uInt16 mnWid; // Width of the graphics
1331 sal_uInt16 mnHei; // Height of the graphics
1333 GraphicDetails(const ww8::Frame &rFly, sal_uInt16 nWid, sal_uInt16 nHei)
1334 : maFly(rFly), mnPos(0), mnWid(nWid), mnHei(nHei)
1336 GraphicDetails& operator=(const GraphicDetails& rOther);
1338 bool operator==(const GraphicDetails& rIn) const
1340 return (
1341 (mnWid == rIn.mnWid) && (mnHei == rIn.mnHei) &&
1342 (maFly.RefersToSameFrameAs(rIn.maFly))
1347 // class SwWW8WrGrf collects graphics and issues them
1348 class SwWW8WrGrf
1350 private:
1351 /// for access to the variables
1352 WW8Export& rWrt;
1354 std::vector<GraphicDetails> maDetails;
1355 typedef std::vector<GraphicDetails>::iterator myiter;
1356 sal_uInt16 mnIdx; // index in file positions
1358 static void WritePICFHeader(SvStream& rStrm, const ww8::Frame &rFly,
1359 sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight,
1360 const SwAttrSet* pAttrSet = nullptr);
1361 void WriteGraphicNode(SvStream& rStrm, const GraphicDetails &rItem);
1362 void WriteGrfFromGrfNode(SvStream& rStrm, const SwGrfNode &rNd,
1363 const ww8::Frame &rFly, sal_uInt16 nWidth, sal_uInt16 nHeight);
1365 static void WritePICBulletFHeader(SvStream& rStrm, const Graphic &rGrf, sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight);
1366 void WriteGrfForBullet(SvStream& rStrm, const Graphic &rGrf, sal_uInt16 nWidth, sal_uInt16 nHeight);
1368 SwWW8WrGrf(const SwWW8WrGrf&) = delete;
1369 SwWW8WrGrf& operator=(const SwWW8WrGrf&) = delete;
1370 public:
1371 explicit SwWW8WrGrf( WW8Export& rW ) : rWrt( rW ), mnIdx( 0 ) {}
1372 void Insert(const ww8::Frame &rFly);
1373 void Write();
1374 sal_uLong GetFPos()
1375 { return (mnIdx < maDetails.size()) ? maDetails[mnIdx++].mnPos : 0; }
1378 /** The class MSWordAttrIter is a helper class to build the Fkp.chpx.
1379 This is a base class to output the SwTextAttrs and the EditEngineTextAttrs.
1381 class MSWordAttrIter
1383 private:
1384 MSWordAttrIter* pOld;
1385 MSWordAttrIter(const MSWordAttrIter&) = delete;
1386 MSWordAttrIter& operator=(const MSWordAttrIter&) = delete;
1387 protected:
1388 MSWordExportBase& m_rExport;
1389 public:
1390 explicit MSWordAttrIter( MSWordExportBase& rExport );
1391 virtual ~MSWordAttrIter();
1393 virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const = 0;
1394 virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const = 0;
1397 /// Used to export formatted text associated to drawings.
1398 class MSWord_SdrAttrIter : public MSWordAttrIter
1400 private:
1401 const EditTextObject* pEditObj;
1402 const SfxItemPool* pEditPool;
1403 std::vector<EECharAttrib> aTextAtrArr;
1404 std::vector<const EECharAttrib*> aChrTextAtrArr;
1405 std::vector<rtl_TextEncoding> aChrSetArr;
1406 sal_Int32 nPara;
1407 sal_Int32 nAktSwPos;
1408 sal_Int32 nTmpSwPos; // for HasItem()
1409 rtl_TextEncoding eNdChrSet;
1410 sal_uInt16 nScript;
1411 sal_uInt8 mnTyp;
1413 sal_Int32 SearchNext( sal_Int32 nStartPos );
1414 void SetCharSet(const EECharAttrib& rTextAttr, bool bStart);
1416 void SetItemsThatDifferFromStandard(bool bCharAttr, SfxItemSet& rSet);
1418 MSWord_SdrAttrIter(const MSWord_SdrAttrIter&) = delete;
1419 MSWord_SdrAttrIter& operator=(const MSWord_SdrAttrIter&) = delete;
1420 public:
1421 MSWord_SdrAttrIter( MSWordExportBase& rWr, const EditTextObject& rEditObj,
1422 sal_uInt8 nType );
1423 void NextPara( sal_Int32 nPar );
1424 void OutParaAttr(bool bCharAttr, const std::set<sal_uInt16>* pWhichsToIgnore = nullptr);
1425 void OutEEField(const SfxPoolItem& rHt);
1427 bool IsTextAttr(sal_Int32 nSwPos);
1429 void NextPos() { if ( nAktSwPos < SAL_MAX_INT32 ) nAktSwPos = SearchNext( nAktSwPos + 1 ); }
1431 void OutAttr( sal_Int32 nSwPos );
1432 virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const override;
1433 virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const override;
1434 sal_Int32 WhereNext() const { return nAktSwPos; }
1435 rtl_TextEncoding GetNextCharSet() const;
1436 rtl_TextEncoding GetNodeCharSet() const { return eNdChrSet; }
1439 // class SwWW8AttrIter is a helper for constructing the Fkp.chpx.
1440 // Only character attributes are considered; paragraph attributes do not need this treatment.
1441 // The paragraph and text attributes of the Writer are passed, and
1442 // Where() returns the next position where the attributes change.
1443 // IsTextAtr() tells if, at the position returned by Where(), there is
1444 // an attribute without end and with \xff in the text.
1445 // Using OutAttr(), the attributes on the passed SwPos are returned.
1446 class SwWW8AttrIter : public MSWordAttrIter
1448 private:
1449 const SwTextNode& rNd;
1451 sw::util::CharRuns maCharRuns;
1452 sw::util::cCharRunIter maCharRunIter;
1454 rtl_TextEncoding meChrSet;
1455 sal_uInt16 mnScript;
1456 bool mbCharIsRTL;
1458 const SwRangeRedline* pCurRedline;
1459 sal_Int32 nAktSwPos;
1460 sal_uInt16 nCurRedlinePos;
1462 bool mbParaIsRTL;
1464 const SwFormatDrop &mrSwFormatDrop;
1466 ww8::Frames maFlyFrames; // #i2916#
1467 ww8::FrameIter maFlyIter;
1469 sal_Int32 SearchNext( sal_Int32 nStartPos );
1471 void OutSwFormatRefMark(const SwFormatRefMark& rAttr, bool bStart);
1473 void IterToCurrent();
1475 SwWW8AttrIter(const SwWW8AttrIter&) = delete;
1476 SwWW8AttrIter& operator=(const SwWW8AttrIter&) = delete;
1477 public:
1478 SwWW8AttrIter( MSWordExportBase& rWr, const SwTextNode& rNd );
1480 bool IsTextAttr( sal_Int32 nSwPos );
1481 bool IncludeEndOfParaCRInRedlineProperties(sal_Int32 nPos) const;
1482 bool IsDropCap( int nSwPos );
1483 bool RequiresImplicitBookmark();
1485 void NextPos() { if ( nAktSwPos < SAL_MAX_INT32 ) nAktSwPos = SearchNext( nAktSwPos + 1 ); }
1487 void OutAttr( sal_Int32 nSwPos, bool bRuby = false );
1488 virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const override;
1489 virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const override;
1490 int OutAttrWithRange(sal_Int32 nPos);
1491 const SwRedlineData* GetParagraphLevelRedline( );
1492 const SwRedlineData* GetRunLevelRedline( sal_Int32 nPos );
1493 FlyProcessingState OutFlys(sal_Int32 nSwPos);
1495 sal_Int32 WhereNext() const { return nAktSwPos; }
1496 sal_uInt16 GetScript() const { return mnScript; }
1497 bool IsParaRTL() const { return mbParaIsRTL; }
1498 rtl_TextEncoding GetCharSet() const { return meChrSet; }
1499 OUString GetSnippet(const OUString &rStr, sal_Int32 nAktPos,
1500 sal_Int32 nLen) const;
1501 const SwFormatDrop& GetSwFormatDrop() const { return mrSwFormatDrop; }
1503 bool IsWatermarkFrame();
1504 bool IsAnchorLinkedToThisNode( sal_uLong nNodePos );
1507 /// Class to collect and output the styles table.
1508 class MSWordStyles
1510 MSWordExportBase& m_rExport;
1511 sal_uInt16 m_aHeadingParagraphStyles[MAXLEVEL];
1512 SwFormat** m_pFormatA; ///< Slot <-> Character and paragraph style array (0 for list styles).
1513 sal_uInt16 m_nUsedSlots;
1514 bool m_bListStyles; ///< If list styles are requested to be exported as well.
1515 std::map<sal_uInt16, const SwNumRule*> m_aNumRules; ///< Slot <-> List style map.
1517 /// We need to build style id's for DOCX export; ideally we should roundtrip that, but this is good enough.
1518 std::vector<OString> m_aStyleIds;
1520 /// Create the style table, called from the constructor.
1521 void BuildStylesTable();
1523 /// Based on pFormatA, fill in m_aStyleIds with unique, MS-like names.
1524 void BuildStyleIds();
1526 /// Get slot number during building the style table.
1527 sal_uInt16 BuildGetSlot( const SwFormat& rFormat );
1528 sal_uInt16 BuildGetSlot( const SwNumRule& /*rNumRule*/ ) { return m_nUsedSlots++;}
1530 /// Return information about one style.
1531 void GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& nBase, sal_uInt16& nNext );
1533 /// Outputs attributes of one style.
1534 void WriteProperties( const SwFormat* pFormat, bool bPap, sal_uInt16 nPos, bool bInsDefCharSiz );
1536 static sal_uInt16 GetWWId( const SwFormat& rFormat );
1538 void SetStyleDefaults( const SwFormat& rFormat, bool bPap );
1540 /// Outputs one style - called (in a loop) from OutputStylesTable().
1541 void OutputStyle( SwFormat* pFormat, sal_uInt16 nPos );
1542 void OutputStyle( const SwNumRule* pNumRule, sal_uInt16 nPos );
1544 MSWordStyles( const MSWordStyles& ) = delete;
1545 MSWordStyles& operator=( const MSWordStyles& ) = delete;
1547 public:
1548 MSWordStyles( MSWordExportBase& rExport, bool bListStyles = false );
1549 ~MSWordStyles();
1551 /// Output the styles table.
1552 void OutputStylesTable();
1554 /// Get id of the style (rFormat).
1555 sal_uInt16 GetSlot( const SwFormat* pFormat ) const;
1557 /// Get styleId of the nId-th style (nId is its position in pFormatA).
1558 OString GetStyleId(sal_uInt16 nId) const;
1560 const SwFormat* GetSwFormat(sal_uInt16 nId) const { return m_pFormatA[nId]; }
1561 /// Get numbering rule of the nId-th style
1562 const SwNumRule* GetSwNumRule(sal_uInt16 nId) const;
1563 sal_uInt16 GetHeadingParagraphStyleId(sal_uInt16 nLevel) const { return m_aHeadingParagraphStyles[ nLevel ]; }
1566 #define MSWORD_MAX_STYLES_LIMIT 4091
1568 sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat);
1569 // A bit of a bag on the side for now
1570 OUString FieldString(ww::eField eIndex);
1571 OUString BookmarkToWord(const OUString &rBookmark);
1573 class WW8SHDLong
1575 sal_uInt32 m_cvFore;
1576 sal_uInt32 m_cvBack;
1578 public:
1579 WW8SHDLong() : m_cvFore(0), m_cvBack(0) {}
1581 void Write(WW8Export & rExport);
1582 void setCvFore(sal_uInt32 cvFore) { m_cvFore = cvFore; }
1583 void setCvBack(sal_uInt32 cvBack) { m_cvBack = cvBack; }
1586 #endif // INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX
1588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */