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