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