1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 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/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 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 . 18 */ 19 20 #ifndef INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX 21 #define INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX 22 23 #include <sot/storage.hxx> 24 #include <tools/solar.h> 25 #include <tools/gen.hxx> 26 #include <editeng/editdata.hxx> 27 #include <filter/msfilter/ww8fields.hxx> 28 29 #include <shellio.hxx> 30 31 #include "ww8struc.hxx" 32 #include "ww8scan.hxx" 33 #include "types.hxx" 34 #include "writerhelper.hxx" 35 #include <msfilter.hxx> 36 #include <expfld.hxx> 37 #include "WW8TableInfo.hxx" 38 #include <calbck.hxx> 39 #include <IDocumentRedlineAccess.hxx> 40 41 #include <vcl/graph.hxx> 42 43 #include <optional> 44 #include <o3tl/typed_flags_set.hxx> 45 #include <o3tl/sorted_vector.hxx> 46 47 #include <cstddef> 48 #include <memory> 49 #include <map> 50 #include <string_view> 51 #include <vector> 52 53 54 class SvxBrushItem; 55 class EditTextObject; 56 57 // some forward declarations 58 class SwWW8AttrIter; 59 namespace msfilter 60 { 61 class MSCodec_Std97; 62 } 63 64 namespace editeng { class SvxBorderLine; } 65 66 class AttributeOutputBase; 67 class DocxAttributeOutput; 68 class RtfAttributeOutput; 69 class BitmapPalette; 70 class SwEscherEx; 71 class DateTime; 72 namespace vcl { class Font; } 73 class MSWordExportBase; 74 class SdrObject; 75 class SdrTextObj; 76 class SfxItemSet; 77 class SvStream; 78 class SvxFontItem; 79 class SvxBoxItem; 80 class SwAttrSet; 81 class SwCharFormat; 82 class SwContentNode; 83 class SwField; 84 class SwFormat; 85 class SwFormatContent; 86 class SwFormatFootnote; 87 class SwFrameFormat; 88 class SwGrfNode; 89 class SwNumFormat; 90 class SwNumRule; 91 class SwNumRuleTable; 92 class SwPageDesc; 93 class SwFormatPageDesc; 94 class SwOLENode; 95 class SwPostItField; 96 class SwRedlineData; 97 class SwSectionFormat; 98 class SwSectionNode; 99 class SwTableNode; 100 class SwTOXType; 101 class SwTextFormatColl; 102 class SwTextNode; 103 class SwWW8WrGrf; 104 class SwWW8Writer; 105 class MSWordStyles; 106 class WW8AttributeOutput; 107 class WW8Export; 108 class MSWordAttrIter; 109 class WW8_WrFkp; 110 class WW8_WrPlc0; 111 class WW8_WrPlc1; 112 class WW8_WrPlcField; 113 class WW8_WrMagicTable; 114 class WW8_WrPlcFootnoteEdn; 115 class WW8_WrPlcPn; 116 class WW8_WrPlcAnnotations; 117 class WW8_WrtFactoids; 118 class MSWordSections; 119 class WW8_WrPlcTextBoxes; 120 class WW8_WrPct; // administration 121 class WW8_WrtBookmarks; 122 class WW8_WrtRedlineAuthor; 123 class SvxMSExportOLEObjects; 124 class SwMSConvertControls; 125 class WW8_WrPc; 126 struct WW8_PdAttrDesc; 127 class SvxBrushItem; 128 namespace sw::mark { class IFieldmark; } 129 namespace com::sun::star::embed { class XEmbeddedObject; } 130 131 typedef std::map<const css::embed::XEmbeddedObject*, sal_Int32> WW8OleMap; 132 typedef o3tl::sorted_vector< sal_Int32 > SwSoftPageBreakList; 133 134 #define GRF_MAGIC_1 0x12 // 3 magic bytes for PicLocFc attribute 135 #define GRF_MAGIC_2 0x34 136 #define GRF_MAGIC_3 0x56 137 #define GRF_MAGIC_321 0x563412L 138 139 #define OLE_PREVIEW_AS_EMF //If we want to export ole2 previews as emf in ww8+ 140 141 enum class FieldFlags : sal_uInt8 // for InsertField- Method 142 { 143 NONE = 0x00, 144 Start = 0x01, 145 CmdStart = 0x02, 146 CmdEnd = 0x04, 147 End = 0x10, 148 Close = 0x20, 149 All = 0x37 150 }; 151 namespace o3tl { 152 template<> struct typed_flags<FieldFlags> : is_typed_flags<FieldFlags, 0x37> {}; 153 } 154 155 enum TextTypes //enums for TextTypes 156 { 157 TXT_MAINTEXT = 0, /*TXT_FTNEDN = 1,*/ TXT_HDFT = 2, TXT_FTN = 3, 158 TXT_EDN = 4, TXT_ATN = 5, TXT_TXTBOX = 6, TXT_HFTXTBOX= 7 159 }; 160 161 /** 162 enum to state the present state of the fly 163 */ 164 enum FlyProcessingState 165 { 166 FLY_NONE, 167 FLY_PROCESSED, 168 FLY_POSTPONED, 169 FLY_NOT_PROCESSED 170 }; 171 172 struct WW8_SepInfo 173 { 174 const SwPageDesc* pPageDesc; 175 const SwSectionFormat* pSectionFormat; 176 const SwNode* pPDNd; 177 sal_uLong nLnNumRestartNo; 178 ::std::optional<sal_uInt16> oPgRestartNo; 179 bool bIsFirstParagraph; 180 WW8_SepInfoWW8_SepInfo181 WW8_SepInfo( const SwPageDesc* pPD, const SwSectionFormat* pFormat, 182 sal_uLong nLnRestart, ::std::optional<sal_uInt16> oPgRestart = std::nullopt, 183 const SwNode* pNd = nullptr, bool bIsFirstPara = false ) 184 : pPageDesc( pPD ), pSectionFormat( pFormat ), pPDNd( pNd ), 185 nLnNumRestartNo( nLnRestart ), oPgRestartNo( oPgRestart ), 186 bIsFirstParagraph( bIsFirstPara ) 187 {} 188 189 bool IsProtected() const; 190 }; 191 192 /// Class to collect and output the sections/headers/footers. 193 // Plc for PageDescs -> Sepx ( Section Extensions ) 194 class MSWordSections 195 { 196 protected: 197 bool mbDocumentIsProtected; 198 std::vector<WW8_SepInfo> aSects; 199 200 void CheckForFacinPg( const WW8Export& rWrt ) const; 201 void NeedsDocumentProtected(const WW8_SepInfo &rInfo); 202 203 //No copy, no assign 204 MSWordSections( const MSWordSections& ); 205 MSWordSections& operator=( const MSWordSections& ); 206 public: 207 explicit MSWordSections( MSWordExportBase& rExport ); 208 virtual ~MSWordSections(); 209 210 virtual bool HeaderFooterWritten(); 211 212 void AppendSection( const SwPageDesc* pPd, 213 const SwSectionFormat* pSectionFormat, 214 sal_uLong nLnNumRestartNo, 215 bool bIsFirstParagraph = false ); 216 void AppendSection( const SwFormatPageDesc& rPd, 217 const SwNode& rNd, 218 const SwSectionFormat* pSectionFormat, 219 sal_uLong nLnNumRestartNo ); 220 221 /// Number of columns based on the most recent WW8_SepInfo. 222 sal_uInt16 CurrentNumberOfColumns( const SwDoc &rDoc ) const; 223 224 /// Number of columns of the provided WW8_SepInfo. 225 static sal_uInt16 NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo ); 226 DocumentIsProtected() const227 bool DocumentIsProtected() const { return mbDocumentIsProtected; } 228 229 /// The most recent WW8_SepInfo. 230 const WW8_SepInfo* CurrentSectionInfo(); 231 232 static void SetHeaderFlag( sal_uInt8& rHeadFootFlags, const SwFormat& rFormat, 233 sal_uInt8 nFlag ); 234 static void SetFooterFlag( sal_uInt8& rHeadFootFlags, const SwFormat& rFormat, 235 sal_uInt8 nFlag ); 236 237 /// Should we output borders? 238 static bool HasBorderItem( const SwFormat& rFormat ); 239 }; 240 241 class WW8_WrPlcSepx : public MSWordSections 242 { 243 std::vector<WW8_CP> aCps; 244 std::vector< std::shared_ptr<WW8_PdAttrDesc> > m_SectionAttributes; 245 // hack to prevent adding sections in endnotes 246 bool m_bHeaderFooterWritten; 247 std::unique_ptr<WW8_WrPlc0> pTextPos; // Position of the headers/footers 248 249 WW8_WrPlcSepx( const WW8_WrPlcSepx& ) = delete; 250 WW8_WrPlcSepx& operator=( const WW8_WrPlcSepx& ) = delete; 251 252 public: 253 explicit WW8_WrPlcSepx( MSWordExportBase& rExport ); 254 virtual ~WW8_WrPlcSepx() override; 255 256 virtual bool HeaderFooterWritten() override; // override 257 258 void AppendSep( WW8_CP nStartCp, 259 const SwPageDesc* pPd, 260 const SwSectionFormat* pSectionFormat, 261 sal_uLong nLnNumRestartNo ); 262 void AppendSep( WW8_CP nStartCp, const SwFormatPageDesc& rPd, 263 const SwNode& rNd, 264 const SwSectionFormat* pSectionFormat, 265 sal_uLong nLnNumRestartNo ); Finish(WW8_CP nEndCp)266 void Finish( WW8_CP nEndCp ) { aCps.push_back( nEndCp ); } 267 268 bool WriteKFText( WW8Export& rWrt ); 269 void WriteSepx( SvStream& rStrm ) const; 270 void WritePlcSed( WW8Export& rWrt ) const; 271 void WritePlcHdd( WW8Export& rWrt ) const; 272 273 private: 274 void WriteFootnoteEndText( WW8Export& rWrt, sal_uLong nCpStt ); 275 public: 276 void OutHeaderFooter(WW8Export& rWrt, bool bHeader, 277 const SwFormat& rFormat, sal_uLong& rCpPos, sal_uInt8 nHFFlags, sal_uInt8 nFlag, sal_uInt8 nBreakCode); 278 }; 279 280 // class WW8_WrPct to construct the piece table 281 class WW8_WrPct 282 { 283 std::vector<std::unique_ptr<WW8_WrPc>> m_Pcts; 284 WW8_FC nOldFc; 285 public: 286 explicit WW8_WrPct(WW8_FC nStartFc); 287 ~WW8_WrPct(); 288 void AppendPc(WW8_FC nStartFc); 289 void WritePc( WW8Export& rWrt ); 290 void SetParaBreak(); 291 WW8_CP Fc2Cp( sal_uLong nFc ) const; 292 }; 293 294 /// Collects and outputs fonts. 295 class wwFont 296 { 297 //In some future land the stream could be converted to a nice stream interface 298 //and we could have harmony 299 private: 300 sal_uInt8 maWW8_FFN[6] = {}; 301 OUString msFamilyNm; 302 OUString msAltNm; 303 bool mbAlt; 304 FontPitch mePitch; 305 FontFamily meFamily; 306 rtl_TextEncoding meChrSet; 307 public: 308 wwFont( const OUString &rFamilyName, FontPitch ePitch, FontFamily eFamily, 309 rtl_TextEncoding eChrSet); 310 void Write( SvStream *pTableStram ) const; 311 void WriteDocx( DocxAttributeOutput* rAttrOutput ) const; 312 void WriteRtf( const RtfAttributeOutput* rAttrOutput ) const; GetFamilyName() const313 OUString const & GetFamilyName() const { return msFamilyNm; } 314 friend bool operator < (const wwFont &r1, const wwFont &r2); 315 }; 316 317 class wwFontHelper 318 { 319 private: 320 /// Keep track of fonts that need to be exported. 321 std::map<wwFont, sal_uInt16> maFonts; 322 323 /// Convert from fast insertion map to linear vector in the order that we want to write. 324 std::vector< const wwFont* > AsVector() const; 325 326 public: wwFontHelper()327 wwFontHelper() : bLoadAllFonts(false) {} 328 /// rDoc used only to get the initial standard font(s) in use. 329 void InitFontTable(const SwDoc& rDoc); 330 sal_uInt16 GetId(const SvxFontItem& rFont); 331 sal_uInt16 GetId(const wwFont& rFont); 332 void WriteFontTable( SvStream *pTableStream, WW8Fib& pFib ); 333 void WriteFontTable( DocxAttributeOutput& rAttrOutput ); 334 void WriteFontTable( const RtfAttributeOutput& rAttrOutput ); 335 336 /// If true, all fonts are loaded before processing the document. 337 bool bLoadAllFonts: 1; 338 }; 339 340 class DrawObj 341 { 342 public: 343 WW8_CP mnCp; // CP-Pos of references 344 sal_uInt32 mnShapeId; // ShapeId for the SwFrameFormats 345 ww8::Frame maContent; // the frame itself 346 Point maParentPos; // Points 347 sal_Int32 mnThick; // Border Thicknesses 348 SvxFrameDirection mnDirection; // If BiDi or not 349 unsigned int mnHdFtIndex; // 0 for main text, +1 for each subsequent 350 // msword hd/ft 351 DrawObj(const ww8::Frame & rContent,WW8_CP nCp,Point aParentPos,SvxFrameDirection nDir,unsigned int nHdFtIndex)352 DrawObj(const ww8::Frame &rContent, WW8_CP nCp, Point aParentPos, SvxFrameDirection nDir, 353 unsigned int nHdFtIndex) 354 : mnCp(nCp), mnShapeId(0), maContent(rContent), maParentPos(aParentPos), 355 mnThick(0), mnDirection(nDir), mnHdFtIndex(nHdFtIndex) {} 356 void SetShapeDetails(sal_uInt32 nId, sal_Int32 nThick); 357 }; 358 359 typedef std::vector<DrawObj> DrawObjVector; 360 typedef std::vector<DrawObj *> DrawObjPointerVector; 361 362 class PlcDrawObj // PC for DrawObjects and Text-/OLE-/GRF-Boxes 363 { 364 private: 365 DrawObjVector maDrawObjs; // vector of drawobjs 366 protected: 367 virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart, 368 sal_uInt32 nLen) const = 0; 369 virtual WW8_CP GetCpOffset(const WW8Fib &rFib) const = 0; 370 public: PlcDrawObj()371 PlcDrawObj() {} 372 void WritePlc( WW8Export& rWrt ) const; 373 bool Append( WW8Export const &, WW8_CP nCp, const ww8::Frame& rFormat, 374 const Point& rNdTopLeft ); size()375 int size() { return maDrawObjs.size(); }; GetObjArr()376 DrawObjVector &GetObjArr() { return maDrawObjs; } 377 virtual ~PlcDrawObj(); 378 private: 379 PlcDrawObj(const PlcDrawObj&) = delete; 380 PlcDrawObj& operator=(const PlcDrawObj&) = delete; 381 }; 382 383 class MainTextPlcDrawObj : public PlcDrawObj 384 { 385 public: MainTextPlcDrawObj()386 MainTextPlcDrawObj() {} 387 private: 388 virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart, 389 sal_uInt32 nLen) const override; 390 virtual WW8_CP GetCpOffset(const WW8Fib &) const override; 391 private: 392 MainTextPlcDrawObj(const MainTextPlcDrawObj&) = delete; 393 MainTextPlcDrawObj& operator=(const MainTextPlcDrawObj&) = delete; 394 }; 395 396 class HdFtPlcDrawObj : public PlcDrawObj 397 { 398 public: HdFtPlcDrawObj()399 HdFtPlcDrawObj() {} 400 private: 401 virtual void RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart, 402 sal_uInt32 nLen) const override; 403 virtual WW8_CP GetCpOffset(const WW8Fib &rFib) const override; 404 private: 405 HdFtPlcDrawObj(const HdFtPlcDrawObj&) = delete; 406 HdFtPlcDrawObj& operator=(const HdFtPlcDrawObj&) = delete; 407 }; 408 409 typedef std::pair<OUString, sal_uLong> aBookmarkPair; 410 411 class WW8_WrtRedlineAuthor : public sw::util::WrtRedlineAuthor 412 { 413 public: 414 virtual void Write(Writer &rWrt) override; 415 }; 416 417 /** Structure that is used to save some of the WW8Export/DocxExport data. 418 419 It is used to be able to recurse inside of the WW8Export/DocxExport (eg. 420 for the needs of the tables) - you need to tall WriteText() from there with 421 new values of PaM etc. 422 423 It must contain all the stuff that might be saved either in WW8Export or in 424 DocxExport, because it makes no sense to do it abstract, and specialize it 425 for each of the cases. If you implement other *Export, just add the needed 426 members here, and store them in the appropriate SaveData() method. 427 */ 428 struct MSWordSaveData 429 { 430 Point* pOldFlyOffset; 431 RndStdIds eOldAnchorType; 432 std::unique_ptr<ww::bytes> pOOld; ///< WW8Export only 433 std::shared_ptr<SwUnoCursor> pOldPam; 434 SwPaM* pOldEnd; 435 sal_uLong nOldStart, nOldEnd; 436 const ww8::Frame* pOldFlyFormat; 437 const SwPageDesc* pOldPageDesc; 438 439 bool bOldWriteAll : 1; ///< WW8Export only 440 bool bOldOutTable : 1; 441 bool bOldFlyFrameAttrs : 1; 442 bool bOldStartTOX : 1; 443 bool bOldInWriteTOX : 1; 444 // m_bOutPageDescs does not have to be saved in MSWordExportBase::SaveData 445 // since it is only modified when outputting special texts. 446 }; 447 448 /// Base class for WW8Export and DocxExport 449 class MSWordExportBase 450 { 451 public: 452 wwFontHelper m_aFontHelper; 453 std::vector<sal_uLong> m_aChapterFieldLocs; 454 OUString m_aMainStg; 455 std::vector<const SwTOXType*> m_aTOXArr; 456 const SfxItemSet* m_pISet; // for double attributes 457 const SwFrameFormat* m_pFirstPageFormat = nullptr; 458 WW8_WrPct* m_pPiece; // Pointer to Piece-Table 459 std::unique_ptr<SwNumRuleTable> m_pUsedNumTable; // all used NumRules 460 /// overriding numdef index -> (existing numdef index, abstractnumdef index) 461 std::map<size_t, std::pair<size_t, size_t>> m_OverridingNums; 462 /// list-id -> abstractnumdef index 463 std::map<OUString, size_t> m_Lists; 464 465 /// Map of maps for list levels overrides 466 /// listid -> level number -> restart value 467 std::map < size_t, std::map<size_t, size_t> > m_ListLevelOverrides; 468 469 const SwTextNode *m_pTopNodeOfHdFtPage; ///< Top node of host page when in hd/ft 470 std::stack< sal_Int32 > m_aCurrentCharPropStarts; ///< To remember the position in a run. 471 WW8_WrtBookmarks* m_pBkmks; 472 WW8_WrtRedlineAuthor* m_pRedlAuthors; 473 std::shared_ptr<NfKeywordTable> m_pKeyMap; 474 std::unique_ptr<SvxMSExportOLEObjects> m_pOLEExp; 475 std::unique_ptr<SwMSConvertControls> m_pOCXExp; 476 WW8OleMap m_aOleMap; // To remember all already exported ole objects 477 ww8::WW8TableInfo::Pointer_t m_pTableInfo; 478 479 sal_uInt16 m_nCharFormatStart; 480 sal_uInt16 m_nFormatCollStart; 481 sal_uInt16 m_nStyleBeforeFly; ///< style number of the node 482 ///< to which the Fly is connected 483 sal_uInt16 m_nLastFormatId; ///< Style of last TextNode in normal range 484 sal_uInt16 m_nUniqueList; ///< current number for creating unique list names 485 unsigned int m_nHdFtIndex; 486 487 RedlineFlags m_nOrigRedlineFlags; ///< Remember the original redline mode 488 bool m_bOrigShowChanges; ///< Remember the original Show Changes mode 489 490 public: 491 /* implicit bookmark vector containing pairs of node indexes and bookmark names */ 492 std::vector<aBookmarkPair> m_aImplicitBookmarks; 493 std::unordered_map<OUString, OUString> m_TOXMarkBookmarksByURL; 494 std::unordered_map<SwTOXMark const*, OUString> m_TOXMarkBookmarksByTOXMark; 495 ww8::Frames m_aFrames; // The floating frames in this document 496 const SwPageDesc *m_pCurrentPageDesc; 497 bool m_bFirstTOCNodeWithSection; 498 std::unique_ptr<WW8_WrPlcPn> m_pPapPlc; 499 std::unique_ptr<WW8_WrPlcPn> m_pChpPlc; 500 MSWordAttrIter* m_pChpIter; 501 std::unique_ptr<MSWordStyles> m_pStyles; 502 WW8_WrPlcAnnotations* m_pAtn; 503 std::unique_ptr<WW8_WrtFactoids> m_pFactoids; 504 WW8_WrPlcTextBoxes *m_pTextBxs, *m_pHFTextBxs; 505 506 struct LinkedTextboxInfo //help analyze textbox flow links 507 { 508 sal_Int32 nId; 509 sal_Int32 nSeq; 510 OUString sNextChain; 511 OUString sPrevChain; LinkedTextboxInfoMSWordExportBase::LinkedTextboxInfo512 LinkedTextboxInfo(): nId(0), nSeq(0) {} 513 }; 514 std::map<OUString,LinkedTextboxInfo> m_aLinkedTextboxesHelper; 515 bool m_bLinkedTextboxesHelperInitialized = false; 516 sal_Int32 m_nLinkedTextboxesChainId=0; 517 518 const ww8::Frame *m_pParentFrame; // If set we are exporting content inside 519 // a frame, e.g. a graphic node 520 521 Point* m_pFlyOffset; // for adjusting of character-bound Fly in the Writer, 522 RndStdIds m_eNewAnchorType; // that is paragraph-bound in the WW. 523 524 std::unique_ptr<WW8_WrPlcField> m_pFieldMain; // fields in MainText 525 std::unique_ptr<WW8_WrPlcField> m_pFieldHdFt; // fields in Header/Footer 526 std::unique_ptr<WW8_WrPlcField> m_pFieldFootnote; // fields in FootNotes 527 std::unique_ptr<WW8_WrPlcField> m_pFieldEdn; // fields in EndNotes 528 std::unique_ptr<WW8_WrPlcField> m_pFieldAtn; // fields in Annotations 529 std::unique_ptr<WW8_WrPlcField> m_pFieldTextBxs; // fields in textboxes 530 std::unique_ptr<WW8_WrPlcField> m_pFieldHFTextBxs; // fields in header/footer textboxes 531 std::unique_ptr<WW8_WrMagicTable> m_pMagicTable; // keeps track of table cell positions, and 532 // marks those that contain graphics, 533 // which is required to make word display 534 // graphics inside tables 535 std::unique_ptr<SwWW8WrGrf> m_pGrf; 536 const SwAttrSet* m_pStyAttr; // StyleAttr for Tabs 537 const sw::BroadcastingModify* m_pOutFormatNode; // write Format or Node 538 const SwFormat *m_pCurrentStyle; // iff bStyDef=true, then this store the current style 539 540 MainTextPlcDrawObj *m_pSdrObjs; // Draw-/Fly-Objects 541 HdFtPlcDrawObj *m_pHFSdrObjs; // Draw-/Fly-Objects in header or footer 542 543 SwEscherEx* m_pEscher; // escher export class 544 // #i43447# - removed 545 // SwTwips nFlyWidth, nFlyHeight; // for adaptation of graphics 546 547 sal_uInt8 m_nTextTyp; 548 549 bool m_bStyDef : 1; // should Style be written? 550 bool m_bBreakBefore : 1; // Breaks are being written 2 times 551 bool m_bOutKF : 1; // Header/Footer texts are being written 552 bool m_bOutFlyFrameAttrs : 1; // Frame-attr of Flys are being written 553 bool m_bOutPageDescs : 1; ///< PageDescs (section properties) are being written 554 bool m_bOutFirstPage : 1; // write Attrset of FirstPageDesc 555 bool m_bOutTable : 1; // table is being written 556 // ( is reset e.g. for Flys in a table ) 557 bool m_bOutGrf : 1; // graphics are being written 558 bool m_bInWriteEscher : 1; // in write textboxes 559 bool m_bStartTOX : 1; // true: a TOX is started 560 bool m_bInWriteTOX : 1; // true: all content are in a TOX 561 bool m_bFootnoteAtTextEnd : 1; // true: all FTN at Textend 562 bool m_bEndAtTextEnd : 1; // true: all END at Textend 563 bool m_bHasHdr : 1; 564 bool m_bHasFtr : 1; 565 bool m_bSubstituteBullets : 1; // true: SubstituteBullet() gets called 566 bool m_bTabInTOC : 1; //true for TOC field flag 'w' 567 568 bool m_bHideTabLeaderAndPageNumbers : 1 ; // true: the 'z' field of TOC is set. 569 bool m_bExportModeRTF; 570 /// Is font size written already as part of the current character properties? 571 bool m_bFontSizeWritten; 572 bool m_bAddFootnoteTab; // only one aesthetic spacing tab per footnote 573 574 SwDoc& m_rDoc; 575 sal_uLong m_nCurStart, m_nCurEnd; 576 std::shared_ptr<SwUnoCursor> & m_pCurPam; 577 SwPaM *m_pOrigPam; 578 579 /// Stack to remember the nesting (see MSWordSaveData for more) 580 std::stack< MSWordSaveData > m_aSaveData; 581 582 /// Used to split the runs according to the bookmarks start and ends 583 typedef std::vector< ::sw::mark::IMark* > IMarkVector; 584 IMarkVector m_rSortedBookmarksStart; 585 IMarkVector m_rSortedBookmarksEnd; 586 IMarkVector m_rSortedAnnotationMarksStart; 587 IMarkVector m_rSortedAnnotationMarksEnd; 588 589 public: 590 /// The main function to export the document. 591 ErrCode ExportDocument( bool bWriteAll ); 592 593 /// Iterate through the nodes and call the appropriate OutputNode() on them. 594 void WriteText(); 595 596 /// Return whether currently exported node is in table. 597 bool IsInTable() const; 598 599 /// Set the pCurPam appropriately and call WriteText(). 600 /// 601 /// Used to export paragraphs in footnotes/endnotes/etc. 602 void WriteSpecialText( sal_uLong nStart, sal_uLong nEnd, sal_uInt8 nTTyp ); 603 604 /// Export the pool items to attributes (through an attribute output class). 605 void ExportPoolItemsToCHP( ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont, bool bWriteCombChars = false ); 606 607 /// Return the numeric id of the numbering rule 608 sal_uInt16 GetNumberingId( const SwNumRule& rNumRule ); 609 610 /// Return the numeric id of the style. 611 sal_uInt16 GetId( const SwTextFormatColl& rColl ) const; 612 613 /// Return the numeric id of the style. 614 sal_uInt16 GetId( const SwCharFormat* pFormat ) const; 615 616 sal_uInt16 GetId( const SwTOXType& rTOXType ); 617 618 /// Return the numeric id of the font (and add it to the font list if needed) GetId(const SvxFontItem & rFont)619 sal_uInt16 GetId( const SvxFontItem& rFont) 620 { 621 return m_aFontHelper.GetId(rFont); 622 } 623 /// @overload GetId(const wwFont & rFont)624 void GetId( const wwFont& rFont) 625 { 626 m_aFontHelper.GetId(rFont); 627 } 628 629 const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const; GetItem(TypedWhichId<T> nWhich) const630 template<class T> const T& GetItem( TypedWhichId<T> nWhich ) const 631 { 632 return static_cast<const T&>(GetItem(sal_uInt16(nWhich))); 633 } 634 635 /// Find the reference. 636 bool HasRefToAttr(const OUString& rName); 637 bool HasRefToFootOrEndnote(const bool isEndNote, const sal_uInt16 nSeqNo); 638 639 /// Find the bookmark name. 640 static OUString GetBookmarkName( sal_uInt16 nTyp, const OUString* pName, sal_uInt16 nSeqNo ); 641 642 /// Use OutputItem() on an item set according to the parameters. 643 void OutputItemSet( const SfxItemSet& rSet, bool bPapFormat, bool bChpFormat, sal_uInt16 nScript, bool bExportParentItemSet ); 644 645 SvxFrameDirection GetDefaultFrameDirection( ) const; 646 647 /// Right to left? 648 SvxFrameDirection TrueFrameDirection( const SwFrameFormat& rFlyFormat ) const; 649 650 /// Right to left? 651 SvxFrameDirection GetCurrentPageDirection() const; 652 653 /// In case of numbering restart. 654 655 /// List is set to restart at a particular value so for export make a 656 /// completely new list based on this one and export that instead, 657 /// which duplicates words behaviour in this respect. 658 sal_uInt16 DuplicateNumRule(const SwNumRule* pRule, sal_uInt8 nLevel, sal_uInt16 nVal); 659 SwNumRule * DuplicateNumRuleImpl(const SwNumRule *pRule); 660 661 /// check if a new abstractNum is needed for this list 662 sal_uInt16 DuplicateAbsNum(OUString const& rListId, 663 SwNumRule const& rAbstractRule); 664 665 666 /// Create a overriding numbering definition (if it does not yet exist) 667 /// @return index of the overriding numbering definition 668 sal_uInt16 OverrideNumRule(SwNumRule const& rExistingRule, 669 OUString const& rListId, 670 SwNumRule const& rAbstractRule); 671 672 /// Store list level overrides (restart of list) 673 void AddListLevelOverride(sal_uInt16 nListId, 674 sal_uInt16 nLevelNum, 675 sal_uInt16 nStartAt); 676 677 /// Access to the attribute output class. 678 virtual AttributeOutputBase& AttrOutput() const = 0; 679 680 /// Access to the sections/headers/footres. 681 virtual MSWordSections& Sections() const = 0; 682 683 /// Determines if the import filter already quoted fields or not. 684 virtual bool FieldsQuoted() const = 0; 685 686 /// Determines the Section Breaks are to be added for TOX Section 687 virtual bool AddSectionBreaksForTOX() const = 0; 688 689 /// Used to filter out attributes that can be e.g. written to .doc but not to .docx ignoreAttributeForStyleDefaults(sal_uInt16) const690 virtual bool ignoreAttributeForStyleDefaults( sal_uInt16 /*nWhich*/ ) const { return false; } 691 692 /// If saving page break is preferred as a paragraph attribute (yes) or as a special character (no). 693 virtual bool PreferPageBreakBefore() const = 0; 694 695 /// Guess the script (asian/western). 696 /// 697 /// Sadly word does not have two different sizes for asian font size and 698 /// western font size, it has two different fonts, but not sizes, so we 699 /// have to use our guess as to the script used and disable the export of 700 /// one type. The same occurs for font weight and posture (bold and 701 /// italic). 702 /// 703 /// In addition WW7- has only one character language identifier while WW8+ 704 /// has two 705 virtual bool CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich ) = 0; 706 707 virtual void AppendBookmarks( const SwTextNode& rNd, sal_Int32 nCurrentPos, sal_Int32 nLen ) = 0; 708 709 virtual void AppendBookmark( const OUString& rName ) = 0; 710 711 virtual void AppendAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen ) = 0; 712 AppendSmartTags(SwTextNode &)713 virtual void AppendSmartTags(SwTextNode& /*rTextNode*/) { } 714 715 //For i120928,add this interface to export graphic of bullet 716 virtual void ExportGrfBullet(const SwTextNode& rNd) = 0; 717 718 // FIXME probably a hack... 719 virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() ) = 0; 720 721 // FIXME definitely a hack, must not be here - it can't do anything 722 // sensible for docx 723 virtual void WriteChar( sal_Unicode c ) = 0; 724 725 /// Output attributes. 726 void OutputFormat( const SwFormat& rFormat, bool bPapFormat, bool bChpFormat, bool bFlyFormat = false ); 727 728 /// Getter for pISet. GetCurItemSet() const729 const SfxItemSet* GetCurItemSet() const { return m_pISet; } 730 731 /// Setter for pISet. SetCurItemSet(const SfxItemSet * pS)732 void SetCurItemSet( const SfxItemSet* pS ) { m_pISet = pS; } 733 734 /// Remember some of the members so that we can recurse in WriteText(). 735 virtual void SaveData( sal_uLong nStt, sal_uLong nEnd ); 736 737 /// Restore what was saved in SaveData(). 738 virtual void RestoreData(); 739 740 /// The return value indicates, if a follow page desc is written. 741 bool OutputFollowPageDesc( const SfxItemSet* pSet, 742 const SwTextNode* pNd ); 743 744 /// Write header/footer text. 745 void WriteHeaderFooterText( const SwFormat& rFormat, bool bHeader); 746 747 /// Format of the section. 748 static const SwSectionFormat* GetSectionFormat( const SwNode& rNd ); 749 750 /// Line number of the section start. 751 static sal_uLong GetSectionLineNo( const SfxItemSet* pSet, const SwNode& rNd ); 752 753 /// Start new section. 754 void OutputSectionBreaks( const SfxItemSet *pSet, const SwNode& rNd, bool isCellOpen = false ); 755 756 /// Write section properties. 757 /// 758 /// pA is ignored for docx. 759 void SectionProperties( const WW8_SepInfo& rSectionInfo, WW8_PdAttrDesc* pA = nullptr ); 760 761 /// Output the numbering table. 762 virtual void WriteNumbering() = 0; 763 764 /// Write static data of SwNumRule - LSTF 765 void NumberingDefinitions(); 766 767 /// Write all Levels for all SwNumRules - LVLF 768 void AbstractNumberingDefinitions(); 769 770 /// Write one numbering level 771 void NumberingLevel(SwNumRule const& rRule, sal_uInt8 nLvl); 772 773 // Convert the bullet according to the font. 774 void SubstituteBullet( OUString& rNumStr, rtl_TextEncoding& rChrSet, 775 OUString& rFontName ) const; 776 777 /// Setup the pA's info. SetupSectionPositions(WW8_PdAttrDesc *)778 virtual void SetupSectionPositions( WW8_PdAttrDesc* /*pA*/ ) {} 779 780 /// Top node of host page when in header/footer. SetHdFtPageRoot(const SwTextNode * pNd)781 void SetHdFtPageRoot( const SwTextNode *pNd ) { m_pTopNodeOfHdFtPage = pNd; } 782 783 /// Top node of host page when in header/footer. GetHdFtPageRoot() const784 const SwTextNode *GetHdFtPageRoot() const { return m_pTopNodeOfHdFtPage; } 785 786 /// Output the actual headers and footers. 787 virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags, 788 const SwFrameFormat& rFormat, const SwFrameFormat& rLeftHeaderFormat, const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& rFirstPageFormat, 789 sal_uInt8 nBreakCode, bool bEvenAndOddHeaders) = 0; 790 791 /// Write the field 792 virtual void OutputField( const SwField* pField, ww::eField eFieldType, 793 const OUString& rFieldCmd, FieldFlags nMode = FieldFlags::All ) = 0; 794 795 /// Write the data of the form field 796 virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) = 0; 797 virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark& rFieldmark ) = 0; 798 799 virtual void DoComboBox(const OUString &rName, 800 const OUString &rHelp, 801 const OUString &ToolTip, 802 const OUString &rSelected, 803 const css::uno::Sequence<OUString> &rListItems) = 0; 804 805 virtual void DoFormText(const SwInputField * pField) = 0; 806 807 static bool NoPageBreakSection( const SfxItemSet *pSet ); 808 809 // Compute the number format for WW dates 810 bool GetNumberFormat(const SwField& rField, OUString& rStr); 811 812 virtual sal_uLong ReplaceCr( sal_uInt8 nChar ) = 0; 813 814 const SfxPoolItem* HasItem( sal_uInt16 nWhich ) const; 815 816 /// Returns the index of a picture bullet, used in numberings. 817 int GetGrfIndex(const SvxBrushItem& rBrush); 818 819 enum ExportFormat { DOC = 0, RTF = 1, DOCX = 2}; 820 virtual ExportFormat GetExportFormat() const = 0; 821 822 protected: 823 /// Format-dependent part of the actual export. 824 virtual ErrCode ExportDocument_Impl() = 0; 825 826 /// Get the next position in the text node to output 827 sal_Int32 GetNextPos( SwWW8AttrIter const * pAttrIter, const SwTextNode& rNode, sal_Int32 nCurrentPos ); 828 829 /// Update the information for GetNextPos(). 830 void UpdatePosition( SwWW8AttrIter* pAttrIter, sal_Int32 nCurrentPos ); 831 832 /// Output SwTextNode 833 virtual void OutputTextNode( SwTextNode& ); 834 835 /// Setup the chapter fields (maChapterFieldLocs). 836 void GatherChapterFields(); 837 838 void AddLinkTarget( std::u16string_view rURL ); 839 void CollectOutlineBookmarks( const SwDoc &rDoc ); 840 841 bool SetCurrentPageDescFromNode(const SwNode &rNd); 842 bool ContentContainsChapterField(const SwFormatContent &rContent) const; 843 bool FormatHdFtContainsChapterField(const SwFrameFormat &rFormat) const; 844 845 virtual void SectionBreaksAndFrames( const SwTextNode& rNode ) = 0; 846 847 virtual void PrepareNewPageDesc( const SfxItemSet* pSet, 848 const SwNode& rNd, 849 const SwFormatPageDesc* pNewPgDescFormat, 850 const SwPageDesc* pNewPgDesc, 851 bool bExtraPageBreak = false ) = 0; 852 853 /// Return value indicates if an inherited outline numbering is suppressed. 854 virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) = 0; 855 856 /// Output SwStartNode 857 void OutputStartNode( const SwStartNode& ); 858 859 /// Output SwEndNode 860 virtual void OutputEndNode( const SwEndNode& ); 861 862 /// Output SwGrfNode 863 virtual void OutputGrfNode( const SwGrfNode& ) = 0; 864 865 /// Output SwOLENode 866 virtual void OutputOLENode( const SwOLENode& ) = 0; 867 868 virtual void OutputLinkedOLE( const OUString& ) = 0; 869 870 /// Output SwSectionNode 871 void OutputSectionNode( const SwSectionNode& ); 872 static void UpdateTocSectionNodeProperties(const SwSectionNode& rSectionNode); 873 874 virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum ) = 0; 875 876 /// Call the right (virtual) function according to the type of the item. 877 /// 878 /// One of OutputTextNode(), OutputGrfNode(), or OutputOLENode() 879 void OutputContentNode( SwContentNode& ); 880 881 /// Find the nearest bookmark from the current position. 882 /// 883 /// Returns false when there is no bookmark. 884 bool NearestBookmark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly ); 885 886 void GetSortedBookmarks( const SwTextNode& rNd, sal_Int32 nCurrentPos, sal_Int32 nLen ); 887 888 bool GetBookmarks( const SwTextNode& rNd, sal_Int32 nStt, sal_Int32 nEnd, 889 IMarkVector& rArr ); 890 891 /// Find the nearest annotation mark from the current position. 892 /// 893 void NearestAnnotationMark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly ); 894 895 void GetSortedAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen ); 896 897 bool GetAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nStt, sal_Int32 nEnd, 898 IMarkVector& rArr ); 899 900 const NfKeywordTable & GetNfKeywordTable(); 901 902 void SetCurPam(sal_uLong nStt, sal_uLong nEnd); 903 904 /// Get background color of the document, if there is one. 905 std::unique_ptr<SvxBrushItem> getBackground(); 906 /// Populates m_vecBulletPic with all the bullet graphics used by numberings. 907 int CollectGrfsOfBullets(); 908 /// Write the numbering picture bullets. 909 void BulletDefinitions(); 910 911 bool NeedSectionBreak( const SwNode& rNd ) const; 912 bool NeedTextNodeSplit( const SwTextNode& rNd, SwSoftPageBreakList& pList ) const; 913 914 std::vector<const Graphic*> m_vecBulletPic; ///< Vector to record all the graphics of bullets 915 916 public: 917 MSWordExportBase(SwDoc& rDocument, std::shared_ptr<SwUnoCursor> & pCurrentPam, SwPaM* pOriginalPam); 918 virtual ~MSWordExportBase(); 919 920 // TODO move as much as possible here from WW8Export! ;-) 921 922 static void CorrectTabStopInSet( SfxItemSet& rSet, sal_Int32 nAbsLeft ); 923 924 private: 925 MSWordExportBase( const MSWordExportBase& ) = delete; 926 MSWordExportBase& operator=( const MSWordExportBase& ) = delete; 927 }; 928 929 /// The writer class that gets called for the WW8 filter. 930 class SwWW8Writer: public StgWriter 931 { 932 // friends to get access to m_pExport 933 // FIXME avoid that, this is probably not what we want 934 // (if yes, remove the friends, and provide here a GetExport() method) 935 friend void WW8_WrtRedlineAuthor::Write(Writer &rWrt); 936 937 WW8Export *m_pExport; 938 SfxMedium *mpMedium; 939 940 public: 941 SwWW8Writer(const OUString& rFltName, const OUString& rBaseURL); 942 virtual ~SwWW8Writer() override; 943 944 virtual ErrCode WriteStorage() override; 945 virtual ErrCode WriteMedium( SfxMedium& ) override; 946 947 // TODO most probably we want to be able to get these in 948 // MSExportFilterBase 949 using Writer::getIDocumentSettingAccess; 950 951 public: 952 static void InsUInt16(ww::bytes &rO, sal_uInt16 n); 953 static void InsUInt32(ww::bytes &rO, sal_uInt32 n); 954 static void InsAsString16(ww::bytes &rO, const OUString& rStr); 955 static void InsAsString8(ww::bytes & O, std::u16string_view rStr, 956 rtl_TextEncoding eCodeSet); 957 958 static sal_uLong FillUntil( SvStream& rStrm, sal_uLong nEndPos = 0 ); 959 static void FillCount( SvStream& rStrm, sal_uLong nCount ); 960 WriteShort(SvStream & rStrm,sal_Int16 nVal)961 static void WriteShort( SvStream& rStrm, sal_Int16 nVal ) { rStrm.WriteInt16( nVal ); } 962 static void WriteShort( SvStream& rStrm, sal_uLong nPos, sal_Int16 nVal ); 963 WriteLong(SvStream & rStrm,sal_Int32 nVal)964 static void WriteLong( SvStream& rStrm, sal_Int32 nVal ) { rStrm.WriteInt32( nVal ); } 965 static void WriteLong( SvStream& rStrm, sal_uLong nPos, sal_Int32 nVal ); 966 967 static void WriteString16(SvStream& rStrm, const OUString& rStr, 968 bool bAddZero); 969 static void WriteString8(SvStream& rStrm, std::u16string_view rStr, 970 bool bAddZero, rtl_TextEncoding eCodeSet); 971 972 static void WriteString_xstz(SvStream& rStrm, const OUString& rStr, bool bAddZero); 973 974 bool InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec ); 975 976 using StgWriter::Write; 977 virtual ErrCode Write( SwPaM&, SfxMedium&, const OUString* ) override; 978 //Seems not an expected to provide method to access the private member GetMedia()979 SfxMedium* GetMedia() { return mpMedium; } 980 981 private: 982 SwWW8Writer(const SwWW8Writer&) = delete; 983 SwWW8Writer& operator=(const SwWW8Writer&) = delete; 984 ErrCode WriteStorageImpl(); 985 }; 986 987 /// Exporter of the binary Word file formats. 988 class WW8Export : public MSWordExportBase 989 { 990 public: 991 std::unique_ptr<ww::bytes> pO; ///< Buffer 992 993 SvStream *pTableStrm, *pDataStrm; ///< Streams for WW97 Export 994 995 std::unique_ptr<WW8Fib> pFib; ///< File Information Block 996 std::unique_ptr<WW8Dop> pDop; ///< Document Properties 997 std::unique_ptr<WW8_WrPlcFootnoteEdn> pFootnote; ///< Footnotes - structure to remember them, and output 998 std::unique_ptr<WW8_WrPlcFootnoteEdn> pEdn; ///< Endnotes - structure to remember them, and output 999 std::unique_ptr<WW8_WrPlcSepx> pSepx; ///< Sections/headers/footers 1000 1001 bool m_bDot; ///< Template or document. 1002 1003 protected: 1004 SwWW8Writer *m_pWriter; ///< Pointer to the writer 1005 std::unique_ptr<WW8AttributeOutput> m_pAttrOutput; ///< Converting attributes to stream data 1006 1007 private: 1008 tools::SvRef<SotStorage> xEscherStg; /// memory leak #i120098#, to hold the reference to unnamed SotStorage obj 1009 1010 public: 1011 /// Access to the attribute output class. 1012 virtual AttributeOutputBase& AttrOutput() const override; 1013 1014 /// Access to the sections/headers/footres. 1015 virtual MSWordSections& Sections() const override; 1016 PreferPageBreakBefore() const1017 virtual bool PreferPageBreakBefore() const override { return true; } 1018 FieldsQuoted() const1019 virtual bool FieldsQuoted() const override { return false; } 1020 AddSectionBreaksForTOX() const1021 virtual bool AddSectionBreaksForTOX() const override { return false; } 1022 private: 1023 /// Format-dependent part of the actual export. 1024 virtual ErrCode ExportDocument_Impl() override; 1025 1026 void PrepareStorage(); 1027 void WriteFkpPlcUsw(); 1028 void WriteMainText(); 1029 void StoreDoc1(); 1030 1031 /// Output the numbering table. 1032 virtual void WriteNumbering() override; 1033 1034 void OutOverrideListTab(); 1035 void OutListNamesTab(); 1036 1037 void RestoreMacroCmds(); 1038 1039 void DoComboBox(css::uno::Reference<css::beans::XPropertySet> const & xPropSet); 1040 1041 public: 1042 1043 /// Setup the pA's info. 1044 virtual void SetupSectionPositions( WW8_PdAttrDesc* pA ) override; 1045 1046 bool MiserableFormFieldExportHack(const SwFrameFormat& rFrameFormat); 1047 GetOCXExp()1048 SwMSConvertControls& GetOCXExp() { return *m_pOCXExp; } 1049 void ExportDopTypography(WW8DopTypography &rTypo); 1050 1051 sal_uInt16 AddRedlineAuthor( std::size_t nId ); 1052 1053 void WriteFootnoteBegin( const SwFormatFootnote& rFootnote, ww::bytes* pO = nullptr ); 1054 void WritePostItBegin( ww::bytes* pO = nullptr ); 1055 const SvxBrushItem* GetCurrentPageBgBrush() const; 1056 std::shared_ptr<SvxBrushItem> TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const; 1057 1058 void AppendFlyInFlys(const ww8::Frame& rFrameFormat, const Point& rNdTopLeft); 1059 void WriteOutliner(const OutlinerParaObject& rOutliner, sal_uInt8 nTyp); 1060 void WriteSdrTextObj(const SdrTextObj& rObj, sal_uInt8 nTyp); 1061 1062 sal_uInt32 GetSdrOrdNum( const SwFrameFormat& rFormat ) const; 1063 void CreateEscher(); 1064 void WriteEscher(); 1065 1066 /// Write the field 1067 virtual void OutputField( const SwField* pField, ww::eField eFieldType, 1068 const OUString& rFieldCmd, FieldFlags nMode = FieldFlags::All ) override; 1069 1070 void StartCommentOutput( std::u16string_view rName ); 1071 void EndCommentOutput( std::u16string_view rName ); 1072 void OutGrf(const ww8::Frame &rFrame); 1073 bool TestOleNeedsGraphic(const SwAttrSet& rSet, tools::SvRef<SotStorage> const& xOleStg, 1074 const tools::SvRef<SotStorage>& xObjStg, OUString const& rStorageName, 1075 SwOLENode* pOLENd); 1076 1077 virtual void AppendBookmarks( const SwTextNode& rNd, sal_Int32 nCurrentPos, sal_Int32 nLen ) override; 1078 virtual void AppendBookmark( const OUString& rName ) override; 1079 void AppendBookmarkEndWithCorrection( const OUString& rName ); 1080 1081 virtual void AppendAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen ) override; 1082 1083 virtual void AppendSmartTags(SwTextNode& rTextNode) override; 1084 1085 virtual void ExportGrfBullet(const SwTextNode& rNd) override; 1086 void OutGrfBullets(const ww8::Frame &rFrame); 1087 1088 void MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo); 1089 1090 void WriteAsStringTable(const std::vector<OUString>&, sal_Int32& rfcSttbf, 1091 sal_Int32& rlcbSttbf); 1092 1093 virtual sal_uLong ReplaceCr( sal_uInt8 nChar ) override; 1094 1095 virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() ) override; 1096 void WriteChar( sal_Unicode c ) override; 1097 1098 void OutSwString(const OUString&, sal_Int32 nStt, sal_Int32 nLen); 1099 Fc2Cp(sal_uLong nFc) const1100 WW8_CP Fc2Cp( sal_uLong nFc ) const { return m_pPiece->Fc2Cp( nFc ); } 1101 1102 // some partly static semi-internal function declarations 1103 OutSprmBytes(sal_uInt8 * pBytes,sal_uInt16 nSiz)1104 void OutSprmBytes( sal_uInt8* pBytes, sal_uInt16 nSiz ) 1105 { pO->insert( pO->end(), pBytes, pBytes+nSiz ); } 1106 1107 virtual void SectionBreaksAndFrames( const SwTextNode& rNode ) override; 1108 1109 /// Helper method for OutputSectionBreaks() and OutputFollowPageDesc(). 1110 // #i76300# 1111 virtual void PrepareNewPageDesc( const SfxItemSet* pSet, 1112 const SwNode& rNd, 1113 const SwFormatPageDesc* pNewPgDescFormat, 1114 const SwPageDesc* pNewPgDesc, 1115 bool bExtraPageBreak = false ) override; 1116 1117 static void Out_BorderLine(ww::bytes& rO, const ::editeng::SvxBorderLine* pLine, 1118 sal_uInt16 nDist, sal_uInt16 nSprmNo, sal_uInt16 nSprmNoVer9, 1119 bool bShadow); 1120 1121 void Out_SwFormatBox(const SvxBoxItem& rBox, bool bShadow); 1122 static void Out_SwFormatTableBox( ww::bytes& rO, const SvxBoxItem * rBox ); 1123 void Out_CellRangeBorders(const SvxBoxItem * pBox, sal_uInt8 nStart, 1124 sal_uInt8 nLimit); 1125 static bool TransBrush(const Color& rCol, WW8_SHD& rShd); 1126 static WW8_BRCVer9 TranslateBorderLine(const ::editeng::SvxBorderLine& pLine, 1127 sal_uInt16 nDist, bool bShadow); 1128 1129 // #i77805# - new return value indicates, if an inherited outline numbering is suppressed 1130 virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) override; 1131 GetHdFtIndex() const1132 unsigned int GetHdFtIndex() const { return m_nHdFtIndex; } SetHdFtIndex(unsigned int nHdFtIndex)1133 void SetHdFtIndex(unsigned int nHdFtIndex) { m_nHdFtIndex = nHdFtIndex; } IncrementHdFtIndex()1134 void IncrementHdFtIndex() { ++m_nHdFtIndex; } 1135 1136 /** 1137 * Converts the SVX numbering type to MSONFC. 1138 * 1139 * This is used for section, footnote and endnote numbering purposes. 1140 */ 1141 static sal_uInt8 GetNumId( sal_uInt16 eNumType ); 1142 1143 /// Guess the script (asian/western). 1144 virtual bool CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich ) override; 1145 1146 SwTwips CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const; 1147 1148 /// Nasty swap for bidi if necessary 1149 void MiserableRTLFrameFormatHack(SwTwips &rLeft, SwTwips &rRight, 1150 const ww8::Frame &rFrameFormat); 1151 InsUInt16(sal_uInt16 n)1152 void InsUInt16( sal_uInt16 n ) { SwWW8Writer::InsUInt16( *pO, n ); } InsInt16(sal_Int16 n)1153 void InsInt16(sal_Int16 n) { InsUInt16(sal_uInt16(n)); } InsUInt32(sal_uInt32 n)1154 void InsUInt32( sal_uInt32 n ) { SwWW8Writer::InsUInt32( *pO, n ); } 1155 void WriteStringAsPara( const OUString& rText ); 1156 1157 /// Setup the exporter. 1158 WW8Export( SwWW8Writer *pWriter, 1159 SwDoc& rDocument, std::shared_ptr<SwUnoCursor> & pCurrentPam, SwPaM* pOriginalPam, 1160 bool bDot ); 1161 virtual ~WW8Export() override; 1162 1163 virtual void DoComboBox(const OUString &rName, 1164 const OUString &rHelp, 1165 const OUString &ToolTip, 1166 const OUString &rSelected, 1167 const css::uno::Sequence<OUString> &rListItems) override; 1168 1169 virtual void DoFormText(const SwInputField * pField) override; 1170 1171 void GetCurrentItems(ww::bytes &rItems) const; 1172 1173 /// Write the data of the form field 1174 virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) override; 1175 virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark& rFieldmark ) override; 1176 1177 /// Fields. 1178 WW8_WrPlcField* CurrentFieldPlc() const; 1179 GetWriter() const1180 SwWW8Writer& GetWriter() const { return *m_pWriter; } Strm() const1181 SvStream& Strm() const { return m_pWriter->Strm(); } 1182 1183 /// Remember some of the members so that we can recurse in WriteText(). 1184 virtual void SaveData( sal_uLong nStt, sal_uLong nEnd ) override; 1185 1186 /// Restore what was saved in SaveData(). 1187 virtual void RestoreData() override; 1188 1189 /// Output the actual headers and footers. 1190 virtual void WriteHeadersFooters( sal_uInt8 nHeadFootFlags, 1191 const SwFrameFormat& rFormat, const SwFrameFormat& rLeftHeaderFormat, const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& rFirstPageFormat, 1192 sal_uInt8 nBreakCode, bool bEvenAndOddHeaders) override; 1193 GetExportFormat() const1194 virtual ExportFormat GetExportFormat() const override { return ExportFormat::DOC; } 1195 1196 protected: 1197 /// Output SwGrfNode 1198 virtual void OutputGrfNode( const SwGrfNode& ) override; 1199 1200 /// Output SwOLENode 1201 virtual void OutputOLENode( const SwOLENode& ) override; 1202 1203 virtual void OutputLinkedOLE( const OUString& ) override; 1204 1205 virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum ) override; 1206 1207 private: 1208 WW8Export(const WW8Export&) = delete; 1209 WW8Export& operator=(const WW8Export&) = delete; 1210 }; 1211 1212 class WW8_WrPlcSubDoc // double Plc for Footnotes/Endnotes and Postits 1213 { 1214 private: 1215 WW8_WrPlcSubDoc(const WW8_WrPlcSubDoc&) = delete; 1216 WW8_WrPlcSubDoc& operator=(const WW8_WrPlcSubDoc&) = delete; 1217 protected: 1218 std::vector<WW8_CP> aCps; 1219 std::vector<const void*> aContent; // PTRARR of SwFormatFootnote/PostIts/.. 1220 std::vector<const SwFrameFormat*> aSpareFormats; // a backup for aContent: if there's no SdrObject, stores the fmt directly here 1221 std::unique_ptr<WW8_WrPlc0> pTextPos; // positions of the individual texts 1222 1223 WW8_WrPlcSubDoc(); 1224 virtual ~WW8_WrPlcSubDoc(); 1225 1226 bool WriteGenericText( WW8Export& rWrt, sal_uInt8 nTTyp, WW8_CP& rCount ); 1227 void WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp, WW8_FC& rTextStt, 1228 sal_Int32& rTextCnt, WW8_FC& rRefStt, sal_Int32& rRefCnt ) const; 1229 1230 virtual const std::vector<sal_uInt32>* GetShapeIdArr() const; 1231 }; 1232 1233 // double Plc for Footnotes/Endnotes 1234 class WW8_WrPlcFootnoteEdn : public WW8_WrPlcSubDoc 1235 { 1236 private: 1237 sal_uInt8 nTyp; 1238 1239 WW8_WrPlcFootnoteEdn(const WW8_WrPlcFootnoteEdn&) = delete; 1240 WW8_WrPlcFootnoteEdn& operator=(WW8_WrPlcFootnoteEdn const &) = delete; 1241 public: WW8_WrPlcFootnoteEdn(sal_uInt8 nTTyp)1242 explicit WW8_WrPlcFootnoteEdn( sal_uInt8 nTTyp ) : nTyp( nTTyp ) {} 1243 1244 bool WriteText( WW8Export& rWrt ); 1245 void WritePlc( WW8Export& rWrt ) const; 1246 1247 void Append( WW8_CP nCp, const SwFormatFootnote& rFootnote ); 1248 }; 1249 1250 struct WW8_Annotation 1251 { 1252 const OutlinerParaObject* mpRichText; 1253 OUString msSimpleText; 1254 OUString msOwner; 1255 OUString m_sInitials; 1256 DateTime maDateTime; 1257 WW8_CP m_nRangeStart, m_nRangeEnd; 1258 bool m_bIgnoreEmpty = true; 1259 WW8_Annotation(const SwPostItField* pPostIt, WW8_CP nRangeStart, WW8_CP nRangeEnd); 1260 explicit WW8_Annotation(const SwRedlineData* pRedline); 1261 /// An annotation has a range if start != end or the m_bIgnoreEmpty flag is cleared. 1262 bool HasRange() const; 1263 }; 1264 1265 class WW8_WrPlcAnnotations : public WW8_WrPlcSubDoc // double Plc for Postits 1266 { 1267 private: 1268 WW8_WrPlcAnnotations(const WW8_WrPlcAnnotations&) = delete; 1269 WW8_WrPlcAnnotations& operator=(WW8_WrPlcAnnotations const &) = delete; 1270 o3tl::sorted_vector<const SwRedlineData*> maProcessedRedlines; 1271 1272 std::map<const OUString, std::pair<WW8_CP, bool>> m_aRangeStartPositions; 1273 public: WW8_WrPlcAnnotations()1274 WW8_WrPlcAnnotations() {} 1275 virtual ~WW8_WrPlcAnnotations() override; 1276 1277 void AddRangeStartPosition(const OUString& rName, WW8_CP nStartCp, bool bIgnoreEmpty); 1278 void Append( WW8_CP nCp, const SwPostItField* pPostIt ); 1279 void Append( WW8_CP nCp, const SwRedlineData* pRedLine ); 1280 bool IsNewRedlineComment( const SwRedlineData* pRedLine ); 1281 bool WriteText( WW8Export& rWrt ); 1282 void WritePlc( WW8Export& rWrt ) const; 1283 }; 1284 1285 class WW8_WrPlcTextBoxes : public WW8_WrPlcSubDoc // double Plc for Textboxes 1286 { // Frame/DrawTextboxes! 1287 private: 1288 sal_uInt8 nTyp; 1289 std::vector<sal_uInt32> aShapeIds; // VARARR of ShapeIds for the SwFrameFormats 1290 virtual const std::vector<sal_uInt32>* GetShapeIdArr() const override; 1291 1292 WW8_WrPlcTextBoxes(const WW8_WrPlcTextBoxes&) = delete; 1293 WW8_WrPlcTextBoxes& operator=(WW8_WrPlcTextBoxes const &) = delete; 1294 public: WW8_WrPlcTextBoxes(sal_uInt8 nTTyp)1295 explicit WW8_WrPlcTextBoxes( sal_uInt8 nTTyp ) : nTyp( nTTyp ) {} 1296 1297 bool WriteText( WW8Export& rWrt ); 1298 void WritePlc( WW8Export& rWrt ) const; 1299 void Append( const SdrObject& rObj, sal_uInt32 nShapeId ); 1300 void Append( const SwFrameFormat* pFormat, sal_uInt32 nShapeId ); Count() const1301 sal_uInt16 Count() const { return aContent.size(); } GetPos(const void * p) const1302 sal_uInt16 GetPos( const void* p ) const 1303 { 1304 std::vector<const void*>::const_iterator it 1305 = std::find( aContent.begin(), aContent.end(), p ); 1306 return it == aContent.end() ? USHRT_MAX : it - aContent.begin(); 1307 } 1308 }; 1309 1310 class WW8_WrPlcPn // Plc for Page Numbers 1311 { 1312 private: 1313 WW8Export& rWrt; 1314 // Plc for Chpx and Papx ( incl PN-Plc ) 1315 std::vector<std::unique_ptr<WW8_WrFkp>> m_Fkps; 1316 sal_uInt16 nFkpStartPage; 1317 ePLCFT ePlc; 1318 1319 WW8_WrPlcPn(const WW8_WrPlcPn&) = delete; 1320 WW8_WrPlcPn& operator=(const WW8_WrPlcPn&) = delete; 1321 public: 1322 WW8_WrPlcPn( WW8Export& rWrt, ePLCFT ePl, WW8_FC nStartFc ); 1323 ~WW8_WrPlcPn(); 1324 void AppendFkpEntry(WW8_FC nEndFc,short nVarLen = 0,const sal_uInt8* pSprms = nullptr); 1325 void WriteFkps(); 1326 void WritePlc(); 1327 sal_uInt8 *CopyLastSprms(sal_uInt8 &rLen); 1328 }; 1329 1330 // class WW8_WrPlc1 is only used for fields 1331 class WW8_WrPlc1 1332 { 1333 private: 1334 std::vector<WW8_CP> aPos; 1335 std::unique_ptr<sal_uInt8[]> pData; // content ( structures ) 1336 sal_uLong nDataLen; 1337 sal_uInt16 nStructSiz; 1338 1339 WW8_WrPlc1(const WW8_WrPlc1&) = delete; 1340 WW8_WrPlc1& operator=(const WW8_WrPlc1&) = delete; 1341 protected: Count() const1342 sal_uInt16 Count() const { return aPos.size(); } 1343 void Write( SvStream& rStrm ); 1344 WW8_CP Prev() const; 1345 public: 1346 explicit WW8_WrPlc1( sal_uInt16 nStructSz ); 1347 ~WW8_WrPlc1(); 1348 void Append( WW8_CP nCp, const void* pData ); 1349 void Finish( sal_uLong nLastCp, sal_uLong nStartCp ); 1350 }; 1351 1352 // class WW8_WrPlcField is for fields 1353 class WW8_WrPlcField : public WW8_WrPlc1 1354 { 1355 private: 1356 sal_uInt8 nTextTyp; 1357 sal_uInt16 nResults; 1358 1359 WW8_WrPlcField(const WW8_WrPlcField&) = delete; 1360 WW8_WrPlcField& operator=(const WW8_WrPlcField&) = delete; 1361 public: WW8_WrPlcField(sal_uInt16 nStructSz,sal_uInt8 nTTyp)1362 WW8_WrPlcField( sal_uInt16 nStructSz, sal_uInt8 nTTyp ) 1363 : WW8_WrPlc1( nStructSz ), nTextTyp( nTTyp ), nResults(0) 1364 {} 1365 void Write( WW8Export& rWrt ); ResultAdded()1366 void ResultAdded() { ++nResults; } ResultCount() const1367 sal_uInt16 ResultCount() const { return nResults; } 1368 }; 1369 1370 class WW8_WrMagicTable : public WW8_WrPlc1 1371 { 1372 private: 1373 WW8_WrMagicTable(const WW8_WrMagicTable&) = delete; 1374 WW8_WrMagicTable& operator=(const WW8_WrMagicTable&) = delete; 1375 public: WW8_WrMagicTable()1376 WW8_WrMagicTable() : WW8_WrPlc1( 4 ) {Append(0,0);} 1377 void Append( WW8_CP nCp, sal_uLong nData ); 1378 void Write( WW8Export& rWrt ); 1379 }; 1380 1381 class GraphicDetails 1382 { 1383 public: 1384 ww8::Frame maFly; // surrounding FlyFrames 1385 sal_uLong mnPos; // FilePos of the graphics 1386 sal_uInt16 mnWid; // Width of the graphics 1387 sal_uInt16 mnHei; // Height of the graphics 1388 GraphicDetails(const ww8::Frame & rFly,sal_uInt16 nWid,sal_uInt16 nHei)1389 GraphicDetails(const ww8::Frame &rFly, sal_uInt16 nWid, sal_uInt16 nHei) 1390 : maFly(rFly), mnPos(0), mnWid(nWid), mnHei(nHei) 1391 {} 1392 operator ==(const GraphicDetails & rIn) const1393 bool operator==(const GraphicDetails& rIn) const 1394 { 1395 return ( 1396 (mnWid == rIn.mnWid) && (mnHei == rIn.mnHei) && 1397 (maFly.RefersToSameFrameAs(rIn.maFly)) 1398 ); 1399 } 1400 }; 1401 1402 // class SwWW8WrGrf collects graphics and issues them 1403 class SwWW8WrGrf 1404 { 1405 private: 1406 /// for access to the variables 1407 WW8Export& rWrt; 1408 1409 std::vector<GraphicDetails> maDetails; 1410 sal_uInt16 mnIdx; // index in file positions 1411 1412 static void WritePICFHeader(SvStream& rStrm, const ww8::Frame &rFly, 1413 sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight, 1414 const SwAttrSet* pAttrSet = nullptr); 1415 void WriteGraphicNode(SvStream& rStrm, const GraphicDetails &rItem); 1416 void WriteGrfFromGrfNode(SvStream& rStrm, const SwGrfNode &rNd, 1417 const ww8::Frame &rFly, sal_uInt16 nWidth, sal_uInt16 nHeight); 1418 1419 static void WritePICBulletFHeader(SvStream& rStrm, const Graphic &rGrf, sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight); 1420 void WriteGrfForBullet(SvStream& rStrm, const Graphic &rGrf, sal_uInt16 nWidth, sal_uInt16 nHeight); 1421 1422 SwWW8WrGrf(const SwWW8WrGrf&) = delete; 1423 SwWW8WrGrf& operator=(const SwWW8WrGrf&) = delete; 1424 public: SwWW8WrGrf(WW8Export & rW)1425 explicit SwWW8WrGrf( WW8Export& rW ) : rWrt( rW ), mnIdx( 0 ) {} 1426 void Insert(const ww8::Frame &rFly); 1427 void Write(); GetFPos()1428 sal_uLong GetFPos() 1429 { return (mnIdx < maDetails.size()) ? maDetails[mnIdx++].mnPos : 0; } 1430 }; 1431 1432 /** The class MSWordAttrIter is a helper class to build the Fkp.chpx. 1433 This is a base class to output the SwTextAttrs and the EditEngineTextAttrs. 1434 */ 1435 class MSWordAttrIter 1436 { 1437 private: 1438 MSWordAttrIter* pOld; 1439 MSWordAttrIter(const MSWordAttrIter&) = delete; 1440 MSWordAttrIter& operator=(const MSWordAttrIter&) = delete; 1441 protected: 1442 MSWordExportBase& m_rExport; 1443 public: 1444 explicit MSWordAttrIter( MSWordExportBase& rExport ); 1445 virtual ~MSWordAttrIter(); 1446 1447 virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const = 0; 1448 virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const = 0; 1449 }; 1450 1451 /// Used to export formatted text associated to drawings. 1452 class MSWord_SdrAttrIter : public MSWordAttrIter 1453 { 1454 private: 1455 const EditTextObject* pEditObj; 1456 const SfxItemPool* pEditPool; 1457 std::vector<EECharAttrib> aTextAtrArr; 1458 std::vector<const EECharAttrib*> aChrTextAtrArr; 1459 std::vector<rtl_TextEncoding> aChrSetArr; 1460 sal_Int32 nPara; 1461 sal_Int32 nCurrentSwPos; 1462 sal_Int32 nTmpSwPos; // for HasItem() 1463 rtl_TextEncoding eNdChrSet; 1464 sal_uInt16 nScript; 1465 sal_uInt8 mnTyp; 1466 1467 sal_Int32 SearchNext( sal_Int32 nStartPos ); 1468 void SetCharSet(const EECharAttrib& rTextAttr, bool bStart); 1469 1470 void SetItemsThatDifferFromStandard(bool bCharAttr, SfxItemSet& rSet); 1471 1472 MSWord_SdrAttrIter(const MSWord_SdrAttrIter&) = delete; 1473 MSWord_SdrAttrIter& operator=(const MSWord_SdrAttrIter&) = delete; 1474 public: 1475 MSWord_SdrAttrIter( MSWordExportBase& rWr, const EditTextObject& rEditObj, 1476 sal_uInt8 nType ); 1477 void NextPara( sal_Int32 nPar ); 1478 void OutParaAttr(bool bCharAttr, const std::set<sal_uInt16>* pWhichsToIgnore = nullptr); 1479 void OutEEField(const SfxPoolItem& rHt); 1480 1481 bool IsTextAttr(sal_Int32 nSwPos); 1482 NextPos()1483 void NextPos() { if ( nCurrentSwPos < SAL_MAX_INT32 ) nCurrentSwPos = SearchNext( nCurrentSwPos + 1 ); } 1484 1485 void OutAttr( sal_Int32 nSwPos ); 1486 virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const override; 1487 virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const override; WhereNext() const1488 sal_Int32 WhereNext() const { return nCurrentSwPos; } 1489 rtl_TextEncoding GetNextCharSet() const; GetNodeCharSet() const1490 rtl_TextEncoding GetNodeCharSet() const { return eNdChrSet; } 1491 }; 1492 1493 // class SwWW8AttrIter is a helper for constructing the Fkp.chpx. 1494 // Only character attributes are considered; paragraph attributes do not need this treatment. 1495 // The paragraph and text attributes of the Writer are passed, and 1496 // Where() returns the next position where the attributes change. 1497 // IsTextAtr() tells if, at the position returned by Where(), there is 1498 // an attribute without end and with \xff in the text. 1499 // Using OutAttr(), the attributes on the passed SwPos are returned. 1500 class SwWW8AttrIter : public MSWordAttrIter 1501 { 1502 private: 1503 const SwTextNode& rNd; 1504 1505 sw::util::CharRuns maCharRuns; 1506 sw::util::CharRuns::const_iterator maCharRunIter; 1507 1508 rtl_TextEncoding meChrSet; 1509 sal_uInt16 mnScript; 1510 bool mbCharIsRTL; 1511 1512 const SwRangeRedline* pCurRedline; 1513 sal_Int32 nCurrentSwPos; 1514 SwRedlineTable::size_type nCurRedlinePos; 1515 1516 bool mbParaIsRTL; 1517 1518 const SwFormatDrop &mrSwFormatDrop; 1519 1520 ww8::Frames maFlyFrames; // #i2916# 1521 ww8::FrameIter maFlyIter; 1522 1523 sal_Int32 SearchNext( sal_Int32 nStartPos ); 1524 1525 void OutSwFormatRefMark(const SwFormatRefMark& rAttr); 1526 1527 void IterToCurrent(); 1528 1529 SwWW8AttrIter(const SwWW8AttrIter&) = delete; 1530 SwWW8AttrIter& operator=(const SwWW8AttrIter&) = delete; 1531 1532 void handleToggleProperty(SfxItemSet& rExportSet, const SwFormatCharFormat* pCharFormatItem, sal_uInt16 nWhich, const SfxPoolItem* pValue); 1533 public: 1534 SwWW8AttrIter( MSWordExportBase& rWr, const SwTextNode& rNd ); 1535 1536 bool IsTextAttr( sal_Int32 nSwPos ) const; 1537 bool IsExportableAttr(sal_Int32 nSwPos) const; 1538 bool IncludeEndOfParaCRInRedlineProperties(sal_Int32 nPos) const; 1539 bool IsDropCap( int nSwPos ); 1540 bool RequiresImplicitBookmark(); 1541 NextPos()1542 void NextPos() { if ( nCurrentSwPos < SAL_MAX_INT32 ) nCurrentSwPos = SearchNext( nCurrentSwPos + 1 ); } 1543 1544 void OutAttr(sal_Int32 nSwPos, bool bWriteCombinedChars, bool bPostponeSingleUse = false); 1545 virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const override; 1546 virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const override; 1547 int OutAttrWithRange(const SwTextNode& rNode, sal_Int32 nPos); 1548 const SwRedlineData* GetParagraphLevelRedline( ); 1549 const SwRedlineData* GetRunLevelRedline( sal_Int32 nPos ); 1550 FlyProcessingState OutFlys(sal_Int32 nSwPos); 1551 bool HasFlysAt(sal_Int32 nSwPos) const; 1552 WhereNext() const1553 sal_Int32 WhereNext() const { return nCurrentSwPos; } GetScript() const1554 sal_uInt16 GetScript() const { return mnScript; } IsParaRTL() const1555 bool IsParaRTL() const { return mbParaIsRTL; } GetCharSet() const1556 rtl_TextEncoding GetCharSet() const { return meChrSet; } 1557 OUString GetSnippet(const OUString &rStr, sal_Int32 nCurrentPos, 1558 sal_Int32 nLen) const; GetSwFormatDrop() const1559 const SwFormatDrop& GetSwFormatDrop() const { return mrSwFormatDrop; } 1560 1561 bool IsWatermarkFrame(); 1562 bool IsAnchorLinkedToThisNode( sal_uLong nNodePos ); 1563 1564 void SplitRun( sal_Int32 nSplitEndPos ); 1565 GetNode() const1566 const SwTextNode& GetNode() const { return rNd; } 1567 }; 1568 1569 /// Class to collect and output the styles table. 1570 class MSWordStyles 1571 { 1572 MSWordExportBase& m_rExport; 1573 sal_uInt16 m_aHeadingParagraphStyles[MAXLEVEL]; 1574 std::vector<SwFormat*> m_aFormatA; ///< Slot <-> Character and paragraph style array (0 for list styles). 1575 sal_uInt16 m_nUsedSlots; 1576 bool m_bListStyles; ///< If list styles are requested to be exported as well. 1577 std::map<sal_uInt16, const SwNumRule*> m_aNumRules; ///< Slot <-> List style map. 1578 1579 /// We need to build style id's for DOCX export; ideally we should roundtrip that, but this is good enough. 1580 std::vector<OString> m_aStyleIds; 1581 1582 /// Create the style table, called from the constructor. 1583 void BuildStylesTable(); 1584 1585 /// Based on pFormatA, fill in m_aStyleIds with unique, MS-like names. 1586 void BuildStyleIds(); 1587 1588 /// Get slot number during building the style table. 1589 sal_uInt16 BuildGetSlot( const SwFormat& rFormat ); BuildGetSlot(const SwNumRule &)1590 sal_uInt16 BuildGetSlot( const SwNumRule& /*rNumRule*/ ) { return m_nUsedSlots++;} 1591 1592 /// Return information about one style. 1593 void GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& nBase, sal_uInt16& nNext ); 1594 1595 /// Outputs attributes of one style. 1596 void WriteProperties( const SwFormat* pFormat, bool bPap, sal_uInt16 nPos, bool bInsDefCharSiz ); 1597 1598 static sal_uInt16 GetWWId( const SwFormat& rFormat ); 1599 1600 void SetStyleDefaults( const SwFormat& rFormat, bool bPap ); 1601 1602 /// Outputs one style - called (in a loop) from OutputStylesTable(). 1603 void OutputStyle( SwFormat* pFormat, sal_uInt16 nPos ); 1604 void OutputStyle( const SwNumRule* pNumRule, sal_uInt16 nPos ); 1605 1606 MSWordStyles( const MSWordStyles& ) = delete; 1607 MSWordStyles& operator=( const MSWordStyles& ) = delete; 1608 1609 public: 1610 MSWordStyles( MSWordExportBase& rExport, bool bListStyles = false ); 1611 ~MSWordStyles(); 1612 1613 /// Output the styles table. 1614 void OutputStylesTable(); 1615 1616 /// Get id of the style (rFormat). 1617 sal_uInt16 GetSlot( const SwFormat* pFormat ) const; 1618 1619 /// create style id using only ASCII characters of the style name 1620 static OString CreateStyleId(const OUString &rName); 1621 1622 /// Get styleId of the nId-th style (nId is its position in pFormatA). 1623 OString const & GetStyleId(sal_uInt16 nId) const; 1624 GetSwFormat(sal_uInt16 nId) const1625 const SwFormat* GetSwFormat(sal_uInt16 nId) const { return m_aFormatA[nId]; } 1626 /// Get numbering rule of the nId-th style 1627 const SwNumRule* GetSwNumRule(sal_uInt16 nId) const; GetHeadingParagraphStyleId(sal_uInt16 nLevel) const1628 sal_uInt16 GetHeadingParagraphStyleId(sal_uInt16 nLevel) const { return m_aHeadingParagraphStyles[ nLevel ]; } 1629 }; 1630 1631 #define MSWORD_MAX_STYLES_LIMIT 4091 1632 1633 sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat); 1634 // A bit of a bag on the side for now 1635 OUString FieldString(ww::eField eIndex); 1636 OUString BookmarkToWord(const OUString &rBookmark); 1637 1638 class WW8SHDLong 1639 { 1640 sal_uInt32 m_cvFore; 1641 sal_uInt32 m_cvBack; 1642 1643 public: WW8SHDLong()1644 WW8SHDLong() : m_cvFore(0), m_cvBack(0) {} 1645 1646 void Write(WW8Export & rExport); setCvFore(sal_uInt32 cvFore)1647 void setCvFore(sal_uInt32 cvFore) { m_cvFore = cvFore; } setCvBack(sal_uInt32 cvBack)1648 void setCvBack(sal_uInt32 cvBack) { m_cvBack = cvBack; } 1649 }; 1650 1651 #endif // INCLUDED_SW_SOURCE_FILTER_WW8_WRTWW8_HXX 1652 1653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1654