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