1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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/whiter.hxx>
51 #include <svl/zforlist.hxx>
52 #include <vcl/outdev.hxx>
53 #include <tools/fract.hxx>
54 #include <tools/UnitConversion.hxx>
55 #include <osl/diagnose.h>
58 #include <patattr.hxx>
59 #include <docpool.hxx>
60 #include <stlsheet.hxx>
61 #include <stlpool.hxx>
62 #include <document.hxx>
63 #include <globstr.hrc>
64 #include <scresid.hxx>
65 #include <validat.hxx>
67 #include <fillinfo.hxx>
68 #include <comphelper/lok.hxx>
69 #include <tabvwsh.hxx>
71 const WhichRangesContainer
aScPatternAttrSchema(svl::Items
<ATTR_PATTERN_START
, ATTR_PATTERN_END
>);
73 ScPatternAttr::ScPatternAttr( SfxItemSet
&& pItemSet
, const OUString
& rStyleName
)
74 : SfxSetItem ( ATTR_PATTERN
, std::move(pItemSet
) ),
79 setExceptionalSCItem();
81 // We need to ensure that ScPatternAttr is using the correct WhichRange,
82 // see comments in commit message. This does transfers the items with
83 // minimized overhead, too
84 if (GetItemSet().GetRanges() != aScPatternAttrSchema
)
85 GetItemSet().SetRanges(aScPatternAttrSchema
);
88 ScPatternAttr::ScPatternAttr( SfxItemSet
&& pItemSet
)
89 : SfxSetItem ( ATTR_PATTERN
, std::move(pItemSet
) ),
93 setExceptionalSCItem();
95 // We need to ensure that ScPatternAttr is using the correct WhichRange,
96 // see comments in commit message. This does transfers the items with
97 // minimized overhead, too
98 if (GetItemSet().GetRanges() != aScPatternAttrSchema
)
99 GetItemSet().SetRanges(aScPatternAttrSchema
);
102 ScPatternAttr::ScPatternAttr( SfxItemPool
* pItemPool
)
103 : SfxSetItem ( ATTR_PATTERN
, SfxItemSetFixed
<ATTR_PATTERN_START
, ATTR_PATTERN_END
>( *pItemPool
) ),
107 setExceptionalSCItem();
110 ScPatternAttr::ScPatternAttr( const ScPatternAttr
& rPatternAttr
)
111 : SfxSetItem ( rPatternAttr
),
112 pName ( rPatternAttr
.pName
),
113 pStyle ( rPatternAttr
.pStyle
),
114 mnPAKey(rPatternAttr
.mnPAKey
)
116 setExceptionalSCItem();
119 ScPatternAttr
* ScPatternAttr::Clone( SfxItemPool
*pPool
) const
121 ScPatternAttr
* pPattern
= new ScPatternAttr( GetItemSet().CloneAsValue(true, pPool
) );
123 pPattern
->pStyle
= pStyle
;
124 pPattern
->pName
= pName
;
129 static bool StrCmp( const OUString
* pStr1
, const OUString
* pStr2
)
137 return *pStr1
== *pStr2
;
140 constexpr size_t compareSize
= ATTR_PATTERN_END
- ATTR_PATTERN_START
+ 1;
142 bool ScPatternAttr::operator==( const SfxPoolItem
& rCmp
) const
144 // check if same incarnation
148 // check SfxPoolItem base class
149 if (!SfxPoolItem::operator==(rCmp
) )
152 // check everything except the SfxItemSet from base class SfxSetItem
153 const ScPatternAttr
& rOther(static_cast<const ScPatternAttr
&>(rCmp
));
154 if (!StrCmp(GetStyleName(), rOther
.GetStyleName()))
157 // here we need to compare the SfxItemSet. We *know* that these are
158 // all simple (one range, same range)
159 const SfxItemSet
& rSet1(GetItemSet());
160 const SfxItemSet
& rSet2(rOther
.GetItemSet());
162 // the former method 'FastEqualPatternSets' mentioned:
163 // "Actually test_tdf133629 from UITest_calc_tests9 somehow manages to have
164 // a different range (and I don't understand enough why), so better be safe and compare fully."
165 // in that case the hash code above would already fail, too
166 if (rSet1
.TotalCount() != compareSize
|| rSet2
.TotalCount() != compareSize
)
168 // assert this for now, should not happen. If it does, look for it and evtl.
169 // enable SfxItemSet::operator== below
171 return rSet1
== rSet2
;
174 // check pools, do not accept different pools
175 if (rSet1
.GetPool() != rSet2
.GetPool())
178 // check count of set items, has to be equal
179 if (rSet1
.Count() != rSet2
.Count())
182 // compare each item separately
183 const SfxPoolItem
**ppItem1(rSet1
.GetItems_Impl());
184 const SfxPoolItem
**ppItem2(rSet2
.GetItems_Impl());
186 // are all pointers the same?
187 if (0 == memcmp(ppItem1
, ppItem2
, compareSize
* sizeof(ppItem1
[0])))
190 for (sal_uInt16
nPos(0); nPos
< compareSize
; nPos
++)
192 if (!SfxPoolItem::areSame(*ppItem1
, *ppItem2
))
201 SvxCellOrientation
ScPatternAttr::GetCellOrientation( const SfxItemSet
& rItemSet
, const SfxItemSet
* pCondSet
)
203 SvxCellOrientation eOrient
= SvxCellOrientation::Standard
;
205 if( GetItem( ATTR_STACKED
, rItemSet
, pCondSet
).GetValue() )
207 eOrient
= SvxCellOrientation::Stacked
;
211 Degree100 nAngle
= GetItem( ATTR_ROTATE_VALUE
, rItemSet
, pCondSet
).GetValue();
212 if( nAngle
== 9000_deg100
)
213 eOrient
= SvxCellOrientation::BottomUp
;
214 else if( nAngle
== 27000_deg100
)
215 eOrient
= SvxCellOrientation::TopBottom
;
221 SvxCellOrientation
ScPatternAttr::GetCellOrientation( const SfxItemSet
* pCondSet
) const
223 return GetCellOrientation( GetItemSet(), pCondSet
);
228 void getFontIDsByScriptType(SvtScriptType nScript
,
229 TypedWhichId
<SvxFontItem
>& nFontId
,
230 TypedWhichId
<SvxFontHeightItem
>& nHeightId
,
231 TypedWhichId
<SvxWeightItem
>& nWeightId
,
232 TypedWhichId
<SvxPostureItem
>& nPostureId
,
233 TypedWhichId
<SvxLanguageItem
>& nLangId
)
235 if ( nScript
== SvtScriptType::ASIAN
)
237 nFontId
= ATTR_CJK_FONT
;
238 nHeightId
= ATTR_CJK_FONT_HEIGHT
;
239 nWeightId
= ATTR_CJK_FONT_WEIGHT
;
240 nPostureId
= ATTR_CJK_FONT_POSTURE
;
241 nLangId
= ATTR_CJK_FONT_LANGUAGE
;
243 else if ( nScript
== SvtScriptType::COMPLEX
)
245 nFontId
= ATTR_CTL_FONT
;
246 nHeightId
= ATTR_CTL_FONT_HEIGHT
;
247 nWeightId
= ATTR_CTL_FONT_WEIGHT
;
248 nPostureId
= ATTR_CTL_FONT_POSTURE
;
249 nLangId
= ATTR_CTL_FONT_LANGUAGE
;
254 nHeightId
= ATTR_FONT_HEIGHT
;
255 nWeightId
= ATTR_FONT_WEIGHT
;
256 nPostureId
= ATTR_FONT_POSTURE
;
257 nLangId
= ATTR_FONT_LANGUAGE
;
263 void ScPatternAttr::fillFont(
264 vcl::Font
& rFont
, const SfxItemSet
& rItemSet
, ScAutoFontColorMode eAutoMode
,
265 const OutputDevice
* pOutDev
, const Fraction
* pScale
,
266 const SfxItemSet
* pCondSet
, SvtScriptType nScript
,
267 const Color
* pBackConfigColor
, const Color
* pTextConfigColor
)
269 model::ComplexColor aComplexColor
;
271 // determine effective font color
272 ScPatternAttr::fillFontOnly(rFont
, rItemSet
, pOutDev
, pScale
, pCondSet
, nScript
);
273 ScPatternAttr::fillColor(aComplexColor
, rItemSet
, eAutoMode
, pCondSet
, pBackConfigColor
, pTextConfigColor
);
276 rFont
.SetColor(aComplexColor
.getFinalColor());
279 void ScPatternAttr::fillFontOnly(
280 vcl::Font
& rFont
, const SfxItemSet
& rItemSet
,
281 const OutputDevice
* pOutDev
, const Fraction
* pScale
,
282 const SfxItemSet
* pCondSet
, SvtScriptType nScript
)
286 const SvxFontItem
* pFontAttr
;
287 sal_uInt32 nFontHeight
;
290 FontLineStyle eUnder
;
293 FontStrikeout eStrike
;
296 FontEmphasisMark eEmphasis
;
300 TypedWhichId
<SvxFontItem
> nFontId(0);
301 TypedWhichId
<SvxFontHeightItem
> nHeightId(0);
302 TypedWhichId
<SvxWeightItem
> nWeightId(0);
303 TypedWhichId
<SvxPostureItem
> nPostureId(0);
304 TypedWhichId
<SvxLanguageItem
> nLangId(0);
305 getFontIDsByScriptType(nScript
, nFontId
, nHeightId
, nWeightId
, nPostureId
, nLangId
);
309 pFontAttr
= pCondSet
->GetItemIfSet( nFontId
);
311 pFontAttr
= &rItemSet
.Get( nFontId
);
313 const SvxFontHeightItem
* pFontHeightItem
= pCondSet
->GetItemIfSet( nHeightId
);
314 if ( !pFontHeightItem
)
315 pFontHeightItem
= &rItemSet
.Get( nHeightId
);
316 nFontHeight
= pFontHeightItem
->GetHeight();
318 const SvxWeightItem
* pFontHWeightItem
= pCondSet
->GetItemIfSet( nWeightId
);
319 if ( !pFontHWeightItem
)
320 pFontHWeightItem
= &rItemSet
.Get( nWeightId
);
321 eWeight
= pFontHWeightItem
->GetValue();
323 const SvxPostureItem
* pPostureItem
= pCondSet
->GetItemIfSet( nPostureId
);
325 pPostureItem
= &rItemSet
.Get( nPostureId
);
326 eItalic
= pPostureItem
->GetValue();
328 const SvxUnderlineItem
* pUnderlineItem
= pCondSet
->GetItemIfSet( ATTR_FONT_UNDERLINE
);
329 if ( !pUnderlineItem
)
330 pUnderlineItem
= &rItemSet
.Get( ATTR_FONT_UNDERLINE
);
331 eUnder
= pUnderlineItem
->GetValue();
333 const SvxOverlineItem
* pOverlineItem
= pCondSet
->GetItemIfSet( ATTR_FONT_OVERLINE
);
334 if ( !pOverlineItem
)
335 pOverlineItem
= &rItemSet
.Get( ATTR_FONT_OVERLINE
);
336 eOver
= pOverlineItem
->GetValue();
338 const SvxWordLineModeItem
* pWordlineItem
= pCondSet
->GetItemIfSet( ATTR_FONT_WORDLINE
);
339 if ( !pWordlineItem
)
340 pWordlineItem
= &rItemSet
.Get( ATTR_FONT_WORDLINE
);
341 bWordLine
= pWordlineItem
->GetValue();
343 const SvxCrossedOutItem
* pCrossedOutItem
= pCondSet
->GetItemIfSet( ATTR_FONT_CROSSEDOUT
);
344 if ( !pCrossedOutItem
)
345 pCrossedOutItem
= &rItemSet
.Get( ATTR_FONT_CROSSEDOUT
);
346 eStrike
= pCrossedOutItem
->GetValue();
348 const SvxContourItem
* pContourItem
= pCondSet
->GetItemIfSet( ATTR_FONT_CONTOUR
);
350 pContourItem
= &rItemSet
.Get( ATTR_FONT_CONTOUR
);
351 bOutline
= pContourItem
->GetValue();
353 const SvxShadowedItem
* pShadowedItem
= pCondSet
->GetItemIfSet( ATTR_FONT_SHADOWED
);
354 if ( !pShadowedItem
)
355 pShadowedItem
= &rItemSet
.Get( ATTR_FONT_SHADOWED
);
356 bShadow
= pShadowedItem
->GetValue();
358 const SvxEmphasisMarkItem
* pEmphasisMarkItem
= pCondSet
->GetItemIfSet( ATTR_FONT_EMPHASISMARK
);
359 if ( !pEmphasisMarkItem
)
360 pEmphasisMarkItem
= &rItemSet
.Get( ATTR_FONT_EMPHASISMARK
);
361 eEmphasis
= pEmphasisMarkItem
->GetEmphasisMark();
363 const SvxCharReliefItem
* pCharReliefItem
= pCondSet
->GetItemIfSet( ATTR_FONT_RELIEF
);
364 if ( !pCharReliefItem
)
365 pCharReliefItem
= &rItemSet
.Get( ATTR_FONT_RELIEF
);
366 eRelief
= pCharReliefItem
->GetValue();
368 const SvxLanguageItem
* pLanguageItem
= pCondSet
->GetItemIfSet( nLangId
);
369 if ( !pLanguageItem
)
370 pLanguageItem
= &rItemSet
.Get( nLangId
);
371 eLang
= pLanguageItem
->GetLanguage();
373 else // Everything from rItemSet
375 pFontAttr
= &rItemSet
.Get( nFontId
);
376 nFontHeight
= rItemSet
.Get( nHeightId
).GetHeight();
377 eWeight
= rItemSet
.Get( nWeightId
).GetValue();
378 eItalic
= rItemSet
.Get( nPostureId
).GetValue();
379 eUnder
= rItemSet
.Get( ATTR_FONT_UNDERLINE
).GetValue();
380 eOver
= rItemSet
.Get( ATTR_FONT_OVERLINE
).GetValue();
381 bWordLine
= rItemSet
.Get( ATTR_FONT_WORDLINE
).GetValue();
382 eStrike
= rItemSet
.Get( ATTR_FONT_CROSSEDOUT
).GetValue();
383 bOutline
= rItemSet
.Get( ATTR_FONT_CONTOUR
).GetValue();
384 bShadow
= rItemSet
.Get( ATTR_FONT_SHADOWED
).GetValue();
385 eEmphasis
= rItemSet
.Get( ATTR_FONT_EMPHASISMARK
).GetEmphasisMark();
386 eRelief
= rItemSet
.Get( ATTR_FONT_RELIEF
).GetValue();
387 // for graphite language features
388 eLang
= rItemSet
.Get( nLangId
).GetLanguage();
390 OSL_ENSURE(pFontAttr
,"Oops?");
396 if (rFont
.GetFamilyName() != pFontAttr
->GetFamilyName())
397 rFont
.SetFamilyName( pFontAttr
->GetFamilyName() );
398 if (rFont
.GetStyleName() != pFontAttr
->GetStyleName())
399 rFont
.SetStyleName( pFontAttr
->GetStyleName() );
401 rFont
.SetFamily( pFontAttr
->GetFamily() );
402 rFont
.SetCharSet( pFontAttr
->GetCharSet() );
403 rFont
.SetPitch( pFontAttr
->GetPitch() );
405 rFont
.SetLanguage(eLang
);
409 if ( pOutDev
!= nullptr )
412 Fraction
aFraction( 1,1 );
415 Size
aSize( 0, static_cast<tools::Long
>(nFontHeight
) );
416 MapMode aDestMode
= pOutDev
->GetMapMode();
417 MapMode
aSrcMode( MapUnit::MapTwip
, Point(), aFraction
, aFraction
);
418 if (aDestMode
.GetMapUnit() == MapUnit::MapPixel
&& pOutDev
->GetDPIX() > 0)
419 aEffSize
= pOutDev
->LogicToPixel( aSize
, aSrcMode
);
422 Fraction
aFractOne(1,1);
423 aDestMode
.SetScaleX( aFractOne
);
424 aDestMode
.SetScaleY( aFractOne
);
425 aEffSize
= OutputDevice::LogicToLogic( aSize
, aSrcMode
, aDestMode
);
427 rFont
.SetFontSize( aEffSize
);
429 else /* if pOutDev != NULL */
431 rFont
.SetFontSize( Size( 0, static_cast<tools::Long
>(nFontHeight
) ) );
435 rFont
.SetWeight( eWeight
);
436 rFont
.SetItalic( eItalic
);
437 rFont
.SetUnderline( eUnder
);
438 rFont
.SetOverline( eOver
);
439 rFont
.SetWordLineMode( bWordLine
);
440 rFont
.SetStrikeout( eStrike
);
441 rFont
.SetOutline( bOutline
);
442 rFont
.SetShadow( bShadow
);
443 rFont
.SetEmphasisMark( eEmphasis
);
444 rFont
.SetRelief( eRelief
);
445 rFont
.SetTransparent( true );
448 void ScPatternAttr::fillColor(model::ComplexColor
& rComplexColor
, const SfxItemSet
& rItemSet
, ScAutoFontColorMode eAutoMode
, const SfxItemSet
* pCondSet
, const Color
* pBackConfigColor
, const Color
* pTextConfigColor
)
450 model::ComplexColor aComplexColor
;
454 SvxColorItem
const* pColorItem
= nullptr;
457 pColorItem
= pCondSet
->GetItemIfSet(ATTR_FONT_COLOR
);
460 pColorItem
= &rItemSet
.Get(ATTR_FONT_COLOR
);
464 aComplexColor
= pColorItem
->getComplexColor();
465 aColor
= pColorItem
->GetValue();
468 if (aComplexColor
.getType() == model::ColorType::Unused
)
470 aComplexColor
.setColor(aColor
);
473 if ((aColor
== COL_AUTO
&& eAutoMode
!= ScAutoFontColorMode::Raw
)
474 || eAutoMode
== ScAutoFontColorMode::IgnoreFont
475 || eAutoMode
== ScAutoFontColorMode::IgnoreAll
)
477 // get background color from conditional or own set
481 const SvxBrushItem
* pItem
= pCondSet
->GetItemIfSet(ATTR_BACKGROUND
);
483 pItem
= &rItemSet
.Get(ATTR_BACKGROUND
);
484 aBackColor
= pItem
->GetColor();
488 aBackColor
= rItemSet
.Get(ATTR_BACKGROUND
).GetColor();
491 // if background color attribute is transparent, use window color for brightness comparisons
492 if (aBackColor
== COL_TRANSPARENT
493 || eAutoMode
== ScAutoFontColorMode::IgnoreBack
494 || eAutoMode
== ScAutoFontColorMode::IgnoreAll
)
496 if (!comphelper::LibreOfficeKit::isActive())
498 if ( eAutoMode
== ScAutoFontColorMode::Print
)
499 aBackColor
= COL_WHITE
;
500 else if ( pBackConfigColor
)
502 // pBackConfigColor can be used to avoid repeated lookup of the configured color
503 aBackColor
= *pBackConfigColor
;
506 aBackColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
;
510 // Get document color from current view instead
511 SfxViewShell
* pSfxViewShell
= SfxViewShell::Current();
512 ScTabViewShell
* pViewShell
= dynamic_cast<ScTabViewShell
*>(pSfxViewShell
);
515 const ScViewRenderingOptions
& rViewRenderingOptions
= pViewShell
->GetViewRenderingData();
516 aBackColor
= eAutoMode
== ScAutoFontColorMode::Print
? COL_WHITE
:
517 rViewRenderingOptions
.GetDocColor();
522 // get system text color for comparison
524 if (eAutoMode
== ScAutoFontColorMode::Print
)
526 aSysTextColor
= COL_BLACK
;
528 else if (pTextConfigColor
)
530 // pTextConfigColor can be used to avoid repeated lookup of the configured color
531 aSysTextColor
= *pTextConfigColor
;
535 aSysTextColor
= SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
;
538 // select the resulting color
539 if ( aBackColor
.IsDark() && aSysTextColor
.IsDark() )
541 // use white instead of dark on dark
544 else if ( aBackColor
.IsBright() && aSysTextColor
.IsBright() )
546 // use black instead of bright on bright
551 // use aSysTextColor (black for ScAutoFontColorMode::Print, from style settings otherwise)
552 aColor
= aSysTextColor
;
555 aComplexColor
.setFinalColor(aColor
);
556 rComplexColor
= aComplexColor
;
559 ScDxfFont
ScPatternAttr::GetDxfFont(const SfxItemSet
& rItemSet
, SvtScriptType nScript
)
561 TypedWhichId
<SvxFontItem
> nFontId(0);
562 TypedWhichId
<SvxFontHeightItem
> nHeightId(0);
563 TypedWhichId
<SvxWeightItem
> nWeightId(0);
564 TypedWhichId
<SvxPostureItem
> nPostureId(0);
565 TypedWhichId
<SvxLanguageItem
> nLangId(0);
566 getFontIDsByScriptType(nScript
, nFontId
, nHeightId
, nWeightId
, nPostureId
, nLangId
);
570 if ( const SvxFontItem
* pItem
= rItemSet
.GetItemIfSet( nFontId
) )
572 aReturn
.pFontAttr
= pItem
;
575 if ( const SvxFontHeightItem
* pItem
= rItemSet
.GetItemIfSet( nHeightId
) )
577 aReturn
.nFontHeight
= pItem
->GetHeight();
580 if ( const SvxWeightItem
* pItem
= rItemSet
.GetItemIfSet( nWeightId
) )
582 aReturn
.eWeight
= pItem
->GetValue();
585 if ( const SvxPostureItem
* pItem
= rItemSet
.GetItemIfSet( nPostureId
) )
587 aReturn
.eItalic
= pItem
->GetValue();
590 if ( const SvxUnderlineItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_UNDERLINE
) )
592 pItem
= &rItemSet
.Get( ATTR_FONT_UNDERLINE
);
593 aReturn
.eUnder
= pItem
->GetValue();
596 if ( const SvxOverlineItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_OVERLINE
) )
598 aReturn
.eOver
= pItem
->GetValue();
601 if ( const SvxWordLineModeItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_WORDLINE
) )
603 aReturn
.bWordLine
= pItem
->GetValue();
606 if ( const SvxCrossedOutItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_CROSSEDOUT
) )
608 pItem
= &rItemSet
.Get( ATTR_FONT_CROSSEDOUT
);
609 aReturn
.eStrike
= pItem
->GetValue();
612 if ( const SvxContourItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_CONTOUR
) )
614 aReturn
.bOutline
= pItem
->GetValue();
617 if ( const SvxShadowedItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_SHADOWED
) )
619 pItem
= &rItemSet
.Get( ATTR_FONT_SHADOWED
);
620 aReturn
.bShadow
= pItem
->GetValue();
623 if ( const SvxEmphasisMarkItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_EMPHASISMARK
) )
625 aReturn
.eEmphasis
= pItem
->GetEmphasisMark();
628 if ( const SvxCharReliefItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_RELIEF
) )
630 aReturn
.eRelief
= pItem
->GetValue();
633 if ( const SvxColorItem
* pItem
= rItemSet
.GetItemIfSet( ATTR_FONT_COLOR
) )
635 aReturn
.aColor
= pItem
->GetValue();
638 if ( const SvxLanguageItem
* pItem
= rItemSet
.GetItemIfSet( nLangId
) )
640 aReturn
.eLang
= pItem
->GetLanguage();
647 static void lcl_populate( std::unique_ptr
<T
>& rxItem
, TypedWhichId
<T
> nWhich
, const SfxItemSet
& rSrcSet
, const SfxItemSet
* pCondSet
)
649 const T
* pItem
= pCondSet
->GetItemIfSet( nWhich
);
651 pItem
= &rSrcSet
.Get( nWhich
);
652 rxItem
.reset(pItem
->Clone());
655 void ScPatternAttr::FillToEditItemSet( SfxItemSet
& rEditSet
, const SfxItemSet
& rSrcSet
, const SfxItemSet
* pCondSet
)
659 std::unique_ptr
<SvxColorItem
> aColorItem(std::make_unique
<SvxColorItem
>(EE_CHAR_COLOR
)); // use item as-is
660 std::unique_ptr
<SvxFontItem
> aFontItem(std::make_unique
<SvxFontItem
>(EE_CHAR_FONTINFO
)); // use item as-is
661 std::unique_ptr
<SvxFontItem
> aCjkFontItem(std::make_unique
<SvxFontItem
>(EE_CHAR_FONTINFO_CJK
)); // use item as-is
662 std::unique_ptr
<SvxFontItem
> aCtlFontItem(std::make_unique
<SvxFontItem
>(EE_CHAR_FONTINFO_CTL
)); // use item as-is
663 tools::Long nTHeight
, nCjkTHeight
, nCtlTHeight
; // Twips
664 FontWeight eWeight
, eCjkWeight
, eCtlWeight
;
665 std::unique_ptr
<SvxUnderlineItem
> aUnderlineItem(std::make_unique
<SvxUnderlineItem
>(LINESTYLE_NONE
, EE_CHAR_UNDERLINE
));
666 std::unique_ptr
<SvxOverlineItem
> aOverlineItem(std::make_unique
<SvxOverlineItem
>(LINESTYLE_NONE
, EE_CHAR_OVERLINE
));
668 FontStrikeout eStrike
;
669 FontItalic eItalic
, eCjkItalic
, eCtlItalic
;
673 FontEmphasisMark eEmphasis
;
675 LanguageType eLang
, eCjkLang
, eCtlLang
;
677 SvxFrameDirection eDirection
;
679 //TODO: additional parameter to control if language is needed?
683 lcl_populate(aColorItem
, ATTR_FONT_COLOR
, rSrcSet
, pCondSet
);
684 lcl_populate(aFontItem
, ATTR_FONT
, rSrcSet
, pCondSet
);
685 lcl_populate(aCjkFontItem
, ATTR_CJK_FONT
, rSrcSet
, pCondSet
);
686 lcl_populate(aCtlFontItem
, ATTR_CTL_FONT
, rSrcSet
, pCondSet
);
688 const SvxFontHeightItem
* pFontHeightItem
= pCondSet
->GetItemIfSet( ATTR_FONT_HEIGHT
);
689 if (!pFontHeightItem
)
690 pFontHeightItem
= &rSrcSet
.Get( ATTR_FONT_HEIGHT
);
691 nTHeight
= pFontHeightItem
->GetHeight();
692 pFontHeightItem
= pCondSet
->GetItemIfSet( ATTR_CJK_FONT_HEIGHT
);
693 if ( !pFontHeightItem
)
694 pFontHeightItem
= &rSrcSet
.Get( ATTR_CJK_FONT_HEIGHT
);
695 nCjkTHeight
= pFontHeightItem
->GetHeight();
696 pFontHeightItem
= pCondSet
->GetItemIfSet( ATTR_CTL_FONT_HEIGHT
);
697 if ( !pFontHeightItem
)
698 pFontHeightItem
= &rSrcSet
.Get( ATTR_CTL_FONT_HEIGHT
);
699 nCtlTHeight
= pFontHeightItem
->GetHeight();
701 const SvxWeightItem
* pWeightItem
= pCondSet
->GetItemIfSet( ATTR_FONT_WEIGHT
);
703 pWeightItem
= &rSrcSet
.Get( ATTR_FONT_WEIGHT
);
704 eWeight
= pWeightItem
->GetValue();
705 pWeightItem
= pCondSet
->GetItemIfSet( ATTR_CJK_FONT_WEIGHT
);
707 pWeightItem
= &rSrcSet
.Get( ATTR_CJK_FONT_WEIGHT
);
708 eCjkWeight
= pWeightItem
->GetValue();
709 pWeightItem
= pCondSet
->GetItemIfSet( ATTR_CTL_FONT_WEIGHT
);
711 pWeightItem
= &rSrcSet
.Get( ATTR_CTL_FONT_WEIGHT
);
712 eCtlWeight
= pWeightItem
->GetValue();
714 const SvxPostureItem
* pPostureItem
= pCondSet
->GetItemIfSet( ATTR_FONT_POSTURE
);
716 pPostureItem
= &rSrcSet
.Get( ATTR_FONT_POSTURE
);
717 eItalic
= pPostureItem
->GetValue();
718 pPostureItem
= pCondSet
->GetItemIfSet( ATTR_CJK_FONT_POSTURE
);
720 pPostureItem
= &rSrcSet
.Get( ATTR_CJK_FONT_POSTURE
);
721 eCjkItalic
= pPostureItem
->GetValue();
722 pPostureItem
= pCondSet
->GetItemIfSet( ATTR_CTL_FONT_POSTURE
);
724 pPostureItem
= &rSrcSet
.Get( ATTR_CTL_FONT_POSTURE
);
725 eCtlItalic
= pPostureItem
->GetValue();
727 lcl_populate(aUnderlineItem
, ATTR_FONT_UNDERLINE
, rSrcSet
, pCondSet
);
728 lcl_populate(aOverlineItem
, ATTR_FONT_OVERLINE
, rSrcSet
, pCondSet
);
730 const SvxWordLineModeItem
* pWordLineModeItem
= pCondSet
->GetItemIfSet( ATTR_FONT_WORDLINE
);
731 if ( !pWordLineModeItem
)
732 pWordLineModeItem
= &rSrcSet
.Get( ATTR_FONT_WORDLINE
);
733 bWordLine
= pWordLineModeItem
->GetValue();
735 const SvxCrossedOutItem
* pCrossedOutItem
= pCondSet
->GetItemIfSet( ATTR_FONT_CROSSEDOUT
);
736 if ( !pCrossedOutItem
)
737 pCrossedOutItem
= &rSrcSet
.Get( ATTR_FONT_CROSSEDOUT
);
738 eStrike
= pCrossedOutItem
->GetValue();
740 const SvxContourItem
* pContourItem
= pCondSet
->GetItemIfSet( ATTR_FONT_CONTOUR
);
742 pContourItem
= &rSrcSet
.Get( ATTR_FONT_CONTOUR
);
743 bOutline
= pContourItem
->GetValue();
745 const SvxShadowedItem
* pShadowedItem
= pCondSet
->GetItemIfSet( ATTR_FONT_SHADOWED
);
746 if ( !pShadowedItem
)
747 pShadowedItem
= &rSrcSet
.Get( ATTR_FONT_SHADOWED
);
748 bShadow
= pShadowedItem
->GetValue();
750 const SvxForbiddenRuleItem
* pForbiddenRuleItem
= pCondSet
->GetItemIfSet( ATTR_FORBIDDEN_RULES
);
751 if ( !pForbiddenRuleItem
)
752 pForbiddenRuleItem
= &rSrcSet
.Get( ATTR_FORBIDDEN_RULES
);
753 bForbidden
= pForbiddenRuleItem
->GetValue();
755 const SvxEmphasisMarkItem
* pEmphasisMarkItem
= pCondSet
->GetItemIfSet( ATTR_FONT_EMPHASISMARK
);
756 if ( !pEmphasisMarkItem
)
757 pEmphasisMarkItem
= &rSrcSet
.Get( ATTR_FONT_EMPHASISMARK
);
758 eEmphasis
= pEmphasisMarkItem
->GetEmphasisMark();
759 const SvxCharReliefItem
* pCharReliefItem
= pCondSet
->GetItemIfSet( ATTR_FONT_RELIEF
);
760 if ( !pCharReliefItem
)
761 pCharReliefItem
= &rSrcSet
.Get( ATTR_FONT_RELIEF
);
762 eRelief
= pCharReliefItem
->GetValue();
764 const SvxLanguageItem
* pLanguageItem
= pCondSet
->GetItemIfSet( ATTR_FONT_LANGUAGE
);
765 if ( !pLanguageItem
)
766 pLanguageItem
= &rSrcSet
.Get( ATTR_FONT_LANGUAGE
);
767 eLang
= pLanguageItem
->GetLanguage();
768 pLanguageItem
= pCondSet
->GetItemIfSet( ATTR_CJK_FONT_LANGUAGE
);
769 if ( !pLanguageItem
)
770 pLanguageItem
= &rSrcSet
.Get( ATTR_CJK_FONT_LANGUAGE
);
771 eCjkLang
= pLanguageItem
->GetLanguage();
772 pLanguageItem
= pCondSet
->GetItemIfSet( ATTR_CTL_FONT_LANGUAGE
);
773 if ( !pLanguageItem
)
774 pLanguageItem
= &rSrcSet
.Get( ATTR_CTL_FONT_LANGUAGE
);
775 eCtlLang
= pLanguageItem
->GetLanguage();
777 const ScHyphenateCell
* pHyphenateCell
= pCondSet
->GetItemIfSet( ATTR_HYPHENATE
);
778 if ( !pHyphenateCell
)
779 pHyphenateCell
= &rSrcSet
.Get( ATTR_HYPHENATE
);
780 bHyphenate
= pHyphenateCell
->GetValue();
782 const SvxFrameDirectionItem
* pFrameDirectionItem
= pCondSet
->GetItemIfSet( ATTR_WRITINGDIR
);
783 if ( !pFrameDirectionItem
)
784 pFrameDirectionItem
= &rSrcSet
.Get( ATTR_WRITINGDIR
);
785 eDirection
= pFrameDirectionItem
->GetValue();
787 else // Everything directly from Pattern
789 aColorItem
.reset(rSrcSet
.Get(ATTR_FONT_COLOR
).Clone());
790 aFontItem
.reset(rSrcSet
.Get(ATTR_FONT
).Clone());
791 aCjkFontItem
.reset(rSrcSet
.Get(ATTR_CJK_FONT
).Clone());
792 aCtlFontItem
.reset(rSrcSet
.Get(ATTR_CTL_FONT
).Clone());
793 nTHeight
= rSrcSet
.Get( ATTR_FONT_HEIGHT
).GetHeight();
794 nCjkTHeight
= rSrcSet
.Get( ATTR_CJK_FONT_HEIGHT
).GetHeight();
795 nCtlTHeight
= rSrcSet
.Get( ATTR_CTL_FONT_HEIGHT
).GetHeight();
796 eWeight
= rSrcSet
.Get( ATTR_FONT_WEIGHT
).GetValue();
797 eCjkWeight
= rSrcSet
.Get( ATTR_CJK_FONT_WEIGHT
).GetValue();
798 eCtlWeight
= rSrcSet
.Get( ATTR_CTL_FONT_WEIGHT
).GetValue();
799 eItalic
= rSrcSet
.Get( ATTR_FONT_POSTURE
).GetValue();
800 eCjkItalic
= rSrcSet
.Get( ATTR_CJK_FONT_POSTURE
).GetValue();
801 eCtlItalic
= rSrcSet
.Get( ATTR_CTL_FONT_POSTURE
).GetValue();
802 aUnderlineItem
.reset(rSrcSet
.Get(ATTR_FONT_UNDERLINE
).Clone());
803 aOverlineItem
.reset(rSrcSet
.Get(ATTR_FONT_OVERLINE
).Clone());
804 bWordLine
= rSrcSet
.Get( ATTR_FONT_WORDLINE
).GetValue();
805 eStrike
= rSrcSet
.Get( ATTR_FONT_CROSSEDOUT
).GetValue();
806 bOutline
= rSrcSet
.Get( ATTR_FONT_CONTOUR
).GetValue();
807 bShadow
= rSrcSet
.Get( ATTR_FONT_SHADOWED
).GetValue();
808 bForbidden
= rSrcSet
.Get( ATTR_FORBIDDEN_RULES
).GetValue();
809 eEmphasis
= rSrcSet
.Get( ATTR_FONT_EMPHASISMARK
).GetEmphasisMark();
810 eRelief
= rSrcSet
.Get( ATTR_FONT_RELIEF
).GetValue();
811 eLang
= rSrcSet
.Get( ATTR_FONT_LANGUAGE
).GetLanguage();
812 eCjkLang
= rSrcSet
.Get( ATTR_CJK_FONT_LANGUAGE
).GetLanguage();
813 eCtlLang
= rSrcSet
.Get( ATTR_CTL_FONT_LANGUAGE
).GetLanguage();
814 bHyphenate
= rSrcSet
.Get( ATTR_HYPHENATE
).GetValue();
815 eDirection
= rSrcSet
.Get( ATTR_WRITINGDIR
).GetValue();
818 // Expect to be compatible to LogicToLogic, ie. 2540/1440 = 127/72, and round
820 tools::Long nHeight
= convertTwipToMm100(nTHeight
);
821 tools::Long nCjkHeight
= convertTwipToMm100(nCjkTHeight
);
822 tools::Long nCtlHeight
= convertTwipToMm100(nCtlTHeight
);
824 // put items into EditEngine ItemSet
826 if ( aColorItem
->GetValue() == COL_AUTO
)
828 // When cell attributes are converted to EditEngine paragraph attributes,
829 // don't create a hard item for automatic color, because that would be converted
830 // to black when the item's Store method is used in CreateTransferable/WriteBin.
831 // COL_AUTO is the EditEngine's pool default, so ClearItem will result in automatic
832 // color, too, without having to store the item.
833 rEditSet
.ClearItem( EE_CHAR_COLOR
);
837 // tdf#125054 adapt WhichID
838 rEditSet
.Put( std::move(aColorItem
), EE_CHAR_COLOR
);
841 // tdf#125054 adapt WhichID
842 rEditSet
.Put( std::move(aFontItem
), EE_CHAR_FONTINFO
);
843 rEditSet
.Put( std::move(aCjkFontItem
), EE_CHAR_FONTINFO_CJK
);
844 rEditSet
.Put( std::move(aCtlFontItem
), EE_CHAR_FONTINFO_CTL
);
846 rEditSet
.Put( SvxFontHeightItem( nHeight
, 100, EE_CHAR_FONTHEIGHT
) );
847 rEditSet
.Put( SvxFontHeightItem( nCjkHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
848 rEditSet
.Put( SvxFontHeightItem( nCtlHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
849 rEditSet
.Put( SvxWeightItem ( eWeight
, EE_CHAR_WEIGHT
) );
850 rEditSet
.Put( SvxWeightItem ( eCjkWeight
, EE_CHAR_WEIGHT_CJK
) );
851 rEditSet
.Put( SvxWeightItem ( eCtlWeight
, EE_CHAR_WEIGHT_CTL
) );
853 // tdf#125054 adapt WhichID
854 rEditSet
.Put( std::move(aUnderlineItem
), EE_CHAR_UNDERLINE
);
855 rEditSet
.Put( std::move(aOverlineItem
), EE_CHAR_OVERLINE
);
857 rEditSet
.Put( SvxWordLineModeItem( bWordLine
, EE_CHAR_WLM
) );
858 rEditSet
.Put( SvxCrossedOutItem( eStrike
, EE_CHAR_STRIKEOUT
) );
859 rEditSet
.Put( SvxPostureItem ( eItalic
, EE_CHAR_ITALIC
) );
860 rEditSet
.Put( SvxPostureItem ( eCjkItalic
, EE_CHAR_ITALIC_CJK
) );
861 rEditSet
.Put( SvxPostureItem ( eCtlItalic
, EE_CHAR_ITALIC_CTL
) );
862 rEditSet
.Put( SvxContourItem ( bOutline
, EE_CHAR_OUTLINE
) );
863 rEditSet
.Put( SvxShadowedItem ( bShadow
, EE_CHAR_SHADOW
) );
864 rEditSet
.Put( SvxForbiddenRuleItem(bForbidden
, EE_PARA_FORBIDDENRULES
) );
865 rEditSet
.Put( SvxEmphasisMarkItem( eEmphasis
, EE_CHAR_EMPHASISMARK
) );
866 rEditSet
.Put( SvxCharReliefItem( eRelief
, EE_CHAR_RELIEF
) );
867 rEditSet
.Put( SvxLanguageItem ( eLang
, EE_CHAR_LANGUAGE
) );
868 rEditSet
.Put( SvxLanguageItem ( eCjkLang
, EE_CHAR_LANGUAGE_CJK
) );
869 rEditSet
.Put( SvxLanguageItem ( eCtlLang
, EE_CHAR_LANGUAGE_CTL
) );
870 rEditSet
.Put( SfxBoolItem ( EE_PARA_HYPHENATE
, bHyphenate
) );
871 rEditSet
.Put( SvxFrameDirectionItem( eDirection
, EE_PARA_WRITINGDIR
) );
873 // Script spacing is always off.
874 // The cell attribute isn't used here as long as there is no UI to set it
875 // (don't evaluate attributes that can't be changed).
876 // If a locale-dependent default is needed, it has to go into the cell
877 // style, like the fonts.
878 rEditSet
.Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING
) );
881 void ScPatternAttr::FillEditItemSet( SfxItemSet
* pEditSet
, const SfxItemSet
* pCondSet
) const
884 FillToEditItemSet( *pEditSet
, GetItemSet(), pCondSet
);
887 void ScPatternAttr::GetFromEditItemSet( SfxItemSet
& rDestSet
, const SfxItemSet
& rEditSet
)
889 if (const SvxColorItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_COLOR
))
890 rDestSet
.Put( *pItem
, ATTR_FONT_COLOR
);
892 if (const SvxFontItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_FONTINFO
))
893 rDestSet
.Put( *pItem
, ATTR_FONT
);
894 if (const SvxFontItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_FONTINFO_CJK
))
895 rDestSet
.Put( *pItem
, ATTR_CJK_FONT
);
896 if (const SvxFontItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_FONTINFO_CTL
))
897 rDestSet
.Put( *pItem
, ATTR_CTL_FONT
);
899 if (const SvxFontHeightItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_FONTHEIGHT
))
900 rDestSet
.Put( SvxFontHeightItem(o3tl::toTwips(pItem
->GetHeight(), o3tl::Length::mm100
),
901 100, ATTR_FONT_HEIGHT
) );
902 if (const SvxFontHeightItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_FONTHEIGHT_CJK
))
903 rDestSet
.Put( SvxFontHeightItem(o3tl::toTwips(pItem
->GetHeight(), o3tl::Length::mm100
),
904 100, ATTR_CJK_FONT_HEIGHT
) );
905 if (const SvxFontHeightItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_FONTHEIGHT_CTL
))
906 rDestSet
.Put( SvxFontHeightItem(o3tl::toTwips(pItem
->GetHeight(), o3tl::Length::mm100
),
907 100, ATTR_CTL_FONT_HEIGHT
) );
909 if (const SvxWeightItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_WEIGHT
))
910 rDestSet
.Put( SvxWeightItem( pItem
->GetValue(),
912 if (const SvxWeightItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_WEIGHT_CJK
))
913 rDestSet
.Put( SvxWeightItem( pItem
->GetValue(),
914 ATTR_CJK_FONT_WEIGHT
) );
915 if (const SvxWeightItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_WEIGHT_CTL
))
916 rDestSet
.Put( SvxWeightItem( pItem
->GetValue(),
917 ATTR_CTL_FONT_WEIGHT
) );
919 // SvxTextLineItem contains enum and color
920 if (const SvxUnderlineItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_UNDERLINE
))
921 rDestSet
.Put( *pItem
, ATTR_FONT_UNDERLINE
);
922 if (const SvxOverlineItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_OVERLINE
))
923 rDestSet
.Put( *pItem
, ATTR_FONT_OVERLINE
);
924 if (const SvxWordLineModeItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_WLM
))
925 rDestSet
.Put( SvxWordLineModeItem( pItem
->GetValue(),
926 ATTR_FONT_WORDLINE
) );
928 if (const SvxCrossedOutItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_STRIKEOUT
))
929 rDestSet
.Put( SvxCrossedOutItem( pItem
->GetValue(),
930 ATTR_FONT_CROSSEDOUT
) );
932 if (const SvxPostureItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_ITALIC
))
933 rDestSet
.Put( SvxPostureItem( pItem
->GetValue(),
934 ATTR_FONT_POSTURE
) );
935 if (const SvxPostureItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_ITALIC_CJK
))
936 rDestSet
.Put( SvxPostureItem( pItem
->GetValue(),
937 ATTR_CJK_FONT_POSTURE
) );
938 if (const SvxPostureItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_ITALIC_CTL
))
939 rDestSet
.Put( SvxPostureItem( pItem
->GetValue(),
940 ATTR_CTL_FONT_POSTURE
) );
942 if (const SvxContourItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_OUTLINE
))
943 rDestSet
.Put( SvxContourItem( pItem
->GetValue(),
944 ATTR_FONT_CONTOUR
) );
945 if (const SvxShadowedItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_SHADOW
))
946 rDestSet
.Put( SvxShadowedItem( pItem
->GetValue(),
947 ATTR_FONT_SHADOWED
) );
948 if (const SvxEmphasisMarkItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_EMPHASISMARK
))
949 rDestSet
.Put( SvxEmphasisMarkItem( pItem
->GetEmphasisMark(),
950 ATTR_FONT_EMPHASISMARK
) );
951 if (const SvxCharReliefItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_RELIEF
))
952 rDestSet
.Put( SvxCharReliefItem( pItem
->GetValue(),
955 if (const SvxLanguageItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_LANGUAGE
))
956 rDestSet
.Put( SvxLanguageItem(pItem
->GetValue(), ATTR_FONT_LANGUAGE
) );
957 if (const SvxLanguageItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_LANGUAGE_CJK
))
958 rDestSet
.Put( SvxLanguageItem(pItem
->GetValue(), ATTR_CJK_FONT_LANGUAGE
) );
959 if (const SvxLanguageItem
* pItem
= rEditSet
.GetItemIfSet(EE_CHAR_LANGUAGE_CTL
))
960 rDestSet
.Put( SvxLanguageItem(pItem
->GetValue(), ATTR_CTL_FONT_LANGUAGE
) );
962 const SvxAdjustItem
* pAdjustItem
= rEditSet
.GetItemIfSet(EE_PARA_JUST
);
967 SvxCellHorJustify eVal
;
968 switch ( pAdjustItem
->GetAdjust() )
970 case SvxAdjust::Left
:
971 // EditEngine Default is always set in the GetAttribs() ItemSet !
972 // whether left or right, is decided in text / number
973 eVal
= SvxCellHorJustify::Standard
;
975 case SvxAdjust::Right
:
976 eVal
= SvxCellHorJustify::Right
;
978 case SvxAdjust::Block
:
979 eVal
= SvxCellHorJustify::Block
;
981 case SvxAdjust::Center
:
982 eVal
= SvxCellHorJustify::Center
;
984 case SvxAdjust::BlockLine
:
985 eVal
= SvxCellHorJustify::Block
;
988 eVal
= SvxCellHorJustify::Right
;
991 eVal
= SvxCellHorJustify::Standard
;
993 if ( eVal
!= SvxCellHorJustify::Standard
)
994 rDestSet
.Put( SvxHorJustifyItem( eVal
, ATTR_HOR_JUSTIFY
) );
997 void ScPatternAttr::GetFromEditItemSet( const SfxItemSet
* pEditSet
)
1001 GetFromEditItemSet( GetItemSet(), *pEditSet
);
1005 void ScPatternAttr::FillEditParaItems( SfxItemSet
* pEditSet
) const
1007 // already there in GetFromEditItemSet, but not in FillEditItemSet
1008 // Default horizontal alignment is always implemented as left
1010 const SfxItemSet
& rMySet
= GetItemSet();
1012 SvxCellHorJustify eHorJust
= rMySet
.Get(ATTR_HOR_JUSTIFY
).GetValue();
1014 SvxAdjust eSvxAdjust
;
1017 case SvxCellHorJustify::Right
: eSvxAdjust
= SvxAdjust::Right
; break;
1018 case SvxCellHorJustify::Center
: eSvxAdjust
= SvxAdjust::Center
; break;
1019 case SvxCellHorJustify::Block
: eSvxAdjust
= SvxAdjust::Block
; break;
1020 default: eSvxAdjust
= SvxAdjust::Left
; break;
1022 pEditSet
->Put( SvxAdjustItem( eSvxAdjust
, EE_PARA_JUST
) );
1025 void ScPatternAttr::DeleteUnchanged( const ScPatternAttr
* pOldAttrs
)
1027 SfxItemSet
& rThisSet
= GetItemSet();
1028 const SfxItemSet
& rOldSet
= pOldAttrs
->GetItemSet();
1030 const SfxPoolItem
* pThisItem
;
1031 const SfxPoolItem
* pOldItem
;
1033 for ( sal_uInt16 nSubWhich
=ATTR_PATTERN_START
; nSubWhich
<=ATTR_PATTERN_END
; nSubWhich
++ )
1035 // only items that are set are interesting
1036 if ( rThisSet
.GetItemState( nSubWhich
, false, &pThisItem
) == SfxItemState::SET
)
1038 SfxItemState eOldState
= rOldSet
.GetItemState( nSubWhich
, true, &pOldItem
);
1039 if ( eOldState
== SfxItemState::SET
)
1041 // item is set in OldAttrs (or its parent) -> compare pointers
1042 if (SfxPoolItem::areSame( pThisItem
, pOldItem
))
1044 rThisSet
.ClearItem( nSubWhich
);
1048 else if ( eOldState
!= SfxItemState::DONTCARE
)
1050 // not set in OldAttrs -> compare item value to default item
1051 if ( *pThisItem
== rThisSet
.GetPool()->GetDefaultItem( nSubWhich
) )
1053 rThisSet
.ClearItem( nSubWhich
);
1061 bool ScPatternAttr::HasItemsSet( const sal_uInt16
* pWhich
) const
1063 const SfxItemSet
& rSet
= GetItemSet();
1064 for (sal_uInt16 i
=0; pWhich
[i
]; i
++)
1065 if ( rSet
.GetItemState( pWhich
[i
], false ) == SfxItemState::SET
)
1070 void ScPatternAttr::ClearItems( const sal_uInt16
* pWhich
)
1072 SfxItemSet
& rSet
= GetItemSet();
1073 for (sal_uInt16 i
=0; pWhich
[i
]; i
++)
1074 rSet
.ClearItem(pWhich
[i
]);
1078 static SfxStyleSheetBase
* lcl_CopyStyleToPool
1080 SfxStyleSheetBase
* pSrcStyle
,
1081 SfxStyleSheetBasePool
* pSrcPool
,
1082 SfxStyleSheetBasePool
* pDestPool
,
1083 const SvNumberFormatterIndexTable
* pFormatExchangeList
1086 if ( !pSrcStyle
|| !pDestPool
|| !pSrcPool
)
1088 OSL_FAIL( "CopyStyleToPool: Invalid Arguments :-/" );
1092 const OUString aStrSrcStyle
= pSrcStyle
->GetName();
1093 const SfxStyleFamily eFamily
= pSrcStyle
->GetFamily();
1094 SfxStyleSheetBase
* pDestStyle
= pDestPool
->Find( aStrSrcStyle
, eFamily
);
1098 const OUString aStrParent
= pSrcStyle
->GetParent();
1099 const SfxItemSet
& rSrcSet
= pSrcStyle
->GetItemSet();
1101 pDestStyle
= &pDestPool
->Make( aStrSrcStyle
, eFamily
, SfxStyleSearchBits::UserDefined
);
1102 SfxItemSet
& rDestSet
= pDestStyle
->GetItemSet();
1103 rDestSet
.Put( rSrcSet
);
1105 // number format exchange list has to be handled here, too
1106 // (only called for cell styles)
1108 const SfxUInt32Item
* pSrcItem
;
1109 if ( pFormatExchangeList
&&
1110 (pSrcItem
= rSrcSet
.GetItemIfSet( ATTR_VALUE_FORMAT
, false )) )
1112 sal_uInt32 nOldFormat
= pSrcItem
->GetValue();
1113 SvNumberFormatterIndexTable::const_iterator it
= pFormatExchangeList
->find(nOldFormat
);
1114 if (it
!= pFormatExchangeList
->end())
1116 sal_uInt32 nNewFormat
= it
->second
;
1117 rDestSet
.Put( SfxUInt32Item( ATTR_VALUE_FORMAT
, nNewFormat
) );
1121 // if necessary create derivative Styles, if not available:
1123 if ( ScResId(STR_STYLENAME_STANDARD
) != aStrParent
&&
1124 aStrSrcStyle
!= aStrParent
&&
1125 !pDestPool
->Find( aStrParent
, eFamily
) )
1127 lcl_CopyStyleToPool( pSrcPool
->Find( aStrParent
, eFamily
),
1128 pSrcPool
, pDestPool
, pFormatExchangeList
);
1131 pDestStyle
->SetParent( aStrParent
);
1137 ScPatternAttr
* ScPatternAttr::PutInPool( ScDocument
* pDestDoc
, ScDocument
* pSrcDoc
) const
1139 const SfxItemSet
* pSrcSet
= &GetItemSet();
1141 ScPatternAttr
aDestPattern( pDestDoc
->GetPool() );
1142 SfxItemSet
* pDestSet
= &aDestPattern
.GetItemSet();
1144 // Copy cell pattern style to other document:
1146 if ( pDestDoc
!= pSrcDoc
)
1148 OSL_ENSURE( pStyle
, "Missing Pattern-Style! :-/" );
1150 // if pattern in DestDoc is available, use this, otherwise copy
1151 // parent style to style or create if necessary and attach DestDoc
1153 SfxStyleSheetBase
* pStyleCpy
= lcl_CopyStyleToPool( pStyle
,
1154 pSrcDoc
->GetStyleSheetPool(),
1155 pDestDoc
->GetStyleSheetPool(),
1156 pDestDoc
->GetFormatExchangeList() );
1158 aDestPattern
.SetStyleSheet( static_cast<ScStyleSheet
*>(pStyleCpy
) );
1161 for ( sal_uInt16 nAttrId
= ATTR_PATTERN_START
; nAttrId
<= ATTR_PATTERN_END
; nAttrId
++ )
1163 const SfxPoolItem
* pSrcItem
;
1164 SfxItemState eItemState
= pSrcSet
->GetItemState( nAttrId
, false, &pSrcItem
);
1165 if (eItemState
==SfxItemState::SET
)
1167 std::unique_ptr
<SfxPoolItem
> pNewItem
;
1169 if ( nAttrId
== ATTR_VALIDDATA
)
1171 // Copy validity to the new document
1173 sal_uInt32 nNewIndex
= 0;
1174 ScValidationDataList
* pSrcList
= pSrcDoc
->GetValidationList();
1177 sal_uInt32 nOldIndex
= static_cast<const SfxUInt32Item
*>(pSrcItem
)->GetValue();
1178 const ScValidationData
* pOldData
= pSrcList
->GetData( nOldIndex
);
1180 nNewIndex
= pDestDoc
->AddValidationEntry( *pOldData
);
1182 pNewItem
.reset(new SfxUInt32Item( ATTR_VALIDDATA
, nNewIndex
));
1184 else if ( nAttrId
== ATTR_VALUE_FORMAT
&& pDestDoc
->GetFormatExchangeList() )
1186 // Number format to Exchange List
1188 sal_uInt32 nOldFormat
= static_cast<const SfxUInt32Item
*>(pSrcItem
)->GetValue();
1189 SvNumberFormatterIndexTable::const_iterator it
= pDestDoc
->GetFormatExchangeList()->find(nOldFormat
);
1190 if (it
!= pDestDoc
->GetFormatExchangeList()->end())
1192 sal_uInt32 nNewFormat
= it
->second
;
1193 pNewItem
.reset(new SfxUInt32Item( ATTR_VALUE_FORMAT
, nNewFormat
));
1199 pDestSet
->Put(std::move(pNewItem
));
1202 pDestSet
->Put(*pSrcItem
);
1206 ScPatternAttr
* pPatternAttr
= const_cast<ScPatternAttr
*>( &pDestDoc
->GetPool()->DirectPutItemInPool(aDestPattern
) );
1207 return pPatternAttr
;
1210 bool ScPatternAttr::IsVisible() const
1212 if (!mxVisible
.has_value())
1213 mxVisible
= CalcVisible();
1217 bool ScPatternAttr::CalcVisible() const
1219 const SfxItemSet
& rSet
= GetItemSet();
1221 if ( const SvxBrushItem
* pItem
= rSet
.GetItemIfSet( ATTR_BACKGROUND
) )
1222 if ( pItem
->GetColor() != COL_TRANSPARENT
)
1225 if ( const SvxBoxItem
* pBoxItem
= rSet
.GetItemIfSet( ATTR_BORDER
) )
1227 if ( pBoxItem
->GetTop() || pBoxItem
->GetBottom() ||
1228 pBoxItem
->GetLeft() || pBoxItem
->GetRight() )
1232 if ( const SvxLineItem
* pItem
= rSet
.GetItemIfSet( ATTR_BORDER_TLBR
) )
1233 if( pItem
->GetLine() )
1236 if ( const SvxLineItem
* pItem
= rSet
.GetItemIfSet( ATTR_BORDER_BLTR
) )
1237 if( pItem
->GetLine() )
1240 if ( const SvxShadowItem
* pItem
= rSet
.GetItemIfSet( ATTR_SHADOW
) )
1241 if ( pItem
->GetLocation() != SvxShadowLocation::NONE
)
1247 bool ScPatternAttr::IsVisibleEqual( const ScPatternAttr
& rOther
) const
1249 // This method is hot, so we do an optimised comparison here, by
1250 // walking the two itemsets in parallel, avoiding doing repeated searches.
1251 auto IsInterestingWhich
= [](sal_uInt16 n
)
1253 return n
== ATTR_BORDER_TLBR
|| n
== ATTR_BORDER_BLTR
|| n
== ATTR_BACKGROUND
1254 || n
== ATTR_BORDER
|| n
== ATTR_SHADOW
;
1256 SfxWhichIter
aIter1(GetItemSet());
1257 SfxWhichIter
aIter2(rOther
.GetItemSet());
1258 sal_uInt16 nWhich1
= aIter1
.FirstWhich();
1259 sal_uInt16 nWhich2
= aIter2
.FirstWhich();
1262 while (nWhich1
!= nWhich2
)
1264 SfxWhichIter
* pIterToIncrement
;
1265 sal_uInt16
* pSmallerWhich
;
1266 if (nWhich1
== 0 || nWhich1
> nWhich2
)
1268 pSmallerWhich
= &nWhich2
;
1269 pIterToIncrement
= &aIter2
;
1273 pSmallerWhich
= &nWhich1
;
1274 pIterToIncrement
= &aIter1
;
1277 if (IsInterestingWhich(*pSmallerWhich
))
1279 // the iter with larger which has already passed this point, and has no interesting
1280 // item available in the other - so indeed these are unequal
1284 *pSmallerWhich
= pIterToIncrement
->NextWhich();
1287 // Here nWhich1 == nWhich2
1289 if (!nWhich1
/* && !nWhich2*/)
1292 if (IsInterestingWhich(nWhich1
))
1294 const SfxPoolItem
* pItem1
= nullptr;
1295 const SfxPoolItem
* pItem2
= nullptr;
1296 SfxItemState state1
= aIter1
.GetItemState(true, &pItem1
);
1297 SfxItemState state2
= aIter2
.GetItemState(true, &pItem2
);
1298 if (state1
!= state2
1299 && (state1
< SfxItemState::DEFAULT
|| state2
< SfxItemState::DEFAULT
))
1301 if (!SfxPoolItem::areSame(pItem1
, pItem2
))
1304 nWhich1
= aIter1
.NextWhich();
1305 nWhich2
= aIter2
.NextWhich();
1307 //TODO: also here only check really visible values !!!
1310 const OUString
* ScPatternAttr::GetStyleName() const
1312 return pName
? &*pName
: ( pStyle
? &pStyle
->GetName() : nullptr );
1315 void ScPatternAttr::SetStyleSheet( ScStyleSheet
* pNewStyle
, bool bClearDirectFormat
)
1319 SfxItemSet
& rPatternSet
= GetItemSet();
1320 const SfxItemSet
& rStyleSet
= pNewStyle
->GetItemSet();
1322 if (bClearDirectFormat
)
1324 for (sal_uInt16 i
=ATTR_PATTERN_START
; i
<=ATTR_PATTERN_END
; i
++)
1326 if (rStyleSet
.GetItemState(i
) == SfxItemState::SET
)
1327 rPatternSet
.ClearItem(i
);
1330 rPatternSet
.SetParent(&pNewStyle
->GetItemSet());
1336 OSL_FAIL( "ScPatternAttr::SetStyleSheet( NULL ) :-|" );
1337 GetItemSet().SetParent(nullptr);
1343 void ScPatternAttr::UpdateStyleSheet(const ScDocument
& rDoc
)
1347 pStyle
= static_cast<ScStyleSheet
*>(rDoc
.GetStyleSheetPool()->Find(*pName
, SfxStyleFamily::Para
));
1349 // use Standard if Style is not found,
1350 // to avoid empty display in Toolbox-Controller
1351 // Assumes that "Standard" is always the 1st entry!
1354 std::unique_ptr
<SfxStyleSheetIterator
> pIter
= rDoc
.GetStyleSheetPool()->CreateIterator(SfxStyleFamily::Para
);
1355 pStyle
= dynamic_cast< ScStyleSheet
* >(pIter
->First());
1360 GetItemSet().SetParent(&pStyle
->GetItemSet());
1369 void ScPatternAttr::StyleToName()
1371 // Style was deleted, remember name:
1375 pName
= pStyle
->GetName();
1377 GetItemSet().SetParent( nullptr );
1382 bool ScPatternAttr::IsSymbolFont() const
1384 if( const SvxFontItem
* pItem
= GetItemSet().GetItemIfSet( ATTR_FONT
) )
1385 return pItem
->GetCharSet() == RTL_TEXTENCODING_SYMBOL
;
1392 sal_uInt32
getNumberFormatKey(const SfxItemSet
& rSet
)
1394 return rSet
.Get(ATTR_VALUE_FORMAT
).GetValue();
1397 LanguageType
getLanguageType(const SfxItemSet
& rSet
)
1399 return rSet
.Get(ATTR_LANGUAGE_FORMAT
).GetLanguage();
1404 sal_uInt32
ScPatternAttr::GetNumberFormat( SvNumberFormatter
* pFormatter
) const
1406 sal_uInt32 nFormat
= getNumberFormatKey(GetItemSet());
1407 LanguageType eLang
= getLanguageType(GetItemSet());
1408 if ( nFormat
< SV_COUNTRY_LANGUAGE_OFFSET
&& eLang
== LANGUAGE_SYSTEM
)
1409 ; // it remains as it is
1410 else if ( pFormatter
)
1411 nFormat
= pFormatter
->GetFormatForLanguageIfBuiltIn( nFormat
, eLang
);
1415 sal_uInt32
ScPatternAttr::GetNumberFormat( const ScInterpreterContext
& rContext
) const
1417 sal_uInt32 nFormat
= getNumberFormatKey(GetItemSet());
1418 LanguageType eLang
= getLanguageType(GetItemSet());
1419 if ( nFormat
< SV_COUNTRY_LANGUAGE_OFFSET
&& eLang
== LANGUAGE_SYSTEM
)
1420 ; // it remains as it is
1422 nFormat
= rContext
.GetFormatForLanguageIfBuiltIn( nFormat
, eLang
);
1426 // the same if conditional formatting is in play:
1428 sal_uInt32
ScPatternAttr::GetNumberFormat( SvNumberFormatter
* pFormatter
,
1429 const SfxItemSet
* pCondSet
) const
1433 return GetNumberFormat(pFormatter
);
1435 // Conditional format takes precedence over style and even hard format.
1439 if (pCondSet
->GetItemState(ATTR_VALUE_FORMAT
) == SfxItemState::SET
)
1441 nFormat
= getNumberFormatKey(*pCondSet
);
1442 if (pCondSet
->GetItemState(ATTR_LANGUAGE_FORMAT
) == SfxItemState::SET
)
1443 eLang
= getLanguageType(*pCondSet
);
1445 eLang
= getLanguageType(GetItemSet());
1449 nFormat
= getNumberFormatKey(GetItemSet());
1450 eLang
= getLanguageType(GetItemSet());
1453 return pFormatter
->GetFormatForLanguageIfBuiltIn(nFormat
, eLang
);
1456 const SfxPoolItem
& ScPatternAttr::GetItem( sal_uInt16 nWhich
, const SfxItemSet
& rItemSet
, const SfxItemSet
* pCondSet
)
1458 const SfxPoolItem
* pCondItem
;
1459 if ( pCondSet
&& pCondSet
->GetItemState( nWhich
, true, &pCondItem
) == SfxItemState::SET
)
1461 return rItemSet
.Get(nWhich
);
1464 const SfxPoolItem
& ScPatternAttr::GetItem( sal_uInt16 nSubWhich
, const SfxItemSet
* pCondSet
) const
1466 return GetItem( nSubWhich
, GetItemSet(), pCondSet
);
1469 // GetRotateVal is tested before ATTR_ORIENTATION
1471 Degree100
ScPatternAttr::GetRotateVal( const SfxItemSet
* pCondSet
) const
1473 Degree100
nAttrRotate(0);
1474 if ( GetCellOrientation() == SvxCellOrientation::Standard
)
1476 bool bRepeat
= ( GetItem(ATTR_HOR_JUSTIFY
, pCondSet
).
1477 GetValue() == SvxCellHorJustify::Repeat
);
1478 // ignore orientation/rotation if "repeat" is active
1480 nAttrRotate
= GetItem( ATTR_ROTATE_VALUE
, pCondSet
).GetValue();
1485 ScRotateDir
ScPatternAttr::GetRotateDir( const SfxItemSet
* pCondSet
) const
1487 ScRotateDir nRet
= ScRotateDir::NONE
;
1489 Degree100 nAttrRotate
= GetRotateVal( pCondSet
);
1492 SvxRotateMode eRotMode
= GetItem(ATTR_ROTATE_MODE
, pCondSet
).GetValue();
1494 if ( eRotMode
== SVX_ROTATE_MODE_STANDARD
|| nAttrRotate
== 18000_deg100
)
1495 nRet
= ScRotateDir::Standard
;
1496 else if ( eRotMode
== SVX_ROTATE_MODE_CENTER
)
1497 nRet
= ScRotateDir::Center
;
1498 else if ( eRotMode
== SVX_ROTATE_MODE_TOP
|| eRotMode
== SVX_ROTATE_MODE_BOTTOM
)
1500 Degree100 nRot180
= nAttrRotate
% 18000_deg100
; // 1/100 degrees
1501 if ( nRot180
== 9000_deg100
)
1502 nRet
= ScRotateDir::Center
;
1503 else if ( ( eRotMode
== SVX_ROTATE_MODE_TOP
&& nRot180
< 9000_deg100
) ||
1504 ( eRotMode
== SVX_ROTATE_MODE_BOTTOM
&& nRot180
> 9000_deg100
) )
1505 nRet
= ScRotateDir::Left
;
1507 nRet
= ScRotateDir::Right
;
1514 void ScPatternAttr::SetPAKey(sal_uInt64 nKey
)
1519 sal_uInt64
ScPatternAttr::GetPAKey() const
1524 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */