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