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