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