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