xref: /core/sc/source/core/data/patattr.cxx (revision b225980d)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #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/zforlist.hxx>
50 #include <vcl/outdev.hxx>
51 #include <tools/fract.hxx>
52 #include <osl/diagnose.h>
53 
54 #include <attrib.hxx>
55 #include <patattr.hxx>
56 #include <docpool.hxx>
57 #include <stlsheet.hxx>
58 #include <stlpool.hxx>
59 #include <document.hxx>
60 #include <global.hxx>
61 #include <globstr.hrc>
62 #include <scresid.hxx>
63 #include <validat.hxx>
64 #include <scmod.hxx>
65 #include <fillinfo.hxx>
66 #include <boost/functional/hash.hpp>
67 
68 using sc::HMMToTwips;
69 using sc::TwipsToHMM;
70 
71 ScPatternAttr::ScPatternAttr( std::unique_ptr<SfxItemSet>&& pItemSet, const OUString& rStyleName )
72     :   SfxSetItem  ( ATTR_PATTERN, std::move(pItemSet) ),
73         pName       ( rStyleName ),
74         pStyle      ( nullptr ),
75         mnKey(0)
76 {
77 }
78 
79 ScPatternAttr::ScPatternAttr( std::unique_ptr<SfxItemSet>&& pItemSet )
80     :   SfxSetItem  ( ATTR_PATTERN, std::move(pItemSet) ),
81         pStyle      ( nullptr ),
82         mnKey(0)
83 {
84 }
85 
86 ScPatternAttr::ScPatternAttr( SfxItemPool* pItemPool )
87     :   SfxSetItem  ( ATTR_PATTERN, std::make_unique<SfxItemSet>( *pItemPool, svl::Items<ATTR_PATTERN_START, ATTR_PATTERN_END>{} ) ),
88         pStyle      ( nullptr ),
89         mnKey(0)
90 {
91 }
92 
93 ScPatternAttr::ScPatternAttr( const ScPatternAttr& rPatternAttr )
94     :   SfxSetItem  ( rPatternAttr ),
95         pName       ( rPatternAttr.pName ),
96         pStyle      ( rPatternAttr.pStyle ),
97         mnKey(rPatternAttr.mnKey)
98 {
99 }
100 
101 ScPatternAttr::~ScPatternAttr()
102 {
103 }
104 
105 ScPatternAttr* ScPatternAttr::Clone( SfxItemPool *pPool ) const
106 {
107     ScPatternAttr* pPattern = new ScPatternAttr( GetItemSet().Clone(true, pPool) );
108 
109     pPattern->pStyle = pStyle;
110     pPattern->pName = pName;
111 
112     return pPattern;
113 }
114 
115 static bool StrCmp( const OUString* pStr1, const OUString* pStr2 )
116 {
117     if (pStr1 == pStr2)
118         return true;
119     if (pStr1 && !pStr2)
120         return false;
121     if (!pStr1 && pStr2)
122         return false;
123     return *pStr1 == *pStr2;
124 }
125 
126 static bool EqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 )
127 {
128     // #i62090# The SfxItemSet in the SfxSetItem base class always has the same ranges
129     // (single range from ATTR_PATTERN_START to ATTR_PATTERN_END), and the items are pooled,
130     // so it's enough to compare just the pointers (Count just because it's even faster).
131 
132     if ( rSet1.Count() != rSet2.Count() )
133         return false;
134 
135     SfxPoolItem const ** pItems1 = rSet1.GetItems_Impl();   // inline method of SfxItemSet
136     SfxPoolItem const ** pItems2 = rSet2.GetItems_Impl();
137 
138     return ( 0 == memcmp( pItems1, pItems2, (ATTR_PATTERN_END - ATTR_PATTERN_START + 1) * sizeof(pItems1[0]) ) );
139 }
140 
141 bool ScPatternAttr::operator==( const SfxPoolItem& rCmp ) const
142 {
143     // #i62090# Use quick comparison between ScPatternAttr's ItemSets
144 
145     if (!SfxPoolItem::operator==(rCmp) )
146         return false;
147     if (!mxHashCode)
148         CalcHashCode();
149     auto const & rOther = static_cast<const ScPatternAttr&>(rCmp);
150     if (!rOther.mxHashCode)
151         rOther.CalcHashCode();
152     if (*mxHashCode != *rOther.mxHashCode)
153         return false;
154     return EqualPatternSets( GetItemSet(), rOther.GetItemSet() ) &&
155             StrCmp( GetStyleName(), rOther.GetStyleName() );
156 }
157 
158 SvxCellOrientation ScPatternAttr::GetCellOrientation( const SfxItemSet& rItemSet, const SfxItemSet* pCondSet )
159 {
160     SvxCellOrientation eOrient = SvxCellOrientation::Standard;
161 
162     if( GetItem( ATTR_STACKED, rItemSet, pCondSet ).GetValue() )
163     {
164         eOrient = SvxCellOrientation::Stacked;
165     }
166     else
167     {
168         sal_Int32 nAngle = GetItem( ATTR_ROTATE_VALUE, rItemSet, pCondSet ).GetValue();
169         if( nAngle == 9000 )
170             eOrient = SvxCellOrientation::BottomUp;
171         else if( nAngle == 27000 )
172             eOrient = SvxCellOrientation::TopBottom;
173     }
174 
175     return eOrient;
176 }
177 
178 SvxCellOrientation ScPatternAttr::GetCellOrientation( const SfxItemSet* pCondSet ) const
179 {
180     return GetCellOrientation( GetItemSet(), pCondSet );
181 }
182 
183 namespace {
184 
185 void getFontIDsByScriptType(SvtScriptType nScript,
186 sal_uInt16& nFontId, sal_uInt16& nHeightId, sal_uInt16& nWeightId, sal_uInt16& nPostureId, sal_uInt16& nLangId)
187 {
188     if ( nScript == SvtScriptType::ASIAN )
189     {
190         nFontId    = ATTR_CJK_FONT;
191         nHeightId  = ATTR_CJK_FONT_HEIGHT;
192         nWeightId  = ATTR_CJK_FONT_WEIGHT;
193         nPostureId = ATTR_CJK_FONT_POSTURE;
194         nLangId    = ATTR_CJK_FONT_LANGUAGE;
195     }
196     else if ( nScript == SvtScriptType::COMPLEX )
197     {
198         nFontId    = ATTR_CTL_FONT;
199         nHeightId  = ATTR_CTL_FONT_HEIGHT;
200         nWeightId  = ATTR_CTL_FONT_WEIGHT;
201         nPostureId = ATTR_CTL_FONT_POSTURE;
202         nLangId    = ATTR_CTL_FONT_LANGUAGE;
203     }
204     else
205     {
206         nFontId    = ATTR_FONT;
207         nHeightId  = ATTR_FONT_HEIGHT;
208         nWeightId  = ATTR_FONT_WEIGHT;
209         nPostureId = ATTR_FONT_POSTURE;
210         nLangId    = ATTR_FONT_LANGUAGE;
211     }
212 }
213 
214 }
215 
216 void ScPatternAttr::GetFont(
217         vcl::Font& rFont, const SfxItemSet& rItemSet, ScAutoFontColorMode eAutoMode,
218         const OutputDevice* pOutDev, const Fraction* pScale,
219         const SfxItemSet* pCondSet, SvtScriptType nScript,
220         const Color* pBackConfigColor, const Color* pTextConfigColor )
221 {
222     // Read items
223 
224     const SvxFontItem* pFontAttr;
225     sal_uInt32 nFontHeight;
226     FontWeight eWeight;
227     FontItalic eItalic;
228     FontLineStyle eUnder;
229     FontLineStyle eOver;
230     bool bWordLine;
231     FontStrikeout eStrike;
232     bool bOutline;
233     bool bShadow;
234     FontEmphasisMark eEmphasis;
235     FontRelief eRelief;
236     Color aColor;
237     LanguageType eLang;
238 
239     sal_uInt16 nFontId, nHeightId, nWeightId, nPostureId, nLangId;
240     getFontIDsByScriptType(nScript, nFontId, nHeightId, nWeightId, nPostureId, nLangId);
241 
242     if ( pCondSet )
243     {
244         const SfxPoolItem* pItem;
245 
246         if ( pCondSet->GetItemState( nFontId, true, &pItem ) != SfxItemState::SET )
247             pItem = &rItemSet.Get( nFontId );
248         pFontAttr = static_cast<const SvxFontItem*>(pItem);
249 
250         if ( pCondSet->GetItemState( nHeightId, true, &pItem ) != SfxItemState::SET )
251             pItem = &rItemSet.Get( nHeightId );
252         nFontHeight = static_cast<const SvxFontHeightItem*>(pItem)->GetHeight();
253 
254         if ( pCondSet->GetItemState( nWeightId, true, &pItem ) != SfxItemState::SET )
255             pItem = &rItemSet.Get( nWeightId );
256         eWeight = static_cast<const SvxWeightItem*>(pItem)->GetValue();
257 
258         if ( pCondSet->GetItemState( nPostureId, true, &pItem ) != SfxItemState::SET )
259             pItem = &rItemSet.Get( nPostureId );
260         eItalic = static_cast<const SvxPostureItem*>(pItem)->GetValue();
261 
262         if ( pCondSet->GetItemState( ATTR_FONT_UNDERLINE, true, &pItem ) != SfxItemState::SET )
263             pItem = &rItemSet.Get( ATTR_FONT_UNDERLINE );
264         eUnder = static_cast<const SvxUnderlineItem*>(pItem)->GetValue();
265 
266         if ( pCondSet->GetItemState( ATTR_FONT_OVERLINE, true, &pItem ) != SfxItemState::SET )
267             pItem = &rItemSet.Get( ATTR_FONT_OVERLINE );
268         eOver = static_cast<const SvxOverlineItem*>(pItem)->GetValue();
269 
270         if ( pCondSet->GetItemState( ATTR_FONT_WORDLINE, true, &pItem ) != SfxItemState::SET )
271             pItem = &rItemSet.Get( ATTR_FONT_WORDLINE );
272         bWordLine = static_cast<const SvxWordLineModeItem*>(pItem)->GetValue();
273 
274         if ( pCondSet->GetItemState( ATTR_FONT_CROSSEDOUT, true, &pItem ) != SfxItemState::SET )
275             pItem = &rItemSet.Get( ATTR_FONT_CROSSEDOUT );
276         eStrike = static_cast<const SvxCrossedOutItem*>(pItem)->GetValue();
277 
278         if ( pCondSet->GetItemState( ATTR_FONT_CONTOUR, true, &pItem ) != SfxItemState::SET )
279             pItem = &rItemSet.Get( ATTR_FONT_CONTOUR );
280         bOutline = static_cast<const SvxContourItem*>(pItem)->GetValue();
281 
282         if ( pCondSet->GetItemState( ATTR_FONT_SHADOWED, true, &pItem ) != SfxItemState::SET )
283             pItem = &rItemSet.Get( ATTR_FONT_SHADOWED );
284         bShadow = static_cast<const SvxShadowedItem*>(pItem)->GetValue();
285 
286         if ( pCondSet->GetItemState( ATTR_FONT_EMPHASISMARK, true, &pItem ) != SfxItemState::SET )
287             pItem = &rItemSet.Get( ATTR_FONT_EMPHASISMARK );
288         eEmphasis = static_cast<const SvxEmphasisMarkItem*>(pItem)->GetEmphasisMark();
289 
290         if ( pCondSet->GetItemState( ATTR_FONT_RELIEF, true, &pItem ) != SfxItemState::SET )
291             pItem = &rItemSet.Get( ATTR_FONT_RELIEF );
292         eRelief = static_cast<const SvxCharReliefItem*>(pItem)->GetValue();
293 
294         if ( pCondSet->GetItemState( ATTR_FONT_COLOR, true, &pItem ) != SfxItemState::SET )
295             pItem = &rItemSet.Get( ATTR_FONT_COLOR );
296         aColor = static_cast<const SvxColorItem*>(pItem)->GetValue();
297 
298         if ( pCondSet->GetItemState( nLangId, true, &pItem ) != SfxItemState::SET )
299             pItem = &rItemSet.Get( nLangId );
300         eLang = static_cast<const SvxLanguageItem*>(pItem)->GetLanguage();
301     }
302     else    // Everything from rItemSet
303     {
304         pFontAttr = &static_cast<const SvxFontItem&>(rItemSet.Get( nFontId ));
305         nFontHeight = static_cast<const SvxFontHeightItem&>(
306                         rItemSet.Get( nHeightId )).GetHeight();
307         eWeight = static_cast<const SvxWeightItem&>(
308                         rItemSet.Get( nWeightId )).GetValue();
309         eItalic = static_cast<const SvxPostureItem&>(
310                         rItemSet.Get( nPostureId )).GetValue();
311         eUnder = rItemSet.Get( ATTR_FONT_UNDERLINE ).GetValue();
312         eOver = rItemSet.Get( ATTR_FONT_OVERLINE ).GetValue();
313         bWordLine = rItemSet.Get( ATTR_FONT_WORDLINE ).GetValue();
314         eStrike = rItemSet.Get( ATTR_FONT_CROSSEDOUT ).GetValue();
315         bOutline = rItemSet.Get( ATTR_FONT_CONTOUR ).GetValue();
316         bShadow = rItemSet.Get( ATTR_FONT_SHADOWED ).GetValue();
317         eEmphasis = rItemSet.Get( ATTR_FONT_EMPHASISMARK ).GetEmphasisMark();
318         eRelief = rItemSet.Get( ATTR_FONT_RELIEF ).GetValue();
319         aColor = rItemSet.Get( ATTR_FONT_COLOR ).GetValue();
320         // for graphite language features
321         eLang = static_cast<const SvxLanguageItem&>(rItemSet.Get( nLangId )).GetLanguage();
322     }
323     OSL_ENSURE(pFontAttr,"Oops?");
324 
325     //  Evaluate
326 
327     //  FontItem:
328 
329     if (rFont.GetFamilyName() != pFontAttr->GetFamilyName())
330         rFont.SetFamilyName( pFontAttr->GetFamilyName() );
331     if (rFont.GetStyleName() != pFontAttr->GetStyleName())
332         rFont.SetStyleName( pFontAttr->GetStyleName() );
333 
334     rFont.SetFamily( pFontAttr->GetFamily() );
335     rFont.SetCharSet( pFontAttr->GetCharSet() );
336     rFont.SetPitch( pFontAttr->GetPitch() );
337 
338     rFont.SetLanguage(eLang);
339 
340     //  Size
341 
342     if ( pOutDev != nullptr )
343     {
344         Size aEffSize;
345         Fraction aFraction( 1,1 );
346         if (pScale)
347             aFraction = *pScale;
348         Size aSize( 0, static_cast<tools::Long>(nFontHeight) );
349         MapMode aDestMode = pOutDev->GetMapMode();
350         MapMode aSrcMode( MapUnit::MapTwip, Point(), aFraction, aFraction );
351         if (aDestMode.GetMapUnit() == MapUnit::MapPixel && pOutDev->GetDPIX() > 0)
352             aEffSize = pOutDev->LogicToPixel( aSize, aSrcMode );
353         else
354         {
355             Fraction aFractOne(1,1);
356             aDestMode.SetScaleX( aFractOne );
357             aDestMode.SetScaleY( aFractOne );
358             aEffSize = OutputDevice::LogicToLogic( aSize, aSrcMode, aDestMode );
359         }
360         rFont.SetFontSize( aEffSize );
361     }
362     else /* if pOutDev != NULL */
363     {
364         rFont.SetFontSize( Size( 0, static_cast<tools::Long>(nFontHeight) ) );
365     }
366 
367     //  determine effective font color
368 
369     if ( ( aColor == COL_AUTO && eAutoMode != SC_AUTOCOL_RAW ) ||
370             eAutoMode == SC_AUTOCOL_IGNOREFONT || eAutoMode == SC_AUTOCOL_IGNOREALL )
371     {
372         if ( eAutoMode == SC_AUTOCOL_BLACK )
373             aColor = COL_BLACK;
374         else
375         {
376             //  get background color from conditional or own set
377             Color aBackColor;
378             if ( pCondSet )
379             {
380                 const SfxPoolItem* pItem;
381                 if ( pCondSet->GetItemState( ATTR_BACKGROUND, true, &pItem ) != SfxItemState::SET )
382                     pItem = &rItemSet.Get( ATTR_BACKGROUND );
383                 aBackColor = static_cast<const SvxBrushItem*>(pItem)->GetColor();
384             }
385             else
386                 aBackColor = rItemSet.Get( ATTR_BACKGROUND ).GetColor();
387 
388             //  if background color attribute is transparent, use window color for brightness comparisons
389             if ( aBackColor == COL_TRANSPARENT ||
390                     eAutoMode == SC_AUTOCOL_IGNOREBACK || eAutoMode == SC_AUTOCOL_IGNOREALL )
391             {
392                 if ( eAutoMode == SC_AUTOCOL_PRINT )
393                     aBackColor = COL_WHITE;
394                 else if ( pBackConfigColor )
395                 {
396                     // pBackConfigColor can be used to avoid repeated lookup of the configured color
397                     aBackColor = *pBackConfigColor;
398                 }
399                 else
400                     aBackColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
401             }
402 
403             //  get system text color for comparison
404             Color aSysTextColor;
405             if ( eAutoMode == SC_AUTOCOL_PRINT )
406                 aSysTextColor = COL_BLACK;
407             else if ( pTextConfigColor )
408             {
409                 // pTextConfigColor can be used to avoid repeated lookup of the configured color
410                 aSysTextColor = *pTextConfigColor;
411             }
412             else
413                 aSysTextColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
414 
415             //  select the resulting color
416             if ( aBackColor.IsDark() && aSysTextColor.IsDark() )
417             {
418                 //  use white instead of dark on dark
419                 aColor = COL_WHITE;
420             }
421             else if ( aBackColor.IsBright() && aSysTextColor.IsBright() )
422             {
423                 //  use black instead of bright on bright
424                 aColor = COL_BLACK;
425             }
426             else
427             {
428                 //  use aSysTextColor (black for SC_AUTOCOL_PRINT, from style settings otherwise)
429                 aColor = aSysTextColor;
430             }
431         }
432     }
433 
434     //  set font effects
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.SetColor( aColor );
446     rFont.SetTransparent( true );
447 }
448 
449 void ScPatternAttr::GetFont(
450         vcl::Font& rFont, ScAutoFontColorMode eAutoMode,
451         const OutputDevice* pOutDev, const Fraction* pScale,
452         const SfxItemSet* pCondSet, SvtScriptType nScript,
453         const Color* pBackConfigColor, const Color* pTextConfigColor ) const
454 {
455     GetFont( rFont, GetItemSet(), eAutoMode, pOutDev, pScale, pCondSet, nScript, pBackConfigColor, pTextConfigColor );
456 }
457 
458 ScDxfFont ScPatternAttr::GetDxfFont(const SfxItemSet& rItemSet, SvtScriptType nScript)
459 {
460     sal_uInt16 nFontId, nHeightId, nWeightId, nPostureId, nLangId;
461     getFontIDsByScriptType(nScript, nFontId, nHeightId, nWeightId, nPostureId, nLangId);
462     const SfxPoolItem* pItem;
463 
464     ScDxfFont aReturn;
465 
466     if ( rItemSet.GetItemState( nFontId, true, &pItem ) == SfxItemState::SET )
467     {
468         pItem = &rItemSet.Get( nFontId );
469         aReturn.pFontAttr = static_cast<const SvxFontItem*>(pItem);
470     }
471 
472     if ( rItemSet.GetItemState( nHeightId, true, &pItem ) == SfxItemState::SET )
473     {
474         pItem = &rItemSet.Get( nHeightId );
475         aReturn.nFontHeight = static_cast<const SvxFontHeightItem*>(pItem)->GetHeight();
476     }
477 
478     if ( rItemSet.GetItemState( nWeightId, true, &pItem ) == SfxItemState::SET )
479     {
480         pItem = &rItemSet.Get( nWeightId );
481         aReturn.eWeight = static_cast<const SvxWeightItem*>(pItem)->GetValue();
482     }
483 
484     if ( rItemSet.GetItemState( nPostureId, true, &pItem ) == SfxItemState::SET )
485     {
486         pItem = &rItemSet.Get( nPostureId );
487         aReturn.eItalic = static_cast<const SvxPostureItem*>(pItem)->GetValue();
488     }
489 
490     if ( rItemSet.GetItemState( ATTR_FONT_UNDERLINE, true, &pItem ) == SfxItemState::SET )
491     {
492         pItem = &rItemSet.Get( ATTR_FONT_UNDERLINE );
493         aReturn.eUnder = static_cast<const SvxUnderlineItem*>(pItem)->GetValue();
494     }
495 
496     if ( rItemSet.GetItemState( ATTR_FONT_OVERLINE, true, &pItem ) == SfxItemState::SET )
497     {
498         pItem = &rItemSet.Get( ATTR_FONT_OVERLINE );
499         aReturn.eOver = static_cast<const SvxOverlineItem*>(pItem)->GetValue();
500     }
501 
502     if ( rItemSet.GetItemState( ATTR_FONT_WORDLINE, true, &pItem ) == SfxItemState::SET )
503     {
504         pItem = &rItemSet.Get( ATTR_FONT_WORDLINE );
505         aReturn.bWordLine = static_cast<const SvxWordLineModeItem*>(pItem)->GetValue();
506     }
507 
508     if ( rItemSet.GetItemState( ATTR_FONT_CROSSEDOUT, true, &pItem ) == SfxItemState::SET )
509     {
510         pItem = &rItemSet.Get( ATTR_FONT_CROSSEDOUT );
511         aReturn.eStrike = static_cast<const SvxCrossedOutItem*>(pItem)->GetValue();
512     }
513 
514     if ( rItemSet.GetItemState( ATTR_FONT_CONTOUR, true, &pItem ) == SfxItemState::SET )
515     {
516         pItem = &rItemSet.Get( ATTR_FONT_CONTOUR );
517         aReturn.bOutline = static_cast<const SvxContourItem*>(pItem)->GetValue();
518     }
519 
520     if ( rItemSet.GetItemState( ATTR_FONT_SHADOWED, true, &pItem ) == SfxItemState::SET )
521     {
522         pItem = &rItemSet.Get( ATTR_FONT_SHADOWED );
523         aReturn.bShadow = static_cast<const SvxShadowedItem*>(pItem)->GetValue();
524     }
525 
526     if ( rItemSet.GetItemState( ATTR_FONT_EMPHASISMARK, true, &pItem ) == SfxItemState::SET )
527     {
528         pItem = &rItemSet.Get( ATTR_FONT_EMPHASISMARK );
529         aReturn.eEmphasis = static_cast<const SvxEmphasisMarkItem*>(pItem)->GetEmphasisMark();
530     }
531 
532     if ( rItemSet.GetItemState( ATTR_FONT_RELIEF, true, &pItem ) == SfxItemState::SET )
533     {
534         pItem = &rItemSet.Get( ATTR_FONT_RELIEF );
535         aReturn.eRelief = static_cast<const SvxCharReliefItem*>(pItem)->GetValue();
536     }
537 
538     if ( rItemSet.GetItemState( ATTR_FONT_COLOR, true, &pItem ) == SfxItemState::SET )
539     {
540         pItem = &rItemSet.Get( ATTR_FONT_COLOR );
541         aReturn.aColor = static_cast<const SvxColorItem*>(pItem)->GetValue();
542     }
543 
544     if ( rItemSet.GetItemState( nLangId, true, &pItem ) == SfxItemState::SET )
545     {
546         pItem = &rItemSet.Get( nLangId );
547         aReturn.eLang = static_cast<const SvxLanguageItem*>(pItem)->GetLanguage();
548     }
549 
550     return aReturn;
551 }
552 
553 void ScPatternAttr::FillToEditItemSet( SfxItemSet& rEditSet, const SfxItemSet& rSrcSet, const SfxItemSet* pCondSet )
554 {
555     //  Read Items
556 
557     std::unique_ptr<SvxColorItem> aColorItem(std::make_unique<SvxColorItem>(EE_CHAR_COLOR));              // use item as-is
558     std::unique_ptr<SvxFontItem> aFontItem(std::make_unique<SvxFontItem>(EE_CHAR_FONTINFO));            // use item as-is
559     std::unique_ptr<SvxFontItem> aCjkFontItem(std::make_unique<SvxFontItem>(EE_CHAR_FONTINFO_CJK));            // use item as-is
560     std::unique_ptr<SvxFontItem> aCtlFontItem(std::make_unique<SvxFontItem>(EE_CHAR_FONTINFO_CTL));            // use item as-is
561     tools::Long            nTHeight, nCjkTHeight, nCtlTHeight;     // Twips
562     FontWeight      eWeight, eCjkWeight, eCtlWeight;
563     std::unique_ptr<SvxUnderlineItem> aUnderlineItem(std::make_unique<SvxUnderlineItem>(LINESTYLE_NONE, EE_CHAR_UNDERLINE));
564     std::unique_ptr<SvxOverlineItem> aOverlineItem(std::make_unique<SvxOverlineItem>(LINESTYLE_NONE, EE_CHAR_OVERLINE));
565     bool            bWordLine;
566     FontStrikeout   eStrike;
567     FontItalic      eItalic, eCjkItalic, eCtlItalic;
568     bool            bOutline;
569     bool            bShadow;
570     bool            bForbidden;
571     FontEmphasisMark eEmphasis;
572     FontRelief      eRelief;
573     LanguageType    eLang, eCjkLang, eCtlLang;
574     bool            bHyphenate;
575     SvxFrameDirection eDirection;
576 
577     //TODO: additional parameter to control if language is needed?
578 
579     if ( pCondSet )
580     {
581         const SfxPoolItem* pItem;
582 
583         if ( pCondSet->GetItemState( ATTR_FONT_COLOR, true, &pItem ) != SfxItemState::SET )
584             pItem = &rSrcSet.Get( ATTR_FONT_COLOR );
585         aColorItem.reset(static_cast<SvxColorItem*>(pItem->Clone()));
586 
587         if ( pCondSet->GetItemState( ATTR_FONT, true, &pItem ) != SfxItemState::SET )
588             pItem = &rSrcSet.Get( ATTR_FONT );
589         aFontItem.reset(static_cast<SvxFontItem*>(pItem->Clone()));
590 
591         if ( pCondSet->GetItemState( ATTR_CJK_FONT, true, &pItem ) != SfxItemState::SET )
592             pItem = &rSrcSet.Get( ATTR_CJK_FONT );
593         aCjkFontItem.reset(static_cast<SvxFontItem*>(pItem->Clone()));
594 
595         if ( pCondSet->GetItemState( ATTR_CTL_FONT, true, &pItem ) != SfxItemState::SET )
596             pItem = &rSrcSet.Get( ATTR_CTL_FONT );
597         aCtlFontItem.reset(static_cast<SvxFontItem*>(pItem->Clone()));
598 
599         if ( pCondSet->GetItemState( ATTR_FONT_HEIGHT, true, &pItem ) != SfxItemState::SET )
600             pItem = &rSrcSet.Get( ATTR_FONT_HEIGHT );
601         nTHeight = static_cast<const SvxFontHeightItem*>(pItem)->GetHeight();
602         if ( pCondSet->GetItemState( ATTR_CJK_FONT_HEIGHT, true, &pItem ) != SfxItemState::SET )
603             pItem = &rSrcSet.Get( ATTR_CJK_FONT_HEIGHT );
604         nCjkTHeight = static_cast<const SvxFontHeightItem*>(pItem)->GetHeight();
605         if ( pCondSet->GetItemState( ATTR_CTL_FONT_HEIGHT, true, &pItem ) != SfxItemState::SET )
606             pItem = &rSrcSet.Get( ATTR_CTL_FONT_HEIGHT );
607         nCtlTHeight = static_cast<const SvxFontHeightItem*>(pItem)->GetHeight();
608 
609         if ( pCondSet->GetItemState( ATTR_FONT_WEIGHT, true, &pItem ) != SfxItemState::SET )
610             pItem = &rSrcSet.Get( ATTR_FONT_WEIGHT );
611         eWeight = static_cast<const SvxWeightItem*>(pItem)->GetValue();
612         if ( pCondSet->GetItemState( ATTR_CJK_FONT_WEIGHT, true, &pItem ) != SfxItemState::SET )
613             pItem = &rSrcSet.Get( ATTR_CJK_FONT_WEIGHT );
614         eCjkWeight = static_cast<const SvxWeightItem*>(pItem)->GetValue();
615         if ( pCondSet->GetItemState( ATTR_CTL_FONT_WEIGHT, true, &pItem ) != SfxItemState::SET )
616             pItem = &rSrcSet.Get( ATTR_CTL_FONT_WEIGHT );
617         eCtlWeight = static_cast<const SvxWeightItem*>(pItem)->GetValue();
618 
619         if ( pCondSet->GetItemState( ATTR_FONT_POSTURE, true, &pItem ) != SfxItemState::SET )
620             pItem = &rSrcSet.Get( ATTR_FONT_POSTURE );
621         eItalic = static_cast<const SvxPostureItem*>(pItem)->GetValue();
622         if ( pCondSet->GetItemState( ATTR_CJK_FONT_POSTURE, true, &pItem ) != SfxItemState::SET )
623             pItem = &rSrcSet.Get( ATTR_CJK_FONT_POSTURE );
624         eCjkItalic = static_cast<const SvxPostureItem*>(pItem)->GetValue();
625         if ( pCondSet->GetItemState( ATTR_CTL_FONT_POSTURE, true, &pItem ) != SfxItemState::SET )
626             pItem = &rSrcSet.Get( ATTR_CTL_FONT_POSTURE );
627         eCtlItalic = static_cast<const SvxPostureItem*>(pItem)->GetValue();
628 
629         if ( pCondSet->GetItemState( ATTR_FONT_UNDERLINE, true, &pItem ) != SfxItemState::SET )
630             pItem = &rSrcSet.Get( ATTR_FONT_UNDERLINE );
631         aUnderlineItem.reset(static_cast<SvxUnderlineItem*>(pItem->Clone()));
632 
633         if ( pCondSet->GetItemState( ATTR_FONT_OVERLINE, true, &pItem ) != SfxItemState::SET )
634             pItem = &rSrcSet.Get( ATTR_FONT_OVERLINE );
635         aOverlineItem.reset(static_cast<SvxOverlineItem*>(pItem->Clone()));
636 
637         if ( pCondSet->GetItemState( ATTR_FONT_WORDLINE, true, &pItem ) != SfxItemState::SET )
638             pItem = &rSrcSet.Get( ATTR_FONT_WORDLINE );
639         bWordLine = static_cast<const SvxWordLineModeItem*>(pItem)->GetValue();
640 
641         if ( pCondSet->GetItemState( ATTR_FONT_CROSSEDOUT, true, &pItem ) != SfxItemState::SET )
642             pItem = &rSrcSet.Get( ATTR_FONT_CROSSEDOUT );
643         eStrike = static_cast<const SvxCrossedOutItem*>(pItem)->GetValue();
644 
645         if ( pCondSet->GetItemState( ATTR_FONT_CONTOUR, true, &pItem ) != SfxItemState::SET )
646             pItem = &rSrcSet.Get( ATTR_FONT_CONTOUR );
647         bOutline = static_cast<const SvxContourItem*>(pItem)->GetValue();
648 
649         if ( pCondSet->GetItemState( ATTR_FONT_SHADOWED, true, &pItem ) != SfxItemState::SET )
650             pItem = &rSrcSet.Get( ATTR_FONT_SHADOWED );
651         bShadow = static_cast<const SvxShadowedItem*>(pItem)->GetValue();
652 
653         if ( pCondSet->GetItemState( ATTR_FORBIDDEN_RULES, true, &pItem ) != SfxItemState::SET )
654             pItem = &rSrcSet.Get( ATTR_FORBIDDEN_RULES );
655         bForbidden = static_cast<const SvxForbiddenRuleItem*>(pItem)->GetValue();
656 
657         if ( pCondSet->GetItemState( ATTR_FONT_EMPHASISMARK, true, &pItem ) != SfxItemState::SET )
658             pItem = &rSrcSet.Get( ATTR_FONT_EMPHASISMARK );
659         eEmphasis = static_cast<const SvxEmphasisMarkItem*>(pItem)->GetEmphasisMark();
660         if ( pCondSet->GetItemState( ATTR_FONT_RELIEF, true, &pItem ) != SfxItemState::SET )
661             pItem = &rSrcSet.Get( ATTR_FONT_RELIEF );
662         eRelief = static_cast<const SvxCharReliefItem*>(pItem)->GetValue();
663 
664         if ( pCondSet->GetItemState( ATTR_FONT_LANGUAGE, true, &pItem ) != SfxItemState::SET )
665             pItem = &rSrcSet.Get( ATTR_FONT_LANGUAGE );
666         eLang = static_cast<const SvxLanguageItem*>(pItem)->GetLanguage();
667         if ( pCondSet->GetItemState( ATTR_CJK_FONT_LANGUAGE, true, &pItem ) != SfxItemState::SET )
668             pItem = &rSrcSet.Get( ATTR_CJK_FONT_LANGUAGE );
669         eCjkLang = static_cast<const SvxLanguageItem*>(pItem)->GetLanguage();
670         if ( pCondSet->GetItemState( ATTR_CTL_FONT_LANGUAGE, true, &pItem ) != SfxItemState::SET )
671             pItem = &rSrcSet.Get( ATTR_CTL_FONT_LANGUAGE );
672         eCtlLang = static_cast<const SvxLanguageItem*>(pItem)->GetLanguage();
673 
674         if ( pCondSet->GetItemState( ATTR_HYPHENATE, true, &pItem ) != SfxItemState::SET )
675             pItem = &rSrcSet.Get( ATTR_HYPHENATE );
676         bHyphenate = static_cast<const ScHyphenateCell*>(pItem)->GetValue();
677 
678         if ( pCondSet->GetItemState( ATTR_WRITINGDIR, true, &pItem ) != SfxItemState::SET )
679             pItem = &rSrcSet.Get( ATTR_WRITINGDIR );
680         eDirection = static_cast<const SvxFrameDirectionItem*>(pItem)->GetValue();
681     }
682     else        // Everything directly from Pattern
683     {
684         aColorItem.reset(rSrcSet.Get(ATTR_FONT_COLOR).Clone());
685         aFontItem.reset(rSrcSet.Get(ATTR_FONT).Clone());
686         aCjkFontItem.reset(rSrcSet.Get(ATTR_CJK_FONT).Clone());
687         aCtlFontItem.reset(rSrcSet.Get(ATTR_CTL_FONT).Clone());
688         nTHeight = rSrcSet.Get( ATTR_FONT_HEIGHT ).GetHeight();
689         nCjkTHeight = rSrcSet.Get( ATTR_CJK_FONT_HEIGHT ).GetHeight();
690         nCtlTHeight = rSrcSet.Get( ATTR_CTL_FONT_HEIGHT ).GetHeight();
691         eWeight = rSrcSet.Get( ATTR_FONT_WEIGHT ).GetValue();
692         eCjkWeight = rSrcSet.Get( ATTR_CJK_FONT_WEIGHT ).GetValue();
693         eCtlWeight = rSrcSet.Get( ATTR_CTL_FONT_WEIGHT ).GetValue();
694         eItalic = rSrcSet.Get( ATTR_FONT_POSTURE ).GetValue();
695         eCjkItalic = rSrcSet.Get( ATTR_CJK_FONT_POSTURE ).GetValue();
696         eCtlItalic = rSrcSet.Get( ATTR_CTL_FONT_POSTURE ).GetValue();
697         aUnderlineItem.reset(rSrcSet.Get(ATTR_FONT_UNDERLINE).Clone());
698         aOverlineItem.reset(rSrcSet.Get(ATTR_FONT_OVERLINE).Clone());
699         bWordLine = rSrcSet.Get( ATTR_FONT_WORDLINE ).GetValue();
700         eStrike = rSrcSet.Get( ATTR_FONT_CROSSEDOUT ).GetValue();
701         bOutline = rSrcSet.Get( ATTR_FONT_CONTOUR ).GetValue();
702         bShadow = rSrcSet.Get( ATTR_FONT_SHADOWED ).GetValue();
703         bForbidden = rSrcSet.Get( ATTR_FORBIDDEN_RULES ).GetValue();
704         eEmphasis = rSrcSet.Get( ATTR_FONT_EMPHASISMARK ).GetEmphasisMark();
705         eRelief = rSrcSet.Get( ATTR_FONT_RELIEF ).GetValue();
706         eLang = rSrcSet.Get( ATTR_FONT_LANGUAGE ).GetLanguage();
707         eCjkLang = rSrcSet.Get( ATTR_CJK_FONT_LANGUAGE ).GetLanguage();
708         eCtlLang = rSrcSet.Get( ATTR_CTL_FONT_LANGUAGE ).GetLanguage();
709         bHyphenate = rSrcSet.Get( ATTR_HYPHENATE ).GetValue();
710         eDirection = rSrcSet.Get( ATTR_WRITINGDIR ).GetValue();
711     }
712 
713     // Expect to be compatible to LogicToLogic, ie. 2540/1440 = 127/72, and round
714 
715     tools::Long nHeight = TwipsToHMM(nTHeight);
716     tools::Long nCjkHeight = TwipsToHMM(nCjkTHeight);
717     tools::Long nCtlHeight = TwipsToHMM(nCtlTHeight);
718 
719     //  put items into EditEngine ItemSet
720 
721     if ( aColorItem->GetValue() == COL_AUTO )
722     {
723         //  When cell attributes are converted to EditEngine paragraph attributes,
724         //  don't create a hard item for automatic color, because that would be converted
725         //  to black when the item's Store method is used in CreateTransferable/WriteBin.
726         //  COL_AUTO is the EditEngine's pool default, so ClearItem will result in automatic
727         //  color, too, without having to store the item.
728         rEditSet.ClearItem( EE_CHAR_COLOR );
729     }
730     else
731     {
732         // tdf#125054 adapt WhichID
733         rEditSet.Put( *aColorItem, EE_CHAR_COLOR );
734     }
735 
736     // tdf#125054 adapt WhichID
737     rEditSet.Put( *aFontItem, EE_CHAR_FONTINFO );
738     rEditSet.Put( *aCjkFontItem, EE_CHAR_FONTINFO_CJK );
739     rEditSet.Put( *aCtlFontItem, EE_CHAR_FONTINFO_CTL );
740 
741     rEditSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
742     rEditSet.Put( SvxFontHeightItem( nCjkHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
743     rEditSet.Put( SvxFontHeightItem( nCtlHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
744     rEditSet.Put( SvxWeightItem ( eWeight,      EE_CHAR_WEIGHT ) );
745     rEditSet.Put( SvxWeightItem ( eCjkWeight,   EE_CHAR_WEIGHT_CJK ) );
746     rEditSet.Put( SvxWeightItem ( eCtlWeight,   EE_CHAR_WEIGHT_CTL ) );
747 
748     // tdf#125054 adapt WhichID
749     rEditSet.Put( *aUnderlineItem, EE_CHAR_UNDERLINE );
750     rEditSet.Put( *aOverlineItem, EE_CHAR_OVERLINE );
751 
752     rEditSet.Put( SvxWordLineModeItem( bWordLine,   EE_CHAR_WLM ) );
753     rEditSet.Put( SvxCrossedOutItem( eStrike,       EE_CHAR_STRIKEOUT ) );
754     rEditSet.Put( SvxPostureItem    ( eItalic,      EE_CHAR_ITALIC ) );
755     rEditSet.Put( SvxPostureItem    ( eCjkItalic,   EE_CHAR_ITALIC_CJK ) );
756     rEditSet.Put( SvxPostureItem    ( eCtlItalic,   EE_CHAR_ITALIC_CTL ) );
757     rEditSet.Put( SvxContourItem    ( bOutline,     EE_CHAR_OUTLINE ) );
758     rEditSet.Put( SvxShadowedItem   ( bShadow,      EE_CHAR_SHADOW ) );
759     rEditSet.Put( SvxForbiddenRuleItem(bForbidden, EE_PARA_FORBIDDENRULES) );
760     rEditSet.Put( SvxEmphasisMarkItem( eEmphasis,   EE_CHAR_EMPHASISMARK ) );
761     rEditSet.Put( SvxCharReliefItem( eRelief,       EE_CHAR_RELIEF ) );
762     rEditSet.Put( SvxLanguageItem   ( eLang,        EE_CHAR_LANGUAGE ) );
763     rEditSet.Put( SvxLanguageItem   ( eCjkLang,     EE_CHAR_LANGUAGE_CJK ) );
764     rEditSet.Put( SvxLanguageItem   ( eCtlLang,     EE_CHAR_LANGUAGE_CTL ) );
765     rEditSet.Put( SfxBoolItem       ( EE_PARA_HYPHENATE, bHyphenate ) );
766     rEditSet.Put( SvxFrameDirectionItem( eDirection, EE_PARA_WRITINGDIR ) );
767 
768     // Script spacing is always off.
769     // The cell attribute isn't used here as long as there is no UI to set it
770     // (don't evaluate attributes that can't be changed).
771     // If a locale-dependent default is needed, it has to go into the cell
772     // style, like the fonts.
773     rEditSet.Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
774 }
775 
776 void ScPatternAttr::FillEditItemSet( SfxItemSet* pEditSet, const SfxItemSet* pCondSet ) const
777 {
778     if( pEditSet )
779         FillToEditItemSet( *pEditSet, GetItemSet(), pCondSet );
780 }
781 
782 void ScPatternAttr::GetFromEditItemSet( SfxItemSet& rDestSet, const SfxItemSet& rEditSet )
783 {
784     const SfxPoolItem* pItem;
785 
786     if (rEditSet.GetItemState(EE_CHAR_COLOR,true,&pItem) == SfxItemState::SET)
787         rDestSet.Put( *static_cast<const SvxColorItem*>(pItem), ATTR_FONT_COLOR );
788 
789     if (rEditSet.GetItemState(EE_CHAR_FONTINFO,true,&pItem) == SfxItemState::SET)
790         rDestSet.Put( *static_cast<const SvxFontItem*>(pItem), ATTR_FONT );
791     if (rEditSet.GetItemState(EE_CHAR_FONTINFO_CJK,true,&pItem) == SfxItemState::SET)
792         rDestSet.Put( *static_cast<const SvxFontItem*>(pItem), ATTR_CJK_FONT );
793     if (rEditSet.GetItemState(EE_CHAR_FONTINFO_CTL,true,&pItem) == SfxItemState::SET)
794         rDestSet.Put( *static_cast<const SvxFontItem*>(pItem), ATTR_CTL_FONT );
795 
796     if (rEditSet.GetItemState(EE_CHAR_FONTHEIGHT,true,&pItem) == SfxItemState::SET)
797         rDestSet.Put( SvxFontHeightItem( HMMToTwips( static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() ),
798                         100, ATTR_FONT_HEIGHT ) );
799     if (rEditSet.GetItemState(EE_CHAR_FONTHEIGHT_CJK,true,&pItem) == SfxItemState::SET)
800         rDestSet.Put( SvxFontHeightItem( HMMToTwips( static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() ),
801                         100, ATTR_CJK_FONT_HEIGHT ) );
802     if (rEditSet.GetItemState(EE_CHAR_FONTHEIGHT_CTL,true,&pItem) == SfxItemState::SET)
803         rDestSet.Put( SvxFontHeightItem( HMMToTwips( static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() ),
804                         100, ATTR_CTL_FONT_HEIGHT ) );
805 
806     if (rEditSet.GetItemState(EE_CHAR_WEIGHT,true,&pItem) == SfxItemState::SET)
807         rDestSet.Put( SvxWeightItem( static_cast<const SvxWeightItem*>(pItem)->GetValue(),
808                         ATTR_FONT_WEIGHT) );
809     if (rEditSet.GetItemState(EE_CHAR_WEIGHT_CJK,true,&pItem) == SfxItemState::SET)
810         rDestSet.Put( SvxWeightItem( static_cast<const SvxWeightItem*>(pItem)->GetValue(),
811                         ATTR_CJK_FONT_WEIGHT) );
812     if (rEditSet.GetItemState(EE_CHAR_WEIGHT_CTL,true,&pItem) == SfxItemState::SET)
813         rDestSet.Put( SvxWeightItem( static_cast<const SvxWeightItem*>(pItem)->GetValue(),
814                         ATTR_CTL_FONT_WEIGHT) );
815 
816     // SvxTextLineItem contains enum and color
817     if (rEditSet.GetItemState(EE_CHAR_UNDERLINE,true,&pItem) == SfxItemState::SET)
818         rDestSet.Put( *static_cast<const SvxUnderlineItem*>(pItem), ATTR_FONT_UNDERLINE );
819     if (rEditSet.GetItemState(EE_CHAR_OVERLINE,true,&pItem) == SfxItemState::SET)
820         rDestSet.Put( *static_cast<const SvxOverlineItem*>(pItem), ATTR_FONT_OVERLINE );
821     if (rEditSet.GetItemState(EE_CHAR_WLM,true,&pItem) == SfxItemState::SET)
822         rDestSet.Put( SvxWordLineModeItem( static_cast<const SvxWordLineModeItem*>(pItem)->GetValue(),
823                         ATTR_FONT_WORDLINE) );
824 
825     if (rEditSet.GetItemState(EE_CHAR_STRIKEOUT,true,&pItem) == SfxItemState::SET)
826         rDestSet.Put( SvxCrossedOutItem( static_cast<const SvxCrossedOutItem*>(pItem)->GetValue(),
827                         ATTR_FONT_CROSSEDOUT) );
828 
829     if (rEditSet.GetItemState(EE_CHAR_ITALIC,true,&pItem) == SfxItemState::SET)
830         rDestSet.Put( SvxPostureItem( static_cast<const SvxPostureItem*>(pItem)->GetValue(),
831                         ATTR_FONT_POSTURE) );
832     if (rEditSet.GetItemState(EE_CHAR_ITALIC_CJK,true,&pItem) == SfxItemState::SET)
833         rDestSet.Put( SvxPostureItem( static_cast<const SvxPostureItem*>(pItem)->GetValue(),
834                         ATTR_CJK_FONT_POSTURE) );
835     if (rEditSet.GetItemState(EE_CHAR_ITALIC_CTL,true,&pItem) == SfxItemState::SET)
836         rDestSet.Put( SvxPostureItem( static_cast<const SvxPostureItem*>(pItem)->GetValue(),
837                         ATTR_CTL_FONT_POSTURE) );
838 
839     if (rEditSet.GetItemState(EE_CHAR_OUTLINE,true,&pItem) == SfxItemState::SET)
840         rDestSet.Put( SvxContourItem( static_cast<const SvxContourItem*>(pItem)->GetValue(),
841                         ATTR_FONT_CONTOUR) );
842     if (rEditSet.GetItemState(EE_CHAR_SHADOW,true,&pItem) == SfxItemState::SET)
843         rDestSet.Put( SvxShadowedItem( static_cast<const SvxShadowedItem*>(pItem)->GetValue(),
844                         ATTR_FONT_SHADOWED) );
845     if (rEditSet.GetItemState(EE_CHAR_EMPHASISMARK,true,&pItem) == SfxItemState::SET)
846         rDestSet.Put( SvxEmphasisMarkItem( static_cast<const SvxEmphasisMarkItem*>(pItem)->GetEmphasisMark(),
847                         ATTR_FONT_EMPHASISMARK) );
848     if (rEditSet.GetItemState(EE_CHAR_RELIEF,true,&pItem) == SfxItemState::SET)
849         rDestSet.Put( SvxCharReliefItem( static_cast<const SvxCharReliefItem*>(pItem)->GetValue(),
850                         ATTR_FONT_RELIEF) );
851 
852     if (rEditSet.GetItemState(EE_CHAR_LANGUAGE,true,&pItem) == SfxItemState::SET)
853         rDestSet.Put( SvxLanguageItem(static_cast<const SvxLanguageItem*>(pItem)->GetValue(), ATTR_FONT_LANGUAGE) );
854     if (rEditSet.GetItemState(EE_CHAR_LANGUAGE_CJK,true,&pItem) == SfxItemState::SET)
855         rDestSet.Put( SvxLanguageItem(static_cast<const SvxLanguageItem*>(pItem)->GetValue(), ATTR_CJK_FONT_LANGUAGE) );
856     if (rEditSet.GetItemState(EE_CHAR_LANGUAGE_CTL,true,&pItem) == SfxItemState::SET)
857         rDestSet.Put( SvxLanguageItem(static_cast<const SvxLanguageItem*>(pItem)->GetValue(), ATTR_CTL_FONT_LANGUAGE) );
858 
859     if (rEditSet.GetItemState(EE_PARA_JUST,true,&pItem) != SfxItemState::SET)
860         return;
861 
862     SvxCellHorJustify eVal;
863     switch ( static_cast<const SvxAdjustItem*>(pItem)->GetAdjust() )
864     {
865         case SvxAdjust::Left:
866             // EditEngine Default is always set in the GetAttribs() ItemSet !
867             // whether left or right, is decided in text / number
868             eVal = SvxCellHorJustify::Standard;
869             break;
870         case SvxAdjust::Right:
871             eVal = SvxCellHorJustify::Right;
872             break;
873         case SvxAdjust::Block:
874             eVal = SvxCellHorJustify::Block;
875             break;
876         case SvxAdjust::Center:
877             eVal = SvxCellHorJustify::Center;
878             break;
879         case SvxAdjust::BlockLine:
880             eVal = SvxCellHorJustify::Block;
881             break;
882         case SvxAdjust::End:
883             eVal = SvxCellHorJustify::Right;
884             break;
885         default:
886             eVal = SvxCellHorJustify::Standard;
887     }
888     if ( eVal != SvxCellHorJustify::Standard )
889         rDestSet.Put( SvxHorJustifyItem( eVal, ATTR_HOR_JUSTIFY) );
890 }
891 
892 void ScPatternAttr::GetFromEditItemSet( const SfxItemSet* pEditSet )
893 {
894     if( !pEditSet )
895         return;
896     GetFromEditItemSet( GetItemSet(), *pEditSet );
897     mxHashCode.reset();
898 }
899 
900 void ScPatternAttr::FillEditParaItems( SfxItemSet* pEditSet ) const
901 {
902     //  already there in GetFromEditItemSet, but not in FillEditItemSet
903     //  Default horizontal alignment is always implemented as left
904 
905     const SfxItemSet& rMySet = GetItemSet();
906 
907     SvxCellHorJustify eHorJust = rMySet.Get(ATTR_HOR_JUSTIFY).GetValue();
908 
909     SvxAdjust eSvxAdjust;
910     switch (eHorJust)
911     {
912         case SvxCellHorJustify::Right:  eSvxAdjust = SvxAdjust::Right;  break;
913         case SvxCellHorJustify::Center: eSvxAdjust = SvxAdjust::Center; break;
914         case SvxCellHorJustify::Block:  eSvxAdjust = SvxAdjust::Block;  break;
915         default:                     eSvxAdjust = SvxAdjust::Left;   break;
916     }
917     pEditSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
918 }
919 
920 void ScPatternAttr::DeleteUnchanged( const ScPatternAttr* pOldAttrs )
921 {
922     SfxItemSet& rThisSet = GetItemSet();
923     const SfxItemSet& rOldSet = pOldAttrs->GetItemSet();
924 
925     const SfxPoolItem* pThisItem;
926     const SfxPoolItem* pOldItem;
927 
928     for ( sal_uInt16 nSubWhich=ATTR_PATTERN_START; nSubWhich<=ATTR_PATTERN_END; nSubWhich++ )
929     {
930         //  only items that are set are interesting
931         if ( rThisSet.GetItemState( nSubWhich, false, &pThisItem ) == SfxItemState::SET )
932         {
933             SfxItemState eOldState = rOldSet.GetItemState( nSubWhich, true, &pOldItem );
934             if ( eOldState == SfxItemState::SET )
935             {
936                 //  item is set in OldAttrs (or its parent) -> compare pointers
937                 if ( pThisItem == pOldItem )
938                 {
939                     rThisSet.ClearItem( nSubWhich );
940                     mxHashCode.reset();
941                 }
942             }
943             else if ( eOldState != SfxItemState::DONTCARE )
944             {
945                 //  not set in OldAttrs -> compare item value to default item
946                 if ( *pThisItem == rThisSet.GetPool()->GetDefaultItem( nSubWhich ) )
947                 {
948                     rThisSet.ClearItem( nSubWhich );
949                     mxHashCode.reset();
950                 }
951             }
952         }
953     }
954 }
955 
956 bool ScPatternAttr::HasItemsSet( const sal_uInt16* pWhich ) const
957 {
958     const SfxItemSet& rSet = GetItemSet();
959     for (sal_uInt16 i=0; pWhich[i]; i++)
960         if ( rSet.GetItemState( pWhich[i], false ) == SfxItemState::SET )
961             return true;
962     return false;
963 }
964 
965 void ScPatternAttr::ClearItems( const sal_uInt16* pWhich )
966 {
967     SfxItemSet& rSet = GetItemSet();
968     for (sal_uInt16 i=0; pWhich[i]; i++)
969         rSet.ClearItem(pWhich[i]);
970     mxHashCode.reset();
971 }
972 
973 static SfxStyleSheetBase* lcl_CopyStyleToPool
974     (
975         SfxStyleSheetBase*      pSrcStyle,
976         SfxStyleSheetBasePool*  pSrcPool,
977         SfxStyleSheetBasePool*  pDestPool,
978         const SvNumberFormatterIndexTable*     pFormatExchangeList
979     )
980 {
981     if ( !pSrcStyle || !pDestPool || !pSrcPool )
982     {
983         OSL_FAIL( "CopyStyleToPool: Invalid Arguments :-/" );
984         return nullptr;
985     }
986 
987     const OUString       aStrSrcStyle = pSrcStyle->GetName();
988     const SfxStyleFamily eFamily      = pSrcStyle->GetFamily();
989     SfxStyleSheetBase*   pDestStyle   = pDestPool->Find( aStrSrcStyle, eFamily );
990 
991     if ( !pDestStyle )
992     {
993         const OUString   aStrParent = pSrcStyle->GetParent();
994         const SfxItemSet& rSrcSet = pSrcStyle->GetItemSet();
995 
996         pDestStyle = &pDestPool->Make( aStrSrcStyle, eFamily, SfxStyleSearchBits::UserDefined );
997         SfxItemSet& rDestSet = pDestStyle->GetItemSet();
998         rDestSet.Put( rSrcSet );
999 
1000         // number format exchange list has to be handled here, too
1001         // (only called for cell styles)
1002 
1003         const SfxPoolItem* pSrcItem;
1004         if ( pFormatExchangeList &&
1005              rSrcSet.GetItemState( ATTR_VALUE_FORMAT, false, &pSrcItem ) == SfxItemState::SET )
1006         {
1007             sal_uLong nOldFormat = static_cast<const SfxUInt32Item*>(pSrcItem)->GetValue();
1008             SvNumberFormatterIndexTable::const_iterator it = pFormatExchangeList->find(nOldFormat);
1009             if (it != pFormatExchangeList->end())
1010             {
1011                 sal_uInt32 nNewFormat = it->second;
1012                 rDestSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
1013             }
1014         }
1015 
1016         // if necessary create derivative Styles, if not available:
1017 
1018         if ( (ScResId(STR_STYLENAME_STANDARD_CELL) != aStrParent || ScResId(STR_STYLENAME_STANDARD_PAGE) != aStrParent) &&
1019              aStrSrcStyle != aStrParent &&
1020              !pDestPool->Find( aStrParent, eFamily ) )
1021         {
1022             lcl_CopyStyleToPool( pSrcPool->Find( aStrParent, eFamily ),
1023                                  pSrcPool, pDestPool, pFormatExchangeList );
1024         }
1025 
1026         pDestStyle->SetParent( aStrParent );
1027     }
1028 
1029     return pDestStyle;
1030 }
1031 
1032 ScPatternAttr* ScPatternAttr::PutInPool( ScDocument* pDestDoc, ScDocument* pSrcDoc ) const
1033 {
1034     const SfxItemSet* pSrcSet = &GetItemSet();
1035 
1036     std::unique_ptr<ScPatternAttr> pDestPattern( new ScPatternAttr(pDestDoc->GetPool()) );
1037     SfxItemSet* pDestSet = &pDestPattern->GetItemSet();
1038 
1039     // Copy cell pattern style to other document:
1040 
1041     if ( pDestDoc != pSrcDoc )
1042     {
1043         OSL_ENSURE( pStyle, "Missing Pattern-Style! :-/" );
1044 
1045         // if pattern in DestDoc is available, use this, otherwise copy
1046         // parent style to style or create if necessary and attach DestDoc
1047 
1048         SfxStyleSheetBase* pStyleCpy = lcl_CopyStyleToPool( pStyle,
1049                                                             pSrcDoc->GetStyleSheetPool(),
1050                                                             pDestDoc->GetStyleSheetPool(),
1051                                                             pDestDoc->GetFormatExchangeList() );
1052 
1053         pDestPattern->SetStyleSheet( static_cast<ScStyleSheet*>(pStyleCpy) );
1054     }
1055 
1056     for ( sal_uInt16 nAttrId = ATTR_PATTERN_START; nAttrId <= ATTR_PATTERN_END; nAttrId++ )
1057     {
1058         const SfxPoolItem* pSrcItem;
1059         SfxItemState eItemState = pSrcSet->GetItemState( nAttrId, false, &pSrcItem );
1060         if (eItemState==SfxItemState::SET)
1061         {
1062             std::unique_ptr<SfxPoolItem> pNewItem;
1063 
1064             if ( nAttrId == ATTR_VALIDDATA )
1065             {
1066                 // Copy validity to the new document
1067 
1068                 sal_uLong nNewIndex = 0;
1069                 ScValidationDataList* pSrcList = pSrcDoc->GetValidationList();
1070                 if ( pSrcList )
1071                 {
1072                     sal_uLong nOldIndex = static_cast<const SfxUInt32Item*>(pSrcItem)->GetValue();
1073                     const ScValidationData* pOldData = pSrcList->GetData( nOldIndex );
1074                     if ( pOldData )
1075                         nNewIndex = pDestDoc->AddValidationEntry( *pOldData );
1076                 }
1077                 pNewItem.reset(new SfxUInt32Item( ATTR_VALIDDATA, nNewIndex ));
1078             }
1079             else if ( nAttrId == ATTR_VALUE_FORMAT && pDestDoc->GetFormatExchangeList() )
1080             {
1081                 //  Number format to Exchange List
1082 
1083                 sal_uLong nOldFormat = static_cast<const SfxUInt32Item*>(pSrcItem)->GetValue();
1084                 SvNumberFormatterIndexTable::const_iterator it = pDestDoc->GetFormatExchangeList()->find(nOldFormat);
1085                 if (it != pDestDoc->GetFormatExchangeList()->end())
1086                 {
1087                     sal_uInt32 nNewFormat = it->second;
1088                     pNewItem.reset(new SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ));
1089                 }
1090             }
1091 
1092             if ( pNewItem )
1093             {
1094                 pDestSet->Put(*pNewItem);
1095             }
1096             else
1097                 pDestSet->Put(*pSrcItem);
1098         }
1099     }
1100 
1101     ScPatternAttr* pPatternAttr = const_cast<ScPatternAttr*>( &pDestDoc->GetPool()->Put(*pDestPattern) );
1102     return pPatternAttr;
1103 }
1104 
1105 bool ScPatternAttr::IsVisible() const
1106 {
1107     const SfxItemSet& rSet = GetItemSet();
1108 
1109     const SfxPoolItem* pItem;
1110     SfxItemState eState;
1111 
1112     eState = rSet.GetItemState( ATTR_BACKGROUND, true, &pItem );
1113     if ( eState == SfxItemState::SET )
1114         if ( static_cast<const SvxBrushItem*>(pItem)->GetColor() != COL_TRANSPARENT )
1115             return true;
1116 
1117     eState = rSet.GetItemState( ATTR_BORDER, true, &pItem );
1118     if ( eState == SfxItemState::SET )
1119     {
1120         const SvxBoxItem* pBoxItem = static_cast<const SvxBoxItem*>(pItem);
1121         if ( pBoxItem->GetTop() || pBoxItem->GetBottom() ||
1122              pBoxItem->GetLeft() || pBoxItem->GetRight() )
1123             return true;
1124     }
1125 
1126     eState = rSet.GetItemState( ATTR_BORDER_TLBR, true, &pItem );
1127     if ( eState == SfxItemState::SET )
1128         if( static_cast< const SvxLineItem* >( pItem )->GetLine() )
1129             return true;
1130 
1131     eState = rSet.GetItemState( ATTR_BORDER_BLTR, true, &pItem );
1132     if ( eState == SfxItemState::SET )
1133         if( static_cast< const SvxLineItem* >( pItem )->GetLine() )
1134             return true;
1135 
1136     eState = rSet.GetItemState( ATTR_SHADOW, true, &pItem );
1137     if ( eState == SfxItemState::SET )
1138         if ( static_cast<const SvxShadowItem*>(pItem)->GetLocation() != SvxShadowLocation::NONE )
1139             return true;
1140 
1141     return false;
1142 }
1143 
1144 static bool OneEqual( const SfxItemSet& rSet1, const SfxItemSet& rSet2, sal_uInt16 nId )
1145 {
1146     const SfxPoolItem* pItem1 = &rSet1.Get(nId);
1147     const SfxPoolItem* pItem2 = &rSet2.Get(nId);
1148     return ( pItem1 == pItem2 || *pItem1 == *pItem2 );
1149 }
1150 
1151 bool ScPatternAttr::IsVisibleEqual( const ScPatternAttr& rOther ) const
1152 {
1153     const SfxItemSet& rThisSet = GetItemSet();
1154     const SfxItemSet& rOtherSet = rOther.GetItemSet();
1155 
1156     return OneEqual( rThisSet, rOtherSet, ATTR_BACKGROUND ) &&
1157             OneEqual( rThisSet, rOtherSet, ATTR_BORDER ) &&
1158             OneEqual( rThisSet, rOtherSet, ATTR_BORDER_TLBR ) &&
1159             OneEqual( rThisSet, rOtherSet, ATTR_BORDER_BLTR ) &&
1160             OneEqual( rThisSet, rOtherSet, ATTR_SHADOW );
1161 
1162     //TODO: also here only check really visible values !!!
1163 }
1164 
1165 const OUString* ScPatternAttr::GetStyleName() const
1166 {
1167     return pName ? &*pName : ( pStyle ? &pStyle->GetName() : nullptr );
1168 }
1169 
1170 void ScPatternAttr::SetStyleSheet( ScStyleSheet* pNewStyle, bool bClearDirectFormat )
1171 {
1172     if (pNewStyle)
1173     {
1174         SfxItemSet&       rPatternSet = GetItemSet();
1175         const SfxItemSet& rStyleSet = pNewStyle->GetItemSet();
1176 
1177         if (bClearDirectFormat)
1178         {
1179             for (sal_uInt16 i=ATTR_PATTERN_START; i<=ATTR_PATTERN_END; i++)
1180             {
1181                 if (rStyleSet.GetItemState(i) == SfxItemState::SET)
1182                     rPatternSet.ClearItem(i);
1183             }
1184         }
1185         rPatternSet.SetParent(&pNewStyle->GetItemSet());
1186         pStyle = pNewStyle;
1187         pName.reset();
1188     }
1189     else
1190     {
1191         OSL_FAIL( "ScPatternAttr::SetStyleSheet( NULL ) :-|" );
1192         GetItemSet().SetParent(nullptr);
1193         pStyle = nullptr;
1194     }
1195 }
1196 
1197 void ScPatternAttr::UpdateStyleSheet(const ScDocument& rDoc)
1198 {
1199     if (pName)
1200     {
1201         pStyle = static_cast<ScStyleSheet*>(rDoc.GetStyleSheetPool()->Find(*pName, SfxStyleFamily::Para));
1202 
1203         //  use Standard if Style is not found,
1204         //  to avoid empty display in Toolbox-Controller
1205         //  Assumes that "Standard" is always the 1st entry!
1206         if (!pStyle)
1207         {
1208             std::unique_ptr<SfxStyleSheetIterator> pIter = rDoc.GetStyleSheetPool()->CreateIterator(SfxStyleFamily::Para);
1209             pStyle = dynamic_cast< ScStyleSheet* >(pIter->First());
1210         }
1211 
1212         if (pStyle)
1213         {
1214             GetItemSet().SetParent(&pStyle->GetItemSet());
1215             pName.reset();
1216         }
1217     }
1218     else
1219         pStyle = nullptr;
1220 }
1221 
1222 void ScPatternAttr::StyleToName()
1223 {
1224     // Style was deleted, remember name:
1225 
1226     if ( pStyle )
1227     {
1228         pName = pStyle->GetName();
1229         pStyle = nullptr;
1230         GetItemSet().SetParent( nullptr );
1231     }
1232 }
1233 
1234 bool ScPatternAttr::IsSymbolFont() const
1235 {
1236     const SfxPoolItem* pItem;
1237     if( GetItemSet().GetItemState( ATTR_FONT, true, &pItem ) == SfxItemState::SET )
1238         return static_cast<const SvxFontItem*>(pItem)->GetCharSet() == RTL_TEXTENCODING_SYMBOL;
1239     else
1240         return false;
1241 }
1242 
1243 namespace {
1244 
1245 sal_uInt32 getNumberFormatKey(const SfxItemSet& rSet)
1246 {
1247     return rSet.Get(ATTR_VALUE_FORMAT).GetValue();
1248 }
1249 
1250 LanguageType getLanguageType(const SfxItemSet& rSet)
1251 {
1252     return rSet.Get(ATTR_LANGUAGE_FORMAT).GetLanguage();
1253 }
1254 
1255 }
1256 
1257 sal_uInt32 ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter ) const
1258 {
1259     sal_uInt32 nFormat = getNumberFormatKey(GetItemSet());
1260     LanguageType eLang = getLanguageType(GetItemSet());
1261     if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLang == LANGUAGE_SYSTEM )
1262         ;       // it remains as it is
1263     else if ( pFormatter )
1264         nFormat = pFormatter->GetFormatForLanguageIfBuiltIn( nFormat, eLang );
1265     return nFormat;
1266 }
1267 
1268 // the same if conditional formatting is in play:
1269 
1270 sal_uInt32 ScPatternAttr::GetNumberFormat( SvNumberFormatter* pFormatter,
1271                                            const SfxItemSet* pCondSet ) const
1272 {
1273     assert(pFormatter);
1274     if (!pCondSet)
1275         return GetNumberFormat(pFormatter);
1276 
1277     // Conditional format takes precedence over style and even hard format.
1278 
1279     const SfxPoolItem* pFormItem;
1280     sal_uInt32 nFormat;
1281     const SfxPoolItem* pLangItem;
1282     LanguageType eLang;
1283     if (pCondSet->GetItemState(ATTR_VALUE_FORMAT, true, &pFormItem) == SfxItemState::SET )
1284     {
1285         nFormat = getNumberFormatKey(*pCondSet);
1286         if (pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT, true, &pLangItem) == SfxItemState::SET)
1287             eLang = getLanguageType(*pCondSet);
1288         else
1289             eLang = getLanguageType(GetItemSet());
1290     }
1291     else
1292     {
1293         nFormat = getNumberFormatKey(GetItemSet());
1294         eLang = getLanguageType(GetItemSet());
1295     }
1296 
1297     return pFormatter->GetFormatForLanguageIfBuiltIn(nFormat, eLang);
1298 }
1299 
1300 const SfxPoolItem& ScPatternAttr::GetItem( sal_uInt16 nWhich, const SfxItemSet& rItemSet, const SfxItemSet* pCondSet )
1301 {
1302     const SfxPoolItem* pCondItem;
1303     if ( pCondSet && pCondSet->GetItemState( nWhich, true, &pCondItem ) == SfxItemState::SET )
1304         return *pCondItem;
1305     return rItemSet.Get(nWhich);
1306 }
1307 
1308 const SfxPoolItem& ScPatternAttr::GetItem( sal_uInt16 nSubWhich, const SfxItemSet* pCondSet ) const
1309 {
1310     return GetItem( nSubWhich, GetItemSet(), pCondSet );
1311 }
1312 
1313 //  GetRotateVal is tested before ATTR_ORIENTATION
1314 
1315 tools::Long ScPatternAttr::GetRotateVal( const SfxItemSet* pCondSet ) const
1316 {
1317     tools::Long nAttrRotate = 0;
1318     if ( GetCellOrientation() == SvxCellOrientation::Standard )
1319     {
1320         bool bRepeat = ( GetItem(ATTR_HOR_JUSTIFY, pCondSet).
1321                             GetValue() == SvxCellHorJustify::Repeat );
1322         // ignore orientation/rotation if "repeat" is active
1323         if ( !bRepeat )
1324             nAttrRotate = GetItem( ATTR_ROTATE_VALUE, pCondSet ).GetValue();
1325     }
1326     return nAttrRotate;
1327 }
1328 
1329 ScRotateDir ScPatternAttr::GetRotateDir( const SfxItemSet* pCondSet ) const
1330 {
1331     ScRotateDir nRet = ScRotateDir::NONE;
1332 
1333     tools::Long nAttrRotate = GetRotateVal( pCondSet );
1334     if ( nAttrRotate )
1335     {
1336         SvxRotateMode eRotMode = GetItem(ATTR_ROTATE_MODE, pCondSet).GetValue();
1337 
1338         if ( eRotMode == SVX_ROTATE_MODE_STANDARD || nAttrRotate == 18000 )
1339             nRet = ScRotateDir::Standard;
1340         else if ( eRotMode == SVX_ROTATE_MODE_CENTER )
1341             nRet = ScRotateDir::Center;
1342         else if ( eRotMode == SVX_ROTATE_MODE_TOP || eRotMode == SVX_ROTATE_MODE_BOTTOM )
1343         {
1344             tools::Long nRot180 = nAttrRotate % 18000;     // 1/100 degrees
1345             if ( nRot180 == 9000 )
1346                 nRet = ScRotateDir::Center;
1347             else if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nRot180 < 9000 ) ||
1348                       ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nRot180 > 9000 ) )
1349                 nRet = ScRotateDir::Left;
1350             else
1351                 nRet = ScRotateDir::Right;
1352         }
1353     }
1354 
1355     return nRet;
1356 }
1357 
1358 void ScPatternAttr::SetKey(sal_uInt64 nKey)
1359 {
1360     mnKey = nKey;
1361 }
1362 
1363 sal_uInt64 ScPatternAttr::GetKey() const
1364 {
1365     return mnKey;
1366 }
1367 
1368 void ScPatternAttr::CalcHashCode() const
1369 {
1370     auto const & rSet = GetItemSet();
1371     mxHashCode = boost::hash_range(rSet.GetItems_Impl(), rSet.GetItems_Impl() + rSet.Count());
1372 }
1373 
1374 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1375