tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / core / data / patattr.cxx
blob59c5753633f0fe21e98536c686983ec1dadd9df2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <utility>
22 #include <scitems.hxx>
23 #include <editeng/adjustitem.hxx>
24 #include <editeng/boxitem.hxx>
25 #include <editeng/lineitem.hxx>
26 #include <editeng/brushitem.hxx>
27 #include <editeng/charreliefitem.hxx>
28 #include <editeng/contouritem.hxx>
29 #include <svtools/colorcfg.hxx>
30 #include <editeng/colritem.hxx>
31 #include <editeng/crossedoutitem.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <editeng/emphasismarkitem.hxx>
34 #include <editeng/fhgtitem.hxx>
35 #include <editeng/fontitem.hxx>
36 #include <editeng/forbiddenruleitem.hxx>
37 #include <editeng/frmdiritem.hxx>
38 #include <editeng/langitem.hxx>
39 #include <editeng/postitem.hxx>
40 #include <svx/rotmodit.hxx>
41 #include <editeng/scriptspaceitem.hxx>
42 #include <editeng/shaditem.hxx>
43 #include <editeng/shdditem.hxx>
44 #include <editeng/udlnitem.hxx>
45 #include <editeng/wghtitem.hxx>
46 #include <editeng/wrlmitem.hxx>
47 #include <editeng/justifyitem.hxx>
48 #include <svl/intitem.hxx>
49 #include <svl/numformat.hxx>
50 #include <svl/zforlist.hxx>
51 #include <vcl/outdev.hxx>
52 #include <tools/fract.hxx>
53 #include <tools/UnitConversion.hxx>
54 #include <osl/diagnose.h>
56 #include <attrib.hxx>
57 #include <patattr.hxx>
58 #include <stlsheet.hxx>
59 #include <stlpool.hxx>
60 #include <document.hxx>
61 #include <globstr.hrc>
62 #include <scresid.hxx>
63 #include <validat.hxx>
64 #include <scmod.hxx>
65 #include <fillinfo.hxx>
66 #include <comphelper/lok.hxx>
67 #include <tabvwsh.hxx>
69 CellAttributeHelper::CellAttributeHelper(SfxItemPool& rSfxItemPool)
70 : mrSfxItemPool(rSfxItemPool)
71 , mpDefaultCellAttribute(nullptr)
72 , maRegisteredCellAttributes()
73 , mpLastHit(nullptr)
74 , mnCurrentMaxKey(0)
78 CellAttributeHelper::~CellAttributeHelper()
80 delete mpDefaultCellAttribute;
83 static int CompareStringPtr(const OUString* lhs, const OUString* rhs)
85 if (lhs == rhs)
86 return 0;
87 if (lhs && rhs)
88 return (*lhs).compareTo(*rhs);
89 if (!lhs && rhs)
90 return -1;
91 return 1;
94 const ScPatternAttr* CellAttributeHelper::registerAndCheck(const ScPatternAttr& rCandidate, bool bPassingOwnership) const
96 if (&rCandidate == &getDefaultCellAttribute())
97 return &rCandidate;
99 assert(rCandidate.pCellAttributeHelper == this && "WRONG CellAttributeHelper in ScPatternAttr (!)");
101 if (rCandidate.isRegistered())
103 assert(!bPassingOwnership && "Trying to register an already registered CellAttribute with ownership change (!)");
104 rCandidate.mnRefCount++;
105 return &rCandidate;
108 if (ScPatternAttr::areSame(mpLastHit, &rCandidate))
110 // hit for single-entry cache, make use of it
111 mpLastHit->mnRefCount++;
112 if (bPassingOwnership)
113 delete &rCandidate;
114 return mpLastHit;
116 const OUString* pCandidateStyleName = rCandidate.GetStyleName();
117 auto it = maRegisteredCellAttributes.lower_bound(pCandidateStyleName);
118 for (; it != maRegisteredCellAttributes.end(); ++it)
120 const ScPatternAttr* pCheck = *it;
121 if (CompareStringPtr(pCheck->GetStyleName(), pCandidateStyleName) != 0)
122 break;
123 if (ScPatternAttr::areSame(pCheck, &rCandidate))
125 pCheck->mnRefCount++;
126 if (bPassingOwnership)
127 delete &rCandidate;
128 mpLastHit = pCheck;
129 return pCheck;
133 const ScPatternAttr* pCandidate(bPassingOwnership ? &rCandidate : new ScPatternAttr(rCandidate));
134 pCandidate->mnRefCount++;
135 const_cast<ScPatternAttr*>(pCandidate)->SetPAKey(mnCurrentMaxKey++);
136 maRegisteredCellAttributes.insert(pCandidate);
137 mpLastHit = pCandidate;
138 return pCandidate;
141 void CellAttributeHelper::doUnregister(const ScPatternAttr& rCandidate)
143 if (&rCandidate == &getDefaultCellAttribute())
144 return;
146 assert(rCandidate.isRegistered());
147 rCandidate.mnRefCount--;
149 if (0 != rCandidate.mnRefCount)
150 return;
152 if (mpLastHit == &rCandidate)
153 mpLastHit = nullptr;
155 maRegisteredCellAttributes.erase(&rCandidate);
156 delete &rCandidate;
159 const ScPatternAttr& CellAttributeHelper::getDefaultCellAttribute() const
161 // *have* to create on-demand due to mrScDocument.GetPool() *can* be nullptr
162 // since mxPoolHelper is *only* created for SCDOCMODE_DOCUMENT and
163 // SCDOCMODE_FUNCTIONACCESS (!)
164 if (!mpDefaultCellAttribute)
166 // GetRscString only works after ScGlobal::Init (indicated by the EmptyBrushItem)
167 // TODO: Write additional method ScGlobal::IsInit() or somesuch
168 // or detect whether this is the Secondary Pool for a MessagePool
169 if (ScGlobal::GetEmptyBrushItem())
171 const OUString aInitialStyle(ScResId(STR_STYLENAME_STANDARD));
172 mpDefaultCellAttribute = new ScPatternAttr(
173 *const_cast<CellAttributeHelper*>(this),
174 nullptr, // no SfxItemSet
175 &aInitialStyle);
177 else
179 mpDefaultCellAttribute = new ScPatternAttr(*const_cast<CellAttributeHelper*>(this));
182 return *mpDefaultCellAttribute;
185 void CellAttributeHelper::CellStyleDeleted(const ScStyleSheet& rStyle)
187 const OUString& rCandidateStyleName = rStyle.GetName();
188 auto it = maRegisteredCellAttributes.lower_bound(&rCandidateStyleName);
189 for (; it != maRegisteredCellAttributes.end(); ++it)
191 const ScPatternAttr* pCheck = *it;
192 if (CompareStringPtr(pCheck->GetStyleName(), &rCandidateStyleName) != 0)
193 break;
194 if (&rStyle == pCheck->GetStyleSheet())
195 const_cast<ScPatternAttr*>(pCheck)->StyleToName();
199 void CellAttributeHelper::CellStyleCreated(ScDocument& rDoc, const OUString& rName)
201 // If a style was created, don't keep any pattern with its name string in the pool,
202 // because it would compare equal to a pattern with a pointer to the new style.
203 // Calling StyleSheetChanged isn't enough because the pool may still contain items
204 // for undo or clipboard content.
205 std::vector<const ScPatternAttr*> aChanged;
206 auto it = maRegisteredCellAttributes.lower_bound(&rName);
207 while(it != maRegisteredCellAttributes.end())
209 const ScPatternAttr* pCheck = *it;
210 if (CompareStringPtr(pCheck->GetStyleName(), &rName) != 0)
211 break;
212 // tdf#163831 Invalidate cache if the style is modified/created
213 const_cast<ScPatternAttr*>(pCheck)->InvalidateCaches();
214 if (nullptr == pCheck->GetStyleSheet())
215 if (const_cast<ScPatternAttr*>(pCheck)->UpdateStyleSheet(rDoc)) // find and store style pointer
217 aChanged.push_back(pCheck);
218 // if the name changed, we have to re-insert it
219 it = maRegisteredCellAttributes.erase(it);
221 else
222 ++it;
223 else
224 ++it;
226 for (const ScPatternAttr* p : aChanged)
227 maRegisteredCellAttributes.insert(p);
230 void CellAttributeHelper::UpdateAllStyleSheets(ScDocument& rDoc)
232 bool bNameChanged = false;
233 for (const ScPatternAttr* pCheck : maRegisteredCellAttributes)
234 bNameChanged |= const_cast<ScPatternAttr*>(pCheck)->UpdateStyleSheet(rDoc);
235 if (bNameChanged)
236 ReIndexRegistered();
238 // force existence, then access
239 getDefaultCellAttribute();
240 mpDefaultCellAttribute->UpdateStyleSheet(rDoc);
243 void CellAttributeHelper::AllStylesToNames()
245 for (const ScPatternAttr* pCheck : maRegisteredCellAttributes)
246 const_cast<ScPatternAttr*>(pCheck)->StyleToName();
248 // force existence, then access
249 getDefaultCellAttribute();
250 mpDefaultCellAttribute->StyleToName();
253 /// If the style name changed, we need to reindex.
254 void CellAttributeHelper::ReIndexRegistered()
256 RegisteredAttrSet aNewSet;
257 for (auto const & p : maRegisteredCellAttributes)
258 aNewSet.insert(p);
259 maRegisteredCellAttributes = std::move(aNewSet);
262 bool CellAttributeHelper::RegisteredAttrSetLess::operator()(const ScPatternAttr* lhs, const ScPatternAttr* rhs) const
264 int cmp = CompareStringPtr(lhs->GetStyleName(), rhs->GetStyleName());
265 if (cmp < 0)
266 return true;
267 if (cmp > 0)
268 return false;
269 return lhs < rhs;
271 bool CellAttributeHelper::RegisteredAttrSetLess::operator()(const ScPatternAttr* lhs, const OUString* rhs) const
273 int cmp = CompareStringPtr(lhs->GetStyleName(), rhs);
274 if (cmp < 0)
275 return true;
276 if (cmp > 0)
277 return false;
278 return false;
280 bool CellAttributeHelper::RegisteredAttrSetLess::operator()(const OUString* lhs, const ScPatternAttr* rhs) const
282 int cmp = CompareStringPtr(lhs, rhs->GetStyleName());
283 if (cmp < 0)
284 return true;
285 if (cmp > 0)
286 return false;
287 return true;
291 CellAttributeHolder::CellAttributeHolder(const ScPatternAttr* pNew, bool bPassingOwnership)
292 : mpScPatternAttr(nullptr)
294 if (nullptr != pNew)
295 suppress_fun_call_w_exception(mpScPatternAttr = pNew->getCellAttributeHelper().registerAndCheck(*pNew, bPassingOwnership));
298 CellAttributeHolder::CellAttributeHolder(const CellAttributeHolder& rHolder)
299 : mpScPatternAttr(nullptr)
301 if (rHolder.getScPatternAttr())
302 suppress_fun_call_w_exception(mpScPatternAttr = rHolder.getScPatternAttr()->getCellAttributeHelper().registerAndCheck(*rHolder.getScPatternAttr(), false));
305 CellAttributeHolder::~CellAttributeHolder()
307 if (nullptr != mpScPatternAttr)
308 suppress_fun_call_w_exception(mpScPatternAttr->getCellAttributeHelper().doUnregister(*mpScPatternAttr));
311 CellAttributeHolder& CellAttributeHolder::operator=(const CellAttributeHolder& rHolder)
313 if (nullptr != mpScPatternAttr)
315 mpScPatternAttr->getCellAttributeHelper().doUnregister(*mpScPatternAttr);
316 mpScPatternAttr = nullptr;
319 if (rHolder.getScPatternAttr())
320 mpScPatternAttr = rHolder.getScPatternAttr()->getCellAttributeHelper().registerAndCheck(*rHolder.getScPatternAttr(), false);
322 return *this;
325 bool CellAttributeHolder::operator==(const CellAttributeHolder& rHolder) const
327 // here we have registered entries, so no need to test for equality
328 return mpScPatternAttr == rHolder.mpScPatternAttr;
331 void CellAttributeHolder::setScPatternAttr(const ScPatternAttr* pNew, bool bPassingOwnership)
333 if (nullptr != mpScPatternAttr)
334 mpScPatternAttr->getCellAttributeHelper().doUnregister(*mpScPatternAttr);
336 mpScPatternAttr = nullptr;
338 if (nullptr != pNew)
339 mpScPatternAttr = pNew->getCellAttributeHelper().registerAndCheck(*pNew, bPassingOwnership);
342 bool CellAttributeHolder::areSame(const CellAttributeHolder* p1, const CellAttributeHolder* p2)
344 if (p1 == p2)
345 // pointer compare, this handles already
346 // nullptr and if indeed handed over twice
347 return true;
349 if (nullptr == p1 || nullptr == p2)
350 // one ptr is nullptr, not both, that would
351 // have triggered above
352 return false;
354 // return content compare using operator== at last
355 return *p1 == *p2;
358 #ifdef DBG_UTIL
359 static size_t nUsedScPatternAttr(0);
360 #endif
362 const WhichRangesContainer aScPatternAttrSchema(svl::Items<ATTR_PATTERN_START, ATTR_PATTERN_END>);
364 ScPatternAttr::ScPatternAttr(CellAttributeHelper& rHelper, const SfxItemSet* pItemSet, const OUString* pStyleName)
365 : maLocalSfxItemSet(rHelper.GetPool(), aScPatternAttrSchema)
366 , mxVisible()
367 , pStyle(nullptr)
368 , pCellAttributeHelper(&rHelper)
369 , mnPAKey(0)
370 , mnRefCount(0)
371 #ifdef DBG_UTIL
372 , m_nSerialNumber(nUsedScPatternAttr++)
373 , m_bDeleted(false)
374 #endif
376 if (nullptr != pStyleName)
377 moName = *pStyleName;
379 // We need to ensure that ScPatternAttr is using the correct WhichRange,
380 // see comments in commit message. This does transfers the items with
381 // minimized overhead, too
382 if (nullptr != pItemSet)
384 // CAUTION: Use bInvalidAsDefault == false for the ::Put,
385 // we *need* to take over also Items/Slots in state
386 // SfxItemState::INVALID aka IsInvalidItem, this is a precious
387 // value/information e.g. in ScDocument::CreateSelectionPattern
388 maLocalSfxItemSet.Put(*pItemSet, false);
392 ScPatternAttr::ScPatternAttr(const ScPatternAttr& rPatternAttr)
393 : maLocalSfxItemSet(rPatternAttr.maLocalSfxItemSet)
394 , moName(rPatternAttr.moName)
395 , mxVisible()
396 , pStyle(rPatternAttr.pStyle)
397 , pCellAttributeHelper(rPatternAttr.pCellAttributeHelper)
398 , mnPAKey(rPatternAttr.mnPAKey)
399 , mnRefCount(0)
400 #ifdef DBG_UTIL
401 , m_nSerialNumber(nUsedScPatternAttr++)
402 , m_bDeleted(false)
403 #endif
407 ScPatternAttr::~ScPatternAttr()
409 #ifdef DBG_UTIL
410 m_bDeleted = true;
411 #endif
412 // should no longer be referenced, complain if not so
413 assert(!isRegistered());
416 static bool StrCmp( const OUString* pStr1, const OUString* pStr2 )
418 if (pStr1 == pStr2)
419 return true;
420 if (pStr1 && !pStr2)
421 return false;
422 if (!pStr1 && pStr2)
423 return false;
424 assert(pStr1 && pStr2);
425 return *pStr1 == *pStr2;
428 bool ScPatternAttr::operator==(const ScPatternAttr& rCmp) const
430 // check if same incarnation
431 if (this == &rCmp)
432 return true;
434 // check everything except the SfxItemSet from base class SfxSetItem
435 if (!StrCmp(GetStyleName(), rCmp.GetStyleName()))
436 return false;
438 // use SfxItemSet::operator==, does the same as locally done here before,
439 // including pool compare (default). It also compares parent, not used here.
440 // There was the old comment from
441 // "Actually test_tdf133629 from UITest_calc_tests9 somehow manages to have
442 // a different range (and I don't understand enough why), so better be safe and compare fully."
443 // that hints to different WhichRanges, but WhichRanges are not compared in
444 // the std-operator (but the Items - if needed - as was here done locally)
445 return maLocalSfxItemSet == rCmp.maLocalSfxItemSet;
448 bool ScPatternAttr::areSame(const ScPatternAttr* pItem1, const ScPatternAttr* pItem2)
450 if (pItem1 == pItem2)
451 // pointer compare, this handles already
452 // nullptr and if indeed handed over twice
453 return true;
455 if (nullptr == pItem1 || nullptr == pItem2)
456 // one ptr is nullptr, not both, that would
457 // have triggered above
458 return false;
460 // return content compare using operator== at last
461 return *pItem1 == *pItem2;
464 SvxCellOrientation ScPatternAttr::GetCellOrientation( const SfxItemSet& rItemSet, const SfxItemSet* pCondSet )
466 SvxCellOrientation eOrient = SvxCellOrientation::Standard;
468 if( GetItem( ATTR_STACKED, rItemSet, pCondSet ).GetValue() )
470 eOrient = SvxCellOrientation::Stacked;
472 else
474 Degree100 nAngle = GetItem( ATTR_ROTATE_VALUE, rItemSet, pCondSet ).GetValue();
475 if( nAngle == 9000_deg100 )
476 eOrient = SvxCellOrientation::BottomUp;
477 else if( nAngle == 27000_deg100 )
478 eOrient = SvxCellOrientation::TopBottom;
481 return eOrient;
484 SvxCellOrientation ScPatternAttr::GetCellOrientation( const SfxItemSet* pCondSet ) const
486 return GetCellOrientation( GetItemSet(), pCondSet );
489 namespace {
491 void getFontIDsByScriptType(SvtScriptType nScript,
492 TypedWhichId<SvxFontItem>& nFontId,
493 TypedWhichId<SvxFontHeightItem>& nHeightId,
494 TypedWhichId<SvxWeightItem>& nWeightId,
495 TypedWhichId<SvxPostureItem>& nPostureId,
496 TypedWhichId<SvxLanguageItem>& nLangId)
498 if ( nScript == SvtScriptType::ASIAN )
500 nFontId = ATTR_CJK_FONT;
501 nHeightId = ATTR_CJK_FONT_HEIGHT;
502 nWeightId = ATTR_CJK_FONT_WEIGHT;
503 nPostureId = ATTR_CJK_FONT_POSTURE;
504 nLangId = ATTR_CJK_FONT_LANGUAGE;
506 else if ( nScript == SvtScriptType::COMPLEX )
508 nFontId = ATTR_CTL_FONT;
509 nHeightId = ATTR_CTL_FONT_HEIGHT;
510 nWeightId = ATTR_CTL_FONT_WEIGHT;
511 nPostureId = ATTR_CTL_FONT_POSTURE;
512 nLangId = ATTR_CTL_FONT_LANGUAGE;
514 else
516 nFontId = ATTR_FONT;
517 nHeightId = ATTR_FONT_HEIGHT;
518 nWeightId = ATTR_FONT_WEIGHT;
519 nPostureId = ATTR_FONT_POSTURE;
520 nLangId = ATTR_FONT_LANGUAGE;
526 void ScPatternAttr::fillFont(
527 vcl::Font& rFont, const SfxItemSet& rItemSet, ScAutoFontColorMode eAutoMode,
528 const OutputDevice* pOutDev, const Fraction* pScale,
529 const SfxItemSet* pCondSet, SvtScriptType nScript,
530 const Color* pBackConfigColor, const Color* pTextConfigColor)
532 model::ComplexColor aComplexColor;
534 // determine effective font color
535 ScPatternAttr::fillFontOnly(rFont, rItemSet, pOutDev, pScale, pCondSet, nScript);
536 ScPatternAttr::fillColor(aComplexColor, rItemSet, eAutoMode, pCondSet, pBackConfigColor, pTextConfigColor);
538 // set font effects
539 rFont.SetColor(aComplexColor.getFinalColor());
542 void ScPatternAttr::fillFontOnly(
543 vcl::Font& rFont, const SfxItemSet& rItemSet,
544 const OutputDevice* pOutDev, const Fraction* pScale,
545 const SfxItemSet* pCondSet, SvtScriptType nScript)
547 // Read items
549 const SvxFontItem* pFontAttr;
550 sal_uInt32 nFontHeight;
551 FontWeight eWeight;
552 FontItalic eItalic;
553 FontLineStyle eUnder;
554 FontLineStyle eOver;
555 bool bWordLine;
556 FontStrikeout eStrike;
557 bool bOutline;
558 bool bShadow;
559 FontEmphasisMark eEmphasis;
560 FontRelief eRelief;
561 LanguageType eLang;
563 TypedWhichId<SvxFontItem> nFontId(0);
564 TypedWhichId<SvxFontHeightItem> nHeightId(0);
565 TypedWhichId<SvxWeightItem> nWeightId(0);
566 TypedWhichId<SvxPostureItem> nPostureId(0);
567 TypedWhichId<SvxLanguageItem> nLangId(0);
568 getFontIDsByScriptType(nScript, nFontId, nHeightId, nWeightId, nPostureId, nLangId);
570 if (pCondSet)
572 pFontAttr = pCondSet->GetItemIfSet( nFontId );
573 if ( !pFontAttr )
574 pFontAttr = &rItemSet.Get( nFontId );
576 const SvxFontHeightItem* pFontHeightItem = pCondSet->GetItemIfSet( nHeightId );
577 if ( !pFontHeightItem )
578 pFontHeightItem = &rItemSet.Get( nHeightId );
579 nFontHeight = pFontHeightItem->GetHeight();
581 const SvxWeightItem* pFontHWeightItem = pCondSet->GetItemIfSet( nWeightId );
582 if ( !pFontHWeightItem )
583 pFontHWeightItem = &rItemSet.Get( nWeightId );
584 eWeight = pFontHWeightItem->GetValue();
586 const SvxPostureItem* pPostureItem = pCondSet->GetItemIfSet( nPostureId );
587 if ( !pPostureItem )
588 pPostureItem = &rItemSet.Get( nPostureId );
589 eItalic = pPostureItem->GetValue();
591 const SvxUnderlineItem* pUnderlineItem = pCondSet->GetItemIfSet( ATTR_FONT_UNDERLINE );
592 if ( !pUnderlineItem )
593 pUnderlineItem = &rItemSet.Get( ATTR_FONT_UNDERLINE );
594 eUnder = pUnderlineItem->GetValue();
596 const SvxOverlineItem* pOverlineItem = pCondSet->GetItemIfSet( ATTR_FONT_OVERLINE );
597 if ( !pOverlineItem )
598 pOverlineItem = &rItemSet.Get( ATTR_FONT_OVERLINE );
599 eOver = pOverlineItem->GetValue();
601 const SvxWordLineModeItem* pWordlineItem = pCondSet->GetItemIfSet( ATTR_FONT_WORDLINE );
602 if ( !pWordlineItem )
603 pWordlineItem = &rItemSet.Get( ATTR_FONT_WORDLINE );
604 bWordLine = pWordlineItem->GetValue();
606 const SvxCrossedOutItem* pCrossedOutItem = pCondSet->GetItemIfSet( ATTR_FONT_CROSSEDOUT );
607 if ( !pCrossedOutItem )
608 pCrossedOutItem = &rItemSet.Get( ATTR_FONT_CROSSEDOUT );
609 eStrike = pCrossedOutItem->GetValue();
611 const SvxContourItem* pContourItem = pCondSet->GetItemIfSet( ATTR_FONT_CONTOUR );
612 if ( !pContourItem )
613 pContourItem = &rItemSet.Get( ATTR_FONT_CONTOUR );
614 bOutline = pContourItem->GetValue();
616 const SvxShadowedItem* pShadowedItem = pCondSet->GetItemIfSet( ATTR_FONT_SHADOWED );
617 if ( !pShadowedItem )
618 pShadowedItem = &rItemSet.Get( ATTR_FONT_SHADOWED );
619 bShadow = pShadowedItem->GetValue();
621 const SvxEmphasisMarkItem* pEmphasisMarkItem = pCondSet->GetItemIfSet( ATTR_FONT_EMPHASISMARK );
622 if ( !pEmphasisMarkItem )
623 pEmphasisMarkItem = &rItemSet.Get( ATTR_FONT_EMPHASISMARK );
624 eEmphasis = pEmphasisMarkItem->GetEmphasisMark();
626 const SvxCharReliefItem* pCharReliefItem = pCondSet->GetItemIfSet( ATTR_FONT_RELIEF );
627 if ( !pCharReliefItem )
628 pCharReliefItem = &rItemSet.Get( ATTR_FONT_RELIEF );
629 eRelief = pCharReliefItem->GetValue();
631 const SvxLanguageItem* pLanguageItem = pCondSet->GetItemIfSet( nLangId );
632 if ( !pLanguageItem )
633 pLanguageItem = &rItemSet.Get( nLangId );
634 eLang = pLanguageItem->GetLanguage();
636 else // Everything from rItemSet
638 pFontAttr = &rItemSet.Get( nFontId );
639 nFontHeight = rItemSet.Get( nHeightId ).GetHeight();
640 eWeight = rItemSet.Get( nWeightId ).GetValue();
641 eItalic = rItemSet.Get( nPostureId ).GetValue();
642 eUnder = rItemSet.Get( ATTR_FONT_UNDERLINE ).GetValue();
643 eOver = rItemSet.Get( ATTR_FONT_OVERLINE ).GetValue();
644 bWordLine = rItemSet.Get( ATTR_FONT_WORDLINE ).GetValue();
645 eStrike = rItemSet.Get( ATTR_FONT_CROSSEDOUT ).GetValue();
646 bOutline = rItemSet.Get( ATTR_FONT_CONTOUR ).GetValue();
647 bShadow = rItemSet.Get( ATTR_FONT_SHADOWED ).GetValue();
648 eEmphasis = rItemSet.Get( ATTR_FONT_EMPHASISMARK ).GetEmphasisMark();
649 eRelief = rItemSet.Get( ATTR_FONT_RELIEF ).GetValue();
650 // for graphite language features
651 eLang = rItemSet.Get( nLangId ).GetLanguage();
653 OSL_ENSURE(pFontAttr,"Oops?");
655 // Evaluate
657 // FontItem:
659 if (rFont.GetFamilyName() != pFontAttr->GetFamilyName())
660 rFont.SetFamilyName( pFontAttr->GetFamilyName() );
661 if (rFont.GetStyleName() != pFontAttr->GetStyleName())
662 rFont.SetStyleName( pFontAttr->GetStyleName() );
664 rFont.SetFamily( pFontAttr->GetFamily() );
665 rFont.SetCharSet( pFontAttr->GetCharSet() );
666 rFont.SetPitch( pFontAttr->GetPitch() );
668 rFont.SetLanguage(eLang);
670 // Size
672 if ( pOutDev != nullptr )
674 Size aEffSize;
675 Fraction aFraction( 1,1 );
676 if (pScale)
677 aFraction = *pScale;
678 Size aSize( 0, static_cast<tools::Long>(nFontHeight) );
679 MapMode aDestMode = pOutDev->GetMapMode();
680 MapMode aSrcMode( MapUnit::MapTwip, Point(), aFraction, aFraction );
681 if (aDestMode.GetMapUnit() == MapUnit::MapPixel && pOutDev->GetDPIX() > 0)
682 aEffSize = pOutDev->LogicToPixel( aSize, aSrcMode );
683 else
685 Fraction aFractOne(1,1);
686 aDestMode.SetScaleX( aFractOne );
687 aDestMode.SetScaleY( aFractOne );
688 aEffSize = OutputDevice::LogicToLogic( aSize, aSrcMode, aDestMode );
690 rFont.SetFontSize( aEffSize );
692 else /* if pOutDev != NULL */
694 rFont.SetFontSize( Size( 0, static_cast<tools::Long>(nFontHeight) ) );
697 // set font effects
698 rFont.SetWeight( eWeight );
699 rFont.SetItalic( eItalic );
700 rFont.SetUnderline( eUnder );
701 rFont.SetOverline( eOver );
702 rFont.SetWordLineMode( bWordLine );
703 rFont.SetStrikeout( eStrike );
704 rFont.SetOutline( bOutline );
705 rFont.SetShadow( bShadow );
706 rFont.SetEmphasisMark( eEmphasis );
707 rFont.SetRelief( eRelief );
708 rFont.SetTransparent( true );
711 void ScPatternAttr::fillColor(model::ComplexColor& rComplexColor, const SfxItemSet& rItemSet, ScAutoFontColorMode eAutoMode, const SfxItemSet* pCondSet, const Color* pBackConfigColor, const Color* pTextConfigColor)
713 model::ComplexColor aComplexColor;
715 Color aColor;
717 SvxColorItem const* pColorItem = nullptr;
719 if (pCondSet)
720 pColorItem = pCondSet->GetItemIfSet(ATTR_FONT_COLOR);
722 if (!pColorItem)
723 pColorItem = &rItemSet.Get(ATTR_FONT_COLOR);
725 if (pColorItem)
727 aComplexColor = pColorItem->getComplexColor();
728 aColor = pColorItem->GetValue();
731 if (aComplexColor.getType() == model::ColorType::Unused)
733 aComplexColor.setColor(aColor);
736 if ((aColor == COL_AUTO && eAutoMode != ScAutoFontColorMode::Raw)
737 || eAutoMode == ScAutoFontColorMode::IgnoreFont
738 || eAutoMode == ScAutoFontColorMode::IgnoreAll)
740 // get background color from conditional or own set
741 Color aBackColor;
742 if ( pCondSet )
744 const SvxBrushItem* pItem = pCondSet->GetItemIfSet(ATTR_BACKGROUND);
745 if (!pItem)
746 pItem = &rItemSet.Get(ATTR_BACKGROUND);
747 aBackColor = pItem->GetColor();
749 else
751 aBackColor = rItemSet.Get(ATTR_BACKGROUND).GetColor();
754 // if background color attribute is transparent, use window color for brightness comparisons
755 if (aBackColor == COL_TRANSPARENT
756 || eAutoMode == ScAutoFontColorMode::IgnoreBack
757 || eAutoMode == ScAutoFontColorMode::IgnoreAll)
759 if (!comphelper::LibreOfficeKit::isActive())
761 if ( eAutoMode == ScAutoFontColorMode::Print )
762 aBackColor = COL_WHITE;
763 else if ( pBackConfigColor )
765 // pBackConfigColor can be used to avoid repeated lookup of the configured color
766 aBackColor = *pBackConfigColor;
768 else
769 aBackColor = ScModule::get()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
771 else
773 // Get document color from current view instead
774 SfxViewShell* pSfxViewShell = SfxViewShell::Current();
775 ScTabViewShell* pViewShell = dynamic_cast<ScTabViewShell*>(pSfxViewShell);
776 if (pViewShell)
778 const ScViewRenderingOptions& rViewRenderingOptions = pViewShell->GetViewRenderingData();
779 aBackColor = eAutoMode == ScAutoFontColorMode::Print ? COL_WHITE :
780 rViewRenderingOptions.GetDocColor();
785 // get system text color for comparison
786 Color aSysTextColor;
787 if (eAutoMode == ScAutoFontColorMode::Print)
789 aSysTextColor = COL_BLACK;
791 else if (pTextConfigColor)
793 // pTextConfigColor can be used to avoid repeated lookup of the configured color
794 aSysTextColor = *pTextConfigColor;
795 if (ScModule::get()->GetColorConfig().GetColorValue(svtools::FONTCOLOR, false).nColor == COL_AUTO)
797 if ( aBackColor.IsDark() && aSysTextColor.IsDark() )
798 aSysTextColor = COL_WHITE;
799 else
800 aSysTextColor = COL_BLACK;
803 else
805 aSysTextColor = ScModule::get()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
808 if (comphelper::LibreOfficeKit::isActive() && SfxViewShell::Current())
810 if (aBackColor.IsDark())
811 aColor = COL_WHITE;
812 else
813 aColor = COL_BLACK;
815 else
817 aColor = aSysTextColor;
820 aComplexColor.setFinalColor(aColor);
821 rComplexColor = std::move(aComplexColor);
824 ScDxfFont ScPatternAttr::GetDxfFont(const SfxItemSet& rItemSet, SvtScriptType nScript)
826 TypedWhichId<SvxFontItem> nFontId(0);
827 TypedWhichId<SvxFontHeightItem> nHeightId(0);
828 TypedWhichId<SvxWeightItem> nWeightId(0);
829 TypedWhichId<SvxPostureItem> nPostureId(0);
830 TypedWhichId<SvxLanguageItem> nLangId(0);
831 getFontIDsByScriptType(nScript, nFontId, nHeightId, nWeightId, nPostureId, nLangId);
833 ScDxfFont aReturn;
835 if ( const SvxFontItem* pItem = rItemSet.GetItemIfSet( nFontId ) )
837 aReturn.pFontAttr = pItem;
840 if ( const SvxFontHeightItem* pItem = rItemSet.GetItemIfSet( nHeightId ) )
842 aReturn.nFontHeight = pItem->GetHeight();
845 if ( const SvxWeightItem* pItem = rItemSet.GetItemIfSet( nWeightId ) )
847 aReturn.eWeight = pItem->GetValue();
850 if ( const SvxPostureItem* pItem = rItemSet.GetItemIfSet( nPostureId ) )
852 aReturn.eItalic = pItem->GetValue();
855 if ( const SvxUnderlineItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_UNDERLINE ) )
857 pItem = &rItemSet.Get( ATTR_FONT_UNDERLINE );
858 aReturn.eUnder = pItem->GetValue();
861 if ( const SvxOverlineItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_OVERLINE ) )
863 aReturn.eOver = pItem->GetValue();
866 if ( const SvxWordLineModeItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_WORDLINE ) )
868 aReturn.bWordLine = pItem->GetValue();
871 if ( const SvxCrossedOutItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_CROSSEDOUT ) )
873 pItem = &rItemSet.Get( ATTR_FONT_CROSSEDOUT );
874 aReturn.eStrike = pItem->GetValue();
877 if ( const SvxContourItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_CONTOUR ) )
879 aReturn.bOutline = pItem->GetValue();
882 if ( const SvxShadowedItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_SHADOWED ) )
884 pItem = &rItemSet.Get( ATTR_FONT_SHADOWED );
885 aReturn.bShadow = pItem->GetValue();
888 if ( const SvxEmphasisMarkItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_EMPHASISMARK ) )
890 aReturn.eEmphasis = pItem->GetEmphasisMark();
893 if ( const SvxCharReliefItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_RELIEF ) )
895 aReturn.eRelief = pItem->GetValue();
898 if ( const SvxColorItem* pItem = rItemSet.GetItemIfSet( ATTR_FONT_COLOR ) )
900 aReturn.aColor = pItem->GetValue();
903 if ( const SvxLanguageItem* pItem = rItemSet.GetItemIfSet( nLangId ) )
905 aReturn.eLang = pItem->GetLanguage();
908 return aReturn;
911 template <class T>
912 static void lcl_populate( std::unique_ptr<T>& rxItem, TypedWhichId<T> nWhich, const SfxItemSet& rSrcSet, const SfxItemSet* pCondSet )
914 const T* pItem = pCondSet->GetItemIfSet( nWhich );
915 if ( !pItem )
916 pItem = &rSrcSet.Get( nWhich );
917 rxItem.reset(pItem->Clone());
920 void ScPatternAttr::FillToEditItemSet( SfxItemSet& rEditSet, const SfxItemSet& rSrcSet, const SfxItemSet* pCondSet )
922 // Read Items
924 std::unique_ptr<SvxColorItem> aColorItem(std::make_unique<SvxColorItem>(EE_CHAR_COLOR)); // use item as-is
925 std::unique_ptr<SvxFontItem> aFontItem(std::make_unique<SvxFontItem>(EE_CHAR_FONTINFO)); // use item as-is
926 std::unique_ptr<SvxFontItem> aCjkFontItem(std::make_unique<SvxFontItem>(EE_CHAR_FONTINFO_CJK)); // use item as-is
927 std::unique_ptr<SvxFontItem> aCtlFontItem(std::make_unique<SvxFontItem>(EE_CHAR_FONTINFO_CTL)); // use item as-is
928 tools::Long nTHeight, nCjkTHeight, nCtlTHeight; // Twips
929 FontWeight eWeight, eCjkWeight, eCtlWeight;
930 std::unique_ptr<SvxUnderlineItem> aUnderlineItem(std::make_unique<SvxUnderlineItem>(LINESTYLE_NONE, EE_CHAR_UNDERLINE));
931 std::unique_ptr<SvxOverlineItem> aOverlineItem(std::make_unique<SvxOverlineItem>(LINESTYLE_NONE, EE_CHAR_OVERLINE));
932 bool bWordLine;
933 FontStrikeout eStrike;
934 FontItalic eItalic, eCjkItalic, eCtlItalic;
935 bool bOutline;
936 bool bShadow;
937 bool bForbidden;
938 FontEmphasisMark eEmphasis;
939 FontRelief eRelief;
940 LanguageType eLang, eCjkLang, eCtlLang;
941 bool bHyphenate;
942 SvxFrameDirection eDirection;
944 //TODO: additional parameter to control if language is needed?
946 if ( pCondSet )
948 lcl_populate(aColorItem, ATTR_FONT_COLOR, rSrcSet, pCondSet);
949 lcl_populate(aFontItem, ATTR_FONT, rSrcSet, pCondSet);
950 lcl_populate(aCjkFontItem, ATTR_CJK_FONT, rSrcSet, pCondSet);
951 lcl_populate(aCtlFontItem, ATTR_CTL_FONT, rSrcSet, pCondSet);
953 const SvxFontHeightItem* pFontHeightItem = pCondSet->GetItemIfSet( ATTR_FONT_HEIGHT );
954 if (!pFontHeightItem)
955 pFontHeightItem = &rSrcSet.Get( ATTR_FONT_HEIGHT );
956 nTHeight = pFontHeightItem->GetHeight();
957 pFontHeightItem = pCondSet->GetItemIfSet( ATTR_CJK_FONT_HEIGHT );
958 if ( !pFontHeightItem )
959 pFontHeightItem = &rSrcSet.Get( ATTR_CJK_FONT_HEIGHT );
960 nCjkTHeight = pFontHeightItem->GetHeight();
961 pFontHeightItem = pCondSet->GetItemIfSet( ATTR_CTL_FONT_HEIGHT );
962 if ( !pFontHeightItem )
963 pFontHeightItem = &rSrcSet.Get( ATTR_CTL_FONT_HEIGHT );
964 nCtlTHeight = pFontHeightItem->GetHeight();
966 const SvxWeightItem* pWeightItem = pCondSet->GetItemIfSet( ATTR_FONT_WEIGHT );
967 if ( !pWeightItem )
968 pWeightItem = &rSrcSet.Get( ATTR_FONT_WEIGHT );
969 eWeight = pWeightItem->GetValue();
970 pWeightItem = pCondSet->GetItemIfSet( ATTR_CJK_FONT_WEIGHT );
971 if ( !pWeightItem )
972 pWeightItem = &rSrcSet.Get( ATTR_CJK_FONT_WEIGHT );
973 eCjkWeight = pWeightItem->GetValue();
974 pWeightItem = pCondSet->GetItemIfSet( ATTR_CTL_FONT_WEIGHT );
975 if ( !pWeightItem )
976 pWeightItem = &rSrcSet.Get( ATTR_CTL_FONT_WEIGHT );
977 eCtlWeight = pWeightItem->GetValue();
979 const SvxPostureItem* pPostureItem = pCondSet->GetItemIfSet( ATTR_FONT_POSTURE );
980 if ( !pPostureItem )
981 pPostureItem = &rSrcSet.Get( ATTR_FONT_POSTURE );
982 eItalic = pPostureItem->GetValue();
983 pPostureItem = pCondSet->GetItemIfSet( ATTR_CJK_FONT_POSTURE );
984 if ( !pPostureItem )
985 pPostureItem = &rSrcSet.Get( ATTR_CJK_FONT_POSTURE );
986 eCjkItalic = pPostureItem->GetValue();
987 pPostureItem = pCondSet->GetItemIfSet( ATTR_CTL_FONT_POSTURE );
988 if ( !pPostureItem )
989 pPostureItem = &rSrcSet.Get( ATTR_CTL_FONT_POSTURE );
990 eCtlItalic = pPostureItem->GetValue();
992 lcl_populate(aUnderlineItem, ATTR_FONT_UNDERLINE, rSrcSet, pCondSet);
993 lcl_populate(aOverlineItem, ATTR_FONT_OVERLINE, rSrcSet, pCondSet);
995 const SvxWordLineModeItem* pWordLineModeItem = pCondSet->GetItemIfSet( ATTR_FONT_WORDLINE );
996 if ( !pWordLineModeItem )
997 pWordLineModeItem = &rSrcSet.Get( ATTR_FONT_WORDLINE );
998 bWordLine = pWordLineModeItem->GetValue();
1000 const SvxCrossedOutItem* pCrossedOutItem = pCondSet->GetItemIfSet( ATTR_FONT_CROSSEDOUT );
1001 if ( !pCrossedOutItem )
1002 pCrossedOutItem = &rSrcSet.Get( ATTR_FONT_CROSSEDOUT );
1003 eStrike = pCrossedOutItem->GetValue();
1005 const SvxContourItem* pContourItem = pCondSet->GetItemIfSet( ATTR_FONT_CONTOUR );
1006 if ( !pContourItem )
1007 pContourItem = &rSrcSet.Get( ATTR_FONT_CONTOUR );
1008 bOutline = pContourItem->GetValue();
1010 const SvxShadowedItem* pShadowedItem = pCondSet->GetItemIfSet( ATTR_FONT_SHADOWED );
1011 if ( !pShadowedItem )
1012 pShadowedItem = &rSrcSet.Get( ATTR_FONT_SHADOWED );
1013 bShadow = pShadowedItem->GetValue();
1015 const SvxForbiddenRuleItem* pForbiddenRuleItem = pCondSet->GetItemIfSet( ATTR_FORBIDDEN_RULES );
1016 if ( !pForbiddenRuleItem )
1017 pForbiddenRuleItem = &rSrcSet.Get( ATTR_FORBIDDEN_RULES );
1018 bForbidden = pForbiddenRuleItem->GetValue();
1020 const SvxEmphasisMarkItem* pEmphasisMarkItem = pCondSet->GetItemIfSet( ATTR_FONT_EMPHASISMARK );
1021 if ( !pEmphasisMarkItem )
1022 pEmphasisMarkItem = &rSrcSet.Get( ATTR_FONT_EMPHASISMARK );
1023 eEmphasis = pEmphasisMarkItem->GetEmphasisMark();
1024 const SvxCharReliefItem* pCharReliefItem = pCondSet->GetItemIfSet( ATTR_FONT_RELIEF );
1025 if ( !pCharReliefItem )
1026 pCharReliefItem = &rSrcSet.Get( ATTR_FONT_RELIEF );
1027 eRelief = pCharReliefItem->GetValue();
1029 const SvxLanguageItem* pLanguageItem = pCondSet->GetItemIfSet( ATTR_FONT_LANGUAGE );
1030 if ( !pLanguageItem )
1031 pLanguageItem = &rSrcSet.Get( ATTR_FONT_LANGUAGE );
1032 eLang = pLanguageItem->GetLanguage();
1033 pLanguageItem = pCondSet->GetItemIfSet( ATTR_CJK_FONT_LANGUAGE );
1034 if ( !pLanguageItem )
1035 pLanguageItem = &rSrcSet.Get( ATTR_CJK_FONT_LANGUAGE );
1036 eCjkLang = pLanguageItem->GetLanguage();
1037 pLanguageItem = pCondSet->GetItemIfSet( ATTR_CTL_FONT_LANGUAGE );
1038 if ( !pLanguageItem )
1039 pLanguageItem = &rSrcSet.Get( ATTR_CTL_FONT_LANGUAGE );
1040 eCtlLang = pLanguageItem->GetLanguage();
1042 const ScHyphenateCell* pHyphenateCell = pCondSet->GetItemIfSet( ATTR_HYPHENATE );
1043 if ( !pHyphenateCell )
1044 pHyphenateCell = &rSrcSet.Get( ATTR_HYPHENATE );
1045 bHyphenate = pHyphenateCell->GetValue();
1047 const SvxFrameDirectionItem* pFrameDirectionItem = pCondSet->GetItemIfSet( ATTR_WRITINGDIR );
1048 if ( !pFrameDirectionItem )
1049 pFrameDirectionItem = &rSrcSet.Get( ATTR_WRITINGDIR );
1050 eDirection = pFrameDirectionItem->GetValue();
1052 else // Everything directly from Pattern
1054 aColorItem.reset(rSrcSet.Get(ATTR_FONT_COLOR).Clone());
1055 aFontItem.reset(rSrcSet.Get(ATTR_FONT).Clone());
1056 aCjkFontItem.reset(rSrcSet.Get(ATTR_CJK_FONT).Clone());
1057 aCtlFontItem.reset(rSrcSet.Get(ATTR_CTL_FONT).Clone());
1058 nTHeight = rSrcSet.Get( ATTR_FONT_HEIGHT ).GetHeight();
1059 nCjkTHeight = rSrcSet.Get( ATTR_CJK_FONT_HEIGHT ).GetHeight();
1060 nCtlTHeight = rSrcSet.Get( ATTR_CTL_FONT_HEIGHT ).GetHeight();
1061 eWeight = rSrcSet.Get( ATTR_FONT_WEIGHT ).GetValue();
1062 eCjkWeight = rSrcSet.Get( ATTR_CJK_FONT_WEIGHT ).GetValue();
1063 eCtlWeight = rSrcSet.Get( ATTR_CTL_FONT_WEIGHT ).GetValue();
1064 eItalic = rSrcSet.Get( ATTR_FONT_POSTURE ).GetValue();
1065 eCjkItalic = rSrcSet.Get( ATTR_CJK_FONT_POSTURE ).GetValue();
1066 eCtlItalic = rSrcSet.Get( ATTR_CTL_FONT_POSTURE ).GetValue();
1067 aUnderlineItem.reset(rSrcSet.Get(ATTR_FONT_UNDERLINE).Clone());
1068 aOverlineItem.reset(rSrcSet.Get(ATTR_FONT_OVERLINE).Clone());
1069 bWordLine = rSrcSet.Get( ATTR_FONT_WORDLINE ).GetValue();
1070 eStrike = rSrcSet.Get( ATTR_FONT_CROSSEDOUT ).GetValue();
1071 bOutline = rSrcSet.Get( ATTR_FONT_CONTOUR ).GetValue();
1072 bShadow = rSrcSet.Get( ATTR_FONT_SHADOWED ).GetValue();
1073 bForbidden = rSrcSet.Get( ATTR_FORBIDDEN_RULES ).GetValue();
1074 eEmphasis = rSrcSet.Get( ATTR_FONT_EMPHASISMARK ).GetEmphasisMark();
1075 eRelief = rSrcSet.Get( ATTR_FONT_RELIEF ).GetValue();
1076 eLang = rSrcSet.Get( ATTR_FONT_LANGUAGE ).GetLanguage();
1077 eCjkLang = rSrcSet.Get( ATTR_CJK_FONT_LANGUAGE ).GetLanguage();
1078 eCtlLang = rSrcSet.Get( ATTR_CTL_FONT_LANGUAGE ).GetLanguage();
1079 bHyphenate = rSrcSet.Get( ATTR_HYPHENATE ).GetValue();
1080 eDirection = rSrcSet.Get( ATTR_WRITINGDIR ).GetValue();
1083 // Expect to be compatible to LogicToLogic, ie. 2540/1440 = 127/72, and round
1085 tools::Long nHeight = convertTwipToMm100(nTHeight);
1086 tools::Long nCjkHeight = convertTwipToMm100(nCjkTHeight);
1087 tools::Long nCtlHeight = convertTwipToMm100(nCtlTHeight);
1089 // put items into EditEngine ItemSet
1091 if ( aColorItem->GetValue() == COL_AUTO )
1093 // When cell attributes are converted to EditEngine paragraph attributes,
1094 // don't create a hard item for automatic color, because that would be converted
1095 // to black when the item's Store method is used in CreateTransferable/WriteBin.
1096 // COL_AUTO is the EditEngine's pool default, so ClearItem will result in automatic
1097 // color, too, without having to store the item.
1098 rEditSet.ClearItem( EE_CHAR_COLOR );
1100 else
1102 // tdf#125054 adapt WhichID
1103 rEditSet.PutAsTargetWhich( std::move(aColorItem), EE_CHAR_COLOR );
1106 // tdf#125054 adapt WhichID
1107 rEditSet.PutAsTargetWhich( std::move(aFontItem), EE_CHAR_FONTINFO );
1108 rEditSet.PutAsTargetWhich( std::move(aCjkFontItem), EE_CHAR_FONTINFO_CJK );
1109 rEditSet.PutAsTargetWhich( std::move(aCtlFontItem), EE_CHAR_FONTINFO_CTL );
1111 rEditSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
1112 rEditSet.Put( SvxFontHeightItem( nCjkHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
1113 rEditSet.Put( SvxFontHeightItem( nCtlHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
1114 rEditSet.Put( SvxWeightItem ( eWeight, EE_CHAR_WEIGHT ) );
1115 rEditSet.Put( SvxWeightItem ( eCjkWeight, EE_CHAR_WEIGHT_CJK ) );
1116 rEditSet.Put( SvxWeightItem ( eCtlWeight, EE_CHAR_WEIGHT_CTL ) );
1118 // tdf#125054 adapt WhichID
1119 rEditSet.PutAsTargetWhich( std::move(aUnderlineItem), EE_CHAR_UNDERLINE );
1120 rEditSet.PutAsTargetWhich( std::move(aOverlineItem), EE_CHAR_OVERLINE );
1122 rEditSet.Put( SvxWordLineModeItem( bWordLine, EE_CHAR_WLM ) );
1123 rEditSet.Put( SvxCrossedOutItem( eStrike, EE_CHAR_STRIKEOUT ) );
1124 rEditSet.Put( SvxPostureItem ( eItalic, EE_CHAR_ITALIC ) );
1125 rEditSet.Put( SvxPostureItem ( eCjkItalic, EE_CHAR_ITALIC_CJK ) );
1126 rEditSet.Put( SvxPostureItem ( eCtlItalic, EE_CHAR_ITALIC_CTL ) );
1127 rEditSet.Put( SvxContourItem ( bOutline, EE_CHAR_OUTLINE ) );
1128 rEditSet.Put( SvxShadowedItem ( bShadow, EE_CHAR_SHADOW ) );
1129 rEditSet.Put( SvxForbiddenRuleItem(bForbidden, EE_PARA_FORBIDDENRULES) );
1130 rEditSet.Put( SvxEmphasisMarkItem( eEmphasis, EE_CHAR_EMPHASISMARK ) );
1131 rEditSet.Put( SvxCharReliefItem( eRelief, EE_CHAR_RELIEF ) );
1132 rEditSet.Put( SvxLanguageItem ( eLang, EE_CHAR_LANGUAGE ) );
1133 rEditSet.Put( SvxLanguageItem ( eCjkLang, EE_CHAR_LANGUAGE_CJK ) );
1134 rEditSet.Put( SvxLanguageItem ( eCtlLang, EE_CHAR_LANGUAGE_CTL ) );
1135 rEditSet.Put( SfxBoolItem ( EE_PARA_HYPHENATE, bHyphenate ) );
1136 rEditSet.Put( SvxFrameDirectionItem( eDirection, EE_PARA_WRITINGDIR ) );
1138 // Script spacing is always off.
1139 // The cell attribute isn't used here as long as there is no UI to set it
1140 // (don't evaluate attributes that can't be changed).
1141 // If a locale-dependent default is needed, it has to go into the cell
1142 // style, like the fonts.
1143 rEditSet.Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
1146 void ScPatternAttr::FillEditItemSet( SfxItemSet* pEditSet, const SfxItemSet* pCondSet ) const
1148 if( pEditSet )
1149 FillToEditItemSet( *pEditSet, GetItemSet(), pCondSet );
1152 void ScPatternAttr::GetFromEditItemSet( SfxItemSet& rDestSet, const SfxItemSet& rEditSet )
1154 if (const SvxColorItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_COLOR))
1155 rDestSet.PutAsTargetWhich( *pItem, ATTR_FONT_COLOR );
1157 if (const SvxFontItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_FONTINFO))
1158 rDestSet.PutAsTargetWhich( *pItem, ATTR_FONT );
1159 if (const SvxFontItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_FONTINFO_CJK))
1160 rDestSet.PutAsTargetWhich( *pItem, ATTR_CJK_FONT );
1161 if (const SvxFontItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_FONTINFO_CTL))
1162 rDestSet.PutAsTargetWhich( *pItem, ATTR_CTL_FONT );
1164 if (const SvxFontHeightItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_FONTHEIGHT))
1165 rDestSet.Put( SvxFontHeightItem(o3tl::toTwips(pItem->GetHeight(), o3tl::Length::mm100),
1166 100, ATTR_FONT_HEIGHT ) );
1167 if (const SvxFontHeightItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_FONTHEIGHT_CJK))
1168 rDestSet.Put( SvxFontHeightItem(o3tl::toTwips(pItem->GetHeight(), o3tl::Length::mm100),
1169 100, ATTR_CJK_FONT_HEIGHT ) );
1170 if (const SvxFontHeightItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_FONTHEIGHT_CTL))
1171 rDestSet.Put( SvxFontHeightItem(o3tl::toTwips(pItem->GetHeight(), o3tl::Length::mm100),
1172 100, ATTR_CTL_FONT_HEIGHT ) );
1174 if (const SvxWeightItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_WEIGHT))
1175 rDestSet.Put( SvxWeightItem( pItem->GetValue(),
1176 ATTR_FONT_WEIGHT) );
1177 if (const SvxWeightItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_WEIGHT_CJK))
1178 rDestSet.Put( SvxWeightItem( pItem->GetValue(),
1179 ATTR_CJK_FONT_WEIGHT) );
1180 if (const SvxWeightItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_WEIGHT_CTL))
1181 rDestSet.Put( SvxWeightItem( pItem->GetValue(),
1182 ATTR_CTL_FONT_WEIGHT) );
1184 // SvxTextLineItem contains enum and color
1185 if (const SvxUnderlineItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_UNDERLINE))
1186 rDestSet.PutAsTargetWhich( *pItem, ATTR_FONT_UNDERLINE );
1187 if (const SvxOverlineItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_OVERLINE))
1188 rDestSet.PutAsTargetWhich( *pItem, ATTR_FONT_OVERLINE );
1189 if (const SvxWordLineModeItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_WLM))
1190 rDestSet.Put( SvxWordLineModeItem( pItem->GetValue(),
1191 ATTR_FONT_WORDLINE) );
1193 if (const SvxCrossedOutItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_STRIKEOUT))
1194 rDestSet.Put( SvxCrossedOutItem( pItem->GetValue(),
1195 ATTR_FONT_CROSSEDOUT) );
1197 if (const SvxPostureItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_ITALIC))
1198 rDestSet.Put( SvxPostureItem( pItem->GetValue(),
1199 ATTR_FONT_POSTURE) );
1200 if (const SvxPostureItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_ITALIC_CJK))
1201 rDestSet.Put( SvxPostureItem( pItem->GetValue(),
1202 ATTR_CJK_FONT_POSTURE) );
1203 if (const SvxPostureItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_ITALIC_CTL))
1204 rDestSet.Put( SvxPostureItem( pItem->GetValue(),
1205 ATTR_CTL_FONT_POSTURE) );
1207 if (const SvxContourItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_OUTLINE))
1208 rDestSet.Put( SvxContourItem( pItem->GetValue(),
1209 ATTR_FONT_CONTOUR) );
1210 if (const SvxShadowedItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_SHADOW))
1211 rDestSet.Put( SvxShadowedItem( pItem->GetValue(),
1212 ATTR_FONT_SHADOWED) );
1213 if (const SvxEmphasisMarkItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_EMPHASISMARK))
1214 rDestSet.Put( SvxEmphasisMarkItem( pItem->GetEmphasisMark(),
1215 ATTR_FONT_EMPHASISMARK) );
1216 if (const SvxCharReliefItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_RELIEF))
1217 rDestSet.Put( SvxCharReliefItem( pItem->GetValue(),
1218 ATTR_FONT_RELIEF) );
1220 if (const SvxLanguageItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_LANGUAGE))
1221 rDestSet.Put( SvxLanguageItem(pItem->GetValue(), ATTR_FONT_LANGUAGE) );
1222 if (const SvxLanguageItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_LANGUAGE_CJK))
1223 rDestSet.Put( SvxLanguageItem(pItem->GetValue(), ATTR_CJK_FONT_LANGUAGE) );
1224 if (const SvxLanguageItem* pItem = rEditSet.GetItemIfSet(EE_CHAR_LANGUAGE_CTL))
1225 rDestSet.Put( SvxLanguageItem(pItem->GetValue(), ATTR_CTL_FONT_LANGUAGE) );
1227 const SvxAdjustItem* pAdjustItem = rEditSet.GetItemIfSet(EE_PARA_JUST);
1229 if (!pAdjustItem)
1230 return;
1232 SvxCellHorJustify eVal;
1233 switch ( pAdjustItem->GetAdjust() )
1235 case SvxAdjust::Left:
1236 // EditEngine Default is always set in the GetAttribs() ItemSet !
1237 // whether left or right, is decided in text / number
1238 eVal = SvxCellHorJustify::Standard;
1239 break;
1240 case SvxAdjust::Right:
1241 eVal = SvxCellHorJustify::Right;
1242 break;
1243 case SvxAdjust::Block:
1244 eVal = SvxCellHorJustify::Block;
1245 break;
1246 case SvxAdjust::Center:
1247 eVal = SvxCellHorJustify::Center;
1248 break;
1249 case SvxAdjust::BlockLine:
1250 eVal = SvxCellHorJustify::Block;
1251 break;
1252 case SvxAdjust::End:
1253 eVal = SvxCellHorJustify::Right;
1254 break;
1255 default:
1256 eVal = SvxCellHorJustify::Standard;
1258 if ( eVal != SvxCellHorJustify::Standard )
1259 rDestSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY) );
1262 void ScPatternAttr::GetFromEditItemSet( const SfxItemSet* pEditSet )
1264 if( !pEditSet )
1265 return;
1266 GetFromEditItemSet( GetItemSet(), *pEditSet );
1267 InvalidateCaches();
1270 void ScPatternAttr::FillEditParaItems( SfxItemSet* pEditSet ) const
1272 // already there in GetFromEditItemSet, but not in FillEditItemSet
1273 // Default horizontal alignment is always implemented as left
1275 const SfxItemSet& rMySet = GetItemSet();
1277 SvxCellHorJustify eHorJust = rMySet.Get(ATTR_HOR_JUSTIFY).GetValue();
1279 SvxAdjust eSvxAdjust;
1280 switch (eHorJust)
1282 case SvxCellHorJustify::Right: eSvxAdjust = SvxAdjust::Right; break;
1283 case SvxCellHorJustify::Center: eSvxAdjust = SvxAdjust::Center; break;
1284 case SvxCellHorJustify::Block: eSvxAdjust = SvxAdjust::Block; break;
1285 default: eSvxAdjust = SvxAdjust::Left; break;
1287 pEditSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
1290 void ScPatternAttr::DeleteUnchanged( const ScPatternAttr* pOldAttrs )
1292 SfxItemSet& rThisSet = GetItemSet();
1293 const SfxItemSet& rOldSet = pOldAttrs->GetItemSet();
1295 const SfxPoolItem* pThisItem;
1296 const SfxPoolItem* pOldItem;
1298 for ( sal_uInt16 nSubWhich=ATTR_PATTERN_START; nSubWhich<=ATTR_PATTERN_END; nSubWhich++ )
1300 // only items that are set are interesting
1301 if ( rThisSet.GetItemState( nSubWhich, false, &pThisItem ) == SfxItemState::SET )
1303 SfxItemState eOldState = rOldSet.GetItemState( nSubWhich, true, &pOldItem );
1304 if ( eOldState == SfxItemState::SET )
1306 // item is set in OldAttrs (or its parent) -> compare pointers
1307 if (SfxPoolItem::areSame( pThisItem, pOldItem ))
1309 rThisSet.ClearItem( nSubWhich );
1310 InvalidateCaches();
1313 else if ( eOldState != SfxItemState::INVALID )
1315 // not set in OldAttrs -> compare item value to default item
1316 if ( *pThisItem == rThisSet.GetPool()->GetUserOrPoolDefaultItem( nSubWhich ) )
1318 rThisSet.ClearItem( nSubWhich );
1319 InvalidateCaches();
1326 bool ScPatternAttr::HasItemsSet( const sal_uInt16* pWhich ) const
1328 const SfxItemSet& rSet = GetItemSet();
1329 for (sal_uInt16 i=0; pWhich[i]; i++)
1330 if ( rSet.GetItemState( pWhich[i], false ) == SfxItemState::SET )
1331 return true;
1332 return false;
1335 void ScPatternAttr::ClearItems( const sal_uInt16* pWhich )
1337 SfxItemSet& rSet = GetItemSet();
1338 for (sal_uInt16 i=0; pWhich[i]; i++)
1339 rSet.ClearItem(pWhich[i]);
1340 InvalidateCaches();
1343 static SfxStyleSheetBase* lcl_CopyStyleToPool
1345 SfxStyleSheetBase* pSrcStyle,
1346 SfxStyleSheetBasePool* pSrcPool,
1347 SfxStyleSheetBasePool* pDestPool,
1348 const SvNumberFormatterIndexTable* pFormatExchangeList
1351 if ( !pSrcStyle || !pDestPool || !pSrcPool )
1353 OSL_FAIL( "CopyStyleToPool: Invalid Arguments :-/" );
1354 return nullptr;
1357 const OUString aStrSrcStyle = pSrcStyle->GetName();
1358 const SfxStyleFamily eFamily = pSrcStyle->GetFamily();
1359 SfxStyleSheetBase* pDestStyle = pDestPool->Find( aStrSrcStyle, eFamily );
1361 if ( !pDestStyle )
1363 const OUString aStrParent = pSrcStyle->GetParent();
1364 const SfxItemSet& rSrcSet = pSrcStyle->GetItemSet();
1366 pDestStyle = &pDestPool->Make( aStrSrcStyle, eFamily, SfxStyleSearchBits::UserDefined );
1367 SfxItemSet& rDestSet = pDestStyle->GetItemSet();
1368 rDestSet.Put( rSrcSet );
1370 // number format exchange list has to be handled here, too
1371 // (only called for cell styles)
1373 const SfxUInt32Item* pSrcItem;
1374 if ( pFormatExchangeList &&
1375 (pSrcItem = rSrcSet.GetItemIfSet( ATTR_VALUE_FORMAT, false )) )
1377 sal_uInt32 nOldFormat = pSrcItem->GetValue();
1378 SvNumberFormatterIndexTable::const_iterator it = pFormatExchangeList->find(nOldFormat);
1379 if (it != pFormatExchangeList->end())
1381 sal_uInt32 nNewFormat = it->second;
1382 rDestSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
1386 // if necessary create derivative Styles, if not available:
1388 if ( ScResId(STR_STYLENAME_STANDARD) != aStrParent &&
1389 aStrSrcStyle != aStrParent &&
1390 !pDestPool->Find( aStrParent, eFamily ) )
1392 lcl_CopyStyleToPool( pSrcPool->Find( aStrParent, eFamily ),
1393 pSrcPool, pDestPool, pFormatExchangeList );
1396 pDestStyle->SetParent( aStrParent );
1399 return pDestStyle;
1402 CellAttributeHolder ScPatternAttr::MigrateToDocument( ScDocument* pDestDoc, ScDocument* pSrcDoc ) const
1404 const SfxItemSet* pSrcSet = &GetItemSet();
1405 ScPatternAttr* pDestPattern(new ScPatternAttr(pDestDoc->getCellAttributeHelper()));
1406 SfxItemSet* pDestSet(&pDestPattern->GetItemSet());
1408 // Copy cell pattern style to other document:
1409 if ( pDestDoc != pSrcDoc )
1411 OSL_ENSURE( pStyle, "Missing Pattern-Style! :-/" );
1413 // if pattern in DestDoc is available, use this, otherwise copy
1414 // parent style to style or create if necessary and attach DestDoc
1416 SfxStyleSheetBase* pStyleCpy = lcl_CopyStyleToPool( pStyle,
1417 pSrcDoc->GetStyleSheetPool(),
1418 pDestDoc->GetStyleSheetPool(),
1419 pDestDoc->GetFormatExchangeList() );
1421 pDestPattern->SetStyleSheet( static_cast<ScStyleSheet*>(pStyleCpy) );
1424 for ( sal_uInt16 nAttrId = ATTR_PATTERN_START; nAttrId <= ATTR_PATTERN_END; nAttrId++ )
1426 const SfxPoolItem* pSrcItem;
1427 SfxItemState eItemState = pSrcSet->GetItemState( nAttrId, false, &pSrcItem );
1428 if (eItemState==SfxItemState::SET)
1430 std::unique_ptr<SfxPoolItem> pNewItem;
1432 if ( nAttrId == ATTR_VALIDDATA )
1434 // Copy validity to the new document
1436 sal_uInt32 nNewIndex = 0;
1437 ScValidationDataList* pSrcList = pSrcDoc->GetValidationList();
1438 if ( pSrcList )
1440 sal_uInt32 nOldIndex = static_cast<const SfxUInt32Item*>(pSrcItem)->GetValue();
1441 const ScValidationData* pOldData = pSrcList->GetData( nOldIndex );
1442 if ( pOldData )
1443 nNewIndex = pDestDoc->AddValidationEntry( *pOldData );
1445 pNewItem.reset(new SfxUInt32Item( ATTR_VALIDDATA, nNewIndex ));
1447 else if ( nAttrId == ATTR_VALUE_FORMAT && pDestDoc->GetFormatExchangeList() )
1449 // Number format to Exchange List
1451 sal_uInt32 nOldFormat = static_cast<const SfxUInt32Item*>(pSrcItem)->GetValue();
1452 SvNumberFormatterIndexTable::const_iterator it = pDestDoc->GetFormatExchangeList()->find(nOldFormat);
1453 if (it != pDestDoc->GetFormatExchangeList()->end())
1455 sal_uInt32 nNewFormat = it->second;
1456 pNewItem.reset(new SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ));
1460 if ( pNewItem )
1462 pDestSet->Put(std::move(pNewItem));
1464 else
1465 pDestSet->Put(*pSrcItem);
1469 return CellAttributeHolder(pDestPattern, true);
1472 bool ScPatternAttr::IsVisible() const
1474 if (!mxVisible.has_value())
1475 mxVisible = CalcVisible();
1476 return *mxVisible;
1479 bool ScPatternAttr::CalcVisible() const
1481 const SfxItemSet& rSet = GetItemSet();
1483 if ( const SvxBrushItem* pItem = rSet.GetItemIfSet( ATTR_BACKGROUND ) )
1484 if ( pItem->GetColor() != COL_TRANSPARENT )
1485 return true;
1487 if ( const SvxBoxItem* pBoxItem = rSet.GetItemIfSet( ATTR_BORDER ) )
1489 if ( pBoxItem->GetTop() || pBoxItem->GetBottom() ||
1490 pBoxItem->GetLeft() || pBoxItem->GetRight() )
1491 return true;
1494 if ( const SvxLineItem* pItem = rSet.GetItemIfSet( ATTR_BORDER_TLBR ) )
1495 if( pItem->GetLine() )
1496 return true;
1498 if ( const SvxLineItem* pItem = rSet.GetItemIfSet( ATTR_BORDER_BLTR ) )
1499 if( pItem->GetLine() )
1500 return true;
1502 if ( const SvxShadowItem* pItem = rSet.GetItemIfSet( ATTR_SHADOW ) )
1503 if ( pItem->GetLocation() != SvxShadowLocation::NONE )
1504 return true;
1506 return false;
1509 static bool OneEqual( const SfxItemSet& rSet1, const SfxItemSet& rSet2, sal_uInt16 nId )
1511 const SfxPoolItem* pItem1 = &rSet1.Get(nId);
1512 const SfxPoolItem* pItem2 = &rSet2.Get(nId);
1513 return ( pItem1 == pItem2 || *pItem1 == *pItem2 );
1516 bool ScPatternAttr::IsVisibleEqual( const ScPatternAttr& rOther ) const
1518 const SfxItemSet& rThisSet = GetItemSet();
1519 const SfxItemSet& rOtherSet = rOther.GetItemSet();
1521 return OneEqual( rThisSet, rOtherSet, ATTR_BACKGROUND ) &&
1522 OneEqual( rThisSet, rOtherSet, ATTR_BORDER ) &&
1523 OneEqual( rThisSet, rOtherSet, ATTR_BORDER_TLBR ) &&
1524 OneEqual( rThisSet, rOtherSet, ATTR_BORDER_BLTR ) &&
1525 OneEqual( rThisSet, rOtherSet, ATTR_SHADOW );
1527 //TODO: also here only check really visible values !!!
1530 const OUString* ScPatternAttr::GetStyleName() const
1532 return moName ? &*moName : ( pStyle ? &pStyle->GetName() : nullptr );
1535 void ScPatternAttr::SetStyleSheet( ScStyleSheet* pNewStyle, bool bClearDirectFormat )
1537 if (pNewStyle)
1539 SfxItemSet& rPatternSet = GetItemSet();
1540 const SfxItemSet& rStyleSet = pNewStyle->GetItemSet();
1542 if (bClearDirectFormat)
1544 for (sal_uInt16 i=ATTR_PATTERN_START; i<=ATTR_PATTERN_END; i++)
1546 if (rStyleSet.GetItemState(i) == SfxItemState::SET)
1547 rPatternSet.ClearItem(i);
1550 rPatternSet.SetParent(&pNewStyle->GetItemSet());
1551 pStyle = pNewStyle;
1552 moName.reset();
1554 else
1556 OSL_FAIL( "ScPatternAttr::SetStyleSheet( NULL ) :-|" );
1557 GetItemSet().SetParent(nullptr);
1558 pStyle = nullptr;
1560 InvalidateCaches();
1563 bool ScPatternAttr::UpdateStyleSheet(const ScDocument& rDoc)
1565 bool bNameChanged = false;
1566 if (moName)
1568 pStyle = static_cast<ScStyleSheet*>(rDoc.GetStyleSheetPool()->Find(*moName, SfxStyleFamily::Para));
1570 // use Standard if Style is not found,
1571 // to avoid empty display in Toolbox-Controller
1572 // Assumes that "Standard" is always the 1st entry!
1573 if (!pStyle)
1575 std::unique_ptr<SfxStyleSheetIterator> pIter = rDoc.GetStyleSheetPool()->CreateIterator(SfxStyleFamily::Para);
1576 pStyle = dynamic_cast< ScStyleSheet* >(pIter->First());
1579 if (pStyle)
1581 GetItemSet().SetParent(&pStyle->GetItemSet());
1582 moName.reset();
1585 else
1587 pStyle = nullptr;
1588 bNameChanged = true;
1590 InvalidateCaches();
1591 return bNameChanged;
1594 void ScPatternAttr::StyleToName()
1596 // Style was deleted, remember name:
1598 if ( pStyle )
1600 moName = pStyle->GetName();
1601 pStyle = nullptr;
1602 GetItemSet().SetParent( nullptr );
1603 InvalidateCaches();
1607 bool ScPatternAttr::IsSymbolFont() const
1609 if( const SvxFontItem* pItem = GetItemSet().GetItemIfSet( ATTR_FONT ) )
1610 return pItem->GetCharSet() == RTL_TEXTENCODING_SYMBOL;
1611 else
1612 return false;
1615 namespace {
1617 sal_uInt32 getNumberFormatKey(const SfxItemSet& rSet)
1619 return rSet.Get(ATTR_VALUE_FORMAT).GetValue();
1622 LanguageType getLanguageType(const SfxItemSet& rSet)
1624 return rSet.Get(ATTR_LANGUAGE_FORMAT).GetLanguage();
1629 sal_uInt32 ScPatternAttr::GetNumberFormatKey() const
1631 if (!mxNumberFormatKey.has_value())
1632 mxNumberFormatKey = getNumberFormatKey(GetItemSet());
1633 return *mxNumberFormatKey;
1636 LanguageType ScPatternAttr::GetLanguageType() const
1638 if (!mxLanguageType.has_value())
1639 mxLanguageType = getLanguageType(GetItemSet());
1640 return *mxLanguageType;
1643 sal_uInt32 ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter ) const
1645 sal_uInt32 nFormat = GetNumberFormatKey();
1646 LanguageType eLang = GetLanguageType();
1647 if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLang == LANGUAGE_SYSTEM )
1648 ; // it remains as it is
1649 else if ( pFormatter )
1650 nFormat = pFormatter->GetFormatForLanguageIfBuiltIn( nFormat, eLang );
1651 return nFormat;
1654 sal_uInt32 ScPatternAttr::GetNumberFormat( const ScInterpreterContext& rContext ) const
1656 sal_uInt32 nFormat = GetNumberFormatKey();
1657 LanguageType eLang = GetLanguageType();
1658 if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLang == LANGUAGE_SYSTEM )
1659 ; // it remains as it is
1660 else
1661 nFormat = rContext.NFGetFormatForLanguageIfBuiltIn( nFormat, eLang );
1662 return nFormat;
1665 // the same if conditional formatting is in play:
1667 sal_uInt32 ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter,
1668 const SfxItemSet* pCondSet ) const
1670 assert(pFormatter);
1671 if (!pCondSet)
1672 return GetNumberFormat(pFormatter);
1674 // Conditional format takes precedence over style and even hard format.
1676 sal_uInt32 nFormat;
1677 LanguageType eLang;
1678 if (pCondSet->GetItemState(ATTR_VALUE_FORMAT) == SfxItemState::SET )
1680 nFormat = getNumberFormatKey(*pCondSet);
1681 if (pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT) == SfxItemState::SET)
1682 eLang = getLanguageType(*pCondSet);
1683 else
1684 eLang = GetLanguageType();
1686 else
1688 nFormat = GetNumberFormatKey();
1689 eLang = GetLanguageType();
1692 return pFormatter->GetFormatForLanguageIfBuiltIn(nFormat, eLang);
1695 sal_uInt32 ScPatternAttr::GetNumberFormat( const ScInterpreterContext& rContext,
1696 const SfxItemSet* pCondSet ) const
1698 if (!pCondSet)
1699 return GetNumberFormat(rContext);
1701 // Conditional format takes precedence over style and even hard format.
1703 sal_uInt32 nFormat;
1704 LanguageType eLang;
1705 if (pCondSet->GetItemState(ATTR_VALUE_FORMAT) == SfxItemState::SET )
1707 nFormat = getNumberFormatKey(*pCondSet);
1708 if (pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT) == SfxItemState::SET)
1709 eLang = getLanguageType(*pCondSet);
1710 else
1711 eLang = GetLanguageType();
1713 else
1715 nFormat = GetNumberFormatKey();
1716 eLang = GetLanguageType();
1719 return rContext.NFGetFormatForLanguageIfBuiltIn(nFormat, eLang);
1722 const SfxPoolItem& ScPatternAttr::GetItem( sal_uInt16 nWhich, const SfxItemSet& rItemSet, const SfxItemSet* pCondSet )
1724 const SfxPoolItem* pCondItem;
1725 if ( pCondSet && pCondSet->GetItemState( nWhich, true, &pCondItem ) == SfxItemState::SET )
1726 return *pCondItem;
1727 return rItemSet.Get(nWhich);
1730 const SfxPoolItem& ScPatternAttr::GetItem( sal_uInt16 nSubWhich, const SfxItemSet* pCondSet ) const
1732 return GetItem( nSubWhich, GetItemSet(), pCondSet );
1735 // GetRotateVal is tested before ATTR_ORIENTATION
1737 Degree100 ScPatternAttr::GetRotateVal( const SfxItemSet* pCondSet ) const
1739 Degree100 nAttrRotate(0);
1740 if ( GetCellOrientation() == SvxCellOrientation::Standard )
1742 bool bRepeat = ( GetItem(ATTR_HOR_JUSTIFY, pCondSet).
1743 GetValue() == SvxCellHorJustify::Repeat );
1744 // ignore orientation/rotation if "repeat" is active
1745 if ( !bRepeat )
1746 nAttrRotate = GetItem( ATTR_ROTATE_VALUE, pCondSet ).GetValue();
1748 return nAttrRotate;
1751 ScRotateDir ScPatternAttr::GetRotateDir( const SfxItemSet* pCondSet ) const
1753 ScRotateDir nRet = ScRotateDir::NONE;
1755 Degree100 nAttrRotate = GetRotateVal( pCondSet );
1756 if ( nAttrRotate )
1758 SvxRotateMode eRotMode = GetItem(ATTR_ROTATE_MODE, pCondSet).GetValue();
1760 if ( eRotMode == SVX_ROTATE_MODE_STANDARD || nAttrRotate == 18000_deg100 )
1761 nRet = ScRotateDir::Standard;
1762 else if ( eRotMode == SVX_ROTATE_MODE_CENTER )
1763 nRet = ScRotateDir::Center;
1764 else if ( eRotMode == SVX_ROTATE_MODE_TOP || eRotMode == SVX_ROTATE_MODE_BOTTOM )
1766 Degree100 nRot180 = nAttrRotate % 18000_deg100; // 1/100 degrees
1767 if ( nRot180 == 9000_deg100 )
1768 nRet = ScRotateDir::Center;
1769 else if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nRot180 < 9000_deg100 ) ||
1770 ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nRot180 > 9000_deg100 ) )
1771 nRet = ScRotateDir::Left;
1772 else
1773 nRet = ScRotateDir::Right;
1777 return nRet;
1780 void ScPatternAttr::SetPAKey(sal_uInt64 nKey)
1782 mnPAKey = nKey;
1785 sal_uInt64 ScPatternAttr::GetPAKey() const
1787 return mnPAKey;
1790 void ScPatternAttr::InvalidateCaches()
1792 mxVisible.reset();
1793 mxNumberFormatKey.reset();
1794 mxLanguageType.reset();
1797 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */