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