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