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