Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / core / layout / atrfrm.cxx
blobe4351b163e158851d5425488535d9399a22f0431
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
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>
96 #include <ndtxt.hxx>
98 #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
99 #include <svl/itemiter.hxx>
100 #include <wrtsh.hxx>
101 #include <txtfld.hxx>
102 #include <cellatr.hxx>
104 using namespace ::com::sun::star;
106 namespace sw {
108 bool GetAtPageRelOrientation(sal_Int16 & rOrientation, bool const isIgnorePrintArea)
110 switch (rOrientation)
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)
119 return false;
121 else
123 rOrientation = text::RelOrientation::PAGE_PRINT_AREA;
124 return true;
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;
137 } // namespace sw
139 SfxPoolItem* SwFormatLineNumber::CreateDefault() { return new SwFormatLineNumber; }
141 static sal_Int16 lcl_IntToRelation(const uno::Any& rVal)
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;
149 static void lcl_DelHFFormat( SwClient *pToRemove, SwFrameFormat *pFormat )
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() )
157 delete pFormat;
158 return;
161 // Anything other than frames registered?
162 bool bDel = true;
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;
172 if ( !bDel )
173 return;
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() )
180 SwNode *pNode = nullptr;
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 )
193 if ( pNode->IsContentNode() &&
194 static_cast<SwContentNode*>(pNode)->HasWriterListeners() )
196 SwCursorShell *pShell = SwIterator<SwCursorShell,SwContentNode>( *static_cast<SwContentNode*>(pNode) ).First();
197 if( pShell )
199 pShell->ParkCursor( aIdx.GetNode() );
200 aIdx = nEnd-1;
203 ++aIdx;
204 pNode = & aIdx.GetNode();
207 rCnt.SetNewContentIdx( nullptr );
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());
213 OSL_ENSURE( pNode, "A big problem." );
214 pDoc->getIDocumentContentOperations().DeleteSection( pNode );
216 delete pFormat;
219 void SwFormatFrameSize::ScaleMetrics(tools::Long lMult, tools::Long lDiv) {
220 // Don't inherit the SvxSizeItem override (might or might not be relevant; added "just in case"
221 // when changing SwFormatFrameSize to derive from SvxSizeItem instead of directly from
222 // SfxPoolItem):
223 return SfxPoolItem::ScaleMetrics(lMult, lDiv);
226 bool SwFormatFrameSize::HasMetrics() const {
227 // Don't inherit the SvxSizeItem override (might or might not be relevant; added "just in case"
228 // when changing SwFormatFrameSize to derive from SvxSizeItem instead of directly from
229 // SfxPoolItem):
230 return SfxPoolItem::HasMetrics();
233 // Partially implemented inline in hxx
234 SwFormatFrameSize::SwFormatFrameSize( SwFrameSize eSize, SwTwips nWidth, SwTwips nHeight )
235 : SvxSizeItem( RES_FRM_SIZE, {nWidth, nHeight} ),
236 m_eFrameHeightType( eSize ),
237 m_eFrameWidthType( SwFrameSize::Fixed )
239 m_nWidthPercent = m_eWidthPercentRelation = m_nHeightPercent = m_eHeightPercentRelation = 0;
242 bool SwFormatFrameSize::operator==( const SfxPoolItem& rAttr ) const
244 assert(SfxPoolItem::operator==(rAttr));
245 return( m_eFrameHeightType == static_cast<const SwFormatFrameSize&>(rAttr).m_eFrameHeightType &&
246 m_eFrameWidthType == static_cast<const SwFormatFrameSize&>(rAttr).m_eFrameWidthType &&
247 SvxSizeItem::operator==(rAttr)&&
248 m_nWidthPercent == static_cast<const SwFormatFrameSize&>(rAttr).GetWidthPercent() &&
249 m_eWidthPercentRelation == static_cast<const SwFormatFrameSize&>(rAttr).GetWidthPercentRelation() &&
250 m_nHeightPercent == static_cast<const SwFormatFrameSize&>(rAttr).GetHeightPercent() &&
251 m_eHeightPercentRelation == static_cast<const SwFormatFrameSize&>(rAttr).GetHeightPercentRelation() );
254 SwFormatFrameSize* SwFormatFrameSize::Clone( SfxItemPool* ) const
256 return new SwFormatFrameSize( *this );
259 bool SwFormatFrameSize::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
261 // here we convert always!
262 nMemberId &= ~CONVERT_TWIPS;
263 switch ( nMemberId )
265 case MID_FRMSIZE_SIZE:
267 awt::Size aTmp;
268 aTmp.Height = convertTwipToMm100(GetHeight());
269 aTmp.Width = convertTwipToMm100(GetWidth());
270 rVal <<= aTmp;
272 break;
273 case MID_FRMSIZE_REL_HEIGHT:
274 rVal <<= static_cast<sal_Int16>(GetHeightPercent() != SwFormatFrameSize::SYNCED ? GetHeightPercent() : 0);
275 break;
276 case MID_FRMSIZE_REL_HEIGHT_RELATION:
277 rVal <<= GetHeightPercentRelation();
278 break;
279 case MID_FRMSIZE_REL_WIDTH:
280 rVal <<= static_cast<sal_Int16>(GetWidthPercent() != SwFormatFrameSize::SYNCED ? GetWidthPercent() : 0);
281 break;
282 case MID_FRMSIZE_REL_WIDTH_RELATION:
283 rVal <<= GetWidthPercentRelation();
284 break;
285 case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH:
286 rVal <<= SwFormatFrameSize::SYNCED == GetHeightPercent();
287 break;
288 case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT:
289 rVal <<= SwFormatFrameSize::SYNCED == GetWidthPercent();
290 break;
291 case MID_FRMSIZE_WIDTH :
292 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(GetWidth()));
293 break;
294 case MID_FRMSIZE_HEIGHT:
295 // #95848# returned size should never be zero.
296 // (there was a bug that allowed for setting height to 0.
297 // Thus there some documents existing with that not allowed
298 // attribute value which may cause problems on import.)
299 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(GetHeight() < MINLAY ? MINLAY : GetHeight() ));
300 break;
301 case MID_FRMSIZE_SIZE_TYPE:
302 rVal <<= static_cast<sal_Int16>(GetHeightSizeType());
303 break;
304 case MID_FRMSIZE_IS_AUTO_HEIGHT:
305 rVal <<= SwFrameSize::Fixed != GetHeightSizeType();
306 break;
307 case MID_FRMSIZE_WIDTH_TYPE:
308 rVal <<= static_cast<sal_Int16>(GetWidthSizeType());
309 break;
311 return true;
314 bool SwFormatFrameSize::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
316 bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
317 nMemberId &= ~CONVERT_TWIPS;
318 bool bRet = true;
319 switch ( nMemberId )
321 case MID_FRMSIZE_SIZE:
323 awt::Size aVal;
324 if(!(rVal >>= aVal))
325 bRet = false;
326 else
328 Size aTmp(aVal.Width, aVal.Height);
329 if(bConvert)
331 aTmp.setHeight(o3tl::toTwips(aTmp.Height(), o3tl::Length::mm100));
332 aTmp.setWidth(o3tl::toTwips(aTmp.Width(), o3tl::Length::mm100));
334 SetSize(aTmp);
337 break;
338 case MID_FRMSIZE_REL_HEIGHT:
340 sal_Int16 nSet = 0;
341 rVal >>= nSet;
342 if(nSet >= 0 && nSet < SwFormatFrameSize::SYNCED)
343 SetHeightPercent(static_cast<sal_uInt8>(nSet));
344 else
345 bRet = false;
347 break;
348 case MID_FRMSIZE_REL_HEIGHT_RELATION:
350 sal_Int16 eSet = 0;
351 rVal >>= eSet;
352 SetHeightPercentRelation(eSet);
354 break;
355 case MID_FRMSIZE_REL_WIDTH:
357 sal_Int16 nSet = 0;
358 rVal >>= nSet;
359 if(nSet >= 0 && nSet < SwFormatFrameSize::SYNCED)
360 SetWidthPercent(static_cast<sal_uInt8>(nSet));
361 else
362 bRet = false;
364 break;
365 case MID_FRMSIZE_REL_WIDTH_RELATION:
367 sal_Int16 eSet = 0;
368 rVal >>= eSet;
369 SetWidthPercentRelation(eSet);
371 break;
372 case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH:
374 bool bSet = *o3tl::doAccess<bool>(rVal);
375 if(bSet)
376 SetHeightPercent(SwFormatFrameSize::SYNCED);
377 else if( SwFormatFrameSize::SYNCED == GetHeightPercent() )
378 SetHeightPercent( 0 );
380 break;
381 case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT:
383 bool bSet = *o3tl::doAccess<bool>(rVal);
384 if(bSet)
385 SetWidthPercent(SwFormatFrameSize::SYNCED);
386 else if( SwFormatFrameSize::SYNCED == GetWidthPercent() )
387 SetWidthPercent(0);
389 break;
390 case MID_FRMSIZE_WIDTH :
392 sal_Int32 nWd = 0;
393 if(rVal >>= nWd)
395 if(bConvert)
396 nWd = o3tl::toTwips(nWd, o3tl::Length::mm100);
397 if(nWd < MINLAY)
398 nWd = MINLAY;
399 SetWidth(nWd);
401 else
402 bRet = false;
404 break;
405 case MID_FRMSIZE_HEIGHT:
407 sal_Int32 nHg = 0;
408 if(rVal >>= nHg)
410 if(bConvert)
411 nHg = o3tl::toTwips(nHg, o3tl::Length::mm100);
412 if(nHg < MINLAY)
413 nHg = MINLAY;
414 SetHeight(nHg);
416 else
417 bRet = false;
419 break;
420 case MID_FRMSIZE_SIZE_TYPE:
422 sal_Int16 nType = 0;
423 if((rVal >>= nType) && nType >= 0 && nType <= static_cast<int>(SwFrameSize::Minimum) )
425 SetHeightSizeType(static_cast<SwFrameSize>(nType));
427 else
428 bRet = false;
430 break;
431 case MID_FRMSIZE_IS_AUTO_HEIGHT:
433 bool bSet = *o3tl::doAccess<bool>(rVal);
434 SetHeightSizeType(bSet ? SwFrameSize::Variable : SwFrameSize::Fixed);
436 break;
437 case MID_FRMSIZE_WIDTH_TYPE:
439 sal_Int16 nType = 0;
440 if((rVal >>= nType) && nType >= 0 && nType <= static_cast<int>(SwFrameSize::Minimum) )
442 SetWidthSizeType(static_cast<SwFrameSize>(nType));
444 else
445 bRet = false;
447 break;
448 default:
449 bRet = false;
451 return bRet;
454 void SwFormatFrameSize::dumpAsXml(xmlTextWriterPtr pWriter) const
456 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatFrameSize"));
457 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
459 std::stringstream aSize;
460 aSize << GetSize();
461 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), BAD_CAST(aSize.str().c_str()));
463 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameHeightType"), BAD_CAST(OString::number(static_cast<int>(m_eFrameHeightType)).getStr()));
464 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eFrameWidthType"), BAD_CAST(OString::number(static_cast<int>(m_eFrameWidthType)).getStr()));
465 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthPercent"), BAD_CAST(OString::number(m_nWidthPercent).getStr()));
466 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eWidthPercentRelation"), BAD_CAST(OString::number(m_eWidthPercentRelation).getStr()));
467 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nHeightPercent"), BAD_CAST(OString::number(m_nHeightPercent).getStr()));
468 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eHeightPercentRelation"), BAD_CAST(OString::number(m_eHeightPercentRelation).getStr()));
470 (void)xmlTextWriterEndElement(pWriter);
473 // Partially implemented inline in hxx
474 SwFormatFillOrder::SwFormatFillOrder( SwFillOrder nFO )
475 : SfxEnumItem( RES_FILL_ORDER, nFO )
478 SwFormatFillOrder* SwFormatFillOrder::Clone( SfxItemPool* ) const
480 return new SwFormatFillOrder( GetValue() );
483 sal_uInt16 SwFormatFillOrder::GetValueCount() const
485 return SW_FILL_ORDER_END - SW_FILL_ORDER_BEGIN;
488 // Partially implemented inline in hxx
489 SwFormatHeader::SwFormatHeader( SwFrameFormat *pHeaderFormat )
490 : SfxPoolItem( RES_HEADER ),
491 SwClient( pHeaderFormat ),
492 m_bActive( pHeaderFormat )
496 SwFormatHeader::SwFormatHeader( const SwFormatHeader &rCpy )
497 : SfxPoolItem( RES_HEADER ),
498 SwClient( const_cast<sw::BroadcastingModify*>(static_cast<const sw::BroadcastingModify*>(rCpy.GetRegisteredIn())) ),
499 m_bActive( rCpy.IsActive() )
503 SwFormatHeader::SwFormatHeader( bool bOn )
504 : SfxPoolItem( RES_HEADER ),
505 SwClient( nullptr ),
506 m_bActive( bOn )
510 SwFormatHeader::~SwFormatHeader()
512 if ( GetHeaderFormat() )
513 lcl_DelHFFormat( this, GetHeaderFormat() );
516 bool SwFormatHeader::operator==( const SfxPoolItem& rAttr ) const
518 assert(SfxPoolItem::operator==(rAttr));
519 return ( GetRegisteredIn() == static_cast<const SwFormatHeader&>(rAttr).GetRegisteredIn() &&
520 m_bActive == static_cast<const SwFormatHeader&>(rAttr).IsActive() );
523 SwFormatHeader* SwFormatHeader::Clone( SfxItemPool* ) const
525 return new SwFormatHeader( *this );
528 void SwFormatHeader::RegisterToFormat( SwFormat& rFormat )
530 rFormat.Add(this);
533 // Partially implemented inline in hxx
534 SwFormatFooter::SwFormatFooter( SwFrameFormat *pFooterFormat )
535 : SfxPoolItem( RES_FOOTER ),
536 SwClient( pFooterFormat ),
537 m_bActive( pFooterFormat )
541 SwFormatFooter::SwFormatFooter( const SwFormatFooter &rCpy )
542 : SfxPoolItem( RES_FOOTER ),
543 SwClient( const_cast<sw::BroadcastingModify*>(static_cast<const sw::BroadcastingModify*>(rCpy.GetRegisteredIn())) ),
544 m_bActive( rCpy.IsActive() )
548 SwFormatFooter::SwFormatFooter( bool bOn )
549 : SfxPoolItem( RES_FOOTER ),
550 SwClient( nullptr ),
551 m_bActive( bOn )
555 SwFormatFooter::~SwFormatFooter()
557 if ( GetFooterFormat() )
558 lcl_DelHFFormat( this, GetFooterFormat() );
561 void SwFormatFooter::RegisterToFormat( SwFormat& rFormat )
563 rFormat.Add(this);
566 bool SwFormatFooter::operator==( const SfxPoolItem& rAttr ) const
568 assert(SfxPoolItem::operator==(rAttr));
569 return ( GetRegisteredIn() == static_cast<const SwFormatFooter&>(rAttr).GetRegisteredIn() &&
570 m_bActive == static_cast<const SwFormatFooter&>(rAttr).IsActive() );
573 SwFormatFooter* SwFormatFooter::Clone( SfxItemPool* ) const
575 return new SwFormatFooter( *this );
578 // Partially implemented inline in hxx
579 SwFormatContent::SwFormatContent( const SwFormatContent &rCpy )
580 : SfxPoolItem( RES_CNTNT )
581 , m_oStartNode( rCpy.m_oStartNode )
585 SwFormatContent::SwFormatContent( const SwStartNode *pStartNd )
586 : SfxPoolItem( RES_CNTNT )
588 if (pStartNd)
589 m_oStartNode = *pStartNd;
592 SwFormatContent::~SwFormatContent()
596 void SwFormatContent::SetNewContentIdx( const SwNodeIndex *pIdx )
598 if (pIdx)
599 m_oStartNode = *pIdx;
600 else
601 m_oStartNode.reset();
604 bool SwFormatContent::operator==( const SfxPoolItem& rAttr ) const
606 assert(SfxPoolItem::operator==(rAttr));
607 return m_oStartNode == static_cast<const SwFormatContent&>(rAttr).m_oStartNode;
610 SwFormatContent* SwFormatContent::Clone( SfxItemPool* ) const
612 return new SwFormatContent( *this );
615 void SwFormatContent::dumpAsXml(xmlTextWriterPtr pWriter) const
617 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatContent"));
618 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
619 if (m_oStartNode)
621 (void)xmlTextWriterWriteAttribute(
622 pWriter, BAD_CAST("startNode"),
623 BAD_CAST(OString::number(sal_Int32(m_oStartNode->GetNode().GetIndex())).getStr()));
624 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("startNodePtr"), "%p",
625 &m_oStartNode->GetNode());
627 (void)xmlTextWriterEndElement(pWriter);
630 // Partially implemented inline in hxx
631 SwFormatPageDesc::SwFormatPageDesc( const SwFormatPageDesc &rCpy )
632 : SfxPoolItem( RES_PAGEDESC ),
633 SwClient( const_cast<SwPageDesc*>(rCpy.GetPageDesc()) ),
634 m_oNumOffset( rCpy.m_oNumOffset ),
635 m_pDefinedIn( nullptr )
639 SwFormatPageDesc::SwFormatPageDesc( const SwPageDesc *pDesc )
640 : SfxPoolItem( RES_PAGEDESC ),
641 SwClient( const_cast<SwPageDesc*>(pDesc) ),
642 m_pDefinedIn( nullptr )
646 SwFormatPageDesc &SwFormatPageDesc::operator=(const SwFormatPageDesc &rCpy)
648 if(this == &rCpy)
649 return *this;
651 if (rCpy.GetPageDesc())
652 RegisterToPageDesc(*const_cast<SwPageDesc*>(rCpy.GetPageDesc()));
653 m_oNumOffset = rCpy.m_oNumOffset;
654 m_pDefinedIn = nullptr;
656 return *this;
659 SwFormatPageDesc::~SwFormatPageDesc() {}
661 bool SwFormatPageDesc::KnowsPageDesc() const
663 return (GetRegisteredIn() != nullptr);
666 bool SwFormatPageDesc::operator==( const SfxPoolItem& rAttr ) const
668 assert(SfxPoolItem::operator==(rAttr));
669 return ( m_pDefinedIn == static_cast<const SwFormatPageDesc&>(rAttr).m_pDefinedIn ) &&
670 ( m_oNumOffset == static_cast<const SwFormatPageDesc&>(rAttr).m_oNumOffset ) &&
671 ( GetPageDesc() == static_cast<const SwFormatPageDesc&>(rAttr).GetPageDesc() );
674 SwFormatPageDesc* SwFormatPageDesc::Clone( SfxItemPool* ) const
676 return new SwFormatPageDesc( *this );
679 void SwFormatPageDesc::SwClientNotify(const SwModify&, const SfxHint& rHint)
681 if (const SwPageDescHint* pHint = dynamic_cast<const SwPageDescHint*>(&rHint))
683 // mba: shouldn't that be broadcasted also?
684 SwFormatPageDesc aDfltDesc(pHint->GetPageDesc());
685 SwPageDesc* pDesc = pHint->GetPageDesc();
686 const sw::BroadcastingModify* pMod = GetDefinedIn();
687 if(pMod)
689 if(auto pContentNode = dynamic_cast<const SwContentNode*>(pMod))
690 const_cast<SwContentNode*>(pContentNode)->SetAttr(aDfltDesc);
691 else if(auto pFormat = dynamic_cast<const SwFormat*>(pMod))
692 const_cast<SwFormat*>(pFormat)->SetFormatAttr( aDfltDesc );
693 else
695 SAL_WARN("sw.core", "SwFormatPageDesc registered at " << typeid(pMod).name() << ".");
696 RegisterToPageDesc(*pDesc);
699 else
700 // there could be an Undo-copy
701 RegisterToPageDesc(*pDesc);
703 else if (rHint.GetId() == SfxHintId::SwLegacyModify)
705 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
706 if(RES_OBJECTDYING == pLegacy->GetWhich())
708 m_pDefinedIn = nullptr;
709 EndListeningAll();
714 void SwFormatPageDesc::RegisterToPageDesc( SwPageDesc& rDesc )
716 rDesc.Add( this );
719 bool SwFormatPageDesc::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
721 // here we convert always!
722 nMemberId &= ~CONVERT_TWIPS;
723 bool bRet = true;
724 switch ( nMemberId )
726 case MID_PAGEDESC_PAGENUMOFFSET:
728 ::std::optional<sal_uInt16> oOffset = GetNumOffset();
729 if (oOffset)
731 rVal <<= static_cast<sal_Int16>(*oOffset);
733 else
735 rVal.clear();
738 break;
740 case MID_PAGEDESC_PAGEDESCNAME:
742 const SwPageDesc* pDesc = GetPageDesc();
743 if( pDesc )
745 OUString aString;
746 SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, SwGetPoolIdFromName::PageDesc);
747 rVal <<= aString;
749 else
750 rVal.clear();
752 break;
753 default:
754 OSL_ENSURE( false, "unknown MemberId" );
755 bRet = false;
757 return bRet;
760 bool SwFormatPageDesc::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
762 // here we convert always!
763 nMemberId &= ~CONVERT_TWIPS;
764 bool bRet = true;
765 switch ( nMemberId )
767 case MID_PAGEDESC_PAGENUMOFFSET:
769 sal_Int16 nOffset = 0;
770 if (!rVal.hasValue())
772 SetNumOffset(std::nullopt);
774 else if (rVal >>= nOffset)
775 SetNumOffset( nOffset );
776 else
777 bRet = false;
779 break;
781 case MID_PAGEDESC_PAGEDESCNAME:
782 /* Doesn't work, because the attribute doesn't need the name but a
783 * pointer to the PageDesc (it's a client of it). The pointer can
784 * only be requested from the document using the name.
786 default:
787 OSL_ENSURE( false, "unknown MemberId" );
788 bRet = false;
790 return bRet;
793 void SwFormatPageDesc::dumpAsXml(xmlTextWriterPtr pWriter) const
795 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatPageDesc"));
796 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
797 if (m_oNumOffset)
798 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("oNumOffset"), BAD_CAST(OString::number(*m_oNumOffset).getStr()));
799 else
800 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("oNumOffset"), BAD_CAST("none"));
801 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("pPageDesc"), "%p", GetPageDesc());
802 if (const SwPageDesc* pPageDesc = GetPageDesc())
803 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(pPageDesc->GetName().toUtf8().getStr()));
804 (void)xmlTextWriterEndElement(pWriter);
807 // class SwFormatCol
808 // Partially implemented inline in hxx
810 SwColumn::SwColumn() :
811 m_nWish ( 0 ),
812 m_nLeft ( 0 ),
813 m_nRight( 0 )
817 bool SwColumn::operator==( const SwColumn &rCmp ) const
819 return m_nWish == rCmp.GetWishWidth() &&
820 GetLeft() == rCmp.GetLeft() &&
821 GetRight() == rCmp.GetRight();
824 void SwColumn::dumpAsXml(xmlTextWriterPtr pWriter) const
826 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwColumn"));
827 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWish"), BAD_CAST(OString::number(m_nWish).getStr()));
828 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUpper"), BAD_CAST(OString::number(0).getStr()));
829 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLower"), BAD_CAST(OString::number(0).getStr()));
830 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeft"), BAD_CAST(OString::number(m_nLeft).getStr()));
831 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRight"), BAD_CAST(OString::number(m_nRight).getStr()));
832 (void)xmlTextWriterEndElement(pWriter);
835 SwFormatCol::SwFormatCol( const SwFormatCol& rCpy )
836 : SfxPoolItem( RES_COL ),
837 m_eLineStyle( rCpy.m_eLineStyle ),
838 m_nLineWidth( rCpy.m_nLineWidth),
839 m_aLineColor( rCpy.m_aLineColor),
840 m_nLineHeight( rCpy.GetLineHeight() ),
841 m_eAdj( rCpy.GetLineAdj() ),
842 m_nWidth( rCpy.GetWishWidth() ),
843 m_aWidthAdjustValue( rCpy.m_aWidthAdjustValue ),
844 m_bOrtho( rCpy.IsOrtho() )
846 m_aColumns.reserve(rCpy.GetNumCols());
847 for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i )
849 m_aColumns.emplace_back(rCpy.GetColumns()[i] );
853 SwFormatCol::~SwFormatCol() {}
855 SwFormatCol& SwFormatCol::operator=( const SwFormatCol& rCpy )
857 if (this != &rCpy)
859 m_eLineStyle = rCpy.m_eLineStyle;
860 m_nLineWidth = rCpy.m_nLineWidth;
861 m_aLineColor = rCpy.m_aLineColor;
862 m_nLineHeight = rCpy.GetLineHeight();
863 m_eAdj = rCpy.GetLineAdj();
864 m_nWidth = rCpy.GetWishWidth();
865 m_aWidthAdjustValue = rCpy.m_aWidthAdjustValue;
866 m_bOrtho = rCpy.IsOrtho();
868 m_aColumns.clear();
869 for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i )
871 m_aColumns.emplace_back(rCpy.GetColumns()[i] );
874 return *this;
877 SwFormatCol::SwFormatCol()
878 : SfxPoolItem( RES_COL )
879 , m_eLineStyle( SvxBorderLineStyle::NONE)
881 m_nLineWidth(0),
882 m_nLineHeight( 100 ),
883 m_eAdj( COLADJ_NONE ),
884 m_nWidth( USHRT_MAX ),
885 m_aWidthAdjustValue( 0 ),
886 m_bOrtho( true )
890 bool SwFormatCol::operator==( const SfxPoolItem& rAttr ) const
892 assert(SfxPoolItem::operator==(rAttr));
893 const SwFormatCol &rCmp = static_cast<const SwFormatCol&>(rAttr);
894 if( !(m_eLineStyle == rCmp.m_eLineStyle &&
895 m_nLineWidth == rCmp.m_nLineWidth &&
896 m_aLineColor == rCmp.m_aLineColor &&
897 m_nLineHeight == rCmp.GetLineHeight() &&
898 m_eAdj == rCmp.GetLineAdj() &&
899 m_nWidth == rCmp.GetWishWidth() &&
900 m_bOrtho == rCmp.IsOrtho() &&
901 m_aColumns.size() == rCmp.GetNumCols() &&
902 m_aWidthAdjustValue == rCmp.GetAdjustValue()
904 return false;
906 for ( size_t i = 0; i < m_aColumns.size(); ++i )
907 if ( !(m_aColumns[i] == rCmp.GetColumns()[i]) )
908 return false;
910 return true;
913 SwFormatCol* SwFormatCol::Clone( SfxItemPool* ) const
915 return new SwFormatCol( *this );
918 sal_uInt16 SwFormatCol::GetGutterWidth( bool bMin ) const
920 sal_uInt16 nRet = 0;
921 if ( m_aColumns.size() == 2 )
922 nRet = m_aColumns[0].GetRight() + m_aColumns[1].GetLeft();
923 else if ( m_aColumns.size() > 2 )
925 bool bSet = false;
926 for ( size_t i = 1; i+1 < m_aColumns.size(); ++i )
928 const sal_uInt16 nTmp = m_aColumns[i].GetRight() + m_aColumns[i+1].GetLeft();
929 if ( bSet )
931 if ( nTmp != nRet )
933 if ( !bMin )
934 return USHRT_MAX;
935 if ( nRet > nTmp )
936 nRet = nTmp;
939 else
941 bSet = true;
942 nRet = nTmp;
946 return nRet;
949 void SwFormatCol::SetGutterWidth( sal_uInt16 nNew, sal_uInt16 nAct )
951 if ( m_bOrtho )
952 Calc( nNew, nAct );
953 else
955 sal_uInt16 nHalf = nNew / 2;
956 for (size_t i = 0; i < m_aColumns.size(); ++i)
958 SwColumn &rCol = m_aColumns[i];
959 rCol.SetLeft(nHalf);
960 rCol.SetRight(nHalf);
961 if ( i == 0 )
962 rCol.SetLeft(0);
963 else if ( i+1 == m_aColumns.size() )
964 rCol.SetRight(0);
969 void SwFormatCol::Init( sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct )
971 // Deleting seems to be a bit radical on the first sight; but otherwise we
972 // have to initialize all values of the remaining SwColumns.
973 m_aColumns.clear();
974 for ( sal_uInt16 i = 0; i < nNumCols; ++i )
976 m_aColumns.emplace_back( );
978 m_bOrtho = true;
979 m_nWidth = USHRT_MAX;
980 if( nNumCols )
981 Calc( nGutterWidth, nAct );
984 void SwFormatCol::SetOrtho( bool bNew, sal_uInt16 nGutterWidth, sal_uInt16 nAct )
986 m_bOrtho = bNew;
987 if ( bNew && !m_aColumns.empty() )
988 Calc( nGutterWidth, nAct );
991 sal_uInt16 SwFormatCol::CalcColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const
993 assert(nCol < m_aColumns.size());
994 if ( m_nWidth != nAct )
996 tools::Long nW = m_aColumns[nCol].GetWishWidth();
997 nW *= nAct;
998 nW /= m_nWidth;
999 return sal_uInt16(nW);
1001 else
1002 return m_aColumns[nCol].GetWishWidth();
1005 sal_uInt16 SwFormatCol::CalcPrtColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const
1007 assert(nCol < m_aColumns.size());
1008 sal_uInt16 nRet = CalcColWidth( nCol, nAct );
1009 const SwColumn *pCol = &m_aColumns[nCol];
1010 nRet = nRet - pCol->GetLeft();
1011 nRet = nRet - pCol->GetRight();
1012 return nRet;
1015 void SwFormatCol::Calc( sal_uInt16 nGutterWidth, sal_uInt16 nAct )
1017 if (!GetNumCols())
1018 return;
1020 //First set the column widths with the current width, then calculate the
1021 //column's requested width using the requested total width.
1022 const sal_uInt16 nGutterHalf = nGutterWidth ? nGutterWidth / 2 : 0;
1024 //Width of PrtAreas is totalwidth - spacings / count
1025 sal_uInt16 nSpacings;
1026 bool bFail = o3tl::checked_multiply<sal_uInt16>(GetNumCols() - 1, nGutterWidth, nSpacings);
1027 if (bFail)
1029 SAL_WARN("sw.core", "SwFormatVertOrient::Calc: overflow");
1030 return;
1033 const sal_uInt16 nPrtWidth = (nAct - nSpacings) / GetNumCols();
1034 sal_uInt16 nAvail = nAct;
1036 //The first column is PrtWidth + (gap width / 2)
1037 const sal_uInt16 nLeftWidth = nPrtWidth + nGutterHalf;
1038 SwColumn &rFirstCol = m_aColumns.front();
1039 rFirstCol.SetWishWidth(nLeftWidth);
1040 rFirstCol.SetRight(nGutterHalf);
1041 rFirstCol.SetLeft(0);
1042 nAvail = nAvail - nLeftWidth;
1044 //Column 2 to n-1 is PrtWidth + gap width
1045 const sal_uInt16 nMidWidth = nPrtWidth + nGutterWidth;
1047 for (sal_uInt16 i = 1; i < GetNumCols()-1; ++i)
1049 SwColumn &rCol = m_aColumns[i];
1050 rCol.SetWishWidth(nMidWidth);
1051 rCol.SetLeft(nGutterHalf);
1052 rCol.SetRight(nGutterHalf);
1053 nAvail = nAvail - nMidWidth;
1056 //The last column is equivalent to the first one - to compensate rounding
1057 //errors we add the remaining space of the other columns to the last one.
1058 SwColumn &rLastCol = m_aColumns.back();
1059 rLastCol.SetWishWidth(nAvail);
1060 rLastCol.SetLeft(nGutterHalf);
1061 rLastCol.SetRight(0);
1063 assert(nAct != 0);
1064 //Convert the current width to the requested width.
1065 for (SwColumn &rCol: m_aColumns)
1067 tools::Long nTmp = rCol.GetWishWidth();
1068 nTmp *= GetWishWidth();
1069 nTmp = nAct == 0 ? nTmp : nTmp / nAct;
1070 rCol.SetWishWidth(sal_uInt16(nTmp));
1074 bool SwFormatCol::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1076 // here we convert always!
1077 nMemberId &= ~CONVERT_TWIPS;
1078 if(MID_COLUMN_SEPARATOR_LINE == nMemberId)
1080 OSL_FAIL("not implemented");
1082 else
1084 uno::Reference<text::XTextColumns> xCols(SvxXTextColumns_createInstance(),
1085 css::uno::UNO_QUERY_THROW);
1086 uno::Reference<beans::XPropertySet> xProps(xCols, css::uno::UNO_QUERY_THROW);
1088 if (GetNumCols() > 0)
1090 xCols->setColumnCount(GetNumCols());
1091 const sal_uInt16 nItemGutterWidth = GetGutterWidth();
1092 sal_Int32 nAutoDistance = IsOrtho() ? USHRT_MAX == nItemGutterWidth
1093 ? DEF_GUTTER_WIDTH
1094 : static_cast<sal_Int32>(nItemGutterWidth)
1095 : 0;
1096 nAutoDistance = convertTwipToMm100(nAutoDistance);
1097 xProps->setPropertyValue(UNO_NAME_AUTOMATIC_DISTANCE, uno::Any(nAutoDistance));
1099 if (!IsOrtho())
1101 auto aTextColumns = xCols->getColumns();
1102 text::TextColumn* pColumns = aTextColumns.getArray();
1103 const SwColumns& rCols = GetColumns();
1104 for (sal_Int32 i = 0; i < aTextColumns.getLength(); ++i)
1106 const SwColumn* pCol = &rCols[i];
1108 pColumns[i].Width = pCol->GetWishWidth();
1109 pColumns[i].LeftMargin = convertTwipToMm100(pCol->GetLeft());
1110 pColumns[i].RightMargin = convertTwipToMm100(pCol->GetRight());
1112 xCols->setColumns(aTextColumns); // sets "IsAutomatic" property to false
1115 uno::Any aVal;
1116 aVal <<= o3tl::narrowing<sal_Int32>(
1117 o3tl::convert(GetLineWidth(), o3tl::Length::twip, o3tl::Length::mm100));
1118 xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH, aVal);
1119 aVal <<= GetLineColor();
1120 xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR, aVal);
1121 aVal <<= static_cast<sal_Int32>(GetLineHeight());
1122 xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT, aVal);
1123 aVal <<= GetLineAdj() != COLADJ_NONE;
1124 xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON, aVal);
1125 sal_Int16 nStyle;
1126 switch (GetLineStyle())
1128 case SvxBorderLineStyle::SOLID:
1129 nStyle = css::text::ColumnSeparatorStyle::SOLID;
1130 break;
1131 case SvxBorderLineStyle::DOTTED:
1132 nStyle = css::text::ColumnSeparatorStyle::DOTTED;
1133 break;
1134 case SvxBorderLineStyle::DASHED:
1135 nStyle = css::text::ColumnSeparatorStyle::DASHED;
1136 break;
1137 case SvxBorderLineStyle::NONE:
1138 default:
1139 nStyle = css::text::ColumnSeparatorStyle::NONE;
1140 break;
1142 aVal <<= nStyle;
1143 xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE, aVal);
1144 style::VerticalAlignment eAlignment;
1145 switch (GetLineAdj())
1147 case COLADJ_TOP:
1148 eAlignment = style::VerticalAlignment_TOP;
1149 break;
1150 case COLADJ_BOTTOM:
1151 eAlignment = style::VerticalAlignment_BOTTOM;
1152 break;
1153 case COLADJ_CENTER:
1154 case COLADJ_NONE:
1155 default:
1156 eAlignment = style::VerticalAlignment_MIDDLE;
1158 aVal <<= eAlignment;
1159 xProps->setPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT, aVal);
1160 rVal <<= xCols;
1162 return true;
1165 bool SwFormatCol::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1167 // here we convert always!
1168 nMemberId &= ~CONVERT_TWIPS;
1169 bool bRet = false;
1170 if(MID_COLUMN_SEPARATOR_LINE == nMemberId)
1172 OSL_FAIL("not implemented");
1174 else
1176 uno::Reference< text::XTextColumns > xCols;
1177 rVal >>= xCols;
1178 if(xCols.is())
1180 uno::Sequence<text::TextColumn> aSetColumns = xCols->getColumns();
1181 const text::TextColumn* pArray = aSetColumns.getConstArray();
1182 m_aColumns.clear();
1183 //max count is 64k here - this is something the array can't do
1184 sal_uInt16 nCount = std::min( o3tl::narrowing<sal_uInt16>(aSetColumns.getLength()),
1185 sal_uInt16(0x3fff) );
1186 sal_uInt16 nWidthSum = 0;
1187 // #101224# one column is no column
1189 if(nCount > 1)
1190 for(sal_uInt16 i = 0; i < nCount; i++)
1192 SwColumn aCol;
1193 aCol.SetWishWidth(pArray[i].Width );
1194 nWidthSum = nWidthSum + pArray[i].Width;
1195 aCol.SetLeft (o3tl::toTwips(pArray[i].LeftMargin, o3tl::Length::mm100));
1196 aCol.SetRight(o3tl::toTwips(pArray[i].RightMargin, o3tl::Length::mm100));
1197 m_aColumns.insert(m_aColumns.begin() + i, aCol);
1199 bRet = true;
1200 m_nWidth = nWidthSum;
1201 m_bOrtho = false;
1203 if (uno::Reference<beans::XPropertySet> xProps{ xCols, css::uno::UNO_QUERY })
1205 xProps->getPropertyValue(UNO_NAME_IS_AUTOMATIC) >>= m_bOrtho;
1206 xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_WIDTH) >>= m_nLineWidth;
1207 m_nLineWidth = o3tl::toTwips(m_nLineWidth, o3tl::Length::mm100);
1208 xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_COLOR) >>= m_aLineColor;
1209 if (sal_Int32 nHeight;
1210 xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT) >>= nHeight)
1211 m_nLineHeight = nHeight;
1212 switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_STYLE).get<sal_Int16>())
1214 default:
1215 case css::text::ColumnSeparatorStyle::NONE:
1216 m_eLineStyle = SvxBorderLineStyle::NONE;
1217 break;
1218 case css::text::ColumnSeparatorStyle::SOLID:
1219 m_eLineStyle = SvxBorderLineStyle::SOLID;
1220 break;
1221 case css::text::ColumnSeparatorStyle::DOTTED:
1222 m_eLineStyle = SvxBorderLineStyle::DOTTED;
1223 break;
1224 case css::text::ColumnSeparatorStyle::DASHED:
1225 m_eLineStyle = SvxBorderLineStyle::DASHED;
1226 break;
1228 if (!xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_IS_ON).get<bool>())
1229 m_eAdj = COLADJ_NONE;
1230 else switch (xProps->getPropertyValue(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT).get<style::VerticalAlignment>())
1232 case style::VerticalAlignment_TOP: m_eAdj = COLADJ_TOP; break;
1233 case style::VerticalAlignment_MIDDLE: m_eAdj = COLADJ_CENTER; break;
1234 case style::VerticalAlignment_BOTTOM: m_eAdj = COLADJ_BOTTOM; break;
1235 default: OSL_ENSURE( false, "unknown alignment" ); break;
1240 return bRet;
1243 void SwFormatCol::dumpAsXml(xmlTextWriterPtr pWriter) const
1245 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatCol"));
1246 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1247 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLineStyle"), BAD_CAST(OString::number(static_cast<sal_Int16>(m_eLineStyle)).getStr()));
1248 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineWidth"), BAD_CAST(OString::number(m_nLineWidth).getStr()));
1249 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aLineColor"), BAD_CAST(m_aLineColor.AsRGBHexString().toUtf8().getStr()));
1250 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLineHeight"), BAD_CAST(OString::number(m_nLineHeight).getStr()));
1251 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eAdj"), BAD_CAST(OString::number(m_eAdj).getStr()));
1252 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth"), BAD_CAST(OString::number(m_nWidth).getStr()));
1253 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidthAdjustValue"), BAD_CAST(OString::number(m_aWidthAdjustValue).getStr()));
1254 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOrtho"), BAD_CAST(OString::boolean(m_bOrtho).getStr()));
1256 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("aColumns"));
1257 for (const SwColumn& rColumn : m_aColumns)
1258 rColumn.dumpAsXml(pWriter);
1259 (void)xmlTextWriterEndElement(pWriter);
1261 (void)xmlTextWriterEndElement(pWriter);
1264 // Partially implemented inline in hxx
1265 SwFormatSurround::SwFormatSurround( css::text::WrapTextMode eFly ) :
1266 SfxEnumItem( RES_SURROUND, eFly )
1268 m_bAnchorOnly = m_bContour = m_bOutside = false;
1271 bool SwFormatSurround::operator==( const SfxPoolItem& rAttr ) const
1273 assert(SfxPoolItem::operator==(rAttr));
1274 return ( GetValue() == static_cast<const SwFormatSurround&>(rAttr).GetValue() &&
1275 m_bAnchorOnly== static_cast<const SwFormatSurround&>(rAttr).m_bAnchorOnly &&
1276 m_bContour== static_cast<const SwFormatSurround&>(rAttr).m_bContour &&
1277 m_bOutside== static_cast<const SwFormatSurround&>(rAttr).m_bOutside );
1280 SwFormatSurround* SwFormatSurround::Clone( SfxItemPool* ) const
1282 return new SwFormatSurround( *this );
1285 sal_uInt16 SwFormatSurround::GetValueCount() const
1287 return 6;
1290 bool SwFormatSurround::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1292 // here we convert always!
1293 nMemberId &= ~CONVERT_TWIPS;
1294 bool bRet = true;
1295 switch ( nMemberId )
1297 case MID_SURROUND_SURROUNDTYPE:
1298 rVal <<= GetSurround();
1299 break;
1300 case MID_SURROUND_ANCHORONLY:
1301 rVal <<= IsAnchorOnly();
1302 break;
1303 case MID_SURROUND_CONTOUR:
1304 rVal <<= IsContour();
1305 break;
1306 case MID_SURROUND_CONTOUROUTSIDE:
1307 rVal <<= IsOutside();
1308 break;
1309 default:
1310 OSL_ENSURE( false, "unknown MemberId" );
1311 bRet = false;
1313 return bRet;
1316 bool SwFormatSurround::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1318 // here we convert always!
1319 nMemberId &= ~CONVERT_TWIPS;
1320 bool bRet = true;
1321 switch ( nMemberId )
1323 case MID_SURROUND_SURROUNDTYPE:
1325 css::text::WrapTextMode eVal = static_cast<css::text::WrapTextMode>(SWUnoHelper::GetEnumAsInt32( rVal ));
1326 if( eVal >= css::text::WrapTextMode_NONE && eVal <= css::text::WrapTextMode_RIGHT )
1327 SetValue( eVal );
1328 else {
1329 //exception
1333 break;
1335 case MID_SURROUND_ANCHORONLY:
1336 SetAnchorOnly( *o3tl::doAccess<bool>(rVal) );
1337 break;
1338 case MID_SURROUND_CONTOUR:
1339 SetContour( *o3tl::doAccess<bool>(rVal) );
1340 break;
1341 case MID_SURROUND_CONTOUROUTSIDE:
1342 SetOutside( *o3tl::doAccess<bool>(rVal) );
1343 break;
1344 default:
1345 OSL_ENSURE( false, "unknown MemberId" );
1346 bRet = false;
1348 return bRet;
1351 void SwFormatSurround::dumpAsXml(xmlTextWriterPtr pWriter) const
1353 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatSurround"));
1354 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1355 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(static_cast<sal_Int32>(GetValue())).getStr()));
1357 OUString aPresentation;
1358 IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
1359 GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, MapUnit::Map100thMM, aPresentation, aIntlWrapper);
1360 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(aPresentation.toUtf8().getStr()));
1362 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bAnchorOnly"), BAD_CAST(OString::boolean(m_bAnchorOnly).getStr()));
1363 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bContour"), BAD_CAST(OString::boolean(m_bContour).getStr()));
1364 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bOutside"), BAD_CAST(OString::boolean(m_bOutside).getStr()));
1366 (void)xmlTextWriterEndElement(pWriter);
1369 // Partially implemented inline in hxx
1370 SwFormatVertOrient::SwFormatVertOrient( SwTwips nY, sal_Int16 eVert,
1371 sal_Int16 eRel )
1372 : SfxPoolItem( RES_VERT_ORIENT ),
1373 m_nYPos( nY ),
1374 m_eOrient( eVert ),
1375 m_eRelation( eRel )
1378 bool SwFormatVertOrient::operator==( const SfxPoolItem& rAttr ) const
1380 assert(SfxPoolItem::operator==(rAttr));
1381 return ( m_nYPos == static_cast<const SwFormatVertOrient&>(rAttr).m_nYPos &&
1382 m_eOrient == static_cast<const SwFormatVertOrient&>(rAttr).m_eOrient &&
1383 m_eRelation == static_cast<const SwFormatVertOrient&>(rAttr).m_eRelation );
1386 SwFormatVertOrient* SwFormatVertOrient::Clone( SfxItemPool* ) const
1388 return new SwFormatVertOrient( *this );
1391 bool SwFormatVertOrient::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1393 // here we convert always!
1394 nMemberId &= ~CONVERT_TWIPS;
1395 bool bRet = true;
1396 switch ( nMemberId )
1398 case MID_VERTORIENT_ORIENT:
1400 rVal <<= m_eOrient;
1402 break;
1403 case MID_VERTORIENT_RELATION:
1404 rVal <<= m_eRelation;
1405 break;
1406 case MID_VERTORIENT_POSITION:
1407 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(GetPos()));
1408 break;
1409 default:
1410 OSL_ENSURE( false, "unknown MemberId" );
1411 bRet = false;
1413 return bRet;
1416 bool SwFormatVertOrient::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1418 bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
1419 nMemberId &= ~CONVERT_TWIPS;
1420 bool bRet = true;
1421 switch ( nMemberId )
1423 case MID_VERTORIENT_ORIENT:
1425 sal_uInt16 nVal = text::VertOrientation::NONE;
1426 rVal >>= nVal;
1427 m_eOrient = nVal;
1429 break;
1430 case MID_VERTORIENT_RELATION:
1432 m_eRelation = lcl_IntToRelation(rVal);
1434 break;
1435 case MID_VERTORIENT_POSITION:
1437 sal_Int32 nVal = 0;
1438 rVal >>= nVal;
1439 if(bConvert)
1440 nVal = o3tl::toTwips(nVal, o3tl::Length::mm100);
1441 SetPos( nVal );
1443 break;
1444 default:
1445 OSL_ENSURE( false, "unknown MemberId" );
1446 bRet = false;
1448 return bRet;
1451 void SwFormatVertOrient::dumpAsXml(xmlTextWriterPtr pWriter) const
1453 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatVertOrient"));
1454 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1455 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nYPos"), BAD_CAST(OString::number(m_nYPos).getStr()));
1456 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eOrient"), BAD_CAST(OString::number(m_eOrient).getStr()));
1457 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eRelation"), BAD_CAST(OString::number(m_eRelation).getStr()));
1458 (void)xmlTextWriterEndElement(pWriter);
1461 // Partially implemented inline in hxx
1462 SwFormatHoriOrient::SwFormatHoriOrient( SwTwips nX, sal_Int16 eHori,
1463 sal_Int16 eRel, bool bPos )
1464 : SfxPoolItem( RES_HORI_ORIENT ),
1465 m_nXPos( nX ),
1466 m_eOrient( eHori ),
1467 m_eRelation( eRel ),
1468 m_bPosToggle( bPos )
1471 bool SwFormatHoriOrient::operator==( const SfxPoolItem& rAttr ) const
1473 assert(SfxPoolItem::operator==(rAttr));
1474 return ( m_nXPos == static_cast<const SwFormatHoriOrient&>(rAttr).m_nXPos &&
1475 m_eOrient == static_cast<const SwFormatHoriOrient&>(rAttr).m_eOrient &&
1476 m_eRelation == static_cast<const SwFormatHoriOrient&>(rAttr).m_eRelation &&
1477 m_bPosToggle == static_cast<const SwFormatHoriOrient&>(rAttr).m_bPosToggle );
1480 SwFormatHoriOrient* SwFormatHoriOrient::Clone( SfxItemPool* ) const
1482 return new SwFormatHoriOrient( *this );
1485 bool SwFormatHoriOrient::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1487 // here we convert always!
1488 nMemberId &= ~CONVERT_TWIPS;
1489 bool bRet = true;
1490 switch ( nMemberId )
1492 case MID_HORIORIENT_ORIENT:
1494 rVal <<= m_eOrient;
1496 break;
1497 case MID_HORIORIENT_RELATION:
1498 rVal <<= m_eRelation;
1499 break;
1500 case MID_HORIORIENT_POSITION:
1501 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(GetPos()));
1502 break;
1503 case MID_HORIORIENT_PAGETOGGLE:
1504 rVal <<= IsPosToggle();
1505 break;
1506 default:
1507 OSL_ENSURE( false, "unknown MemberId" );
1508 bRet = false;
1510 return bRet;
1513 bool SwFormatHoriOrient::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1515 bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
1516 nMemberId &= ~CONVERT_TWIPS;
1517 bool bRet = true;
1518 switch ( nMemberId )
1520 case MID_HORIORIENT_ORIENT:
1522 sal_Int16 nVal = text::HoriOrientation::NONE;
1523 rVal >>= nVal;
1524 m_eOrient = nVal;
1526 break;
1527 case MID_HORIORIENT_RELATION:
1529 m_eRelation = lcl_IntToRelation(rVal);
1531 break;
1532 case MID_HORIORIENT_POSITION:
1534 sal_Int32 nVal = 0;
1535 if(!(rVal >>= nVal))
1536 bRet = false;
1537 if(bConvert)
1538 nVal = o3tl::toTwips(nVal, o3tl::Length::mm100);
1539 SetPos( nVal );
1541 break;
1542 case MID_HORIORIENT_PAGETOGGLE:
1543 SetPosToggle( *o3tl::doAccess<bool>(rVal));
1544 break;
1545 default:
1546 OSL_ENSURE( false, "unknown MemberId" );
1547 bRet = false;
1549 return bRet;
1552 void SwFormatHoriOrient::dumpAsXml(xmlTextWriterPtr pWriter) const
1554 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatHoriOrient"));
1555 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1556 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nXPos"), BAD_CAST(OString::number(m_nXPos).getStr()));
1557 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eOrient"), BAD_CAST(OString::number(m_eOrient).getStr()));
1558 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eRelation"), BAD_CAST(OString::number(m_eRelation).getStr()));
1559 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bPosToggle"), BAD_CAST(OString::boolean(m_bPosToggle).getStr()));
1560 (void)xmlTextWriterEndElement(pWriter);
1563 SwFormatAnchor::SwFormatAnchor( RndStdIds nRnd, sal_uInt16 nPage )
1564 : SfxPoolItem( RES_ANCHOR ),
1565 m_eAnchorId( nRnd ),
1566 m_nPageNumber( nPage ),
1567 // OD 2004-05-05 #i28701# - get always new increased order number
1568 m_nOrder( ++s_nOrderCounter )
1570 assert( m_eAnchorId == RndStdIds::FLY_AT_PARA
1571 || m_eAnchorId == RndStdIds::FLY_AS_CHAR
1572 || m_eAnchorId == RndStdIds::FLY_AT_PAGE
1573 || m_eAnchorId == RndStdIds::FLY_AT_FLY
1574 || m_eAnchorId == RndStdIds::FLY_AT_CHAR);
1575 // only FLY_AT_PAGE should have a valid page
1576 assert( m_eAnchorId == RndStdIds::FLY_AT_PAGE || nPage == 0 );
1579 SwFormatAnchor::SwFormatAnchor( const SwFormatAnchor &rCpy )
1580 : SfxPoolItem( RES_ANCHOR )
1581 , m_oContentAnchor( rCpy.m_oContentAnchor )
1582 , m_eAnchorId( rCpy.m_eAnchorId )
1583 , m_nPageNumber( rCpy.m_nPageNumber )
1584 // OD 2004-05-05 #i28701# - get always new increased order number
1585 , m_nOrder( ++s_nOrderCounter )
1589 SwFormatAnchor::~SwFormatAnchor()
1593 void SwFormatAnchor::SetAnchor( const SwPosition *pPos )
1595 if (!pPos)
1597 m_oContentAnchor.reset();
1598 return;
1600 // anchor only to paragraphs, or start nodes in case of RndStdIds::FLY_AT_FLY
1601 // also allow table node, this is used when a table is selected and is converted to a frame by the UI
1602 assert((RndStdIds::FLY_AT_FLY == m_eAnchorId && pPos->GetNode().GetStartNode())
1603 || (RndStdIds::FLY_AT_PARA == m_eAnchorId && pPos->GetNode().GetTableNode())
1604 || pPos->GetNode().GetTextNode());
1605 // verify that the SwPosition being passed to us is not screwy
1606 assert(!pPos->nContent.GetContentNode()
1607 || &pPos->nNode.GetNode() == pPos->nContent.GetContentNode());
1608 m_oContentAnchor.emplace(*pPos);
1609 // Flys anchored AT paragraph should not point into the paragraph content
1610 if ((RndStdIds::FLY_AT_PARA == m_eAnchorId) || (RndStdIds::FLY_AT_FLY == m_eAnchorId))
1611 m_oContentAnchor->nContent.Assign( nullptr, 0 );
1614 SwNode* SwFormatAnchor::GetAnchorNode() const
1616 if (!m_oContentAnchor)
1617 return nullptr;
1618 if (auto pCntNd = m_oContentAnchor->nContent.GetContentNode())
1619 return const_cast<SwContentNode*>(pCntNd);
1620 return &m_oContentAnchor->nNode.GetNode();
1623 SwContentNode* SwFormatAnchor::GetAnchorContentNode() const
1625 SwNode* pAnchorNode = GetAnchorNode();
1626 if (pAnchorNode)
1627 return pAnchorNode->GetContentNode();
1628 return nullptr;
1631 sal_Int32 SwFormatAnchor::GetAnchorContentOffset() const
1633 if (!m_oContentAnchor)
1634 return 0;
1635 if (m_oContentAnchor->nContent.GetContentNode())
1636 return m_oContentAnchor->nContent.GetIndex();
1637 return 0;
1640 SwFormatAnchor& SwFormatAnchor::operator=(const SwFormatAnchor& rAnchor)
1642 if (this != &rAnchor)
1644 m_eAnchorId = rAnchor.m_eAnchorId;
1645 m_nPageNumber = rAnchor.m_nPageNumber;
1646 // OD 2004-05-05 #i28701# - get always new increased order number
1647 m_nOrder = ++s_nOrderCounter;
1648 m_oContentAnchor = rAnchor.m_oContentAnchor;
1650 return *this;
1653 bool SwFormatAnchor::operator==( const SfxPoolItem& rAttr ) const
1655 assert(SfxPoolItem::operator==(rAttr));
1656 SwFormatAnchor const& rFormatAnchor(static_cast<SwFormatAnchor const&>(rAttr));
1657 // OD 2004-05-05 #i28701# - Note: <mnOrder> hasn't to be considered.
1658 return ( m_eAnchorId == rFormatAnchor.m_eAnchorId &&
1659 m_nPageNumber == rFormatAnchor.m_nPageNumber &&
1660 // compare anchor: either both do not point into a textnode or
1661 // both do (valid m_oContentAnchor) and the positions are equal
1662 (m_oContentAnchor == rFormatAnchor.m_oContentAnchor) );
1665 SwFormatAnchor* SwFormatAnchor::Clone( SfxItemPool* ) const
1667 return new SwFormatAnchor( *this );
1670 // OD 2004-05-05 #i28701#
1671 sal_uInt32 SwFormatAnchor::s_nOrderCounter = 0;
1673 // OD 2004-05-05 #i28701#
1675 bool SwFormatAnchor::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1677 // here we convert always!
1678 nMemberId &= ~CONVERT_TWIPS;
1679 bool bRet = true;
1680 switch ( nMemberId )
1682 case MID_ANCHOR_ANCHORTYPE:
1684 text::TextContentAnchorType eRet;
1685 switch (m_eAnchorId)
1687 case RndStdIds::FLY_AT_CHAR:
1688 eRet = text::TextContentAnchorType_AT_CHARACTER;
1689 break;
1690 case RndStdIds::FLY_AT_PAGE:
1691 eRet = text::TextContentAnchorType_AT_PAGE;
1692 break;
1693 case RndStdIds::FLY_AT_FLY:
1694 eRet = text::TextContentAnchorType_AT_FRAME;
1695 break;
1696 case RndStdIds::FLY_AS_CHAR:
1697 eRet = text::TextContentAnchorType_AS_CHARACTER;
1698 break;
1699 //case RndStdIds::FLY_AT_PARA:
1700 default:
1701 eRet = text::TextContentAnchorType_AT_PARAGRAPH;
1703 rVal <<= eRet;
1704 break;
1705 case MID_ANCHOR_PAGENUM:
1706 rVal <<= static_cast<sal_Int16>(GetPageNum());
1707 break;
1708 case MID_ANCHOR_ANCHORFRAME:
1710 if (m_oContentAnchor && RndStdIds::FLY_AT_FLY == m_eAnchorId)
1712 SwFrameFormat* pFormat = m_oContentAnchor->GetNode().GetFlyFormat();
1713 if(pFormat)
1715 uno::Reference<text::XTextFrame> const xRet(
1716 SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat));
1717 rVal <<= xRet;
1721 break;
1722 default:
1723 OSL_ENSURE( false, "unknown MemberId" );
1724 bRet = false;
1726 return bRet;
1729 bool SwFormatAnchor::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1731 // here we convert always!
1732 nMemberId &= ~CONVERT_TWIPS;
1733 bool bRet = true;
1734 switch ( nMemberId )
1736 case MID_ANCHOR_ANCHORTYPE:
1738 RndStdIds eAnchor;
1739 switch( static_cast<text::TextContentAnchorType>(SWUnoHelper::GetEnumAsInt32( rVal )) )
1741 case text::TextContentAnchorType_AS_CHARACTER:
1742 eAnchor = RndStdIds::FLY_AS_CHAR;
1743 break;
1744 case text::TextContentAnchorType_AT_PAGE:
1745 eAnchor = RndStdIds::FLY_AT_PAGE;
1746 if( GetPageNum() > 0 )
1748 // If the anchor type is page and a valid page number
1749 // has been set, the content position isn't required
1750 // any longer.
1751 m_oContentAnchor.reset();
1753 break;
1754 case text::TextContentAnchorType_AT_FRAME:
1755 eAnchor = RndStdIds::FLY_AT_FLY;
1756 break;
1757 case text::TextContentAnchorType_AT_CHARACTER:
1758 eAnchor = RndStdIds::FLY_AT_CHAR;
1759 break;
1760 case text::TextContentAnchorType_AT_PARAGRAPH:
1761 eAnchor = RndStdIds::FLY_AT_PARA;
1762 break;
1763 default:
1764 eAnchor = RndStdIds::FLY_AT_PARA; // just to keep some compilers happy
1765 assert(false);
1767 SetType( eAnchor );
1769 break;
1770 case MID_ANCHOR_PAGENUM:
1772 sal_Int16 nVal = 0;
1773 if((rVal >>= nVal) && nVal > 0)
1775 if (RndStdIds::FLY_AT_PAGE == m_eAnchorId)
1777 SetPageNum( nVal );
1778 // If the anchor type is page and a valid page number
1779 // is set, the content position has to be deleted to not
1780 // confuse the layout (frmtool.cxx). However, if the
1781 // anchor type is not page, any content position will
1782 // be kept.
1783 m_oContentAnchor.reset();
1785 else
1787 assert(false && "cannot set page number on this anchor type");
1788 bRet = false;
1791 else
1792 bRet = false;
1794 break;
1795 case MID_ANCHOR_ANCHORFRAME:
1796 //no break here!;
1797 default:
1798 OSL_ENSURE( false, "unknown MemberId" );
1799 bRet = false;
1801 return bRet;
1804 void SwFormatAnchor::dumpAsXml(xmlTextWriterPtr pWriter) const
1806 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatAnchor"));
1807 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1809 if (m_oContentAnchor)
1811 std::stringstream aContentAnchor;
1812 aContentAnchor << *m_oContentAnchor;
1813 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_pContentAnchor"), BAD_CAST(aContentAnchor.str().c_str()));
1815 else
1816 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_pContentAnchor"), BAD_CAST("(nil)"));
1817 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_eAnchorType"), BAD_CAST(OString::number(static_cast<int>(m_eAnchorId)).getStr()));
1818 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPageNumber"), BAD_CAST(OString::number(m_nPageNumber).getStr()));
1819 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nOrder"), BAD_CAST(OString::number(m_nOrder).getStr()));
1820 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("s_nOrderCounter"), BAD_CAST(OString::number(s_nOrderCounter).getStr()));
1821 OUString aPresentation;
1822 IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
1823 GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, MapUnit::Map100thMM, aPresentation, aIntlWrapper);
1824 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(aPresentation.toUtf8().getStr()));
1826 (void)xmlTextWriterEndElement(pWriter);
1829 // Partially implemented inline in hxx
1830 SwFormatURL::SwFormatURL() :
1831 SfxPoolItem( RES_URL ),
1832 m_bIsServerMap( false )
1836 SwFormatURL::SwFormatURL( const SwFormatURL &rURL) :
1837 SfxPoolItem( RES_URL ),
1838 m_sTargetFrameName( rURL.GetTargetFrameName() ),
1839 m_sURL( rURL.GetURL() ),
1840 m_sName( rURL.GetName() ),
1841 m_bIsServerMap( rURL.IsServerMap() )
1843 if (rURL.GetMap())
1844 m_pMap.reset( new ImageMap( *rURL.GetMap() ) );
1847 SwFormatURL::~SwFormatURL()
1851 bool SwFormatURL::operator==( const SfxPoolItem &rAttr ) const
1853 assert(SfxPoolItem::operator==(rAttr));
1854 const SwFormatURL &rCmp = static_cast<const SwFormatURL&>(rAttr);
1855 bool bRet = m_bIsServerMap == rCmp.IsServerMap() &&
1856 m_sURL == rCmp.GetURL() &&
1857 m_sTargetFrameName == rCmp.GetTargetFrameName() &&
1858 m_sName == rCmp.GetName();
1859 if ( bRet )
1861 if ( m_pMap && rCmp.GetMap() )
1862 bRet = *m_pMap == *rCmp.GetMap();
1863 else
1864 bRet = m_pMap.get() == rCmp.GetMap();
1866 return bRet;
1869 SwFormatURL* SwFormatURL::Clone( SfxItemPool* ) const
1871 return new SwFormatURL( *this );
1874 void SwFormatURL::SetURL(const OUString &rURL, bool bServerMap)
1876 m_sURL = rURL;
1877 m_bIsServerMap = bServerMap;
1880 void SwFormatURL::SetMap( const ImageMap *pM )
1882 m_pMap.reset( pM ? new ImageMap( *pM ) : nullptr);
1885 bool SwFormatURL::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1887 // here we convert always!
1888 nMemberId &= ~CONVERT_TWIPS;
1889 bool bRet = true;
1890 switch ( nMemberId )
1892 case MID_URL_URL:
1893 rVal <<= GetURL();
1894 break;
1895 case MID_URL_TARGET:
1896 rVal <<= GetTargetFrameName();
1897 break;
1898 case MID_URL_HYPERLINKNAME:
1899 rVal <<= GetName();
1900 break;
1901 case MID_URL_CLIENTMAP:
1903 uno::Reference< uno::XInterface > xInt;
1904 if(m_pMap)
1906 xInt = SvUnoImageMap_createInstance( *m_pMap, sw_GetSupportedMacroItems() );
1908 else
1910 ImageMap aEmptyMap;
1911 xInt = SvUnoImageMap_createInstance( aEmptyMap, sw_GetSupportedMacroItems() );
1913 uno::Reference< container::XIndexContainer > xCont(xInt, uno::UNO_QUERY);
1914 rVal <<= xCont;
1916 break;
1917 case MID_URL_SERVERMAP:
1918 rVal <<= IsServerMap();
1919 break;
1920 default:
1921 OSL_ENSURE( false, "unknown MemberId" );
1922 bRet = false;
1924 return bRet;
1927 bool SwFormatURL::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1929 // here we convert always!
1930 nMemberId &= ~CONVERT_TWIPS;
1931 bool bRet = true;
1932 switch ( nMemberId )
1934 case MID_URL_URL:
1936 OUString sTmp;
1937 rVal >>= sTmp;
1938 SetURL( sTmp, m_bIsServerMap );
1940 break;
1941 case MID_URL_TARGET:
1943 OUString sTmp;
1944 rVal >>= sTmp;
1945 SetTargetFrameName( sTmp );
1947 break;
1948 case MID_URL_HYPERLINKNAME:
1950 OUString sTmp;
1951 rVal >>= sTmp;
1952 SetName( sTmp );
1954 break;
1955 case MID_URL_CLIENTMAP:
1957 uno::Reference<container::XIndexContainer> xCont;
1958 if(!rVal.hasValue())
1959 m_pMap.reset();
1960 else if(rVal >>= xCont)
1962 if(!m_pMap)
1963 m_pMap.reset(new ImageMap);
1964 bRet = SvUnoImageMap_fillImageMap( xCont, *m_pMap );
1966 else
1967 bRet = false;
1969 break;
1970 case MID_URL_SERVERMAP:
1971 m_bIsServerMap = *o3tl::doAccess<bool>(rVal);
1972 break;
1973 default:
1974 OSL_ENSURE( false, "unknown MemberId" );
1975 bRet = false;
1977 return bRet;
1980 SwFormatEditInReadonly* SwFormatEditInReadonly::Clone( SfxItemPool* ) const
1982 return new SwFormatEditInReadonly( *this );
1985 SwFormatLayoutSplit* SwFormatLayoutSplit::Clone( SfxItemPool* ) const
1987 return new SwFormatLayoutSplit( *this );
1990 SwFormatRowSplit* SwFormatRowSplit::Clone( SfxItemPool* ) const
1992 return new SwFormatRowSplit( *this );
1995 SwFormatNoBalancedColumns* SwFormatNoBalancedColumns::Clone( SfxItemPool* ) const
1997 return new SwFormatNoBalancedColumns( *this );
2000 void SwFormatNoBalancedColumns::dumpAsXml(xmlTextWriterPtr pWriter) const
2002 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatNoBalancedColumns"));
2003 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
2004 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::boolean(GetValue()).getStr()));
2005 (void)xmlTextWriterEndElement(pWriter);
2008 // class SwFormatFootnoteEndAtTextEnd
2010 sal_uInt16 SwFormatFootnoteEndAtTextEnd::GetValueCount() const
2012 return sal_uInt16( FTNEND_ATTXTEND_END );
2015 SwFormatFootnoteEndAtTextEnd& SwFormatFootnoteEndAtTextEnd::operator=(
2016 const SwFormatFootnoteEndAtTextEnd& rAttr )
2018 SfxEnumItem::SetValue( rAttr.GetValue() );
2019 m_aFormat = rAttr.m_aFormat;
2020 m_nOffset = rAttr.m_nOffset;
2021 m_sPrefix = rAttr.m_sPrefix;
2022 m_sSuffix = rAttr.m_sSuffix;
2023 return *this;
2026 bool SwFormatFootnoteEndAtTextEnd::operator==( const SfxPoolItem& rItem ) const
2028 const SwFormatFootnoteEndAtTextEnd& rAttr = static_cast<const SwFormatFootnoteEndAtTextEnd&>(rItem);
2029 return SfxEnumItem::operator==( rItem ) &&
2030 m_aFormat.GetNumberingType() == rAttr.m_aFormat.GetNumberingType() &&
2031 m_nOffset == rAttr.m_nOffset &&
2032 m_sPrefix == rAttr.m_sPrefix &&
2033 m_sSuffix == rAttr.m_sSuffix;
2036 bool SwFormatFootnoteEndAtTextEnd::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2038 nMemberId &= ~CONVERT_TWIPS;
2039 switch(nMemberId)
2041 case MID_COLLECT :
2042 rVal <<= GetValue() >= FTNEND_ATTXTEND;
2043 break;
2044 case MID_RESTART_NUM :
2045 rVal <<= GetValue() >= FTNEND_ATTXTEND_OWNNUMSEQ;
2046 break;
2047 case MID_NUM_START_AT: rVal <<= static_cast<sal_Int16>(m_nOffset); break;
2048 case MID_OWN_NUM :
2049 rVal <<= GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT;
2050 break;
2051 case MID_NUM_TYPE : rVal <<= static_cast<sal_Int16>(m_aFormat.GetNumberingType()); break;
2052 case MID_PREFIX : rVal <<= m_sPrefix; break;
2053 case MID_SUFFIX : rVal <<= m_sSuffix; break;
2054 default: return false;
2056 return true;
2059 bool SwFormatFootnoteEndAtTextEnd::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2061 bool bRet = true;
2062 nMemberId &= ~CONVERT_TWIPS;
2063 switch(nMemberId)
2065 case MID_COLLECT :
2067 bool bVal = *o3tl::doAccess<bool>(rVal);
2068 if(!bVal && GetValue() >= FTNEND_ATTXTEND)
2069 SetValue(FTNEND_ATPGORDOCEND);
2070 else if(bVal && GetValue() < FTNEND_ATTXTEND)
2071 SetValue(FTNEND_ATTXTEND);
2073 break;
2074 case MID_RESTART_NUM :
2076 bool bVal = *o3tl::doAccess<bool>(rVal);
2077 if(!bVal && GetValue() >= FTNEND_ATTXTEND_OWNNUMSEQ)
2078 SetValue(FTNEND_ATTXTEND);
2079 else if(bVal && GetValue() < FTNEND_ATTXTEND_OWNNUMSEQ)
2080 SetValue(FTNEND_ATTXTEND_OWNNUMSEQ);
2082 break;
2083 case MID_NUM_START_AT:
2085 sal_Int16 nVal = 0;
2086 rVal >>= nVal;
2087 if(nVal >= 0)
2088 m_nOffset = nVal;
2089 else
2090 bRet = false;
2092 break;
2093 case MID_OWN_NUM :
2095 bool bVal = *o3tl::doAccess<bool>(rVal);
2096 if(!bVal && GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT)
2097 SetValue(FTNEND_ATTXTEND_OWNNUMSEQ);
2098 else if(bVal && GetValue() < FTNEND_ATTXTEND_OWNNUMANDFMT)
2099 SetValue(FTNEND_ATTXTEND_OWNNUMANDFMT);
2101 break;
2102 case MID_NUM_TYPE :
2104 sal_Int16 nVal = 0;
2105 rVal >>= nVal;
2106 if(nVal >= 0 &&
2107 (nVal <= SVX_NUM_ARABIC ||
2108 SVX_NUM_CHARS_UPPER_LETTER_N == nVal ||
2109 SVX_NUM_CHARS_LOWER_LETTER_N == nVal ))
2110 m_aFormat.SetNumberingType(static_cast<SvxNumType>(nVal));
2111 else
2112 bRet = false;
2114 break;
2115 case MID_PREFIX :
2117 OUString sVal; rVal >>= sVal;
2118 m_sPrefix = sVal;
2120 break;
2121 case MID_SUFFIX :
2123 OUString sVal; rVal >>= sVal;
2124 m_sSuffix = sVal;
2126 break;
2127 default: bRet = false;
2129 return bRet;
2132 // class SwFormatFootnoteAtTextEnd
2134 SwFormatFootnoteAtTextEnd* SwFormatFootnoteAtTextEnd::Clone( SfxItemPool* ) const
2136 return new SwFormatFootnoteAtTextEnd(*this);
2139 // class SwFormatEndAtTextEnd
2141 SwFormatEndAtTextEnd* SwFormatEndAtTextEnd::Clone( SfxItemPool* ) const
2143 return new SwFormatEndAtTextEnd(*this);
2146 //class SwFormatChain
2148 bool SwFormatChain::operator==( const SfxPoolItem &rAttr ) const
2150 assert(SfxPoolItem::operator==(rAttr));
2152 return GetPrev() == static_cast<const SwFormatChain&>(rAttr).GetPrev() &&
2153 GetNext() == static_cast<const SwFormatChain&>(rAttr).GetNext();
2156 SwFormatChain::SwFormatChain( const SwFormatChain &rCpy ) :
2157 SfxPoolItem( RES_CHAIN )
2159 SetPrev( rCpy.GetPrev() );
2160 SetNext( rCpy.GetNext() );
2163 SwFormatChain* SwFormatChain::Clone( SfxItemPool* ) const
2165 SwFormatChain *pRet = new SwFormatChain;
2166 pRet->SetPrev( GetPrev() );
2167 pRet->SetNext( GetNext() );
2168 return pRet;
2171 void SwFormatChain::SetPrev( SwFlyFrameFormat *pFormat )
2173 if ( pFormat )
2174 pFormat->Add( &m_aPrev );
2175 else
2176 m_aPrev.EndListeningAll();
2179 void SwFormatChain::SetNext( SwFlyFrameFormat *pFormat )
2181 if ( pFormat )
2182 pFormat->Add( &m_aNext );
2183 else
2184 m_aNext.EndListeningAll();
2187 bool SwFormatChain::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2189 // here we convert always!
2190 nMemberId &= ~CONVERT_TWIPS;
2191 bool bRet = true;
2192 OUString aRet;
2193 switch ( nMemberId )
2195 case MID_CHAIN_PREVNAME:
2196 if ( GetPrev() )
2197 aRet = GetPrev()->GetName();
2198 break;
2199 case MID_CHAIN_NEXTNAME:
2200 if ( GetNext() )
2201 aRet = GetNext()->GetName();
2202 break;
2203 default:
2204 OSL_ENSURE( false, "unknown MemberId" );
2205 bRet = false;
2207 rVal <<= aRet;
2208 return bRet;
2211 SwFormatLineNumber::SwFormatLineNumber() :
2212 SfxPoolItem( RES_LINENUMBER )
2214 m_nStartValue = 0;
2215 m_bCountLines = true;
2218 SwFormatLineNumber::~SwFormatLineNumber()
2222 bool SwFormatLineNumber::operator==( const SfxPoolItem &rAttr ) const
2224 assert(SfxPoolItem::operator==(rAttr));
2226 return m_nStartValue == static_cast<const SwFormatLineNumber&>(rAttr).GetStartValue() &&
2227 m_bCountLines == static_cast<const SwFormatLineNumber&>(rAttr).IsCount();
2230 SwFormatLineNumber* SwFormatLineNumber::Clone( SfxItemPool* ) const
2232 return new SwFormatLineNumber( *this );
2235 bool SwFormatLineNumber::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2237 // here we convert always!
2238 nMemberId &= ~CONVERT_TWIPS;
2239 bool bRet = true;
2240 switch ( nMemberId )
2242 case MID_LINENUMBER_COUNT:
2243 rVal <<= IsCount();
2244 break;
2245 case MID_LINENUMBER_STARTVALUE:
2246 rVal <<= static_cast<sal_Int32>(GetStartValue());
2247 break;
2248 default:
2249 OSL_ENSURE( false, "unknown MemberId" );
2250 bRet = false;
2252 return bRet;
2255 bool SwFormatLineNumber::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2257 // here we convert always!
2258 nMemberId &= ~CONVERT_TWIPS;
2259 bool bRet = true;
2260 switch ( nMemberId )
2262 case MID_LINENUMBER_COUNT:
2263 SetCountLines( *o3tl::doAccess<bool>(rVal) );
2264 break;
2265 case MID_LINENUMBER_STARTVALUE:
2267 sal_Int32 nVal = 0;
2268 if(rVal >>= nVal)
2269 SetStartValue( nVal );
2270 else
2271 bRet = false;
2273 break;
2274 default:
2275 OSL_ENSURE( false, "unknown MemberId" );
2276 bRet = false;
2278 return bRet;
2281 SwTextGridItem::SwTextGridItem()
2282 : SfxPoolItem( RES_TEXTGRID ), m_aColor( COL_LIGHTGRAY ), m_nLines( 20 )
2283 , m_nBaseHeight( 400 ), m_nRubyHeight( 200 ), m_eGridType( GRID_NONE )
2284 , m_bRubyTextBelow( false ), m_bPrintGrid( true ), m_bDisplayGrid( true )
2285 , m_nBaseWidth(400), m_bSnapToChars( true ), m_bSquaredMode(true)
2289 SwTextGridItem::~SwTextGridItem()
2293 bool SwTextGridItem::operator==( const SfxPoolItem& rAttr ) const
2295 assert(SfxPoolItem::operator==(rAttr));
2296 SwTextGridItem const& rOther(static_cast<SwTextGridItem const&>(rAttr));
2297 return m_eGridType == rOther.GetGridType()
2298 && m_nLines == rOther.GetLines()
2299 && m_nBaseHeight == rOther.GetBaseHeight()
2300 && m_nRubyHeight == rOther.GetRubyHeight()
2301 && m_bRubyTextBelow == rOther.GetRubyTextBelow()
2302 && m_bDisplayGrid == rOther.GetDisplayGrid()
2303 && m_bPrintGrid == rOther.GetPrintGrid()
2304 && m_aColor == rOther.GetColor()
2305 && m_nBaseWidth == rOther.GetBaseWidth()
2306 && m_bSnapToChars == rOther.GetSnapToChars()
2307 && m_bSquaredMode == rOther.GetSquaredMode();
2310 SwTextGridItem* SwTextGridItem::Clone( SfxItemPool* ) const
2312 return new SwTextGridItem( *this );
2315 bool SwTextGridItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2317 bool bRet = true;
2319 switch( nMemberId & ~CONVERT_TWIPS )
2321 case MID_GRID_COLOR:
2322 rVal <<= GetColor();
2323 break;
2324 case MID_GRID_LINES:
2325 rVal <<= GetLines();
2326 break;
2327 case MID_GRID_RUBY_BELOW:
2328 rVal <<= m_bRubyTextBelow;
2329 break;
2330 case MID_GRID_PRINT:
2331 rVal <<= m_bPrintGrid;
2332 break;
2333 case MID_GRID_DISPLAY:
2334 rVal <<= m_bDisplayGrid;
2335 break;
2336 case MID_GRID_BASEHEIGHT:
2337 OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
2338 "This value needs TWIPS-MM100 conversion" );
2339 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(m_nBaseHeight));
2340 break;
2341 case MID_GRID_BASEWIDTH:
2342 OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
2343 "This value needs TWIPS-MM100 conversion" );
2344 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(m_nBaseWidth));
2345 break;
2346 case MID_GRID_RUBYHEIGHT:
2347 OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
2348 "This value needs TWIPS-MM100 conversion" );
2349 rVal <<= static_cast<sal_Int32>(convertTwipToMm100(m_nRubyHeight));
2350 break;
2351 case MID_GRID_TYPE:
2352 switch( GetGridType() )
2354 case GRID_NONE:
2355 rVal <<= text::TextGridMode::NONE;
2356 break;
2357 case GRID_LINES_ONLY:
2358 rVal <<= text::TextGridMode::LINES;
2359 break;
2360 case GRID_LINES_CHARS:
2361 rVal <<= text::TextGridMode::LINES_AND_CHARS;
2362 break;
2363 default:
2364 OSL_FAIL("unknown SwTextGrid value");
2365 bRet = false;
2366 break;
2368 break;
2369 case MID_GRID_SNAPTOCHARS:
2370 rVal <<= m_bSnapToChars;
2371 break;
2372 case MID_GRID_STANDARD_MODE:
2373 rVal <<= !m_bSquaredMode;
2374 break;
2375 default:
2376 OSL_FAIL("Unknown SwTextGridItem member");
2377 bRet = false;
2378 break;
2381 return bRet;
2384 bool SwTextGridItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2386 bool bRet = true;
2387 switch( nMemberId & ~CONVERT_TWIPS )
2389 case MID_GRID_COLOR:
2391 Color nTmp;
2392 bRet = (rVal >>= nTmp);
2393 if( bRet )
2394 SetColor( nTmp );
2396 break;
2397 case MID_GRID_LINES:
2399 sal_Int16 nTmp = 0;
2400 bRet = (rVal >>= nTmp);
2401 if( bRet && (nTmp >= 0) )
2402 SetLines( nTmp );
2403 else
2404 bRet = false;
2406 break;
2407 case MID_GRID_RUBY_BELOW:
2408 SetRubyTextBelow( *o3tl::doAccess<bool>(rVal) );
2409 break;
2410 case MID_GRID_PRINT:
2411 SetPrintGrid( *o3tl::doAccess<bool>(rVal) );
2412 break;
2413 case MID_GRID_DISPLAY:
2414 SetDisplayGrid( *o3tl::doAccess<bool>(rVal) );
2415 break;
2416 case MID_GRID_BASEHEIGHT:
2417 case MID_GRID_BASEWIDTH:
2418 case MID_GRID_RUBYHEIGHT:
2420 OSL_ENSURE( (nMemberId & CONVERT_TWIPS) != 0,
2421 "This value needs TWIPS-MM100 conversion" );
2422 sal_Int32 nTmp = 0;
2423 bRet = (rVal >>= nTmp);
2424 nTmp = o3tl::toTwips(nTmp, o3tl::Length::mm100);
2425 if( bRet && (nTmp >= 0) && ( nTmp <= SAL_MAX_UINT16) )
2427 // rhbz#1043551 round up to 5pt -- 0 causes divide-by-zero
2428 // in layout; 1pt ties the painting code up in knots for
2429 // minutes with bazillion lines...
2430 #define MIN_TEXTGRID_SIZE 100
2431 if( (nMemberId & ~CONVERT_TWIPS) == MID_GRID_BASEHEIGHT )
2433 nTmp = std::max<sal_Int32>(nTmp, MIN_TEXTGRID_SIZE);
2434 SetBaseHeight( o3tl::narrowing<sal_uInt16>(nTmp) );
2436 else if( (nMemberId & ~CONVERT_TWIPS) == MID_GRID_BASEWIDTH )
2438 nTmp = std::max<sal_Int32>(nTmp, MIN_TEXTGRID_SIZE);
2439 SetBaseWidth( o3tl::narrowing<sal_uInt16>(nTmp) );
2441 else
2442 SetRubyHeight( o3tl::narrowing<sal_uInt16>(nTmp) );
2444 else
2445 bRet = false;
2447 break;
2448 case MID_GRID_TYPE:
2450 sal_Int16 nTmp = 0;
2451 bRet = (rVal >>= nTmp);
2452 if( bRet )
2454 switch( nTmp )
2456 case text::TextGridMode::NONE:
2457 SetGridType( GRID_NONE );
2458 break;
2459 case text::TextGridMode::LINES:
2460 SetGridType( GRID_LINES_ONLY );
2461 break;
2462 case text::TextGridMode::LINES_AND_CHARS:
2463 SetGridType( GRID_LINES_CHARS );
2464 break;
2465 default:
2466 bRet = false;
2467 break;
2470 break;
2472 case MID_GRID_SNAPTOCHARS:
2473 SetSnapToChars( *o3tl::doAccess<bool>(rVal) );
2474 break;
2475 case MID_GRID_STANDARD_MODE:
2477 bool bStandard = *o3tl::doAccess<bool>(rVal);
2478 SetSquaredMode( !bStandard );
2479 break;
2481 default:
2482 OSL_FAIL("Unknown SwTextGridItem member");
2483 bRet = false;
2486 return bRet;
2489 void SwTextGridItem::SwitchPaperMode(bool bNew)
2491 if (bNew == m_bSquaredMode)
2493 //same paper mode, not switch
2494 return;
2497 // use default value when grid is disable
2498 if (m_eGridType == GRID_NONE)
2500 m_bSquaredMode = bNew;
2501 Init();
2502 return;
2505 if (m_bSquaredMode)
2507 //switch from "squared mode" to "standard mode"
2508 m_nBaseWidth = m_nBaseHeight;
2509 m_nBaseHeight = m_nBaseHeight + m_nRubyHeight;
2510 m_nRubyHeight = 0;
2512 else
2514 //switch from "standard mode" to "squared mode"
2515 m_nRubyHeight = m_nBaseHeight/3;
2516 m_nBaseHeight = m_nBaseHeight - m_nRubyHeight;
2517 m_nBaseWidth = m_nBaseHeight;
2519 m_bSquaredMode = !m_bSquaredMode;
2522 void SwTextGridItem::Init()
2524 if (m_bSquaredMode)
2526 m_nLines = 20;
2527 m_nBaseHeight = 400;
2528 m_nRubyHeight = 200;
2529 m_eGridType = GRID_NONE;
2530 m_bRubyTextBelow = false;
2531 m_bPrintGrid = true;
2532 m_bDisplayGrid = true;
2533 m_bSnapToChars = true;
2534 m_nBaseWidth = 400;
2536 else
2538 m_nLines = 44;
2539 m_nBaseHeight = 312;
2540 m_nRubyHeight = 0;
2541 m_eGridType = GRID_NONE;
2542 m_bRubyTextBelow = false;
2543 m_bPrintGrid = true;
2544 m_bDisplayGrid = true;
2545 m_nBaseWidth = 210;
2546 m_bSnapToChars = true;
2550 SwHeaderAndFooterEatSpacingItem* SwHeaderAndFooterEatSpacingItem::Clone( SfxItemPool* ) const
2552 return new SwHeaderAndFooterEatSpacingItem( Which(), GetValue() );
2555 SwFrameFormat::SwFrameFormat(
2556 SwAttrPool& rPool,
2557 const char* pFormatNm,
2558 SwFrameFormat *pDrvdFrame,
2559 sal_uInt16 nFormatWhich,
2560 const WhichRangesContainer& pWhichRange)
2561 : SwFormat(rPool, pFormatNm, pWhichRange, pDrvdFrame, nFormatWhich),
2562 m_ffList(nullptr)
2566 SwFrameFormat::SwFrameFormat(
2567 SwAttrPool& rPool,
2568 const OUString &rFormatNm,
2569 SwFrameFormat *pDrvdFrame,
2570 sal_uInt16 nFormatWhich,
2571 const WhichRangesContainer& pWhichRange)
2572 : SwFormat(rPool, rFormatNm, pWhichRange, pDrvdFrame, nFormatWhich),
2573 m_ffList(nullptr)
2577 SwFrameFormat::~SwFrameFormat()
2579 if( !GetDoc()->IsInDtor())
2581 const SwFormatAnchor& rAnchor = GetAnchor();
2582 if (SwNode* pAnchorNode = rAnchor.GetAnchorNode())
2584 pAnchorNode->RemoveAnchoredFly(this);
2588 // Check if there any textboxes attached to this format.
2589 if( nullptr == m_pOtherTextBoxFormats )
2590 return;
2592 // This is a fly-frame-format just delete this
2593 // textbox entry from the textbox collection.
2594 // Note: Do not delete it from the doc, as that
2595 // is already in progress.
2596 if (Which() == RES_FLYFRMFMT)
2597 m_pOtherTextBoxFormats->DelTextBox(this);
2599 // This is a draw-frame-format what belongs to
2600 // a shape with textbox(es). Delete all of them.
2601 if (Which() == RES_DRAWFRMFMT)
2602 m_pOtherTextBoxFormats->ClearAll();
2604 // Release the pointer.
2605 m_pOtherTextBoxFormats.reset();
2608 void SwFrameFormat::SetFormatName( const OUString& rNewName, bool bBroadcast )
2610 if (m_ffList != nullptr) {
2611 SAL_INFO_IF(m_aFormatName == rNewName, "sw.core", "SwFrmFmt not really renamed, as both names are equal");
2612 sw::NameChanged aHint(m_aFormatName, rNewName);
2613 m_ffList->Rename(*this, rNewName);
2614 if (bBroadcast) {
2615 GetNotifier().Broadcast(aHint);
2618 // update accessibility sidebar object name if we modify the object name on the navigator bar
2619 if (!aHint.m_sOld.isEmpty() && aHint.m_sOld != aHint.m_sNew)
2621 if (SwFlyFrame* pSFly = SwIterator<SwFlyFrame, SwFormat>(*this).First())
2623 if (pSFly->Lower() && !pSFly->Lower()->IsNoTextFrame())
2625 if (SwTextNode* pSwTxtNode = static_cast<SwTextFrame*>(pSFly->ContainsContent())->GetTextNodeFirst())
2626 pSwTxtNode->resetAndQueueAccessibilityCheck(true);
2628 else
2630 if (SwNode* pSwNode = static_cast<SwNoTextFrame*>(pSFly->Lower())->GetNode())
2631 pSwNode->resetAndQueueAccessibilityCheck(true);
2636 else
2637 SwFormat::SetFormatName( rNewName, bBroadcast );
2640 bool SwFrameFormat::supportsFullDrawingLayerFillAttributeSet() const
2642 return true;
2645 void SwFrameFormat::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
2647 if (rHint.GetId() != SfxHintId::SwLegacyModify)
2648 return;
2649 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
2650 const sal_uInt16 nNewWhich = pLegacy->m_pNew ? pLegacy->m_pNew->Which() : 0;
2651 const SwAttrSetChg* pNewAttrSetChg = nullptr;
2652 const SwFormatHeader* pH = nullptr;
2653 const SwFormatFooter* pF = nullptr;
2654 SwNode* pNewAnchorNode = nullptr;
2655 switch(nNewWhich)
2657 case RES_ATTRSET_CHG:
2659 pNewAttrSetChg = static_cast<const SwAttrSetChg*>(pLegacy->m_pNew);
2660 pH = pNewAttrSetChg->GetChgSet()->GetItem(RES_HEADER, false);
2661 pF = pNewAttrSetChg->GetChgSet()->GetItem(RES_FOOTER, false);
2663 // reset fill information
2664 if(maFillAttributes && supportsFullDrawingLayerFillAttributeSet())
2666 SfxItemIter aIter(*pNewAttrSetChg->GetChgSet());
2667 for(const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
2669 if(!IsInvalidItem(pItem) && pItem->Which() >= XATTR_FILL_FIRST && pItem->Which() <= XATTR_FILL_LAST)
2671 maFillAttributes.reset();
2672 break;
2676 const SwFormatAnchor* pAnchor = pNewAttrSetChg->GetChgSet()->GetItem(RES_ANCHOR, false);
2677 if(pAnchor)
2679 pNewAnchorNode = pAnchor->GetAnchorNode();
2680 assert(pNewAnchorNode == nullptr || // style's set must not contain position!
2681 pNewAttrSetChg->GetTheChgdSet() == &m_aSet);
2683 break;
2685 case RES_FMT_CHG:
2687 // reset fill information on format change (e.g. style changed)
2688 if(maFillAttributes && supportsFullDrawingLayerFillAttributeSet())
2689 maFillAttributes.reset();
2690 break;
2692 case RES_HEADER:
2693 pH = static_cast<const SwFormatHeader*>(pLegacy->m_pNew);
2694 break;
2695 case RES_FOOTER:
2696 pF = static_cast<const SwFormatFooter*>(pLegacy->m_pNew);
2697 break;
2698 case RES_ANCHOR:
2699 pNewAnchorNode = static_cast<const SwFormatAnchor*>(pLegacy->m_pNew)->GetAnchorNode();
2700 break;
2702 const sal_uInt16 nOldWhich = pLegacy->m_pOld ? pLegacy->m_pOld->Which() : 0;
2703 SwNode* pOldAnchorNode = nullptr;
2704 switch(nOldWhich)
2706 case RES_ATTRSET_CHG:
2708 const SwAttrSetChg* pOldAttrSetChg = nullptr;
2709 pOldAttrSetChg = static_cast<const SwAttrSetChg*>(pLegacy->m_pOld);
2710 const SwFormatAnchor* pAnchor = pOldAttrSetChg->GetChgSet()->GetItem(RES_ANCHOR, false);
2711 if(pAnchor)
2713 pOldAnchorNode = pAnchor->GetAnchorNode();
2714 assert(pOldAnchorNode == nullptr || // style's set must not contain position!
2715 pOldAttrSetChg->GetTheChgdSet() == &m_aSet);
2717 break;
2719 case RES_ANCHOR:
2720 pOldAnchorNode = static_cast<const SwFormatAnchor*>(pLegacy->m_pOld)->GetAnchorNode();
2721 break;
2722 case RES_REMOVE_UNO_OBJECT:
2723 SetXObject(uno::Reference<uno::XInterface>(nullptr));
2724 break;
2727 assert(nOldWhich == nNewWhich || !nOldWhich || !nNewWhich);
2728 if(pH && pH->IsActive() && !pH->GetHeaderFormat())
2729 { //If he doesn't have one, I'll add one
2730 SwFrameFormat* pFormat = GetDoc()->getIDocumentLayoutAccess().MakeLayoutFormat(RndStdIds::HEADER, nullptr);
2731 const_cast<SwFormatHeader*>(pH)->RegisterToFormat(*pFormat);
2733 if(pF && pF->IsActive() && !pF->GetFooterFormat())
2734 { //If he doesn't have one, I'll add one
2735 SwFrameFormat* pFormat = GetDoc()->getIDocumentLayoutAccess().MakeLayoutFormat(RndStdIds::FOOTER, nullptr);
2736 const_cast<SwFormatFooter*>(pF)->RegisterToFormat(*pFormat);
2738 SwFormat::SwClientNotify(rMod, rHint);
2739 if(pOldAnchorNode != nullptr && (pNewAnchorNode == nullptr || pOldAnchorNode->GetIndex() != pNewAnchorNode->GetIndex()))
2740 pOldAnchorNode->RemoveAnchoredFly(this);
2741 if(pNewAnchorNode != nullptr && (pOldAnchorNode == nullptr || pOldAnchorNode->GetIndex() != pNewAnchorNode->GetIndex()))
2742 pNewAnchorNode->AddAnchoredFly(this);
2745 void SwFrameFormat::RegisterToFormat( SwFormat& rFormat )
2747 rFormat.Add( this );
2750 /// Delete all Frames that are registered in aDepend.
2751 void SwFrameFormat::DelFrames()
2753 SwIterator<SwFrame,SwFormat> aIter( *this );
2754 SwFrame * pLast = aIter.First();
2755 if( pLast )
2756 do {
2757 pLast->Cut();
2758 SwFrame::DestroyFrame(pLast);
2759 } while( nullptr != ( pLast = aIter.Next() ));
2762 void SwFrameFormat::MakeFrames()
2764 assert(false); // unimplemented in base class
2767 SwRect SwFrameFormat::FindLayoutRect( const bool bPrtArea, const Point* pPoint ) const
2769 SwRect aRet;
2770 SwFrame *pFrame = nullptr;
2771 if( auto pSectionFormat = dynamic_cast<const SwSectionFormat*>( this ))
2773 // get the Frame using Node2Layout
2774 const SwSectionNode* pSectNd = pSectionFormat->GetSectionNode();
2775 if( pSectNd )
2777 SwNode2Layout aTmp( *pSectNd, pSectNd->GetIndex() - 1 );
2778 pFrame = aTmp.NextFrame();
2780 if( pFrame && !pFrame->KnowsFormat(*this) )
2782 // the Section doesn't have his own Frame, so if someone
2783 // needs the real size, we have to implement this by requesting
2784 // the matching Frame from the end.
2785 // PROBLEM: what happens if SectionFrames overlaps multiple
2786 // pages?
2787 if( bPrtArea )
2788 aRet = pFrame->getFramePrintArea();
2789 else
2791 aRet = pFrame->getFrameArea();
2792 aRet.Pos().AdjustY( -1 );
2794 pFrame = nullptr; // the rect is finished by now
2798 else
2800 const SwFrameType nFrameType = RES_FLYFRMFMT == Which() ? SwFrameType::Fly : FRM_ALL;
2801 std::pair<Point, bool> tmp;
2802 if (pPoint)
2804 tmp.first = *pPoint;
2805 tmp.second = false;
2807 pFrame = ::GetFrameOfModify(nullptr, *this, nFrameType, nullptr, pPoint ? &tmp : nullptr);
2810 if( pFrame )
2812 if( bPrtArea )
2813 aRet = pFrame->getFramePrintArea();
2814 else
2815 aRet = pFrame->getFrameArea();
2817 return aRet;
2820 SdrObject* SwFrameFormat::FindRealSdrObject()
2822 if( RES_FLYFRMFMT == Which() )
2824 Point aNullPt;
2825 std::pair<Point, bool> const tmp(aNullPt, false);
2826 SwFlyFrame* pFly = static_cast<SwFlyFrame*>(::GetFrameOfModify( nullptr, *this, SwFrameType::Fly,
2827 nullptr, &tmp));
2828 if( pFly )
2829 return pFly->GetVirtDrawObj();
2831 if( !GetDoc() || !GetDoc()->GetDocShell() ||
2832 GetDoc()->GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED )
2833 return nullptr;
2835 // tdf#126477 fix lost charts in embedded documents
2837 return FindSdrObject();
2840 bool SwFrameFormat::IsLowerOf( const SwFrameFormat& rFormat ) const
2842 //Also linking from inside to outside or from outside to inside is not
2843 //allowed.
2844 SwFlyFrame *pSFly = SwIterator<SwFlyFrame,SwFormat>(*this).First();
2845 if( pSFly )
2847 SwFlyFrame *pAskFly = SwIterator<SwFlyFrame,SwFormat>(rFormat).First();
2848 if( pAskFly )
2849 return pSFly->IsLowerOf( pAskFly );
2852 // let's try it using the node positions
2853 const SwFormatAnchor* pAnchor = &rFormat.GetAnchor();
2854 if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) && pAnchor->GetAnchorNode())
2856 const SwNode* pFlyNd = pAnchor->GetAnchorNode()->FindFlyStartNode();
2857 while( pFlyNd )
2859 // then we walk up using the anchor
2860 for(const sw::SpzFrameFormat* pFormat: *GetDoc()->GetSpzFrameFormats())
2862 const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
2863 if( pIdx && pFlyNd == &pIdx->GetNode() )
2865 if( pFormat == this )
2866 return true;
2868 pAnchor = &pFormat->GetAnchor();
2869 if ((RndStdIds::FLY_AT_PAGE == pAnchor->GetAnchorId()) ||
2870 !pAnchor->GetAnchorNode() )
2872 return false;
2875 pFlyNd = pAnchor->GetAnchorNode()->FindFlyStartNode();
2876 break;
2881 return false;
2884 // #i31698#
2885 SwFrameFormat::tLayoutDir SwFrameFormat::GetLayoutDir() const
2887 return SwFrameFormat::HORI_L2R;
2890 void SwFrameFormat::SetLayoutDir( const SwFrameFormat::tLayoutDir )
2892 // empty body, because default implementation does nothing
2895 // #i28749#
2896 sal_Int16 SwFrameFormat::GetPositionLayoutDir() const
2898 return text::PositionLayoutDir::PositionInLayoutDirOfAnchor;
2900 void SwFrameFormat::SetPositionLayoutDir( const sal_Int16 )
2902 // empty body, because default implementation does nothing
2905 OUString SwFrameFormat::GetDescription() const
2907 return SwResId(STR_FRAME);
2910 void SwFrameFormat::dumpAsXml(xmlTextWriterPtr pWriter) const
2912 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFrameFormat"));
2913 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
2914 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(GetName().toUtf8().getStr()));
2915 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("whichId"), "%d", Which());
2917 const char* pWhich = nullptr;
2918 switch (Which())
2920 case RES_FLYFRMFMT:
2921 pWhich = "fly frame format";
2922 break;
2923 case RES_DRAWFRMFMT:
2924 pWhich = "draw frame format";
2925 break;
2927 if (pWhich)
2928 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("which"), BAD_CAST(pWhich));
2930 if (m_pOtherTextBoxFormats)
2932 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("OtherTextBoxFormat"), "%p", m_pOtherTextBoxFormats.get());
2935 GetAttrSet().dumpAsXml(pWriter);
2937 if (const SdrObject* pSdrObject = FindSdrObject())
2938 pSdrObject->dumpAsXml(pWriter);
2940 (void)xmlTextWriterEndElement(pWriter);
2943 SwFlyFrameFormat::SwFlyFrameFormat(SwAttrPool& rPool, const OUString &rFormatName, SwFrameFormat* pDerivedFrame)
2944 : sw::SpzFrameFormat(rPool, rFormatName, pDerivedFrame, RES_FLYFRMFMT)
2947 SwFlyFrameFormat::~SwFlyFrameFormat()
2949 SwIterator<SwFlyFrame,SwFormat> aIter( *this );
2950 SwFlyFrame * pLast = aIter.First();
2951 if( pLast )
2954 SwFrame::DestroyFrame(pLast);
2955 } while( nullptr != ( pLast = aIter.Next() ));
2959 SwFlyDrawContact* SwFlyFrameFormat::GetOrCreateContact()
2961 if(!m_pContact)
2963 SwDrawModel* pDrawModel(GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel());
2964 m_pContact.reset(new SwFlyDrawContact(this, *pDrawModel));
2967 return m_pContact.get();
2970 /// Creates the Frames if the format describes a paragraph-bound frame.
2971 /// MA: 1994-02-14: creates the Frames also for frames anchored at page.
2972 void SwFlyFrameFormat::MakeFrames()
2974 // is there a layout?
2975 if( !GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() )
2976 return;
2978 sw::BroadcastingModify *pModify = nullptr;
2979 // OD 24.07.2003 #111032# - create local copy of anchor attribute for possible changes.
2980 SwFormatAnchor aAnchorAttr( GetAnchor() );
2981 switch( aAnchorAttr.GetAnchorId() )
2983 case RndStdIds::FLY_AS_CHAR:
2984 case RndStdIds::FLY_AT_PARA:
2985 case RndStdIds::FLY_AT_CHAR:
2986 if( aAnchorAttr.GetAnchorNode() )
2988 pModify = aAnchorAttr.GetAnchorNode()->GetContentNode();
2990 break;
2992 case RndStdIds::FLY_AT_FLY:
2993 if( aAnchorAttr.GetAnchorNode() )
2995 //First search in the content because this is O(1)
2996 //This can go wrong for linked frames because in this case it's
2997 //possible, that no Frame exists for this content.
2998 //In such a situation we also need to search from StartNode to
2999 //FrameFormat.
3000 SwNodeIndex aIdx( *aAnchorAttr.GetAnchorNode() );
3001 SwContentNode *pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
3002 // #i105535#
3003 if ( pCNd == nullptr )
3005 pCNd = aAnchorAttr.GetAnchorNode()->GetContentNode();
3007 if ( pCNd )
3009 if (SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti>(*pCNd).First())
3011 pModify = pCNd;
3014 // #i105535#
3015 if ( pModify == nullptr )
3017 const SwNode & rNd = *aAnchorAttr.GetAnchorNode();
3018 for(sw::SpzFrameFormat* pFlyFormat: *GetDoc()->GetSpzFrameFormats())
3020 if( pFlyFormat->GetContent().GetContentIdx() &&
3021 rNd == pFlyFormat->GetContent().GetContentIdx()->GetNode() )
3023 pModify = pFlyFormat;
3024 break;
3029 break;
3031 case RndStdIds::FLY_AT_PAGE:
3033 sal_uInt16 nPgNum = aAnchorAttr.GetPageNum();
3034 SwPageFrame *pPage = static_cast<SwPageFrame*>(GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()->Lower());
3035 if( nPgNum == 0 && aAnchorAttr.GetAnchorNode() )
3037 SwContentNode *pCNd = aAnchorAttr.GetAnchorNode()->GetContentNode();
3038 SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aIter(*pCNd);
3039 for ( SwFrame* pFrame = aIter.First(); pFrame != nullptr; pFrame = aIter.Next() )
3041 pPage = pFrame->FindPageFrame();
3042 if( pPage )
3044 nPgNum = pPage->GetPhyPageNum();
3045 aAnchorAttr.SetPageNum( nPgNum );
3046 aAnchorAttr.SetAnchor( nullptr );
3047 SetFormatAttr( aAnchorAttr );
3048 break;
3052 while ( pPage )
3054 if ( pPage->GetPhyPageNum() == nPgNum )
3056 // #i50432# - adjust synopsis of <PlaceFly(..)>
3057 pPage->PlaceFly( nullptr, this );
3058 break;
3060 pPage = static_cast<SwPageFrame*>(pPage->GetNext());
3063 break;
3064 default:
3065 break;
3068 if( !pModify )
3069 return;
3071 SwIterator<SwFrame, sw::BroadcastingModify, sw::IteratorMode::UnwrapMulti> aIter(*pModify);
3072 for( SwFrame *pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
3074 bool bAdd = !pFrame->IsContentFrame() ||
3075 !static_cast<SwContentFrame*>(pFrame)->IsFollow();
3077 if ( RndStdIds::FLY_AT_FLY == aAnchorAttr.GetAnchorId() && !pFrame->IsFlyFrame() )
3079 SwFrame* pFlyFrame = pFrame->FindFlyFrame();
3080 if ( pFlyFrame )
3082 pFrame = pFlyFrame;
3084 else
3086 aAnchorAttr.SetType( RndStdIds::FLY_AT_PARA );
3087 SetFormatAttr( aAnchorAttr );
3088 MakeFrames();
3089 return;
3093 if (bAdd)
3095 switch (aAnchorAttr.GetAnchorId())
3097 case RndStdIds::FLY_AS_CHAR:
3098 case RndStdIds::FLY_AT_PARA:
3099 case RndStdIds::FLY_AT_CHAR:
3101 assert(pFrame->IsTextFrame());
3102 bAdd = IsAnchoredObjShown(*static_cast<SwTextFrame*>(pFrame), aAnchorAttr);
3104 break;
3105 default:
3106 break;
3110 if (bAdd && pFrame->GetDrawObjs())
3112 // #i28701# - new type <SwSortedObjs>
3113 SwSortedObjs &rObjs = *pFrame->GetDrawObjs();
3114 for(SwAnchoredObject* pObj : rObjs)
3116 // #i28701# - consider changed type of
3117 // <SwSortedObjs> entries.
3118 if( pObj->DynCastFlyFrame() != nullptr &&
3119 (&pObj->GetFrameFormat()) == this )
3121 bAdd = false;
3122 break;
3127 if( bAdd )
3129 SwFlyFrame *pFly = nullptr; // avoid warnings
3130 switch( aAnchorAttr.GetAnchorId() )
3132 case RndStdIds::FLY_AT_FLY:
3133 pFly = new SwFlyLayFrame( this, pFrame, pFrame );
3134 break;
3136 case RndStdIds::FLY_AT_PARA:
3137 case RndStdIds::FLY_AT_CHAR:
3138 pFly = new SwFlyAtContentFrame( this, pFrame, pFrame );
3139 break;
3141 case RndStdIds::FLY_AS_CHAR:
3142 pFly = new SwFlyInContentFrame( this, pFrame, pFrame );
3143 break;
3145 default:
3146 assert(false && "New anchor type" );
3148 pFrame->AppendFly( pFly );
3149 pFly->GetFormat()->SetObjTitle(GetObjTitle());
3150 pFly->GetFormat()->SetObjDescription(GetObjDescription());
3151 SwPageFrame *pPage = pFly->FindPageFrame();
3152 if( pPage )
3153 ::RegistFlys( pPage, pFly );
3158 SwFlyFrame* SwFlyFrameFormat::GetFrame( const Point* pPoint ) const
3160 std::pair<Point, bool> tmp;
3161 if (pPoint)
3163 tmp.first = *pPoint;
3164 tmp.second = false;
3166 return static_cast<SwFlyFrame*>(::GetFrameOfModify( nullptr, *this, SwFrameType::Fly,
3167 nullptr, &tmp));
3170 SwAnchoredObject* SwFlyFrameFormat::GetAnchoredObj() const
3172 SwFlyFrame* pFlyFrame( GetFrame() );
3173 if ( pFlyFrame )
3175 return pFlyFrame;
3177 else
3179 return nullptr;
3183 // #i73249#
3184 void SwFlyFrameFormat::SetObjTitle( const OUString& rTitle, bool bBroadcast )
3186 SdrObject* pMasterObject = FindSdrObject();
3187 OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::SetObjTitle(..)> - missing <SdrObject> instance" );
3188 msTitle = rTitle;
3189 if ( !pMasterObject )
3191 return;
3194 const sw::TitleChanged aHint(pMasterObject->GetTitle(), rTitle);
3195 pMasterObject->SetTitle(rTitle);
3196 if(bBroadcast)
3198 GetNotifier().Broadcast(aHint);
3202 OUString SwFlyFrameFormat::GetObjTitle() const
3204 const SdrObject* pMasterObject = FindSdrObject();
3205 OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::GetObjTitle(..)> - missing <SdrObject> instance" );
3206 if ( !pMasterObject )
3208 return msTitle;
3210 if (!pMasterObject->GetTitle().isEmpty())
3211 return pMasterObject->GetTitle();
3212 else
3213 return msTitle;
3216 void SwFlyFrameFormat::SetObjTooltip(const OUString& rTooltip)
3218 msTooltip = rTooltip;
3221 const OUString & SwFlyFrameFormat::GetObjTooltip() const
3223 return msTooltip;
3226 void SwFlyFrameFormat::SetObjDescription( const OUString& rDescription, bool bBroadcast )
3228 SdrObject* pMasterObject = FindSdrObject();
3229 OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance" );
3230 msDesc = rDescription;
3231 if ( !pMasterObject )
3233 return;
3236 const sw::DescriptionChanged aHint;
3237 pMasterObject->SetDescription(rDescription);
3238 if(bBroadcast)
3240 GetNotifier().Broadcast(aHint);
3244 OUString SwFlyFrameFormat::GetObjDescription() const
3246 const SdrObject* pMasterObject = FindSdrObject();
3247 OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::GetDescription(..)> - missing <SdrObject> instance" );
3248 if ( !pMasterObject )
3250 return msDesc;
3252 if (!pMasterObject->GetDescription().isEmpty())
3253 return pMasterObject->GetDescription();
3254 else
3255 return msDesc;
3258 bool SwFlyFrameFormat::IsDecorative() const
3260 const SdrObject* pMasterObject = FindSdrObject();
3261 OSL_ENSURE(pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance");
3262 if (!pMasterObject)
3264 return false;
3267 return pMasterObject->IsDecorative();
3270 void SwFlyFrameFormat::SetObjDecorative(bool const isDecorative)
3272 SdrObject* pMasterObject = FindSdrObject();
3273 OSL_ENSURE( pMasterObject, "<SwFlyFrameFormat::SetDescription(..)> - missing <SdrObject> instance" );
3274 if ( !pMasterObject )
3276 return;
3279 SetFormatAttr(SfxBoolItem(RES_DECORATIVE, isDecorative));
3280 pMasterObject->SetDecorative(isDecorative);
3281 // does anybody care about a broadcast?
3285 /** SwFlyFrameFormat::IsBackgroundTransparent - for #99657#
3287 OD 22.08.2002 - overriding virtual method and its default implementation,
3288 because format of fly frame provides transparent backgrounds.
3289 Method determines, if background of fly frame is transparent.
3291 @return true, if background color is transparent, but not "no fill"
3292 or the transparency of an existing background graphic is set.
3294 bool SwFlyFrameFormat::IsBackgroundTransparent() const
3296 if (supportsFullDrawingLayerFillAttributeSet() && getSdrAllFillAttributesHelper())
3298 return getSdrAllFillAttributesHelper()->isTransparent();
3301 // NOTE: If background color is "no fill"/"auto fill" (COL_TRANSPARENT)
3302 // and there is no background graphic, it "inherites" the background
3303 // from its anchor.
3304 std::unique_ptr<SvxBrushItem> aBackground(makeBackgroundBrushItem());
3305 if ( aBackground->GetColor().IsTransparent() &&
3306 aBackground->GetColor() != COL_TRANSPARENT
3309 return true;
3311 else
3313 const GraphicObject *pTmpGrf = aBackground->GetGraphicObject();
3314 if ( pTmpGrf &&
3315 pTmpGrf->GetAttr().IsTransparent()
3318 return true;
3322 return false;
3325 /** SwFlyFrameFormat::IsBackgroundBrushInherited - for #103898#
3327 OD 08.10.2002 - method to determine, if the brush for drawing the
3328 background is "inherited" from its parent/grandparent.
3329 This is the case, if no background graphic is set and the background
3330 color is "no fill"/"auto fill"
3331 NOTE: condition is "copied" from method <SwFrame::GetBackgroundBrush(..).
3333 @return true, if background brush is "inherited" from parent/grandparent
3335 bool SwFlyFrameFormat::IsBackgroundBrushInherited() const
3337 if (supportsFullDrawingLayerFillAttributeSet() && getSdrAllFillAttributesHelper())
3339 return !getSdrAllFillAttributesHelper()->isUsed();
3341 else
3343 std::unique_ptr<SvxBrushItem> aBackground(makeBackgroundBrushItem());
3344 if ( (aBackground->GetColor() == COL_TRANSPARENT) &&
3345 !(aBackground->GetGraphicObject()) )
3347 return true;
3351 return false;
3354 SwHandleAnchorNodeChg::SwHandleAnchorNodeChg( SwFlyFrameFormat& _rFlyFrameFormat,
3355 const SwFormatAnchor& _rNewAnchorFormat,
3356 SwFlyFrame const * _pKeepThisFlyFrame )
3357 : mrFlyFrameFormat( _rFlyFrameFormat ),
3358 mbAnchorNodeChanged( false ),
3359 mpWrtShell(nullptr)
3361 const SwFormatAnchor& aOldAnchorFormat(_rFlyFrameFormat.GetAnchor());
3362 const RndStdIds nNewAnchorType( _rNewAnchorFormat.GetAnchorId() );
3363 if ( ((nNewAnchorType == RndStdIds::FLY_AT_PARA) ||
3364 (nNewAnchorType == RndStdIds::FLY_AT_CHAR)) &&
3365 _rNewAnchorFormat.GetAnchorNode() &&
3366 _rNewAnchorFormat.GetAnchorNode()->GetContentNode() )
3368 if ( aOldAnchorFormat.GetAnchorId() == nNewAnchorType &&
3369 aOldAnchorFormat.GetAnchorNode() &&
3370 aOldAnchorFormat.GetAnchorNode()->GetContentNode() &&
3371 aOldAnchorFormat.GetContentAnchor()->GetNode() !=
3372 _rNewAnchorFormat.GetContentAnchor()->GetNode() )
3374 // determine 'old' number of anchor frames
3375 sal_uInt32 nOldNumOfAnchFrame( 0 );
3376 SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aOldIter(
3377 *(aOldAnchorFormat.GetAnchorNode()->GetContentNode()) );
3378 for( SwFrame* pOld = aOldIter.First(); pOld; pOld = aOldIter.Next() )
3380 ++nOldNumOfAnchFrame;
3382 // determine 'new' number of anchor frames
3383 sal_uInt32 nNewNumOfAnchFrame( 0 );
3384 SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aNewIter(
3385 *(_rNewAnchorFormat.GetAnchorNode()->GetContentNode()) );
3386 for( SwFrame* pNew = aNewIter.First(); pNew; pNew = aNewIter.Next() )
3388 ++nNewNumOfAnchFrame;
3390 if ( nOldNumOfAnchFrame != nNewNumOfAnchFrame )
3392 // delete existing fly frames except <_pKeepThisFlyFrame>
3393 SwIterator<SwFrame,SwFormat> aIter( mrFlyFrameFormat );
3394 SwFrame* pFrame = aIter.First();
3395 if ( pFrame )
3397 do {
3398 if ( pFrame != _pKeepThisFlyFrame )
3400 pFrame->Cut();
3401 SwFrame::DestroyFrame(pFrame);
3403 } while( nullptr != ( pFrame = aIter.Next() ));
3405 // indicate, that re-creation of fly frames necessary
3406 mbAnchorNodeChanged = true;
3411 if (aOldAnchorFormat.GetAnchorNode()
3412 && aOldAnchorFormat.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
3414 moCommentAnchor.emplace(*aOldAnchorFormat.GetContentAnchor());
3417 if (_pKeepThisFlyFrame)
3419 SwViewShell* pViewShell = _pKeepThisFlyFrame->getRootFrame()->GetCurrShell();
3420 mpWrtShell = dynamic_cast<SwWrtShell*>(pViewShell);
3424 void SwHandleAnchorNodeChg::ImplDestroy()
3426 if ( mbAnchorNodeChanged )
3428 mrFlyFrameFormat.MakeFrames();
3431 // See if the fly frame had a comment: if so, move it to the new anchor as well.
3432 if (!moCommentAnchor)
3434 return;
3437 SwTextNode* pTextNode = moCommentAnchor->GetNode().GetTextNode();
3438 if (!pTextNode)
3440 return;
3443 const SwTextField* pField = pTextNode->GetFieldTextAttrAt(moCommentAnchor->GetContentIndex());
3444 if (!pField || pField->GetFormatField().GetField()->GetTyp()->Which() != SwFieldIds::Postit)
3446 return;
3449 if (!mpWrtShell)
3451 return;
3454 // Save current cursor position, so we can restore it later.
3455 mpWrtShell->Push();
3457 // Set up the source of the move: the old comment anchor.
3459 SwPaM& rCursor = mpWrtShell->GetCurrentShellCursor();
3460 *rCursor.GetPoint() = *moCommentAnchor;
3461 rCursor.SetMark();
3462 *rCursor.GetMark() = *moCommentAnchor;
3463 rCursor.GetMark()->AdjustContent(+1);
3466 // Set up the target of the move: the new comment anchor.
3467 const SwFormatAnchor& rNewAnchorFormat = mrFlyFrameFormat.GetAnchor();
3468 mpWrtShell->CreateCursor();
3469 *mpWrtShell->GetCurrentShellCursor().GetPoint() = *rNewAnchorFormat.GetContentAnchor();
3471 // Move by copying and deleting.
3472 mpWrtShell->SwEditShell::Copy(*mpWrtShell);
3473 mpWrtShell->DestroyCursor();
3475 mpWrtShell->Delete(false);
3477 mpWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
3480 SwHandleAnchorNodeChg::~SwHandleAnchorNodeChg()
3482 suppress_fun_call_w_exception(ImplDestroy());
3485 namespace sw
3487 DrawFrameFormatHint::~DrawFrameFormatHint() {}
3488 CheckDrawFrameFormatLayerHint::~CheckDrawFrameFormatLayerHint() {}
3489 ContactChangedHint::~ContactChangedHint() {}
3490 DrawFormatLayoutCopyHint::~DrawFormatLayoutCopyHint() {}
3491 WW8AnchorConvHint::~WW8AnchorConvHint() {}
3492 RestoreFlyAnchorHint::~RestoreFlyAnchorHint() {}
3493 CreatePortionHint::~CreatePortionHint() {}
3494 FindSdrObjectHint::~FindSdrObjectHint() {}
3495 CollectTextObjectsHint::~CollectTextObjectsHint() {}
3496 GetZOrderHint::~GetZOrderHint() {}
3497 GetObjectConnectedHint::~GetObjectConnectedHint() {}
3500 SwDrawFrameFormat::~SwDrawFrameFormat()
3502 CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::DYING));
3505 void SwDrawFrameFormat::MakeFrames()
3507 CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::MAKE_FRAMES));
3510 void SwDrawFrameFormat::DelFrames()
3512 CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::DELETE_FRAMES));
3515 // #i31698#
3516 SwFrameFormat::tLayoutDir SwDrawFrameFormat::GetLayoutDir() const
3518 return meLayoutDir;
3521 void SwDrawFrameFormat::SetLayoutDir( const SwFrameFormat::tLayoutDir _eLayoutDir )
3523 meLayoutDir = _eLayoutDir;
3526 // #i28749#
3527 sal_Int16 SwDrawFrameFormat::GetPositionLayoutDir() const
3529 return mnPositionLayoutDir;
3531 void SwDrawFrameFormat::SetPositionLayoutDir( const sal_Int16 _nPositionLayoutDir )
3533 switch ( _nPositionLayoutDir )
3535 case text::PositionLayoutDir::PositionInHoriL2R:
3536 case text::PositionLayoutDir::PositionInLayoutDirOfAnchor:
3538 mnPositionLayoutDir = _nPositionLayoutDir;
3540 break;
3541 default:
3543 OSL_FAIL( "<SwDrawFrameFormat::SetPositionLayoutDir(..)> - invalid attribute value." );
3548 OUString SwDrawFrameFormat::GetDescription() const
3550 OUString aResult;
3551 const SdrObject * pSdrObj = FindSdrObject();
3553 if (pSdrObj)
3555 if (pSdrObj != m_pSdrObjectCached)
3557 m_sSdrObjectCachedComment = SdrUndoNewObj::GetComment(*pSdrObj);
3558 m_pSdrObjectCached = pSdrObj;
3561 aResult = m_sSdrObjectCachedComment;
3563 else
3564 aResult = SwResId(STR_GRAPHIC);
3566 return aResult;
3569 IMapObject* SwFrameFormat::GetIMapObject( const Point& rPoint,
3570 const SwFlyFrame *pFly ) const
3572 const SwFormatURL &rURL = GetURL();
3573 if( !rURL.GetMap() )
3574 return nullptr;
3576 if( !pFly )
3578 pFly = SwIterator<SwFlyFrame,SwFormat>( *this ).First();
3579 if( !pFly )
3580 return nullptr;
3583 //Original size for OLE and graphic is TwipSize, otherwise the size of
3584 //FrameFormat of the Fly.
3585 const SwFrame *pRef;
3586 const SwNoTextNode *pNd = nullptr;
3587 Size aOrigSz;
3588 if( pFly->Lower() && pFly->Lower()->IsNoTextFrame() )
3590 pRef = pFly->Lower();
3591 pNd = static_cast<const SwNoTextFrame*>(pRef)->GetNode()->GetNoTextNode();
3592 aOrigSz = pNd->GetTwipSize();
3594 else
3596 pRef = pFly;
3597 aOrigSz = pFly->GetFormat()->GetFrameSize().GetSize();
3600 if( !aOrigSz.IsEmpty() )
3602 Point aPos( rPoint );
3603 Size aActSz ( pRef == pFly ? pFly->getFrameArea().SSize() : pRef->getFramePrintArea().SSize() );
3604 const o3tl::Length aSrc ( o3tl::Length::twip );
3605 const o3tl::Length aDest( o3tl::Length::mm100 );
3606 aOrigSz = o3tl::convert( aOrigSz, aSrc, aDest );
3607 aActSz = o3tl::convert( aActSz, aSrc, aDest );
3608 aPos -= pRef->getFrameArea().Pos();
3609 aPos -= pRef->getFramePrintArea().Pos();
3610 aPos = o3tl::convert( aPos, aSrc, aDest );
3611 sal_uInt32 nFlags = 0;
3612 if ( pFly != pRef && pNd->IsGrfNode() )
3614 const MirrorGraph nMirror = pNd->GetSwAttrSet().
3615 GetMirrorGrf().GetValue();
3616 if ( MirrorGraph::Both == nMirror )
3617 nFlags = IMAP_MIRROR_HORZ | IMAP_MIRROR_VERT;
3618 else if ( MirrorGraph::Vertical == nMirror )
3619 nFlags = IMAP_MIRROR_VERT;
3620 else if ( MirrorGraph::Horizontal == nMirror )
3621 nFlags = IMAP_MIRROR_HORZ;
3624 return const_cast<ImageMap*>(rURL.GetMap())->GetHitIMapObject( aOrigSz,
3625 aActSz, aPos, nFlags );
3628 return nullptr;
3631 drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFrameFormat::getSdrAllFillAttributesHelper() const
3633 if (supportsFullDrawingLayerFillAttributeSet())
3635 // create FillAttributes on demand
3636 if(!maFillAttributes)
3638 const_cast< SwFrameFormat* >(this)->maFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(GetAttrSet());
3641 else
3643 // FALLBACKBREAKHERE assert wrong usage
3644 OSL_ENSURE(false, "getSdrAllFillAttributesHelper() call only valid for RES_FLYFRMFMT and RES_FRMFMT (!)");
3647 return maFillAttributes;
3650 void SwFrameFormat::MoveTableBox(SwTableBox& rTableBox, const SwFrameFormat* pOldFormat)
3652 Add(&rTableBox);
3653 if(!pOldFormat)
3654 return;
3655 const auto& rOld = pOldFormat->GetFormatAttr(RES_BOXATR_FORMAT);
3656 const auto& rNew = GetFormatAttr(RES_BOXATR_FORMAT);
3657 if(rOld != rNew)
3658 SwClientNotify(*this, sw::LegacyModifyHint(&rOld, &rNew));
3662 bool SwFrameFormat::IsVisible() const
3664 return SwIterator<SwFrame, SwFrameFormat>(*this).First();
3667 namespace sw {
3669 bool IsFlyFrameFormatInHeader(const SwFrameFormat& rFormat)
3671 const SwFlyFrameFormat* pFlyFrameFormat = dynamic_cast<const SwFlyFrameFormat*>(&rFormat);
3672 if (!pFlyFrameFormat)
3673 return false;
3674 SwFlyFrame* pFlyFrame = pFlyFrameFormat->GetFrame();
3675 if (!pFlyFrame) // fdo#54648: "hidden" drawing object has no layout frame
3677 return false;
3679 SwPageFrame* pPageFrame = pFlyFrame->FindPageFrameOfAnchor();
3680 SwFrame* pHeader = pPageFrame->Lower();
3681 if (pHeader->GetType() == SwFrameType::Header)
3683 const SwFrame* pFrame = pFlyFrame->GetAnchorFrame();
3684 while (pFrame)
3686 if (pFrame == pHeader)
3687 return true;
3688 pFrame = pFrame->GetUpper();
3691 return false;
3694 void CheckAnchoredFlyConsistency(SwDoc const& rDoc)
3696 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
3697 SwNodes const& rNodes(rDoc.GetNodes());
3698 SwNodeOffset const count(rNodes.Count());
3699 for (SwNodeOffset i(0); i != count; ++i)
3701 SwNode const*const pNode(rNodes[i]);
3702 std::vector<SwFrameFormat*> const & rFlys(pNode->GetAnchoredFlys());
3703 for (const auto& rpFly : rFlys)
3705 SwFormatAnchor const& rAnchor((*rpFly).GetAnchor(false));
3706 assert(rAnchor.GetAnchorNode() == pNode);
3709 if(!rDoc.GetSpzFrameFormats())
3710 return;
3712 for(sw::SpzFrameFormat* pSpz: *rDoc.GetSpzFrameFormats())
3714 SwFormatAnchor const& rAnchor(pSpz->GetAnchor(false));
3715 if (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId())
3717 assert(!rAnchor.GetAnchorNode()
3718 // for invalid documents that lack text:anchor-page-number
3719 // it may have an anchor before MakeFrames() is called
3720 || (!SwIterator<SwFrame, SwFrameFormat>(*pSpz).First()));
3722 else
3724 SwNode & rNode(*rAnchor.GetAnchorNode());
3725 std::vector<SwFrameFormat*> const& rFlys(rNode.GetAnchoredFlys());
3726 assert(std::find(rFlys.begin(), rFlys.end(), pSpz) != rFlys.end());
3727 switch (rAnchor.GetAnchorId())
3729 case RndStdIds::FLY_AT_FLY:
3730 assert(rNode.IsStartNode());
3731 break;
3732 case RndStdIds::FLY_AT_PARA:
3733 assert(rNode.IsTextNode() || rNode.IsTableNode());
3734 break;
3735 case RndStdIds::FLY_AS_CHAR:
3736 case RndStdIds::FLY_AT_CHAR:
3737 assert(rNode.IsTextNode());
3738 break;
3739 default:
3740 assert(false);
3741 break;
3745 #else
3746 (void) rDoc;
3747 #endif
3750 } // namespace sw
3752 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */