LibreOffice Module sw (master)  1
wrtw8nds.cxx
Go to the documentation of this file.
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 #include <vector>
21 #include <list>
22 #include <utility>
23 #include <algorithm>
24 #include <iostream>
25 
26 #include <oox/core/filterbase.hxx>
27 #include "docxexport.hxx"
28 #include "docxexportfilter.hxx"
29 
30 #include <i18nlangtag/mslangid.hxx>
31 #include <hintids.hxx>
32 #include <tools/urlobj.hxx>
33 #include <editeng/boxitem.hxx>
34 #include <editeng/cmapitem.hxx>
35 #include <editeng/langitem.hxx>
36 #include <editeng/svxfont.hxx>
37 #include <editeng/lrspitem.hxx>
38 #include <editeng/brushitem.hxx>
39 #include <editeng/fontitem.hxx>
40 #include <editeng/keepitem.hxx>
41 #include <editeng/fhgtitem.hxx>
42 #include <editeng/ulspitem.hxx>
44 #include <editeng/frmdiritem.hxx>
45 #include <editeng/tstpitem.hxx>
46 #include <svl/grabbagitem.hxx>
47 #include <svl/urihelper.hxx>
48 #include <svl/whiter.hxx>
49 #include <fmtpdsc.hxx>
50 #include <fmtfsize.hxx>
51 #include <fmtornt.hxx>
52 #include <fmtlsplt.hxx>
53 #include <fmtflcnt.hxx>
54 #include <fmtanchr.hxx>
55 #include <fmtcntnt.hxx>
56 #include <frmatr.hxx>
57 #include <paratr.hxx>
58 #include <txatbase.hxx>
59 #include <fmtinfmt.hxx>
60 #include <fmtrfmrk.hxx>
61 #include <fchrfmt.hxx>
62 #include <fmtautofmt.hxx>
63 #include <charfmt.hxx>
64 #include <tox.hxx>
65 #include <ndtxt.hxx>
66 #include <pam.hxx>
67 #include <doc.hxx>
69 #include <IDocumentMarkAccess.hxx>
70 #include <docary.hxx>
71 #include <swtable.hxx>
72 #include <swtblfmt.hxx>
73 #include <section.hxx>
74 #include <pagedesc.hxx>
75 #include <swrect.hxx>
76 #include <reffld.hxx>
77 #include <redline.hxx>
78 #include <wrtswtbl.hxx>
79 #include <htmltbl.hxx>
80 #include <txttxmrk.hxx>
81 #include <fmtline.hxx>
82 #include <fmtruby.hxx>
83 #include <breakit.hxx>
84 #include <txtatr.hxx>
85 #include <fmtsrnd.hxx>
86 #include <fmtrowsplt.hxx>
87 #include <com/sun/star/drawing/XShape.hpp>
88 #include <com/sun/star/i18n/BreakIterator.hpp>
89 #include <com/sun/star/i18n/ScriptType.hpp>
90 #include <com/sun/star/i18n/WordType.hpp>
91 #include <com/sun/star/text/RubyPosition.hpp>
92 #include <oox/export/vmlexport.hxx>
93 #include <sfx2/docfile.hxx>
94 #include <sal/log.hxx>
96 
97 #include "sprmids.hxx"
98 
99 #include "writerhelper.hxx"
100 #include "writerwordglue.hxx"
101 #include <numrule.hxx>
102 #include "wrtww8.hxx"
103 #include "ww8par.hxx"
104 #include <IMark.hxx>
105 #include "ww8attributeoutput.hxx"
106 
107 #include <ndgrf.hxx>
108 #include <ndole.hxx>
109 
110 #include <cstdio>
111 
112 using namespace ::com::sun::star;
113 using namespace ::com::sun::star::i18n;
114 using namespace sw::util;
115 using namespace sw::types;
116 using namespace sw::mark;
117 using namespace ::oox::vml;
118 
119 static OUString lcl_getFieldCode( const IFieldmark* pFieldmark )
120 {
121  assert(pFieldmark);
122 
123  if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
124  return " FORMTEXT ";
125  if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN )
126  return " FORMDROPDOWN ";
127  if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX )
128  return " FORMCHECKBOX ";
129  if ( pFieldmark->GetFieldname( ) == ODF_FORMDATE )
130  return " ODFFORMDATE ";
131  if ( pFieldmark->GetFieldname( ) == ODF_TOC )
132  return " TOC ";
133  if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
134  return " HYPERLINK ";
135  if ( pFieldmark->GetFieldname( ) == ODF_PAGEREF )
136  return " PAGEREF ";
137  return pFieldmark->GetFieldname();
138 }
139 
140 static ww::eField lcl_getFieldId(const IFieldmark*const pFieldmark)
141 {
142  assert(pFieldmark);
143 
144  if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
145  return ww::eFORMTEXT;
146  if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN )
147  return ww::eFORMDROPDOWN;
148  if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX )
149  return ww::eFORMCHECKBOX;
150  if ( pFieldmark->GetFieldname( ) == ODF_FORMDATE )
151  return ww::eFORMDATE;
152  if ( pFieldmark->GetFieldname( ) == ODF_TOC )
153  return ww::eTOC;
154  if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
155  return ww::eHYPERLINK;
156  if ( pFieldmark->GetFieldname( ) == ODF_PAGEREF )
157  return ww::ePAGEREF;
158  return ww::eUNKNOWN;
159 }
160 
162  : pOld( rExport.m_pChpIter ), m_rExport( rExport )
163 {
164  m_rExport.m_pChpIter = this;
165 }
166 
168 {
170 }
171 
173 {
174 public:
175  bool operator()(const ww8::Frame &rOne, const ww8::Frame &rTwo) const
176  {
177  return rOne.GetPosition() < rTwo.GetPosition();
178  }
179 };
180 
182 {
183  OSL_ENSURE(maCharRuns.begin() != maCharRuns.end(), "Impossible");
184  mnScript = maCharRunIter->mnScript;
185  meChrSet = maCharRunIter->meCharSet;
186  mbCharIsRTL = maCharRunIter->mbRTL;
187 }
188 
190  MSWordAttrIter(rWr),
191  rNd(rTextNd),
192  maCharRuns(GetPseudoCharRuns(rTextNd)),
193  pCurRedline(nullptr),
194  nCurrentSwPos(0),
195  nCurRedlinePos(SwRedlineTable::npos),
196  mrSwFormatDrop(rTextNd.GetSwAttrSet().GetDrop())
197 {
198 
199  SwPosition aPos(rTextNd);
200  mbParaIsRTL = SvxFrameDirection::Horizontal_RL_TB == rWr.m_pDoc->GetTextDirection(aPos);
201 
202  maCharRunIter = maCharRuns.begin();
203  IterToCurrent();
204 
205  /*
206  #i2916#
207  Get list of any graphics which may be anchored from this paragraph.
208  */
210  std::sort(maFlyFrames.begin(), maFlyFrames.end(), sortswflys());
211 
212  /*
213  #i18480#
214  If we are inside a frame then anything anchored inside this frame can
215  only be supported by word anchored inline ("as character"), so force
216  this in the supportable case.
217  */
218  if (rWr.m_bInWriteEscher)
219  {
220  for ( auto& aFlyFrame : maFlyFrames )
221  aFlyFrame.ForceTreatAsInline();
222  }
223 
224  maFlyIter = maFlyFrames.begin();
225 
227  {
228  SwPosition aPosition( rNd, SwIndex( const_cast<SwTextNode*>(&rNd) ) );
230  }
231 
233 }
234 
235 static sal_Int32 lcl_getMinPos( sal_Int32 pos1, sal_Int32 pos2 )
236 {
237  if ( pos1 >= 0 && pos2 >= 0 )
238  {
239  // both valid: return minimum one
240  return std::min(pos1, pos2);
241  }
242 
243  // return the valid one, if any, or -1
244  return std::max(pos1, pos2);
245 }
246 
247 sal_Int32 SwWW8AttrIter::SearchNext( sal_Int32 nStartPos )
248 {
249  const OUString aText = rNd.GetText();
250  sal_Int32 fieldEndPos = aText.indexOf(CH_TXT_ATR_FIELDEND, nStartPos - 1);
251  // HACK: for (so far) mysterious reasons the sdtContent element closes
252  // too late in testDateFormField() unless an empty run is exported at
253  // the end of the fieldmark; hence find *also* the position after the
254  // CH_TXT_ATR_FIELDEND here
255  if (0 <= fieldEndPos && fieldEndPos < nStartPos)
256  {
257  ++fieldEndPos;
258  }
259  sal_Int32 fieldSepPos = aText.indexOf(CH_TXT_ATR_FIELDSEP, nStartPos);
260  sal_Int32 fieldStartPos = aText.indexOf(CH_TXT_ATR_FIELDSTART, nStartPos);
261  sal_Int32 formElementPos = aText.indexOf(CH_TXT_ATR_FORMELEMENT, nStartPos);
262 
263  const sal_Int32 pos = lcl_getMinPos(
264  lcl_getMinPos(lcl_getMinPos(fieldEndPos, fieldSepPos), fieldStartPos),
265  formElementPos );
266 
267  sal_Int32 nMinPos = (pos>=0) ? pos : SAL_MAX_INT32;
268 
269  // first the redline, then the attributes
270  if( pCurRedline )
271  {
272  const SwPosition* pEnd = pCurRedline->End();
273  if (pEnd->nNode == rNd)
274  {
275  const sal_Int32 i = pEnd->nContent.GetIndex();
276  if ( i >= nStartPos && i < nMinPos )
277  {
278  nMinPos = i;
279  }
280  }
281  }
282 
283  if ( nCurRedlinePos < m_rExport.m_pDoc->getIDocumentRedlineAccess().GetRedlineTable().size() )
284  {
285  // nCurRedlinePos point to the next redline
287  if( pCurRedline )
288  ++nRedLinePos;
289 
290  for ( ; nRedLinePos < m_rExport.m_pDoc->getIDocumentRedlineAccess().GetRedlineTable().size(); ++nRedLinePos )
291  {
292  const SwRangeRedline* pRedl = m_rExport.m_pDoc->getIDocumentRedlineAccess().GetRedlineTable()[ nRedLinePos ];
293 
294  const SwPosition* pStt = pRedl->Start();
295  const SwPosition* pEnd = pStt == pRedl->GetPoint()
296  ? pRedl->GetMark()
297  : pRedl->GetPoint();
298 
299  if( pStt->nNode == rNd )
300  {
301  const sal_Int32 i = pStt->nContent.GetIndex();
302  if( i >= nStartPos && i < nMinPos )
303  nMinPos = i;
304  }
305  else
306  break;
307 
308  if( pEnd->nNode == rNd )
309  {
310  const sal_Int32 i = pEnd->nContent.GetIndex();
311  if( i >= nStartPos && i < nMinPos )
312  {
313  nMinPos = i;
314  }
315  }
316  }
317  }
318 
319  if (mrSwFormatDrop.GetWholeWord() && nStartPos <= rNd.GetDropLen(0))
320  nMinPos = rNd.GetDropLen(0);
321  else if(nStartPos <= mrSwFormatDrop.GetChars())
322  nMinPos = mrSwFormatDrop.GetChars();
323 
324  if(const SwpHints* pTextAttrs = rNd.GetpSwpHints())
325  {
326 
327 // can be optimized if we consider that the TextAttrs are sorted by start position.
328 // but then we'd have to save 2 indices
329  for( size_t i = 0; i < pTextAttrs->Count(); ++i )
330  {
331  const SwTextAttr* pHt = pTextAttrs->Get(i);
332  sal_Int32 nPos = pHt->GetStart(); // first Attr characters
333  if( nPos >= nStartPos && nPos <= nMinPos )
334  nMinPos = nPos;
335 
336  if( pHt->End() ) // Attr with end
337  {
338  nPos = *pHt->End(); // last Attr character + 1
339  if( nPos >= nStartPos && nPos <= nMinPos )
340  nMinPos = nPos;
341  }
342  if (pHt->HasDummyChar())
343  {
344  // pos + 1 because of CH_TXTATR in Text
345  nPos = pHt->GetStart() + 1;
346  if( nPos >= nStartPos && nPos <= nMinPos )
347  nMinPos = nPos;
348  }
349  }
350  }
351 
352  if (maCharRunIter != maCharRuns.end())
353  {
354  if (maCharRunIter->mnEndPos < nMinPos)
355  nMinPos = maCharRunIter->mnEndPos;
356  IterToCurrent();
357  }
358 
359  /*
360  #i2916#
361  Check to see if there are any graphics anchored to characters in this
362  paragraph's text. Set nMinPos to 1 past the placement for anchored to
363  character because anchors in Word appear after the character they are
364  anchored to.
365  */
366  if (maFlyIter != maFlyFrames.end())
367  {
368  const SwPosition &rAnchor = maFlyIter->GetPosition();
369 
370  sal_Int32 nPos = rAnchor.nContent.GetIndex();
371  if (nPos >= nStartPos && nPos <= nMinPos)
372  nMinPos = nPos;
373 
374  if (maFlyIter->GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR)
375  {
376  ++nPos;
377  if (nPos >= nStartPos && nPos <= nMinPos)
378  nMinPos = nPos;
379  }
380  }
381 
382  //nMinPos found and not going to change at this point
383 
384  if (maCharRunIter != maCharRuns.end())
385  {
386  if (maCharRunIter->mnEndPos == nMinPos)
387  ++maCharRunIter;
388  }
389 
390  return nMinPos;
391 }
392 
393 void SwWW8AttrIter::OutAttr( sal_Int32 nSwPos, bool bWriteCombChars)
394 {
396 
397  /*
398  Depending on whether text is in CTL/CJK or Western, get the id of that
399  script, the idea is that the font that is actually in use to render this
400  range of text ends up in pFont
401  */
402  sal_uInt16 nFontId = GetWhichOfScript( RES_CHRATR_FONT, GetScript() );
403 
404  const SvxFontItem &rParentFont = ItemGet<SvxFontItem>(
405  static_cast<const SwTextFormatColl&>(rNd.GetAnyFormatColl()), nFontId);
406  const SvxFontItem *pFont = &rParentFont;
407  const SfxPoolItem *pGrabBag = nullptr;
408 
409  SfxItemSet aExportSet(*rNd.GetSwAttrSet().GetPool(),
411 
412  //The hard formatting properties that affect the entire paragraph
413  if (rNd.HasSwAttrSet())
414  {
415  // only copy hard attributes - bDeep = false
416  aExportSet.Set(rNd.GetSwAttrSet(), false/*bDeep*/);
417  // get the current font item. Use rNd.GetSwAttrSet instead of aExportSet:
418  const SvxFontItem &rNdFont = ItemGet<SvxFontItem>(rNd.GetSwAttrSet(), nFontId);
419  pFont = &rNdFont;
420  aExportSet.ClearItem(nFontId);
421  }
422 
423  //The additional hard formatting properties that affect this range in the
424  //paragraph
425  ww8::PoolItems aRangeItems;
426  if (const SwpHints* pTextAttrs = rNd.GetpSwpHints())
427  {
428  for( size_t i = 0; i < pTextAttrs->Count(); ++i )
429  {
430  const SwTextAttr* pHt = pTextAttrs->Get(i);
431  const sal_Int32* pEnd = pHt->End();
432 
433  if (pEnd ? ( nSwPos >= pHt->GetStart() && nSwPos < *pEnd)
434  : nSwPos == pHt->GetStart() )
435  {
436  sal_uInt16 nWhich = pHt->GetAttr().Which();
437  if (nWhich == RES_TXTATR_AUTOFMT)
438  {
439  const SwFormatAutoFormat& rAutoFormat = static_cast<const SwFormatAutoFormat&>(pHt->GetAttr());
440  const std::shared_ptr<SfxItemSet>& pSet = rAutoFormat.GetStyleHandle();
441  SfxWhichIter aIter( *pSet );
442  const SfxPoolItem* pItem;
443  sal_uInt16 nWhichId = aIter.FirstWhich();
444  while( nWhichId )
445  {
446  if( SfxItemState::SET == pSet->GetItemState( nWhichId, false, &pItem ))
447  {
448  if (nWhichId == nFontId)
449  pFont = &(item_cast<SvxFontItem>(*pItem));
450  else if (nWhichId == RES_CHRATR_GRABBAG)
451  pGrabBag = pItem;
452  else
453  aRangeItems[nWhichId] = pItem;
454  }
455  nWhichId = aIter.NextWhich();
456  }
457  }
458  else
459  aRangeItems[nWhich] = (&(pHt->GetAttr()));
460  }
461  else if (nSwPos < pHt->GetStart())
462  break;
463  }
464  }
465 
466  /*
467  For #i24291# we need to explicitly remove any properties from the
468  aExportSet which a SwCharFormat would override, we can't rely on word doing
469  this for us like writer does
470  */
471  const SwFormatCharFormat *pCharFormatItem =
472  HasItem< SwFormatCharFormat >( aRangeItems, RES_TXTATR_CHARFMT );
473  if ( pCharFormatItem )
474  ClearOverridesFromSet( *pCharFormatItem, aExportSet );
475 
476  // tdf#113790: AutoFormat style overwrites char style, so remove all
477  // elements from CHARFMT grab bag which are set in AUTOFMT grab bag
478  if (const SfxGrabBagItem *pAutoFmtGrabBag = dynamic_cast<const SfxGrabBagItem*>(pGrabBag))
479  {
480  if (const SfxGrabBagItem *pCharFmtGrabBag = aExportSet.GetItem<SfxGrabBagItem>(RES_CHRATR_GRABBAG, false))
481  {
482  std::unique_ptr<SfxGrabBagItem> pNewCharFmtGrabBag(static_cast<SfxGrabBagItem*>(pCharFmtGrabBag->Clone()));
483  assert(pNewCharFmtGrabBag);
484  auto & rNewFmtMap = pNewCharFmtGrabBag->GetGrabBag();
485  for (auto const & item : pAutoFmtGrabBag->GetGrabBag())
486  {
487  if (item.second.hasValue())
488  rNewFmtMap.erase(item.first);
489  }
490  aExportSet.Put(std::move(pNewCharFmtGrabBag));
491  }
492  }
493 
494  ww8::PoolItems aExportItems;
495  GetPoolItems( aExportSet, aExportItems, false );
496 
497  if( rNd.GetpSwpHints() == nullptr )
498  m_rExport.SetCurItemSet(&aExportSet);
499 
500  for ( const auto& aRangeItem : aRangeItems )
501  {
502  aExportItems[aRangeItem.first] = aRangeItem.second;
503  }
504 
505  if ( !aExportItems.empty() )
506  {
507  const SwModify* pOldMod = m_rExport.m_pOutFormatNode;
509  m_rExport.m_aCurrentCharPropStarts.push( nSwPos );
510 
511  // tdf#38778 Fix output of the font in DOC run for fields
512  const SvxFontItem * pFontToOutput = ( rParentFont != *pFont )? pFont : nullptr;
513 
514  m_rExport.ExportPoolItemsToCHP( aExportItems, GetScript(), pFontToOutput, bWriteCombChars );
515 
516  // HasTextItem only allowed in the above range
518  m_rExport.m_pOutFormatNode = pOldMod;
519  }
520 
521  if( rNd.GetpSwpHints() == nullptr )
522  m_rExport.SetCurItemSet(nullptr);
523 
524  OSL_ENSURE( pFont, "must be *some* font associated with this txtnode" );
525  if ( pFont )
526  {
527  SvxFontItem aFont( *pFont );
528 
529  if ( rParentFont != aFont )
530  m_rExport.AttrOutput().OutputItem( aFont );
531  }
532 
533  // Output grab bag attributes
534  if (pGrabBag)
535  m_rExport.AttrOutput().OutputItem( *pGrabBag );
536 }
537 
539 {
540  if (maFlyFrames.size() != 1)
541  return false;
542 
543  while ( maFlyIter != maFlyFrames.end() )
544  {
545  const SdrObject* pSdrObj = maFlyIter->GetFrameFormat().FindRealSdrObject();
546 
547  if (pSdrObj)
548  {
549  if (VMLExport::IsWaterMarkShape(pSdrObj->GetName()))
550  return true;
551  }
552  ++maFlyIter;
553  }
554 
555  return false;
556 }
557 
559 {
560  ww8::FrameIter aTmpFlyIter = maFlyIter ;
561 
562  while ( aTmpFlyIter != maFlyFrames.end() )
563  {
564  const SwPosition &rAnchor = maFlyIter->GetPosition();
565  sal_uLong nAnchorPos = rAnchor.nNode.GetIndex();
566  /* if current node position and the anchor position are the same
567  then the frame anchor is linked to this node
568  */
569  if ( nAnchorPos == nNodePos )
570  return true ;
571 
572  ++aTmpFlyIter;
573  }
574  return false ;
575 }
576 
577 bool SwWW8AttrIter::HasFlysAt(sal_Int32 nSwPos) const
578 {
579  for (const auto& rFly : maFlyFrames)
580  {
581  const SwPosition& rAnchor = rFly.GetPosition();
582  const sal_Int32 nPos = rAnchor.nContent.GetIndex();
583  if (nPos == nSwPos)
584  {
585  return true;
586  }
587  }
588 
589  return false;
590 }
591 
593 {
594  // collection point to first gather info about all of the potentially linked textboxes: to be analyzed later.
595  OUString sLinkChainName;
596  ww8::FrameIter linkedTextboxesIter = maFlyIter;
597  while ( linkedTextboxesIter != maFlyFrames.end() )
598  {
599  uno::Reference< drawing::XShape > xShape;
600  ww8::Frame aFrame = *linkedTextboxesIter;
601  const SdrObject* pSdrObj = aFrame.GetFrameFormat().FindRealSdrObject();
602  if( pSdrObj )
603  xShape.set(const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY);
604  uno::Reference< beans::XPropertySet > xPropertySet(xShape, uno::UNO_QUERY);
605  uno::Reference< beans::XPropertySetInfo > xPropertySetInfo;
606  if( xPropertySet.is() )
607  xPropertySetInfo = xPropertySet->getPropertySetInfo();
608  if( xPropertySetInfo.is() )
609  {
610  MSWordExportBase::LinkedTextboxInfo aLinkedTextboxInfo;
611 
612  if( xPropertySetInfo->hasPropertyByName("LinkDisplayName") )
613  xPropertySet->getPropertyValue("LinkDisplayName") >>= sLinkChainName;
614  else if( xPropertySetInfo->hasPropertyByName("ChainName") )
615  xPropertySet->getPropertyValue("ChainName") >>= sLinkChainName;
616 
617  if( xPropertySetInfo->hasPropertyByName("ChainNextName") )
618  xPropertySet->getPropertyValue("ChainNextName") >>= aLinkedTextboxInfo.sNextChain;
619  if( xPropertySetInfo->hasPropertyByName("ChainPrevName") )
620  xPropertySet->getPropertyValue("ChainPrevName") >>= aLinkedTextboxInfo.sPrevChain;
621 
622  //collect a list of linked textboxes: those with a NEXT or PREVIOUS link
623  if( !aLinkedTextboxInfo.sNextChain.isEmpty() || !aLinkedTextboxInfo.sPrevChain.isEmpty() )
624  {
625  assert( !sLinkChainName.isEmpty() );
626 
627  //there are many discarded duplicates in documents - no duplicates allowed in the list, so try to find the real one.
628  //if this LinkDisplayName/ChainName already exists on a different shape...
629  // the earlier processed duplicates are thrown out unless this one can be proved as bad. (last processed duplicate usually is stored)
630  auto linkFinder = m_rExport.m_aLinkedTextboxesHelper.find(sLinkChainName);
631  if( linkFinder != m_rExport.m_aLinkedTextboxesHelper.end() )
632  {
633  //If my NEXT/PREV targets have already been discovered, but don't match me, then assume I'm an abandoned remnant
634  // (this logic fails if both me and one of my links are duplicated, and the remnants were added first.)
635  linkFinder = m_rExport.m_aLinkedTextboxesHelper.find(aLinkedTextboxInfo.sNextChain);
636  if( (linkFinder != m_rExport.m_aLinkedTextboxesHelper.end()) && (linkFinder->second.sPrevChain != sLinkChainName) )
637  {
638  ++linkedTextboxesIter;
639  break;
640  }
641 
642  linkFinder = m_rExport.m_aLinkedTextboxesHelper.find(aLinkedTextboxInfo.sPrevChain);
643  if( (linkFinder != m_rExport.m_aLinkedTextboxesHelper.end()) && (linkFinder->second.sNextChain != sLinkChainName) )
644  {
645  ++linkedTextboxesIter;
646  break;
647  }
648  }
650  m_rExport.m_aLinkedTextboxesHelper[sLinkChainName] = aLinkedTextboxInfo;
651  }
652  }
653  ++linkedTextboxesIter;
654  }
655 
656  /*
657  #i2916#
658  May have an anchored graphic to be placed, loop through sorted array
659  and output all at this position
660  */
661  while ( maFlyIter != maFlyFrames.end() )
662  {
663  const SwPosition &rAnchor = maFlyIter->GetPosition();
664  const sal_Int32 nPos = rAnchor.nContent.GetIndex();
665 
666  if ( nPos != nSwPos )
667  return FLY_NOT_PROCESSED ; // We haven't processed the fly
668 
669  const SdrObject* pSdrObj = maFlyIter->GetFrameFormat().FindRealSdrObject();
670 
671  if (pSdrObj)
672  {
673  if (VMLExport::IsWaterMarkShape(pSdrObj->GetName()))
674  {
675  // This is a watermark object. Should be written ONLY in the header
677  {
678  // Should write a watermark in the header
680  }
681  else
682  {
683  // Should not write watermark object in the main body text
684  }
685  }
686  else
687  {
688  // This is not a watermark object - write normally
690  }
691  }
692  else
693  {
694  // This is not a watermark object - write normally
696  }
697  ++maFlyIter;
698  }
700 }
701 
702 bool SwWW8AttrIter::IsTextAttr( sal_Int32 nSwPos ) const
703 {
704  // search for attrs with dummy character or content
705  if (const SwpHints* pTextAttrs = rNd.GetpSwpHints())
706  {
707  for (size_t i = 0; i < pTextAttrs->Count(); ++i)
708  {
709  const SwTextAttr* pHt = pTextAttrs->Get(i);
710  if (nSwPos == pHt->GetStart())
711  {
712  if (pHt->HasDummyChar() || pHt->HasContent() )
713  {
714  return true;
715  }
716  }
717  else if (nSwPos < pHt->GetStart())
718  {
719  break; // sorted by start
720  }
721  }
722  }
723 
724  return false;
725 }
726 
727 bool SwWW8AttrIter::IsExportableAttr(sal_Int32 nSwPos) const
728 {
729  if (const SwpHints* pTextAttrs = rNd.GetpSwpHints())
730  {
731  for (size_t i = 0; i < pTextAttrs->Count(); ++i)
732  {
733  const SwTextAttr* pHt = pTextAttrs->GetSortedByEnd(i);
734  const sal_Int32 nStart = pHt->GetStart();
735  const sal_Int32 nEnd = pHt->End() ? *pHt->End() : INT_MAX;
736  if (nSwPos >= nStart && nSwPos < nEnd)
737  {
738  switch (pHt->GetAttr().Which())
739  {
740  // Metadata fields should be dynamically generated, not dumped as text.
742  return false;
743  }
744  }
745  }
746  }
747 
748  return true;
749 }
750 
751 bool SwWW8AttrIter::IsDropCap( int nSwPos )
752 {
753  // see if the current position falls on a DropCap
754  int nDropChars = mrSwFormatDrop.GetChars();
755  bool bWholeWord = mrSwFormatDrop.GetWholeWord();
756  if (bWholeWord)
757  {
758  const sal_Int32 nWordLen = rNd.GetDropLen(0);
759  if(nSwPos == nWordLen && nSwPos != 0)
760  return true;
761  }
762  else
763  {
764  if (nSwPos == nDropChars && nSwPos != 0)
765  return true;
766  }
767  return false;
768 }
769 
771 {
772  return std::any_of(m_rExport.m_aImplicitBookmarks.begin(), m_rExport.m_aImplicitBookmarks.end(),
773  [this](const aBookmarkPair& rBookmarkPair) { return rBookmarkPair.second == rNd.GetIndex(); });
774 }
775 
776 //HasItem is for the summary of the double attributes: Underline and WordlineMode as TextItems.
777 // OutAttr () calls the output function, which can call HasItem() for other items at the attribute's start position.
778 // Only attributes with end can be queried.
779 // It searches with bDeep
780 const SfxPoolItem* SwWW8AttrIter::HasTextItem( sal_uInt16 nWhich ) const
781 {
782  const SfxPoolItem* pRet = nullptr;
783  const SwpHints* pTextAttrs = rNd.GetpSwpHints();
784  if (pTextAttrs && !m_rExport.m_aCurrentCharPropStarts.empty())
785  {
786  const sal_Int32 nTmpSwPos = m_rExport.m_aCurrentCharPropStarts.top();
787  for (size_t i = 0; i < pTextAttrs->Count(); ++i)
788  {
789  const SwTextAttr* pHt = pTextAttrs->Get(i);
790  const SfxPoolItem* pItem = &pHt->GetAttr();
791  const sal_Int32 * pAtrEnd = nullptr;
792  if( nullptr != ( pAtrEnd = pHt->End() ) && // only Attr with an end
793  nTmpSwPos >= pHt->GetStart() && nTmpSwPos < *pAtrEnd )
794  {
795  if ( nWhich == pItem->Which() )
796  {
797  pRet = pItem; // found it
798  break;
799  }
800  else if( RES_TXTATR_INETFMT == pHt->Which() ||
801  RES_TXTATR_CHARFMT == pHt->Which() ||
802  RES_TXTATR_AUTOFMT == pHt->Which() )
803  {
804  const SfxItemSet* pSet = CharFormat::GetItemSet( pHt->GetAttr() );
805  const SfxPoolItem* pCharItem;
806  if ( pSet &&
807  SfxItemState::SET == pSet->GetItemState( nWhich, pHt->Which() != RES_TXTATR_AUTOFMT, &pCharItem ) )
808  {
809  pRet = pCharItem; // found it
810  break;
811  }
812  }
813  }
814  else if (nTmpSwPos < pHt->GetStart())
815  break; // nothing more to come
816  }
817  }
818  return pRet;
819 }
820 
822 {
823  rItems.insert(rItems.end(), pO->begin(), pO->end());
824 }
825 
826 const SfxPoolItem& SwWW8AttrIter::GetItem(sal_uInt16 nWhich) const
827 {
828  const SfxPoolItem* pRet = HasTextItem(nWhich);
829  return pRet ? *pRet : rNd.SwContentNode::GetAttr(nWhich);
830 }
831 
832 void WW8AttributeOutput::StartRuby( const SwTextNode& rNode, sal_Int32 /*nPos*/, const SwFormatRuby& rRuby )
833 {
834  WW8Ruby aWW8Ruby(rNode, rRuby, GetExport());
835  OUString aStr( FieldString( ww::eEQ ) + "\\* jc" );
836  aStr += OUString::number(aWW8Ruby.GetJC()) + " \\* \"Font:";
837  aStr += aWW8Ruby.GetFontFamily() + "\" \\* hps";
838  aStr += OUString::number((aWW8Ruby.GetRubyHeight() + 5) / 10) + " \\o";
839  if (aWW8Ruby.GetDirective())
840  {
841  aStr += OUStringLiteral("\\a") + OUStringChar(aWW8Ruby.GetDirective());
842  }
843  aStr += "(\\s\\up " + OUString::number((aWW8Ruby.GetBaseHeight() + 10) / 20 - 1) + "(";
844  aStr += rRuby.GetText() + ")";
845 
846  // The parameter separator depends on the FIB.lid
847  if ( m_rWW8Export.pFib->getNumDecimalSep() == '.' )
848  aStr += ",";
849  else
850  aStr += ";";
851 
852  m_rWW8Export.OutputField( nullptr, ww::eEQ, aStr,
854 }
855 
856 void WW8AttributeOutput::EndRuby(const SwTextNode& /*rNode*/, sal_Int32 /*nPos*/)
857 {
858  m_rWW8Export.WriteChar( ')' );
860 }
861 
862 /*#i15387# Better ideas welcome*/
863 static OUString &TruncateBookmark( OUString &rRet )
864 {
865  if ( rRet.getLength() > 40 )
866  rRet = rRet.copy( 0, 40 );
867  OSL_ENSURE( rRet.getLength() <= 40, "Word cannot have bookmarks longer than 40 chars" );
868  return rRet;
869 }
870 
871 OUString AttributeOutputBase::ConvertURL( const OUString& rUrl, bool bAbsoluteOut )
872 {
873  OUString sURL = rUrl;
874 
875  INetURLObject anAbsoluteParent(m_sBaseURL);
876  OUString sConvertedParent = INetURLObject::GetScheme( anAbsoluteParent.GetProtocol() ) + anAbsoluteParent.GetURLPath();
877  OUString sParentPath = sConvertedParent.isEmpty() ? m_sBaseURL : sConvertedParent;
878 
879  if ( bAbsoluteOut )
880  {
881  INetURLObject anAbsoluteNew;
882 
883  if ( anAbsoluteParent.GetNewAbsURL( rUrl, &anAbsoluteNew ) )
884  sURL = anAbsoluteNew.GetMainURL( INetURLObject::DecodeMechanism::NONE );
885  }
886  else
887  {
888  OUString sToConvert = rUrl.replaceAll( "\\", "/" );
889  INetURLObject aURL( sToConvert );
890  sToConvert = INetURLObject::GetScheme( aURL.GetProtocol() ) + aURL.GetURLPath();
892  if ( !sRelative.isEmpty() )
893  sURL = sRelative;
894  }
895 
896  return sURL;
897 }
898 
899 bool AttributeOutputBase::AnalyzeURL( const OUString& rUrl, const OUString& /*rTarget*/, OUString* pLinkURL, OUString* pMark )
900 {
901  bool bBookMarkOnly = false;
902 
903  OUString sMark;
904  OUString sURL;
905 
906  if ( rUrl.getLength() > 1 && rUrl[0] == '#' )
907  {
908  sMark = BookmarkToWriter( rUrl.copy(1) );
909 
910  const sal_Int32 nPos = sMark.lastIndexOf( cMarkSeparator );
911 
912  const OUString sRefType(nPos>=0 && nPos+1<sMark.getLength() ?
913  sMark.copy(nPos+1).replaceAll(" ", "") :
914  OUString());
915 
916  // #i21465# Only interested in outline references
917  if ( !sRefType.isEmpty() &&
918  (sRefType == "outline" || sRefType == "graphic" || sRefType == "frame" || sRefType == "ole" || sRefType == "region" || sRefType == "table") )
919  {
920  for ( const auto& rBookmarkPair : GetExport().m_aImplicitBookmarks )
921  {
922  if ( rBookmarkPair.first == sMark )
923  {
924  sMark = "_toc" + OUString::number( rBookmarkPair.second );
925  break;
926  }
927  }
928  }
929  }
930  else
931  {
932  INetURLObject aURL( rUrl, INetProtocol::NotValid );
935  INetProtocol aProtocol = aURL.GetProtocol();
936 
937  if ( aProtocol == INetProtocol::File || aProtocol == INetProtocol::NotValid )
938  {
939  // INetProtocol::NotValid - may be a relative link
940  bool bExportRelative = m_aSaveOpt.IsSaveRelFSys();
941  sURL = ConvertURL( rUrl, !bExportRelative );
942  }
943  }
944 
945  if ( !sMark.isEmpty() && sURL.isEmpty() )
946  bBookMarkOnly = true;
947 
948  *pMark = sMark;
949  *pLinkURL = sURL;
950  return bBookMarkOnly;
951 }
952 
953 bool WW8AttributeOutput::AnalyzeURL( const OUString& rUrl, const OUString& rTarget, OUString* pLinkURL, OUString* pMark )
954 {
955  bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
956 
957  OUString sURL = *pLinkURL;
958 
959  if ( !sURL.isEmpty() )
961 
962  if ( bBookMarkOnly )
963  sURL = FieldString( ww::eHYPERLINK );
964  else
965  sURL = FieldString( ww::eHYPERLINK ) + "\"" + sURL + "\"";
966 
967  if ( !pMark->isEmpty() )
968  sURL += " \\l \"" + *pMark + "\"";
969 
970  if ( !rTarget.isEmpty() )
971  sURL += " \\n " + rTarget;
972 
973  *pLinkURL = sURL;
974 
975  return bBookMarkOnly;
976 }
977 
978 void WW8AttributeOutput::WriteBookmarkInActParagraph( const OUString& rName, sal_Int32 nFirstRunPos, sal_Int32 nLastRunPos )
979 {
980  m_aBookmarksOfParagraphStart.insert(std::pair<sal_Int32, OUString>(nFirstRunPos, rName));
981  m_aBookmarksOfParagraphEnd.insert(std::pair<sal_Int32, OUString>(nLastRunPos, rName));
982 }
983 
984 bool WW8AttributeOutput::StartURL( const OUString &rUrl, const OUString &rTarget )
985 {
986  INetURLObject aURL( rUrl );
987  OUString sURL;
988  OUString sMark;
989 
990  bool bBookMarkOnly = AnalyzeURL( rUrl, rTarget, &sURL, &sMark );
991 
993 
994  // write the reference to the "picture" structure
995  sal_uLong nDataStt = m_rWW8Export.pDataStrm->Tell();
996  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() );
997 
998  // WinWord 2000 doesn't write this - so it's a temp solution by W97 ?
999  m_rWW8Export.WriteChar( 0x01 );
1000 
1001  static sal_uInt8 aArr1[] = {
1002  0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
1003 
1004  0x06, 0x08, 0x01, // sprmCFData
1005  0x55, 0x08, 0x01, // sprmCFSpec
1006  0x02, 0x08, 0x01 // sprmCFFieldVanish
1007  };
1008  sal_uInt8* pDataAdr = aArr1 + 2;
1009  Set_UInt32( pDataAdr, nDataStt );
1010 
1011  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), sizeof( aArr1 ), aArr1 );
1012 
1014 
1015  // now write the picture structure
1016  sURL = aURL.GetURLNoMark();
1017 
1018  // Compare the URL written by AnalyzeURL with the original one to see if
1019  // the output URL is absolute or relative.
1020  OUString sRelativeURL;
1021  if ( !rUrl.isEmpty() )
1023  bool bAbsolute = sRelativeURL == rUrl;
1024 
1025  static sal_uInt8 aURLData1[] = {
1026  0,0,0,0, // len of struct
1027  0x44,0, // the start of "next" data
1028  0,0,0,0,0,0,0,0,0,0, // PIC-Structure!
1029  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
1030  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
1031  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
1032  0,0,0,0, // /
1033  };
1034  static sal_uInt8 MAGIC_A[] = {
1035  // start of "next" data
1036  0xD0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
1037  0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
1038  };
1039 
1040  m_rWW8Export.pDataStrm->WriteBytes(aURLData1, sizeof(aURLData1));
1041  /* Write HFD Structure */
1042  sal_uInt8 nAnchor = 0x00;
1043  if ( !sMark.isEmpty() )
1044  nAnchor = 0x08;
1045  m_rWW8Export.pDataStrm->WriteUChar(nAnchor); // HFDBits
1046  m_rWW8Export.pDataStrm->WriteBytes(MAGIC_A, sizeof(MAGIC_A)); //clsid
1047 
1048  /* Write Hyperlink Object see [MS-OSHARED] spec*/
1050  sal_uInt32 nFlag = bBookMarkOnly ? 0 : 0x01;
1051  if ( bAbsolute )
1052  nFlag |= 0x02;
1053  if ( !sMark.isEmpty() )
1054  nFlag |= 0x08;
1056 
1057  INetProtocol eProto = aURL.GetProtocol();
1058  if ( eProto == INetProtocol::File || eProto == INetProtocol::Smb )
1059  {
1060  // version 1 (for a document)
1061 
1062  static sal_uInt8 MAGIC_C[] = {
1063  0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1064  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
1065  0x00, 0x00
1066  };
1067 
1068  static sal_uInt8 MAGIC_D[] = {
1069  0xFF, 0xFF, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,
1070  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1071  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1072  };
1073 
1074  // save the links to files as relative
1076  if ( eProto == INetProtocol::File && sURL.startsWith( "/" ) )
1077  sURL = aURL.PathToFileName();
1078 
1079  // special case for the absolute windows names
1080  // (convert '/c:/foo/bar.doc' into 'c:\foo\bar.doc')
1081  if (sURL.getLength()>=3)
1082  {
1083  const sal_Unicode aDrive = sURL[1];
1084  if ( sURL[0]=='/' && sURL[2]==':' &&
1085  ( (aDrive>='A' && aDrive<='Z' ) || (aDrive>='a' && aDrive<='z') ) )
1086  {
1087  sURL = sURL.copy(1).replaceAll("/", "\\");
1088  }
1089  }
1090 
1091  // n#261623 convert smb notation to '\\'
1092  const char pSmb[] = "smb://";
1093  if ( eProto == INetProtocol::Smb && sURL.startsWith( pSmb ) )
1094  {
1095  sURL = sURL.copy( sizeof(pSmb)-3 ).replaceAll( "/", "\\" );
1096  }
1097 
1098  m_rWW8Export.pDataStrm->WriteBytes(MAGIC_C, sizeof(MAGIC_C));
1099  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sURL.getLength()+1 );
1101  RTL_TEXTENCODING_MS_1252 );
1102  m_rWW8Export.pDataStrm->WriteBytes(MAGIC_D, sizeof(MAGIC_D));
1103 
1104  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.getLength() + 6 );
1105  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.getLength() );
1108  }
1109  else if ( eProto != INetProtocol::NotValid )
1110  {
1111  // version 2 (simple url)
1112  // and write some data to the data stream, but don't ask
1113  // what the data mean, except for the URL.
1114  // The First piece is the WW8_PIC structure.
1115  static sal_uInt8 MAGIC_B[] = {
1116  0xE0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
1117  0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
1118  };
1119 
1120  m_rWW8Export.pDataStrm->WriteBytes(MAGIC_B, sizeof(MAGIC_B));
1121  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2 * ( sURL.getLength() + 1 ) );
1123  }
1124 
1125  if ( !sMark.isEmpty() )
1126  {
1127  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sMark.getLength()+1 );
1129  }
1131  m_rWW8Export.pDataStrm->Tell() - nDataStt );
1132 
1133  return true;
1134 }
1135 
1137 {
1138  m_rWW8Export.OutputField( nullptr, ww::eHYPERLINK, OUString(), FieldFlags::Close );
1139 
1140  return true;
1141 }
1142 
1143 OUString BookmarkToWord(const OUString &rBookmark)
1144 {
1145  OUString sRet(INetURLObject::encode(
1146  rBookmark.replace(' ', '_'), // Spaces are prohibited in bookmark name
1148  INetURLObject::EncodeMechanism::All, RTL_TEXTENCODING_ASCII_US));
1149  // Unicode letters are allowed
1150  sRet = INetURLObject::decode(sRet, INetURLObject::DecodeMechanism::Unambiguous, RTL_TEXTENCODING_UTF8);
1151  return TruncateBookmark(sRet);
1152 }
1153 
1154 OUString BookmarkToWriter(const OUString &rBookmark)
1155 {
1156  return INetURLObject::decode(rBookmark,
1157  INetURLObject::DecodeMechanism::Unambiguous, RTL_TEXTENCODING_ASCII_US);
1158 }
1159 
1161 {
1162  if ( m_rExport.HasRefToObject( REF_SETREFATTR, &rAttr.GetRefName(), 0 ) )
1164  &rAttr.GetRefName(), 0 ));
1165 }
1166 
1167 void SwWW8AttrIter::SplitRun( sal_Int32 nSplitEndPos )
1168 {
1169  auto aIter = std::find_if(maCharRuns.begin(), maCharRuns.end(),
1170  [nSplitEndPos](const CharRunEntry& rCharRun) { return rCharRun.mnEndPos >= nSplitEndPos; });
1171  if (aIter == maCharRuns.end() || aIter->mnEndPos == nSplitEndPos)
1172  return;
1173 
1174  CharRunEntry aNewEntry = *aIter;
1175  aIter->mnEndPos = nSplitEndPos;
1176  maCharRuns.insert( ++aIter, aNewEntry);
1177  maCharRunIter = maCharRuns.begin();
1178  IterToCurrent();
1180 }
1181 
1182 void WW8AttributeOutput::FieldVanish( const OUString& rText, ww::eField /*eType*/ )
1183 {
1184  ww::bytes aItems;
1185  m_rWW8Export.GetCurrentItems( aItems );
1186 
1187  // sprmCFFieldVanish
1189  aItems.push_back( 1 );
1190 
1191  sal_uInt16 nStt_sprmCFSpec = aItems.size();
1192 
1193  // sprmCFSpec -- fSpec-Attribut true
1194  SwWW8Writer::InsUInt16( aItems, 0x855 );
1195  aItems.push_back( 1 );
1196 
1197  m_rWW8Export.WriteChar( '\x13' );
1198  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.size(),
1199  aItems.data() );
1200  m_rWW8Export.OutSwString(rText, 0, rText.getLength());
1201  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), nStt_sprmCFSpec,
1202  aItems.data() );
1203  m_rWW8Export.WriteChar( '\x15' );
1204  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.size(),
1205  aItems.data() );
1206 }
1207 
1208 void AttributeOutputBase::TOXMark( const SwTextNode& rNode, const SwTOXMark& rAttr )
1209 {
1210  // it's a field; so get the Text from the Node and build the field
1211  OUString sText;
1213 
1214  const SwTextTOXMark& rTextTOXMark = *rAttr.GetTextTOXMark();
1215  const sal_Int32* pTextEnd = rTextTOXMark.End();
1216  if ( pTextEnd ) // has range?
1217  {
1218  sText = rNode.GetExpandText(nullptr, rTextTOXMark.GetStart(),
1219  *pTextEnd - rTextTOXMark.GetStart() );
1220  }
1221  else
1222  sText = rAttr.GetAlternativeText();
1223 
1224  switch ( rAttr.GetTOXType()->GetType() )
1225  {
1226  case TOX_INDEX:
1227  eType = ww::eXE;
1228  if ( !rAttr.GetPrimaryKey().isEmpty() )
1229  {
1230  if ( !rAttr.GetSecondaryKey().isEmpty() )
1231  {
1232  sText = rAttr.GetSecondaryKey() + ":" + sText;
1233  }
1234 
1235  sText = rAttr.GetPrimaryKey() + ":" + sText;
1236  }
1237  sText = " XE \"" + sText + "\" ";
1238  break;
1239 
1240  case TOX_USER:
1241  sText += "\" \\f \"" + OUStringChar(static_cast<sal_Char>( 'A' + GetExport( ).GetId( *rAttr.GetTOXType() ) ));
1242  [[fallthrough]];
1243  case TOX_CONTENT:
1244  {
1245  eType = ww::eTC;
1246  sText = " TC \"" + sText;
1247  sal_uInt16 nLvl = rAttr.GetLevel();
1248  if (nLvl > WW8ListManager::nMaxLevel)
1250 
1251  sText += "\" \\l " + OUString::number(nLvl) + " ";
1252  }
1253  break;
1254  default:
1255  OSL_ENSURE( false, "Unhandled option for toc export" );
1256  break;
1257  }
1258 
1259  if (!sText.isEmpty())
1260  FieldVanish( sText, eType );
1261 }
1262 
1263 int SwWW8AttrIter::OutAttrWithRange(const SwTextNode& rNode, sal_Int32 nPos)
1264 {
1265  int nRet = 0;
1266  if ( const SwpHints* pTextAttrs = rNd.GetpSwpHints() )
1267  {
1268  m_rExport.m_aCurrentCharPropStarts.push( nPos );
1269  const sal_Int32* pEnd;
1270  // first process ends of attributes with extent
1271  for (size_t i = 0; i < pTextAttrs->Count(); ++i)
1272  {
1273  const SwTextAttr* pHt = pTextAttrs->GetSortedByEnd(i);
1274  const SfxPoolItem* pItem = &pHt->GetAttr();
1275  switch ( pItem->Which() )
1276  {
1277  case RES_TXTATR_INETFMT:
1278  pEnd = pHt->End();
1279  if (nPos == *pEnd && nPos != pHt->GetStart())
1280  {
1281  if (m_rExport.AttrOutput().EndURL(nPos == rNd.Len()))
1282  --nRet;
1283  }
1284  break;
1285  case RES_TXTATR_REFMARK:
1286  pEnd = pHt->End();
1287  if (nullptr != pEnd && nPos == *pEnd && nPos != pHt->GetStart())
1288  {
1289  OutSwFormatRefMark(*static_cast<const SwFormatRefMark*>(pItem));
1290  --nRet;
1291  }
1292  break;
1293  case RES_TXTATR_CJK_RUBY:
1294  pEnd = pHt->End();
1295  if (nPos == *pEnd && nPos != pHt->GetStart())
1296  {
1297  m_rExport.AttrOutput().EndRuby(rNode, nPos);
1298  --nRet;
1299  }
1300  break;
1301  }
1302  if (nPos < pHt->GetAnyEnd())
1303  break; // sorted by end
1304  }
1305  for ( size_t i = 0; i < pTextAttrs->Count(); ++i )
1306  {
1307  const SwTextAttr* pHt = pTextAttrs->Get(i);
1308  const SfxPoolItem* pItem = &pHt->GetAttr();
1309  switch ( pItem->Which() )
1310  {
1311  case RES_TXTATR_INETFMT:
1312  if ( nPos == pHt->GetStart() )
1313  {
1314  const SwFormatINetFormat *rINet = static_cast< const SwFormatINetFormat* >( pItem );
1315  if ( m_rExport.AttrOutput().StartURL( rINet->GetValue(), rINet->GetTargetFrame() ) )
1316  ++nRet;
1317  }
1318  pEnd = pHt->End();
1319  if (nPos == *pEnd && nPos == pHt->GetStart())
1320  { // special case: empty must be handled here
1321  if (m_rExport.AttrOutput().EndURL(nPos == rNd.Len()))
1322  --nRet;
1323  }
1324  break;
1325  case RES_TXTATR_REFMARK:
1326  if ( nPos == pHt->GetStart() )
1327  {
1328  OutSwFormatRefMark( *static_cast< const SwFormatRefMark* >( pItem ) );
1329  ++nRet;
1330  }
1331  pEnd = pHt->End();
1332  if (nullptr != pEnd && nPos == *pEnd && nPos == pHt->GetStart())
1333  { // special case: empty TODO: is this possible or would empty one have pEnd null?
1334  OutSwFormatRefMark( *static_cast< const SwFormatRefMark* >( pItem ) );
1335  --nRet;
1336  }
1337  break;
1338  case RES_TXTATR_TOXMARK:
1339  if ( nPos == pHt->GetStart() )
1340  m_rExport.AttrOutput().TOXMark( rNd, *static_cast< const SwTOXMark* >( pItem ) );
1341  break;
1342  case RES_TXTATR_CJK_RUBY:
1343  if ( nPos == pHt->GetStart() )
1344  {
1345  m_rExport.AttrOutput().StartRuby( rNd, nPos, *static_cast< const SwFormatRuby* >( pItem ) );
1346  ++nRet;
1347  }
1348  pEnd = pHt->End();
1349  if (nPos == *pEnd && nPos == pHt->GetStart())
1350  { // special case: empty must be handled here
1351  m_rExport.AttrOutput().EndRuby( rNd, nPos );
1352  --nRet;
1353  }
1354  break;
1355  }
1356  if (nPos < pHt->GetStart())
1357  break; // sorted by start
1358  }
1359  m_rExport.m_aCurrentCharPropStarts.pop(); // HasTextItem only allowed in the above range
1360  }
1361  return nRet;
1362 }
1363 
1365 {
1366  // search next Redline
1369  {
1371  const SwPosition* pEnd = pRange->End();
1372  const SwPosition* pStart = pRange->Start();
1373  bool bBreak = true;
1374  // In word the paragraph end marker is a real character, in writer it is not.
1375  // Here we find out if the para end marker we will emit is affected by
1376  // redlining, in which case it must be included by the range of character
1377  // attributes that contains the redlining information.
1378  if (pEnd->nNode == rNd)
1379  {
1380  if (pEnd->nContent.GetIndex() == nEnd)
1381  {
1382  // This condition detects if the pseudo-char we will export
1383  // should be explicitly included by the redlining char
1384  // properties on this node because the redlining ends right
1385  // after it
1386  return true;
1387  }
1388  bBreak = false;
1389  }
1390  if (pStart->nNode == rNd)
1391  {
1392  if (pStart->nContent.GetIndex() == nEnd)
1393  {
1394  // This condition detects if the pseudo-char we will export
1395  // should be explicitly included by the redlining char
1396  // properties on this node because the redlining starts right
1397  // before it
1398  return true;
1399  }
1400  bBreak = false;
1401  }
1402  if (pStart->nNode.GetIndex()-1 == rNd.GetIndex())
1403  {
1404  if (pStart->nContent.GetIndex() == 0)
1405  {
1406  // This condition detects if the pseudo-char we will export
1407  // should be implicitly excluded by the redlining char
1408  // properties starting on the next node.
1409  return true;
1410  }
1411  bBreak = false;
1412  }
1413 
1414  if (bBreak)
1415  break;
1416  }
1417  return false;
1418 }
1419 
1421 {
1422  pCurRedline = nullptr;
1423 
1424  // ToDo : this is not the most ideal ... should start maybe from 'nCurRedlinePos'
1426  {
1427  const SwPosition* pCheckedStt = pRedl->Start();
1428 
1429  if( pCheckedStt->nNode == rNd )
1430  {
1431  // Maybe add here a check that also the start & end of the redline is the entire paragraph
1432 
1433  // Only return if this is a paragraph formatting redline
1434  if (pRedl->GetType() == RedlineType::ParagraphFormat)
1435  {
1436  // write data of this redline
1437  pCurRedline = pRedl;
1438  return &( pCurRedline->GetRedlineData() );
1439  }
1440  }
1441  }
1442  return nullptr;
1443 }
1444 
1446 {
1447  if( pCurRedline )
1448  {
1449  const SwPosition* pEnd = pCurRedline->End();
1450  if (!(pEnd->nNode == rNd && pEnd->nContent.GetIndex() <= nPos))
1451  {
1452  switch( pCurRedline->GetType() )
1453  {
1454  case RedlineType::Insert:
1455  case RedlineType::Delete:
1456  case RedlineType::Format:
1457  // write data of this redline
1458  return &( pCurRedline->GetRedlineData() );
1459  break;
1460  default:
1461  break;
1462  }
1463  }
1464  pCurRedline = nullptr;
1465  ++nCurRedlinePos;
1466  }
1467 
1468  assert(!pCurRedline);
1469  // search next Redline
1471  ++nCurRedlinePos )
1472  {
1474 
1475  const SwPosition* pStt = pRedl->Start();
1476  const SwPosition* pEnd = pStt == pRedl->GetPoint()
1477  ? pRedl->GetMark()
1478  : pRedl->GetPoint();
1479 
1480  if( pStt->nNode == rNd )
1481  {
1482  if( pStt->nContent.GetIndex() >= nPos )
1483  {
1484  if( pStt->nContent.GetIndex() == nPos )
1485  {
1486  switch( pRedl->GetType() )
1487  {
1488  case RedlineType::Insert:
1489  case RedlineType::Delete:
1490  case RedlineType::Format:
1491  // write data of this redline
1492  pCurRedline = pRedl;
1493  return &( pCurRedline->GetRedlineData() );
1494  break;
1495  default:
1496  break;
1497  }
1498  }
1499  break;
1500  }
1501  }
1502  else
1503  {
1504  break;
1505  }
1506 
1507  if( pEnd->nNode == rNd &&
1508  pEnd->nContent.GetIndex() < nPos )
1509  {
1510  pCurRedline = pRedl;
1511  break;
1512  }
1513  }
1514  return nullptr;
1515 }
1516 
1518 {
1519  const SwFrameFormat &rFormat = m_pCurrentPageDesc
1521  : m_pDoc->GetPageDesc( 0 ).GetMaster();
1522  return rFormat.GetFrameDir().GetValue();
1523 }
1524 
1526 {
1527  SvxFrameDirection nDir = SvxFrameDirection::Environment;
1528 
1529  if ( m_bOutPageDescs )
1530  nDir = GetCurrentPageDirection( );
1531  else if ( m_pOutFormatNode )
1532  {
1533  if ( m_bOutFlyFrameAttrs ) //frame
1534  {
1535  nDir = TrueFrameDirection( *static_cast< const SwFrameFormat * >(m_pOutFormatNode) );
1536  }
1537  else if ( dynamic_cast< const SwContentNode *>( m_pOutFormatNode ) != nullptr ) //paragraph
1538  {
1539  const SwContentNode *pNd = static_cast<const SwContentNode *>(m_pOutFormatNode);
1540  SwPosition aPos( *pNd );
1541  nDir = m_pDoc->GetTextDirection( aPos );
1542  }
1543  else if ( dynamic_cast< const SwTextFormatColl *>( m_pOutFormatNode ) != nullptr )
1544  {
1546  nDir = SvxFrameDirection::Horizontal_RL_TB;
1547  else
1548  nDir = SvxFrameDirection::Horizontal_LR_TB; //what else can we do :-(
1549  }
1550  }
1551 
1552  if ( nDir == SvxFrameDirection::Environment )
1553  {
1554  // fdo#44029 put direction right when the locale are RTL.
1556  nDir = SvxFrameDirection::Horizontal_RL_TB;
1557  else
1558  nDir = SvxFrameDirection::Horizontal_LR_TB; //Set something
1559  }
1560 
1561  return nDir;
1562 }
1563 
1565 {
1566  const SwFrameFormat *pFlyFormat = &rFlyFormat;
1567  const SvxFrameDirectionItem* pItem = nullptr;
1568  while ( pFlyFormat )
1569  {
1570  pItem = &pFlyFormat->GetFrameDir();
1571  if ( SvxFrameDirection::Environment == pItem->GetValue() )
1572  {
1573  pItem = nullptr;
1574  const SwFormatAnchor* pAnchor = &pFlyFormat->GetAnchor();
1575  if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
1576  pAnchor->GetContentAnchor() )
1577  {
1578  pFlyFormat = pAnchor->GetContentAnchor()->nNode.GetNode().GetFlyFormat();
1579  }
1580  else
1581  pFlyFormat = nullptr;
1582  }
1583  else
1584  pFlyFormat = nullptr;
1585  }
1586 
1587  SvxFrameDirection nRet;
1588  if ( pItem )
1589  nRet = pItem->GetValue();
1590  else
1591  nRet = GetCurrentPageDirection();
1592 
1593  OSL_ENSURE( nRet != SvxFrameDirection::Environment, "leaving with environment direction" );
1594  return nRet;
1595 }
1596 
1598 {
1599  const SwFrameFormat &rFormat = m_pCurrentPageDesc
1601  : m_pDoc->GetPageDesc(0).GetMaster();
1602 
1603  const SfxPoolItem* pItem = nullptr;
1604  //If not set, or "no fill", get real bg
1605  SfxItemState eState = rFormat.GetItemState(RES_BACKGROUND, true, &pItem);
1606 
1607  const SvxBrushItem* pRet = static_cast<const SvxBrushItem*>(pItem);
1608  if (SfxItemState::SET != eState || !pRet || (!pRet->GetGraphic() &&
1609  pRet->GetColor() == COL_TRANSPARENT))
1610  {
1611  pRet = &(DefaultItemGet<SvxBrushItem>(*m_pDoc,RES_BACKGROUND));
1612  }
1613  return pRet;
1614 }
1615 
1616 std::shared_ptr<SvxBrushItem> WW8Export::TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const
1617 {
1618  const SwFrameFormat *pFlyFormat = &rFlyFormat;
1619  const SvxBrushItem* pRet = nullptr;
1620 
1621  while (pFlyFormat)
1622  {
1623  //If not set, or "no fill", get real bg
1624  const SfxPoolItem* pItem = nullptr;
1625  SfxItemState eState =
1626  pFlyFormat->GetItemState(RES_BACKGROUND, true, &pItem);
1627  pRet = static_cast<const SvxBrushItem*>(pItem);
1628  if (SfxItemState::SET != eState || !pRet || (!pRet->GetGraphic() &&
1629  pRet->GetColor() == COL_TRANSPARENT))
1630  {
1631  pRet = nullptr;
1632  const SwFormatAnchor* pAnchor = &pFlyFormat->GetAnchor();
1633  if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
1634  pAnchor->GetContentAnchor())
1635  {
1636  pFlyFormat =
1637  pAnchor->GetContentAnchor()->nNode.GetNode().GetFlyFormat();
1638  }
1639  else
1640  pFlyFormat = nullptr;
1641  }
1642  else
1643  pFlyFormat = nullptr;
1644  }
1645 
1646  if (!pRet)
1647  pRet = GetCurrentPageBgBrush();
1648 
1649  const Color aTmpColor( COL_WHITE );
1650  std::shared_ptr<SvxBrushItem> aRet(std::make_shared<SvxBrushItem>(aTmpColor, RES_BACKGROUND));
1651 
1652  if (pRet && (pRet->GetGraphic() ||( pRet->GetColor() != COL_TRANSPARENT)))
1653  {
1654  aRet.reset(static_cast<SvxBrushItem*>(pRet->Clone()));
1655  }
1656 
1657  return aRet;
1658 }
1659 
1660 /*
1661 Convert characters that need to be converted, the basic replacements and the
1662 ridiculously complicated title case attribute mapping to hardcoded upper case
1663 because word doesn't have the feature
1664 */
1665 OUString SwWW8AttrIter::GetSnippet(const OUString &rStr, sal_Int32 nCurrentPos,
1666  sal_Int32 nLen) const
1667 {
1668  if (!nLen)
1669  return OUString();
1670 
1671  OUString aSnippet(rStr.copy(nCurrentPos, nLen));
1672  // 0x0a ( Hard Line Break ) -> 0x0b
1673  // 0xad ( soft hyphen ) -> 0x1f
1674  // 0x2011 ( hard hyphen ) -> 0x1e
1675  aSnippet = aSnippet.replace(0x0A, 0x0B);
1676  aSnippet = aSnippet.replace(CHAR_HARDHYPHEN, 0x1e);
1677  aSnippet = aSnippet.replace(CHAR_SOFTHYPHEN, 0x1f);
1678 
1679  m_rExport.m_aCurrentCharPropStarts.push( nCurrentPos );
1680  const SfxPoolItem &rItem = GetItem(RES_CHRATR_CASEMAP);
1681 
1682  if (SvxCaseMap::Capitalize == static_cast<const SvxCaseMapItem&>(rItem).GetValue())
1683  {
1684  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
1685  sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType(aSnippet, 0);
1686 
1687  LanguageType nLanguage;
1688  switch (nScriptType)
1689  {
1690  case i18n::ScriptType::ASIAN:
1691  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_CJK_LANGUAGE)).GetLanguage();
1692  break;
1693  case i18n::ScriptType::COMPLEX:
1694  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_CTL_LANGUAGE)).GetLanguage();
1695  break;
1696  case i18n::ScriptType::LATIN:
1697  default:
1698  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_LANGUAGE)).GetLanguage();
1699  break;
1700  }
1701 
1702  SvxFont aFontHelper;
1703  aFontHelper.SetCaseMap(SvxCaseMap::Capitalize);
1704  aFontHelper.SetLanguage(nLanguage);
1705  aSnippet = aFontHelper.CalcCaseMap(aSnippet);
1706 
1707  //If we weren't at the begin of a word undo the case change.
1708  //not done before doing the casemap because the sequence might start
1709  //with whitespace
1710  if (!g_pBreakIt->GetBreakIter()->isBeginWord(
1711  rStr, nCurrentPos, g_pBreakIt->GetLocale(nLanguage),
1712  i18n::WordType::ANYWORD_IGNOREWHITESPACES ) )
1713  {
1714  aSnippet = OUStringChar(rStr[nCurrentPos]) + aSnippet.copy(1);
1715  }
1716  }
1718 
1719  return aSnippet;
1720 }
1721 
1729 {
1732  while( nPos < nMax )
1733  {
1734  const SwRangeRedline* pRedl = rExport.m_pDoc->getIDocumentRedlineAccess().GetRedlineTable()[ nPos++ ];
1735  const SwPosition* pStt = pRedl->Start();
1736  const SwPosition* pEnd = pStt == pRedl->GetPoint()
1737  ? pRedl->GetMark()
1738  : pRedl->GetPoint();
1739  // Looking for deletions, which ends in current pTextNode
1740  if( RedlineType::Delete == pRedl->GetRedlineData().GetType() &&
1741  pEnd->nNode == *pTextNode && pStt->nNode != *pTextNode &&
1742  pStt->nNode.GetNode().IsTextNode() )
1743  {
1744  pTextNode = pStt->nNode.GetNode().GetTextNode();
1745  nMax = nPos;
1746  nPos = 0;
1747  }
1748  }
1749  return static_cast<SwTextFormatColl&>( pTextNode->GetAnyFormatColl() );
1750 }
1751 
1752 void WW8AttributeOutput::FormatDrop( const SwTextNode& rNode, const SwFormatDrop &rSwFormatDrop, sal_uInt16 nStyle,
1754 {
1755  short nDropLines = rSwFormatDrop.GetLines();
1756  short nDistance = rSwFormatDrop.GetDistance();
1757  int rFontHeight, rDropHeight, rDropDescent;
1758 
1759  SVBT16 nSty;
1760  ShortToSVBT16( nStyle, nSty );
1761  m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), nSty, nSty+2 ); // Style #
1762 
1763  m_rWW8Export.InsUInt16( NS_sprm::sprmPPc ); // Alignment (sprmPPc)
1764  m_rWW8Export.pO->push_back( 0x20 );
1765 
1766  m_rWW8Export.InsUInt16( NS_sprm::sprmPWr ); // Wrapping (sprmPWr)
1767  m_rWW8Export.pO->push_back( 0x02 );
1768 
1769  m_rWW8Export.InsUInt16( NS_sprm::sprmPDcs ); // Dropcap (sprmPDcs)
1770  int nDCS = ( nDropLines << 3 ) | 0x01;
1771  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
1772 
1773  m_rWW8Export.InsUInt16( NS_sprm::sprmPDxaFromText ); // Distance from text (sprmPDxaFromText)
1774  m_rWW8Export.InsUInt16( nDistance );
1775 
1776  if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1777  {
1778  m_rWW8Export.InsUInt16( NS_sprm::sprmPDyaLine ); // Line spacing
1779  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
1780  m_rWW8Export.InsUInt16( 0 );
1781  }
1782 
1783  m_rWW8Export.WriteCR( pTextNodeInfoInner );
1784 
1785  if ( pTextNodeInfo.get() != nullptr )
1786  {
1787 #ifdef DBG_UTIL
1788  SAL_INFO( "sw.ww8", pTextNodeInfo->toString());
1789 #endif
1790  TableInfoCell( pTextNodeInfoInner );
1791  }
1792 
1793  m_rWW8Export.m_pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
1794  m_rWW8Export.pO->clear();
1795 
1796  if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1797  {
1798  const SwCharFormat *pSwCharFormat = rSwFormatDrop.GetCharFormat();
1799  if ( pSwCharFormat )
1800  {
1802  m_rWW8Export.InsUInt16( m_rWW8Export.GetId( pSwCharFormat ) );
1803  }
1804 
1805  m_rWW8Export.InsUInt16( NS_sprm::sprmCHpsPos ); // Lower the chars
1806  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
1807 
1808  m_rWW8Export.InsUInt16( NS_sprm::sprmCHps ); // Font Size
1809  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
1810  }
1811 
1812  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
1813  m_rWW8Export.pO->clear();
1814 }
1815 
1816 sal_Int32 MSWordExportBase::GetNextPos( SwWW8AttrIter const * aAttrIter, const SwTextNode& rNode, sal_Int32 nCurrentPos )
1817 {
1818  // Get the bookmarks for the normal run
1819  const sal_Int32 nNextPos = aAttrIter->WhereNext();
1820  sal_Int32 nNextBookmark = nNextPos;
1821  sal_Int32 nNextAnnotationMark = nNextPos;
1822 
1823  if( nNextBookmark > nCurrentPos ) //no need to search for bookmarks otherwise (checked in UpdatePosition())
1824  {
1825  GetSortedBookmarks( rNode, nCurrentPos, nNextBookmark - nCurrentPos );
1826  NearestBookmark( nNextBookmark, nCurrentPos, false );
1827  GetSortedAnnotationMarks(*aAttrIter, nCurrentPos, nNextAnnotationMark - nCurrentPos);
1828  NearestAnnotationMark( nNextAnnotationMark, nCurrentPos, false );
1829  }
1830  return std::min( nNextPos, std::min( nNextBookmark, nNextAnnotationMark ) );
1831 }
1832 
1833 void MSWordExportBase::UpdatePosition( SwWW8AttrIter* aAttrIter, sal_Int32 nCurrentPos )
1834 {
1835  sal_Int32 nNextPos;
1836 
1837  // go to next attribute if no bookmark is found or if the bookmark is after the next attribute position
1838  // It may happened that the WhereNext() wasn't used in the previous increment because there was a
1839  // bookmark before it. Use that position before trying to find another one.
1840  bool bNextBookmark = NearestBookmark( nNextPos, nCurrentPos, true );
1841  if( nCurrentPos == aAttrIter->WhereNext() && ( !bNextBookmark || nNextPos > aAttrIter->WhereNext() ) )
1842  aAttrIter->NextPos();
1843 }
1844 
1845 bool MSWordExportBase::GetBookmarks( const SwTextNode& rNd, sal_Int32 nStt,
1846  sal_Int32 nEnd, IMarkVector& rArr )
1847 {
1848  IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
1849  sal_uLong nNd = rNd.GetIndex( );
1850 
1851  const sal_Int32 nMarks = pMarkAccess->getAllMarksCount();
1852  for ( sal_Int32 i = 0; i < nMarks; i++ )
1853  {
1854  IMark* pMark = pMarkAccess->getAllMarksBegin()[i];
1855 
1856  switch (IDocumentMarkAccess::GetType( *pMark ))
1857  {
1866  continue; // ignore irrelevant marks
1870  break;
1871  }
1872 
1873  // Only keep the bookmarks starting or ending in this node
1874  if ( pMark->GetMarkStart().nNode == nNd ||
1875  pMark->GetMarkEnd().nNode == nNd )
1876  {
1877  const sal_Int32 nBStart = pMark->GetMarkStart().nContent.GetIndex();
1878  const sal_Int32 nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
1879 
1880  // Keep only the bookmarks starting or ending in the snippet
1881  bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( nBStart >= nStt ) && ( nBStart <= nEnd );
1882  bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
1883 
1884  if ( bIsStartOk || bIsEndOk )
1885  {
1886  rArr.push_back( pMark );
1887  }
1888  }
1889  }
1890  return ( !rArr.empty() );
1891 }
1892 
1893 bool MSWordExportBase::GetAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nStt,
1894  sal_Int32 nEnd, IMarkVector& rArr )
1895 {
1896  IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
1897  sal_uLong nNd = rAttrs.GetNode().GetIndex();
1898 
1899  const sal_Int32 nMarks = pMarkAccess->getAnnotationMarksCount();
1900  for ( sal_Int32 i = 0; i < nMarks; i++ )
1901  {
1902  IMark* pMark = pMarkAccess->getAnnotationMarksBegin()[i];
1903 
1904  // Only keep the bookmarks starting or ending in this node
1905  if ( pMark->GetMarkStart().nNode == nNd ||
1906  pMark->GetMarkEnd().nNode == nNd )
1907  {
1908  const sal_Int32 nBStart = pMark->GetMarkStart().nContent.GetIndex();
1909  const sal_Int32 nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
1910 
1911  // Keep only the bookmarks starting or ending in the snippet
1912  bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( nBStart >= nStt ) && ( nBStart <= nEnd );
1913  bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
1914 
1915  // Annotation marks always have at least one character: the anchor
1916  // point of the comment field. In this case Word wants only the
1917  // comment field, so ignore the annotation mark itself.
1918  bool bSingleChar = pMark->GetMarkStart().nNode == pMark->GetMarkEnd().nNode && nBStart + 1 == nBEnd;
1919 
1920  if (bSingleChar)
1921  {
1922  if (rAttrs.HasFlysAt(nBStart))
1923  {
1924  // There is content (an at-char anchored frame) between the annotation mark
1925  // start/end, so still emit range start/end.
1926  bSingleChar = false;
1927  }
1928  }
1929 
1930  if ( ( bIsStartOk || bIsEndOk ) && !bSingleChar )
1931  {
1932  rArr.push_back( pMark );
1933  }
1934  }
1935  }
1936  return ( !rArr.empty() );
1937 }
1938 
1940 {
1941 public:
1942  bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
1943  {
1944  const sal_Int32 nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
1945  const sal_Int32 nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
1946 
1947  return nOEnd < nTEnd;
1948  }
1949 };
1950 
1951 bool MSWordExportBase::NearestBookmark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly )
1952 {
1953  bool bHasBookmark = false;
1954 
1955  if ( !m_rSortedBookmarksStart.empty() )
1956  {
1957  IMark* pMarkStart = m_rSortedBookmarksStart.front();
1958  const sal_Int32 nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
1959  if( !bNextPositionOnly || (nNext > nCurrentPos ))
1960  {
1961  rNearest = nNext;
1962  bHasBookmark = true;
1963  }
1964  }
1965 
1966  if ( !m_rSortedBookmarksEnd.empty() )
1967  {
1968  IMark* pMarkEnd = m_rSortedBookmarksEnd[0];
1969  const sal_Int32 nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
1970  if( !bNextPositionOnly || nNext > nCurrentPos )
1971  {
1972  if ( !bHasBookmark )
1973  rNearest = nNext;
1974  else
1975  rNearest = std::min( rNearest, nNext );
1976  bHasBookmark = true;
1977  }
1978  }
1979 
1980  return bHasBookmark;
1981 }
1982 
1983 void MSWordExportBase::NearestAnnotationMark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly )
1984 {
1985  bool bHasAnnotationMark = false;
1986 
1987  if ( !m_rSortedAnnotationMarksStart.empty() )
1988  {
1989  IMark* pMarkStart = m_rSortedAnnotationMarksStart.front();
1990  const sal_Int32 nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
1991  if( !bNextPositionOnly || (nNext > nCurrentPos ))
1992  {
1993  rNearest = nNext;
1994  bHasAnnotationMark = true;
1995  }
1996  }
1997 
1998  if ( !m_rSortedAnnotationMarksEnd.empty() )
1999  {
2000  IMark* pMarkEnd = m_rSortedAnnotationMarksEnd[0];
2001  const sal_Int32 nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
2002  if( !bNextPositionOnly || nNext > nCurrentPos )
2003  {
2004  if ( !bHasAnnotationMark )
2005  rNearest = nNext;
2006  else
2007  rNearest = std::min( rNearest, nNext );
2008  }
2009  }
2010 }
2011 
2012 void MSWordExportBase::GetSortedAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen )
2013 {
2014  IMarkVector aMarksStart;
2015  if (GetAnnotationMarks(rAttrs, nCurrentPos, nCurrentPos + nLen, aMarksStart))
2016  {
2017  IMarkVector aSortedEnd;
2018  IMarkVector aSortedStart;
2019  for ( IMark* pMark : aMarksStart )
2020  {
2021  // Remove the positions equal to the current pos
2022  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
2023  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
2024 
2025  const SwTextNode& rNode = rAttrs.GetNode();
2026  if ( nStart > nCurrentPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
2027  aSortedStart.push_back( pMark );
2028 
2029  if ( nEnd > nCurrentPos && nEnd <= ( nCurrentPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
2030  aSortedEnd.push_back( pMark );
2031  }
2032 
2033  // Sort the bookmarks by end position
2034  std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
2035 
2036  m_rSortedAnnotationMarksStart.swap( aSortedStart );
2037  m_rSortedAnnotationMarksEnd.swap( aSortedEnd );
2038  }
2039  else
2040  {
2042  m_rSortedAnnotationMarksEnd.clear( );
2043  }
2044 }
2045 
2046 void MSWordExportBase::GetSortedBookmarks( const SwTextNode& rNode, sal_Int32 nCurrentPos, sal_Int32 nLen )
2047 {
2048  IMarkVector aMarksStart;
2049  if ( GetBookmarks( rNode, nCurrentPos, nCurrentPos + nLen, aMarksStart ) )
2050  {
2051  IMarkVector aSortedEnd;
2052  IMarkVector aSortedStart;
2053  for ( IMark* pMark : aMarksStart )
2054  {
2055  // Remove the positions equal to the current pos
2056  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
2057  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
2058 
2059  if ( nStart > nCurrentPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
2060  aSortedStart.push_back( pMark );
2061 
2062  if ( nEnd > nCurrentPos && nEnd <= ( nCurrentPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
2063  aSortedEnd.push_back( pMark );
2064  }
2065 
2066  // Sort the bookmarks by end position
2067  std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
2068 
2069  m_rSortedBookmarksStart.swap( aSortedStart );
2070  m_rSortedBookmarksEnd.swap( aSortedEnd );
2071  }
2072  else
2073  {
2074  m_rSortedBookmarksStart.clear( );
2075  m_rSortedBookmarksEnd.clear( );
2076  }
2077 }
2078 
2080 {
2082  return false;
2083 
2084  const SwPageDesc * pPageDesc = rNd.FindPageDesc()->GetFollow();
2085 
2086  if (m_pCurrentPageDesc != pPageDesc)
2087  {
2089  {
2090  return true;
2091  }
2092  }
2093 
2094  return false;
2095 }
2096 
2098 {
2099  rNd.fillSoftPageBreakList( pList );
2100  pList.insert(0);
2101  pList.insert( rNd.GetText().getLength() );
2102  return pList.size() > 2 && NeedSectionBreak( rNd );
2103 }
2104 
2106 {
2107  SAL_INFO( "sw.ww8", "<OutWW8_SwTextNode>" );
2108 
2109  ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo( m_pTableInfo->getTableNodeInfo( &rNode ) );
2110 
2111  //For i120928,identify the last node
2112  bool bLastCR = false;
2113  bool bExported = false;
2114  {
2115  SwNodeIndex aNextIdx(rNode,1);
2116  SwNodeIndex aLastIdx(rNode.GetNodes().GetEndOfContent());
2117  if (aNextIdx == aLastIdx)
2118  bLastCR = true;
2119  }
2120 
2121  // In order to make sure watermark is stored in 'header.xml', check nTextTyp.
2122  // if it is document.xml, don't write the tags (watermark should be only in the 'header')
2123  SwWW8AttrIter aWatermarkAttrIter( *this, rNode );
2124  if (( TXT_HDFT != m_nTextTyp) && aWatermarkAttrIter.IsWatermarkFrame())
2125  {
2126  return;
2127  }
2128 
2129  bool bFlyInTable = m_pParentFrame && IsInTable();
2130 
2131  SwTextFormatColl& rTextColl = lcl_getFormatCollection( *this, &rNode );
2132  if ( !bFlyInTable )
2133  m_nStyleBeforeFly = GetId( rTextColl );
2134 
2135  // nStyleBeforeFly may change when we recurse into another node, so we
2136  // have to remember it in nStyle
2137  sal_uInt16 nStyle = m_nStyleBeforeFly;
2138 
2139  SwWW8AttrIter aAttrIter( *this, rNode );
2140  rtl_TextEncoding eChrSet = aAttrIter.GetCharSet();
2141 
2142  if ( m_bStartTOX )
2143  {
2144  // ignore TOX header section
2145  const SwSectionNode* pSectNd = rNode.FindSectionNode();
2146  if ( pSectNd && TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() )
2147  {
2148  AttrOutput().StartTOX( pSectNd->GetSection() );
2149  m_aCurrentCharPropStarts.push( 0 );
2150  }
2151  }
2152 
2153  // Emulate: If 1-row table is marked as don't split, then set the row as don't split.
2154  if ( IsInTable() )
2155  {
2156  const SwTableNode* pTableNode = rNode.FindTableNode();
2157  if ( pTableNode )
2158  {
2159  const SwTable& rTable = pTableNode->GetTable();
2160  const bool bKeep = rTable.GetFrameFormat()->GetKeep().GetValue();
2161  const bool bDontSplit = !rTable.GetFrameFormat()->GetLayoutSplit().GetValue();
2162  // bKeep handles this a different way later on, so ignore now
2163  if ( !bKeep && bDontSplit && rTable.GetTabLines().size() == 1 )
2164  {
2165  // bDontSplit : set don't split once for the row
2166  // but only for non-complex tables
2167  const SwTableBox* pBox = rNode.GetTableBox();
2168  const SwTableLine* pLine = pBox ? pBox->GetUpper() : nullptr;
2169  if ( pLine && !pLine->GetUpper() )
2170  {
2171  // check if box is first in that line:
2172  if ( 0 == pLine->GetBoxPos( pBox ) && pBox->GetSttNd() )
2173  {
2174  // check if paragraph is first in that line:
2175  if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
2176  pLine->GetFrameFormat()->SetFormatAttr(SwFormatRowSplit(!bDontSplit));
2177  }
2178  }
2179  }
2180  }
2181  }
2182 
2183  SwSoftPageBreakList softBreakList;
2184  // Let's decide if we need to split the paragraph because of a section break
2185  bool bNeedParaSplit = NeedTextNodeSplit( rNode, softBreakList )
2186  && !IsInTable();
2187 
2188  auto aBreakIt = softBreakList.begin();
2189  // iterate through portions on different pages
2190  do
2191  {
2192  sal_Int32 nCurrentPos = *aBreakIt;
2193 
2194  if( softBreakList.size() > 1 ) // not for empty paragraph
2195  ++aBreakIt;
2196 
2197  AttrOutput().StartParagraph( pTextNodeInfo );
2198 
2199  const SwSection* pTOXSect = nullptr;
2200  if( m_bInWriteTOX )
2201  {
2202  // check for end of TOX
2203  SwNodeIndex aIdx( rNode, 1 );
2204  if( !aIdx.GetNode().IsTextNode() )
2205  {
2206  const SwSectionNode* pTOXSectNd = rNode.FindSectionNode();
2207  if ( pTOXSectNd )
2208  {
2209  pTOXSect = &pTOXSectNd->GetSection();
2210 
2211  const SwNode* pNxt = rNode.GetNodes().GoNext( &aIdx );
2212  if( pNxt && pNxt->FindSectionNode() == pTOXSectNd )
2213  pTOXSect = nullptr;
2214  }
2215  }
2216  }
2217 
2218  if ( aAttrIter.RequiresImplicitBookmark() )
2219  {
2220  OUString sBkmkName = "_toc" + OUString::number( rNode.GetIndex() );
2221  // Add a bookmark converted to a Word name.
2222  AppendBookmark( BookmarkToWord( sBkmkName ) );
2223  }
2224 
2225  // Call this before write out fields and runs
2226  AttrOutput().GenerateBookmarksForSequenceField(rNode, aAttrIter);
2227 
2228  const OUString& aStr( rNode.GetText() );
2229 
2230  sal_Int32 const nEnd = bNeedParaSplit ? *aBreakIt : aStr.getLength();
2231  bool bIncludeEndOfParaCRInRedlineProperties = false;
2232  sal_Int32 nOpenAttrWithRange = 0;
2233 
2234  ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner;
2235  if ( pTextNodeInfo.get() != nullptr )
2236  {
2237  pTextNodeInfoInner = pTextNodeInfo->getFirstInner();
2238  }
2239 
2240  do {
2241 
2242  const SwRedlineData* pRedlineData = aAttrIter.GetRunLevelRedline( nCurrentPos );
2243  FlyProcessingState nStateOfFlyFrame = FLY_PROCESSED;
2244  bool bPostponeWritingText = false ;
2245  OUString aSavedSnippet ;
2246 
2247  sal_Int32 nNextAttr = GetNextPos( &aAttrIter, rNode, nCurrentPos );
2248 
2249  // Skip un-exportable attributes.
2250  if (!aAttrIter.IsExportableAttr(nCurrentPos))
2251  {
2252  nCurrentPos = nNextAttr;
2253  UpdatePosition(&aAttrIter, nCurrentPos);
2254  eChrSet = aAttrIter.GetCharSet();
2255  continue;
2256  }
2257 
2258  // Is this the only run in this paragraph and it's empty?
2259  bool bSingleEmptyRun = nCurrentPos == 0 && nNextAttr == 0;
2260  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2261 
2262  if( nNextAttr > nEnd )
2263  nNextAttr = nEnd;
2264 
2265  if( m_nTextTyp == TXT_FTN || m_nTextTyp == TXT_EDN )
2266  {
2267  if( AttrOutput().FootnoteEndnoteRefTag() )
2268  {
2269  AttrOutput().EndRun( &rNode, nCurrentPos, nNextAttr == nEnd );
2270  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2271  }
2272  }
2273 
2274  /*
2275  1) If there is a text node and an overlapping anchor, then write them in two different
2276  runs and not as part of the same run.
2277  2) Ensure that it is a text node and not in a fly.
2278  3) If the anchor is associated with a text node with empty text then we ignore.
2279  */
2280  if( rNode.IsTextNode()
2281  && aStr != "\001" && !aStr.isEmpty()
2282  && !rNode.GetFlyFormat()
2283  && !(IsInTable() && !AllowPostponedTextInTable())
2284  && aAttrIter.IsAnchorLinkedToThisNode(rNode.GetIndex()) )
2285  {
2286  bPostponeWritingText = true ;
2287  }
2288 
2289  nStateOfFlyFrame = aAttrIter.OutFlys( nCurrentPos );
2290  AttrOutput().SetStateOfFlyFrame( nStateOfFlyFrame );
2291  AttrOutput().SetAnchorIsLinkedToNode( bPostponeWritingText && (FLY_POSTPONED != nStateOfFlyFrame) );
2292  // Append bookmarks in this range after flys, exclusive of final
2293  // position of this range
2294  AppendBookmarks( rNode, nCurrentPos, nNextAttr - nCurrentPos );
2295  AppendAnnotationMarks(aAttrIter, nCurrentPos, nNextAttr - nCurrentPos);
2296 
2297  // At the moment smarttags are only written for paragraphs, at the
2298  // beginning of the paragraph.
2299  if (nCurrentPos == 0)
2300  AppendSmartTags(rNode);
2301 
2302  bool bTextAtr = aAttrIter.IsTextAttr( nCurrentPos );
2303  nOpenAttrWithRange += aAttrIter.OutAttrWithRange( rNode, nCurrentPos );
2304 
2305  sal_Int32 nLen = nNextAttr - nCurrentPos;
2306  if ( !bTextAtr && nLen )
2307  {
2308  sal_Unicode ch = aStr[nCurrentPos];
2309 
2310  const sal_Int32 ofs = (ch == CH_TXT_ATR_FIELDSTART
2311  || ch == CH_TXT_ATR_FIELDSEP
2312  || ch == CH_TXT_ATR_FIELDEND
2313  || ch == CH_TXT_ATR_FORMELEMENT)
2314  ? 1 : 0;
2315 
2316  IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
2317  if ( ch == CH_TXT_ATR_FIELDSTART )
2318  {
2319  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2320  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2321  assert(pFieldmark);
2322 
2323  // Date field is exported as content control, not as a simple field
2324  if (pFieldmark->GetFieldname() == ODF_FORMDATE)
2325  {
2326  if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
2327  {
2328  OutputField( nullptr, lcl_getFieldId( pFieldmark ),
2329  lcl_getFieldCode( pFieldmark ),
2331  WriteFormData( *pFieldmark );
2332  }
2333  }
2334  else
2335  {
2336 
2337  if (pFieldmark->GetFieldname() == ODF_FORMTEXT
2338  && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
2339  {
2340  AppendBookmark( pFieldmark->GetName() );
2341  }
2342  ww::eField eFieldId = lcl_getFieldId( pFieldmark );
2343  OUString sCode = lcl_getFieldCode( pFieldmark );
2344  if (pFieldmark->GetFieldname() == ODF_UNHANDLED )
2345  {
2346  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
2347  if ( it != pFieldmark->GetParameters()->end() )
2348  {
2349  OUString sFieldId;
2350  it->second >>= sFieldId;
2351  eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
2352  }
2353 
2354  it = pFieldmark->GetParameters()->find( ODF_CODE_PARAM );
2355  if ( it != pFieldmark->GetParameters()->end() )
2356  {
2357  it->second >>= sCode;
2358  }
2359  }
2360 
2361  OutputField( nullptr, eFieldId, sCode, FieldFlags::Start | FieldFlags::CmdStart );
2362 
2363  if (pFieldmark->GetFieldname() == ODF_FORMTEXT)
2364  WriteFormData( *pFieldmark );
2365  else if (pFieldmark->GetFieldname() == ODF_HYPERLINK)
2366  WriteHyperlinkData( *pFieldmark );
2367  }
2368  }
2369  else if (ch == CH_TXT_ATR_FIELDSEP)
2370  {
2371  SwPosition aPosition(rNode, SwIndex(&rNode, nCurrentPos));
2372  // the innermost field is the correct one
2373  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkFor(aPosition);
2374  assert(pFieldmark);
2375  // DateFieldmark / ODF_FORMDATE is not a field...
2376  if (pFieldmark->GetFieldname() != ODF_FORMDATE)
2377  {
2378  OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::CmdEnd );
2379 
2380  if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
2381  {
2382  // Check for the presence of a linked OLE object
2383  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_OLE_PARAM );
2384  if ( it != pFieldmark->GetParameters()->end() )
2385  {
2386  OUString sOleId;
2387  uno::Any aValue = it->second;
2388  aValue >>= sOleId;
2389  if ( !sOleId.isEmpty() )
2390  OutputLinkedOLE( sOleId );
2391  }
2392  }
2393  }
2394  }
2395  else if ( ch == CH_TXT_ATR_FIELDEND )
2396  {
2397  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2398  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2399 
2400  assert(pFieldmark);
2401 
2402  if (pFieldmark->GetFieldname() == ODF_FORMDATE)
2403  {
2404  if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
2405  {
2406  OutputField( nullptr, ww::eFORMDATE, OUString(), FieldFlags::Close );
2407  }
2408  }
2409  else
2410  {
2411  ww::eField eFieldId = lcl_getFieldId( pFieldmark );
2412  if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
2413  {
2414  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
2415  if ( it != pFieldmark->GetParameters()->end() )
2416  {
2417  OUString sFieldId;
2418  it->second >>= sFieldId;
2419  eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
2420  }
2421  }
2422 
2423  OutputField( nullptr, eFieldId, OUString(), FieldFlags::Close );
2424 
2425  if (pFieldmark->GetFieldname() == ODF_FORMTEXT
2426  && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
2427  {
2428  AppendBookmark( pFieldmark->GetName() );
2429  }
2430  }
2431  }
2432  else if ( ch == CH_TXT_ATR_FORMELEMENT )
2433  {
2434  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2435  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2436  assert(pFieldmark);
2437 
2438  bool const isDropdownOrCheckbox(pFieldmark->GetFieldname() == ODF_FORMDROPDOWN ||
2439  pFieldmark->GetFieldname() == ODF_FORMCHECKBOX);
2440  if ( isDropdownOrCheckbox )
2441  AppendBookmark( pFieldmark->GetName() );
2442  OutputField( nullptr, lcl_getFieldId( pFieldmark ),
2443  lcl_getFieldCode( pFieldmark ),
2445  if ( isDropdownOrCheckbox )
2446  WriteFormData( *pFieldmark );
2447  OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::Close );
2448  if ( isDropdownOrCheckbox )
2449  AppendBookmark( pFieldmark->GetName() );
2450  }
2451  nLen -= ofs;
2452 
2453  // if paragraph needs to be split, write only until split position
2454  assert(!bNeedParaSplit || nCurrentPos <= *aBreakIt);
2455  if( bNeedParaSplit && nCurrentPos + ofs + nLen > *aBreakIt)
2456  nLen = *aBreakIt - nCurrentPos - ofs;
2457  assert(0 <= nLen);
2458 
2459  OUString aSnippet( aAttrIter.GetSnippet( aStr, nCurrentPos + ofs, nLen ) );
2460  if ( ( m_nTextTyp == TXT_EDN || m_nTextTyp == TXT_FTN ) && nCurrentPos == 0 && nLen > 0 )
2461  {
2462  // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent
2463  sal_Int32 nFirstLineIndent=0;
2465  const SwTextNode* pTextNode( rNode.GetTextNode() );
2466  if ( pTextNode && pTextNode->GetAttr(aSet) )
2467  {
2468  const SvxLRSpaceItem* pLRSpace = aSet.GetItem<SvxLRSpaceItem>(RES_LR_SPACE);
2469  if ( pLRSpace )
2470  nFirstLineIndent = pLRSpace->GetTextFirstLineOfst();
2471  }
2472 
2473  // Insert tab for aesthetic purposes #i24762#
2474  if ( m_bAddFootnoteTab && nFirstLineIndent < 0 && aSnippet[0] != 0x09 )
2475  aSnippet = "\x09" + aSnippet;
2476  m_bAddFootnoteTab = false;
2477  }
2478 
2479  if ( bPostponeWritingText && ( FLY_POSTPONED != nStateOfFlyFrame ) )
2480  {
2481  bPostponeWritingText = true ;
2482  aSavedSnippet = aSnippet ;
2483  }
2484  else
2485  {
2486  bPostponeWritingText = false ;
2487  AttrOutput().RunText( aSnippet, eChrSet );
2488  }
2489  }
2490 
2491  if ( aAttrIter.IsDropCap( nNextAttr ) )
2492  AttrOutput().FormatDrop( rNode, aAttrIter.GetSwFormatDrop(), nStyle, pTextNodeInfo, pTextNodeInfoInner );
2493 
2494  // Only output character attributes if this is not a postponed text run.
2495  if (0 != nEnd && !(bPostponeWritingText && FLY_PROCESSED == nStateOfFlyFrame))
2496  {
2497  // Output the character attributes
2498  // #i51277# do this before writing flys at end of paragraph
2500  aAttrIter.OutAttr( nCurrentPos, false );
2501  AttrOutput().EndRunProperties( pRedlineData );
2502  }
2503 
2504  // At the end of line, output the attributes until the CR.
2505  // Exception: footnotes at the end of line
2506  if ( nNextAttr == nEnd )
2507  {
2508  OSL_ENSURE( nOpenAttrWithRange >= 0, "odd to see this happening, expected >= 0" );
2509  if ( !bTextAtr && nOpenAttrWithRange <= 0 )
2510  {
2511  if ( aAttrIter.IncludeEndOfParaCRInRedlineProperties( nEnd ) )
2512  bIncludeEndOfParaCRInRedlineProperties = true;
2513  else
2514  {
2515  // insert final graphic anchors if any before CR
2516  nStateOfFlyFrame = aAttrIter.OutFlys( nEnd );
2517  // insert final bookmarks if any before CR and after flys
2518  AppendBookmarks( rNode, nEnd, 1 );
2519  AppendAnnotationMarks(aAttrIter, nEnd, 1);
2520  if ( pTOXSect )
2521  {
2523  AttrOutput().EndTOX( *pTOXSect ,false);
2524  }
2525  //For i120928,the position of the bullet's graphic is at end of doc
2526  if (bLastCR && (!bExported))
2527  {
2528  ExportGrfBullet(rNode);
2529  bExported = true;
2530  }
2531 
2532  WriteCR( pTextNodeInfoInner );
2533  }
2534  }
2535  }
2536 
2537  if (0 == nEnd)
2538  {
2539  // Output the character attributes
2540  // do it after WriteCR for an empty paragraph (otherwise
2541  // WW8_WrFkp::Append throws SPRMs away...)
2543  aAttrIter.OutAttr( nCurrentPos, false );
2544  AttrOutput().EndRunProperties( pRedlineData );
2545  }
2546 
2547  // Exception: footnotes at the end of line
2548  if ( nNextAttr == nEnd )
2549  {
2550  OSL_ENSURE(nOpenAttrWithRange >= 0,
2551  "odd to see this happening, expected >= 0");
2552  bool bAttrWithRange = (nOpenAttrWithRange > 0);
2553  if ( nCurrentPos != nEnd )
2554  {
2555  nOpenAttrWithRange += aAttrIter.OutAttrWithRange( rNode, nEnd );
2556  OSL_ENSURE(nOpenAttrWithRange == 0,
2557  "odd to see this happening, expected 0");
2558  }
2559 
2560  // !bIncludeEndOfParaCRInRedlineProperties implies we have just
2561  // emitted a CR, in which case we want to pass force=true to
2562  // OutputFKP to ensure that an FKP entry for direct character
2563  // formatting is written even if empty, so that the next one will
2564  // start after the CR.
2565  AttrOutput().OutputFKP(!bIncludeEndOfParaCRInRedlineProperties);
2566 
2567  if (bTextAtr || bAttrWithRange || bIncludeEndOfParaCRInRedlineProperties)
2568  {
2569  // insert final graphic anchors if any before CR
2570  nStateOfFlyFrame = aAttrIter.OutFlys( nEnd );
2571  // insert final bookmarks if any before CR and after flys
2572  AppendBookmarks( rNode, nEnd, 1 );
2573  AppendAnnotationMarks(aAttrIter, nEnd, 1);
2574  WriteCR( pTextNodeInfoInner );
2575  // #i120928 - position of the bullet's graphic is at end of doc
2576  if (bLastCR && (!bExported))
2577  {
2578  ExportGrfBullet(rNode);
2579  bExported = true;
2580  }
2581 
2582  if ( pTOXSect )
2583  {
2585  AttrOutput().EndTOX( *pTOXSect );
2586  }
2587 
2588  if (bIncludeEndOfParaCRInRedlineProperties)
2589  {
2590  AttrOutput().Redline( aAttrIter.GetRunLevelRedline( nEnd ) );
2591  //If there was no redline property emitted, force adding
2592  //another entry for the CR so that in the case that this
2593  //has no redline, but the next para does, then this one is
2594  //not merged with the next
2595  AttrOutput().OutputFKP(true);
2596  }
2597  }
2598  }
2599 
2601 
2602  if( bPostponeWritingText && FLY_PROCESSED == nStateOfFlyFrame )
2603  {
2604  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2605  //write the postponed text run
2606  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2609  if (0 != nEnd)
2610  {
2612  aAttrIter.OutAttr( nCurrentPos, false );
2613  AttrOutput().EndRunProperties( pRedlineData );
2614  }
2615  AttrOutput().RunText( aSavedSnippet, eChrSet );
2616  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2617  }
2618  else if( bPostponeWritingText && !aSavedSnippet.isEmpty() )
2619  {
2620  //write the postponed text run
2621  AttrOutput().RunText( aSavedSnippet, eChrSet );
2622  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2623  }
2624  else
2625  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2626 
2627  nCurrentPos = nNextAttr;
2628  UpdatePosition( &aAttrIter, nCurrentPos );
2629  eChrSet = aAttrIter.GetCharSet();
2630  }
2631  while ( nCurrentPos < nEnd );
2632 
2633  // if paragraph is split, put the section break between the parts
2634  if( bNeedParaSplit && *aBreakIt != rNode.GetText().getLength() )
2635  {
2636  SwNodeIndex aNextIndex( rNode, 1 );
2637  const SwNode& pNextNode = aNextIndex.GetNode();
2638  // if there is a next node, use its attributes to create the new
2639  // section
2640  if( pNextNode.IsTextNode() )
2641  {
2642  const SwTextNode& rNextNode = *static_cast<SwTextNode*>(
2643  &aNextIndex.GetNode() );
2644  OutputSectionBreaks(rNextNode.GetpSwAttrSet(), rNextNode);
2645  }
2646  else if (pNextNode.IsEndNode() )
2647  {
2648  // In this case the same paragraph holds the next page style
2649  // too.
2650  const SwPageDesc* pNextPageDesc = m_pCurrentPageDesc->GetFollow();
2651  assert(pNextPageDesc);
2652  PrepareNewPageDesc( rNode.GetpSwAttrSet(), rNode, nullptr , pNextPageDesc);
2653  }
2654  }
2655  else if (!bNeedParaSplit)
2656  {
2657  // else check if section break needed after the paragraph
2658  AttrOutput().SectionBreaks(rNode);
2659  }
2660 
2662 
2663  AttrOutput().ParagraphStyle( nStyle );
2664 
2665  if ( m_pParentFrame && IsInTable() ) // Fly-Attrs
2666  OutputFormat( m_pParentFrame->GetFrameFormat(), false, false, true );
2667 
2668  if ( pTextNodeInfo.get() != nullptr )
2669  {
2670 #ifdef DBG_UTIL
2671  SAL_INFO( "sw.ww8", pTextNodeInfo->toString());
2672 #endif
2673 
2674  AttrOutput().TableInfoCell( pTextNodeInfoInner );
2675  if (pTextNodeInfoInner->isFirstInTable())
2676  {
2677  const SwTable * pTable = pTextNodeInfoInner->getTable();
2678 
2679  const SwTableFormat* pTabFormat = pTable->GetFrameFormat();
2680  if (pTabFormat != nullptr)
2681  {
2682  if (pTabFormat->GetBreak().GetBreak() == SvxBreak::PageBefore)
2683  AttrOutput().PageBreakBefore(true);
2684  }
2685  }
2686  }
2687 
2688  if ( !bFlyInTable )
2689  {
2690  SfxItemSet* pTmpSet = nullptr;
2691  const sal_uInt8 nPrvNxtNd = rNode.HasPrevNextLayNode();
2692 
2693  if( (ND_HAS_PREV_LAYNODE|ND_HAS_NEXT_LAYNODE ) != nPrvNxtNd )
2694  {
2695  const SfxPoolItem* pItem;
2696  if( SfxItemState::SET == rNode.GetSwAttrSet().GetItemState(
2697  RES_UL_SPACE, true, &pItem ) &&
2698  ( ( !( ND_HAS_PREV_LAYNODE & nPrvNxtNd ) &&
2699  static_cast<const SvxULSpaceItem*>(pItem)->GetUpper()) ||
2700  ( !( ND_HAS_NEXT_LAYNODE & nPrvNxtNd ) &&
2701  static_cast<const SvxULSpaceItem*>(pItem)->GetLower()) ))
2702  {
2703  pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
2704  SvxULSpaceItem aUL( *static_cast<const SvxULSpaceItem*>(pItem) );
2705  // #i25901#- consider compatibility option
2707  {
2708  if( !(ND_HAS_PREV_LAYNODE & nPrvNxtNd ))
2709  aUL.SetUpper( 0 );
2710  }
2711  // #i25901# - consider compatibility option
2713  {
2714  if( !(ND_HAS_NEXT_LAYNODE & nPrvNxtNd ))
2715  aUL.SetLower( 0 );
2716  }
2717  pTmpSet->Put( aUL );
2718  }
2719  }
2720 
2721  const bool bParaRTL = aAttrIter.IsParaRTL();
2722 
2723  int nNumberLevel = -1;
2724  if (rNode.IsNumbered())
2725  nNumberLevel = rNode.GetActualListLevel();
2726  if (nNumberLevel >= 0 && nNumberLevel < MAXLEVEL)
2727  {
2728  const SwNumRule* pRule = rNode.GetNumRule();
2729  sal_uInt8 nLvl = static_cast< sal_uInt8 >(nNumberLevel);
2730  const SwNumFormat* pFormat = pRule->GetNumFormat( nLvl );
2731  if( !pFormat )
2732  pFormat = &pRule->Get( nLvl );
2733 
2734  if( !pTmpSet )
2735  pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
2736 
2737  SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*pTmpSet, RES_LR_SPACE));
2738  // #i86652#
2739  if ( pFormat->GetPositionAndSpaceMode() ==
2741  {
2742  aLR.SetTextLeft( aLR.GetTextLeft() + pFormat->GetAbsLSpace() );
2743  }
2744 
2745  if( rNode.IsNumbered() && rNode.IsCountedInList() )
2746  {
2747  // #i86652#
2748  if ( pFormat->GetPositionAndSpaceMode() ==
2750  {
2751  if (bParaRTL)
2752  aLR.SetTextFirstLineOfstValue(pFormat->GetAbsLSpace() - pFormat->GetFirstLineOffset()); //TODO: overflow
2753  else
2754  aLR.SetTextFirstLineOfst(GetWordFirstLineOffset(*pFormat));
2755  }
2756 
2757  // correct fix for issue i94187
2758  if (SfxItemState::SET !=
2759  pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2760  {
2761  // List style set via paragraph style - then put it into the itemset.
2762  // This is needed to get list level and list id exported for
2763  // the paragraph.
2764  pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
2765 
2766  // Put indent values into the itemset in case that the list
2767  // style is applied via paragraph style and the list level
2768  // indent values are not applicable.
2769  if ( pFormat->GetPositionAndSpaceMode() ==
2772  {
2773  pTmpSet->Put( aLR );
2774  }
2775  }
2776  }
2777  else
2778  pTmpSet->ClearItem(RES_PARATR_NUMRULE);
2779 
2780  // #i86652#
2781  if ( pFormat->GetPositionAndSpaceMode() ==
2783  {
2784  pTmpSet->Put(aLR);
2785 
2786  //#i21847#
2787  SvxTabStopItem aItem(
2788  ItemGet<SvxTabStopItem>(*pTmpSet, RES_PARATR_TABSTOP));
2789  SvxTabStop aTabStop(pFormat->GetAbsLSpace());
2790  aItem.Insert(aTabStop);
2791  pTmpSet->Put(aItem);
2792 
2794  }
2795  }
2796 
2797  /*
2798  If a given para is using the SvxFrameDirection::Environment direction we
2799  cannot export that, if it's ltr then that's ok as that is word's
2800  default. Otherwise we must add a RTL attribute to our export list
2801  Only necessary if the ParaStyle doesn't define the direction.
2802  */
2803  const SvxFrameDirectionItem* pItem =
2805  if (
2806  (!pItem || pItem->GetValue() == SvxFrameDirection::Environment) &&
2807  rTextColl.GetFrameDir().GetValue() == SvxFrameDirection::Environment
2808  )
2809  {
2810  if ( !pTmpSet )
2811  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2812 
2813  if ( bParaRTL )
2814  pTmpSet->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_RL_TB, RES_FRAMEDIR));
2815  else
2816  pTmpSet->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB, RES_FRAMEDIR));
2817 
2818  const SvxAdjustItem* pAdjust = rNode.GetSwAttrSet().GetItem(RES_PARATR_ADJUST);
2819  if ( pAdjust && (pAdjust->GetAdjust() == SvxAdjust::Left || pAdjust->GetAdjust() == SvxAdjust::Right ) )
2820  pTmpSet->Put( *pAdjust, RES_PARATR_ADJUST );
2821  }
2822  // move code for handling of numbered,
2823  // but not counted paragraphs to this place. Otherwise, the paragraph
2824  // isn't exported as numbered, but not counted, if no other attribute
2825  // is found in <pTmpSet>
2826  // #i44815# adjust numbering/indents for numbered paragraphs
2827  // without number (NO_NUMLEVEL)
2828  // #i47013# need to check rNode.GetNumRule()!=NULL as well.
2829  if ( ! rNode.IsCountedInList() && rNode.GetNumRule()!=nullptr )
2830  {
2831  // WW8 does not know numbered paragraphs without number
2832  // (NO_NUMLEVEL). In WW8AttributeOutput::ParaNumRule(), we will export
2833  // the RES_PARATR_NUMRULE as list-id 0, which in WW8 means
2834  // no numbering. Here, we will adjust the indents to match
2835  // visually.
2836 
2837  if ( !pTmpSet )
2838  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2839 
2840  // create new LRSpace item, based on the current (if present)
2841  const SfxPoolItem* pPoolItem = nullptr;
2842  pTmpSet->GetItemState(RES_LR_SPACE, true, &pPoolItem);
2843  SvxLRSpaceItem aLRSpace(
2844  ( pPoolItem == nullptr )
2845  ? SvxLRSpaceItem(0, 0, 0, 0, RES_LR_SPACE)
2846  : *static_cast<const SvxLRSpaceItem*>( pPoolItem ) );
2847 
2848  // new left margin = old left + label space
2849  const SwNumRule* pRule = rNode.GetNumRule();
2850  int nLevel = rNode.GetActualListLevel();
2851 
2852  if (nLevel < 0)
2853  nLevel = 0;
2854 
2855  if (nLevel >= MAXLEVEL)
2856  nLevel = MAXLEVEL - 1;
2857 
2858  const SwNumFormat& rNumFormat = pRule->Get( static_cast< sal_uInt16 >(nLevel) );
2859 
2860  // #i86652#
2861  if ( rNumFormat.GetPositionAndSpaceMode() ==
2863  {
2864  aLRSpace.SetTextLeft( aLRSpace.GetLeft() + rNumFormat.GetAbsLSpace() );
2865  }
2866  else
2867  {
2868  aLRSpace.SetTextLeft( aLRSpace.GetLeft() + rNumFormat.GetIndentAt() );
2869  }
2870 
2871  // new first line indent = 0
2872  // (first line indent is ignored for NO_NUMLEVEL)
2873  if (!bParaRTL)
2874  aLRSpace.SetTextFirstLineOfst( 0 );
2875 
2876  // put back the new item
2877  pTmpSet->Put( aLRSpace );
2878 
2879  // assure that numbering rule is in <pTmpSet>
2880  if (SfxItemState::SET != pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2881  {
2882  pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
2883  }
2884  }
2885 
2886  // #i75457#
2887  // Export page break after attribute from paragraph style.
2888  // If page break attribute at the text node exist, an existing page
2889  // break after at the paragraph style hasn't got to be considered.
2890  if ( !rNode.GetpSwAttrSet() ||
2891  SfxItemState::SET != rNode.GetpSwAttrSet()->GetItemState(RES_BREAK, false) )
2892  {
2893  const SvxFormatBreakItem& rBreakAtParaStyle
2894  = ItemGet<SvxFormatBreakItem>(rNode.GetSwAttrSet(), RES_BREAK);
2895  if (rBreakAtParaStyle.GetBreak() == SvxBreak::PageAfter)
2896  {
2897  if ( !pTmpSet )
2898  {
2899  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2900  }
2901  pTmpSet->Put(rBreakAtParaStyle);
2902  }
2903  else if( pTmpSet )
2904  { // Even a pagedesc item is set, the break item can be set 'NONE',
2905  // this has to be overruled.
2906  const SwFormatPageDesc& rPageDescAtParaStyle =
2907  ItemGet<SwFormatPageDesc>( rNode, RES_PAGEDESC );
2908  if( rPageDescAtParaStyle.KnowsPageDesc() )
2909  pTmpSet->ClearItem( RES_BREAK );
2910  }
2911  }
2912 
2913  // #i76520# Emulate non-splitting tables
2914  if ( IsInTable() )
2915  {
2916  const SwTableNode* pTableNode = rNode.FindTableNode();
2917 
2918  if ( pTableNode )
2919  {
2920  const SwTable& rTable = pTableNode->GetTable();
2921  const SvxFormatKeepItem& rKeep = rTable.GetFrameFormat()->GetKeep();
2922  const bool bKeep = rKeep.GetValue();
2923  const bool bDontSplit = !(bKeep ||
2924  rTable.GetFrameFormat()->GetLayoutSplit().GetValue());
2925 
2926  if ( bKeep || bDontSplit )
2927  {
2928  // bKeep: set keep at first paragraphs in all lines
2929  // bDontSplit : set keep at first paragraphs in all lines except from last line
2930  // but only for non-complex tables
2931  const SwTableBox* pBox = rNode.GetTableBox();
2932  const SwTableLine* pLine = pBox ? pBox->GetUpper() : nullptr;
2933 
2934  if ( pLine && !pLine->GetUpper() )
2935  {
2936  // check if box is first in that line:
2937  if ( 0 == pLine->GetBoxPos( pBox ) && pBox->GetSttNd() )
2938  {
2939  // check if paragraph is first in that line:
2940  if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
2941  {
2942  bool bSetAtPara = false;
2943  if ( bKeep )
2944  bSetAtPara = true;
2945  else if ( bDontSplit )
2946  {
2947  // check if pLine isn't last line in table
2948  if ( rTable.GetTabLines().size() - rTable.GetTabLines().GetPos( pLine ) != 1 )
2949  bSetAtPara = true;
2950  }
2951 
2952  if ( bSetAtPara )
2953  {
2954  if ( !pTmpSet )
2955  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2956 
2957  const SvxFormatKeepItem aKeepItem( true, RES_KEEP );
2958  pTmpSet->Put( aKeepItem );
2959  }
2960  }
2961  }
2962  }
2963  }
2964  }
2965  }
2966 
2967  const SfxItemSet* pNewSet = pTmpSet ? pTmpSet : rNode.GetpSwAttrSet();
2968  if( pNewSet )
2969  { // Para-Attrs
2970  m_pStyAttr = &rNode.GetAnyFormatColl().GetAttrSet();
2971 
2972  const SwModify* pOldMod = m_pOutFormatNode;
2973  m_pOutFormatNode = &rNode;
2974 
2975  // Pap-Attrs, so script is not necessary
2976  OutputItemSet( *pNewSet, true, false, i18n::ScriptType::LATIN, false);
2977 
2978  m_pStyAttr = nullptr;
2979  m_pOutFormatNode = pOldMod;
2980 
2981  if( pNewSet != rNode.GetpSwAttrSet() )
2982  delete pNewSet;
2983  }
2984  }
2985 
2986  // The formatting of the paragraph marker has two sources:
2987  // 0) If there is a RES_PARATR_LIST_AUTOFMT, then use that.
2988  // 1) If there are hints at the end of the paragraph, then use that.
2989  // 2) Else use the RES_CHRATR_BEGIN..RES_TXTATR_END range of the paragraph
2990  // properties.
2991  //
2992  // Exception: if there is a character style hint at the end of the
2993  // paragraph only, then still go with 2), as RES_TXTATR_CHARFMT is always
2994  // set as a hint.
2996  bool bCharFormatOnly = true;
2997 
2998  SwFormatAutoFormat const& rListAutoFormat(static_cast<SwFormatAutoFormat const&>(rNode.GetAttr(RES_PARATR_LIST_AUTOFMT)));
2999  if (std::shared_ptr<SfxItemSet> const& pSet = rListAutoFormat.GetStyleHandle())
3000  {
3001  aParagraphMarkerProperties.Put(*pSet);
3002  bCharFormatOnly = false;
3003  // TODO: still need to check for a RES_TXTATR_CHARFMT hint...
3004  }
3005  if (const SwpHints* pTextAttrs = rNode.GetpSwpHints())
3006  {
3007  for( size_t i = 0; i < pTextAttrs->Count(); ++i )
3008  {
3009  const SwTextAttr* pHt = pTextAttrs->Get(i);
3010  const sal_Int32 startPos = pHt->GetStart(); // first Attr characters
3011  const sal_Int32* endPos = pHt->End(); // end Attr characters
3012  // Check if these attributes are for the last character in the paragraph
3013  // - which means the paragraph marker. If a paragraph has 7 characters,
3014  // then properties on character 8 are for the paragraph marker
3015  if( endPos && (startPos == *endPos ) && (*endPos == rNode.GetText().getLength()) )
3016  {
3017  SAL_INFO( "sw.ww8", startPos << "startPos == endPos" << *endPos);
3018  sal_uInt16 nWhich = pHt->GetAttr().Which();
3019  SAL_INFO( "sw.ww8", "nWhich" << nWhich);
3020  if ((nWhich == RES_TXTATR_AUTOFMT && bCharFormatOnly)
3021  || nWhich == RES_TXTATR_CHARFMT)
3022  {
3023  aParagraphMarkerProperties.Put(pHt->GetAttr());
3024  }
3025  if (nWhich != RES_TXTATR_CHARFMT)
3026  bCharFormatOnly = false;
3027  }
3028  }
3029  }
3030  if (rNode.GetpSwAttrSet() && bCharFormatOnly)
3031  {
3032  aParagraphMarkerProperties.Put(*rNode.GetpSwAttrSet());
3033  }
3034  const SwRedlineData* pRedlineParagraphMarkerDelete = AttrOutput().GetParagraphMarkerRedline( rNode, RedlineType::Delete );
3035  const SwRedlineData* pRedlineParagraphMarkerInsert = AttrOutput().GetParagraphMarkerRedline( rNode, RedlineType::Insert );
3036  const SwRedlineData* pParagraphRedlineData = aAttrIter.GetParagraphLevelRedline( );
3037  AttrOutput().EndParagraphProperties(aParagraphMarkerProperties, pParagraphRedlineData, pRedlineParagraphMarkerDelete, pRedlineParagraphMarkerInsert);
3038 
3039  AttrOutput().EndParagraph( pTextNodeInfoInner );
3040  }while(*aBreakIt != rNode.GetText().getLength() && bNeedParaSplit );
3041 
3042  SAL_INFO( "sw.ww8", "</OutWW8_SwTextNode>" );
3043 }
3044 
3045 // Tables
3046 
3048 {
3049  m_rWW8Export.WriteStringAsPara( OUString() );
3050 }
3051 
3053 {
3054  bool bRet = false;
3055  const SfxPoolItem* pI;
3056  if( pSet)
3057  {
3058  bool bNoPageBreak = false;
3059  if ( SfxItemState::SET != pSet->GetItemState(RES_PAGEDESC, true, &pI)
3060  || nullptr == static_cast<const SwFormatPageDesc*>(pI)->GetPageDesc() )
3061  {
3062  bNoPageBreak = true;
3063  }
3064 
3065  if (bNoPageBreak)
3066  {
3067  if (SfxItemState::SET == pSet->GetItemState(RES_BREAK, true, &pI))
3068  {
3069  SvxBreak eBreak = static_cast<const SvxFormatBreakItem*>(pI)->GetBreak();
3070  switch (eBreak)
3071  {
3072  case SvxBreak::PageBefore:
3073  case SvxBreak::PageAfter:
3074  bNoPageBreak = false;
3075  break;
3076  default:
3077  break;
3078  }
3079  }
3080  }
3081  bRet = bNoPageBreak;
3082  }
3083  return bRet;
3084 }
3085 
3087 {
3088  const SwSection& rSection = rSectionNode.GetSection();
3089 
3090  SwNodeIndex aIdx( rSectionNode, 1 );
3091  const SwNode& rNd = aIdx.GetNode();
3092  if ( !rNd.IsSectionNode() && !IsInTable() ) //No sections in table
3093  {
3094  // if the first Node inside the section has an own
3095  // PageDesc or PageBreak attribute, then don't write
3096  // here the section break
3097  sal_uLong nRstLnNum = 0;
3098  const SfxItemSet* pSet;
3099  if ( rNd.IsContentNode() )
3100  {
3101  pSet = &rNd.GetContentNode()->GetSwAttrSet();
3102  nRstLnNum = pSet->Get( RES_LINENUMBER ).GetStartValue();
3103  }
3104  else
3105  pSet = nullptr;
3106 
3107  if ( pSet && NoPageBreakSection( pSet ) )
3108  pSet = nullptr;
3109  else
3110  AttrOutput().SectionBreaks( rSectionNode );
3111 
3112  const bool bInTOX = rSection.GetType() == TOX_CONTENT_SECTION || rSection.GetType() == TOX_HEADER_SECTION;
3113  if ( !pSet && !bInTOX )
3114  {
3115  // new Section with no own PageDesc/-Break
3116  // -> write follow section break;
3117  const SwSectionFormat* pFormat = rSection.GetFormat();
3118  ReplaceCr( msword::PageBreak ); // Indicator for Page/Section-Break
3119 
3120  // Get the page in use at the top of this section
3121  const SwPageDesc *pCurrent = SwPageDesc::GetPageDescOfNode(rNd);
3122  if (!pCurrent)
3123  pCurrent = m_pCurrentPageDesc;
3124 
3125  AppendSection( pCurrent, pFormat, nRstLnNum );
3126  }
3127  }
3128  if ( TOX_CONTENT_SECTION == rSection.GetType() )
3129  {
3130  m_bStartTOX = true;
3131  UpdateTocSectionNodeProperties(rSectionNode);
3132  }
3133 }
3134 
3135 // tdf#121561: During export of the ODT file with TOC inside into DOCX format,
3136 // the TOC title is being exported as regular paragraph. We should surround it
3137 // with <w:sdt><w:sdtPr><w:sdtContent> to make it (TOC title) recognizable
3138 // by MS Word as part of the TOC.
3140 {
3141  // check section type
3142  {
3143  const SwSection& rSection = rSectionNode.GetSection();
3144  if (TOX_CONTENT_SECTION != rSection.GetType())
3145  return;
3146 
3147  const SwTOXBase* pTOX = rSection.GetTOXBase();
3148  if (pTOX)
3149  {
3150  TOXTypes type = pTOX->GetType();
3151  if (type != TOXTypes::TOX_CONTENT)
3152  return;
3153  }
3154  }
3155 
3156  // get section node, skip toc-header node
3157  const SwSectionNode* pSectNd = &rSectionNode;
3158  {
3159  SwNodeIndex aIdxNext( *pSectNd, 1 );
3160  const SwNode& rNdNext = aIdxNext.GetNode();
3161 
3162  if (rNdNext.IsSectionNode())
3163  {
3164  const SwSectionNode* pSectNdNext = static_cast<const SwSectionNode*>(&rNdNext);
3165  if (TOX_HEADER_SECTION == pSectNdNext->GetSection().GetType() &&
3166  pSectNdNext->StartOfSectionNode()->IsSectionNode())
3167  {
3168  pSectNd = pSectNdNext;
3169  }
3170  }
3171  }
3172 
3173  // get node of the first paragraph inside TOC
3174  SwNodeIndex aIdxNext( *pSectNd, 1 );
3175  const SwNode& rNdTocPara = aIdxNext.GetNode();
3176  const SwContentNode* pNode = rNdTocPara.GetContentNode();
3177  if (!pNode)
3178  return;
3179 
3180  // put required flags into grab bag of the first node in TOC
3181  {
3182  uno::Sequence<beans::PropertyValue> aDocPropertyValues(comphelper::InitPropertySequence(
3183  {
3184  {"ooxml:CT_SdtDocPart_docPartGallery", uno::makeAny(OUString("Table of Contents"))},
3185  {"ooxml:CT_SdtDocPart_docPartUnique", uno::makeAny(OUString("true"))},
3186  }));
3187 
3188  uno::Sequence<beans::PropertyValue> aSdtPrPropertyValues(comphelper::InitPropertySequence(
3189  {
3190  {"ooxml:CT_SdtPr_docPartObj", uno::makeAny(aDocPropertyValues)},
3191  }));
3192 
3194  aGrabBag.GetGrabBag()["SdtPr"] <<= aSdtPrPropertyValues;
3195 
3196  // create temp attr set
3197  SwAttrSet aSet(pNode->GetSwAttrSet());
3198  aSet.Put(aGrabBag);
3199 
3200  // set new attr to node
3201  const_cast<SwContentNode*>(pNode)->SetAttr(aSet);
3202  }
3203 
3204  // set flag for the next node after TOC
3205  // in order to indicate that std area has been finished
3206  // see, DomainMapper::lcl_startParagraphGroup() for the same functionality during load
3207  {
3208  SwNodeIndex aEndTocNext( *rSectionNode.EndOfSectionNode(), 1 );
3209  const SwNode& rEndTocNextNode = aEndTocNext.GetNode();
3210  const SwContentNode* pNodeAfterToc = rEndTocNextNode.GetContentNode();
3211  if (pNodeAfterToc)
3212  {
3214  aGrabBag.GetGrabBag()["ParaSdtEndBefore"] <<= true;
3215 
3216  // create temp attr set
3217  SwAttrSet aSet(pNodeAfterToc->GetSwAttrSet());
3218  aSet.Put(aGrabBag);
3219 
3220  // set new attr to node
3221  const_cast<SwContentNode*>(pNodeAfterToc)->SetAttr(aSet);
3222  }
3223  }
3224 }
3225 
3226 void WW8Export::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum )
3227 {
3228  pSepx->AppendSep(Fc2Cp(Strm().Tell()), pPageDesc, pFormat, nLnNum);
3229 }
3230 
3231 // Flys
3232 
3233 void WW8AttributeOutput::OutputFlyFrame_Impl( const ww8::Frame& rFormat, const Point& rNdTopLeft )
3234 {
3235  const SwFrameFormat &rFrameFormat = rFormat.GetFrameFormat();
3236  const SwFormatAnchor& rAnch = rFrameFormat.GetAnchor();
3237 
3238  bool bUseEscher = true;
3239 
3240  if (rFormat.IsInline())
3241  {
3243  bUseEscher = eType != ww8::Frame::eGraphic && eType != ww8::Frame::eOle;
3244 
3245  /*
3246  A special case for converting some inline form controls to form fields
3247  when in winword 8+ mode
3248  */
3249  if (bUseEscher && (eType == ww8::Frame::eFormControl))
3250  {
3251  if ( m_rWW8Export.MiserableFormFieldExportHack( rFrameFormat ) )
3252  return ;
3253  }
3254  }
3255 
3256  if (bUseEscher)
3257  {
3258  // write as escher
3259  m_rWW8Export.AppendFlyInFlys(rFormat, rNdTopLeft);
3260  }
3261  else
3262  {
3263  bool bDone = false;
3264 
3265  // Fetch from node and last node the position in the section
3266  const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
3267 
3268  sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
3269  sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
3270 
3271  if( nStt >= nEnd ) // no range, hence no valid node
3272  return;
3273 
3274  if ( !m_rWW8Export.IsInTable() && rFormat.IsInline() )
3275  {
3276  //Test to see if this textbox contains only a single graphic/ole
3277  SwTextNode* pParTextNode = rAnch.GetContentAnchor()->nNode.GetNode().GetTextNode();
3278  if ( pParTextNode && !m_rWW8Export.m_pDoc->GetNodes()[ nStt ]->IsNoTextNode() )
3279  bDone = true;
3280  }
3281  if( !bDone )
3282  {
3283 
3284  m_rWW8Export.SaveData( nStt, nEnd );
3285 
3286  Point aOffset;
3288  {
3289  /* Munge flys in fly into absolutely positioned elements for word 6 */
3290  const SwTextNode* pParTextNode = rAnch.GetContentAnchor()->nNode.GetNode().GetTextNode();
3291  const SwRect aPageRect = pParTextNode->FindPageFrameRect();
3292 
3293  aOffset = rFrameFormat.FindLayoutRect().Pos();
3294  aOffset -= aPageRect.Pos();
3295 
3296  m_rWW8Export.m_pFlyOffset = &aOffset;
3297  m_rWW8Export.m_eNewAnchorType = RndStdIds::FLY_AT_PAGE;
3298  }
3299 
3300  m_rWW8Export.m_pParentFrame = &rFormat;
3301  if (
3302  m_rWW8Export.IsInTable() &&
3303  (RndStdIds::FLY_AT_PAGE != rAnch.GetAnchorId()) &&
3304  !m_rWW8Export.m_pDoc->GetNodes()[ nStt ]->IsNoTextNode()
3305  )
3306  {
3307  // note: set Flag bOutTable again,
3308  // because we deliver the normal content of the table cell, and no border
3309  // ( Flag was deleted above in aSaveData() )
3310  m_rWW8Export.m_bOutTable = true;
3311  const OUString& aName = rFrameFormat.GetName();
3315  }
3316  else
3318 
3320  }
3321  }
3322 }
3323 
3325 {
3326  if ( !rFormat.GetContentNode() )
3327  return;
3328 
3329  const SwContentNode &rNode = *rFormat.GetContentNode();
3330  Point aLayPos;
3331 
3332  // get the Layout Node-Position
3333  if (RndStdIds::FLY_AT_PAGE == rFormat.GetFrameFormat().GetAnchor().GetAnchorId())
3334  aLayPos = rNode.FindPageFrameRect().Pos();
3335  else
3336  aLayPos = rNode.FindLayoutRect().Pos();
3337 
3338  OutputFlyFrame_Impl( rFormat, aLayPos );
3339 }
3340 
3341 // write data of any redline
3343 {
3344  if ( !pRedline )
3345  return;
3346 
3347  if ( pRedline->Next() )
3348  Redline( pRedline->Next() );
3349 
3350  static const sal_uInt16 insSprmIds[ 3 ] =
3351  {
3352  // Ids for insert // for WW8
3354  };
3355  static const sal_uInt16 delSprmIds[ 3 ] =
3356  {
3357  // Ids for delete // for WW8
3359  };
3360 
3361  const sal_uInt16* pSprmIds = nullptr;
3362  switch( pRedline->GetType() )
3363  {
3364  case RedlineType::Insert:
3365  pSprmIds = insSprmIds;
3366  break;
3367 
3368  case RedlineType::Delete:
3369  pSprmIds = delSprmIds;
3370  break;
3371 
3372  case RedlineType::Format:
3374  m_rWW8Export.pO->push_back( 7 ); // len
3375  m_rWW8Export.pO->push_back( 1 );
3378  break;
3379  default:
3380  OSL_ENSURE(false, "Unhandled redline type for export");
3381  break;
3382  }
3383 
3384  if ( pSprmIds )
3385  {
3386  m_rWW8Export.InsUInt16( pSprmIds[0] );
3387  m_rWW8Export.pO->push_back( 1 );
3388 
3389  m_rWW8Export.InsUInt16( pSprmIds[1] );
3391 
3392  m_rWW8Export.InsUInt16( pSprmIds[2] );
3394  }
3395 }
3396 
3398 {
3399  switch ( rNode.GetNodeType() )
3400  {
3401  case SwNodeType::Text:
3402  OutputTextNode( *rNode.GetTextNode() );
3403  break;
3404  case SwNodeType::Grf:
3405  OutputGrfNode( *rNode.GetGrfNode() );
3406  break;
3407  case SwNodeType::Ole:
3408  OutputOLENode( *rNode.GetOLENode() );
3409  break;
3410  default:
3411  SAL_WARN("sw.ww8", "Unhandled node, type == " << static_cast<int>(rNode.GetNodeType()) );
3412  break;
3413  }
3414 }
3415 
3416 
3417 WW8Ruby::WW8Ruby(const SwTextNode& rNode, const SwFormatRuby& rRuby, const MSWordExportBase& rExport ):
3418  m_nJC(0),
3419  m_cDirective(0),
3420  m_nRubyHeight(0),
3421  m_nBaseHeight(0)
3422 {
3423  switch ( rRuby.GetAdjustment() )
3424  {
3425  case css::text::RubyAdjust_LEFT:
3426  m_nJC = 3;
3427  m_cDirective = 'l';
3428  break;
3429  case css::text::RubyAdjust_CENTER:
3430  //defaults to 0
3431  break;
3432  case css::text::RubyAdjust_RIGHT:
3433  m_nJC = 4;
3434  m_cDirective = 'r';
3435  break;
3436  case css::text::RubyAdjust_BLOCK:
3437  m_nJC = 1;
3438  m_cDirective = 'd';
3439  break;
3440  case css::text::RubyAdjust_INDENT_BLOCK:
3441  m_nJC = 2;
3442  m_cDirective = 'd';
3443  break;
3444  default:
3445  OSL_ENSURE( false,"Unhandled Ruby justification code" );
3446  break;
3447  }
3448 
3449  if ( rRuby.GetPosition() == css::text::RubyPosition::INTER_CHARACTER )
3450  {
3451  m_nJC = 5;
3452  m_cDirective = 0;
3453  }
3454 
3455  /*
3456  MS needs to know the name and size of the font used in the ruby item,
3457  but we could have written it in a mixture of asian and western
3458  scripts, and each of these can be a different font and size than the
3459  other, so we make a guess based upon the first character of the text,
3460  defaulting to asian.
3461  */
3462  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
3463  sal_uInt16 nRubyScript = g_pBreakIt->GetBreakIter()->getScriptType(rRuby.GetText(), 0);
3464 
3465  const SwTextRuby* pRubyText = rRuby.GetTextRuby();
3466  const SwCharFormat* pFormat = pRubyText ? pRubyText->GetCharFormat() : nullptr;
3467 
3468  if (pFormat)
3469  {
3470  const auto& rFont
3471  = ItemGet<SvxFontItem>(*pFormat, GetWhichOfScript(RES_CHRATR_FONT, nRubyScript));
3472  m_sFontFamily = rFont.GetFamilyName();
3473 
3474  const auto& rHeight = ItemGet<SvxFontHeightItem>(
3475  *pFormat, GetWhichOfScript(RES_CHRATR_FONTSIZE, nRubyScript));
3476  m_nRubyHeight = rHeight.GetHeight();
3477  }
3478  else
3479  {
3480  /*Get defaults if no formatting on ruby text*/
3481 
3482  const SfxItemPool* pPool = rNode.GetSwAttrSet().GetPool();
3483  pPool = pPool ? pPool : &rExport.m_pDoc->GetAttrPool();
3484 
3485 
3486  const auto& rFont
3487  = DefaultItemGet<SvxFontItem>(*pPool, GetWhichOfScript(RES_CHRATR_FONT, nRubyScript));
3488  m_sFontFamily = rFont.GetFamilyName();
3489 
3490  const auto& rHeight = DefaultItemGet<SvxFontHeightItem>(
3491  *pPool, GetWhichOfScript(RES_CHRATR_FONTSIZE, nRubyScript));
3492  m_nRubyHeight = rHeight.GetHeight();
3493  }
3494 
3495  if (pRubyText)
3496  nRubyScript
3497  = g_pBreakIt->GetBreakIter()->getScriptType(rNode.GetText(), pRubyText->GetStart());
3498  else
3499  nRubyScript = i18n::ScriptType::ASIAN;
3500 
3501  const OUString &rText = rNode.GetText();
3502  sal_uInt16 nScript = i18n::ScriptType::LATIN;
3503 
3504  if (!rText.isEmpty())
3505  nScript = g_pBreakIt->GetBreakIter()->getScriptType(rText, 0);
3506 
3507  sal_uInt16 nWhich = GetWhichOfScript(RES_CHRATR_FONTSIZE, nScript);
3508  auto& rHeightItem = static_cast<const SvxFontHeightItem&>(rExport.GetItem(nWhich));
3509  m_nBaseHeight = rHeightItem.GetHeight();
3510 }
3511 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long GetLeft() const
bool GetValue() const
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:955
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
virtual void WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner=ww8::WW8TableNodeInfoInner::Pointer_t())=0
SvxBreak
OUString GetSnippet(const OUString &rStr, sal_Int32 nCurrentPos, sal_Int32 nLen) const
Definition: wrtw8nds.cxx:1665
TOXTypes
Definition: toxe.hxx:39
virtual AttributeOutputBase & AttrOutput() const =0
Access to the attribute output class.
virtual void OutputOLENode(const SwOLENode &)=0
Output SwOLENode.
bool Insert(const SvxTabStop &rTab)
sal_uLong GetIndex() const
Definition: node.hxx:282
const OUString & GetBaseURL() const
Definition: shellio.hxx:437
virtual void AppendSmartTags(SwTextNode &)
Definition: wrtww8.hxx:714
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
virtual const OUString & GetName() const =0
std::unique_ptr< ww::bytes > pO
Buffer.
Definition: wrtww8.hxx:990
void GetCurrentItems(ww::bytes &rItems) const
Definition: wrtw8nds.cxx:821
bool m_bLinkedTextboxesHelperInitialized
Definition: wrtww8.hxx:516
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
sal_uInt16 AddRedlineAuthor(std::size_t nId)
Definition: wrtww8.cxx:1682
bool IsSaveRelFSys() const
virtual void FormatDrop(const SwTextNode &rNode, const SwFormatDrop &rSwFormatDrop, sal_uInt16 nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)=0
const SwFormatLayoutSplit & GetLayoutSplit(bool=true) const
Definition: fmtlsplt.hxx:46
Marks a position in the document model.
Definition: pam.hxx:35
void OutSwString(const OUString &, sal_Int32 nStt, sal_Int32 nLen)
Definition: wrtww8.cxx:1860
bool GetWholeWord() const
Definition: paratr.hxx:92
bool IsSectionNode() const
Definition: node.hxx:644
#define RES_CHRATR_CJK_LANGUAGE
Definition: hintids.hxx:93
std::unique_ptr< WW8Fib > pFib
File Information Block.
Definition: wrtww8.hxx:994
virtual void SectionBreaks(const SwNode &rNode)=0
Called in order to output section breaks.
ww8::Frames GetFramesInNode(const ww8::Frames &rFrames, const SwNode &rNode)
Get the Frames anchored to a given node.
const SfxPoolItem & GetItem(sal_uInt16 nWhich) const
Definition: wrtww8.cxx:803
static const SwPageDesc * GetPageDescOfNode(const SwNode &rNd)
Given a SwNode return the pagedesc in use at that location.
Definition: pagedesc.cxx:312
OUString & GetRefName()
Definition: fmtrfmrk.hxx:66
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
SvxAdjust GetAdjust() const
sal_uInt8 SVBT16[2]
virtual void EndParagraphProperties(const SfxItemSet &rParagraphMarkerProperties, const SwRedlineData *pRedlineData, const SwRedlineData *pRedlineParagraphMarkerDeleted, const SwRedlineData *pRedlineParagraphMarkerInserted)=0
Called after we end outputting the attributes.
#define ODF_OLE_PARAM
#define RES_CHRATR_FONTSIZE
Definition: hintids.hxx:77
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:161
void WriteStringAsPara(const OUString &rText)
Definition: wrtww8.cxx:1804
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:743
const sal_uInt16 sprmPWr
Definition: sprmids.hxx:381
#define RES_CHRATR_LANGUAGE
Definition: hintids.hxx:79
#define RES_TXTATR_CJK_RUBY
Definition: hintids.hxx:144
RndStdIds m_eNewAnchorType
Definition: wrtww8.hxx:523
bool m_bAddFootnoteTab
Definition: wrtww8.hxx:573
const OUString & GetText() const
Definition: ndtxt.hxx:210
OUString const & GetPrimaryKey() const
Definition: tox.hxx:604
#define RES_PARATR_GRABBAG
Definition: hintids.hxx:180
#define ODF_PAGEREF
sal_uInt16 GetId(const SwTextFormatColl &rColl) const
Return the numeric id of the style.
Definition: wrtw8sty.cxx:134
#define RES_TXTATR_METAFIELD
Definition: hintids.hxx:140
const SwFormatDrop & mrSwFormatDrop
Definition: wrtww8.hxx:1517
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:218
std::string GetValue
const SwRedlineData * Next() const
Definition: redline.hxx:130
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: node.cxx:1155
short GetTextFirstLineOfst() const
const sal_uInt16 sprmCDttmRMarkDel
Definition: sprmids.hxx:328
std::multimap< sal_Int32, OUString > m_aBookmarksOfParagraphEnd
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
Definition: number.cxx:87
OUString GetURLPath(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
SwNodeIndex nNode
Definition: pam.hxx:37
virtual bool AnalyzeURL(const OUString &rURL, const OUString &rTarget, OUString *pLinkURL, OUString *pMark) override
Definition: wrtw8nds.cxx:953
std::size_t GetAuthor() const
Definition: redline.hxx:127
const sal_uInt16 sprmPDxaFromText
Definition: sprmids.hxx:393
SvxBreak GetBreak() const
virtual void Redline(const SwRedlineData *pRedline) override
Output redlining.
Definition: wrtw8nds.cxx:3342
const SwRedlineData * GetParagraphLevelRedline()
Definition: wrtw8nds.cxx:1420
std::vector< sal_uInt8 > bytes
Definition: types.hxx:29
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:284
sal_uInt8 GetLines() const
Definition: paratr.hxx:86
sal_uIntPtr sal_uLong
virtual void EndRuby(const SwTextNode &rNode, sal_Int32 nPos)=0
Output ruby end.
static void WriteString8(SvStream &rStrm, const OUString &rStr, bool bAddZero, rtl_TextEncoding eCodeSet)
Definition: wrtww8.cxx:1791
#define RES_FRAMEDIR
Definition: hintids.hxx:227
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:474
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2647
const SwPosition * GetMark() const
Definition: pam.hxx:209
const SwAttrSet * m_pStyAttr
Definition: wrtww8.hxx:537
const SvxFrameDirectionItem & GetFrameDir(bool=true) const
Definition: frmatr.hxx:94
const SwPageDesc * FindPageDesc(size_t *pPgDescNdIdx=nullptr) const
Search PageDesc with which this node is formatted.
Definition: node.cxx:464
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:402
rtl_TextEncoding meChrSet
Definition: wrtww8.hxx:1507
SwFrameFormat & GetFirstMaster()
Definition: pagedesc.hxx:219
bool MiserableFormFieldExportHack(const SwFrameFormat &rFrameFormat)
Definition: wrtw8esh.cxx:364
Provides access to the marks of a document.
bool m_bOutPageDescs
PageDescs (section properties) are being written.
Definition: wrtww8.hxx:554
#define ODF_FORMCHECKBOX
bool mbCharIsRTL
Definition: wrtww8.hxx:1509
const sal_uInt16 sprmCHps
Definition: sprmids.hxx:302
virtual void StartRuby(const SwTextNode &rNode, sal_Int32 nPos, const SwFormatRuby &rRuby)=0
Output ruby start.
virtual void OutputLinkedOLE(const OUString &)=0
sal_uInt16 FirstWhich()
#define ODF_CODE_PARAM
std::stack< sal_Int32 > m_aCurrentCharPropStarts
To remember the position in a run.
Definition: wrtww8.hxx:472
#define RES_CHRATR_FONT
Definition: hintids.hxx:76
bool NeedSectionBreak(const SwNode &rNd) const
Definition: wrtw8nds.cxx:2079
bool HasDummyChar() const
Definition: txatbase.hxx:101
SwTableLine is one table row in the document model.
Definition: swtable.hxx:344
void SetTextLeft(const long nL, const sal_uInt16 nProp=100)
SwNode & GetNode() const
Definition: ndindex.hxx:119
const OUString & GetName() const
Definition: numrule.hxx:221
bool GetNewAbsURL(OUString const &rTheRelURIRef, INetURLObject *pTheAbsURIRef) const
Point * m_pFlyOffset
Definition: wrtww8.hxx:522
const std::shared_ptr< SfxItemSet > & GetStyleHandle() const
Definition: fmtautofmt.hxx:49
SvxFrameDirection
static OUString GetRelURL(OUString const &rTheBaseURIRef, OUString const &rTheAbsURIRef, EncodeMechanism eEncodeMechanism=EncodeMechanism::WasEncoded, DecodeMechanism eDecodeMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
SwSectionFormat * GetFormat()
Definition: section.hxx:336
SvxFrameDirection GetTextDirection(const SwPosition &rPos, const Point *pPt=nullptr) const
Definition: doclay.cxx:1601
sal_uInt16 m_nStyleBeforeFly
style number of the node
Definition: wrtww8.hxx:483
void Pos(const Point &rNew)
Definition: swrect.hxx:167
bool AreListLevelIndentsApplicable() const
Determines, if the list level indent attributes can be applied to the paragraph.
Definition: ndtxt.cxx:4412
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1602
virtual void StartRunProperties()=0
Called before we start outputting the attributes.
WW8_CP Fc2Cp(sal_uLong nFc) const
Definition: wrtww8.hxx:1104
const SwTOXType * GetTOXType() const
Definition: tox.hxx:542
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
#define RES_TXTATR_CHARFMT
Definition: hintids.hxx:143
sal_uInt16 Which() const
Definition: txatbase.hxx:110
void Set_UInt32(sal_uInt8 *&p, sal_uInt32 n)
Definition: ww8struc.hxx:53
virtual sal_Int32 getAnnotationMarksCount() const =0
void OutputItemSet(const SfxItemSet &rSet, bool bPapFormat, bool bChpFormat, sal_uInt16 nScript, bool bExportParentItemSet)
Use OutputItem() on an item set according to the parameters.
Definition: ww8atr.cxx:262
void AppendFlyInFlys(const ww8::Frame &rFrameFormat, const Point &rNdTopLeft)
Definition: wrtw8esh.cxx:981
bool operator()(const ww8::Frame &rOne, const ww8::Frame &rTwo) const
Definition: wrtw8nds.cxx:175
#define RES_TXTATR_END
Definition: hintids.hxx:159
SVL_DLLPUBLIC OUString simpleNormalizedMakeRelative(OUString const &baseUriReference, OUString const &uriReference)
virtual const SfxPoolItem * HasTextItem(sal_uInt16 nWhich) const override
Definition: wrtw8nds.cxx:780
#define CH_TXT_ATR_FORMELEMENT
Definition: hintids.hxx:50
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2588
virtual ExportFormat GetExportFormat() const =0
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4097
std::shared_ptr< SvxBrushItem > TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const
Definition: wrtw8nds.cxx:1616
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:201
sal_uInt32 m_nBaseHeight
const SwRedlineData * GetParagraphMarkerRedline(const SwTextNode &rNode, RedlineType aRedlineType)
Definition: ww8atr.cxx:5507
size_type size() const
Definition: swtable.hxx:74
sal_uInt16 NextWhich()
IMarkVector m_rSortedAnnotationMarksEnd
Definition: wrtww8.hxx:588
const sal_uInt16 sprmPDyaLine
Definition: sprmids.hxx:371
void GetPoolItems(const SfxItemSet &rSet, ww8::PoolItems &rItems, bool bExportParentItemSet)
Get the SfxPoolItems of a SfxItemSet.
virtual void SetAnchorIsLinkedToNode(bool)
If the node has an anchor linked.
ww8::FrameIter maFlyIter
Definition: wrtww8.hxx:1520
#define CHAR_SOFTHYPHEN
Definition: swtypes.hxx:174
OUString PathToFileName() const
size_type size() const
Definition: docary.hxx:368
OUString BookmarkToWord(const OUString &rBookmark)
Definition: wrtw8nds.cxx:1143
const SwSection & GetSection() const
Definition: node.hxx:541
sal_Int32 WhereNext() const
Definition: wrtww8.hxx:1550
sal_uInt16 GetScript() const
Definition: wrtww8.hxx:1551
void GenerateBookmarksForSequenceField(const SwTextNode &rNode, SwWW8AttrIter &rAttrIter)
MSO uses bookmarks to reference sequence fields, so we need to generate these additional bookmarks du...
Definition: ww8atr.cxx:1996
#define ODF_HYPERLINK
const sal_uInt16 sprmCDttmRMark
Definition: sprmids.hxx:275
void WriteText()
Iterate through the nodes and call the appropriate OutputNode() on them.
Definition: wrtww8.cxx:2710
sal_uInt16 sal_Unicode
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
const SwTextRuby * GetTextRuby() const
Definition: fmtruby.hxx:59
RedlineType GetType() const
Definition: redline.hxx:125
virtual void PageBreakBefore(bool bBreak)=0
Page break As a paragraph property - the paragraph should be on the next page.
virtual void AppendBookmarks(const SwTextNode &rNd, sal_Int32 nCurrentPos, sal_Int32 nLen)=0
virtual void OutputField(const SwField *pField, ww::eField eFieldType, const OUString &rFieldCmd, FieldFlags nMode=FieldFlags::All) override
Write the field.
Definition: ww8atr.cxx:1743
SwWW8AttrIter(const SwWW8AttrIter &)=delete
SwNodeType GetNodeType() const
Definition: node.hxx:144
MSWordExportBase & m_rExport
Definition: wrtww8.hxx:1441
std::map< OUString, LinkedTextboxInfo > m_aLinkedTextboxesHelper
Definition: wrtww8.hxx:515
SwIndex nContent
Definition: pam.hxx:38
bool empty() const
Definition: docary.hxx:367
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
void OutputFormat(const SwFormat &rFormat, bool bPapFormat, bool bChpFormat, bool bFlyFormat=false)
Output attributes.
Definition: ww8atr.cxx:759
virtual bool StartURL(const OUString &rUrl, const OUString &rTarget) override
Output URL start.
Definition: wrtw8nds.cxx:984
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const override
#define RES_PARATR_TABSTOP
Definition: hintids.hxx:167
const OUString & GetName() const
Definition: format.hxx:111
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
void StartTOX(const SwSection &rSect)
Definition: ww8atr.cxx:2165
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
const sal_uInt16 sprmCFRMarkDel
Definition: sprmids.hxx:270
eField
Definition: fields.hxx:26
virtual void StartRun(const SwRedlineData *pRedlineData, sal_Int32 nPos, bool bSingleEmptyRun=false)=0
Start of the text run.
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
const SvxBrushItem * GetCurrentPageBgBrush() const
Definition: wrtw8nds.cxx:1597
MSWordAttrIter * m_pChpIter
Definition: wrtww8.hxx:501
bool m_bInWriteEscher
Definition: wrtww8.hxx:559
virtual void SetStateOfFlyFrame(FlyProcessingState)
Set the state of the Fly at current position.
virtual void StartParagraphProperties()=0
Called before we start outputting the attributes.
#define RES_UL_SPACE
Definition: hintids.hxx:199
virtual bool IsFlyProcessingPostponed()
Is processing of fly postponed ?
const SwTable & GetTable() const
Definition: node.hxx:497
virtual void ResetFlyProcessingFlag()
Reset the flag for FlyProcessing.
virtual parameter_map_t * GetParameters()=0
sal_uInt16 GetDistance() const
Definition: paratr.hxx:95
const SvxFormatKeepItem & GetKeep(bool=true) const
Definition: frmatr.hxx:86
bool HasRefToObject(sal_uInt16 nTyp, const OUString *pName, sal_uInt16 nSeqNo)
Find the reference.
Definition: ww8atr.cxx:895
const Graphic * GetGraphic(OUString const &referer=OUString()) const
#define RES_PARATR_NUMRULE
Definition: hintids.hxx:171
void WriteChar(sal_Unicode c) override
Definition: wrtww8.cxx:1897
INetProtocol
ww8::Frames maFlyFrames
Definition: wrtww8.hxx:1519
#define RES_CHRATR_CASEMAP
Definition: hintids.hxx:70
const sal_uInt16 sprmCIbstRMarkDel
Definition: sprmids.hxx:327
static void UpdateTocSectionNodeProperties(const SwSectionNode &rSectionNode)
Definition: wrtw8nds.cxx:3139
ww8::WW8TableInfo::Pointer_t m_pTableInfo
Definition: wrtww8.hxx:479
void OutputItem(const SfxPoolItem &rHt)
Call the right virtual function according to the type of the item.
Definition: ww8atr.cxx:5171
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
SwAttrPool * GetPool() const
Definition: swatrset.hxx:190
rtl_TextEncoding GetCharSet() const
Definition: wrtww8.hxx:1553
const SwFrameFormat & GetFrameFormat() const
Get the writer SwFrameFormat that this object describes.
const SwRedlineData & GetRedlineData(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1746
SwFormatColl & GetAnyFormatColl() const
Definition: node.hxx:716
const sal_uInt16 sprmPPc
Definition: sprmids.hxx:380
const T & item_cast(const SfxPoolItem &rItem)
Provide a dynamic_cast style cast for SfxPoolItems.
void GetSortedAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen)
Definition: wrtw8nds.cxx:2012
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:164
const OUString & GetText() const
Definition: fmtruby.hxx:61
#define RES_BACKGROUND
Definition: hintids.hxx:212
static void WriteString16(SvStream &rStrm, const OUString &rStr, bool bAddZero)
Definition: wrtww8.cxx:1768
void IterToCurrent()
Definition: wrtw8nds.cxx:181
virtual const_iterator_t getAllMarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence of marks.
const Color & GetColor() const
virtual sal_uLong ReplaceCr(sal_uInt8 nChar)=0
const OUString & GetAlternativeText() const
Definition: tox.hxx:533
bool IsContentNode() const
Definition: node.hxx:628
const sal_uInt16 sprmCIstd
Definition: sprmids.hxx:287
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:443
void NextPos()
Definition: wrtww8.hxx:1539
sal_uInt32 GetRubyHeight() const
virtual bool AnalyzeURL(const OUString &rUrl, const OUString &rTarget, OUString *pLinkURL, OUString *pMark)
Definition: wrtw8nds.cxx:899
std::unique_ptr< WW8_WrPlcPn > m_pPapPlc
Definition: wrtww8.hxx:499
sal_uInt16 GetPosition() const
Definition: fmtruby.hxx:70
WW8Export & m_rWW8Export
Reference to the export, where to get the data from.
void OutputSectionNode(const SwSectionNode &)
Output SwSectionNode.
Definition: wrtw8nds.cxx:3086
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
Style of a layout element.
Definition: frmfmt.hxx:57
size_t Count() const
Definition: ndhints.hxx:142
#define SAL_MAX_INT32
virtual void RunText(const OUString &rText, rtl_TextEncoding eCharSet=RTL_TEXTENCODING_UTF8)=0
Output text (inside a run).
static bool isRightToLeft(LanguageType nLang)
sal_Int32 GetNextPos(SwWW8AttrIter const *pAttrIter, const SwTextNode &rNode, sal_Int32 nCurrentPos)
Get the next position in the text node to output.
Definition: wrtw8nds.cxx:1816
const sal_uInt8 ND_HAS_PREV_LAYNODE
Definition: ndtyp.hxx:63
void SplitRun(sal_Int32 nSplitEndPos)
Definition: wrtw8nds.cxx:1167
virtual ~MSWordAttrIter()
Definition: wrtw8nds.cxx:167
virtual void FormatDrop(const SwTextNode &rNode, const SwFormatDrop &rSwFormatDrop, sal_uInt16 nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner) override
Definition: wrtw8nds.cxx:1752
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
void SetCurItemSet(const SfxItemSet *pS)
Setter for pISet.
Definition: wrtww8.hxx:733
std::map< sal_uInt16, const SfxPoolItem *, sw::util::ItemSort > PoolItems
STL container of SfxPoolItems (Attributes)
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
std::vector< Frame >::iterator FrameIter
STL iterator for Frames.
std::unique_ptr< WW8_WrPlcSepx > pSepx
Sections/headers/footers.
Definition: wrtww8.hxx:998
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
sal_Int32 GetAbsLSpace() const
WW8Ruby(const SwTextNode &rNode, const SwFormatRuby &rRuby, const MSWordExportBase &rExport)
Definition: wrtw8nds.cxx:3417
void NearestAnnotationMark(sal_Int32 &rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly)
Find the nearest annotation mark from the current position.
Definition: wrtw8nds.cxx:1983
void UpdatePosition(SwWW8AttrIter *pAttrIter, sal_Int32 nCurrentPos)
Update the information for GetNextPos().
Definition: wrtw8nds.cxx:1833
const SwPosition * GetPoint() const
Definition: pam.hxx:207
OUString GetURLNoMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
sal_uInt16 mnScript
Definition: wrtww8.hxx:1508
FlyProcessingState OutFlys(sal_Int32 nSwPos)
Definition: wrtw8nds.cxx:592
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
const SwPageDesc & GetPageDesc(const size_t i) const
Definition: doc.hxx:877
const SwTOXBase * GetTOXBase() const
Definition: section.cxx:613
const sal_uInt16 sprmCIbstRMark
Definition: sprmids.hxx:274
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
bool IsParaRTL() const
Definition: wrtww8.hxx:1552
const SwModify * m_pOutFormatNode
Definition: wrtww8.hxx:538
virtual void OutputTextNode(SwTextNode &)
Output SwTextNode.
Definition: wrtw8nds.cxx:2105
sw::util::CharRuns maCharRuns
Definition: wrtww8.hxx:1504
void OutputContentNode(SwContentNode &)
Call the right (virtual) function according to the type of the item.
Definition: wrtw8nds.cxx:3397
bool HasContent() const
Definition: txatbase.hxx:106
virtual void ExportGrfBullet(const SwTextNode &rNd)=0
int i
void OutputSectionBreaks(const SfxItemSet *pSet, const SwNode &rNd, bool isCellOpen=false, bool isTextNodeEmpty=false)
Start new section.
Definition: ww8atr.cxx:413
SwContentNode * GetContentNode()
Definition: node.hxx:615
sal_uInt8 HasPrevNextLayNode() const
Definition: node.cxx:839
vector_type::size_type size_type
Definition: docary.hxx:330
FlyAnchors.
Definition: fmtanchr.hxx:34
sal_uInt16 GetLevel() const
Definition: tox.hxx:598
static void WriteShort(SvStream &rStrm, sal_Int16 nVal)
Definition: wrtww8.hxx:961
const ww8::Frame * m_pParentFrame
Definition: wrtww8.hxx:519
virtual WW8Export & GetExport() override
Return the right export class.
MSWordAttrIter *const pOld
Definition: wrtww8.hxx:1437
static sal_Int32 lcl_getMinPos(sal_Int32 pos1, sal_Int32 pos2)
Definition: wrtw8nds.cxx:235
std::size_t WriteBytes(const void *pData, std::size_t nSize)
virtual void StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo)=0
Start of the paragraph.
Marks a character position inside a document model node.
Definition: index.hxx:37
const SfxItemSet * GetItemSet(const SfxPoolItem &rAttr)
Returns the item set associated with a character/inet/auto style.
Definition: atrstck.cxx:133
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:52
const SwRedlineData * GetRunLevelRedline(sal_Int32 nPos)
Definition: wrtw8nds.cxx:1445
#define RES_CHRATR_BEGIN
Definition: hintids.hxx:69
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:195
const DateTime & GetTimeStamp() const
Definition: redline.hxx:129
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2813
SvxFrameDirection GetDefaultFrameDirection() const
Definition: wrtw8nds.cxx:1525
const std::map< OUString, css::uno::Any > & GetGrabBag() const
static OUString GetScheme(INetProtocol eTheScheme)
virtual void OutputField(const SwField *pField, ww::eField eFieldType, const OUString &rFieldCmd, FieldFlags nMode=FieldFlags::All)=0
Write the field.
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:366
virtual const_iterator_t getAnnotationMarksBegin() const =0
bool KnowsPageDesc() const
Definition: atrfrm.cxx:613
void OutputFlyFrame(const ww8::Frame &rFormat)
Output frames.
Definition: wrtw8nds.cxx:3324
virtual void EndRuby(const SwTextNode &rNode, sal_Int32 nPos) override
Output ruby end.
Definition: wrtw8nds.cxx:856
size
virtual void WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner=ww8::WW8TableNodeInfoInner::Pointer_t()) override
Definition: wrtww8.cxx:1887
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:396
#define RES_TXTATR_TOXMARK
Definition: hintids.hxx:138
Marks a node in the document model.
Definition: ndindex.hxx:31
#define RES_LINENUMBER
Definition: hintids.hxx:223
SwWW8Writer & GetWriter() const
Definition: wrtww8.hxx:1179
bool IsEndNode() const
Definition: node.hxx:632
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
void StartCommentOutput(const OUString &rName)
Definition: ww8atr.cxx:1881
static void CorrectTabStopInSet(SfxItemSet &rSet, sal_Int32 nAbsLeft)
Definition: ww8atr.cxx:671
const sal_uInt16 sprmCPropRMark90
Definition: sprmids.hxx:316
const SvxFormatBreakItem & GetBreak(bool=true) const
Definition: frmatr.hxx:90
bool HasSwAttrSet() const
Definition: node.hxx:444
void InsUInt16(sal_uInt16 n)
Definition: wrtww8.hxx:1151
sal_Char m_cDirective
sal_uInt8 GetChars() const
Definition: paratr.hxx:89
DocumentType const eType
virtual void OutputGrfNode(const SwGrfNode &)=0
Output SwGrfNode.
virtual void TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo)=0
const sal_Unicode cMarkSeparator
Definition: swtypes.hxx:137
const SwRangeRedline * pCurRedline
Definition: wrtww8.hxx:1511
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
Definition: swtable.hxx:356
void InsUInt32(sal_uInt32 n)
Definition: wrtww8.hxx:1153
#define RES_TXTATR_INETFMT
Definition: hintids.hxx:142
void EndTOX(const SwSection &rSect, bool bCareEnd=true)
Definition: ww8atr.cxx:2485
SwTableLines & GetTabLines()
Definition: swtable.hxx:198
OUString GetName() const
IMarkVector m_rSortedAnnotationMarksStart
Definition: wrtww8.hxx:587
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:110
sal_uInt32 GetBaseHeight() const
sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat)
Definition: wrtw8num.cxx:180
const SwPosition * Start() const
Definition: pam.hxx:212
void GetSortedBookmarks(const SwTextNode &rNd, sal_Int32 nCurrentPos, sal_Int32 nLen)
Definition: wrtw8nds.cxx:2046
#define RES_LR_SPACE
Definition: hintids.hxx:198
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:246
virtual void EndRunProperties(const SwRedlineData *pRedlineData)=0
Called after we end outputting the attributes.
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
CharRuns GetPseudoCharRuns(const SwTextNode &rTextNd)
Collect the ranges of Text which share.
long GetIndentAt() const
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:458
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
bool operator()(const IMark *pOneB, const IMark *pTwoB) const
Definition: wrtw8nds.cxx:1942
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void fillSoftPageBreakList(SwSoftPageBreakList &rBreak) const
const SwTextNode & rNd
Definition: wrtww8.hxx:1502
sal_Char GetDirective() const
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:77
virtual void RTLAndCJKState(bool bIsRTL, sal_uInt16 nScript)=0
Export the state of RTL/CJK.
OUString const & GetFontFamily() const
#define ODF_UNHANDLED
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:67
SwFrameFormat & GetMaster()
Definition: pagedesc.hxx:217
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
void OutSwFormatRefMark(const SwFormatRefMark &rAttr)
Definition: wrtw8nds.cxx:1160
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
sal_Int32 GetDropLen(sal_Int32 nWishLen) const
nWishLen = 0 indicates that we want a whole word
Definition: txtdrop.cxx:124
void SetCaseMap(const SvxCaseMap eNew)
virtual void WriteBookmarkInActParagraph(const OUString &rName, sal_Int32 nFirstRunPos, sal_Int32 nLastRunPos) override
Insert a bookmark inside the currently processed paragraph.
Definition: wrtw8nds.cxx:978
sal_uInt32 m_nRubyHeight
#define CHAR_HARDHYPHEN
Definition: swtypes.hxx:173
const sal_uInt16 sprmCFFldVanish
Definition: sprmids.hxx:272
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:334
IMarkVector m_rSortedBookmarksEnd
Definition: wrtww8.hxx:586
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
#define RES_TXTATR_AUTOFMT
Definition: hintids.hxx:141
OUString BookmarkToWriter(const OUString &rBookmark)
Definition: wrtw8nds.cxx:1154
#define ODF_TOC
const SwPageDesc * m_pCurrentPageDesc
Definition: wrtww8.hxx:496
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:67
SfxItemState
OUString GetExpandText(SwRootFrame const *pLayout, const sal_Int32 nIdx=0, const sal_Int32 nLen=-1, const bool bWithNum=false, const bool bAddSpaceAfterListLabelStr=false, const bool bWithSpacesForLevel=false, const ExpandMode eAdditionalMode=ExpandMode::ExpandFootnote) const
add 4th optional parameter indicating, when that a spa...
Definition: ndtxt.cxx:3383
void SetTextFirstLineOfst(const short nF, const sal_uInt16 nProp=100)
virtual void StartRuby(const SwTextNode &rNode, sal_Int32 nPos, const SwFormatRuby &rRuby) override
Output ruby start.
Definition: wrtw8nds.cxx:832
bool HasFlysAt(sal_Int32 nSwPos) const
Definition: wrtw8nds.cxx:577
sal_Int32 GetJC() const
virtual const SfxPoolItem & GetItem(sal_uInt16 nWhich) const override
Definition: wrtw8nds.cxx:826
static OUString & TruncateBookmark(OUString &rRet)
Definition: wrtw8nds.cxx:863
bool GetDropSize(int &rFontHeight, int &rDropHeight, int &rDropDescent) const
Passes back info needed on the dropcap dimensions.
Definition: txtdrop.cxx:230
virtual sal_Int32 getAllMarksCount() const =0
returns the number of marks.
SvStream & Strm() const
Definition: wrtww8.hxx:1180
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
OUString const & GetSecondaryKey() const
Definition: tox.hxx:610
virtual bool AllowPostponedTextInTable() const
Text in tables can be postponed except for .doc.
Definition: wrtww8.hxx:694
std::set< sal_Int32 > SwSoftPageBreakList
Definition: wrtww8.hxx:137
FlyProcessingState
enum to state the present state of the fly
Definition: wrtww8.hxx:169
#define RES_CHRATR_CTL_LANGUAGE
Definition: hintids.hxx:98
unsigned char sal_uInt8
const sal_uInt16 sprmCFRMarkIns
Definition: sprmids.hxx:271
const OUString & GetTargetFrame() const
Definition: fmtinfmt.hxx:89
Make exporting a Writer Frame easy.
bool IsDropCap(int nSwPos)
Definition: wrtw8nds.cxx:751
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2888
const SwContentNode * GetContentNode() const
Get the node this frame is anchored into.
bool IncludeEndOfParaCRInRedlineProperties(sal_Int32 nPos) const
Definition: wrtw8nds.cxx:1364
bool IsWatermarkFrame()
Definition: wrtw8nds.cxx:538
TOXTypes GetType() const
Definition: tox.hxx:695
sal_uInt32 DateTime2DTTM(const DateTime &rDT)
Convert from DTTM to Writer's DateTime.
virtual void AppendAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen)=0
#define SAL_INFO(area, stream)
#define RES_PARATR_LIST_AUTOFMT
Definition: hintids.hxx:191
SvStream & WriteUChar(unsigned char nChar)
sal_Int32 GetIndex() const
Definition: index.hxx:95
SvStream * pDataStrm
Streams for WW97 Export.
Definition: wrtww8.hxx:992
bool IsCountedInList() const
Definition: ndtxt.cxx:4240
INetProtocol GetProtocol() const
#define ODF_FORMTEXT
LanguageType GetAppLanguage()
Definition: init.cxx:729
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:175
SwNodes & GetNodes()
Definition: doc.hxx:402
const sal_uInt8 PageBreak
std::pair< OUString, sal_uLong > aBookmarkPair
Definition: wrtww8.hxx:413
sw::util::CharRuns::const_iterator maCharRunIter
Definition: wrtww8.hxx:1505
const SwPosition * End() const
Definition: pam.hxx:217
OUString CalcCaseMap(const OUString &rTxt) const
#define RES_KEEP
Definition: hintids.hxx:217
std::multimap< sal_Int32, OUString > m_aBookmarksOfParagraphStart
Bookmarks of the current paragraph.
virtual void SaveData(sal_uLong nStt, sal_uLong nEnd) override
Remember some of the members so that we can recurse in WriteText().
Definition: wrtww8.cxx:1974
sal_uInt8 m_nTextTyp
Definition: wrtww8.hxx:548
ww8::Frames m_aFrames
Definition: wrtww8.hxx:495
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1728
const sal_Int32 * End() const
Definition: txatbase.hxx:148
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
bool m_bOutFlyFrameAttrs
Definition: wrtww8.hxx:553
bool NearestBookmark(sal_Int32 &rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly)
Find the nearest bookmark from the current position.
Definition: wrtw8nds.cxx:1951
virtual void FieldVanish(const OUString &rText, ww::eField eType)=0
virtual bool EndURL(bool isAtEndOfParagraph)=0
Output URL end.
sal_uInt64 Tell() const
#define RES_PARATR_ADJUST
Definition: hintids.hxx:163
std::shared_ptr< WW8TableNodeInfoInner > Pointer_t
bool m_bInWriteTOX
Definition: wrtww8.hxx:561
virtual void AppendSection(const SwPageDesc *pPageDesc, const SwSectionFormat *pFormat, sal_uLong nLnNum) override
Definition: wrtw8nds.cxx:3226
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
bool IsPlausableSingleWordSection(const SwFrameFormat &rTitleFormat, const SwFrameFormat &rFollowFormat)
See if two page formats can be expressed as a single word section.
virtual void ParagraphStyle(sal_uInt16 nStyle)=0
Output style.
bool GetBookmarks(const SwTextNode &rNd, sal_Int32 nStt, sal_Int32 nEnd, IMarkVector &rArr)
Definition: wrtw8nds.cxx:1845
sal_Int32 GetFirstLineOffset() const
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
#define RES_TXTATR_REFMARK
Definition: hintids.hxx:137
virtual const SwPosition & GetMarkEnd() const =0
static void InsUInt16(ww::bytes &rO, sal_uInt16 n)
Definition: wrtww8.cxx:1732
virtual void TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo) override
Definition: wrtww8.cxx:2007
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:54
bool GetAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nStt, sal_Int32 nEnd, IMarkVector &rArr)
Definition: wrtw8nds.cxx:1893
TOXTypes GetType() const
Definition: tox.hxx:663
SvtSaveOptions const m_aSaveOpt
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:723
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:349
SwTableBox * GetUpper()
Definition: swtable.hxx:362
virtual bool StartURL(const OUString &rUrl, const OUString &rTarget)=0
Output URL start.
css::text::RubyAdjust GetAdjustment() const
Definition: fmtruby.hxx:73
virtual void PrepareNewPageDesc(const SfxItemSet *pSet, const SwNode &rNd, const SwFormatPageDesc *pNewPgDescFormat, const SwPageDesc *pNewPgDesc)=0
#define ODF_FORMDATE
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:159
OString const aName
void ExportPoolItemsToCHP(ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont, bool bWriteCombChars=false)
Export the pool items to attributes (through an attribute output class).
Definition: ww8atr.cxx:211
virtual OUString GetFieldname() const =0
virtual void Redline(const SwRedlineData *pRedline)=0
Output redlining.
sal_Int32 nCurrentSwPos
Definition: wrtww8.hxx:1512
#define SAL_WARN(area, stream)
const SwCharFormat * GetCharFormat() const
Definition: paratr.hxx:98
Base class for WW8Export and DocxExport.
Definition: wrtww8.hxx:453
OUString GetMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static OUString lcl_getFieldCode(const IFieldmark *pFieldmark)
Definition: wrtw8nds.cxx:119
sal_Int32 SearchNext(sal_Int32 nStartPos)
Definition: wrtw8nds.cxx:247
SwRedlineTable::size_type nCurRedlinePos
Definition: wrtww8.hxx:1513
sal_uInt16 GetPos(const SwTableLine *pBox) const
Definition: swtable.hxx:96
bool IsExportableAttr(sal_Int32 nSwPos) const
Definition: wrtw8nds.cxx:727
SvxFrameDirection GetCurrentPageDirection() const
Right to left?
Definition: wrtw8nds.cxx:1517
const SwFormatDrop & GetSwFormatDrop() const
Definition: wrtww8.hxx:1556
virtual const SwPosition & GetMarkStart() const =0
static OUString GetBookmarkName(sal_uInt16 nTyp, const OUString *pName, sal_uInt16 nSeqNo)
Find the bookmark name.
Definition: ww8atr.cxx:931
virtual void EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)=0
End of the paragraph.
const SwTextTOXMark * GetTextTOXMark() const
Definition: tox.hxx:137
bool mbParaIsRTL
Definition: wrtww8.hxx:1515
const SwTextNode & GetNode() const
Definition: wrtww8.hxx:1563
bool IsInline() const
Is this frame inline (as character)
WriterSource GetWriterType() const
Get the type of frame that this wraps.
SectionType GetType() const
Definition: section.hxx:171
SwGrfNode * GetGrfNode()
Definition: ndgrf.hxx:155
MSWordAttrIter(const MSWordAttrIter &)=delete
static SwTextFormatColl & lcl_getFormatCollection(MSWordExportBase &rExport, const SwTextNode *pTextNode)
Delivers the right paragraph style.
Definition: wrtw8nds.cxx:1728
virtual void WriteHyperlinkData(const ::sw::mark::IFieldmark &rFieldmark)=0
static bool NoPageBreakSection(const SfxItemSet *pSet)
Definition: wrtw8nds.cxx:3052
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
If SwFormatDrop is a Client, it is the CharFormat that describes the font for the DropCaps...
Definition: paratr.hxx:50
const sal_uInt16 sprmPDcs
Definition: sprmids.hxx:390
virtual const SwRedlineTable & GetRedlineTable() const =0
void TOXMark(const SwTextNode &rNode, const SwTOXMark &rAttr)
Definition: wrtw8nds.cxx:1208
std::vector< ::sw::mark::IMark * > IMarkVector
Used to split the runs according to the bookmarks start and ends.
Definition: wrtww8.hxx:584
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
Definition: node.hxx:730
virtual void AppendBookmark(const OUString &rName)=0
void EndCommentOutput(const OUString &rName)
Definition: ww8atr.cxx:1887
void ClearOverridesFromSet(const SwFormatCharFormat &rFormat, SfxItemSet &rSet)
Remove properties from an SfxItemSet which a SwFormatCharFormat overrides.
#define RES_PAGEDESC
Definition: hintids.hxx:200
#define RES_BREAK
Definition: hintids.hxx:201
void OutAttr(sal_Int32 nSwPos, bool bWriteCombinedChars)
Definition: wrtw8nds.cxx:393
virtual void RestoreData() override
Restore what was saved in SaveData().
Definition: wrtww8.cxx:1992
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
bool IsTextAttr(sal_Int32 nSwPos) const
Definition: wrtw8nds.cxx:702
void OutputFlyFrame_Impl(const ww8::Frame &rFormat, const Point &rNdTopLeft) override
Output frames - the implementation.
Definition: wrtw8nds.cxx:3233
virtual bool EndURL(bool) override
Output URL end.
Definition: wrtw8nds.cxx:1136
#define CH_TXT_ATR_FIELDSEP
Definition: hintids.hxx:53
virtual void WriteFormData(const ::sw::mark::IFieldmark &rFieldmark)=0
Write the data of the form field.
int OutAttrWithRange(const SwTextNode &rNode, sal_Int32 nPos)
Definition: wrtw8nds.cxx:1263
SwTableLine * GetUpper()
Definition: swtable.hxx:421
sal_Int32 nPos
static ww::eField lcl_getFieldId(const IFieldmark *const pFieldmark)
Definition: wrtw8nds.cxx:140
bool IsTextNode() const
Definition: node.hxx:636
#define RES_CHRATR_GRABBAG
Definition: hintids.hxx:112
The class MSWordAttrIter is a helper class to build the Fkp.chpx.
Definition: wrtww8.hxx:1434
std::shared_ptr< WW8TableNodeInfo > Pointer_t
static void WriteLong(SvStream &rStrm, sal_Int32 nVal)
Definition: wrtww8.hxx:964
const SwPosition & GetPosition() const
Get the position this frame is anchored at.
bool IsInTable() const
Return whether currently exported node is in table.
Definition: wrtww8.cxx:2883
bool NeedTextNodeSplit(const SwTextNode &rNd, SwSoftPageBreakList &pList) const
Definition: wrtw8nds.cxx:2097
SwFrameFormat * GetFlyFormat() const
If node is in a fly return the respective format.
Definition: node.cxx:708
aStr
SwCharFormat * GetCharFormat()
Definition: txtatr2.cxx:230
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1271
const sal_uInt16 sprmCHpsPos
Definition: sprmids.hxx:303
virtual void AppendSection(const SwPageDesc *pPageDesc, const SwSectionFormat *pFormat, sal_uLong nLnNum)=0
const sal_uInt8 ND_HAS_NEXT_LAYNODE
Definition: ndtyp.hxx:64
virtual void EndRun(const SwTextNode *pNode, sal_Int32 nPos, bool bLastRun=false)=0
End of the text run.
SwRect FindPageFrameRect() const
Definition: node.cxx:1171
virtual void EmptyParagraph() override
Empty paragraph.
Definition: wrtw8nds.cxx:3047
std::unique_ptr< WW8_WrPlcPn > m_pChpPlc
Definition: wrtww8.hxx:500
sal_uInt16 Which() const
SvxFrameDirection TrueFrameDirection(const SwFrameFormat &rFlyFormat) const
Right to left?
Definition: wrtw8nds.cxx:1564
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2700
OUString ConvertURL(const OUString &rUrl, bool bAbsoluteOut)
Definition: wrtw8nds.cxx:871
IMarkVector m_rSortedBookmarksStart
Definition: wrtww8.hxx:585
SwDoc * m_pDoc
Definition: wrtww8.hxx:575
#define ODF_ID_PARAM
virtual MSWordExportBase & GetExport()=0
Return the right export class.
static OUString encode(OUString const &rText, Part ePart, EncodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1309
std::vector< aBookmarkPair > m_aImplicitBookmarks
Definition: wrtww8.hxx:494
virtual void OutputFlyFrame_Impl(const ww8::Frame &rFormat, const Point &rNdTopLeft)=0
Output frames - the implementation.
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:842
#define ODF_FORMDROPDOWN
bool IsAnchorLinkedToThisNode(sal_uLong nNodePos)
Definition: wrtw8nds.cxx:558
virtual void WritePostitFieldReference()
for docx w:commentReference
virtual void FieldVanish(const OUString &rText, ww::eField eType) override
Definition: wrtw8nds.cxx:1182
OUString m_sFontFamily
virtual void OutputFKP(bool)
Output FKP (Formatted disK Page) - necessary for binary formats only.
bool RequiresImplicitBookmark()
Definition: wrtw8nds.cxx:770
Base class of the Writer document model elements.
Definition: node.hxx:79
static OUString decode(OUString const &rText, DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)