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
