LibreOffice Module svx (master) 1
cell.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <com/sun/star/drawing/BitmapMode.hpp>
22#include <com/sun/star/style/XStyle.hpp>
23#include <com/sun/star/text/WritingMode.hpp>
24#include <com/sun/star/table/TableBorder.hpp>
25#include <com/sun/star/table/BorderLine2.hpp>
26#include <com/sun/star/lang/Locale.hpp>
27
29#include <o3tl/any.hxx>
30#include <svl/style.hxx>
31#include <svl/itemset.hxx>
32
33#include <utility>
34#include <vcl/svapp.hxx>
35#include <libxml/xmlwriter.h>
36
38#include <editeng/outlobj.hxx>
40#include <svx/svdotable.hxx>
41#include <svx/svdoutl.hxx>
42#include <svx/unoshtxt.hxx>
43#include <svx/svdmodel.hxx>
44#include <svx/sdooitm.hxx>
45#include <svx/sdtagitm.hxx>
46#include <svx/sdmetitm.hxx>
47#include <svx/xit.hxx>
48#include <getallcharpropids.hxx>
49#include "tableundo.hxx"
50#include <cell.hxx>
51#include <svx/unoshprp.hxx>
52#include <svx/unoshape.hxx>
53#include <editeng/editobj.hxx>
55#include <editeng/boxitem.hxx>
57#include <svx/xflbstit.hxx>
58#include <svx/xflbmtit.hxx>
59#include <svx/svdpool.hxx>
60#include <svx/xflclit.hxx>
62
63
64using ::editeng::SvxBorderLine;
65using namespace ::com::sun::star::uno;
66using namespace ::com::sun::star::beans;
67using namespace ::com::sun::star::lang;
68using namespace ::com::sun::star::text;
69using namespace ::com::sun::star::table;
70using namespace ::com::sun::star::drawing;
71using namespace ::com::sun::star::style;
72using namespace ::com::sun::star::container;
73
74
76{
77 // property map for an outliner text
78 static const SfxItemPropertyMapEntry aSvxCellPropertyMap[] =
79 {
81// { "HasLevels", OWN_ATTR_HASLEVELS, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::READONLY, 0},
82 { u"Style", OWN_ATTR_STYLE, cppu::UnoType< css::style::XStyle >::get(), css::beans::PropertyAttribute::MAYBEVOID, 0},
85 { UNO_NAME_TEXT_LEFTDIST, SDRATTR_TEXT_LEFTDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM},
86 { UNO_NAME_TEXT_LOWERDIST, SDRATTR_TEXT_LOWERDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM},
87 { UNO_NAME_TEXT_RIGHTDIST, SDRATTR_TEXT_RIGHTDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM},
88 { UNO_NAME_TEXT_UPPERDIST, SDRATTR_TEXT_UPPERDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM},
91
98
102 };
103
104 static SvxItemPropertySet aSvxCellPropertySet( aSvxCellPropertyMap, SdrObject::GetGlobalDrawObjectItemPool() );
105 return &aSvxCellPropertySet;
106}
107
108namespace
109{
110
111class CellTextProvider : public svx::ITextProvider
112{
113public:
114 explicit CellTextProvider(sdr::table::CellRef xCell);
115 virtual ~CellTextProvider();
116
117private:
118 virtual sal_Int32 getTextCount() const override;
119 virtual SdrText* getText(sal_Int32 nIndex) const override;
120
121private:
122 const sdr::table::CellRef m_xCell;
123};
124
125CellTextProvider::CellTextProvider(sdr::table::CellRef xCell)
126 : m_xCell(std::move(xCell))
127{
128}
129
130CellTextProvider::~CellTextProvider()
131{
132}
133
134sal_Int32 CellTextProvider::getTextCount() const
135{
136 return 1;
137}
138
139SdrText* CellTextProvider::getText(sal_Int32 nIndex) const
140{
141 (void) nIndex;
142 assert(nIndex == 0);
143 return m_xCell.get();
144}
145
146}
147
148namespace sdr::properties
149{
151 {
152 protected:
153 // create a new itemset
155
156 const svx::ITextProvider& getTextProvider() const override;
157
158 public:
159 // basic constructor
160 CellProperties(SdrObject& rObj, sdr::table::Cell* pCell );
161
162 // constructor for copying, but using new object
163 CellProperties(const CellProperties& rProps, SdrObject& rObj, sdr::table::Cell* pCell);
164
165 // Clone() operator, normally just calls the local copy constructor
166 std::unique_ptr<BaseProperties> Clone(SdrObject& rObj) const override;
167
168 void ForceDefaultAttributes() override;
169
170 void ItemSetChanged(o3tl::span< const SfxPoolItem* const > aChangedItems, sal_uInt16 nDeletedWhich) override;
171
172 void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem = nullptr) override;
173
175
176 private:
177 const CellTextProvider maTextProvider;
178 };
179
180 // create a new itemset
182 {
183 return SfxItemSet(rPool,
184
185 // range from SdrAttrObj
189
190 // range for SdrTableObj
192
193 // range from SdrTextObj
195 }
196
198 {
199 return maTextProvider;
200 }
201
202 CellProperties::CellProperties(SdrObject& rObj, sdr::table::Cell* pCell)
203 : TextProperties(rObj)
204 , mxCell(pCell)
205 , maTextProvider(mxCell)
206 {
207 }
208
209 CellProperties::CellProperties(const CellProperties& rProps, SdrObject& rObj, sdr::table::Cell* pCell)
210 : TextProperties(rProps, rObj)
211 , mxCell( pCell )
212 , maTextProvider(mxCell)
213 {
214 }
215
216 std::unique_ptr<BaseProperties> CellProperties::Clone(SdrObject& rObj) const
217 {
218 OSL_FAIL("CellProperties::Clone(), does not work yet!");
219 return std::unique_ptr<BaseProperties>(new CellProperties(*this, rObj,nullptr));
220 }
221
223 {
224 }
225
226 void CellProperties::ItemSetChanged(o3tl::span< const SfxPoolItem* const > aChangedItems, sal_uInt16 nDeletedWhich)
227 {
228 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
229
230 if( mxCell.is() )
231 {
232 std::optional<OutlinerParaObject> pParaObj = mxCell->CreateEditOutlinerParaObject();
233
234 if( !pParaObj && mxCell->GetOutlinerParaObject())
235 pParaObj = *mxCell->GetOutlinerParaObject();
236
237 if(pParaObj)
238 {
239 // handle outliner attributes
240 Outliner* pOutliner = nullptr;
241
242 if(mxCell->IsTextEditActive())
243 {
244 pOutliner = rObj.GetTextEditOutliner();
245 }
246 else
247 {
248 pOutliner = &rObj.ImpGetDrawOutliner();
249 pOutliner->SetText(*pParaObj);
250 }
251
252 sal_Int32 nParaCount(pOutliner->GetParagraphCount());
253
254 // if the user sets character attributes to the complete
255 // cell we want to remove all hard set character attributes
256 // with same which ids from the text
257 std::vector<sal_uInt16> aCharWhichIds(GetAllCharPropIds(aChangedItems));
258
259 for(sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
260 {
261 SfxItemSet aSet(pOutliner->GetParaAttribs(nPara));
262 for (const SfxPoolItem* pItem : aChangedItems)
263 aSet.Put(*pItem);
264 if (nDeletedWhich)
265 aSet.ClearItem(nDeletedWhich);
266
267 for (const auto& rWhichId : aCharWhichIds)
268 {
269 pOutliner->RemoveCharAttribs(nPara, rWhichId);
270 }
271
272 pOutliner->SetParaAttribs(nPara, aSet);
273 }
274
275 if(!mxCell->IsTextEditActive())
276 {
277 if(nParaCount)
278 {
279 // force ItemSet
281
282 SfxItemSet aNewSet(pOutliner->GetParaAttribs(0));
283 mxItemSet->Put(aNewSet);
284 }
285
286 std::optional<OutlinerParaObject> pTemp = pOutliner->CreateParaObject(0, nParaCount);
287 pOutliner->Clear();
288 mxCell->SetOutlinerParaObject(std::move(pTemp));
289 }
290
291 }
292 }
293
294 // call parent
295 AttributeProperties::ItemSetChanged(aChangedItems, nDeletedWhich);
296
297 if( mxCell.is() )
298 mxCell->notifyModified();
299 }
300
301 void CellProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
302 {
303 if(pNewItem && (SDRATTR_TEXTDIRECTION == nWhich))
304 {
305 bool bVertical(css::text::WritingMode_TB_RL == static_cast<const SvxWritingModeItem*>(pNewItem)->GetValue());
306
308 rObj.SetVerticalWriting(bVertical);
309
310 // Set a cell vertical property
311 std::optional<OutlinerParaObject> pParaObj = mxCell->CreateEditOutlinerParaObject();
312
313 if( !pParaObj && mxCell->GetOutlinerParaObject() )
314 pParaObj = *mxCell->GetOutlinerParaObject();
315
316 if(pParaObj)
317 {
318 pParaObj->SetVertical(bVertical);
319 }
320 }
321
322 if (pNewItem && (SDRATTR_TABLE_TEXT_ROTATION == nWhich))
323 {
324 const SvxTextRotateItem* pRotateItem = static_cast<const SvxTextRotateItem*>(pNewItem);
325
326 // Set a cell vertical property
327 std::optional<OutlinerParaObject> pParaObj = mxCell->CreateEditOutlinerParaObject();
328
329 if (!pParaObj && mxCell->GetOutlinerParaObject())
330 pParaObj = *mxCell->GetOutlinerParaObject();
331
332 if (pParaObj)
333 {
334 if(pRotateItem->IsVertical() && pRotateItem->IsTopToBottom())
335 pParaObj->SetRotation(TextRotation::TOPTOBOTTOM);
336 else if (pRotateItem->IsVertical())
337 pParaObj->SetRotation(TextRotation::BOTTOMTOTOP);
338 else
339 pParaObj->SetRotation(TextRotation::NONE);
340 }
341
342 // Change autogrow direction
343 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
344
345 // rescue object size
346 tools::Rectangle aObjectRect = rObj.GetSnapRect();
347
348 const SfxItemSet& rSet = rObj.GetObjectItemSet();
349 bool bAutoGrowWidth = rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH).GetValue();
350 bool bAutoGrowHeight = rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue();
351
352 // prepare ItemSet to set exchanged width and height items
354
355 aNewSet.Put(rSet);
356 aNewSet.Put(makeSdrTextAutoGrowWidthItem(bAutoGrowHeight));
357 aNewSet.Put(makeSdrTextAutoGrowHeightItem(bAutoGrowWidth));
358 rObj.SetObjectItemSet(aNewSet);
359
360 // restore object size
361 rObj.SetSnapRect(aObjectRect);
362 }
363
364 // call parent
365 AttributeProperties::ItemChange( nWhich, pNewItem );
366 }
367
368} // end of namespace sdr::properties
369
370namespace sdr::table {
371
372
373// Cell
374
375
376rtl::Reference< Cell > Cell::create( SdrTableObj& rTableObj )
377{
378 rtl::Reference< Cell > xCell( new Cell( rTableObj ) );
379 if( xCell->mxTable.is() )
380 {
381 xCell->mxTable->addEventListener( xCell );
382 }
383 return xCell;
384}
385
386
387Cell::Cell(
388 SdrTableObj& rTableObj)
389: SdrText(rTableObj)
391 ,mpPropSet( ImplGetSvxCellPropertySet() )
392 ,mpProperties( new sdr::properties::CellProperties( rTableObj, this ) )
393 ,mnCellContentType( CellContentType_EMPTY )
394 ,mfValue( 0.0 )
395 ,mnError( 0 )
396 ,mbMerged( false )
397 ,mnRowSpan( 1 )
398 ,mnColSpan( 1 )
399 ,mxTable( rTableObj.getTable() )
400{
401 // Caution: Old SetModel() indirectly did a very necessary thing here,
402 // it created a valid SvxTextEditSource which is needed to bind contained
403 // Text to the UNO API and thus to save/load and more. Added version without
404 // model change.
405 // Also done was (not needed, for reference):
406 // SetStyleSheet( nullptr, true );
407 // ForceOutlinerParaObject( OutlinerMode::TextObject );
408 if(nullptr == GetEditSource())
409 {
410 SetEditSource(new SvxTextEditSource(&GetObject(), this));
411 }
412}
413
414Cell::~Cell() COVERITY_NOEXCEPT_FALSE
415{
416 dispose();
417}
418
419void Cell::dispose()
420{
421 if( mxTable.is() )
422 {
423 try
424 {
425 Reference< XEventListener > xThis( this );
426 mxTable->removeEventListener( xThis );
427 }
428 catch( Exception& )
429 {
430 TOOLS_WARN_EXCEPTION("svx.table", "");
431 }
432 mxTable.clear();
433 }
434
435 // tdf#118199 avoid double dispose, detect by using mpProperties
436 // as indicator. Only use SetOutlinerParaObject once
437 if( mpProperties )
438 {
439 mpProperties.reset();
440 SetOutlinerParaObject( std::nullopt );
441 }
442}
443
444void Cell::merge( sal_Int32 nColumnSpan, sal_Int32 nRowSpan )
445{
446 if ((mnColSpan != nColumnSpan) || (mnRowSpan != nRowSpan) || mbMerged)
447 {
448 mnColSpan = nColumnSpan;
449 mnRowSpan = nRowSpan;
450 mbMerged = false;
451 notifyModified();
452 }
453}
454
455
456void Cell::mergeContent( const CellRef& xSourceCell )
457{
458 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
459
460 if( !xSourceCell->hasText() )
461 return;
462
463 SdrOutliner& rOutliner=rTableObj.ImpGetDrawOutliner();
464 rOutliner.SetUpdateLayout(true);
465
466 if( hasText() )
467 {
468 rOutliner.SetText(*GetOutlinerParaObject());
469 rOutliner.AddText(*xSourceCell->GetOutlinerParaObject());
470 }
471 else
472 {
473 rOutliner.SetText(*xSourceCell->GetOutlinerParaObject());
474 }
475
476 SetOutlinerParaObject( rOutliner.CreateParaObject() );
477 rOutliner.Clear();
478 xSourceCell->SetOutlinerParaObject(rOutliner.CreateParaObject());
479 rOutliner.Clear();
480 SetStyleSheet( GetStyleSheet(), true );
481}
482
483
484void Cell::cloneFrom( const CellRef& xCell )
485{
486 if( xCell.is() )
487 {
488 replaceContentAndFormatting( xCell );
489
490 mnCellContentType = xCell->mnCellContentType;
491
492 msFormula = xCell->msFormula;
493 mfValue = xCell->mfValue;
494 mnError = xCell->mnError;
495
496 mbMerged = xCell->mbMerged;
497 mnRowSpan = xCell->mnRowSpan;
498 mnColSpan = xCell->mnColSpan;
499
500 }
501 notifyModified();
502}
503
504void Cell::replaceContentAndFormatting( const CellRef& xSourceCell )
505{
506 if( !(xSourceCell.is() && mpProperties) )
507 return;
508
509 mpProperties->SetMergedItemSet( xSourceCell->GetObjectItemSet() );
510
511 // tdf#118354 OutlinerParaObject may be nullptr, do not dereference when
512 // not set (!)
513 if(xSourceCell->GetOutlinerParaObject())
514 {
515 SetOutlinerParaObject( *xSourceCell->GetOutlinerParaObject() );
516 }
517
518 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
519 SdrTableObj& rSourceTableObj = dynamic_cast< SdrTableObj& >( xSourceCell->GetObject() );
520
521 if(&rSourceTableObj.getSdrModelFromSdrObject() != &rTableObj.getSdrModelFromSdrObject())
522 {
523 // TTTT should not happen - if, then a clone may be needed
524 // Maybe add an assertion here later
525 SetStyleSheet( nullptr, true );
526 }
527}
528
529
530void Cell::setMerged()
531{
532 if( !mbMerged )
533 {
534 mbMerged = true;
535 notifyModified();
536 }
537}
538
539
540void Cell::copyFormatFrom( const CellRef& xSourceCell )
541{
542 if( !(xSourceCell.is() && mpProperties) )
543 return;
544
545 mpProperties->SetMergedItemSet( xSourceCell->GetObjectItemSet() );
546 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
547 SdrTableObj& rSourceTableObj = dynamic_cast< SdrTableObj& >( xSourceCell->GetObject() );
548
549 if(&rSourceTableObj.getSdrModelFromSdrObject() != &rTableObj.getSdrModelFromSdrObject())
550 {
551 // TTTT should not happen - if, then a clone may be needed
552 // Maybe add an assertion here later
553 SetStyleSheet( nullptr, true );
554 }
555
556 notifyModified();
557}
558
559
560void Cell::notifyModified()
561{
562 if( mxTable.is() )
563 mxTable->setModified( true );
564}
565
566
567// SdrTextShape proxy
568
569
570bool Cell::IsActiveCell() const
571{
572 bool isActive = false;
573 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
574 if( rTableObj.getActiveCell().get() == this )
575 isActive = true;
576
577 return isActive;
578}
579
580bool Cell::IsTextEditActive() const
581{
582 bool isActive = false;
583 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
584 if(rTableObj.getActiveCell().get() == this )
585 {
586 if( rTableObj.CanCreateEditOutlinerParaObject() )
587 {
588 isActive = true;
589 }
590 }
591 return isActive;
592}
593
594
595bool Cell::hasText() const
596{
597 const OutlinerParaObject* pParaObj = GetOutlinerParaObject();
598 if( pParaObj )
599 {
600 const EditTextObject& rTextObj = pParaObj->GetTextObject();
601 if( rTextObj.GetParagraphCount() >= 1 )
602 {
603 if( rTextObj.GetParagraphCount() == 1 )
604 {
605 if( rTextObj.GetText(0).isEmpty() )
606 return false;
607 }
608 return true;
609 }
610 }
611
612 return false;
613}
614
615bool Cell::CanCreateEditOutlinerParaObject() const
616{
617 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
618 if( rTableObj.getActiveCell().get() == this )
619 return rTableObj.CanCreateEditOutlinerParaObject();
620 return false;
621}
622
623std::optional<OutlinerParaObject> Cell::CreateEditOutlinerParaObject() const
624{
625 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
626 if( rTableObj.getActiveCell().get() == this )
627 return rTableObj.CreateEditOutlinerParaObject();
628 return std::nullopt;
629}
630
631
632void Cell::SetStyleSheet( SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr )
633{
634 // only allow cell styles for cells
635 if( pStyleSheet && pStyleSheet->GetFamily() != SfxStyleFamily::Frame )
636 return;
637
638 if( mpProperties && (mpProperties->GetStyleSheet() != pStyleSheet) )
639 {
640 mpProperties->SetStyleSheet( pStyleSheet, bDontRemoveHardAttr, true );
641 }
642}
643
644
645const SfxItemSet& Cell::GetObjectItemSet()
646{
647 if( mpProperties )
648 {
649 return mpProperties->GetObjectItemSet();
650 }
651 else
652 {
653 OSL_FAIL("Cell::GetObjectItemSet(), called without properties!");
654 return GetObject().GetObjectItemSet();
655 }
656}
657
658void Cell::SetObjectItem(const SfxPoolItem& rItem)
659{
660 if( mpProperties )
661 {
662 mpProperties->SetObjectItem( rItem );
663 notifyModified();
664 }
665}
666
667void Cell::SetMergedItem(const SfxPoolItem& rItem)
668{
669 SetObjectItem(rItem);
670}
671
672SfxStyleSheet* Cell::GetStyleSheet() const
673{
674 if( mpProperties )
675 return mpProperties->GetStyleSheet();
676 else
677 return nullptr;
678}
679
680void Cell::TakeTextAnchorRect(tools::Rectangle& rAnchorRect) const
681{
682 rAnchorRect.SetLeft( maCellRect.Left() + GetTextLeftDistance() );
683 rAnchorRect.SetRight( maCellRect.Right() - GetTextRightDistance() );
684 rAnchorRect.SetTop( maCellRect.Top() + GetTextUpperDistance() );
685 rAnchorRect.SetBottom( maCellRect.Bottom() - GetTextLowerDistance() );
686}
687
688
689void Cell::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, bool bClearAllItems)
690{
691 if( mpProperties )
692 {
693 mpProperties->SetMergedItemSetAndBroadcast(rSet, bClearAllItems);
694 notifyModified();
695 }
696}
697
698
699sal_Int32 Cell::calcPreferredWidth( const Size aSize )
700{
701 if ( !hasText() )
702 return getMinimumWidth();
703
704 Outliner& rOutliner=static_cast< SdrTableObj& >( GetObject() ).ImpGetDrawOutliner();
705 rOutliner.SetPaperSize(aSize);
706 rOutliner.SetUpdateLayout(true);
707 ForceOutlinerParaObject( OutlinerMode::TextObject );
708
709 if( GetOutlinerParaObject() )
710 rOutliner.SetText(*GetOutlinerParaObject());
711
712 sal_Int32 nPreferredWidth = const_cast<EditEngine&>(rOutliner.GetEditEngine()).CalcTextWidth();
713 rOutliner.Clear();
714
715 return GetTextLeftDistance() + GetTextRightDistance() + nPreferredWidth;
716}
717
718sal_Int32 Cell::getMinimumWidth() const
719{
720 return GetTextLeftDistance() + GetTextRightDistance() + 100;
721}
722
723
724sal_Int32 Cell::getMinimumHeight()
725{
726 if( !mpProperties )
727 return 0;
728
729 SdrTableObj& rTableObj = dynamic_cast< SdrTableObj& >( GetObject() );
730 sal_Int32 nMinimumHeight = 0;
731
732 tools::Rectangle aTextRect;
733 TakeTextAnchorRect( aTextRect );
734 Size aSize( aTextRect.GetSize() );
735 aSize.setHeight(0x0FFFFFFF );
736
737 SdrOutliner* pEditOutliner = rTableObj.GetCellTextEditOutliner( *this );
738 if(pEditOutliner)
739 {
740 pEditOutliner->SetMaxAutoPaperSize(aSize);
741 nMinimumHeight = pEditOutliner->GetTextHeight()+1;
742 }
743 else
744 {
745 Outliner& rOutliner=rTableObj.ImpGetDrawOutliner();
746 rOutliner.SetPaperSize(aSize);
747 rOutliner.SetUpdateLayout(true);
748 ForceOutlinerParaObject( OutlinerMode::TextObject );
749
750 if( GetOutlinerParaObject() )
751 {
752 rOutliner.SetText(*GetOutlinerParaObject());
753 }
754 nMinimumHeight=rOutliner.GetTextHeight()+1;
755 rOutliner.Clear();
756 }
757
758 nMinimumHeight += GetTextUpperDistance() + GetTextLowerDistance();
759 return nMinimumHeight;
760}
761
762
763tools::Long Cell::GetTextLeftDistance() const
764{
765 return GetItemSet().Get(SDRATTR_TEXT_LEFTDIST).GetValue();
766}
767
768
769tools::Long Cell::GetTextRightDistance() const
770{
771 return GetItemSet().Get(SDRATTR_TEXT_RIGHTDIST).GetValue();
772}
773
774
775tools::Long Cell::GetTextUpperDistance() const
776{
777 return GetItemSet().Get(SDRATTR_TEXT_UPPERDIST).GetValue();
778}
779
780
781tools::Long Cell::GetTextLowerDistance() const
782{
783 return GetItemSet().Get(SDRATTR_TEXT_LOWERDIST).GetValue();
784}
785
786
787SdrTextVertAdjust Cell::GetTextVerticalAdjust() const
788{
789 return GetItemSet().Get(SDRATTR_TEXT_VERTADJUST).GetValue();
790}
791
792
793SdrTextHorzAdjust Cell::GetTextHorizontalAdjust() const
794{
795 return GetItemSet().Get(SDRATTR_TEXT_HORZADJUST).GetValue();
796}
797
798
799void Cell::SetOutlinerParaObject( std::optional<OutlinerParaObject> pTextObject )
800{
801 bool bNullTextObject = !pTextObject;
802 SdrText::SetOutlinerParaObject( std::move(pTextObject) );
803 maSelection.nStartPara = EE_PARA_MAX_COUNT;
804
805 if( bNullTextObject )
806 ForceOutlinerParaObject( OutlinerMode::TextObject );
807}
808
809
810void Cell::AddUndo()
811{
812 SdrObject& rObj = GetObject();
813
814 if( rObj.IsInserted() && rObj.getSdrModelFromSdrObject().IsUndoEnabled() )
815 {
816 CellRef xCell( this );
817 rObj.getSdrModelFromSdrObject().AddUndo( std::make_unique<CellUndo>( &rObj, xCell ) );
818
819 // Undo action for the after-text-edit-ended stack.
820 SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(&rObj);
821 if (pTableObj && pTableObj->IsTextEditActive())
822 pTableObj->AddUndo(new CellUndo(pTableObj, xCell));
823 }
824}
825
826
827sdr::properties::TextProperties* Cell::CloneProperties( sdr::properties::TextProperties const * pProperties, SdrObject& rNewObj, Cell& rNewCell )
828{
829 if( pProperties )
830 return new sdr::properties::CellProperties( *static_cast<sdr::properties::CellProperties const *>(pProperties), rNewObj, &rNewCell );
831 else
832 return nullptr;
833}
834
835
836sdr::properties::TextProperties* Cell::CloneProperties( SdrObject& rNewObj, Cell& rNewCell )
837{
838 return CloneProperties(mpProperties.get(),rNewObj,rNewCell);
839}
840
841
842// XInterface
843
844
845Any SAL_CALL Cell::queryInterface( const Type & rType )
846{
848 return Any( Reference< XMergeableCell >( this ) );
849
850 if( rType == cppu::UnoType<XCell>::get() )
851 return Any( Reference< XCell >( this ) );
852
854 return Any( Reference< XLayoutConstrains >( this ) );
855
857 return Any( Reference< XEventListener >( this ) );
858
859 Any aRet( SvxUnoTextBase::queryAggregation( rType ) );
860 if( aRet.hasValue() )
861 return aRet;
862
863 return ::cppu::OWeakObject::queryInterface( rType );
864}
865
866
867void SAL_CALL Cell::acquire() noexcept
868{
870}
871
872
873void SAL_CALL Cell::release() noexcept
874{
876}
877
878
879// XTypeProvider
880
881
882Sequence< Type > SAL_CALL Cell::getTypes( )
883{
885 Sequence {
888}
889
890
891Sequence< sal_Int8 > SAL_CALL Cell::getImplementationId( )
892{
893 return css::uno::Sequence<sal_Int8>();
894}
895
896// XLayoutConstrains
897css::awt::Size SAL_CALL Cell::getMinimumSize()
898{
899 return css::awt::Size( getMinimumWidth(), getMinimumHeight() );
900}
901
902
903css::awt::Size SAL_CALL Cell::getPreferredSize()
904{
905 return getMinimumSize();
906}
907
908
909css::awt::Size SAL_CALL Cell::calcAdjustedSize( const css::awt::Size& aNewSize )
910{
911 return aNewSize;
912}
913
914
915// XMergeableCell
916
917
918sal_Int32 SAL_CALL Cell::getRowSpan()
919{
920 return mnRowSpan;
921}
922
923
924sal_Int32 SAL_CALL Cell::getColumnSpan()
925{
926 return mnColSpan;
927}
928
929
930sal_Bool SAL_CALL Cell::isMerged()
931{
932 return mbMerged;
933}
934
935
936// XCell
937
938
939OUString SAL_CALL Cell::getFormula( )
940{
941 return msFormula;
942}
943
944
945void SAL_CALL Cell::setFormula( const OUString& aFormula )
946{
947 if( msFormula != aFormula )
948 {
949 msFormula = aFormula;
950 }
951}
952
953
954double SAL_CALL Cell::getValue( )
955{
956 return mfValue;
957}
958
959
960void SAL_CALL Cell::setValue( double nValue )
961{
962 if( mfValue != nValue )
963 {
964 mfValue = nValue;
965 mnCellContentType = CellContentType_VALUE;
966 }
967}
968
969
970CellContentType SAL_CALL Cell::getType()
971{
972 return mnCellContentType;
973}
974
975
976sal_Int32 SAL_CALL Cell::getError( )
977{
978 return mnError;
979}
980
981
982// XPropertySet
983
984
985Any Cell::GetAnyForItem( SfxItemSet const & aSet, const SfxItemPropertyMapEntry* pMap )
986{
987 Any aAny( SvxItemPropertySet_getPropertyValue( pMap, aSet ) );
988
989 if( pMap->aType != aAny.getValueType() )
990 {
991 // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
992 if( ( pMap->aType == ::cppu::UnoType<sal_Int16>::get()) && aAny.getValueType() == ::cppu::UnoType<sal_Int32>::get() )
993 {
994 sal_Int32 nValue = 0;
995 aAny >>= nValue;
996 aAny <<= static_cast<sal_Int16>(nValue);
997 }
998 else
999 {
1000 OSL_FAIL("GetAnyForItem() Returnvalue has wrong Type!" );
1001 }
1002 }
1003
1004 return aAny;
1005}
1006
1007Reference< XPropertySetInfo > SAL_CALL Cell::getPropertySetInfo()
1008{
1009 return mpPropSet->getPropertySetInfo();
1010}
1011
1012
1013void SAL_CALL Cell::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
1014{
1015 ::SolarMutexGuard aGuard;
1016
1017 if(mpProperties == nullptr)
1018 throw DisposedException();
1019
1020 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(rPropertyName);
1021 if( pMap )
1022 {
1023 if( (pMap->nFlags & PropertyAttribute::READONLY ) != 0 )
1024 throw PropertyVetoException();
1025
1026 switch( pMap->nWID )
1027 {
1028 case OWN_ATTR_STYLE:
1029 {
1030 Reference< XStyle > xStyle;
1031 if( !( rValue >>= xStyle ) )
1032 throw IllegalArgumentException();
1033
1035 SetStyleSheet( pStyle, true );
1036 return;
1037 }
1039 {
1040 auto pBorder = o3tl::tryAccess<TableBorder>(rValue);
1041 if(!pBorder)
1042 break;
1043
1046 SvxBorderLine aLine;
1047
1048 bool bSet = SvxBoxItem::LineToSvxLine(pBorder->TopLine, aLine, false);
1049 aBox.SetLine(bSet ? &aLine : nullptr, SvxBoxItemLine::TOP);
1050 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::TOP, pBorder->IsTopLineValid);
1051
1052 bSet = SvxBoxItem::LineToSvxLine(pBorder->BottomLine, aLine, false);
1053 aBox.SetLine(bSet ? &aLine : nullptr, SvxBoxItemLine::BOTTOM);
1054 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::BOTTOM, pBorder->IsBottomLineValid);
1055
1056 bSet = SvxBoxItem::LineToSvxLine(pBorder->LeftLine, aLine, false);
1057 aBox.SetLine(bSet ? &aLine : nullptr, SvxBoxItemLine::LEFT);
1058 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::LEFT, pBorder->IsLeftLineValid);
1059
1060 bSet = SvxBoxItem::LineToSvxLine(pBorder->RightLine, aLine, false);
1061 aBox.SetLine(bSet ? &aLine : nullptr, SvxBoxItemLine::RIGHT);
1062 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::RIGHT, pBorder->IsRightLineValid);
1063
1064 bSet = SvxBoxItem::LineToSvxLine(pBorder->HorizontalLine, aLine, false);
1065 aBoxInfo.SetLine(bSet ? &aLine : nullptr, SvxBoxInfoItemLine::HORI);
1066 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::HORI, pBorder->IsHorizontalLineValid);
1067
1068 bSet = SvxBoxItem::LineToSvxLine(pBorder->VerticalLine, aLine, false);
1069 aBoxInfo.SetLine(bSet ? &aLine : nullptr, SvxBoxInfoItemLine::VERT);
1070 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::VERT, pBorder->IsVerticalLineValid);
1071
1072 aBox.SetAllDistances(pBorder->Distance); //TODO
1073 aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::DISTANCE, pBorder->IsDistanceValid);
1074
1075 mpProperties->SetObjectItem(aBox);
1076 mpProperties->SetObjectItem(aBoxInfo);
1077 return;
1078 }
1080 {
1082 if(!(rValue >>= eMode) )
1083 {
1084 sal_Int32 nMode = 0;
1085 if(!(rValue >>= nMode))
1086 throw IllegalArgumentException();
1087
1088 eMode = static_cast<BitmapMode>(nMode);
1089 }
1090
1091 mpProperties->SetObjectItem( XFillBmpStretchItem( eMode == BitmapMode_STRETCH ) );
1092 mpProperties->SetObjectItem( XFillBmpTileItem( eMode == BitmapMode_REPEAT ) );
1093 return;
1094 }
1096 {
1097 sal_Int32 nRotVal = 0;
1098 if (!(rValue >>= nRotVal))
1099 throw IllegalArgumentException();
1100
1101 if (nRotVal != 27000 && nRotVal != 9000 && nRotVal != 0)
1102 throw IllegalArgumentException();
1103
1104 mpProperties->SetObjectItem(SvxTextRotateItem(Degree10(nRotVal/10), SDRATTR_TABLE_TEXT_ROTATION));
1105 return;
1106 }
1107 default:
1108 {
1109 SfxItemSet aSet(GetObject().getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID);
1110 aSet.Put(mpProperties->GetItem(pMap->nWID));
1111
1112 bool bSpecial = false;
1113
1114 switch( pMap->nWID )
1115 {
1116 case XATTR_FILLBITMAP:
1117 case XATTR_FILLGRADIENT:
1118 case XATTR_FILLHATCH:
1120 case XATTR_LINEEND:
1121 case XATTR_LINESTART:
1122 case XATTR_LINEDASH:
1123 {
1124 if( pMap->nMemberId == MID_NAME )
1125 {
1126 OUString aApiName;
1127 if( rValue >>= aApiName )
1128 {
1129 if(SvxShape::SetFillAttribute(pMap->nWID, aApiName, aSet, &GetObject().getSdrModelFromSdrObject()))
1130 bSpecial = true;
1131 }
1132 }
1133 }
1134 break;
1135 }
1136
1137 if( !bSpecial )
1138 {
1139
1140 if( !SvxUnoTextRangeBase::SetPropertyValueHelper( pMap, rValue, aSet ))
1141 {
1142 if( aSet.GetItemState( pMap->nWID ) != SfxItemState::SET )
1143 {
1144 // fetch the default from ItemPool
1145 if(SfxItemPool::IsWhich(pMap->nWID))
1146 aSet.Put(GetObject().getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
1147 }
1148
1149 if( aSet.GetItemState( pMap->nWID ) == SfxItemState::SET )
1150 {
1151 SvxItemPropertySet_setPropertyValue( pMap, rValue, aSet );
1152 }
1153 }
1154 }
1155
1156 GetObject().getSdrModelFromSdrObject().SetChanged();
1157 mpProperties->SetMergedItemSetAndBroadcast( aSet );
1158 return;
1159 }
1160 }
1161 }
1162 throw UnknownPropertyException( rPropertyName, static_cast<cppu::OWeakObject*>(this));
1163}
1164
1165
1166Any SAL_CALL Cell::getPropertyValue( const OUString& PropertyName )
1167{
1168 ::SolarMutexGuard aGuard;
1169
1170 if(mpProperties == nullptr)
1171 throw DisposedException();
1172
1173 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1174 if( pMap )
1175 {
1176 switch( pMap->nWID )
1177 {
1178 case OWN_ATTR_STYLE:
1179 {
1180 return Any( Reference< XStyle >( dynamic_cast< SfxUnoStyleSheet* >( GetStyleSheet() ) ) );
1181 }
1183 {
1184 const SvxBoxInfoItem& rBoxInfoItem = mpProperties->GetItem(SDRATTR_TABLE_BORDER_INNER);
1185 const SvxBoxItem& rBox = mpProperties->GetItem(SDRATTR_TABLE_BORDER);
1186
1187 TableBorder aTableBorder;
1188 aTableBorder.TopLine = SvxBoxItem::SvxLineToLine(rBox.GetTop(), false);
1189 aTableBorder.IsTopLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::TOP);
1190 aTableBorder.BottomLine = SvxBoxItem::SvxLineToLine(rBox.GetBottom(), false);
1191 aTableBorder.IsBottomLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::BOTTOM);
1192 aTableBorder.LeftLine = SvxBoxItem::SvxLineToLine(rBox.GetLeft(), false);
1193 aTableBorder.IsLeftLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::LEFT);
1194 aTableBorder.RightLine = SvxBoxItem::SvxLineToLine(rBox.GetRight(), false);
1195 aTableBorder.IsRightLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::RIGHT );
1196 aTableBorder.HorizontalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetHori(), false);
1197 aTableBorder.IsHorizontalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::HORI);
1198 aTableBorder.VerticalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetVert(), false);
1199 aTableBorder.IsVerticalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::VERT);
1200 aTableBorder.Distance = rBox.GetSmallestDistance();
1201 aTableBorder.IsDistanceValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::DISTANCE);
1202
1203 return Any( aTableBorder );
1204 }
1206 {
1207 const XFillBmpStretchItem& rStretchItem = mpProperties->GetItem(XATTR_FILLBMP_STRETCH);
1208 const XFillBmpTileItem& rTileItem = mpProperties->GetItem(XATTR_FILLBMP_TILE);
1209 if( rTileItem.GetValue() )
1210 {
1211 return Any( BitmapMode_REPEAT );
1212 }
1213 else if( rStretchItem.GetValue() )
1214 {
1215 return Any( BitmapMode_STRETCH );
1216 }
1217 else
1218 {
1219 return Any( BitmapMode_NO_REPEAT );
1220 }
1221 }
1223 {
1224 const SvxTextRotateItem& rTextRotate = mpProperties->GetItem(SDRATTR_TABLE_TEXT_ROTATION);
1225 return Any(sal_Int32(to<Degree100>(rTextRotate.GetValue())));
1226 }
1227 default:
1228 {
1229 SfxItemSet aSet(GetObject().getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID);
1230 aSet.Put(mpProperties->GetItem(pMap->nWID));
1231
1232 Any aAny;
1233 if(!SvxUnoTextRangeBase::GetPropertyValueHelper( aSet, pMap, aAny ))
1234 {
1235 if(!aSet.Count())
1236 {
1237 // fetch the default from ItemPool
1238 if(SfxItemPool::IsWhich(pMap->nWID))
1239 aSet.Put(GetObject().getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
1240 }
1241
1242 if( aSet.Count() )
1243 aAny = GetAnyForItem( aSet, pMap );
1244 }
1245
1246 return aAny;
1247 }
1248 }
1249 }
1250 throw UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
1251}
1252
1253
1254void SAL_CALL Cell::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ )
1255{
1256}
1257
1258
1259void SAL_CALL Cell::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ )
1260{
1261}
1262
1263
1264void SAL_CALL Cell::addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ )
1265{
1266}
1267
1268
1269void SAL_CALL Cell::removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ )
1270{
1271}
1272
1273
1274// XMultiPropertySet
1275
1276
1277void SAL_CALL Cell::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues )
1278{
1279 ::SolarMutexGuard aSolarGuard;
1280
1281 if(mpProperties == nullptr)
1282 throw DisposedException();
1283
1284 const sal_Int32 nCount = aPropertyNames.getLength();
1285
1286 const OUString* pNames = aPropertyNames.getConstArray();
1287 const Any* pValues = aValues.getConstArray();
1288
1289 for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pValues++ )
1290 {
1291 try
1292 {
1293 setPropertyValue( *pNames, *pValues );
1294 }
1295 catch( UnknownPropertyException& )
1296 {
1297 TOOLS_WARN_EXCEPTION("svx.table", "unknown property!");
1298 }
1299 catch( Exception& )
1300 {
1301 TOOLS_WARN_EXCEPTION("svx.table", "");
1302 }
1303 }
1304}
1305
1306
1307Sequence< Any > SAL_CALL Cell::getPropertyValues( const Sequence< OUString >& aPropertyNames )
1308{
1309 ::SolarMutexGuard aSolarGuard;
1310
1311 if(mpProperties == nullptr)
1312 throw DisposedException();
1313
1314 const sal_Int32 nCount = aPropertyNames.getLength();
1315 Sequence< Any > aRet( nCount );
1316 Any* pValue = aRet.getArray();
1317
1318 for( const OUString& rName : aPropertyNames )
1319 {
1320 try
1321 {
1322 *pValue = getPropertyValue( rName );
1323 }
1324 catch( UnknownPropertyException& )
1325 {
1326 TOOLS_WARN_EXCEPTION("svx.table", "unknown property!");
1327 }
1328 catch( Exception& )
1329 {
1330 TOOLS_WARN_EXCEPTION("svx.table", "");
1331 }
1332 pValue++;
1333 }
1334
1335 return aRet;
1336}
1337
1338
1339void SAL_CALL Cell::addPropertiesChangeListener( const Sequence< OUString >& /*aPropertyNames*/, const Reference< XPropertiesChangeListener >& /*xListener*/ )
1340{
1341}
1342
1343
1344void SAL_CALL Cell::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& /*xListener*/ )
1345{
1346}
1347
1348
1349void SAL_CALL Cell::firePropertiesChangeEvent( const Sequence< OUString >& /*aPropertyNames*/, const Reference< XPropertiesChangeListener >& /*xListener*/ )
1350{
1351}
1352
1353
1354// XPropertyState
1355
1356
1357PropertyState SAL_CALL Cell::getPropertyState( const OUString& PropertyName )
1358{
1359 ::SolarMutexGuard aGuard;
1360
1361 if(mpProperties == nullptr)
1362 throw DisposedException();
1363
1364 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1365
1366 if( pMap )
1367 {
1368 PropertyState eState;
1369 switch( pMap->nWID )
1370 {
1372 {
1373 const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
1374
1375 const bool bStretch = rSet.GetItemState( XATTR_FILLBMP_STRETCH, false ) == SfxItemState::SET;
1376 const bool bTile = rSet.GetItemState( XATTR_FILLBMP_TILE, false ) == SfxItemState::SET;
1377 if( bStretch || bTile )
1378 {
1379 eState = PropertyState_DIRECT_VALUE;
1380 }
1381 else
1382 {
1383 eState = PropertyState_DEFAULT_VALUE;
1384 }
1385 break;
1386 }
1387 case OWN_ATTR_STYLE:
1388 {
1389 return PropertyState_DIRECT_VALUE;
1390 }
1392 {
1393 const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
1394 if( (rSet.GetItemState( SDRATTR_TABLE_BORDER_INNER, false ) == SfxItemState::DEFAULT) && (rSet.GetItemState( SDRATTR_TABLE_BORDER, false ) == SfxItemState::DEFAULT) )
1395 return PropertyState_DEFAULT_VALUE;
1396
1397 return PropertyState_DIRECT_VALUE;
1398 }
1399 default:
1400 {
1401 const SfxItemSet& rSet = mpProperties->GetMergedItemSet();
1402
1403 switch( rSet.GetItemState( pMap->nWID, false ) )
1404 {
1405 case SfxItemState::SET:
1406 eState = PropertyState_DIRECT_VALUE;
1407 break;
1408 case SfxItemState::DEFAULT:
1409 eState = PropertyState_DEFAULT_VALUE;
1410 break;
1411 default:
1412 eState = PropertyState_AMBIGUOUS_VALUE;
1413 break;
1414 }
1415
1416 // if an item is set, this doesn't mean we want it :)
1417 if( PropertyState_DIRECT_VALUE == eState )
1418 {
1419 switch( pMap->nWID )
1420 {
1421 // the following items are disabled by changing the
1422 // fill style or the line style. so there is no need
1423 // to export items without names which should be empty
1424 case XATTR_FILLBITMAP:
1425 case XATTR_FILLGRADIENT:
1426 case XATTR_FILLHATCH:
1427 case XATTR_LINEDASH:
1428 {
1429 const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID);
1430 if( ( pItem == nullptr ) || pItem->GetName().isEmpty() )
1431 eState = PropertyState_DEFAULT_VALUE;
1432 }
1433 break;
1434
1435 // #i36115#
1436 // If e.g. the LineStart is on NONE and thus the string has length 0, it still
1437 // may be a hard attribute covering the set LineStart of the parent (Style).
1438 // #i37644#
1439 // same is for fill float transparency
1440 case XATTR_LINEEND:
1441 case XATTR_LINESTART:
1443 {
1444 const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID);
1445 if( pItem == nullptr )
1446 eState = PropertyState_DEFAULT_VALUE;
1447 }
1448 break;
1449 case XATTR_FILLCOLOR:
1450 if (pMap->nMemberId == MID_COLOR_THEME_INDEX)
1451 {
1452 const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1453 if (pColor->GetThemeColor().GetThemeIndex() == -1)
1454 {
1455 eState = PropertyState_DEFAULT_VALUE;
1456 }
1457 }
1458 else if (pMap->nMemberId == MID_COLOR_LUM_MOD)
1459 {
1460 const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1461 if (pColor->GetThemeColor().GetLumMod() == 10000)
1462 {
1463 eState = PropertyState_DEFAULT_VALUE;
1464 }
1465 }
1466 else if (pMap->nMemberId == MID_COLOR_LUM_OFF)
1467 {
1468 const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
1469 if (pColor->GetThemeColor().GetLumOff() == 0)
1470 {
1471 eState = PropertyState_DEFAULT_VALUE;
1472 }
1473 }
1474 }
1475 }
1476 }
1477 }
1478 return eState;
1479 }
1480 throw UnknownPropertyException(PropertyName);
1481}
1482
1483
1484Sequence< PropertyState > SAL_CALL Cell::getPropertyStates( const Sequence< OUString >& aPropertyName )
1485{
1486 ::SolarMutexGuard aGuard;
1487
1488 if(mpProperties == nullptr)
1489 throw DisposedException();
1490
1491 const sal_Int32 nCount = aPropertyName.getLength();
1492 Sequence< PropertyState > aRet( nCount );
1493
1494 std::transform(aPropertyName.begin(), aPropertyName.end(), aRet.getArray(),
1495 [this](const OUString& rName) -> PropertyState {
1496 try
1497 {
1498 return getPropertyState( rName );
1499 }
1500 catch( Exception& )
1501 {
1502 return PropertyState_AMBIGUOUS_VALUE;
1503 }
1504 });
1505
1506 return aRet;
1507}
1508
1509
1510void SAL_CALL Cell::setPropertyToDefault( const OUString& PropertyName )
1511{
1512 ::SolarMutexGuard aGuard;
1513
1514 if(mpProperties == nullptr)
1515 throw DisposedException();
1516
1517 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(PropertyName);
1518 if( pMap )
1519 {
1520 switch( pMap->nWID )
1521 {
1523 {
1524 mpProperties->ClearObjectItem( XATTR_FILLBMP_STRETCH );
1525 mpProperties->ClearObjectItem( XATTR_FILLBMP_TILE );
1526 break;
1527 }
1528 case OWN_ATTR_STYLE:
1529 break;
1530
1532 {
1533 mpProperties->ClearObjectItem( SDRATTR_TABLE_BORDER_INNER );
1534 mpProperties->ClearObjectItem( SDRATTR_TABLE_BORDER );
1535 break;
1536 }
1537
1538 default:
1539 {
1540 mpProperties->ClearObjectItem( pMap->nWID );
1541 }
1542 }
1543
1544 GetObject().getSdrModelFromSdrObject().SetChanged();
1545 return;
1546 }
1547 throw UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
1548}
1549
1550
1551Any SAL_CALL Cell::getPropertyDefault( const OUString& aPropertyName )
1552{
1553 ::SolarMutexGuard aGuard;
1554
1555 if(mpProperties == nullptr)
1556 throw DisposedException();
1557
1558 const SfxItemPropertyMapEntry* pMap = mpPropSet->getPropertyMapEntry(aPropertyName);
1559 if( pMap )
1560 {
1561 switch( pMap->nWID )
1562 {
1564 return Any( BitmapMode_NO_REPEAT );
1565
1566 case OWN_ATTR_STYLE:
1567 {
1568 Reference< XStyle > xStyle;
1569 return Any( xStyle );
1570 }
1571
1573 {
1574 TableBorder aBorder;
1575 return Any( aBorder );
1576 }
1577
1578 default:
1579 {
1580 if( SfxItemPool::IsWhich(pMap->nWID) )
1581 {
1582 SfxItemSet aSet(GetObject().getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID);
1583 aSet.Put(GetObject().getSdrModelFromSdrObject().GetItemPool().GetDefaultItem(pMap->nWID));
1584 return GetAnyForItem( aSet, pMap );
1585 }
1586 }
1587 }
1588 }
1589 throw UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this));
1590}
1591
1592
1593// XMultiPropertyStates
1594
1595
1596void SAL_CALL Cell::setAllPropertiesToDefault()
1597{
1598 mpProperties.reset(new sdr::properties::CellProperties( static_cast< SdrTableObj& >( GetObject() ), this ));
1599
1600 SdrOutliner& rOutliner = GetObject().ImpGetDrawOutliner();
1601
1602 OutlinerParaObject* pParaObj = GetOutlinerParaObject();
1603 if( !pParaObj )
1604 return;
1605
1606 rOutliner.SetText(*pParaObj);
1607 sal_Int32 nParaCount(rOutliner.GetParagraphCount());
1608
1609 if(nParaCount)
1610 {
1611 ESelection aSelection( 0, 0, EE_PARA_ALL, EE_TEXTPOS_ALL);
1612 rOutliner.RemoveAttribs(aSelection, true, 0);
1613
1614 std::optional<OutlinerParaObject> pTemp = rOutliner.CreateParaObject(0, nParaCount);
1615 rOutliner.Clear();
1616
1617 SetOutlinerParaObject(std::move(pTemp));
1618 }
1619}
1620
1621
1622void SAL_CALL Cell::setPropertiesToDefault( const Sequence< OUString >& aPropertyNames )
1623{
1624 for(const OUString& rName : aPropertyNames)
1625 setPropertyToDefault( rName );
1626}
1627
1628
1629Sequence< Any > SAL_CALL Cell::getPropertyDefaults( const Sequence< OUString >& aPropertyNames )
1630{
1631 sal_Int32 nCount = aPropertyNames.getLength();
1632 Sequence< Any > aDefaults( nCount );
1633
1634 std::transform(aPropertyNames.begin(), aPropertyNames.end(), aDefaults.getArray(),
1635 [this](const OUString& rName) -> Any { return getPropertyDefault(rName); });
1636
1637 return aDefaults;
1638}
1639
1640
1641// XText
1642
1643
1644void SAL_CALL Cell::insertTextContent( const Reference< XTextRange >& xRange, const Reference< XTextContent >& xContent, sal_Bool bAbsorb )
1645{
1646 SvxUnoTextBase::insertTextContent( xRange, xContent, bAbsorb );
1647 notifyModified();
1648}
1649
1650
1651void SAL_CALL Cell::removeTextContent( const Reference< XTextContent >& xContent )
1652{
1654 notifyModified();
1655}
1656
1657
1658// XSimpleText
1659
1660
1661void SAL_CALL Cell::insertString( const Reference< XTextRange >& xRange, const OUString& aString, sal_Bool bAbsorb )
1662{
1663 SvxUnoTextBase::insertString( xRange, aString, bAbsorb );
1664 notifyModified();
1665}
1666
1667
1668void SAL_CALL Cell::insertControlCharacter( const Reference< XTextRange >& xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb )
1669{
1670 SvxUnoTextBase::insertControlCharacter( xRange, nControlCharacter, bAbsorb );
1671 notifyModified();
1672}
1673
1674
1675// XTextRange
1676
1677
1678OUString SAL_CALL Cell::getString( )
1679{
1680 maSelection.nStartPara = EE_PARA_MAX_COUNT;
1682}
1683
1684
1685void SAL_CALL Cell::setString( const OUString& aString )
1686{
1687 SvxUnoTextBase::setString( aString );
1688 notifyModified();
1689}
1690
1691// XEventListener
1692void SAL_CALL Cell::disposing( const EventObject& /*Source*/ )
1693{
1694 mxTable.clear();
1695 dispose();
1696}
1697
1698void Cell::dumpAsXml(xmlTextWriterPtr pWriter, sal_Int32 nRow, sal_Int32 nCol) const
1699{
1700 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("Cell"));
1701 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("row"), "%" SAL_PRIdINT32, nRow);
1702 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("col"), "%" SAL_PRIdINT32, nCol);
1703 SdrText::dumpAsXml(pWriter);
1704 //SvxUnoTextBase::dumpAsXml(pWriter);
1705 //mpPropSet->dumpAsXml(pWriter);
1706 mpProperties->dumpAsXml(pWriter);
1707 (void)xmlTextWriterEndElement(pWriter);
1708}
1709
1710}
1711
1712/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
static const SvxItemPropertySet * ImplGetSvxCellPropertySet()
Definition: cell.cxx:75
virtual sal_Int32 GetParagraphCount() const=0
virtual OUString GetText(sal_Int32 nPara) const=0
OUString const & GetName() const
Definition: xit.hxx:53
const EditTextObject & GetTextObject() const
void SetVertical(bool bNew)
void SetRotation(TextRotation nRotation)
void SetMaxAutoPaperSize(const Size &rSz)
void SetText(const OutlinerParaObject &)
const EditEngine & GetEditEngine() const
void AddText(const OutlinerParaObject &, bool bAppend=false)
std::optional< OutlinerParaObject > CreateParaObject(sal_Int32 nStartPara=0, sal_Int32 nParaCount=EE_PARA_ALL) const
void SetPaperSize(const Size &rSize)
void Clear()
bool SetUpdateLayout(bool bUpdate)
void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &)
void RemoveAttribs(const ESelection &rSelection, bool bRemoveParaAttribs, sal_uInt16 nWhich)
SfxItemSet const & GetParaAttribs(sal_Int32 nPara) const
sal_uInt32 GetTextHeight() const
void RemoveCharAttribs(sal_Int32 nPara, sal_uInt16 nWhich=0)
sal_Int32 GetParagraphCount() const
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdoattr.cxx:49
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdmodel.cxx:494
bool IsUndoEnabled() const
returns true if undo is currently enabled This returns false if undo was disabled using EnableUndo( f...
Definition: svdmodel.cxx:525
Abstract DrawObject.
Definition: svdobj.hxx:261
static SdrItemPool & GetGlobalDrawObjectItemPool()
Definition: svdobj.cxx:548
void SetObjectItemSet(const SfxItemSet &rSet)
Definition: svdobj.cxx:1997
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:289
virtual void SetSnapRect(const tools::Rectangle &rRect)
Definition: svdobj.cxx:1690
bool IsInserted() const
Definition: svdobj.hxx:750
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1972
SdrOutliner & ImpGetDrawOutliner() const
Definition: svdotext.cxx:1179
SVX_DLLPRIVATE SdrOutliner * GetTextEditOutliner() const
Definition: svdotext.hxx:143
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: svdtext.cxx:146
virtual void SetOutlinerParaObject(std::optional< OutlinerParaObject > pTextObject)
Definition: svdtext.cxx:72
bool GetValue() const
static bool IsWhich(sal_uInt16 nId)
SfxItemPool * GetPool() const
sal_uInt16 Count() const
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
SfxStyleFamily GetFamily() const
static SfxUnoStyleSheet * getUnoStyleSheet(const css::uno::Reference< css::style::XStyle > &xStyle)
void setHeight(tools::Long nHeight)
bool IsValid(SvxBoxInfoItemValidFlags nValid) const
const editeng::SvxBorderLine * GetHori() const
const editeng::SvxBorderLine * GetVert() const
static bool LineToSvxLine(const css::table::BorderLine &rLine, editeng::SvxBorderLine &rSvxLine, bool bConvert)
const editeng::SvxBorderLine * GetTop() const
sal_uInt16 GetSmallestDistance() const
const editeng::SvxBorderLine * GetRight() const
static css::table::BorderLine2 SvxLineToLine(const editeng::SvxBorderLine *pLine, bool bConvert)
const editeng::SvxBorderLine * GetLeft() const
const editeng::SvxBorderLine * GetBottom() const
bool SetFillAttribute(sal_uInt16 nWID, const OUString &rName)
Definition: unoshape.cxx:1295
bool IsVertical() const
Degree10 GetValue() const
bool IsTopToBottom() const
sal_Int16 GetLumMod() const
sal_Int16 GetThemeIndex() const
sal_Int16 GetLumOff() const
virtual void SAL_CALL removeTextContent(const css::uno::Reference< css::text::XTextContent > &xContent) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
virtual void SAL_CALL insertString(const css::uno::Reference< css::text::XTextRange > &xRange, const OUString &aString, sal_Bool bAbsorb) override
virtual void SAL_CALL insertTextContent(const css::uno::Reference< css::text::XTextRange > &xRange, const css::uno::Reference< css::text::XTextContent > &xContent, sal_Bool bAbsorb) override
virtual void SAL_CALL setString(const OUString &aString) override
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &rType)
virtual void SAL_CALL insertControlCharacter(const css::uno::Reference< css::text::XTextRange > &xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb) override
virtual OUString SAL_CALL getString() override
SvxThemeColor & GetThemeColor()
Definition: xcolit.hxx:54
virtual void SAL_CALL acquire() SAL_NOEXCEPT SAL_OVERRIDE
virtual void SAL_CALL release() SAL_NOEXCEPT SAL_OVERRIDE
css::uno::Type const & get()
virtual void ItemSetChanged(o3tl::span< const SfxPoolItem *const > aChangedItems, sal_uInt16 nDeletedWhich) override
virtual void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem *pNewItem=nullptr) override
virtual const SfxItemSet & GetObjectItemSet() const override
const SdrObject & GetSdrObject() const
Definition: properties.cxx:43
SfxItemSet CreateObjectSpecificItemSet(SfxItemPool &rPool) override
Definition: cell.cxx:181
void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem *pNewItem=nullptr) override
Definition: cell.cxx:301
const CellTextProvider maTextProvider
Definition: cell.cxx:177
std::unique_ptr< BaseProperties > Clone(SdrObject &rObj) const override
Definition: cell.cxx:216
sdr::table::CellRef mxCell
Definition: cell.cxx:174
const svx::ITextProvider & getTextProvider() const override
Get the TextProvider related to our SdrObject.
Definition: cell.cxx:197
void ForceDefaultAttributes() override
Definition: cell.cxx:222
CellProperties(SdrObject &rObj, sdr::table::Cell *pCell)
Definition: cell.cxx:202
void ItemSetChanged(o3tl::span< const SfxPoolItem *const > aChangedItems, sal_uInt16 nDeletedWhich) override
Definition: cell.cxx:226
std::optional< SfxItemSet > mxItemSet
void AddUndo(SdrUndoAction *pUndo)
Add an undo action that should be on the undo stack after ending text edit.
Definition: svdotable.cxx:2071
virtual void SetVerticalWriting(bool bVertical) override
Definition: svdotable.cxx:2036
This interface provides access to text object(s) in an SdrObject.
virtual sal_Int32 getTextCount() const =0
Return the number of texts available for this object.
virtual SdrText * getText(sal_Int32 nIndex) const =0
Return the nth available text.
constexpr void SetLeft(tools::Long v)
constexpr void SetTop(tools::Long v)
constexpr void SetRight(tools::Long v)
constexpr Size GetSize() const
constexpr void SetBottom(tools::Long v)
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
virtual css::uno::Reference< css::embed::XEmbeddedObject > GetObject() override
float u
#define EE_PARA_MAX_COUNT
constexpr sal_uInt16 EE_ITEMS_END(EE_FEATURE_END)
constexpr sal_uInt16 EE_ITEMS_START(OWN_ATTR_VALUE_END+1)
struct _xmlTextWriter * xmlTextWriterPtr
sal_Int16 nValue
Definition: fmsrccfg.cxx:81
Mode eMode
#define BOTTOM_BORDER
#define TOP_BORDER
#define RIGHT_BORDER
#define LEFT_BORDER
const SfxItemSet * GetItemSet(const SfxPoolItem &rAttr)
bool isActive()
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
Type
VBAHELPER_DLLPUBLIC bool setPropertyValue(css::uno::Sequence< css::beans::PropertyValue > &aProp, const OUString &aName, const css::uno::Any &aValue)
rtl::Reference< Cell > CellRef
Definition: celltypes.hxx:33
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
static constexpr auto Items
void dispose()
long Long
BitmapMode
const char GetValue[]
SdrOnOffItem makeSdrTextAutoGrowHeightItem(bool bAuto)
Definition: sdtagitm.hxx:25
SdrOnOffItem makeSdrTextAutoGrowWidthItem(bool bAuto)
Definition: sdtagitm.hxx:30
SdrTextVertAdjust
Definition: sdtaitm.hxx:29
SdrTextHorzAdjust
Definition: sdtaitm.hxx:53
static SfxItemSet & rSet
css::uno::Type aType
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_TEXT_AUTOGROWWIDTH(SDRATTR_MISC_FIRST+12)
constexpr sal_uInt16 SDRATTR_TABLE_FIRST(SDRATTR_CUSTOMSHAPE_LAST+1)
constexpr TypedWhichId< SdrMetricItem > SDRATTR_TEXT_LEFTDIST(SDRATTR_MISC_FIRST+4)
constexpr sal_uInt16 SDRATTR_START(XATTR_START)
constexpr TypedWhichId< SvxBoxInfoItem > SDRATTR_TABLE_BORDER_INNER(SDRATTR_TABLE_FIRST+1)
constexpr sal_uInt16 SDRATTR_TABLE_LAST(SDRATTR_TABLE_TEXT_ROTATION)
constexpr TypedWhichId< SdrTextHorzAdjustItem > SDRATTR_TEXT_HORZADJUST(SDRATTR_MISC_FIRST+13)
constexpr sal_uInt16 SDRATTR_MISC_FIRST(SDRATTR_CAPTION_LAST+1)
constexpr TypedWhichId< SvxTextRotateItem > SDRATTR_TABLE_TEXT_ROTATION(SDRATTR_TABLE_FIRST+4)
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_TEXT_AUTOGROWHEIGHT(SDRATTR_MISC_FIRST+2)
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_TEXT_WORDWRAP(SDRATTR_MISC_FIRST+24)
constexpr sal_uInt16 SDRATTR_SHADOW_LAST(SDRATTR_SHADOWBLUR)
constexpr sal_uInt16 SDRATTR_MISC_LAST(SDRATTR_TEXT_CHAINNEXTNAME)
constexpr TypedWhichId< SdrTextVertAdjustItem > SDRATTR_TEXT_VERTADJUST(SDRATTR_MISC_FIRST+8)
constexpr TypedWhichId< SvxBoxItem > SDRATTR_TABLE_BORDER(SDRATTR_TABLE_FIRST+0)
constexpr TypedWhichId< SdrMetricItem > SDRATTR_TEXT_RIGHTDIST(SDRATTR_MISC_FIRST+5)
constexpr TypedWhichId< SdrMetricItem > SDRATTR_TEXT_LOWERDIST(SDRATTR_MISC_FIRST+7)
constexpr TypedWhichId< SvxWritingModeItem > SDRATTR_TEXTDIRECTION(SDRATTR_NOTPERSIST_FIRST+34)
constexpr TypedWhichId< SdrMetricItem > SDRATTR_TEXT_UPPERDIST(SDRATTR_MISC_FIRST+6)
std::vector< sal_uInt16 > GetAllCharPropIds(const SfxItemSet &rSet)
Definition: svdedtv1.cxx:1033
SvxBoxInfoItem & rBoxInfoItem
sal_Int32 mnColSpan
sal_Int32 mnRowSpan
unsigned char sal_Bool
constexpr OUStringLiteral UNO_NAME_TEXT_LOWERDIST
constexpr OUStringLiteral UNO_NAME_TEXT_UPPERDIST
constexpr OUStringLiteral UNO_NAME_TEXT_HORZADJUST
constexpr OUStringLiteral UNO_NAME_TEXT_WORDWRAP
constexpr OUStringLiteral UNO_NAME_TEXT_VERTADJUST
constexpr OUStringLiteral UNO_NAME_TEXT_LEFTDIST
constexpr OUStringLiteral UNO_NAME_TEXT_WRITINGMODE
constexpr OUStringLiteral UNO_NAME_TEXT_RIGHTDIST
void SvxItemPropertySet_setPropertyValue(const SfxItemPropertyMapEntry *pMap, const uno::Any &rVal, SfxItemSet &rSet)
Definition: unoshape.cxx:3978
uno::Any SvxItemPropertySet_getPropertyValue(const SfxItemPropertyMapEntry *pMap, const SfxItemSet &rSet)
Definition: unoshape.cxx:3968
#define OWN_ATTR_STYLE
Definition: unoshprp.hxx:176
#define OWN_ATTR_TABLEBORDER
Definition: unoshprp.hxx:145
#define OWN_ATTR_FILLBMP_MODE
Definition: unoshprp.hxx:114
#define FILL_PROPERTIES
Definition: unoshprp.hxx:275
const SvxItemPropertySet * ImplGetSvxUnoOutlinerTextCursorSvxPropertySet()
#define SVX_UNOEDIT_OUTLINER_PROPERTIES
#define SVX_UNOEDIT_CHAR_PROPERTIES
#define SVX_UNOEDIT_PARA_PROPERTIES
constexpr TypedWhichId< XFillColorItem > XATTR_FILLCOLOR(XATTR_FILL_FIRST+1)
constexpr TypedWhichId< XLineDashItem > XATTR_LINEDASH(XATTR_LINE_FIRST+1)
constexpr TypedWhichId< XLineEndItem > XATTR_LINEEND(XATTR_LINE_FIRST+5)
constexpr TypedWhichId< XLineStartItem > XATTR_LINESTART(XATTR_LINE_FIRST+4)
constexpr TypedWhichId< XFillBmpStretchItem > XATTR_FILLBMP_STRETCH(XATTR_FILL_FIRST+16)
constexpr TypedWhichId< XFillHatchItem > XATTR_FILLHATCH(XATTR_FILL_FIRST+3)
constexpr TypedWhichId< XFillBmpTileItem > XATTR_FILLBMP_TILE(XATTR_FILL_FIRST+7)
constexpr TypedWhichId< XFillBitmapItem > XATTR_FILLBITMAP(XATTR_FILL_FIRST+4)
constexpr TypedWhichId< XFillFloatTransparenceItem > XATTR_FILLFLOATTRANSPARENCE(XATTR_FILL_FIRST+11)
constexpr TypedWhichId< XFillGradientItem > XATTR_FILLGRADIENT(XATTR_FILL_FIRST+2)