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