xref: /core/sw/source/core/layout/atrfrm.cxx (revision 42b03777256ef9688f01d39792cfd0cbc89d0ad3)
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 <sal/config.h>
21 
22 #include <com/sun/star/style/VerticalAlignment.hpp>
23 #include <com/sun/star/text/ColumnSeparatorStyle.hpp>
24 #include <com/sun/star/text/WrapTextMode.hpp>
25 #include <com/sun/star/text/TextContentAnchorType.hpp>
26 #include <com/sun/star/container/XIndexContainer.hpp>
27 #include <com/sun/star/text/TextGridMode.hpp>
28 #include <com/sun/star/text/XTextColumns.hpp>
29 #include <sal/log.hxx>
30 #include <o3tl/any.hxx>
31 #include <o3tl/safeint.hxx>
32 #include <osl/diagnose.h>
33 #include <svtools/unoimap.hxx>
34 #include <tools/UnitConversion.hxx>
35 #include <vcl/imap.hxx>
36 #include <vcl/imapobj.hxx>
37 #include <unotools/intlwrapper.hxx>
38 #include <unotools/syslocale.hxx>
39 #include <frmfmt.hxx>
40 #include <unocoll.hxx>
41 #include <fmtclds.hxx>
42 #include <fmtornt.hxx>
43 #include <fmthdft.hxx>
44 #include <fmtpdsc.hxx>
45 #include <fmtcntnt.hxx>
46 #include <fmtfsize.hxx>
47 #include <fmtfordr.hxx>
48 #include <fmtsrnd.hxx>
49 #include <fmtlsplt.hxx>
50 #include <fmtrowsplt.hxx>
51 #include <fmtftntx.hxx>
52 #include <fmteiro.hxx>
53 #include <fmturl.hxx>
54 #include <fmtcnct.hxx>
55 #include <section.hxx>
56 #include <fmtline.hxx>
57 #include <tgrditem.hxx>
58 #include <hfspacingitem.hxx>
59 #include <IDocumentDrawModelAccess.hxx>
60 #include <IDocumentUndoRedo.hxx>
61 #include <IDocumentContentOperations.hxx>
62 #include <IDocumentLayoutAccess.hxx>
63 #include <pagefrm.hxx>
64 #include <rootfrm.hxx>
65 #include <cntfrm.hxx>
66 #include <notxtfrm.hxx>
67 #include <txtfrm.hxx>
68 #include <crsrsh.hxx>
69 #include <dflyobj.hxx>
70 #include <dcontact.hxx>
71 #include <frmtool.hxx>
72 #include <flyfrms.hxx>
73 #include <pagedesc.hxx>
74 #include <grfatr.hxx>
75 #include <ndnotxt.hxx>
76 #include <node2lay.hxx>
77 #include <fmtclbl.hxx>
78 #include <swunohelper.hxx>
79 #include <unoframe.hxx>
80 #include <SwStyleNameMapper.hxx>
81 #include <editeng/brushitem.hxx>
82 #include <vcl/GraphicObject.hxx>
83 #include <unomid.h>
84 #include <strings.hrc>
85 #include <svx/svdundo.hxx>
86 #include <svx/SvxXTextColumns.hxx>
87 #include <sortedobjs.hxx>
88 #include <HandleAnchorNodeChg.hxx>
89 #include <calbck.hxx>
90 #include <pagedeschint.hxx>
91 #include <drawdoc.hxx>
92 #include <hints.hxx>
93 #include <frameformats.hxx>
94 #include <unoprnms.hxx>
95 
96 #include <ndtxt.hxx>
97 
98 #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
99 #include <svl/itemiter.hxx>
100 #include <wrtsh.hxx>
101 #include <txtfld.hxx>
102 #include <cellatr.hxx>
103 #include <names.hxx>
104 
105 using namespace ::com::sun::star;
106 
107 namespace sw {
108 
GetAtPageRelOrientation(sal_Int16 & rOrientation,bool const isIgnorePrintArea)109 bool GetAtPageRelOrientation(sal_Int16 & rOrientation, bool const isIgnorePrintArea)
110 {
111     switch (rOrientation)
112     {
113         case text::RelOrientation::CHAR:
114         case text::RelOrientation::FRAME:
115             rOrientation = text::RelOrientation::PAGE_FRAME;
116             return true;
117         case text::RelOrientation::PRINT_AREA:
118             if (isIgnorePrintArea)
119             {
120                 return false;
121             }
122             else
123             {
124                 rOrientation = text::RelOrientation::PAGE_PRINT_AREA;
125                 return true;
126             }
127         case text::RelOrientation::FRAME_LEFT:
128             rOrientation = text::RelOrientation::PAGE_LEFT;
129             return true;
130         case text::RelOrientation::FRAME_RIGHT:
131             rOrientation = text::RelOrientation::PAGE_RIGHT;
132             return true;
133         default:
134             return false;
135     }
136 }
137 
138 
139 } // namespace sw
140 
141 
CreateDefault()142 SfxPoolItem* SwFormatLineNumber::CreateDefault() { return new SwFormatLineNumber; }
143 
lcl_IntToRelation(const uno::Any & rVal)144 static sal_Int16 lcl_IntToRelation(const uno::Any& rVal)
145 {
146     sal_Int16 nVal = text::RelOrientation::FRAME;
147     if (!(rVal >>= nVal))
148         SAL_WARN("sw.core", "lcl_IntToRelation: read from Any failed!");
149     return nVal;
150 }
151 
lcl_DelHFFormat(sw::FrameFormatClient * pToRemove,SwFrameFormat * pFormat)152 static void lcl_DelHFFormat( sw::FrameFormatClient *pToRemove, SwFrameFormat *pFormat )
153 {
154     //If the client is the last one who uses this format, then we have to delete
155     //it - before this is done, we may need to delete the content-section.
156     SwDoc& rDoc = pFormat->GetDoc();
157     pFormat->Remove(*pToRemove);
158     if( rDoc.IsInDtor() )
159     {
160         delete pFormat;
161         return;
162     }
163 
164     // Anything other than frames registered?
165     if(!pFormat->HasOnlySpecificWriterListeners<SwFrame>())
166         return;
167 
168     // If there is a Cursor registered in one of the nodes, we need to call the
169     // ParkCursor in an (arbitrary) shell.
170     SwFormatContent& rCnt = const_cast<SwFormatContent&>(pFormat->GetContent());
171     if ( rCnt.GetContentIdx() )
172     {
173         SwNode *pNode = nullptr;
174         {
175             // #i92993#
176             // Begin with start node of page header/footer to assure that
177             // complete content is checked for cursors and the complete content
178             // is deleted on below made method call <pDoc->getIDocumentContentOperations().DeleteSection(pNode)>
179             SwNodeIndex aIdx( *rCnt.GetContentIdx(), 0 );
180             // If there is a Cursor registered in one of the nodes, we need to call the
181             // ParkCursor in an (arbitrary) shell.
182             pNode = & aIdx.GetNode();
183             SwNodeOffset nEnd = pNode->EndOfSectionIndex();
184             while ( aIdx < nEnd )
185             {
186                 if ( pNode->IsContentNode() &&
187                      static_cast<SwContentNode*>(pNode)->HasWriterListeners() )
188                 {
189                     SwCursorShell *pShell = SwIterator<SwCursorShell,SwContentNode>( *static_cast<SwContentNode*>(pNode) ).First();
190                     if( pShell )
191                     {
192                         pShell->ParkCursor( aIdx.GetNode() );
193                         aIdx = nEnd-1;
194                     }
195                 }
196                 ++aIdx;
197                 pNode = & aIdx.GetNode();
198             }
199         }
200         rCnt.SetNewContentIdx( nullptr );
201 
202         // When deleting a header/footer-format, we ALWAYS need to disable
203         // the undo function (Bug 31069)
204         ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
205 
206         OSL_ENSURE( pNode, "A big problem." );
207         rDoc.getIDocumentContentOperations().DeleteSection( pNode );
208     }
209     delete pFormat;
210 }
211 
getItemInstanceManager() const212 ItemInstanceManager* SwFormatFrameSize::getItemInstanceManager() const
213 {
214     static HashedItemInstanceManager aInstanceManager(ItemType());
215     return &aInstanceManager;
216 }
217 
hashCode() const218 size_t SwFormatFrameSize::hashCode() const
219 {
220     std::size_t seed(0);
221     o3tl::hash_combine(seed, Which());
222     o3tl::hash_combine(seed, GetHeightSizeType());
223     o3tl::hash_combine(seed, GetWidthSizeType());
224     o3tl::hash_combine(seed, GetWidthPercent());
225     o3tl::hash_combine(seed, GetWidthPercentRelation());
226     o3tl::hash_combine(seed, GetHeightPercent());
227     o3tl::hash_combine(seed, GetHeightPercentRelation());
228     o3tl::hash_combine(seed, GetSize().Width());
229     o3tl::hash_combine(seed, GetSize().Height());
230     return seed;
231 }
232 
ScaleMetrics(tools::Long lMult,tools::Long lDiv)233 void SwFormatFrameSize::ScaleMetrics(tools::Long lMult, tools::Long lDiv) {
234     // Don't inherit the SvxSizeItem override (might or might not be relevant; added "just in case"
235     // when changing SwFormatFrameSize to derive from SvxSizeItem instead of directly from
236     // SfxPoolItem):
237     return SfxPoolItem::ScaleMetrics(lMult, lDiv);
238 }
239 
HasMetrics() const240 bool SwFormatFrameSize::HasMetrics() const {
241     // Don't inherit the SvxSizeItem override (might or might not be relevant; added "just in case"
242     // when changing SwFormatFrameSize to derive from SvxSizeItem instead of directly from
243     // SfxPoolItem):
244     return SfxPoolItem::HasMetrics();
245 }
246 
247 // Partially implemented inline in hxx
SwFormatFrameSize(SwFrameSize eSize,SwTwips nWidth,SwTwips nHeight)248 SwFormatFrameSize::SwFormatFrameSize( SwFrameSize eSize, SwTwips nWidth, SwTwips nHeight )
249     : SvxSizeItem( RES_FRM_SIZE, {nWidth, nHeight} ),
250     m_eFrameHeightType( eSize ),
251     m_eFrameWidthType( SwFrameSize::Fixed )
252 {
253     m_nWidthPercent = m_eWidthPercentRelation = m_nHeightPercent = m_eHeightPercentRelation = 0;
254 }
255 
operator ==(const SfxPoolItem & rAttr) const256 bool SwFormatFrameSize::operator==( const SfxPoolItem& rAttr ) const
257 {
258     assert(SfxPoolItem::operator==(rAttr));
259     return( m_eFrameHeightType  == static_cast<const SwFormatFrameSize&>(rAttr).m_eFrameHeightType &&
260             m_eFrameWidthType  == static_cast<const SwFormatFrameSize&>(rAttr).m_eFrameWidthType &&
261             SvxSizeItem::operator==(rAttr)&&
262             m_nWidthPercent   == static_cast<const SwFormatFrameSize&>(rAttr).GetWidthPercent() &&
263             m_eWidthPercentRelation == static_cast<const SwFormatFrameSize&>(rAttr).GetWidthPercentRelation() &&
264             m_nHeightPercent  == static_cast<const SwFormatFrameSize&>(rAttr).GetHeightPercent() &&
265             m_eHeightPercentRelation == static_cast<const SwFormatFrameSize&>(rAttr).GetHeightPercentRelation() );
266 }
267 
Clone(SfxItemPool *) const268 SwFormatFrameSize* SwFormatFrameSize::Clone( SfxItemPool* ) const
269 {
270     return new SwFormatFrameSize( *this );
271 }
272 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const273 bool SwFormatFrameSize::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
274 {
275     // here we convert always!
276     nMemberId &= ~CONVERT_TWIPS;
277     switch ( nMemberId )
278     {
279         case MID_FRMSIZE_SIZE:
280         {
281             awt::Size aTmp;
282             aTmp.Height = convertTwipToMm100(GetHeight());
283             aTmp.Width = convertTwipToMm100(GetWidth());
284             rVal <<= aTmp;
285         }
286         break;
287         case MID_FRMSIZE_REL_HEIGHT:
288             rVal <<= static_cast<sal_Int16>(GetHeightPercent() != SwFormatFrameSize::SYNCED ? GetHeightPercent() : 0);
289         break;
290         case MID_FRMSIZE_REL_HEIGHT_RELATION:
291             rVal <<= GetHeightPercentRelation();
292         break;
293         case MID_FRMSIZE_REL_WIDTH:
294             rVal <<= static_cast<sal_Int16>(GetWidthPercent() != SwFormatFrameSize::SYNCED ? GetWidthPercent() : 0);
295         break;
296         case MID_FRMSIZE_REL_WIDTH_RELATION:
297             rVal <<= GetWidthPercentRelation();
298         break;
299         case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH:
300             rVal <<= SwFormatFrameSize::SYNCED == GetHeightPercent();
301         break;
302         case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT:
303             rVal <<= SwFormatFrameSize::SYNCED == GetWidthPercent();
304         break;
305         case MID_FRMSIZE_WIDTH :
306             rVal <<= static_cast<sal_Int32>(convertTwipToMm100(GetWidth()));
307         break;
308         case MID_FRMSIZE_HEIGHT:
309             // #95848# returned size should never be zero.
310             // (there was a bug that allowed for setting height to 0.
311             // Thus there some documents existing with that not allowed
312             // attribute value which may cause problems on import.)
313             rVal <<= static_cast<sal_Int32>(convertTwipToMm100(GetHeight() < MINLAY ? MINLAY : GetHeight() ));
314         break;
315         case MID_FRMSIZE_SIZE_TYPE:
316             rVal <<= static_cast<sal_Int16>(GetHeightSizeType());
317         break;
318         case MID_FRMSIZE_IS_AUTO_HEIGHT:
319             rVal <<= SwFrameSize::Fixed != GetHeightSizeType();
320         break;
321         case MID_FRMSIZE_WIDTH_TYPE:
322             rVal <<= static_cast<sal_Int16>(GetWidthSizeType());
323         break;
324     }
325     return true;
326 }
327 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)328 bool SwFormatFrameSize::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
329 {
330     bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
331     nMemberId &= ~CONVERT_TWIPS;
332     bool bRet = true;
333     switch ( nMemberId )
334     {
335         case MID_FRMSIZE_SIZE:
336         {
337             awt::Size aVal;
338             if(!(rVal >>= aVal))
339                 bRet = false;
340             else
341             {
342                 Size aTmp(aVal.Width, aVal.Height);
343                 if(bConvert)
344                 {
345                     aTmp.setHeight(o3tl::toTwips(aTmp.Height(), o3tl::Length::mm100));
346                     aTmp.setWidth(o3tl::toTwips(aTmp.Width(), o3tl::Length::mm100));
347                 }
348                 SetSize(aTmp);
349             }
350         }
351         break;
352         case MID_FRMSIZE_REL_HEIGHT:
353         {
354             sal_Int16 nSet = 0;
355             rVal >>= nSet;
356             if(nSet >= 0 && nSet < SwFormatFrameSize::SYNCED)
357                 SetHeightPercent(static_cast<sal_uInt8>(nSet));
358             else
359                 bRet = false;
360         }
361         break;
362         case MID_FRMSIZE_REL_HEIGHT_RELATION:
363         {
364             sal_Int16 eSet = 0;
365             rVal >>= eSet;
366             SetHeightPercentRelation(eSet);
367         }
368         break;
369         case MID_FRMSIZE_REL_WIDTH:
370         {
371             sal_Int16 nSet = 0;
372             rVal >>= nSet;
373             if(nSet >= 0 && nSet < SwFormatFrameSize::SYNCED)
374                 SetWidthPercent(static_cast<sal_uInt8>(nSet));
375             else
376                 bRet = false;
377         }
378         break;
379         case MID_FRMSIZE_REL_WIDTH_RELATION:
380         {
381             sal_Int16 eSet = 0;
382             rVal >>= eSet;
383             SetWidthPercentRelation(eSet);
384         }
385         break;
386         case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH:
387         {
388             bool bSet = *o3tl::doAccess<bool>(rVal);
389             if(bSet)
390                 SetHeightPercent(SwFormatFrameSize::SYNCED);
391             else if( SwFormatFrameSize::SYNCED == GetHeightPercent() )
392                 SetHeightPercent( 0 );
393         }
394         break;
395         case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT:
396         {
397             bool bSet = *o3tl::doAccess<bool>(rVal);
398             if(bSet)
399                 SetWidthPercent(SwFormatFrameSize::SYNCED);
400             else if( SwFormatFrameSize::SYNCED == GetWidthPercent() )
401                 SetWidthPercent(0);
402         }
403         break;
404         case MID_FRMSIZE_WIDTH :
405         {
406             sal_Int32 nWd = 0;
407             if(rVal >>= nWd)
408             {
409                 if(bConvert)
410                     nWd = o3tl::toTwips(nWd, o3tl::Length::mm100);
411                 if(nWd < MINLAY)
412                    nWd = MINLAY;
413                 SetWidth(nWd);
414             }
415             else
416                 bRet = false;
417         }
418         break;
419         case MID_FRMSIZE_HEIGHT:
420         {
421             sal_Int32 nHg = 0;
422             if(rVal >>= nHg)
423             {
424                 if(bConvert)
425                     nHg = o3tl::toTwips(nHg, o3tl::Length::mm100);
426                 if(nHg < MINLAY)
427                     nHg = MINLAY;
428                 SetHeight(nHg);
429             }
430             else
431                 bRet = false;
432         }
433         break;
434         case MID_FRMSIZE_SIZE_TYPE:
435         {
436             sal_Int16 nType = 0;
437             if((rVal >>= nType) && nType >= 0 && nType <= static_cast<int>(SwFrameSize::Minimum) )
438             {
439                 SetHeightSizeType(static_cast<SwFrameSize>(nType));
440             }
441             else
442                 bRet = false;
443         }
444         break;
445         case MID_FRMSIZE_IS_AUTO_HEIGHT:
446         {
447             bool bSet = *o3tl::doAccess<bool>(rVal);
448             SetHeightSizeType(bSet ? SwFrameSize::Variable : SwFrameSize::Fixed);
449         }
450         break;
451         case MID_FRMSIZE_WIDTH_TYPE:
452         {
453             sal_Int16 nType = 0;
454             if((rVal >>= nType) && nType >= 0 && nType <= static_cast<int>(SwFrameSize::Minimum) )
455             {
456                 SetWidthSizeType(static_cast<SwFrameSize>(nType));
457             }
458             else
459                 bRet = false;
460         }
461         break;
462         default:
463             bRet = false;
464     }
465     return bRet;
466 }
467 
dumpAsXml(xmlTextWriterPtr pWriter) const468 void SwFormatFrameSize::dumpAsXml(xmlTextWriterPtr pWriter) const
469 {
470     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatFrameSize"));
471     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
472 
473     std::stringstream aSize;
474     aSize << GetSize();
475     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), BAD_CAST(aSize.str().c_str()));
476 
477     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameHeightType"), BAD_CAST(OString::number(static_cast<int>(m_eFrameHeightType)).getStr()));
478     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameWidthType"), BAD_CAST(OString::number(static_cast<int>(m_eFrameWidthType)).getStr()));
479     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthPercent"), BAD_CAST(OString::number(m_nWidthPercent).getStr()));
480     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eWidthPercentRelation"), BAD_CAST(OString::number(m_eWidthPercentRelation).getStr()));
481     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nHeightPercent"), BAD_CAST(OString::number(m_nHeightPercent).getStr()));
482     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eHeightPercentRelation"), BAD_CAST(OString::number(m_eHeightPercentRelation).getStr()));
483 
484     (void)xmlTextWriterEndElement(pWriter);
485 }
486 
487 // Partially implemented inline in hxx
SwFormatFillOrder(SwFillOrder nFO)488 SwFormatFillOrder::SwFormatFillOrder( SwFillOrder nFO )
489     : SfxEnumItem( RES_FILL_ORDER, nFO )
490 {}
491 
Clone(SfxItemPool *) const492 SwFormatFillOrder* SwFormatFillOrder::Clone( SfxItemPool* ) const
493 {
494     return new SwFormatFillOrder( GetValue() );
495 }
496 
497 // Partially implemented inline in hxx
SwFormatHeader(SwFrameFormat * pHeaderFormat)498 SwFormatHeader::SwFormatHeader( SwFrameFormat *pHeaderFormat )
499     : SfxPoolItem( RES_HEADER ),
500     sw::FrameFormatClient( pHeaderFormat ),
501     m_bActive( pHeaderFormat )
502 {
503 }
504 
SwFormatHeader(const SwFormatHeader & rCpy)505 SwFormatHeader::SwFormatHeader( const SwFormatHeader &rCpy )
506     : SfxPoolItem( RES_HEADER ),
507     sw::FrameFormatClient( const_cast<SwFrameFormat*>(rCpy.GetRegisteredIn()) ),
508     m_bActive( rCpy.IsActive() )
509 {
510 }
511 
SwFormatHeader(bool bOn)512 SwFormatHeader::SwFormatHeader( bool bOn )
513     : SfxPoolItem( RES_HEADER ),
514     sw::FrameFormatClient( nullptr ),
515     m_bActive( bOn )
516 {
517 }
518 
~SwFormatHeader()519  SwFormatHeader::~SwFormatHeader()
520 {
521     if ( GetHeaderFormat() )
522         lcl_DelHFFormat( this, GetHeaderFormat() );
523 }
524 
operator ==(const SfxPoolItem & rAttr) const525 bool SwFormatHeader::operator==( const SfxPoolItem& rAttr ) const
526 {
527     assert(SfxPoolItem::operator==(rAttr));
528     return ( GetRegisteredIn() == static_cast<const SwFormatHeader&>(rAttr).GetRegisteredIn() &&
529              m_bActive == static_cast<const SwFormatHeader&>(rAttr).IsActive() );
530 }
531 
Clone(SfxItemPool *) const532 SwFormatHeader* SwFormatHeader::Clone( SfxItemPool* ) const
533 {
534     return new SwFormatHeader( *this );
535 }
536 
RegisterToFormat(SwFrameFormat & rFormat)537 void SwFormatHeader::RegisterToFormat( SwFrameFormat& rFormat )
538 {
539     rFormat.Add(*this);
540 }
541 
dumpAsXml(xmlTextWriterPtr pWriter) const542 void SwFormatHeader::dumpAsXml(xmlTextWriterPtr pWriter) const
543 {
544     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatHeader"));
545     SfxPoolItem::dumpAsXml(pWriter);
546 
547     const SwFrameFormat* pHeaderFormat = GetHeaderFormat();
548     if (pHeaderFormat)
549     {
550         pHeaderFormat->dumpAsXml(pWriter);
551     }
552 
553     (void)xmlTextWriterEndElement(pWriter);
554 }
555 
556 // Partially implemented inline in hxx
SwFormatFooter(SwFrameFormat * pFooterFormat)557 SwFormatFooter::SwFormatFooter( SwFrameFormat *pFooterFormat )
558     : SfxPoolItem( RES_FOOTER ),
559     sw::FrameFormatClient( pFooterFormat ),
560     m_bActive( pFooterFormat )
561 {
562 }
563 
SwFormatFooter(const SwFormatFooter & rCpy)564 SwFormatFooter::SwFormatFooter( const SwFormatFooter &rCpy )
565     : SfxPoolItem( RES_FOOTER ),
566     sw::FrameFormatClient( const_cast<SwFrameFormat*>(rCpy.GetRegisteredIn()) ),
567     m_bActive( rCpy.IsActive() )
568 {
569 }
570 
SwFormatFooter(bool bOn)571 SwFormatFooter::SwFormatFooter( bool bOn )
572     : SfxPoolItem( RES_FOOTER ),
573     sw::FrameFormatClient( nullptr ),
574     m_bActive( bOn )
575 {
576 }
577 
~SwFormatFooter()578  SwFormatFooter::~SwFormatFooter()
579 {
580     if ( GetFooterFormat() )
581         lcl_DelHFFormat( this, GetFooterFormat() );
582 }
583 
RegisterToFormat(SwFormat & rFormat)584 void SwFormatFooter::RegisterToFormat( SwFormat& rFormat )
585 {
586     rFormat.Add(*this);
587 }
588 
operator ==(const SfxPoolItem & rAttr) const589 bool SwFormatFooter::operator==( const SfxPoolItem& rAttr ) const
590 {
591     assert(SfxPoolItem::operator==(rAttr));
592     return ( GetRegisteredIn() == static_cast<const SwFormatFooter&>(rAttr).GetRegisteredIn() &&
593              m_bActive == static_cast<const SwFormatFooter&>(rAttr).IsActive() );
594 }
595 
Clone(SfxItemPool *) const596 SwFormatFooter* SwFormatFooter::Clone( SfxItemPool* ) const
597 {
598     return new SwFormatFooter( *this );
599 }
600 
dumpAsXml(xmlTextWriterPtr pWriter) const601 void SwFormatFooter::dumpAsXml(xmlTextWriterPtr pWriter) const
602 {
603     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatFooter"));
604     SfxPoolItem::dumpAsXml(pWriter);
605 
606     const SwFrameFormat* pFooterFormat = GetFooterFormat();
607     if (pFooterFormat)
608     {
609         pFooterFormat->dumpAsXml(pWriter);
610     }
611 
612     (void)xmlTextWriterEndElement(pWriter);
613 }
614 
615 // Partially implemented inline in hxx
SwFormatContent(const SwFormatContent & rCpy)616 SwFormatContent::SwFormatContent( const SwFormatContent &rCpy )
617     : SfxPoolItem( RES_CNTNT )
618     , m_oStartNode( rCpy.m_oStartNode )
619 {
620     setNonShareable();
621 }
622 
SwFormatContent(const SwStartNode * pStartNd)623 SwFormatContent::SwFormatContent( const SwStartNode *pStartNd )
624     : SfxPoolItem( RES_CNTNT )
625 {
626     setNonShareable();
627     if (pStartNd)
628         m_oStartNode = *pStartNd;
629 }
630 
~SwFormatContent()631 SwFormatContent::~SwFormatContent()
632 {
633 }
634 
SetNewContentIdx(const SwNodeIndex * pIdx)635 void SwFormatContent::SetNewContentIdx( const SwNodeIndex *pIdx )
636 {
637     if (pIdx)
638         m_oStartNode = *pIdx;
639     else
640         m_oStartNode.reset();
641 }
642 
operator ==(const SfxPoolItem & rAttr) const643 bool SwFormatContent::operator==( const SfxPoolItem& rAttr ) const
644 {
645     assert(SfxPoolItem::operator==(rAttr));
646     return m_oStartNode == static_cast<const SwFormatContent&>(rAttr).m_oStartNode;
647 }
648 
Clone(SfxItemPool *) const649 SwFormatContent* SwFormatContent::Clone( SfxItemPool* ) const
650 {
651     return new SwFormatContent( *this );
652 }
653 
dumpAsXml(xmlTextWriterPtr pWriter) const654 void SwFormatContent::dumpAsXml(xmlTextWriterPtr pWriter) const
655 {
656     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatContent"));
657     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
658     if (m_oStartNode)
659     {
660         (void)xmlTextWriterWriteAttribute(
661             pWriter, BAD_CAST("startNode"),
662             BAD_CAST(OString::number(sal_Int32(m_oStartNode->GetNode().GetIndex())).getStr()));
663         (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("startNodePtr"), "%p",
664                                           &m_oStartNode->GetNode());
665     }
666     (void)xmlTextWriterEndElement(pWriter);
667 }
668 
669 // Partially implemented inline in hxx
SwFormatPageDesc(const SwFormatPageDesc & rCpy)670 SwFormatPageDesc::SwFormatPageDesc( const SwFormatPageDesc &rCpy )
671     : SfxPoolItem( RES_PAGEDESC ),
672     SwClient( const_cast<SwPageDesc*>(rCpy.GetPageDesc()) ),
673     m_oNumOffset( rCpy.m_oNumOffset ),
674     m_pDefinedIn( nullptr )
675 {
676     setNonShareable();
677 }
678 
SwFormatPageDesc(const SwPageDesc * pDesc)679 SwFormatPageDesc::SwFormatPageDesc( const SwPageDesc *pDesc )
680     : SfxPoolItem( RES_PAGEDESC ),
681     SwClient( const_cast<SwPageDesc*>(pDesc) ),
682     m_pDefinedIn( nullptr )
683 {
684     setNonShareable();
685 }
686 
operator =(const SwFormatPageDesc & rCpy)687 SwFormatPageDesc &SwFormatPageDesc::operator=(const SwFormatPageDesc &rCpy)
688 {
689     if (SfxPoolItem::areSame(*this, rCpy))
690         return *this;
691     ASSERT_CHANGE_REFCOUNTED_ITEM;
692     if (rCpy.GetPageDesc())
693         RegisterToPageDesc(*const_cast<SwPageDesc*>(rCpy.GetPageDesc()));
694     m_oNumOffset = rCpy.m_oNumOffset;
695     m_pDefinedIn = nullptr;
696 
697     return *this;
698 }
699 
~SwFormatPageDesc()700  SwFormatPageDesc::~SwFormatPageDesc() {}
701 
KnowsPageDesc() const702 bool SwFormatPageDesc::KnowsPageDesc() const
703 {
704     return (GetRegisteredIn() != nullptr);
705 }
706 
operator ==(const SfxPoolItem & rAttr) const707 bool SwFormatPageDesc::operator==( const SfxPoolItem& rAttr ) const
708 {
709     assert(SfxPoolItem::operator==(rAttr));
710     return  ( m_pDefinedIn == static_cast<const SwFormatPageDesc&>(rAttr).m_pDefinedIn ) &&
711             ( m_oNumOffset == static_cast<const SwFormatPageDesc&>(rAttr).m_oNumOffset ) &&
712             ( GetPageDesc() == static_cast<const SwFormatPageDesc&>(rAttr).GetPageDesc() );
713 }
714 
hashCode() const715 size_t SwFormatPageDesc::hashCode() const
716 {
717     std::size_t seed(0);
718     // note that we cannot include m_pDefinedIn in the hash because that is updated in SwAttrSet::SetModifyAtAttr
719     o3tl::hash_combine(seed, m_oNumOffset);
720     o3tl::hash_combine(seed, GetPageDesc());
721     return seed;
722 }
723 
Clone(SfxItemPool *) const724 SwFormatPageDesc* SwFormatPageDesc::Clone( SfxItemPool* ) const
725 {
726     return new SwFormatPageDesc( *this );
727 }
728 
SwClientNotify(const SwModify &,const SfxHint & rHint)729 void SwFormatPageDesc::SwClientNotify(const SwModify&, const SfxHint& rHint)
730 {
731     if(rHint.GetId() == SfxHintId::SwAutoFormatUsedHint)
732     {
733         if(GetRegisteredIn())
734             static_cast<const sw::AutoFormatUsedHint&>(rHint).SetUsed(); //TODO: recheck if this is really the right way to check for use
735     }
736     else if (rHint.GetId() == SfxHintId::SwPageDesc)
737     {
738         const SwPageDescHint* pHint = static_cast<const SwPageDescHint*>(&rHint);
739         // mba: shouldn't that be broadcasted also?
740         SwFormatPageDesc aDfltDesc(pHint->GetPageDesc());
741         SwPageDesc* pDesc = pHint->GetPageDesc();
742         const sw::BroadcastingModify* pMod = GetDefinedIn();
743         if(pMod)
744         {
745             if(auto pContentNode = dynamic_cast<const SwContentNode*>(pMod))
746                 const_cast<SwContentNode*>(pContentNode)->SetAttr(aDfltDesc);
747             else if(auto pFormat = dynamic_cast<const SwFormat*>(pMod))
748                 const_cast<SwFormat*>(pFormat)->SetFormatAttr( aDfltDesc );
749             else
750             {
751                 SAL_WARN("sw.core", "SwFormatPageDesc registered at " << typeid(pMod).name() << ".");
752                 RegisterToPageDesc(*pDesc);
753             }
754         }
755         else
756             // there could be an Undo-copy
757             RegisterToPageDesc(*pDesc);
758     }
759     else if (rHint.GetId() == SfxHintId::SwObjectDying)
760     {
761         m_pDefinedIn = nullptr;
762         EndListeningAll();
763     }
764 }
765 
RegisterToPageDesc(SwPageDesc & rDesc)766 void SwFormatPageDesc::RegisterToPageDesc( SwPageDesc& rDesc )
767 {
768     rDesc.Add(*this);
769 }
770 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const771 bool SwFormatPageDesc::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
772 {
773     // here we convert always!
774     nMemberId &= ~CONVERT_TWIPS;
775     bool    bRet = true;
776     switch ( nMemberId )
777     {
778         case MID_PAGEDESC_PAGENUMOFFSET:
779             {
780                 ::std::optional<sal_uInt16> oOffset = GetNumOffset();
781                 if (oOffset)
782                 {
783                     rVal <<= static_cast<sal_Int16>(*oOffset);
784                 }
785                 else
786                 {
787                     rVal.clear();
788                 }
789             }
790             break;
791 
792         case MID_PAGEDESC_PAGEDESCNAME:
793             {
794                 const SwPageDesc* pDesc = GetPageDesc();
795                 if( pDesc )
796                 {
797                     ProgName aString;
798                     SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, SwGetPoolIdFromName::PageDesc);
799                     rVal <<= aString.toString();
800                 }
801                 else
802                     rVal.clear();
803             }
804             break;
805         default:
806             OSL_ENSURE( false, "unknown MemberId" );
807             bRet = false;
808     }
809     return bRet;
810 }
811 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)812 bool SwFormatPageDesc::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
813 {
814     ASSERT_CHANGE_REFCOUNTED_ITEM;
815     // here we convert always!
816     nMemberId &= ~CONVERT_TWIPS;
817     bool bRet = true;
818     switch ( nMemberId )
819     {
820         case MID_PAGEDESC_PAGENUMOFFSET:
821         {
822             sal_Int16 nOffset = 0;
823             if (!rVal.hasValue())
824             {
825                 SetNumOffset(std::nullopt);
826             }
827             else if (rVal >>= nOffset)
828                 SetNumOffset( nOffset );
829             else
830                 bRet = false;
831         }
832         break;
833 
834         case MID_PAGEDESC_PAGEDESCNAME:
835             /* Doesn't work, because the attribute doesn't need the name but a
836              * pointer to the PageDesc (it's a client of it). The pointer can
837              * only be requested from the document using the name.
838              */
839         default:
840             OSL_ENSURE( false, "unknown MemberId" );
841             bRet = false;
842     }
843     return bRet;
844 }
845 
dumpAsXml(xmlTextWriterPtr pWriter) const846 void SwFormatPageDesc::dumpAsXml(xmlTextWriterPtr pWriter) const
847 {
848     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatPageDesc"));
849     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
850     if (m_oNumOffset)
851         (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("oNumOffset"), BAD_CAST(OString::number(*m_oNumOffset).getStr()));
852     else
853         (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("oNumOffset"), BAD_CAST("none"));
854     (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("pPageDesc"), "%p", GetPageDesc());
855     if (const SwPageDesc* pPageDesc = GetPageDesc())
856         (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(pPageDesc->GetName().toString().toUtf8().getStr()));
857     (void)xmlTextWriterEndElement(pWriter);
858 }
859 
860 //  class SwFormatCol
861 //  Partially implemented inline in hxx
862 
SwColumn()863 SwColumn::SwColumn() :
864     m_nWish ( 0 ),
865     m_nLeft ( 0 ),
866     m_nRight( 0 )
867 {
868 }
869 
operator ==(const SwColumn & rCmp) const870 bool SwColumn::operator==( const SwColumn &rCmp ) const
871 {
872     return  m_nWish    == rCmp.GetWishWidth() &&
873             GetLeft()  == rCmp.GetLeft() &&
874             GetRight() == rCmp.GetRight();
875 }
876 
dumpAsXml(xmlTextWriterPtr pWriter) const877 void SwColumn::dumpAsXml(xmlTextWriterPtr pWriter) const
878 {
879     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwColumn"));
880     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWish"), BAD_CAST(OString::number(m_nWish).getStr()));
881     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUpper"), BAD_CAST(OString::number(0).getStr()));
882     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLower"), BAD_CAST(OString::number(0).getStr()));
883     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeft"), BAD_CAST(OString::number(m_nLeft).getStr()));
884     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRight"), BAD_CAST(OString::number(m_nRight).getStr()));
885     (void)xmlTextWriterEndElement(pWriter);
886 }
887 
SwFormatCol(const SwFormatCol & rCpy)888 SwFormatCol::SwFormatCol( const SwFormatCol& rCpy )
889     : SfxPoolItem( RES_COL ),
890     m_eLineStyle( rCpy.m_eLineStyle ),
891     m_nLineWidth( rCpy.m_nLineWidth),
892     m_aLineColor( rCpy.m_aLineColor),
893     m_nLineHeight( rCpy.GetLineHeight() ),
894     m_eAdj( rCpy.GetLineAdj() ),
895     m_nWidth( rCpy.GetWishWidth() ),
896     m_aWidthAdjustValue( rCpy.m_aWidthAdjustValue ),
897     m_bOrtho( rCpy.IsOrtho() )
898 {
899     m_aColumns.reserve(rCpy.GetNumCols());
900     for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i )
901     {
902         m_aColumns.emplace_back(rCpy.GetColumns()[i] );
903     }
904 }
905 
~SwFormatCol()906 SwFormatCol::~SwFormatCol() {}
907 
operator =(const SwFormatCol & rCpy)908 SwFormatCol& SwFormatCol::operator=( const SwFormatCol& rCpy )
909 {
910     if (!SfxPoolItem::areSame(*this, rCpy))
911     {
912         m_eLineStyle  = rCpy.m_eLineStyle;
913         m_nLineWidth  = rCpy.m_nLineWidth;
914         m_aLineColor  = rCpy.m_aLineColor;
915         m_nLineHeight = rCpy.GetLineHeight();
916         m_eAdj        = rCpy.GetLineAdj();
917         m_nWidth      = rCpy.GetWishWidth();
918         m_aWidthAdjustValue = rCpy.m_aWidthAdjustValue;
919         m_bOrtho      = rCpy.IsOrtho();
920 
921         m_aColumns.clear();
922         for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i )
923         {
924             m_aColumns.emplace_back(rCpy.GetColumns()[i] );
925         }
926     }
927     return *this;
928 }
929 
SwFormatCol()930 SwFormatCol::SwFormatCol()
931     : SfxPoolItem( RES_COL )
932     , m_eLineStyle( SvxBorderLineStyle::NONE)
933     ,
934     m_nLineWidth(0),
935     m_nLineHeight( 100 ),
936     m_eAdj( COLADJ_NONE ),
937     m_nWidth( USHRT_MAX ),
938     m_aWidthAdjustValue( 0 ),
939     m_bOrtho( true )
940 {
941 }
942 
operator ==(const SfxPoolItem & rAttr) const943 bool SwFormatCol::operator==( const SfxPoolItem& rAttr ) const
944 {
945     assert(SfxPoolItem::operator==(rAttr));
946     const SwFormatCol &rCmp = static_cast<const SwFormatCol&>(rAttr);
947     if( !(m_eLineStyle        == rCmp.m_eLineStyle  &&
948           m_nLineWidth        == rCmp.m_nLineWidth  &&
949           m_aLineColor        == rCmp.m_aLineColor  &&
950           m_nLineHeight        == rCmp.GetLineHeight() &&
951           m_eAdj               == rCmp.GetLineAdj() &&
952           m_nWidth             == rCmp.GetWishWidth() &&
953           m_bOrtho             == rCmp.IsOrtho() &&
954           m_aColumns.size() == rCmp.GetNumCols() &&
955           m_aWidthAdjustValue == rCmp.GetAdjustValue()
956          ) )
957         return false;
958 
959     for ( size_t i = 0; i < m_aColumns.size(); ++i )
960         if ( !(m_aColumns[i] == rCmp.GetColumns()[i]) )
961             return false;
962 
963     return true;
964 }
965 
Clone(SfxItemPool *) const966 SwFormatCol* SwFormatCol::Clone( SfxItemPool* ) const
967 {
968     return new SwFormatCol( *this );
969 }
970 
GetGutterWidth(bool bMin) const971 sal_uInt16 SwFormatCol::GetGutterWidth( bool bMin ) const
972 {
973     sal_uInt16 nRet = 0;
974     if ( m_aColumns.size() == 2 )
975         nRet = m_aColumns[0].GetRight() + m_aColumns[1].GetLeft();
976     else if ( m_aColumns.size() > 2 )
977     {
978         bool bSet = false;
979         for ( size_t i = 1; i+1 < m_aColumns.size(); ++i )
980         {
981             const sal_uInt16 nTmp = m_aColumns[i].GetRight() + m_aColumns[i+1].GetLeft();
982             if ( bSet )
983             {
984                 if ( nTmp != nRet )
985                 {
986                     if ( !bMin )
987                         return USHRT_MAX;
988                     if ( nRet > nTmp )
989                         nRet = nTmp;
990                 }
991             }
992             else
993             {
994                 bSet = true;
995                 nRet = nTmp;
996             }
997         }
998     }
999     return nRet;
1000 }
1001 
SetGutterWidth(sal_uInt16 nNew,sal_uInt16 nAct)1002 void SwFormatCol::SetGutterWidth( sal_uInt16 nNew, sal_uInt16 nAct )
1003 {
1004     if ( m_bOrtho )
1005         Calc( nNew, nAct );
1006     else
1007     {
1008         sal_uInt16 nHalf = nNew / 2;
1009         for (size_t i = 0; i < m_aColumns.size(); ++i)
1010         {
1011             SwColumn &rCol = m_aColumns[i];
1012             rCol.SetLeft(nHalf);
1013             rCol.SetRight(nHalf);
1014             if ( i == 0 )
1015                 rCol.SetLeft(0);
1016             else if ( i+1 == m_aColumns.size() )
1017                 rCol.SetRight(0);
1018         }
1019     }
1020 }
1021 
Init(sal_uInt16 nNumCols,sal_uInt16 nGutterWidth,sal_uInt16 nAct)1022 void SwFormatCol::Init( sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct )
1023 {
1024     // Deleting seems to be a bit radical on the first sight; but otherwise we
1025     // have to initialize all values of the remaining SwColumns.
1026     m_aColumns.clear();
1027     for ( sal_uInt16 i = 0; i < nNumCols; ++i )
1028     {
1029         m_aColumns.emplace_back( );
1030     }
1031     m_bOrtho = true;
1032     m_nWidth = USHRT_MAX;
1033     if( nNumCols )
1034         Calc( nGutterWidth, nAct );
1035 }
1036 
SetOrtho(bool bNew,sal_uInt16 nGutterWidth,sal_uInt16 nAct)1037 void SwFormatCol::SetOrtho( bool bNew, sal_uInt16 nGutterWidth, sal_uInt16 nAct )
1038 {
1039     m_bOrtho = bNew;
1040     if ( bNew && !m_aColumns.empty() )
1041         Calc( nGutterWidth, nAct );
1042 }
1043 
CalcColWidth(sal_uInt16 nCol,sal_uInt16 nAct) const1044 sal_uInt16 SwFormatCol::CalcColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const
1045 {
1046     assert(nCol < m_aColumns.size());
1047     if ( m_nWidth != nAct )
1048     {
1049         tools::Long nW = m_aColumns[nCol].GetWishWidth();
1050         nW *= nAct;
1051         nW /= m_nWidth;
1052         return sal_uInt16(nW);
1053     }
1054     else
1055         return m_aColumns[nCol].GetWishWidth();
1056 }
1057 
CalcPrtColWidth(sal_uInt16 nCol,sal_uInt16 nAct) const1058 sal_uInt16 SwFormatCol::CalcPrtColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const
1059 {
1060     assert(nCol < m_aColumns.size());
1061     sal_uInt16 nRet = CalcColWidth( nCol, nAct );
1062     const SwColumn *pCol = &m_aColumns[nCol];
1063     nRet = nRet - pCol->GetLeft();
1064     nRet = nRet - pCol->GetRight();
1065     return nRet;
1066 }
1067 
Calc(sal_uInt16 nGutterWidth,sal_uInt16 nAct)1068 void SwFormatCol::Calc( sal_uInt16 nGutterWidth, sal_uInt16 nAct )
1069 {
1070     if (!GetNumCols())
1071         return;
1072 
1073     //First set the column widths with the current width, then calculate the
1074     //column's requested width using the requested total width.
1075     const sal_uInt16 nGutterHalf = nGutterWidth ? nGutterWidth / 2 : 0;
1076 
1077     //Width of PrtAreas is totalwidth - spacings / count
1078     sal_uInt16 nSpacings;
1079     bool bFail = o3tl::checked_multiply<sal_uInt16>(GetNumCols() - 1, nGutterWidth, nSpacings);
1080     if (bFail)
1081     {
1082         SAL_WARN("sw.core", "SwFormatVertOrient::Calc: overflow");
1083         return;
1084     }
1085 
1086     const sal_uInt16 nPrtWidth = (nAct - nSpacings) / GetNumCols();
1087     sal_uInt16 nAvail = nAct;
1088 
1089     //The first column is PrtWidth + (gap width / 2)
1090     const sal_uInt16 nLeftWidth = nPrtWidth + nGutterHalf;
1091     SwColumn &rFirstCol = m_aColumns.front();
1092     rFirstCol.SetWishWidth(nLeftWidth);
1093     rFirstCol.SetRight(nGutterHalf);
1094     rFirstCol.SetLeft(0);
1095     nAvail = nAvail - nLeftWidth;
1096 
1097     //Column 2 to n-1 is PrtWidth + gap width
1098     const sal_uInt16 nMidWidth = nPrtWidth + nGutterWidth;
1099 
1100     for (sal_uInt16 i = 1; i < GetNumCols()-1; ++i)
1101     {
1102         SwColumn &rCol = m_aColumns[i];
1103         rCol.SetWishWidth(nMidWidth);
1104         rCol.SetLeft(nGutterHalf);
1105         rCol.SetRight(nGutterHalf);
1106         nAvail = nAvail - nMidWidth;
1107     }
1108 
1109     //The last column is equivalent to the first one - to compensate rounding
1110     //errors we add the remaining space of the other columns to the last one.
1111     SwColumn &rLastCol = m_aColumns.back();
1112     rLastCol.SetWishWidth(nAvail);
1113     rLastCol.SetLeft(nGutterHalf);
1114     rLastCol.SetRight(0);
1115 
1116     assert(nAct != 0);
1117     //Convert the current width to the requested width.
1118     for (SwColumn &rCol: m_aColumns)
1119     {
1120         tools::Long nTmp = rCol.GetWishWidth();
1121         nTmp *= GetWishWidth();
1122         nTmp = nAct == 0 ? nTmp : nTmp / nAct;
1123         rCol.SetWishWidth(sal_uInt16(nTmp));
1124     }
1125 }
1126 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const1127 bool SwFormatCol::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1128 {
1129     // here we convert always!
1130     nMemberId &= ~CONVERT_TWIPS;
1131     if(MID_COLUMN_SEPARATOR_LINE == nMemberId)
1132     {
1133         OSL_FAIL("not implemented");
1134     }
1135     else
1136     {
1137         uno::Reference<text::XTextColumns> xCols(SvxXTextColumns_createInstance(),
1138                                                  css::uno::UNO_QUERY_THROW);
1139         uno::Reference<beans::XPropertySet> xProps(xCols, css::uno::UNO_QUERY_THROW);
1140 
1141         if (GetNumCols() > 0)
1142         {
1143             xCols->setColumnCount(GetNumCols());
1144             const sal_uInt16 nItemGutterWidth = GetGutterWidth();
1145             sal_Int32 nAutoDistance = IsOrtho() ? USHRT_MAX == nItemGutterWidth
1146                                                       ? DEF_GUTTER_WIDTH
1147                                                       : static_cast<sal_Int32>(nItemGutterWidth)
1148                                                 : 0;
1149             nAutoDistance = convertTwipToMm100(nAutoDistance);
1150             xProps->setPropertyValue(UNO_NAME_AUTOMATIC_DISTANCE, uno::Any(nAutoDistance));
1151 
1152             if (!IsOrtho())
1153             {
1154                 auto aTextColumns = xCols->getColumns();
1155                 text::TextColumn* pColumns = aTextColumns.getArray();
1156                 const SwColumns& rCols = GetColumns();
1157                 for (sal_Int32 i = 0; i < aTextColumns.getLength(); ++i)
1158                 {
1159                     const SwColumn* pCol = &rCols[i];
1160 
1161                     pColumns[i].Width = pCol->GetWishWidth();
1162                     pColumns[i].LeftMargin = convertTwipToMm100(pCol->GetLeft());
1163                     pColumns[i].RightMargin = convertTwipToMm100(pCol->GetRight());
1164                 }
1165                 xCols->setColumns(aTextColumns); // sets "IsAutomatic" property to false
1166             }
1167         }
1168         uno::Any aVal;
1169         aVal <<= o3tl::narrowing<sal_Int32>(
1170             o3tl::convert(GetLineWidth(), o3tl::Length::twip, o3tl::Length::mm100));
1171         xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH, aVal);
1172         aVal <<= GetLineColor();
1173         xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR, aVal);
1174         aVal <<= static_cast<sal_Int32>(GetLineHeight());
1175         xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT, aVal);
1176         aVal <<= GetLineAdj() != COLADJ_NONE;
1177         xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON, aVal);
1178         sal_Int16 nStyle;
1179         switch (GetLineStyle())
1180         {
1181             case SvxBorderLineStyle::SOLID:
1182                 nStyle = css::text::ColumnSeparatorStyle::SOLID;
1183                 break;
1184             case SvxBorderLineStyle::DOTTED:
1185                 nStyle = css::text::ColumnSeparatorStyle::DOTTED;
1186                 break;
1187             case SvxBorderLineStyle::DASHED:
1188                 nStyle = css::text::ColumnSeparatorStyle::DASHED;
1189                 break;
1190             case SvxBorderLineStyle::NONE:
1191             default:
1192                 nStyle = css::text::ColumnSeparatorStyle::NONE;
1193                 break;
1194         }
1195         aVal <<= nStyle;
1196         xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE, aVal);
1197         style::VerticalAlignment eAlignment;
1198         switch (GetLineAdj())
1199         {
1200             case COLADJ_TOP:
1201                 eAlignment = style::VerticalAlignment_TOP;
1202                 break;
1203             case COLADJ_BOTTOM:
1204                 eAlignment = style::VerticalAlignment_BOTTOM;
1205                 break;
1206             case COLADJ_CENTER:
1207             case COLADJ_NONE:
1208             default:
1209                 eAlignment = style::VerticalAlignment_MIDDLE;
1210         }
1211         aVal <<= eAlignment;
1212         xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT, aVal);
1213         rVal <<= xCols;
1214     }
1215     return true;
1216 }
1217 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)1218 bool SwFormatCol::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1219 {
1220     // here we convert always!
1221     nMemberId &= ~CONVERT_TWIPS;
1222     bool bRet = false;
1223     if(MID_COLUMN_SEPARATOR_LINE == nMemberId)
1224     {
1225         OSL_FAIL("not implemented");
1226     }
1227     else
1228     {
1229         uno::Reference< text::XTextColumns > xCols;
1230         rVal >>= xCols;
1231         if(xCols.is())
1232         {
1233             uno::Sequence<text::TextColumn> aSetColumns = xCols->getColumns();
1234             const text::TextColumn* pArray = aSetColumns.getConstArray();
1235             m_aColumns.clear();
1236             //max count is 64k here - this is something the array can't do
1237             sal_uInt16 nCount = std::min( o3tl::narrowing<sal_uInt16>(aSetColumns.getLength()),
1238                                      sal_uInt16(0x3fff) );
1239             sal_uInt16 nWidthSum = 0;
1240             // #101224# one column is no column
1241 
1242             if(nCount > 1)
1243                 for(sal_uInt16 i = 0; i < nCount; i++)
1244                 {
1245                     SwColumn aCol;
1246                     aCol.SetWishWidth(pArray[i].Width );
1247                     nWidthSum = nWidthSum + pArray[i].Width;
1248                     aCol.SetLeft (o3tl::toTwips(pArray[i].LeftMargin, o3tl::Length::mm100));
1249                     aCol.SetRight(o3tl::toTwips(pArray[i].RightMargin, o3tl::Length::mm100));
1250                     m_aColumns.insert(m_aColumns.begin() + i, aCol);
1251                 }
1252             bRet = true;
1253             m_nWidth = nWidthSum;
1254             m_bOrtho = false;
1255 
1256             if (uno::Reference<beans::XPropertySet> xProps{ xCols, css::uno::UNO_QUERY })
1257             {
1258                 xProps->getPropertyValue(UNO_NAME_IS_AUTOMATIC) >>= m_bOrtho;
1259                 xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH) >>= m_nLineWidth;
1260                 m_nLineWidth = o3tl::toTwips(m_nLineWidth, o3tl::Length::mm100);
1261                 xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR) >>= m_aLineColor;
1262                 if (sal_Int32 nHeight;
1263                     xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT) >>= nHeight)
1264                     m_nLineHeight = nHeight;
1265                 switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE).get<sal_Int16>())
1266                 {
1267                     default:
1268                     case css::text::ColumnSeparatorStyle::NONE:
1269                         m_eLineStyle = SvxBorderLineStyle::NONE;
1270                         break;
1271                     case css::text::ColumnSeparatorStyle::SOLID:
1272                         m_eLineStyle = SvxBorderLineStyle::SOLID;
1273                         break;
1274                     case css::text::ColumnSeparatorStyle::DOTTED:
1275                         m_eLineStyle = SvxBorderLineStyle::DOTTED;
1276                         break;
1277                     case css::text::ColumnSeparatorStyle::DASHED:
1278                         m_eLineStyle = SvxBorderLineStyle::DASHED;
1279                         break;
1280                 }
1281                 if (!xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON).get<bool>())
1282                     m_eAdj = COLADJ_NONE;
1283                 else switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT).get<style::VerticalAlignment>())
1284                 {
1285                     case style::VerticalAlignment_TOP: m_eAdj = COLADJ_TOP;  break;
1286                     case style::VerticalAlignment_MIDDLE: m_eAdj = COLADJ_CENTER; break;
1287                     case style::VerticalAlignment_BOTTOM: m_eAdj = COLADJ_BOTTOM; break;
1288                     default: OSL_ENSURE( false, "unknown alignment" ); break;
1289                 }
1290             }
1291         }
1292     }
1293     return bRet;
1294 }
1295 
dumpAsXml(xmlTextWriterPtr pWriter) const1296 void SwFormatCol::dumpAsXml(xmlTextWriterPtr pWriter) const
1297 {
1298     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatCol"));
1299     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1300     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLineStyle"), BAD_CAST(OString::number(static_cast<sal_Int16>(m_eLineStyle)).getStr()));
1301     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineWidth"), BAD_CAST(OString::number(m_nLineWidth).getStr()));
1302     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aLineColor"), BAD_CAST(m_aLineColor.AsRGBHexString().toUtf8().getStr()));
1303     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineHeight"), BAD_CAST(OString::number(m_nLineHeight).getStr()));
1304     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eAdj"), BAD_CAST(OString::number(m_eAdj).getStr()));
1305     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth"), BAD_CAST(OString::number(m_nWidth).getStr()));
1306     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthAdjustValue"), BAD_CAST(OString::number(m_aWidthAdjustValue).getStr()));
1307     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOrtho"), BAD_CAST(OString::boolean(m_bOrtho).getStr()));
1308 
1309     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("aColumns"));
1310     for (const SwColumn& rColumn : m_aColumns)
1311         rColumn.dumpAsXml(pWriter);
1312     (void)xmlTextWriterEndElement(pWriter);
1313 
1314     (void)xmlTextWriterEndElement(pWriter);
1315 }
1316 
1317 // Partially implemented inline in hxx
SwFormatSurround(css::text::WrapTextMode eFly)1318 SwFormatSurround::SwFormatSurround( css::text::WrapTextMode eFly ) :
1319     SfxEnumItem( RES_SURROUND, eFly )
1320 {
1321     m_bAnchorOnly = m_bContour = m_bOutside = false;
1322 }
1323 
operator ==(const SfxPoolItem & rAttr) const1324 bool SwFormatSurround::operator==( const SfxPoolItem& rAttr ) const
1325 {
1326     assert(SfxPoolItem::operator==(rAttr));
1327     return ( GetValue() == static_cast<const SwFormatSurround&>(rAttr).GetValue() &&
1328              m_bAnchorOnly== static_cast<const SwFormatSurround&>(rAttr).m_bAnchorOnly &&
1329              m_bContour== static_cast<const SwFormatSurround&>(rAttr).m_bContour &&
1330              m_bOutside== static_cast<const SwFormatSurround&>(rAttr).m_bOutside );
1331 }
1332 
Clone(SfxItemPool *) const1333 SwFormatSurround* SwFormatSurround::Clone( SfxItemPool* ) const
1334 {
1335     return new SwFormatSurround( *this );
1336 }
1337 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const1338 bool SwFormatSurround::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1339 {
1340     // here we convert always!
1341     nMemberId &= ~CONVERT_TWIPS;
1342     bool bRet = true;
1343     switch ( nMemberId )
1344     {
1345         case MID_SURROUND_SURROUNDTYPE:
1346             rVal <<= GetSurround();
1347             break;
1348         case MID_SURROUND_ANCHORONLY:
1349             rVal <<= IsAnchorOnly();
1350             break;
1351         case MID_SURROUND_CONTOUR:
1352             rVal <<= IsContour();
1353             break;
1354         case MID_SURROUND_CONTOUROUTSIDE:
1355             rVal <<= IsOutside();
1356             break;
1357         default:
1358             OSL_ENSURE( false, "unknown MemberId" );
1359             bRet = false;
1360     }
1361     return bRet;
1362 }
1363 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)1364 bool SwFormatSurround::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1365 {
1366     // here we convert always!
1367     nMemberId &= ~CONVERT_TWIPS;
1368     bool bRet = true;
1369     switch ( nMemberId )
1370     {
1371         case MID_SURROUND_SURROUNDTYPE:
1372         {
1373             css::text::WrapTextMode eVal = static_cast<css::text::WrapTextMode>(SWUnoHelper::GetEnumAsInt32( rVal ));
1374             if( eVal >= css::text::WrapTextMode_NONE && eVal <= css::text::WrapTextMode_RIGHT )
1375                 SetValue( eVal );
1376             else {
1377                 //exception
1378                 ;
1379             }
1380         }
1381         break;
1382 
1383         case MID_SURROUND_ANCHORONLY:
1384             SetAnchorOnly( *o3tl::doAccess<bool>(rVal) );
1385             break;
1386         case MID_SURROUND_CONTOUR:
1387             SetContour( *o3tl::doAccess<bool>(rVal) );
1388             break;
1389         case MID_SURROUND_CONTOUROUTSIDE:
1390             SetOutside( *o3tl::doAccess<bool>(rVal) );
1391             break;
1392         default:
1393             OSL_ENSURE( false, "unknown MemberId" );
1394             bRet = false;
1395     }
1396     return bRet;
1397 }
1398 
dumpAsXml(xmlTextWriterPtr pWriter) const1399 void SwFormatSurround::dumpAsXml(xmlTextWriterPtr pWriter) const
1400 {
1401     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatSurround"));
1402     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1403     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(static_cast<sal_Int32>(GetValue())).getStr()));
1404 
1405     OUString aPresentation;
1406     IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
1407     GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, MapUnit::Map100thMM, aPresentation, aIntlWrapper);
1408     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(aPresentation.toUtf8().getStr()));
1409 
1410     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bAnchorOnly"), BAD_CAST(OString::boolean(m_bAnchorOnly).getStr()));
1411     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bContour"), BAD_CAST(OString::boolean(m_bContour).getStr()));
1412     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOutside"), BAD_CAST(OString::boolean(m_bOutside).getStr()));
1413 
1414     (void)xmlTextWriterEndElement(pWriter);
1415 }
1416 
getItemInstanceManager() const1417 ItemInstanceManager* SwFormatVertOrient::getItemInstanceManager() const
1418 {
1419     static HashedItemInstanceManager aInstanceManager(ItemType());
1420     return &aInstanceManager;
1421 }
1422 
hashCode() const1423 size_t SwFormatVertOrient::hashCode() const
1424 {
1425     std::size_t seed(0);
1426     o3tl::hash_combine(seed, Which());
1427     o3tl::hash_combine(seed, GetPos());
1428     o3tl::hash_combine(seed, GetVertOrient());
1429     o3tl::hash_combine(seed, GetRelationOrient());
1430     return seed;
1431 }
1432 // Partially implemented inline in hxx
SwFormatVertOrient(SwTwips nY,sal_Int16 eVert,sal_Int16 eRel)1433 SwFormatVertOrient::SwFormatVertOrient( SwTwips nY, sal_Int16 eVert,
1434                                   sal_Int16 eRel )
1435     : SfxPoolItem( RES_VERT_ORIENT ),
1436     m_nYPos( nY ),
1437     m_eOrient( eVert ),
1438     m_eRelation( eRel )
1439 {}
1440 
operator ==(const SfxPoolItem & rAttr) const1441 bool SwFormatVertOrient::operator==( const SfxPoolItem& rAttr ) const
1442 {
1443     assert(SfxPoolItem::operator==(rAttr));
1444     return ( m_nYPos     == static_cast<const SwFormatVertOrient&>(rAttr).m_nYPos &&
1445              m_eOrient   == static_cast<const SwFormatVertOrient&>(rAttr).m_eOrient &&
1446              m_eRelation == static_cast<const SwFormatVertOrient&>(rAttr).m_eRelation );
1447 }
1448 
Clone(SfxItemPool *) const1449 SwFormatVertOrient* SwFormatVertOrient::Clone( SfxItemPool* ) const
1450 {
1451     return new SwFormatVertOrient( *this );
1452 }
1453 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const1454 bool SwFormatVertOrient::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1455 {
1456     // here we convert always!
1457     nMemberId &= ~CONVERT_TWIPS;
1458     bool bRet = true;
1459     switch ( nMemberId )
1460     {
1461         case MID_VERTORIENT_ORIENT:
1462         {
1463             rVal <<= m_eOrient;
1464         }
1465         break;
1466         case MID_VERTORIENT_RELATION:
1467                 rVal <<= m_eRelation;
1468         break;
1469         case MID_VERTORIENT_POSITION:
1470                 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(GetPos()));
1471                 break;
1472         default:
1473             OSL_ENSURE( false, "unknown MemberId" );
1474             bRet = false;
1475     }
1476     return bRet;
1477 }
1478 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)1479 bool SwFormatVertOrient::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1480 {
1481     bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
1482     nMemberId &= ~CONVERT_TWIPS;
1483     bool bRet = true;
1484     switch ( nMemberId )
1485     {
1486         case MID_VERTORIENT_ORIENT:
1487         {
1488             sal_uInt16 nVal = text::VertOrientation::NONE;
1489             rVal >>= nVal;
1490             m_eOrient = nVal;
1491         }
1492         break;
1493         case MID_VERTORIENT_RELATION:
1494         {
1495             m_eRelation = lcl_IntToRelation(rVal);
1496         }
1497         break;
1498         case MID_VERTORIENT_POSITION:
1499         {
1500             sal_Int32 nVal = 0;
1501             rVal >>= nVal;
1502             if(bConvert)
1503                 nVal = o3tl::toTwips(nVal, o3tl::Length::mm100);
1504             SetPos( nVal );
1505         }
1506         break;
1507         default:
1508             OSL_ENSURE( false, "unknown MemberId" );
1509             bRet = false;
1510     }
1511     return bRet;
1512 }
1513 
dumpAsXml(xmlTextWriterPtr pWriter) const1514 void SwFormatVertOrient::dumpAsXml(xmlTextWriterPtr pWriter) const
1515 {
1516     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatVertOrient"));
1517     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1518     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nYPos"), BAD_CAST(OString::number(m_nYPos).getStr()));
1519     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eOrient"), BAD_CAST(OString::number(m_eOrient).getStr()));
1520     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eRelation"), BAD_CAST(OString::number(m_eRelation).getStr()));
1521     (void)xmlTextWriterEndElement(pWriter);
1522 }
1523 
getItemInstanceManager() const1524 ItemInstanceManager* SwFormatHoriOrient::getItemInstanceManager() const
1525 {
1526     static HashedItemInstanceManager aInstanceManager(ItemType());
1527     return &aInstanceManager;
1528 }
1529 
hashCode() const1530 size_t SwFormatHoriOrient::hashCode() const
1531 {
1532     std::size_t seed(0);
1533     o3tl::hash_combine(seed, Which());
1534     o3tl::hash_combine(seed, GetPos());
1535     o3tl::hash_combine(seed, GetHoriOrient());
1536     o3tl::hash_combine(seed, GetRelationOrient());
1537     o3tl::hash_combine(seed, IsPosToggle());
1538     return seed;
1539 }
1540 // Partially implemented inline in hxx
SwFormatHoriOrient(SwTwips nX,sal_Int16 eHori,sal_Int16 eRel,bool bPos)1541 SwFormatHoriOrient::SwFormatHoriOrient( SwTwips nX, sal_Int16 eHori,
1542                               sal_Int16 eRel, bool bPos )
1543     : SfxPoolItem( RES_HORI_ORIENT ),
1544     m_nXPos( nX ),
1545     m_eOrient( eHori ),
1546     m_eRelation( eRel ),
1547     m_bPosToggle( bPos )
1548 {}
1549 
operator ==(const SfxPoolItem & rAttr) const1550 bool SwFormatHoriOrient::operator==( const SfxPoolItem& rAttr ) const
1551 {
1552     assert(SfxPoolItem::operator==(rAttr));
1553     return ( m_nXPos == static_cast<const SwFormatHoriOrient&>(rAttr).m_nXPos &&
1554              m_eOrient == static_cast<const SwFormatHoriOrient&>(rAttr).m_eOrient &&
1555              m_eRelation == static_cast<const SwFormatHoriOrient&>(rAttr).m_eRelation &&
1556              m_bPosToggle == static_cast<const SwFormatHoriOrient&>(rAttr).m_bPosToggle );
1557 }
1558 
Clone(SfxItemPool *) const1559 SwFormatHoriOrient* SwFormatHoriOrient::Clone( SfxItemPool* ) const
1560 {
1561     return new SwFormatHoriOrient( *this );
1562 }
1563 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const1564 bool SwFormatHoriOrient::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1565 {
1566     // here we convert always!
1567     nMemberId &= ~CONVERT_TWIPS;
1568     bool bRet = true;
1569     switch ( nMemberId )
1570     {
1571         case MID_HORIORIENT_ORIENT:
1572         {
1573             rVal <<= m_eOrient;
1574         }
1575         break;
1576         case MID_HORIORIENT_RELATION:
1577             rVal <<= m_eRelation;
1578         break;
1579         case MID_HORIORIENT_POSITION:
1580                 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(GetPos()));
1581                 break;
1582         case MID_HORIORIENT_PAGETOGGLE:
1583             rVal <<= IsPosToggle();
1584             break;
1585         default:
1586             OSL_ENSURE( false, "unknown MemberId" );
1587             bRet = false;
1588     }
1589     return bRet;
1590 }
1591 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)1592 bool SwFormatHoriOrient::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1593 {
1594     bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
1595     nMemberId &= ~CONVERT_TWIPS;
1596     bool bRet = true;
1597     switch ( nMemberId )
1598     {
1599         case MID_HORIORIENT_ORIENT:
1600         {
1601             sal_Int16 nVal = text::HoriOrientation::NONE;
1602             rVal >>= nVal;
1603             m_eOrient = nVal;
1604         }
1605         break;
1606         case MID_HORIORIENT_RELATION:
1607         {
1608             m_eRelation = lcl_IntToRelation(rVal);
1609         }
1610         break;
1611         case MID_HORIORIENT_POSITION:
1612         {
1613             sal_Int32 nVal = 0;
1614             if(!(rVal >>= nVal))
1615                 bRet = false;
1616             if(bConvert)
1617                 nVal = o3tl::toTwips(nVal, o3tl::Length::mm100);
1618             SetPos( nVal );
1619         }
1620         break;
1621         case MID_HORIORIENT_PAGETOGGLE:
1622                 SetPosToggle( *o3tl::doAccess<bool>(rVal));
1623             break;
1624         default:
1625             OSL_ENSURE( false, "unknown MemberId" );
1626             bRet = false;
1627     }
1628     return bRet;
1629 }
1630 
dumpAsXml(xmlTextWriterPtr pWriter) const1631 void SwFormatHoriOrient::dumpAsXml(xmlTextWriterPtr pWriter) const
1632 {
1633     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatHoriOrient"));
1634     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1635     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nXPos"), BAD_CAST(OString::number(m_nXPos).getStr()));
1636     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eOrient"), BAD_CAST(OString::number(m_eOrient).getStr()));
1637     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eRelation"), BAD_CAST(OString::number(m_eRelation).getStr()));
1638     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bPosToggle"), BAD_CAST(OString::boolean(m_bPosToggle).getStr()));
1639     (void)xmlTextWriterEndElement(pWriter);
1640 }
1641 
SwFormatAnchor(RndStdIds nRnd,sal_uInt16 nPage)1642 SwFormatAnchor::SwFormatAnchor( RndStdIds nRnd, sal_uInt16 nPage )
1643     : SfxPoolItem( RES_ANCHOR ),
1644     m_eAnchorId( nRnd ),
1645     m_nPageNumber( nPage ),
1646     // OD 2004-05-05 #i28701# - get always new increased order number
1647     m_nOrder( ++s_nOrderCounter )
1648 {
1649     setNonShareable();
1650     assert( m_eAnchorId == RndStdIds::FLY_AT_PARA
1651         || m_eAnchorId == RndStdIds::FLY_AS_CHAR
1652         || m_eAnchorId == RndStdIds::FLY_AT_PAGE
1653         || m_eAnchorId == RndStdIds::FLY_AT_FLY
1654         || m_eAnchorId == RndStdIds::FLY_AT_CHAR);
1655     // only FLY_AT_PAGE should have a valid page
1656     assert( m_eAnchorId == RndStdIds::FLY_AT_PAGE || nPage == 0 );
1657 }
1658 
SwFormatAnchor(const SwFormatAnchor & rCpy)1659 SwFormatAnchor::SwFormatAnchor( const SwFormatAnchor &rCpy )
1660     : SfxPoolItem( RES_ANCHOR )
1661     , m_oContentAnchor( rCpy.m_oContentAnchor )
1662     , m_eAnchorId( rCpy.m_eAnchorId )
1663     , m_nPageNumber( rCpy.m_nPageNumber )
1664     // OD 2004-05-05 #i28701# - get always new increased order number
1665     , m_nOrder( ++s_nOrderCounter )
1666 {
1667     setNonShareable();
1668 }
1669 
~SwFormatAnchor()1670 SwFormatAnchor::~SwFormatAnchor()
1671 {
1672 }
1673 
SetAnchor(const SwPosition * pPos)1674 void SwFormatAnchor::SetAnchor( const SwPosition *pPos )
1675 {
1676     if (!pPos)
1677     {
1678         m_oContentAnchor.reset();
1679         return;
1680     }
1681     // anchor only to paragraphs, or start nodes in case of RndStdIds::FLY_AT_FLY
1682     // also allow table node, this is used when a table is selected and is converted to a frame by the UI
1683     assert((RndStdIds::FLY_AT_FLY == m_eAnchorId && pPos->GetNode().GetStartNode())
1684             || (RndStdIds::FLY_AT_PARA == m_eAnchorId && pPos->GetNode().GetTableNode())
1685             || pPos->GetNode().GetTextNode());
1686     // verify that the SwPosition being passed to us is not screwy
1687     assert(!pPos->nContent.GetContentNode()
1688             || &pPos->nNode.GetNode() == pPos->nContent.GetContentNode());
1689     m_oContentAnchor.emplace(*pPos);
1690     // Flys anchored AT paragraph should not point into the paragraph content
1691     if ((RndStdIds::FLY_AT_PARA == m_eAnchorId) || (RndStdIds::FLY_AT_FLY == m_eAnchorId))
1692         m_oContentAnchor->nContent.Assign( nullptr, 0 );
1693 }
1694 
GetAnchorNode() const1695 SwNode* SwFormatAnchor::GetAnchorNode() const
1696 {
1697     if (!m_oContentAnchor)
1698         return nullptr;
1699     if (auto pCntNd = m_oContentAnchor->nContent.GetContentNode())
1700         return const_cast<SwContentNode*>(pCntNd);
1701     return &m_oContentAnchor->nNode.GetNode();
1702 }
1703 
GetAnchorContentNode() const1704 SwContentNode* SwFormatAnchor::GetAnchorContentNode() const
1705 {
1706     SwNode* pAnchorNode = GetAnchorNode();
1707     if (pAnchorNode)
1708         return pAnchorNode->GetContentNode();
1709     return nullptr;
1710 }
1711 
GetAnchorContentOffset() const1712 sal_Int32 SwFormatAnchor::GetAnchorContentOffset() const
1713 {
1714     if (!m_oContentAnchor)
1715         return 0;
1716     if (m_oContentAnchor->nContent.GetContentNode())
1717         return m_oContentAnchor->nContent.GetIndex();
1718     return 0;
1719 }
1720 
operator =(const SwFormatAnchor & rAnchor)1721 SwFormatAnchor& SwFormatAnchor::operator=(const SwFormatAnchor& rAnchor)
1722 {
1723     if (!SfxPoolItem::areSame(*this, rAnchor))
1724     {
1725         m_eAnchorId  = rAnchor.m_eAnchorId;
1726         m_nPageNumber   = rAnchor.m_nPageNumber;
1727         // OD 2004-05-05 #i28701# - get always new increased order number
1728         m_nOrder = ++s_nOrderCounter;
1729         m_oContentAnchor  = rAnchor.m_oContentAnchor;
1730     }
1731     return *this;
1732 }
1733 
operator ==(const SfxPoolItem & rAttr) const1734 bool SwFormatAnchor::operator==( const SfxPoolItem& rAttr ) const
1735 {
1736     assert(SfxPoolItem::operator==(rAttr));
1737     SwFormatAnchor const& rFormatAnchor(static_cast<SwFormatAnchor const&>(rAttr));
1738     // OD 2004-05-05 #i28701# - Note: <mnOrder> hasn't to be considered.
1739     return ( m_eAnchorId == rFormatAnchor.m_eAnchorId &&
1740              m_nPageNumber == rFormatAnchor.m_nPageNumber   &&
1741                 // compare anchor: either both do not point into a textnode or
1742                 // both do (valid m_oContentAnchor) and the positions are equal
1743              (m_oContentAnchor == rFormatAnchor.m_oContentAnchor) );
1744 }
1745 
Clone(SfxItemPool *) const1746 SwFormatAnchor* SwFormatAnchor::Clone( SfxItemPool* ) const
1747 {
1748     return new SwFormatAnchor( *this );
1749 }
1750 
1751 // OD 2004-05-05 #i28701#
1752 sal_uInt32 SwFormatAnchor::s_nOrderCounter = 0;
1753 
1754 // OD 2004-05-05 #i28701#
1755 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const1756 bool SwFormatAnchor::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1757 {
1758     // here we convert always!
1759     nMemberId &= ~CONVERT_TWIPS;
1760     bool bRet = true;
1761     switch ( nMemberId )
1762     {
1763         case MID_ANCHOR_ANCHORTYPE:
1764 
1765             text::TextContentAnchorType eRet;
1766             switch (m_eAnchorId)
1767             {
1768                 case  RndStdIds::FLY_AT_CHAR:
1769                     eRet = text::TextContentAnchorType_AT_CHARACTER;
1770                     break;
1771                 case  RndStdIds::FLY_AT_PAGE:
1772                     eRet = text::TextContentAnchorType_AT_PAGE;
1773                     break;
1774                 case  RndStdIds::FLY_AT_FLY:
1775                     eRet = text::TextContentAnchorType_AT_FRAME;
1776                     break;
1777                 case  RndStdIds::FLY_AS_CHAR:
1778                     eRet = text::TextContentAnchorType_AS_CHARACTER;
1779                     break;
1780                 //case  RndStdIds::FLY_AT_PARA:
1781                 default:
1782                     eRet = text::TextContentAnchorType_AT_PARAGRAPH;
1783             }
1784             rVal <<= eRet;
1785         break;
1786         case MID_ANCHOR_PAGENUM:
1787             rVal <<= static_cast<sal_Int16>(GetPageNum());
1788         break;
1789         case MID_ANCHOR_ANCHORFRAME:
1790         {
1791             if (m_oContentAnchor && RndStdIds::FLY_AT_FLY == m_eAnchorId)
1792             {
1793                 SwFrameFormat* pFormat = m_oContentAnchor->GetNode().GetFlyFormat();
1794                 if(pFormat)
1795                 {
1796                     rtl::Reference<SwXTextFrame> const xRet(
1797                         SwXTextFrame::CreateXTextFrame(pFormat->GetDoc(), pFormat));
1798                     rVal <<= uno::Reference<text::XTextFrame>(xRet);
1799                 }
1800             }
1801         }
1802         break;
1803         default:
1804             OSL_ENSURE( false, "unknown MemberId" );
1805             bRet = false;
1806     }
1807     return bRet;
1808 }
1809 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)1810 bool SwFormatAnchor::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1811 {
1812     // here we convert always!
1813     nMemberId &= ~CONVERT_TWIPS;
1814     bool bRet = true;
1815     switch ( nMemberId )
1816     {
1817         case MID_ANCHOR_ANCHORTYPE:
1818         {
1819             RndStdIds   eAnchor;
1820             switch( static_cast<text::TextContentAnchorType>(SWUnoHelper::GetEnumAsInt32( rVal )) )
1821             {
1822                 case  text::TextContentAnchorType_AS_CHARACTER:
1823                     eAnchor = RndStdIds::FLY_AS_CHAR;
1824                     break;
1825                 case  text::TextContentAnchorType_AT_PAGE:
1826                     eAnchor = RndStdIds::FLY_AT_PAGE;
1827                     if( GetPageNum() > 0 )
1828                     {
1829                         // If the anchor type is page and a valid page number
1830                         // has been set, the content position isn't required
1831                         // any longer.
1832                         m_oContentAnchor.reset();
1833                     }
1834                     break;
1835                 case  text::TextContentAnchorType_AT_FRAME:
1836                     eAnchor = RndStdIds::FLY_AT_FLY;
1837                     break;
1838                 case  text::TextContentAnchorType_AT_CHARACTER:
1839                     eAnchor = RndStdIds::FLY_AT_CHAR;
1840                     break;
1841                 case text::TextContentAnchorType_AT_PARAGRAPH:
1842                     eAnchor = RndStdIds::FLY_AT_PARA;
1843                     break;
1844                 default:
1845                     eAnchor = RndStdIds::FLY_AT_PARA; // just to keep some compilers happy
1846                     assert(false);
1847             }
1848             SetType( eAnchor );
1849         }
1850         break;
1851         case MID_ANCHOR_PAGENUM:
1852         {
1853             sal_Int16 nVal = 0;
1854             if((rVal >>= nVal) && nVal > 0)
1855             {
1856                 if (RndStdIds::FLY_AT_PAGE == m_eAnchorId)
1857                 {
1858                     SetPageNum( nVal );
1859                     // If the anchor type is page and a valid page number
1860                     // is set, the content position has to be deleted to not
1861                     // confuse the layout (frmtool.cxx). However, if the
1862                     // anchor type is not page, any content position will
1863                     // be kept.
1864                     m_oContentAnchor.reset();
1865                 }
1866                 else
1867                 {
1868                     assert(false && "cannot set page number on this anchor type");
1869                     bRet = false;
1870                 }
1871             }
1872             else
1873                 bRet = false;
1874         }
1875         break;
1876         case MID_ANCHOR_ANCHORFRAME:
1877         //no break here!;
1878         default:
1879             OSL_ENSURE( false, "unknown MemberId" );
1880             bRet = false;
1881     }
1882     return bRet;
1883 }
1884 
dumpAsXml(xmlTextWriterPtr pWriter) const1885 void SwFormatAnchor::dumpAsXml(xmlTextWriterPtr pWriter) const
1886 {
1887     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatAnchor"));
1888     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1889 
1890     if (m_oContentAnchor)
1891     {
1892         std::stringstream aContentAnchor;
1893         aContentAnchor << *m_oContentAnchor;
1894         (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_pContentAnchor"), BAD_CAST(aContentAnchor.str().c_str()));
1895     }
1896     else
1897         (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_pContentAnchor"), BAD_CAST("(nil)"));
1898     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_eAnchorType"), BAD_CAST(OString::number(static_cast<int>(m_eAnchorId)).getStr()));
1899     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPageNumber"), BAD_CAST(OString::number(m_nPageNumber).getStr()));
1900     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nOrder"), BAD_CAST(OString::number(m_nOrder).getStr()));
1901     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("s_nOrderCounter"), BAD_CAST(OString::number(s_nOrderCounter).getStr()));
1902     OUString aPresentation;
1903     IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
1904     GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, MapUnit::Map100thMM, aPresentation, aIntlWrapper);
1905     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(aPresentation.toUtf8().getStr()));
1906 
1907     (void)xmlTextWriterEndElement(pWriter);
1908 }
1909 
1910 // Partially implemented inline in hxx
SwFormatURL()1911 SwFormatURL::SwFormatURL() :
1912     SfxPoolItem( RES_URL ),
1913     m_bIsServerMap( false )
1914 {
1915 }
1916 
SwFormatURL(const SwFormatURL & rURL)1917 SwFormatURL::SwFormatURL( const SwFormatURL &rURL) :
1918     SfxPoolItem( RES_URL ),
1919     m_sTargetFrameName( rURL.GetTargetFrameName() ),
1920     m_sURL( rURL.GetURL() ),
1921     m_sName( rURL.GetName() ),
1922     m_bIsServerMap( rURL.IsServerMap() )
1923 {
1924     if (rURL.GetMap())
1925         m_pMap.reset( new ImageMap( *rURL.GetMap() ) );
1926 }
1927 
~SwFormatURL()1928 SwFormatURL::~SwFormatURL()
1929 {
1930 }
1931 
operator ==(const SfxPoolItem & rAttr) const1932 bool SwFormatURL::operator==( const SfxPoolItem &rAttr ) const
1933 {
1934     assert(SfxPoolItem::operator==(rAttr));
1935     const SwFormatURL &rCmp = static_cast<const SwFormatURL&>(rAttr);
1936     bool bRet = m_bIsServerMap     == rCmp.IsServerMap() &&
1937                 m_sURL             == rCmp.GetURL() &&
1938                 m_sTargetFrameName == rCmp.GetTargetFrameName() &&
1939                 m_sName            == rCmp.GetName();
1940     if ( bRet )
1941     {
1942         if ( m_pMap && rCmp.GetMap() )
1943             bRet = *m_pMap == *rCmp.GetMap();
1944         else
1945             bRet = m_pMap.get() == rCmp.GetMap();
1946     }
1947     return bRet;
1948 }
1949 
Clone(SfxItemPool *) const1950 SwFormatURL* SwFormatURL::Clone( SfxItemPool* ) const
1951 {
1952     return new SwFormatURL( *this );
1953 }
1954 
SetURL(const OUString & rURL,bool bServerMap)1955 void SwFormatURL::SetURL(const OUString &rURL, bool bServerMap)
1956 {
1957     m_sURL = rURL;
1958     m_bIsServerMap = bServerMap;
1959 }
1960 
SetMap(const ImageMap * pM)1961 void SwFormatURL::SetMap( const ImageMap *pM )
1962 {
1963     m_pMap.reset( pM ? new ImageMap( *pM ) : nullptr);
1964 }
1965 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const1966 bool SwFormatURL::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1967 {
1968     // here we convert always!
1969     nMemberId &= ~CONVERT_TWIPS;
1970     bool bRet = true;
1971     switch ( nMemberId )
1972     {
1973         case MID_URL_URL:
1974             rVal <<= GetURL();
1975         break;
1976         case MID_URL_TARGET:
1977             rVal <<= GetTargetFrameName();
1978         break;
1979         case MID_URL_HYPERLINKNAME:
1980             rVal <<= GetName();
1981             break;
1982         case MID_URL_CLIENTMAP:
1983         {
1984             uno::Reference< uno::XInterface > xInt;
1985             if(m_pMap)
1986             {
1987                 xInt = SvUnoImageMap_createInstance( *m_pMap, sw_GetSupportedMacroItems() );
1988             }
1989             else
1990             {
1991                 ImageMap aEmptyMap;
1992                 xInt = SvUnoImageMap_createInstance( aEmptyMap, sw_GetSupportedMacroItems() );
1993             }
1994             uno::Reference< container::XIndexContainer > xCont(xInt, uno::UNO_QUERY);
1995             rVal <<= xCont;
1996         }
1997         break;
1998         case MID_URL_SERVERMAP:
1999             rVal <<= IsServerMap();
2000             break;
2001         default:
2002             OSL_ENSURE( false, "unknown MemberId" );
2003             bRet = false;
2004     }
2005     return bRet;
2006 }
2007 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)2008 bool SwFormatURL::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2009 {
2010     // here we convert always!
2011     nMemberId &= ~CONVERT_TWIPS;
2012     bool bRet = true;
2013     switch ( nMemberId )
2014     {
2015         case MID_URL_URL:
2016         {
2017             OUString sTmp;
2018             rVal >>= sTmp;
2019             SetURL( sTmp, m_bIsServerMap );
2020         }
2021         break;
2022         case MID_URL_TARGET:
2023         {
2024             OUString sTmp;
2025             rVal >>= sTmp;
2026             SetTargetFrameName( sTmp );
2027         }
2028         break;
2029         case MID_URL_HYPERLINKNAME:
2030         {
2031             OUString sTmp;
2032             rVal >>= sTmp;
2033             SetName( sTmp );
2034         }
2035         break;
2036         case MID_URL_CLIENTMAP:
2037         {
2038             uno::Reference<container::XIndexContainer> xCont;
2039             if(!rVal.hasValue())
2040                 m_pMap.reset();
2041             else if(rVal >>= xCont)
2042             {
2043                 if(!m_pMap)
2044                     m_pMap.reset(new ImageMap);
2045                 bRet = SvUnoImageMap_fillImageMap( xCont, *m_pMap );
2046             }
2047             else
2048                 bRet = false;
2049         }
2050         break;
2051         case MID_URL_SERVERMAP:
2052             m_bIsServerMap = *o3tl::doAccess<bool>(rVal);
2053             break;
2054         default:
2055             OSL_ENSURE( false, "unknown MemberId" );
2056             bRet = false;
2057     }
2058     return bRet;
2059 }
2060 
Clone(SfxItemPool *) const2061 SwFormatEditInReadonly* SwFormatEditInReadonly::Clone( SfxItemPool* ) const
2062 {
2063     return new SwFormatEditInReadonly( *this );
2064 }
2065 
dumpAsXml(xmlTextWriterPtr pWriter) const2066 void SwFormatEndAtTextEnd::dumpAsXml(xmlTextWriterPtr pWriter) const
2067 {
2068     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatEndAtTextEnd"));
2069     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
2070     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(GetValue()).getStr()));
2071     (void)xmlTextWriterEndElement(pWriter);
2072 }
2073 
Clone(SfxItemPool *) const2074 SwFormatLayoutSplit* SwFormatLayoutSplit::Clone( SfxItemPool* ) const
2075 {
2076     return new SwFormatLayoutSplit( *this );
2077 }
2078 
Clone(SfxItemPool *) const2079 SwFormatRowSplit* SwFormatRowSplit::Clone( SfxItemPool* ) const
2080 {
2081     return new SwFormatRowSplit( *this );
2082 }
2083 
Clone(SfxItemPool *) const2084 SwFormatNoBalancedColumns* SwFormatNoBalancedColumns::Clone( SfxItemPool* ) const
2085 {
2086     return new SwFormatNoBalancedColumns( *this );
2087 }
2088 
dumpAsXml(xmlTextWriterPtr pWriter) const2089 void SwFormatNoBalancedColumns::dumpAsXml(xmlTextWriterPtr pWriter) const
2090 {
2091     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatNoBalancedColumns"));
2092     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
2093     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(GetValue()).getStr()));
2094     (void)xmlTextWriterEndElement(pWriter);
2095 }
2096 
2097 // class SwFormatFootnoteEndAtTextEnd
2098 
operator =(const SwFormatFootnoteEndAtTextEnd & rAttr)2099 SwFormatFootnoteEndAtTextEnd& SwFormatFootnoteEndAtTextEnd::operator=(
2100                         const SwFormatFootnoteEndAtTextEnd& rAttr )
2101 {
2102     SfxEnumItem::SetValue( rAttr.GetValue() );
2103     m_aFormat = rAttr.m_aFormat;
2104     m_nOffset = rAttr.m_nOffset;
2105     m_sPrefix = rAttr.m_sPrefix;
2106     m_sSuffix = rAttr.m_sSuffix;
2107     return *this;
2108 }
2109 
operator ==(const SfxPoolItem & rItem) const2110 bool SwFormatFootnoteEndAtTextEnd::operator==( const SfxPoolItem& rItem ) const
2111 {
2112     const SwFormatFootnoteEndAtTextEnd& rAttr = static_cast<const SwFormatFootnoteEndAtTextEnd&>(rItem);
2113     return SfxEnumItem::operator==( rItem ) &&
2114             m_aFormat.GetNumberingType() == rAttr.m_aFormat.GetNumberingType() &&
2115             m_nOffset == rAttr.m_nOffset &&
2116             m_sPrefix == rAttr.m_sPrefix &&
2117             m_sSuffix == rAttr.m_sSuffix;
2118 }
2119 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const2120 bool SwFormatFootnoteEndAtTextEnd::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2121 {
2122     nMemberId &= ~CONVERT_TWIPS;
2123     switch(nMemberId)
2124     {
2125         case MID_COLLECT     :
2126             rVal <<= GetValue() >= FTNEND_ATTXTEND;
2127         break;
2128         case MID_RESTART_NUM :
2129             rVal <<= GetValue() >= FTNEND_ATTXTEND_OWNNUMSEQ;
2130         break;
2131         case MID_NUM_START_AT: rVal <<= static_cast<sal_Int16>(m_nOffset); break;
2132         case MID_OWN_NUM     :
2133             rVal <<= GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT;
2134         break;
2135         case MID_NUM_TYPE    : rVal <<= static_cast<sal_Int16>(m_aFormat.GetNumberingType()); break;
2136         case MID_PREFIX      : rVal <<= m_sPrefix; break;
2137         case MID_SUFFIX      : rVal <<= m_sSuffix; break;
2138         default: return false;
2139     }
2140     return true;
2141 }
2142 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)2143 bool SwFormatFootnoteEndAtTextEnd::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2144 {
2145     bool bRet = true;
2146     nMemberId &= ~CONVERT_TWIPS;
2147     switch(nMemberId)
2148     {
2149         case MID_COLLECT     :
2150         {
2151             bool bVal = *o3tl::doAccess<bool>(rVal);
2152             if(!bVal && GetValue() >= FTNEND_ATTXTEND)
2153                 SetValue(FTNEND_ATPGORDOCEND);
2154             else if(bVal && GetValue() < FTNEND_ATTXTEND)
2155                 SetValue(FTNEND_ATTXTEND);
2156         }
2157         break;
2158         case MID_RESTART_NUM :
2159         {
2160             bool bVal = *o3tl::doAccess<bool>(rVal);
2161             if(!bVal && GetValue() >= FTNEND_ATTXTEND_OWNNUMSEQ)
2162                 SetValue(FTNEND_ATTXTEND);
2163             else if(bVal && GetValue() < FTNEND_ATTXTEND_OWNNUMSEQ)
2164                 SetValue(FTNEND_ATTXTEND_OWNNUMSEQ);
2165         }
2166         break;
2167         case MID_NUM_START_AT:
2168         {
2169             sal_Int16 nVal = 0;
2170             rVal >>= nVal;
2171             if(nVal >= 0)
2172                 m_nOffset = nVal;
2173             else
2174                 bRet = false;
2175         }
2176         break;
2177         case MID_OWN_NUM     :
2178         {
2179             bool bVal = *o3tl::doAccess<bool>(rVal);
2180             if(!bVal && GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT)
2181                 SetValue(FTNEND_ATTXTEND_OWNNUMSEQ);
2182             else if(bVal && GetValue() < FTNEND_ATTXTEND_OWNNUMANDFMT)
2183                 SetValue(FTNEND_ATTXTEND_OWNNUMANDFMT);
2184         }
2185         break;
2186         case MID_NUM_TYPE    :
2187         {
2188             sal_Int16 nVal = 0;
2189             rVal >>= nVal;
2190             if(nVal >= 0 &&
2191                 (nVal <= SVX_NUM_ARABIC ||
2192                     SVX_NUM_CHARS_UPPER_LETTER_N == nVal ||
2193                         SVX_NUM_CHARS_LOWER_LETTER_N == nVal ))
2194                 m_aFormat.SetNumberingType(static_cast<SvxNumType>(nVal));
2195             else
2196                 bRet = false;
2197         }
2198         break;
2199         case MID_PREFIX      :
2200         {
2201             OUString sVal; rVal >>= sVal;
2202             m_sPrefix = sVal;
2203         }
2204         break;
2205         case MID_SUFFIX      :
2206         {
2207             OUString sVal; rVal >>= sVal;
2208             m_sSuffix = sVal;
2209         }
2210         break;
2211         default: bRet = false;
2212     }
2213     return bRet;
2214 }
2215 
2216 // class SwFormatFootnoteAtTextEnd
2217 
Clone(SfxItemPool *) const2218 SwFormatFootnoteAtTextEnd* SwFormatFootnoteAtTextEnd::Clone( SfxItemPool* ) const
2219 {
2220     return new SwFormatFootnoteAtTextEnd(*this);
2221 }
2222 
2223 // class SwFormatEndAtTextEnd
2224 
Clone(SfxItemPool *) const2225 SwFormatEndAtTextEnd* SwFormatEndAtTextEnd::Clone( SfxItemPool* ) const
2226 {
2227     return new SwFormatEndAtTextEnd(*this);
2228 }
2229 
2230 //class SwFormatChain
2231 
operator ==(const SfxPoolItem & rAttr) const2232 bool SwFormatChain::operator==( const SfxPoolItem &rAttr ) const
2233 {
2234     assert(SfxPoolItem::operator==(rAttr));
2235 
2236     return GetPrev() == static_cast<const SwFormatChain&>(rAttr).GetPrev() &&
2237            GetNext() == static_cast<const SwFormatChain&>(rAttr).GetNext();
2238 }
2239 
SwFormatChain(const SwFormatChain & rCpy)2240 SwFormatChain::SwFormatChain( const SwFormatChain &rCpy ) :
2241     SfxPoolItem( RES_CHAIN )
2242 {
2243     setNonShareable();
2244     SetPrev( rCpy.GetPrev() );
2245     SetNext( rCpy.GetNext() );
2246 }
2247 
Clone(SfxItemPool *) const2248 SwFormatChain* SwFormatChain::Clone( SfxItemPool* ) const
2249 {
2250     SwFormatChain *pRet = new SwFormatChain;
2251     pRet->SetPrev( GetPrev() );
2252     pRet->SetNext( GetNext() );
2253     return pRet;
2254 }
2255 
SetPrev(SwFlyFrameFormat * pFormat)2256 void SwFormatChain::SetPrev( SwFlyFrameFormat *pFormat )
2257 {
2258     if ( pFormat )
2259         pFormat->Add(m_aPrev);
2260     else
2261         m_aPrev.EndListeningAll();
2262 }
2263 
SetNext(SwFlyFrameFormat * pFormat)2264 void SwFormatChain::SetNext( SwFlyFrameFormat *pFormat )
2265 {
2266     if ( pFormat )
2267         pFormat->Add(m_aNext);
2268     else
2269         m_aNext.EndListeningAll();
2270 }
2271 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const2272 bool SwFormatChain::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2273 {
2274     // here we convert always!
2275     nMemberId &= ~CONVERT_TWIPS;
2276     bool   bRet = true;
2277     OUString aRet;
2278     switch ( nMemberId )
2279     {
2280         case MID_CHAIN_PREVNAME:
2281             if ( GetPrev() )
2282                 aRet = GetPrev()->GetName().toString();
2283             break;
2284         case MID_CHAIN_NEXTNAME:
2285             if ( GetNext() )
2286                 aRet = GetNext()->GetName().toString();
2287             break;
2288         default:
2289             OSL_ENSURE( false, "unknown MemberId" );
2290             bRet = false;
2291     }
2292     rVal <<= aRet;
2293     return bRet;
2294 }
2295 
SwFormatLineNumber()2296 SwFormatLineNumber::SwFormatLineNumber() :
2297     SfxPoolItem( RES_LINENUMBER )
2298 {
2299     m_nStartValue = 0;
2300     m_bCountLines = true;
2301 }
2302 
~SwFormatLineNumber()2303 SwFormatLineNumber::~SwFormatLineNumber()
2304 {
2305 }
2306 
operator ==(const SfxPoolItem & rAttr) const2307 bool SwFormatLineNumber::operator==( const SfxPoolItem &rAttr ) const
2308 {
2309     assert(SfxPoolItem::operator==(rAttr));
2310 
2311     return m_nStartValue  == static_cast<const SwFormatLineNumber&>(rAttr).GetStartValue() &&
2312            m_bCountLines  == static_cast<const SwFormatLineNumber&>(rAttr).IsCount();
2313 }
2314 
Clone(SfxItemPool *) const2315 SwFormatLineNumber* SwFormatLineNumber::Clone( SfxItemPool* ) const
2316 {
2317     return new SwFormatLineNumber( *this );
2318 }
2319 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const2320 bool SwFormatLineNumber::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2321 {
2322     // here we convert always!
2323     nMemberId &= ~CONVERT_TWIPS;
2324     bool bRet = true;
2325     switch ( nMemberId )
2326     {
2327         case MID_LINENUMBER_COUNT:
2328             rVal <<= IsCount();
2329             break;
2330         case MID_LINENUMBER_STARTVALUE:
2331             rVal <<= static_cast<sal_Int32>(GetStartValue());
2332             break;
2333         default:
2334             OSL_ENSURE( false, "unknown MemberId" );
2335             bRet = false;
2336     }
2337     return bRet;
2338 }
2339 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)2340 bool SwFormatLineNumber::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2341 {
2342     // here we convert always!
2343     nMemberId &= ~CONVERT_TWIPS;
2344     bool bRet = true;
2345     switch ( nMemberId )
2346     {
2347         case MID_LINENUMBER_COUNT:
2348             SetCountLines( *o3tl::doAccess<bool>(rVal) );
2349             break;
2350         case MID_LINENUMBER_STARTVALUE:
2351         {
2352             sal_Int32 nVal = 0;
2353             if(rVal >>= nVal)
2354                 SetStartValue( nVal );
2355             else
2356                 bRet = false;
2357         }
2358         break;
2359         default:
2360             OSL_ENSURE( false, "unknown MemberId" );
2361             bRet = false;
2362     }
2363     return bRet;
2364 }
2365 
SwTextGridItem()2366 SwTextGridItem::SwTextGridItem()
2367     : SfxPoolItem( RES_TEXTGRID )
2368     , m_aColor( COL_LIGHTGRAY ), m_nLines( 20 )
2369     , m_nBaseHeight( 400 ), m_nRubyHeight( 200 ), m_eGridType( SwTextGrid::NONE )
2370     , m_bRubyTextBelow( false ), m_bPrintGrid( true ), m_bDisplayGrid( true )
2371     , m_nBaseWidth(400), m_bSnapToChars( true ), m_bSquaredMode(true)
2372 {
2373 }
2374 
~SwTextGridItem()2375 SwTextGridItem::~SwTextGridItem()
2376 {
2377 }
2378 
operator ==(const SfxPoolItem & rAttr) const2379 bool SwTextGridItem::operator==( const SfxPoolItem& rAttr ) const
2380 {
2381     assert(SfxPoolItem::operator==(rAttr));
2382     SwTextGridItem const& rOther(static_cast<SwTextGridItem const&>(rAttr));
2383     return m_eGridType == rOther.GetGridType()
2384         && m_nLines == rOther.GetLines()
2385         && m_nBaseHeight == rOther.GetBaseHeight()
2386         && m_nRubyHeight == rOther.GetRubyHeight()
2387         && m_bRubyTextBelow == rOther.GetRubyTextBelow()
2388         && m_bDisplayGrid == rOther.GetDisplayGrid()
2389         && m_bPrintGrid == rOther.GetPrintGrid()
2390         && m_aColor == rOther.GetColor()
2391         && m_nBaseWidth == rOther.GetBaseWidth()
2392         && m_bSnapToChars == rOther.GetSnapToChars()
2393         && m_bSquaredMode == rOther.GetSquaredMode();
2394 }
2395 
Clone(SfxItemPool *) const2396 SwTextGridItem* SwTextGridItem::Clone( SfxItemPool* ) const
2397 {
2398     return new SwTextGridItem( *this );
2399 }
2400 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const2401 bool SwTextGridItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2402 {
2403     bool bRet = true;
2404 
2405     switch( nMemberId & ~CONVERT_TWIPS )
2406     {
2407         case MID_GRID_COLOR:
2408             rVal <<= GetColor();
2409             break;
2410         case MID_GRID_LINES:
2411             rVal <<= GetLines();
2412             break;
2413         case MID_GRID_RUBY_BELOW:
2414             rVal <<= m_bRubyTextBelow;
2415             break;
2416         case MID_GRID_PRINT:
2417             rVal <<= m_bPrintGrid;
2418             break;
2419         case MID_GRID_DISPLAY:
2420             rVal <<= m_bDisplayGrid;
2421             break;
2422         case MID_GRID_BASEHEIGHT:
2423             OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
2424                         "This value needs TWIPS-MM100 conversion" );
2425             rVal <<= static_cast<sal_Int32>(convertTwipToMm100(m_nBaseHeight));
2426             break;
2427         case MID_GRID_BASEWIDTH:
2428             OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
2429                         "This value needs TWIPS-MM100 conversion" );
2430             rVal <<= static_cast<sal_Int32>(convertTwipToMm100(m_nBaseWidth));
2431             break;
2432         case MID_GRID_RUBYHEIGHT:
2433             OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
2434                         "This value needs TWIPS-MM100 conversion" );
2435             rVal <<= static_cast<sal_Int32>(convertTwipToMm100(m_nRubyHeight));
2436             break;
2437         case MID_GRID_TYPE:
2438             switch( GetGridType() )
2439             {
2440                 case SwTextGrid::NONE:
2441                     rVal <<= text::TextGridMode::NONE;
2442                     break;
2443                 case SwTextGrid::LinesOnly:
2444                     rVal <<= text::TextGridMode::LINES;
2445                     break;
2446                 case SwTextGrid::LinesAndChars:
2447                     rVal <<= text::TextGridMode::LINES_AND_CHARS;
2448                     break;
2449                 default:
2450                     OSL_FAIL("unknown SwTextGrid value");
2451                     bRet = false;
2452                     break;
2453             }
2454             break;
2455         case MID_GRID_SNAPTOCHARS:
2456             rVal <<= m_bSnapToChars;
2457             break;
2458         case MID_GRID_STANDARD_MODE:
2459             rVal <<= !m_bSquaredMode;
2460             break;
2461         default:
2462             OSL_FAIL("Unknown SwTextGridItem member");
2463             bRet = false;
2464             break;
2465     }
2466 
2467     return bRet;
2468 }
2469 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)2470 bool SwTextGridItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2471 {
2472     bool bRet = true;
2473     switch( nMemberId & ~CONVERT_TWIPS )
2474     {
2475         case MID_GRID_COLOR:
2476         {
2477             Color nTmp;
2478             bRet = (rVal >>= nTmp);
2479             if( bRet )
2480                 SetColor( nTmp );
2481         }
2482         break;
2483         case MID_GRID_LINES:
2484         {
2485             sal_Int16 nTmp = 0;
2486             bRet = (rVal >>= nTmp);
2487             if( bRet && (nTmp >= 0) )
2488                 SetLines( nTmp );
2489             else
2490                 bRet = false;
2491         }
2492         break;
2493         case MID_GRID_RUBY_BELOW:
2494             SetRubyTextBelow( *o3tl::doAccess<bool>(rVal) );
2495             break;
2496         case MID_GRID_PRINT:
2497             SetPrintGrid( *o3tl::doAccess<bool>(rVal) );
2498             break;
2499         case MID_GRID_DISPLAY:
2500             SetDisplayGrid( *o3tl::doAccess<bool>(rVal) );
2501             break;
2502         case MID_GRID_BASEHEIGHT:
2503         case MID_GRID_BASEWIDTH:
2504         case MID_GRID_RUBYHEIGHT:
2505         {
2506             OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
2507                         "This value needs TWIPS-MM100 conversion" );
2508             sal_Int32 nTmp = 0;
2509             bRet = (rVal >>= nTmp);
2510             nTmp = o3tl::toTwips(nTmp, o3tl::Length::mm100);
2511             if( bRet && (nTmp >= 0) && ( nTmp <= SAL_MAX_UINT16) )
2512             {
2513                 // rhbz#1043551 round up to 5pt -- 0 causes divide-by-zero
2514                 // in layout; 1pt ties the painting code up in knots for
2515                 // minutes with bazillion lines...
2516 #define MIN_TEXTGRID_SIZE 100
2517                 if( (nMemberId & ~CONVERT_TWIPS) == MID_GRID_BASEHEIGHT )
2518                 {
2519                     nTmp = std::max<sal_Int32>(nTmp, MIN_TEXTGRID_SIZE);
2520                     SetBaseHeight( o3tl::narrowing<sal_uInt16>(nTmp) );
2521                 }
2522                 else if( (nMemberId & ~CONVERT_TWIPS) == MID_GRID_BASEWIDTH )
2523                 {
2524                     nTmp = std::max<sal_Int32>(nTmp, MIN_TEXTGRID_SIZE);
2525                     SetBaseWidth( o3tl::narrowing<sal_uInt16>(nTmp) );
2526                 }
2527                 else
2528                     SetRubyHeight( o3tl::narrowing<sal_uInt16>(nTmp) );
2529             }
2530             else
2531                 bRet = false;
2532         }
2533         break;
2534         case MID_GRID_TYPE:
2535         {
2536             sal_Int16 nTmp = 0;
2537             bRet = (rVal >>= nTmp);
2538             if( bRet )
2539             {
2540                 switch( nTmp )
2541                 {
2542                     case text::TextGridMode::NONE:
2543                         SetGridType( SwTextGrid::NONE );
2544                         break;
2545                     case text::TextGridMode::LINES:
2546                         SetGridType( SwTextGrid::LinesOnly );
2547                         break;
2548                     case text::TextGridMode::LINES_AND_CHARS:
2549                         SetGridType( SwTextGrid::LinesAndChars );
2550                         break;
2551                     default:
2552                         bRet = false;
2553                         break;
2554                 }
2555             }
2556             break;
2557         }
2558         case MID_GRID_SNAPTOCHARS:
2559             SetSnapToChars( *o3tl::doAccess<bool>(rVal) );
2560             break;
2561         case MID_GRID_STANDARD_MODE:
2562         {
2563             bool bStandard = *o3tl::doAccess<bool>(rVal);
2564             SetSquaredMode( !bStandard );
2565             break;
2566         }
2567         default:
2568             OSL_FAIL("Unknown SwTextGridItem member");
2569             bRet = false;
2570     }
2571 
2572     return bRet;
2573 }
2574 
SwitchPaperMode(bool bNew)2575 void SwTextGridItem::SwitchPaperMode(bool bNew)
2576 {
2577     if (bNew == m_bSquaredMode)
2578     {
2579         //same paper mode, not switch
2580         return;
2581     }
2582 
2583     // use default value when grid is disable
2584     if (m_eGridType == SwTextGrid::NONE)
2585     {
2586         m_bSquaredMode = bNew;
2587         Init();
2588         return;
2589     }
2590 
2591     if (m_bSquaredMode)
2592     {
2593         //switch from "squared mode" to "standard mode"
2594         m_nBaseWidth = m_nBaseHeight;
2595         m_nBaseHeight = m_nBaseHeight + m_nRubyHeight;
2596         m_nRubyHeight = 0;
2597     }
2598     else
2599     {
2600         //switch from "standard mode" to "squared mode"
2601         m_nRubyHeight = m_nBaseHeight/3;
2602         m_nBaseHeight = m_nBaseHeight - m_nRubyHeight;
2603         m_nBaseWidth = m_nBaseHeight;
2604     }
2605     m_bSquaredMode = !m_bSquaredMode;
2606 }
2607 
Init()2608 void SwTextGridItem::Init()
2609 {
2610     if (m_bSquaredMode)
2611     {
2612         m_nLines = 20;
2613         m_nBaseHeight = 400;
2614         m_nRubyHeight = 200;
2615         m_eGridType = SwTextGrid::NONE;
2616         m_bRubyTextBelow = false;
2617         m_bPrintGrid = true;
2618         m_bDisplayGrid = true;
2619         m_bSnapToChars = true;
2620         m_nBaseWidth = 400;
2621     }
2622     else
2623     {
2624         m_nLines = 44;
2625         m_nBaseHeight = 312;
2626         m_nRubyHeight = 0;
2627         m_eGridType = SwTextGrid::NONE;
2628         m_bRubyTextBelow = false;
2629         m_bPrintGrid = true;
2630         m_bDisplayGrid = true;
2631         m_nBaseWidth = 210;
2632         m_bSnapToChars = true;
2633     }
2634 }
2635 
Clone(SfxItemPool *) const2636 SwHeaderAndFooterEatSpacingItem* SwHeaderAndFooterEatSpacingItem::Clone( SfxItemPool* ) const
2637 {
2638     return new SwHeaderAndFooterEatSpacingItem( Which(), GetValue() );
2639 }
2640 
SwFrameFormat(SwAttrPool & rPool,const UIName & rFormatNm,SwFrameFormat * pDrvdFrame,sal_uInt16 nFormatWhich,const WhichRangesContainer & pWhichRange)2641 SwFrameFormat::SwFrameFormat(
2642     SwAttrPool& rPool,
2643     const UIName &rFormatNm,
2644     SwFrameFormat *pDrvdFrame,
2645     sal_uInt16 nFormatWhich,
2646     const WhichRangesContainer& pWhichRange)
2647 :   SwFormat(rPool, rFormatNm, pWhichRange, pDrvdFrame, nFormatWhich),
2648     m_ffList(nullptr)
2649 {
2650 }
2651 
~SwFrameFormat()2652 SwFrameFormat::~SwFrameFormat()
2653 {
2654     if( !GetDoc().IsInDtor())
2655     {
2656         const SwFormatAnchor& rAnchor = GetAnchor();
2657         if (SwNode* pAnchorNode = rAnchor.GetAnchorNode())
2658         {
2659             pAnchorNode->RemoveAnchoredFly(this);
2660         }
2661     }
2662 
2663     // Check if there any textboxes attached to this format.
2664     if( nullptr == m_pOtherTextBoxFormats )
2665         return;
2666 
2667     // This is a fly-frame-format just delete this
2668     // textbox entry from the textbox collection.
2669     // Note: Do not delete it from the doc, as that
2670     // is already in progress.
2671     if (Which() == RES_FLYFRMFMT)
2672         m_pOtherTextBoxFormats->DelTextBox(this);
2673 
2674     // This is a draw-frame-format what belongs to
2675     // a shape with textbox(es). Delete all of them.
2676     if (Which() == RES_DRAWFRMFMT)
2677         m_pOtherTextBoxFormats->ClearAll();
2678 
2679     // Release the pointer.
2680     m_pOtherTextBoxFormats.reset();
2681 }
2682 
SetFormatName(const UIName & rNewName,bool bBroadcast)2683 void SwFrameFormat::SetFormatName( const UIName& rNewName, bool bBroadcast )
2684 {
2685     if (m_ffList != nullptr) {
2686         SAL_INFO_IF(m_aFormatName == rNewName, "sw.core", "SwFrmFmt not really renamed, as both names are equal");
2687         sw::NameChanged aHint(m_aFormatName, rNewName);
2688         m_ffList->Rename(*this, rNewName);
2689         if (bBroadcast) {
2690             GetNotifier().Broadcast(aHint);
2691         }
2692 
2693         // update accessibility sidebar object name if we modify the object name on the navigator bar
2694         const bool bUpdateA11yName = !aHint.m_sOld.isEmpty() && aHint.m_sOld != aHint.m_sNew;
2695         if (!bUpdateA11yName)
2696             return;
2697         SwFlyFrame* pSFly = SwIterator<SwFlyFrame, SwFormat>(*this).First();
2698         if (!pSFly)
2699             return;
2700         SwFrame *pSFlyLower = pSFly->Lower();
2701         if (!pSFlyLower)
2702             return;
2703         if (!pSFlyLower->IsNoTextFrame())
2704         {
2705             SwContentFrame* pContent = pSFly->ContainsContent();
2706             if (SwTextNode* pSwTxtNode = pContent ? static_cast<SwTextFrame*>(pContent)->GetTextNodeFirst() : nullptr)
2707                 pSwTxtNode->resetAndQueueAccessibilityCheck(true);
2708         }
2709         else
2710         {
2711             if (SwNode* pSwNode = static_cast<SwNoTextFrame*>(pSFlyLower)->GetNode())
2712                 pSwNode->resetAndQueueAccessibilityCheck(true);
2713         }
2714     }
2715     else
2716         SwFormat::SetFormatName( rNewName, bBroadcast );
2717 }
2718 
supportsFullDrawingLayerFillAttributeSet() const2719 bool SwFrameFormat::supportsFullDrawingLayerFillAttributeSet() const
2720 {
2721     return true;
2722 }
2723 
SwClientNotify(const SwModify & rMod,const SfxHint & rHint)2724 void SwFrameFormat::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
2725 {
2726     if(SfxHintId::SwRemoveUnoObject == rHint.GetId())
2727     {
2728         SetXObject(nullptr);
2729         SwFormat::SwClientNotify(rMod, rHint);
2730         return;
2731     }
2732     else if (rHint.GetId() == SfxHintId::SwFormatChange)
2733     {
2734         // reset fill information on format change (e.g. style changed)
2735         if(maFillAttributes && supportsFullDrawingLayerFillAttributeSet())
2736             maFillAttributes.reset();
2737         SwFormat::SwClientNotify(rMod, rHint);
2738         return;
2739     }
2740     else if (rHint.GetId() == SfxHintId::SwObjectDying
2741             || rHint.GetId() == SfxHintId::SwUpdateAttr)
2742     {
2743         SwFormat::SwClientNotify(rMod, rHint);
2744         return;
2745     }
2746     else if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != SfxHintId::SwAttrSetChange)
2747         return;
2748 
2749     const SwFormatHeader* pH = nullptr;
2750     const SwFormatFooter* pF = nullptr;
2751     SwNode* pNewAnchorNode = nullptr;
2752     SwNode* pOldAnchorNode = nullptr;
2753     if (rHint.GetId() == SfxHintId::SwLegacyModify)
2754     {
2755         auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
2756         const sal_uInt16 nNewWhich = pLegacy->m_pNew ? pLegacy->m_pNew->Which() : 0;
2757         switch(nNewWhich)
2758         {
2759             case RES_HEADER:
2760                 pH = static_cast<const SwFormatHeader*>(pLegacy->m_pNew);
2761                 break;
2762             case RES_FOOTER:
2763                 pF = static_cast<const SwFormatFooter*>(pLegacy->m_pNew);
2764                 break;
2765             case RES_ANCHOR:
2766                 pNewAnchorNode = static_cast<const SwFormatAnchor*>(pLegacy->m_pNew)->GetAnchorNode();
2767                 break;
2768         }
2769         const sal_uInt16 nOldWhich = pLegacy->m_pOld ? pLegacy->m_pOld->Which() : 0;
2770         switch(nOldWhich)
2771         {
2772             case RES_ANCHOR:
2773                 pOldAnchorNode = static_cast<const SwFormatAnchor*>(pLegacy->m_pOld)->GetAnchorNode();
2774                 break;
2775         }
2776         assert(nOldWhich == nNewWhich || !nOldWhich || !nNewWhich);
2777     }
2778     else // rHint.GetId() == SfxHintId::SwAttrSetChange
2779     {
2780         auto pChangeHint = static_cast<const sw::AttrSetChangeHint*>(&rHint);
2781         const SwAttrSetChg* pNewAttrSetChg = pChangeHint->m_pNew;
2782         pH = pNewAttrSetChg->GetChgSet()->GetItem(RES_HEADER, false);
2783         pF = pNewAttrSetChg->GetChgSet()->GetItem(RES_FOOTER, false);
2784 
2785         // reset fill information
2786         if(maFillAttributes && supportsFullDrawingLayerFillAttributeSet())
2787         {
2788             SfxItemIter aIter(*pNewAttrSetChg->GetChgSet());
2789             for(const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
2790             {
2791                 if(!IsInvalidItem(pItem) && pItem->Which() >= XATTR_FILL_FIRST && pItem->Which() <= XATTR_FILL_LAST)
2792                 {
2793                     maFillAttributes.reset();
2794                     break;
2795                 }
2796             }
2797         }
2798         if (const SwFormatAnchor* pAnchor = pNewAttrSetChg->GetChgSet()->GetItem(RES_ANCHOR, false))
2799         {
2800             pNewAnchorNode = pAnchor->GetAnchorNode();
2801             assert(pNewAnchorNode == nullptr || // style's set must not contain position!
2802                     pNewAttrSetChg->GetTheChgdSet() == &m_aSet);
2803         }
2804         const SwAttrSetChg* pOldAttrSetChg = pChangeHint->m_pOld;
2805         if (const SwFormatAnchor* pAnchor = pOldAttrSetChg->GetChgSet()->GetItem(RES_ANCHOR, false))
2806         {
2807             pOldAnchorNode = pAnchor->GetAnchorNode();
2808             assert(pOldAnchorNode == nullptr || // style's set must not contain position!
2809                     pOldAttrSetChg->GetTheChgdSet() == &m_aSet);
2810         }
2811     }
2812 
2813     if(pH && pH->IsActive() && !pH->GetHeaderFormat())
2814     {   //If he doesn't have one, I'll add one
2815         SwFrameFormat* pFormat = GetDoc().getIDocumentLayoutAccess().MakeLayoutFormat(RndStdIds::HEADER, nullptr);
2816         const_cast<SwFormatHeader*>(pH)->RegisterToFormat(*pFormat);
2817     }
2818     if(pF && pF->IsActive() && !pF->GetFooterFormat())
2819     {   //If he doesn't have one, I'll add one
2820         SwFrameFormat* pFormat = GetDoc().getIDocumentLayoutAccess().MakeLayoutFormat(RndStdIds::FOOTER, nullptr);
2821         const_cast<SwFormatFooter*>(pF)->RegisterToFormat(*pFormat);
2822     }
2823     SwFormat::SwClientNotify(rMod, rHint);
2824     if(pOldAnchorNode != nullptr && (pNewAnchorNode == nullptr || pOldAnchorNode->GetIndex() != pNewAnchorNode->GetIndex()))
2825         pOldAnchorNode->RemoveAnchoredFly(this);
2826     if(pNewAnchorNode != nullptr && (pOldAnchorNode == nullptr || pOldAnchorNode->GetIndex() != pNewAnchorNode->GetIndex()))
2827         pNewAnchorNode->AddAnchoredFly(this);
2828 }
2829 
RegisterToFormat(SwFormat & rFormat)2830 void SwFrameFormat::RegisterToFormat( SwFormat& rFormat )
2831 {
2832     rFormat.Add(*this);
2833 }
2834 
2835 /// Delete all Frames that are registered in aDepend.
DelFrames()2836 void SwFrameFormat::DelFrames()
2837 {
2838     SwIterator<SwFrame,SwFormat> aIter( *this );
2839     SwFrame * pLast = aIter.First();
2840     if( pLast )
2841         do {
2842                 pLast->Cut();
2843                 SwFrame::DestroyFrame(pLast);
2844         } while( nullptr != ( pLast = aIter.Next() ));
2845 }
2846 
MakeFrames()2847 void SwFrameFormat::MakeFrames()
2848 {
2849     assert(false); // unimplemented in base class
2850 }
2851 
FindLayoutRect(const bool bPrtArea,const Point * pPoint) const2852 SwRect SwFrameFormat::FindLayoutRect( const bool bPrtArea, const Point* pPoint ) const
2853 {
2854     SwRect aRet;
2855     SwFrame *pFrame = nullptr;
2856     if( auto pSectionFormat = dynamic_cast<const SwSectionFormat*>( this ))
2857     {
2858         // get the Frame using Node2Layout
2859         const SwSectionNode* pSectNd = pSectionFormat->GetSectionNode();
2860         if( pSectNd )
2861         {
2862             SwNode2Layout aTmp( *pSectNd, pSectNd->GetIndex() - 1 );
2863             pFrame = aTmp.NextFrame();
2864 
2865             if( pFrame && !pFrame->KnowsFormat(*this) )
2866             {
2867                 // the Section doesn't have his own Frame, so if someone
2868                 // needs the real size, we have to implement this by requesting
2869                 // the matching Frame from the end.
2870                 // PROBLEM: what happens if SectionFrames overlaps multiple
2871                 //          pages?
2872                 if( bPrtArea )
2873                     aRet = pFrame->getFramePrintArea();
2874                 else
2875                 {
2876                     aRet = pFrame->getFrameArea();
2877                     aRet.Pos().AdjustY( -1 );
2878                 }
2879                 pFrame = nullptr;       // the rect is finished by now
2880             }
2881         }
2882     }
2883     else
2884     {
2885         const SwFrameType nFrameType = RES_FLYFRMFMT == Which() ? SwFrameType::Fly : FRM_ALL;
2886         std::pair<Point, bool> tmp;
2887         if (pPoint)
2888         {
2889             tmp.first = *pPoint;
2890             tmp.second = false;
2891         }
2892         pFrame = ::GetFrameOfModify(nullptr, *this, nFrameType, nullptr, pPoint ? &tmp : nullptr);
2893     }
2894 
2895     if( pFrame )
2896     {
2897         if( bPrtArea )
2898             aRet = pFrame->getFramePrintArea();
2899         else
2900             aRet = pFrame->getFrameArea();
2901     }
2902     return aRet;
2903 }
2904 
FindRealSdrObject()2905 SdrObject* SwFrameFormat::FindRealSdrObject()
2906 {
2907     if( RES_FLYFRMFMT == Which() )
2908     {
2909         Point aNullPt;
2910         std::pair<Point, bool> const tmp(aNullPt, false);
2911         SwFlyFrame* pFly = static_cast<SwFlyFrame*>(::GetFrameOfModify( nullptr, *this, SwFrameType::Fly,
2912                                                     nullptr, &tmp));
2913         if( pFly )
2914             return pFly->GetVirtDrawObj();
2915 
2916         SwDoc& rDoc = GetDoc();
2917 
2918         SwDocShell* pShell = rDoc.GetDocShell();
2919         if (!pShell)
2920             return nullptr;
2921 
2922         if (pShell->GetCreateMode() != SfxObjectCreateMode::EMBEDDED )
2923             return nullptr;
2924 
2925         // tdf#126477 fix lost charts in embedded documents
2926     }
2927     return FindSdrObject();
2928 }
2929 
IsLowerOf(const SwFrameFormat & rFormat) const2930 bool SwFrameFormat::IsLowerOf( const SwFrameFormat& rFormat ) const
2931 {
2932     //Also linking from inside to outside or from outside to inside is not
2933     //allowed.
2934     SwFlyFrame *pSFly = SwIterator<SwFlyFrame,SwFormat>(*this).First();
2935     if( pSFly )
2936     {
2937         SwFlyFrame *pAskFly = SwIterator<SwFlyFrame,SwFormat>(rFormat).First();
2938         if( pAskFly )
2939             return pSFly->IsLowerOf( pAskFly );
2940     }
2941 
2942     // let's try it using the node positions
2943     const SwFormatAnchor* pAnchor = &rFormat.GetAnchor();
2944     if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) && pAnchor->GetAnchorNode())
2945     {
2946         const SwNode* pFlyNd = pAnchor->GetAnchorNode()->FindFlyStartNode();
2947         while( pFlyNd )
2948         {
2949             // then we walk up using the anchor
2950             for(const sw::SpzFrameFormat* pFormat: *GetDoc().GetSpzFrameFormats())
2951             {
2952                 const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
2953                 if( pIdx && pFlyNd == &pIdx->GetNode() )
2954                 {
2955                     if( pFormat == this )
2956                         return true;
2957 
2958                     pAnchor = &pFormat->GetAnchor();
2959                     if ((RndStdIds::FLY_AT_PAGE == pAnchor->GetAnchorId()) ||
2960                         !pAnchor->GetAnchorNode() )
2961                     {
2962                         return false;
2963                     }
2964 
2965                     pFlyNd = pAnchor->GetAnchorNode()->FindFlyStartNode();
2966                     break;
2967                 }
2968             }
2969         }
2970     }
2971     return false;
2972 }
2973 
2974 // #i31698#
GetLayoutDir() const2975 SwFrameFormat::tLayoutDir SwFrameFormat::GetLayoutDir() const
2976 {
2977     return SwFrameFormat::HORI_L2R;
2978 }
2979 
SetLayoutDir(const SwFrameFormat::tLayoutDir)2980 void SwFrameFormat::SetLayoutDir( const SwFrameFormat::tLayoutDir )
2981 {
2982     // empty body, because default implementation does nothing
2983 }
2984 
2985 // #i28749#
GetPositionLayoutDir() const2986 sal_Int16 SwFrameFormat::GetPositionLayoutDir() const
2987 {
2988     return text::PositionLayoutDir::PositionInLayoutDirOfAnchor;
2989 }
SetPositionLayoutDir(const sal_Int16)2990 void SwFrameFormat::SetPositionLayoutDir( const sal_Int16 )
2991 {
2992     // empty body, because default implementation does nothing
2993 }
2994 
GetDescription() const2995 OUString SwFrameFormat::GetDescription() const
2996 {
2997     return SwResId(STR_FRAME);
2998 }
2999 
dumpAsXml(xmlTextWriterPtr pWriter) const3000 void SwFrameFormat::dumpAsXml(xmlTextWriterPtr pWriter) const
3001 {
3002     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFrameFormat"));
3003     (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("whichId"), "%d", Which());
3004     const char* pWhich = nullptr;
3005     switch (Which())
3006     {
3007     case RES_FLYFRMFMT:
3008         pWhich = "fly frame format";
3009         break;
3010     case RES_DRAWFRMFMT:
3011         pWhich = "draw frame format";
3012         break;
3013     }
3014     if (pWhich)
3015         (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("which"), BAD_CAST(pWhich));
3016     if (m_pOtherTextBoxFormats)
3017     {
3018         (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("OtherTextBoxFormat"), "%p", m_pOtherTextBoxFormats.get());
3019     }
3020 
3021     SwFormat::dumpAsXml(pWriter);
3022 
3023     if (const SdrObject* pSdrObject = FindSdrObject())
3024         pSdrObject->dumpAsXml(pWriter);
3025     (void)xmlTextWriterEndElement(pWriter);
3026 }
3027 
SwFlyFrameFormat(SwAttrPool & rPool,const UIName & rFormatName,SwFrameFormat * pDerivedFrame)3028 SwFlyFrameFormat::SwFlyFrameFormat(SwAttrPool& rPool, const UIName &rFormatName, SwFrameFormat* pDerivedFrame)
3029     : sw::SpzFrameFormat(rPool, rFormatName, pDerivedFrame, RES_FLYFRMFMT)
3030 {}
3031 
~SwFlyFrameFormat()3032 SwFlyFrameFormat::~SwFlyFrameFormat()
3033 {
3034     SwIterator<SwFlyFrame,SwFormat> aIter( *this );
3035     SwFlyFrame * pLast = aIter.First();
3036     if( pLast )
3037         do
3038         {
3039             SwFrame::DestroyFrame(pLast);
3040         } while( nullptr != ( pLast = aIter.Next() ));
3041 
3042 }
3043 
GetOrCreateContact()3044 SwFlyDrawContact* SwFlyFrameFormat::GetOrCreateContact()
3045 {
3046     if(!m_pContact)
3047     {
3048         SwDrawModel& rDrawModel(GetDoc().getIDocumentDrawModelAccess().GetOrCreateDrawModel());
3049         m_pContact.reset(new SwFlyDrawContact(this, rDrawModel));
3050     }
3051 
3052     return m_pContact.get();
3053 }
3054 
3055 /// Creates the Frames if the format describes a paragraph-bound frame.
3056 /// MA: 1994-02-14: creates the Frames also for frames anchored at page.
MakeFrames()3057 void SwFlyFrameFormat::MakeFrames()
3058 {
3059     // is there a layout?
3060     if( !GetDoc().getIDocumentLayoutAccess().GetCurrentViewShell() )
3061         return;
3062 
3063     sw::BroadcastingModify *pModify = nullptr;
3064     // OD 24.07.2003 #111032# - create local copy of anchor attribute for possible changes.
3065     SwFormatAnchor aAnchorAttr( GetAnchor() );
3066     switch( aAnchorAttr.GetAnchorId() )
3067     {
3068     case RndStdIds::FLY_AS_CHAR:
3069     case RndStdIds::FLY_AT_PARA:
3070     case RndStdIds::FLY_AT_CHAR:
3071         if( aAnchorAttr.GetAnchorNode() )
3072         {
3073             pModify = aAnchorAttr.GetAnchorNode()->GetContentNode();
3074         }
3075         break;
3076 
3077     case RndStdIds::FLY_AT_FLY:
3078         if( aAnchorAttr.GetAnchorNode() )
3079         {
3080             //First search in the content because this is O(1)
3081             //This can go wrong for linked frames because in this case it's
3082             //possible, that no Frame exists for this content.
3083             //In such a situation we also need to search from StartNode to
3084             //FrameFormat.
3085             SwNodeIndex aIdx( *aAnchorAttr.GetAnchorNode() );
3086             SwContentNode* pCNd = SwNodes::GoNext(&aIdx);
3087             // #i105535#
3088             if ( pCNd == nullptr )
3089             {
3090                 pCNd = aAnchorAttr.GetAnchorNode()->GetContentNode();
3091             }
3092             if ( pCNd )
3093             {
3094                 if (SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti>(*pCNd).First())
3095                 {
3096                     pModify = pCNd;
3097                 }
3098             }
3099             // #i105535#
3100             if ( pModify == nullptr )
3101             {
3102                 const SwNode & rNd = *aAnchorAttr.GetAnchorNode();
3103                 for(sw::SpzFrameFormat* pFlyFormat: *GetDoc().GetSpzFrameFormats())
3104                 {
3105                     if( pFlyFormat->GetContent().GetContentIdx() &&
3106                         rNd == pFlyFormat->GetContent().GetContentIdx()->GetNode() )
3107                     {
3108                         pModify = pFlyFormat;
3109                         break;
3110                     }
3111                 }
3112             }
3113         }
3114         break;
3115 
3116     case RndStdIds::FLY_AT_PAGE:
3117         {
3118             sal_uInt16 nPgNum = aAnchorAttr.GetPageNum();
3119             SwPageFrame *pPage = static_cast<SwPageFrame*>(GetDoc().getIDocumentLayoutAccess().GetCurrentLayout()->Lower());
3120             if( nPgNum == 0 && aAnchorAttr.GetAnchorNode() )
3121             {
3122                 SwContentNode *pCNd = aAnchorAttr.GetAnchorNode()->GetContentNode();
3123                 SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aIter(*pCNd);
3124                 for ( SwFrame* pFrame = aIter.First(); pFrame != nullptr; pFrame = aIter.Next() )
3125                 {
3126                     pPage = pFrame->FindPageFrame();
3127                     if( pPage )
3128                     {
3129                         nPgNum = pPage->GetPhyPageNum();
3130                         aAnchorAttr.SetPageNum( nPgNum );
3131                         aAnchorAttr.SetAnchor( nullptr );
3132                         SetFormatAttr( aAnchorAttr );
3133                         break;
3134                     }
3135                 }
3136             }
3137             while ( pPage )
3138             {
3139                 if ( pPage->GetPhyPageNum() == nPgNum )
3140                 {
3141                     // #i50432# - adjust synopsis of <PlaceFly(..)>
3142                     pPage->PlaceFly( nullptr, this );
3143                     break;
3144                 }
3145                 pPage = static_cast<SwPageFrame*>(pPage->GetNext());
3146             }
3147         }
3148         break;
3149     default:
3150         break;
3151     }
3152 
3153     if( !pModify )
3154         return;
3155 
3156     SwIterator<SwFrame, sw::BroadcastingModify, sw::IteratorMode::UnwrapMulti> aIter(*pModify);
3157     for( SwFrame *pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
3158     {
3159         bool bAdd = !pFrame->IsContentFrame() ||
3160                         !static_cast<SwContentFrame*>(pFrame)->IsFollow();
3161 
3162         if ( RndStdIds::FLY_AT_FLY == aAnchorAttr.GetAnchorId() && !pFrame->IsFlyFrame() )
3163         {
3164             SwFrame* pFlyFrame = pFrame->FindFlyFrame();
3165             if ( pFlyFrame )
3166             {
3167                 pFrame = pFlyFrame;
3168             }
3169             else
3170             {
3171                 aAnchorAttr.SetType( RndStdIds::FLY_AT_PARA );
3172                 SetFormatAttr( aAnchorAttr );
3173                 MakeFrames();
3174                 return;
3175             }
3176         }
3177 
3178         if (bAdd)
3179         {
3180             switch (aAnchorAttr.GetAnchorId())
3181             {
3182                 case RndStdIds::FLY_AS_CHAR:
3183                 case RndStdIds::FLY_AT_PARA:
3184                 case RndStdIds::FLY_AT_CHAR:
3185                 {
3186                     assert(pFrame->IsTextFrame());
3187                     bAdd = IsAnchoredObjShown(*static_cast<SwTextFrame*>(pFrame), aAnchorAttr);
3188                 }
3189                 break;
3190                 default:
3191                 break;
3192             }
3193         }
3194 
3195         if (bAdd && pFrame->GetDrawObjs())
3196         {
3197             // #i28701# - new type <SwSortedObjs>
3198             SwSortedObjs &rObjs = *pFrame->GetDrawObjs();
3199             for(SwAnchoredObject* pObj : rObjs)
3200             {
3201                 // #i28701# - consider changed type of
3202                 // <SwSortedObjs> entries.
3203                 if( pObj->DynCastFlyFrame() !=  nullptr &&
3204                     (pObj->GetFrameFormat()) == this )
3205                 {
3206                     bAdd = false;
3207                     break;
3208                 }
3209             }
3210         }
3211 
3212         if( bAdd )
3213         {
3214             SwFlyFrame *pFly = nullptr; // avoid warnings
3215             switch( aAnchorAttr.GetAnchorId() )
3216             {
3217             case RndStdIds::FLY_AT_FLY:
3218                 pFly = new SwFlyLayFrame( this, pFrame, pFrame );
3219                 break;
3220 
3221             case RndStdIds::FLY_AT_PARA:
3222             case RndStdIds::FLY_AT_CHAR:
3223                 pFly = new SwFlyAtContentFrame( this, pFrame, pFrame );
3224                 break;
3225 
3226             case RndStdIds::FLY_AS_CHAR:
3227                 pFly = new SwFlyInContentFrame( this, pFrame, pFrame );
3228                 break;
3229 
3230             default:
3231                 assert(false && "New anchor type" );
3232             }
3233             pFrame->AppendFly( pFly );
3234             pFly->GetFormat()->SetObjTitle(GetObjTitle());
3235             pFly->GetFormat()->SetObjDescription(GetObjDescription());
3236             SwPageFrame *pPage = pFly->FindPageFrame();
3237             if( pPage )
3238                 ::RegistFlys( pPage, pFly );
3239         }
3240     }
3241 }
3242 
GetFrame(const Point * pPoint) const3243 SwFlyFrame* SwFlyFrameFormat::GetFrame( const Point* pPoint ) const
3244 {
3245     std::pair<Point, bool> tmp;
3246     if (pPoint)
3247     {
3248         tmp.first = *pPoint;
3249         tmp.second = false;
3250     }
3251     return static_cast<SwFlyFrame*>(::GetFrameOfModify( nullptr, *this, SwFrameType::Fly,
3252                                             nullptr, &tmp));
3253 }
3254 
GetAnchoredObj() const3255 SwAnchoredObject* SwFlyFrameFormat::GetAnchoredObj() const
3256 {
3257     SwFlyFrame* pFlyFrame( GetFrame() );
3258     if ( pFlyFrame )
3259     {
3260         return pFlyFrame;
3261     }
3262     else
3263     {
3264         return nullptr;
3265     }
3266 }
3267 
3268 // #i73249#
SetObjTitle(const OUString & rTitle,bool bBroadcast)3269 void SwFlyFrameFormat::SetObjTitle( const OUString& rTitle, bool bBroadcast )
3270 {
3271     SdrObject* pMasterObject = FindSdrObject();
3272     OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::SetObjTitle(..)> - missing <SdrObject> instance" );
3273     msTitle = rTitle;
3274     if ( !pMasterObject )
3275     {
3276         return;
3277     }
3278 
3279     const sw::TitleChanged aHint(pMasterObject->GetTitle(), rTitle);
3280     pMasterObject->SetTitle(rTitle);
3281     if(bBroadcast)
3282     {
3283         GetNotifier().Broadcast(aHint);
3284     }
3285 }
3286 
GetObjTitle() const3287 OUString SwFlyFrameFormat::GetObjTitle() const
3288 {
3289     const SdrObject* pMasterObject = FindSdrObject();
3290     OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::GetObjTitle(..)> - missing <SdrObject> instance" );
3291     if ( !pMasterObject )
3292     {
3293         return msTitle;
3294     }
3295     if (!pMasterObject->GetTitle().isEmpty())
3296         return pMasterObject->GetTitle();
3297     else
3298         return msTitle;
3299 }
3300 
SetObjTooltip(const OUString & rTooltip)3301 void SwFlyFrameFormat::SetObjTooltip(const OUString& rTooltip)
3302 {
3303     msTooltip = rTooltip;
3304 }
3305 
GetObjTooltip() const3306 const OUString & SwFlyFrameFormat::GetObjTooltip() const
3307 {
3308     return msTooltip;
3309 }
3310 
SetObjDescription(const OUString & rDescription,bool bBroadcast)3311 void SwFlyFrameFormat::SetObjDescription( const OUString& rDescription, bool bBroadcast )
3312 {
3313     SdrObject* pMasterObject = FindSdrObject();
3314     OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance" );
3315     msDesc = rDescription;
3316     if ( !pMasterObject )
3317     {
3318         return;
3319     }
3320 
3321     const sw::DescriptionChanged aHint;
3322     pMasterObject->SetDescription(rDescription);
3323     if(bBroadcast)
3324     {
3325         GetNotifier().Broadcast(aHint);
3326     }
3327 }
3328 
GetObjDescription() const3329 OUString SwFlyFrameFormat::GetObjDescription() const
3330 {
3331     const SdrObject* pMasterObject = FindSdrObject();
3332     OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::GetDescription(..)> - missing <SdrObject> instance" );
3333     if ( !pMasterObject )
3334     {
3335         return msDesc;
3336     }
3337     if (!pMasterObject->GetDescription().isEmpty())
3338         return pMasterObject->GetDescription();
3339     else
3340         return msDesc;
3341 }
3342 
IsDecorative() const3343 bool SwFlyFrameFormat::IsDecorative() const
3344 {
3345     const SdrObject* pMasterObject = FindSdrObject();
3346     OSL_ENSURE(pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance");
3347     if (!pMasterObject)
3348     {
3349         return false;
3350     }
3351 
3352     return pMasterObject->IsDecorative();
3353 }
3354 
SetObjDecorative(bool const isDecorative)3355 void SwFlyFrameFormat::SetObjDecorative(bool const isDecorative)
3356 {
3357     SdrObject* pMasterObject = FindSdrObject();
3358     OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance" );
3359     if ( !pMasterObject )
3360     {
3361         return;
3362     }
3363 
3364     SetFormatAttr(SfxBoolItem(RES_DECORATIVE, isDecorative));
3365     pMasterObject->SetDecorative(isDecorative);
3366     // does anybody care about a broadcast?
3367 }
3368 
3369 
3370 /** SwFlyFrameFormat::IsBackgroundTransparent - for #99657#
3371 
3372     OD 22.08.2002 - overriding virtual method and its default implementation,
3373     because format of fly frame provides transparent backgrounds.
3374     Method determines, if background of fly frame is transparent.
3375 
3376     @return true, if background color is transparent, but not "no fill"
3377     or the transparency of an existing background graphic is set.
3378 */
IsBackgroundTransparent() const3379 bool SwFlyFrameFormat::IsBackgroundTransparent() const
3380 {
3381     if (supportsFullDrawingLayerFillAttributeSet() && getSdrAllFillAttributesHelper())
3382     {
3383         return getSdrAllFillAttributesHelper()->isTransparent();
3384     }
3385 
3386     // NOTE: If background color is "no fill"/"auto fill" (COL_TRANSPARENT)
3387     //     and there is no background graphic, it "inherites" the background
3388     //     from its anchor.
3389     std::unique_ptr<SvxBrushItem> aBackground(makeBackgroundBrushItem());
3390     if ( aBackground->GetColor().IsTransparent() &&
3391          aBackground->GetColor() != COL_TRANSPARENT
3392        )
3393     {
3394         return true;
3395     }
3396     else
3397     {
3398         const GraphicObject *pTmpGrf = aBackground->GetGraphicObject();
3399         if ( pTmpGrf &&
3400              pTmpGrf->GetAttr().IsTransparent()
3401            )
3402         {
3403             return true;
3404         }
3405     }
3406 
3407     return false;
3408 }
3409 
3410 /** SwFlyFrameFormat::IsBackgroundBrushInherited - for #103898#
3411 
3412     OD 08.10.2002 - method to determine, if the brush for drawing the
3413     background is "inherited" from its parent/grandparent.
3414     This is the case, if no background graphic is set and the background
3415     color is "no fill"/"auto fill"
3416     NOTE: condition is "copied" from method <SwFrame::GetBackgroundBrush(..).
3417 
3418     @return true, if background brush is "inherited" from parent/grandparent
3419 */
IsBackgroundBrushInherited() const3420 bool SwFlyFrameFormat::IsBackgroundBrushInherited() const
3421 {
3422     if (supportsFullDrawingLayerFillAttributeSet() && getSdrAllFillAttributesHelper())
3423     {
3424         return !getSdrAllFillAttributesHelper()->isUsed();
3425     }
3426     else
3427     {
3428         std::unique_ptr<SvxBrushItem> aBackground(makeBackgroundBrushItem());
3429         if ( (aBackground->GetColor() == COL_TRANSPARENT) &&
3430              !(aBackground->GetGraphicObject()) )
3431         {
3432             return true;
3433         }
3434     }
3435 
3436     return false;
3437 }
3438 
SwHandleAnchorNodeChg(SwFlyFrameFormat & _rFlyFrameFormat,const SwFormatAnchor & _rNewAnchorFormat,SwFlyFrame const * _pKeepThisFlyFrame)3439 SwHandleAnchorNodeChg::SwHandleAnchorNodeChg( SwFlyFrameFormat& _rFlyFrameFormat,
3440                                               const SwFormatAnchor& _rNewAnchorFormat,
3441                                               SwFlyFrame const * _pKeepThisFlyFrame )
3442     : mrFlyFrameFormat( _rFlyFrameFormat ),
3443       mbAnchorNodeChanged( false ),
3444       mpWrtShell(nullptr)
3445 {
3446     const SwFormatAnchor& aOldAnchorFormat(_rFlyFrameFormat.GetAnchor());
3447     const RndStdIds nNewAnchorType( _rNewAnchorFormat.GetAnchorId() );
3448     if ( ((nNewAnchorType == RndStdIds::FLY_AT_PARA) ||
3449           (nNewAnchorType == RndStdIds::FLY_AT_CHAR)) &&
3450          _rNewAnchorFormat.GetAnchorNode() &&
3451          _rNewAnchorFormat.GetAnchorNode()->GetContentNode() )
3452     {
3453         if ( aOldAnchorFormat.GetAnchorId() == nNewAnchorType &&
3454              aOldAnchorFormat.GetAnchorNode() &&
3455              aOldAnchorFormat.GetAnchorNode()->GetContentNode() &&
3456              aOldAnchorFormat.GetContentAnchor()->GetNode() !=
3457                                     _rNewAnchorFormat.GetContentAnchor()->GetNode() )
3458         {
3459             // determine 'old' number of anchor frames
3460             sal_uInt32 nOldNumOfAnchFrame( 0 );
3461             SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aOldIter(
3462                 *(aOldAnchorFormat.GetAnchorNode()->GetContentNode()) );
3463             for( SwFrame* pOld = aOldIter.First(); pOld; pOld = aOldIter.Next() )
3464             {
3465                 ++nOldNumOfAnchFrame;
3466             }
3467             // determine 'new' number of anchor frames
3468             sal_uInt32 nNewNumOfAnchFrame( 0 );
3469             SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aNewIter(
3470                 *(_rNewAnchorFormat.GetAnchorNode()->GetContentNode()) );
3471             for( SwFrame* pNew = aNewIter.First(); pNew; pNew = aNewIter.Next() )
3472             {
3473                 ++nNewNumOfAnchFrame;
3474             }
3475             if ( nOldNumOfAnchFrame != nNewNumOfAnchFrame )
3476             {
3477                 // delete existing fly frames except <_pKeepThisFlyFrame>
3478                 SwIterator<SwFrame,SwFormat> aIter( mrFlyFrameFormat );
3479                 SwFrame* pFrame = aIter.First();
3480                 if ( pFrame )
3481                 {
3482                     do {
3483                         if ( pFrame != _pKeepThisFlyFrame )
3484                         {
3485                             pFrame->Cut();
3486                             SwFrame::DestroyFrame(pFrame);
3487                         }
3488                     } while( nullptr != ( pFrame = aIter.Next() ));
3489                 }
3490                 // indicate, that re-creation of fly frames necessary
3491                 mbAnchorNodeChanged = true;
3492             }
3493         }
3494     }
3495 
3496     if (aOldAnchorFormat.GetAnchorNode()
3497         && aOldAnchorFormat.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
3498     {
3499         moCommentAnchor.emplace(*aOldAnchorFormat.GetContentAnchor());
3500     }
3501 
3502     if (_pKeepThisFlyFrame)
3503     {
3504         SwViewShell* pViewShell = _pKeepThisFlyFrame->getRootFrame()->GetCurrShell();
3505         mpWrtShell = dynamic_cast<SwWrtShell*>(pViewShell);
3506     }
3507 }
3508 
ImplDestroy()3509 void SwHandleAnchorNodeChg::ImplDestroy()
3510 {
3511     if ( mbAnchorNodeChanged )
3512     {
3513         mrFlyFrameFormat.MakeFrames();
3514     }
3515 
3516     // See if the fly frame had a comment: if so, move it to the new anchor as well.
3517     if (!moCommentAnchor)
3518     {
3519         return;
3520     }
3521 
3522     SwTextNode* pTextNode = moCommentAnchor->GetNode().GetTextNode();
3523     if (!pTextNode)
3524     {
3525         return;
3526     }
3527 
3528     const SwTextField* pField = pTextNode->GetFieldTextAttrAt(moCommentAnchor->GetContentIndex());
3529     if (!pField || pField->GetFormatField().GetField()->GetTyp()->Which() != SwFieldIds::Postit)
3530     {
3531         return;
3532     }
3533 
3534     if (!mpWrtShell)
3535     {
3536         return;
3537     }
3538 
3539     // Save current cursor position, so we can restore it later.
3540     mpWrtShell->Push();
3541 
3542     // Set up the source of the move: the old comment anchor.
3543     {
3544         SwPaM& rCursor = mpWrtShell->GetCurrentShellCursor();
3545         *rCursor.GetPoint() = *moCommentAnchor;
3546         rCursor.SetMark();
3547         *rCursor.GetMark() = *moCommentAnchor;
3548         rCursor.GetMark()->AdjustContent(+1);
3549     }
3550 
3551     // Set up the target of the move: the new comment anchor.
3552     const SwFormatAnchor& rNewAnchorFormat = mrFlyFrameFormat.GetAnchor();
3553     mpWrtShell->CreateCursor();
3554     *mpWrtShell->GetCurrentShellCursor().GetPoint() = *rNewAnchorFormat.GetContentAnchor();
3555 
3556     // Move by copying and deleting.
3557     mpWrtShell->SwEditShell::Copy(*mpWrtShell);
3558     mpWrtShell->DestroyCursor();
3559 
3560     mpWrtShell->Delete(false);
3561 
3562     mpWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
3563 }
3564 
~SwHandleAnchorNodeChg()3565 SwHandleAnchorNodeChg::~SwHandleAnchorNodeChg()
3566 {
3567     suppress_fun_call_w_exception(ImplDestroy());
3568 }
3569 
3570 namespace sw
3571 {
~DrawFrameFormatHint()3572     DrawFrameFormatHint::~DrawFrameFormatHint() {}
~CheckDrawFrameFormatLayerHint()3573     CheckDrawFrameFormatLayerHint::~CheckDrawFrameFormatLayerHint() {}
~ContactChangedHint()3574     ContactChangedHint::~ContactChangedHint() {}
~DrawFormatLayoutCopyHint()3575     DrawFormatLayoutCopyHint::~DrawFormatLayoutCopyHint() {}
~WW8AnchorConvHint()3576     WW8AnchorConvHint::~WW8AnchorConvHint() {}
~RestoreFlyAnchorHint()3577     RestoreFlyAnchorHint::~RestoreFlyAnchorHint() {}
~CreatePortionHint()3578     CreatePortionHint::~CreatePortionHint() {}
~FindSdrObjectHint()3579     FindSdrObjectHint::~FindSdrObjectHint() {}
~CollectTextObjectsHint()3580     CollectTextObjectsHint::~CollectTextObjectsHint() {}
~GetZOrderHint()3581     GetZOrderHint::~GetZOrderHint() {}
~GetObjectConnectedHint()3582     GetObjectConnectedHint::~GetObjectConnectedHint() {}
3583 }
3584 
~SwDrawFrameFormat()3585 SwDrawFrameFormat::~SwDrawFrameFormat()
3586 {
3587     CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::DYING));
3588 }
3589 
MakeFrames()3590 void SwDrawFrameFormat::MakeFrames()
3591 {
3592     CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::MAKE_FRAMES));
3593 }
3594 
DelFrames()3595 void SwDrawFrameFormat::DelFrames()
3596 {
3597     CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::DELETE_FRAMES));
3598 }
3599 
3600 // #i31698#
GetLayoutDir() const3601 SwFrameFormat::tLayoutDir SwDrawFrameFormat::GetLayoutDir() const
3602 {
3603     return meLayoutDir;
3604 }
3605 
SetLayoutDir(const SwFrameFormat::tLayoutDir _eLayoutDir)3606 void SwDrawFrameFormat::SetLayoutDir( const SwFrameFormat::tLayoutDir _eLayoutDir )
3607 {
3608     meLayoutDir = _eLayoutDir;
3609 }
3610 
3611 // #i28749#
GetPositionLayoutDir() const3612 sal_Int16 SwDrawFrameFormat::GetPositionLayoutDir() const
3613 {
3614     return mnPositionLayoutDir;
3615 }
SetPositionLayoutDir(const sal_Int16 _nPositionLayoutDir)3616 void SwDrawFrameFormat::SetPositionLayoutDir( const sal_Int16 _nPositionLayoutDir )
3617 {
3618     switch ( _nPositionLayoutDir )
3619     {
3620         case text::PositionLayoutDir::PositionInHoriL2R:
3621         case text::PositionLayoutDir::PositionInLayoutDirOfAnchor:
3622         {
3623             mnPositionLayoutDir = _nPositionLayoutDir;
3624         }
3625         break;
3626         default:
3627         {
3628             OSL_FAIL( "<SwDrawFrameFormat::SetPositionLayoutDir(..)> - invalid attribute value." );
3629         }
3630     }
3631 }
3632 
GetDescription() const3633 OUString SwDrawFrameFormat::GetDescription() const
3634 {
3635     OUString aResult;
3636     const SdrObject * pSdrObj = FindSdrObject();
3637 
3638     if (pSdrObj)
3639     {
3640         if (pSdrObj != m_pSdrObjectCached)
3641         {
3642             m_sSdrObjectCachedComment = SdrUndoNewObj::GetComment(*pSdrObj);
3643             m_pSdrObjectCached = pSdrObj;
3644         }
3645 
3646         aResult = m_sSdrObjectCachedComment;
3647     }
3648     else
3649         aResult = SwResId(STR_GRAPHIC);
3650 
3651     return aResult;
3652 }
3653 
GetIMapObject(const Point & rPoint,const SwFlyFrame * pFly) const3654 IMapObject* SwFrameFormat::GetIMapObject( const Point& rPoint,
3655                                         const SwFlyFrame *pFly ) const
3656 {
3657     const SwFormatURL &rURL = GetURL();
3658     if( !rURL.GetMap() )
3659         return nullptr;
3660 
3661     if( !pFly )
3662     {
3663         pFly = SwIterator<SwFlyFrame,SwFormat>( *this ).First();
3664         if( !pFly )
3665             return nullptr;
3666     }
3667 
3668     //Original size for OLE and graphic is TwipSize, otherwise the size of
3669     //FrameFormat of the Fly.
3670     const SwFrame *pRef;
3671     const SwNoTextNode *pNd = nullptr;
3672     Size aOrigSz;
3673     const SwFrame* pLower = pFly->Lower();
3674     if( pLower && pLower->IsNoTextFrame() )
3675     {
3676         pRef = pLower;
3677         pNd = static_cast<const SwNoTextFrame*>(pRef)->GetNode()->GetNoTextNode();
3678         aOrigSz = pNd->GetTwipSize();
3679     }
3680     else
3681     {
3682         pRef = pFly;
3683         aOrigSz = pFly->GetFormat()->GetFrameSize().GetSize();
3684     }
3685 
3686     if( !aOrigSz.IsEmpty() )
3687     {
3688         Point aPos( rPoint );
3689         Size aActSz ( pRef == pFly ? pFly->getFrameArea().SSize() : pRef->getFramePrintArea().SSize() );
3690         const o3tl::Length aSrc ( o3tl::Length::twip );
3691         const o3tl::Length aDest( o3tl::Length::mm100 );
3692         aOrigSz = o3tl::convert( aOrigSz, aSrc, aDest );
3693         aActSz  = o3tl::convert( aActSz,  aSrc, aDest );
3694         aPos -= pRef->getFrameArea().Pos();
3695         aPos -= pRef->getFramePrintArea().Pos();
3696         aPos    = o3tl::convert( aPos, aSrc, aDest );
3697         sal_uInt32 nFlags = 0;
3698         if ( pFly != pRef && pNd->IsGrfNode() )
3699         {
3700             const MirrorGraph nMirror = pNd->GetSwAttrSet().
3701                                         GetMirrorGrf().GetValue();
3702             if ( MirrorGraph::Both == nMirror )
3703                 nFlags = IMAP_MIRROR_HORZ | IMAP_MIRROR_VERT;
3704             else if ( MirrorGraph::Vertical == nMirror )
3705                 nFlags = IMAP_MIRROR_VERT;
3706             else if ( MirrorGraph::Horizontal == nMirror )
3707                 nFlags = IMAP_MIRROR_HORZ;
3708 
3709         }
3710         return rURL.GetMap()->GetHitIMapObject( aOrigSz, aActSz, aPos, nFlags );
3711     }
3712 
3713     return nullptr;
3714 }
3715 
getSdrAllFillAttributesHelper() const3716 drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFrameFormat::getSdrAllFillAttributesHelper() const
3717 {
3718     if (supportsFullDrawingLayerFillAttributeSet())
3719     {
3720         // create FillAttributes on demand
3721         if(!maFillAttributes)
3722         {
3723             const_cast< SwFrameFormat* >(this)->maFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(GetAttrSet());
3724         }
3725     }
3726     else
3727     {
3728         // FALLBACKBREAKHERE assert wrong usage
3729         OSL_ENSURE(false, "getSdrAllFillAttributesHelper() call only valid for RES_FLYFRMFMT and RES_FRMFMT (!)");
3730     }
3731 
3732     return maFillAttributes;
3733 }
3734 
MoveTableBox(SwTableBox & rTableBox,const SwFrameFormat * pOldFormat)3735 void SwFrameFormat::MoveTableBox(SwTableBox& rTableBox, const SwFrameFormat* pOldFormat)
3736 {
3737     Add(rTableBox);
3738     if(!pOldFormat)
3739         return;
3740     const auto& rOld = pOldFormat->GetFormatAttr(RES_BOXATR_FORMAT);
3741     const auto& rNew = GetFormatAttr(RES_BOXATR_FORMAT);
3742     if(rOld != rNew)
3743         SwClientNotify(*this, sw::LegacyModifyHint(&rOld, &rNew));
3744 }
3745 
IsVisible() const3746 bool SwFrameFormat::IsVisible() const
3747 {
3748     return SwIterator<SwFrame, SwFrameFormat>(*this).First();
3749 };
3750 
3751 namespace sw {
3752 
IsFlyFrameFormatInHeader(const SwFrameFormat & rFormat)3753 bool IsFlyFrameFormatInHeader(const SwFrameFormat& rFormat)
3754 {
3755     const SwFlyFrameFormat* pFlyFrameFormat = dynamic_cast<const SwFlyFrameFormat*>(&rFormat);
3756     if (!pFlyFrameFormat)
3757         return false;
3758     SwFlyFrame* pFlyFrame = pFlyFrameFormat->GetFrame();
3759     if (!pFlyFrame) // fdo#54648: "hidden" drawing object has no layout frame
3760     {
3761         return false;
3762     }
3763     SwPageFrame* pPageFrame = pFlyFrame->FindPageFrameOfAnchor();
3764     SwFrame* pHeader = pPageFrame->Lower();
3765     if (pHeader && pHeader->GetType() == SwFrameType::Header)
3766     {
3767         const SwFrame* pFrame = pFlyFrame->GetAnchorFrame();
3768         while (pFrame)
3769         {
3770             if (pFrame == pHeader)
3771                 return true;
3772             pFrame = pFrame->GetUpper();
3773         }
3774     }
3775     return false;
3776 }
3777 
CheckAnchoredFlyConsistency(SwDoc const & rDoc)3778 void CheckAnchoredFlyConsistency(SwDoc const& rDoc)
3779 {
3780 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
3781     SwNodes const& rNodes(rDoc.GetNodes());
3782     SwNodeOffset const count(rNodes.Count());
3783     for (SwNodeOffset i(0); i != count; ++i)
3784     {
3785         SwNode const*const pNode(rNodes[i]);
3786         std::vector<SwFrameFormat*> const & rFlys(pNode->GetAnchoredFlys());
3787         for (const auto& rpFly : rFlys)
3788         {
3789             SwFormatAnchor const& rAnchor((*rpFly).GetAnchor(false));
3790             assert(rAnchor.GetAnchorNode() == pNode);
3791         }
3792     }
3793     if(!rDoc.GetSpzFrameFormats())
3794         return;
3795 
3796     for(sw::SpzFrameFormat* pSpz: *rDoc.GetSpzFrameFormats())
3797     {
3798         SwFormatAnchor const& rAnchor(pSpz->GetAnchor(false));
3799         if (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId())
3800         {
3801             assert(!rAnchor.GetAnchorNode()
3802                 // for invalid documents that lack text:anchor-page-number
3803                 // it may have an anchor before MakeFrames() is called
3804                 || (!SwIterator<SwFrame, SwFrameFormat>(*pSpz).First()));
3805         }
3806         else
3807         {
3808             SwNode & rNode(*rAnchor.GetAnchorNode());
3809             std::vector<SwFrameFormat*> const& rFlys(rNode.GetAnchoredFlys());
3810             assert(std::find(rFlys.begin(), rFlys.end(), pSpz) != rFlys.end());
3811             switch (rAnchor.GetAnchorId())
3812             {
3813                 case RndStdIds::FLY_AT_FLY:
3814                     assert(rNode.IsStartNode());
3815                 break;
3816                 case RndStdIds::FLY_AT_PARA:
3817                     assert(rNode.IsTextNode() || rNode.IsTableNode());
3818                 break;
3819                 case RndStdIds::FLY_AS_CHAR:
3820                 case RndStdIds::FLY_AT_CHAR:
3821                     assert(rNode.IsTextNode());
3822                 break;
3823                 default:
3824                     assert(false);
3825                 break;
3826             }
3827         }
3828     }
3829 #else
3830     (void) rDoc;
3831 #endif
3832 }
3833 
3834 } // namespace sw
3835 
3836 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3837