1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "precompiled_sfx2.hxx" 25 26 #include "sfx2/sidebar/Theme.hxx" 27 #include "Paint.hxx" 28 #include "SidebarResource.hxx" 29 #include "sfx2/sidebar/Tools.hxx" 30 31 #include <tools/svborder.hxx> 32 #include <tools/rc.hxx> 33 #include <vcl/svapp.hxx> 34 35 using namespace css; 36 using namespace cssu; 37 38 39 namespace sfx2 { namespace sidebar { 40 41 ::rtl::Reference<Theme> Theme::mpInstance; 42 43 44 45 46 Theme& Theme::GetCurrentTheme (void) 47 { 48 if ( ! mpInstance.is()) 49 { 50 mpInstance.set(new Theme()); 51 mpInstance->InitializeTheme(); 52 } 53 return *mpInstance; 54 } 55 56 57 58 59 Theme::Theme (void) 60 : ThemeInterfaceBase(m_aMutex), 61 maImages(), 62 maColors(), 63 maPaints(), 64 maIntegers(), 65 maBooleans(), 66 mbIsHighContrastMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode()), 67 mbIsHighContrastModeSetManually(false), 68 maPropertyNameToIdMap(), 69 maPropertyIdToNameMap(), 70 maRawValues(), 71 maChangeListeners(), 72 maVetoableListeners() 73 74 { 75 SetupPropertyMaps(); 76 } 77 78 79 80 81 Theme::~Theme (void) 82 { 83 } 84 85 86 87 88 Image Theme::GetImage (const ThemeItem eItem) 89 { 90 const PropertyType eType (GetPropertyType(eItem)); 91 OSL_ASSERT(eType==PT_Image); 92 const sal_Int32 nIndex (GetIndex(eItem, eType)); 93 const Theme& rTheme (GetCurrentTheme()); 94 return rTheme.maImages[nIndex]; 95 } 96 97 98 99 100 Color Theme::GetColor (const ThemeItem eItem) 101 { 102 const PropertyType eType (GetPropertyType(eItem)); 103 OSL_ASSERT(eType==PT_Color || eType==PT_Paint); 104 const sal_Int32 nIndex (GetIndex(eItem, eType)); 105 const Theme& rTheme (GetCurrentTheme()); 106 if (eType == PT_Color) 107 return rTheme.maColors[nIndex]; 108 else if (eType == PT_Paint) 109 return rTheme.maPaints[nIndex].GetColor(); 110 else 111 return COL_WHITE; 112 } 113 114 115 116 117 const Paint& Theme::GetPaint (const ThemeItem eItem) 118 { 119 const PropertyType eType (GetPropertyType(eItem)); 120 OSL_ASSERT(eType==PT_Paint); 121 const sal_Int32 nIndex (GetIndex(eItem, eType)); 122 const Theme& rTheme (GetCurrentTheme()); 123 return rTheme.maPaints[nIndex]; 124 } 125 126 127 128 129 const Wallpaper Theme::GetWallpaper (const ThemeItem eItem) 130 { 131 return GetPaint(eItem).GetWallpaper(); 132 } 133 134 135 136 137 sal_Int32 Theme::GetInteger (const ThemeItem eItem) 138 { 139 const PropertyType eType (GetPropertyType(eItem)); 140 OSL_ASSERT(eType==PT_Integer); 141 const sal_Int32 nIndex (GetIndex(eItem, eType)); 142 const Theme& rTheme (GetCurrentTheme()); 143 return rTheme.maIntegers[nIndex]; 144 } 145 146 147 148 149 bool Theme::GetBoolean (const ThemeItem eItem) 150 { 151 const PropertyType eType (GetPropertyType(eItem)); 152 OSL_ASSERT(eType==PT_Boolean); 153 const sal_Int32 nIndex (GetIndex(eItem, eType)); 154 const Theme& rTheme (GetCurrentTheme()); 155 return rTheme.maBooleans[nIndex]; 156 } 157 158 159 160 161 Rectangle Theme::GetRectangle (const ThemeItem eItem) 162 { 163 const PropertyType eType (GetPropertyType(eItem)); 164 OSL_ASSERT(eType==PT_Rectangle); 165 const sal_Int32 nIndex (GetIndex(eItem, eType)); 166 const Theme& rTheme (GetCurrentTheme()); 167 return rTheme.maRectangles[nIndex]; 168 } 169 170 171 172 173 bool Theme::IsHighContrastMode (void) 174 { 175 const Theme& rTheme (GetCurrentTheme()); 176 return rTheme.mbIsHighContrastMode; 177 } 178 179 180 181 182 void Theme::HandleDataChange (void) 183 { 184 Theme& rTheme (GetCurrentTheme()); 185 186 if ( ! rTheme.mbIsHighContrastModeSetManually) 187 { 188 // Do not modify mbIsHighContrastMode when it was manually set. 189 GetCurrentTheme().mbIsHighContrastMode = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); 190 rTheme.maRawValues[Bool_IsHighContrastModeActive] = Any(GetCurrentTheme().mbIsHighContrastMode); 191 } 192 193 GetCurrentTheme().UpdateTheme(); 194 } 195 196 197 198 199 void Theme::InitializeTheme (void) 200 { 201 setPropertyValue( 202 maPropertyIdToNameMap[Bool_UseSymphonyIcons], 203 Any(false)); 204 setPropertyValue( 205 maPropertyIdToNameMap[Bool_UseSystemColors], 206 Any(false)); 207 } 208 209 210 211 212 void Theme::UpdateTheme (void) 213 { 214 SidebarResource aLocalResource; 215 216 try 217 { 218 const StyleSettings& rStyle (Application::GetSettings().GetStyleSettings()); 219 const bool bUseSystemColors (GetBoolean(Bool_UseSystemColors)); 220 221 #define Alternatives(n,hc,sys) (mbIsHighContrastMode ? hc : (bUseSystemColors ? sys : n)) 222 223 Color aBaseBackgroundColor (rStyle.GetDialogColor()); 224 // UX says this should be a little brighter, but that looks off when compared to the other windows. 225 //aBaseBackgroundColor.IncreaseLuminance(7); 226 Color aBorderColor (aBaseBackgroundColor); 227 aBorderColor.DecreaseLuminance(15); 228 Color aSecondColor (aBaseBackgroundColor); 229 aSecondColor.DecreaseLuminance(15); 230 231 setPropertyValue( 232 maPropertyIdToNameMap[Paint_DeckBackground], 233 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor()))); 234 235 setPropertyValue( 236 maPropertyIdToNameMap[Paint_DeckTitleBarBackground], 237 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor()))); 238 setPropertyValue( 239 maPropertyIdToNameMap[Int_DeckLeftPadding], 240 Any(sal_Int32(2))); 241 setPropertyValue( 242 maPropertyIdToNameMap[Int_DeckTopPadding], 243 Any(sal_Int32(2))); 244 setPropertyValue( 245 maPropertyIdToNameMap[Int_DeckRightPadding], 246 Any(sal_Int32(2))); 247 setPropertyValue( 248 maPropertyIdToNameMap[Int_DeckBottomPadding], 249 Any(sal_Int32(2))); 250 setPropertyValue( 251 maPropertyIdToNameMap[Int_DeckBorderSize], 252 Any(sal_Int32(1))); 253 setPropertyValue( 254 maPropertyIdToNameMap[Int_DeckSeparatorHeight], 255 Any(sal_Int32(1))); 256 setPropertyValue( 257 maPropertyIdToNameMap[Int_ButtonCornerRadius], 258 Any(sal_Int32(3))); 259 setPropertyValue( 260 maPropertyIdToNameMap[Color_DeckTitleFont], 261 Any(sal_Int32(rStyle.GetFontColor().GetRGBColor()))); 262 setPropertyValue( 263 maPropertyIdToNameMap[Int_DeckTitleBarHeight], 264 Any(sal_Int32(Alternatives( 265 26, 266 26, 267 rStyle.GetFloatTitleHeight())))); 268 setPropertyValue( 269 maPropertyIdToNameMap[Paint_PanelBackground], 270 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor()))); 271 272 setPropertyValue( 273 maPropertyIdToNameMap[Paint_PanelTitleBarBackground], 274 Any(Tools::VclToAwtGradient(Gradient( 275 GRADIENT_LINEAR, 276 aSecondColor.GetRGBColor(), 277 aBaseBackgroundColor.GetRGBColor() 278 )))); 279 setPropertyValue( 280 maPropertyIdToNameMap[Color_PanelTitleFont], 281 Any(sal_Int32(mbIsHighContrastMode ? 0x00ff00 : 0x262626))); 282 setPropertyValue( 283 maPropertyIdToNameMap[Int_PanelTitleBarHeight], 284 Any(sal_Int32(Alternatives( 285 26, 286 26, 287 rStyle.GetTitleHeight())))); 288 setPropertyValue( 289 maPropertyIdToNameMap[Paint_TabBarBackground], 290 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor()))); 291 setPropertyValue( 292 maPropertyIdToNameMap[Int_TabBarLeftPadding], 293 Any(sal_Int32(2))); 294 setPropertyValue( 295 maPropertyIdToNameMap[Int_TabBarTopPadding], 296 Any(sal_Int32(2))); 297 setPropertyValue( 298 maPropertyIdToNameMap[Int_TabBarRightPadding], 299 Any(sal_Int32(2))); 300 setPropertyValue( 301 maPropertyIdToNameMap[Int_TabBarBottomPadding], 302 Any(sal_Int32(2))); 303 304 setPropertyValue( 305 maPropertyIdToNameMap[Int_TabMenuPadding], 306 Any(sal_Int32(6))); 307 setPropertyValue( 308 maPropertyIdToNameMap[Color_TabMenuSeparator], 309 Any(sal_Int32(aBorderColor.GetRGBColor()))); 310 setPropertyValue( 311 maPropertyIdToNameMap[Int_TabMenuSeparatorPadding], 312 Any(sal_Int32(7))); 313 314 setPropertyValue( 315 maPropertyIdToNameMap[Int_TabItemWidth], 316 Any(sal_Int32(32))); 317 setPropertyValue( 318 maPropertyIdToNameMap[Int_TabItemHeight], 319 Any(sal_Int32(32))); 320 setPropertyValue( 321 maPropertyIdToNameMap[Color_TabItemBorder], 322 Any(sal_Int32(rStyle.GetActiveBorderColor().GetRGBColor()))); 323 // mbIsHighContrastMode ? 0x00ff00 : 0xbfbfbf))); 324 325 setPropertyValue( 326 maPropertyIdToNameMap[Paint_DropDownBackground], 327 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor()))); 328 setPropertyValue( 329 maPropertyIdToNameMap[Color_DropDownBorder], 330 Any(sal_Int32(rStyle.GetActiveBorderColor().GetRGBColor()))); 331 332 setPropertyValue( 333 maPropertyIdToNameMap[Color_Highlight], 334 Any(sal_Int32(rStyle.GetHighlightColor().GetRGBColor()))); 335 setPropertyValue( 336 maPropertyIdToNameMap[Color_HighlightText], 337 Any(sal_Int32(rStyle.GetHighlightTextColor().GetRGBColor()))); 338 339 setPropertyValue( 340 maPropertyIdToNameMap[Paint_TabItemBackgroundNormal], 341 Any()); 342 setPropertyValue( 343 maPropertyIdToNameMap[Paint_TabItemBackgroundHighlight], 344 Any(sal_Int32(rStyle.GetActiveTabColor().GetRGBColor()))); 345 // mbIsHighContrastMode ? 0x000000 : 0x00ffffff))); 346 347 setPropertyValue( 348 maPropertyIdToNameMap[Paint_HorizontalBorder], 349 Any(sal_Int32(aBorderColor.GetRGBColor()))); 350 // mbIsHighContrastMode ? 0x00ff00 : 0xe4e4e4))); 351 setPropertyValue( 352 maPropertyIdToNameMap[Paint_VerticalBorder], 353 Any(sal_Int32(aBorderColor.GetRGBColor()))); 354 // mbIsHighContrastMode ? 0x00ff00 : 0xe4e4e4))); 355 356 setPropertyValue( 357 maPropertyIdToNameMap[Image_Grip], 358 Any( 359 mbIsHighContrastMode 360 ? A2S("private:graphicrepository/sfx2/res/grip_hc.png") 361 : A2S("private:graphicrepository/sfx2/res/grip.png"))); 362 setPropertyValue( 363 maPropertyIdToNameMap[Image_Expand], 364 Any( 365 mbIsHighContrastMode 366 ? A2S("private:graphicrepository/res/plus_sch.png") 367 : A2S("private:graphicrepository/res/plus.png"))); 368 setPropertyValue( 369 maPropertyIdToNameMap[Image_Collapse], 370 Any( 371 mbIsHighContrastMode 372 ? A2S("private:graphicrepository/res/minus_sch.png") 373 : A2S("private:graphicrepository/res/minus.png"))); 374 setPropertyValue( 375 maPropertyIdToNameMap[Image_TabBarMenu], 376 Any( 377 mbIsHighContrastMode 378 ? A2S("private:graphicrepository/sfx2/res/symphony/open_more_hc.png") 379 : A2S("private:graphicrepository/sfx2/res/symphony/open_more.png"))); 380 setPropertyValue( 381 maPropertyIdToNameMap[Image_PanelMenu], 382 Any( 383 mbIsHighContrastMode 384 ? A2S("private:graphicrepository/sfx2/res/symphony/morebutton_h.png") 385 : A2S("private:graphicrepository/sfx2/res/symphony/morebutton.png"))); 386 setPropertyValue( 387 maPropertyIdToNameMap[Image_Closer], 388 Any(A2S("private:graphicrepository/sfx2/res/closedoc.png"))); 389 setPropertyValue( 390 maPropertyIdToNameMap[Image_CloseIndicator], 391 Any( 392 mbIsHighContrastMode 393 ? A2S("private:graphicrepository/res/commandimagelist/lch_decrementlevel.png") 394 : A2S("private:graphicrepository/res/commandimagelist/lc_decrementlevel.png"))); 395 setPropertyValue( 396 maPropertyIdToNameMap[Image_ToolBoxItemSeparator], 397 Any( 398 A2S("private:graphicrepository/sfx2/res/separator.png"))); 399 400 // ToolBox 401 402 /* 403 // Separator style 404 setPropertyValue( 405 maPropertyIdToNameMap[Paint_ToolBoxBackground], 406 Any(sal_Int32(rStyle.GetMenuColor().GetRGBColor()))); 407 setPropertyValue( 408 maPropertyIdToNameMap[Paint_ToolBoxBorderTopLeft], 409 Any()); 410 setPropertyValue( 411 maPropertyIdToNameMap[Paint_ToolBoxBorderCenterCorners], 412 Any()); 413 setPropertyValue( 414 maPropertyIdToNameMap[Paint_ToolBoxBorderBottomRight], 415 Any()); 416 setPropertyValue( 417 maPropertyIdToNameMap[Rect_ToolBoxPadding], 418 Any(awt::Rectangle(2,2,2,2))); 419 setPropertyValue( 420 maPropertyIdToNameMap[Rect_ToolBoxBorder], 421 Any(awt::Rectangle(0,0,0,0))); 422 setPropertyValue( 423 maPropertyIdToNameMap[Bool_UseToolBoxItemSeparator], 424 Any(true)); 425 426 */ 427 428 // Gradient style 429 Color aGradientStop2 (aBaseBackgroundColor); 430 aGradientStop2.IncreaseLuminance(17); 431 Color aToolBoxBorderColor (aBaseBackgroundColor); 432 aToolBoxBorderColor.DecreaseLuminance(12); 433 setPropertyValue( 434 maPropertyIdToNameMap[Paint_ToolBoxBackground], 435 Any(Tools::VclToAwtGradient(Gradient( 436 GRADIENT_LINEAR, 437 aBaseBackgroundColor.GetRGBColor(), 438 aGradientStop2.GetRGBColor() 439 )))); 440 setPropertyValue( 441 maPropertyIdToNameMap[Paint_ToolBoxBorderTopLeft], 442 mbIsHighContrastMode 443 ? Any(util::Color(sal_uInt32(0x00ff00))) 444 : Any(util::Color(aToolBoxBorderColor.GetRGBColor()))); 445 setPropertyValue( 446 maPropertyIdToNameMap[Paint_ToolBoxBorderCenterCorners], 447 mbIsHighContrastMode 448 ? Any(util::Color(sal_uInt32(0x00ff00))) 449 : Any(util::Color(aToolBoxBorderColor.GetRGBColor()))); 450 setPropertyValue( 451 maPropertyIdToNameMap[Paint_ToolBoxBorderBottomRight], 452 mbIsHighContrastMode 453 ? Any(util::Color(sal_uInt32(0x00ff00))) 454 : Any(util::Color(aToolBoxBorderColor.GetRGBColor()))); 455 setPropertyValue( 456 maPropertyIdToNameMap[Rect_ToolBoxPadding], 457 Any(awt::Rectangle(2,2,2,2))); 458 setPropertyValue( 459 maPropertyIdToNameMap[Rect_ToolBoxBorder], 460 Any(awt::Rectangle(1,1,1,1))); 461 setPropertyValue( 462 maPropertyIdToNameMap[Bool_UseToolBoxItemSeparator], 463 Any(false)); 464 } 465 catch(beans::UnknownPropertyException& rException) 466 { 467 OSL_TRACE("unknown property: %s", 468 OUStringToOString( 469 rException.Message, 470 RTL_TEXTENCODING_ASCII_US).getStr()); 471 OSL_ASSERT(false); 472 } 473 } 474 475 476 477 478 void SAL_CALL Theme::disposing (void) 479 { 480 ChangeListeners aListeners; 481 maChangeListeners.swap(aListeners); 482 483 const lang::EventObject aEvent (static_cast<XWeak*>(this)); 484 485 for (ChangeListeners::const_iterator 486 iContainer(maChangeListeners.begin()), 487 iContainerEnd(maChangeListeners.end()); 488 iContainerEnd!=iContainerEnd; 489 ++iContainerEnd) 490 { 491 for (ChangeListenerContainer::const_iterator 492 iListener(iContainer->second.begin()), 493 iEnd(iContainer->second.end()); 494 iListener!=iEnd; 495 ++iListener) 496 { 497 try 498 { 499 (*iListener)->disposing(aEvent); 500 } 501 catch(const Exception&) 502 { 503 } 504 } 505 } 506 } 507 508 509 510 511 Reference<beans::XPropertySet> Theme::GetPropertySet (void) 512 { 513 return Reference<beans::XPropertySet>(static_cast<XWeak*>(&GetCurrentTheme()), UNO_QUERY); 514 } 515 516 517 518 519 Reference<beans::XPropertySetInfo> SAL_CALL Theme::getPropertySetInfo (void) 520 throw(cssu::RuntimeException) 521 { 522 return Reference<beans::XPropertySetInfo>(this); 523 } 524 525 526 527 528 void SAL_CALL Theme::setPropertyValue ( 529 const ::rtl::OUString& rsPropertyName, 530 const cssu::Any& rValue) 531 throw(cssu::RuntimeException) 532 { 533 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName)); 534 if (iId == maPropertyNameToIdMap.end()) 535 throw beans::UnknownPropertyException(rsPropertyName, NULL); 536 537 const PropertyType eType (GetPropertyType(iId->second)); 538 if (eType == PT_Invalid) 539 throw beans::UnknownPropertyException(rsPropertyName, NULL); 540 541 const ThemeItem eItem (iId->second); 542 543 if (rValue == maRawValues[eItem]) 544 { 545 // Value is not different from the one in the property 546 // set => nothing to do. 547 return; 548 } 549 550 const Any aOldValue (maRawValues[eItem]); 551 552 const beans::PropertyChangeEvent aEvent( 553 static_cast<XWeak*>(this), 554 rsPropertyName, 555 sal_False, 556 eItem, 557 aOldValue, 558 rValue); 559 560 if (DoVetoableListenersVeto(GetVetoableListeners(__AnyItem, false), aEvent)) 561 return; 562 if (DoVetoableListenersVeto(GetVetoableListeners(eItem, false), aEvent)) 563 return; 564 565 maRawValues[eItem] = rValue; 566 ProcessNewValue(rValue, eItem, eType); 567 568 BroadcastPropertyChange(GetChangeListeners(__AnyItem, false), aEvent); 569 BroadcastPropertyChange(GetChangeListeners(eItem, false), aEvent); 570 } 571 572 573 574 575 Any SAL_CALL Theme::getPropertyValue ( 576 const ::rtl::OUString& rsPropertyName) 577 throw(css::beans::UnknownPropertyException, 578 css::lang::WrappedTargetException, 579 cssu::RuntimeException) 580 { 581 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName)); 582 if (iId == maPropertyNameToIdMap.end()) 583 throw beans::UnknownPropertyException(); 584 585 const PropertyType eType (GetPropertyType(iId->second)); 586 if (eType == PT_Invalid) 587 throw beans::UnknownPropertyException(); 588 589 const ThemeItem eItem (iId->second); 590 591 return maRawValues[eItem]; 592 } 593 594 595 596 597 void SAL_CALL Theme::addPropertyChangeListener( 598 const ::rtl::OUString& rsPropertyName, 599 const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener) 600 throw(css::beans::UnknownPropertyException, 601 css::lang::WrappedTargetException, 602 cssu::RuntimeException) 603 { 604 ThemeItem eItem (__AnyItem); 605 if (rsPropertyName.getLength() > 0) 606 { 607 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName)); 608 if (iId == maPropertyNameToIdMap.end()) 609 throw beans::UnknownPropertyException(); 610 611 const PropertyType eType (GetPropertyType(iId->second)); 612 if (eType == PT_Invalid) 613 throw beans::UnknownPropertyException(); 614 615 eItem = iId->second; 616 } 617 ChangeListenerContainer* pListeners = GetChangeListeners(eItem, true); 618 if (pListeners != NULL) 619 pListeners->push_back(rxListener); 620 } 621 622 623 624 625 void SAL_CALL Theme::removePropertyChangeListener( 626 const ::rtl::OUString& rsPropertyName, 627 const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener) 628 throw(css::beans::UnknownPropertyException, 629 css::lang::WrappedTargetException, 630 cssu::RuntimeException) 631 { 632 ThemeItem eItem (__AnyItem); 633 if (rsPropertyName.getLength() > 0) 634 { 635 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName)); 636 if (iId == maPropertyNameToIdMap.end()) 637 throw beans::UnknownPropertyException(); 638 639 const PropertyType eType (GetPropertyType(iId->second)); 640 if (eType == PT_Invalid) 641 throw beans::UnknownPropertyException(); 642 643 eItem = iId->second; 644 } 645 ChangeListenerContainer* pContainer = GetChangeListeners(eItem, false); 646 if (pContainer != NULL) 647 { 648 ChangeListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener)); 649 if (iListener != pContainer->end()) 650 { 651 pContainer->erase(iListener); 652 653 // Remove the listener container when empty. 654 if (pContainer->empty()) 655 maChangeListeners.erase(eItem); 656 } 657 } 658 } 659 660 661 662 663 void SAL_CALL Theme::addVetoableChangeListener( 664 const ::rtl::OUString& rsPropertyName, 665 const cssu::Reference<css::beans::XVetoableChangeListener>& rxListener) 666 throw(css::beans::UnknownPropertyException, 667 css::lang::WrappedTargetException, 668 cssu::RuntimeException) 669 { 670 ThemeItem eItem (__AnyItem); 671 if (rsPropertyName.getLength() > 0) 672 { 673 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName)); 674 if (iId == maPropertyNameToIdMap.end()) 675 throw beans::UnknownPropertyException(); 676 677 const PropertyType eType (GetPropertyType(iId->second)); 678 if (eType == PT_Invalid) 679 throw beans::UnknownPropertyException(); 680 681 eItem = iId->second; 682 } 683 VetoableListenerContainer* pListeners = GetVetoableListeners(eItem, true); 684 if (pListeners != NULL) 685 pListeners->push_back(rxListener); 686 } 687 688 689 690 691 void SAL_CALL Theme::removeVetoableChangeListener( 692 const ::rtl::OUString& rsPropertyName, 693 const cssu::Reference<css::beans::XVetoableChangeListener>& rxListener) 694 throw(css::beans::UnknownPropertyException, 695 css::lang::WrappedTargetException, 696 cssu::RuntimeException) 697 { 698 ThemeItem eItem (__AnyItem); 699 if (rsPropertyName.getLength() > 0) 700 { 701 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName)); 702 if (iId == maPropertyNameToIdMap.end()) 703 throw beans::UnknownPropertyException(); 704 705 const PropertyType eType (GetPropertyType(iId->second)); 706 if (eType == PT_Invalid) 707 throw beans::UnknownPropertyException(); 708 709 eItem = iId->second; 710 } 711 VetoableListenerContainer* pContainer = GetVetoableListeners(eItem, false); 712 if (pContainer != NULL) 713 { 714 VetoableListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener)); 715 if (iListener != pContainer->end()) 716 { 717 pContainer->erase(iListener); 718 // Remove container when empty. 719 if (pContainer->empty()) 720 maVetoableListeners.erase(eItem); 721 } 722 } 723 } 724 725 726 727 728 cssu::Sequence<css::beans::Property> SAL_CALL Theme::getProperties (void) 729 throw(cssu::RuntimeException) 730 { 731 ::std::vector<beans::Property> aProperties; 732 733 for (sal_Int32 nItem(__Begin),nEnd(__End); nItem!=nEnd; ++nItem) 734 { 735 const ThemeItem eItem (static_cast<ThemeItem>(nItem)); 736 const PropertyType eType (GetPropertyType(eItem)); 737 if (eType == PT_Invalid) 738 continue; 739 740 const beans::Property aProperty( 741 maPropertyIdToNameMap[eItem], 742 eItem, 743 GetCppuType(eType), 744 0); 745 aProperties.push_back(aProperty); 746 } 747 748 return cssu::Sequence<css::beans::Property>( 749 &aProperties.front(), 750 aProperties.size()); 751 } 752 753 754 755 756 beans::Property SAL_CALL Theme::getPropertyByName (const ::rtl::OUString& rsPropertyName) 757 throw(css::beans::UnknownPropertyException, 758 cssu::RuntimeException) 759 { 760 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName)); 761 if (iId == maPropertyNameToIdMap.end()) 762 throw beans::UnknownPropertyException(); 763 764 const PropertyType eType (GetPropertyType(iId->second)); 765 if (eType == PT_Invalid) 766 throw beans::UnknownPropertyException(); 767 768 const ThemeItem eItem (iId->second); 769 770 return beans::Property( 771 rsPropertyName, 772 eItem, 773 GetCppuType(eType), 774 0); 775 } 776 777 778 779 780 sal_Bool SAL_CALL Theme::hasPropertyByName (const ::rtl::OUString& rsPropertyName) 781 throw(cssu::RuntimeException) 782 { 783 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName)); 784 if (iId == maPropertyNameToIdMap.end()) 785 return sal_False; 786 787 const PropertyType eType (GetPropertyType(iId->second)); 788 if (eType == PT_Invalid) 789 return sal_False; 790 791 return sal_True; 792 } 793 794 795 796 797 void Theme::SetupPropertyMaps (void) 798 { 799 maPropertyIdToNameMap.resize(__Post_Rect); 800 maImages.resize(__Image_Color - __Pre_Image - 1); 801 maColors.resize(__Color_Paint - __Image_Color - 1); 802 maPaints.resize(__Paint_Int - __Color_Paint - 1); 803 maIntegers.resize(__Int_Bool - __Paint_Int - 1); 804 maBooleans.resize(__Bool_Rect - __Int_Bool - 1); 805 maRectangles.resize(__Post_Rect - __Bool_Rect - 1); 806 807 #define AddEntry(e) maPropertyNameToIdMap[A2S(#e)]=e; maPropertyIdToNameMap[e]=A2S(#e) 808 809 AddEntry(Image_Grip); 810 AddEntry(Image_Expand); 811 AddEntry(Image_Collapse); 812 AddEntry(Image_TabBarMenu); 813 AddEntry(Image_PanelMenu); 814 AddEntry(Image_ToolBoxItemSeparator); 815 AddEntry(Image_Closer); 816 AddEntry(Image_CloseIndicator); 817 818 AddEntry(Color_DeckTitleFont); 819 AddEntry(Color_PanelTitleFont); 820 AddEntry(Color_TabMenuSeparator); 821 AddEntry(Color_TabItemBorder); 822 AddEntry(Color_DropDownBorder); 823 AddEntry(Color_Highlight); 824 AddEntry(Color_HighlightText); 825 826 AddEntry(Paint_DeckBackground); 827 AddEntry(Paint_DeckTitleBarBackground); 828 AddEntry(Paint_PanelBackground); 829 AddEntry(Paint_PanelTitleBarBackground); 830 AddEntry(Paint_TabBarBackground); 831 AddEntry(Paint_TabItemBackgroundNormal); 832 AddEntry(Paint_TabItemBackgroundHighlight); 833 AddEntry(Paint_HorizontalBorder); 834 AddEntry(Paint_VerticalBorder); 835 AddEntry(Paint_ToolBoxBackground); 836 AddEntry(Paint_ToolBoxBorderTopLeft); 837 AddEntry(Paint_ToolBoxBorderCenterCorners); 838 AddEntry(Paint_ToolBoxBorderBottomRight); 839 AddEntry(Paint_DropDownBackground); 840 841 AddEntry(Int_DeckTitleBarHeight); 842 AddEntry(Int_DeckBorderSize); 843 AddEntry(Int_DeckSeparatorHeight); 844 AddEntry(Int_PanelTitleBarHeight); 845 AddEntry(Int_TabMenuPadding); 846 AddEntry(Int_TabMenuSeparatorPadding); 847 AddEntry(Int_TabItemWidth); 848 AddEntry(Int_TabItemHeight); 849 AddEntry(Int_DeckLeftPadding); 850 AddEntry(Int_DeckTopPadding); 851 AddEntry(Int_DeckRightPadding); 852 AddEntry(Int_DeckBottomPadding); 853 AddEntry(Int_TabBarLeftPadding); 854 AddEntry(Int_TabBarTopPadding); 855 AddEntry(Int_TabBarRightPadding); 856 AddEntry(Int_TabBarBottomPadding); 857 AddEntry(Int_ButtonCornerRadius); 858 859 AddEntry(Bool_UseSymphonyIcons); 860 AddEntry(Bool_UseSystemColors); 861 AddEntry(Bool_UseToolBoxItemSeparator); 862 AddEntry(Bool_IsHighContrastModeActive); 863 864 AddEntry(Rect_ToolBoxPadding); 865 AddEntry(Rect_ToolBoxBorder); 866 867 #undef AddEntry 868 869 maRawValues.resize(maPropertyIdToNameMap.size()); 870 } 871 872 873 874 875 Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem) 876 { 877 switch(eItem) 878 { 879 case Image_Grip: 880 case Image_Expand: 881 case Image_Collapse: 882 case Image_TabBarMenu: 883 case Image_PanelMenu: 884 case Image_ToolBoxItemSeparator: 885 case Image_Closer: 886 case Image_CloseIndicator: 887 return PT_Image; 888 889 case Color_DeckTitleFont: 890 case Color_PanelTitleFont: 891 case Color_TabMenuSeparator: 892 case Color_TabItemBorder: 893 case Color_DropDownBorder: 894 case Color_Highlight: 895 case Color_HighlightText: 896 return PT_Color; 897 898 case Paint_DeckBackground: 899 case Paint_DeckTitleBarBackground: 900 case Paint_PanelBackground: 901 case Paint_PanelTitleBarBackground: 902 case Paint_TabBarBackground: 903 case Paint_TabItemBackgroundNormal: 904 case Paint_TabItemBackgroundHighlight: 905 case Paint_HorizontalBorder: 906 case Paint_VerticalBorder: 907 case Paint_ToolBoxBackground: 908 case Paint_ToolBoxBorderTopLeft: 909 case Paint_ToolBoxBorderCenterCorners: 910 case Paint_ToolBoxBorderBottomRight: 911 case Paint_DropDownBackground: 912 return PT_Paint; 913 914 case Int_DeckTitleBarHeight: 915 case Int_DeckBorderSize: 916 case Int_DeckSeparatorHeight: 917 case Int_PanelTitleBarHeight: 918 case Int_TabMenuPadding: 919 case Int_TabMenuSeparatorPadding: 920 case Int_TabItemWidth: 921 case Int_TabItemHeight: 922 case Int_DeckLeftPadding: 923 case Int_DeckTopPadding: 924 case Int_DeckRightPadding: 925 case Int_DeckBottomPadding: 926 case Int_TabBarLeftPadding: 927 case Int_TabBarTopPadding: 928 case Int_TabBarRightPadding: 929 case Int_TabBarBottomPadding: 930 case Int_ButtonCornerRadius: 931 return PT_Integer; 932 933 case Bool_UseSymphonyIcons: 934 case Bool_UseSystemColors: 935 case Bool_UseToolBoxItemSeparator: 936 case Bool_IsHighContrastModeActive: 937 return PT_Boolean; 938 939 case Rect_ToolBoxBorder: 940 case Rect_ToolBoxPadding: 941 return PT_Rectangle; 942 943 default: 944 return PT_Invalid; 945 } 946 } 947 948 949 950 951 cssu::Type Theme::GetCppuType (const PropertyType eType) 952 { 953 switch(eType) 954 { 955 case PT_Image: 956 return getCppuType((rtl::OUString*)NULL); 957 958 case PT_Color: 959 return getCppuType((sal_uInt32*)NULL); 960 961 case PT_Paint: 962 return getCppuVoidType(); 963 964 case PT_Integer: 965 return getCppuType((sal_Int32*)NULL); 966 967 case PT_Boolean: 968 return getCppuType((sal_Bool*)NULL); 969 970 case PT_Rectangle: 971 return getCppuType((awt::Rectangle*)NULL); 972 973 case PT_Invalid: 974 default: 975 return getCppuVoidType(); 976 } 977 } 978 979 980 981 982 sal_Int32 Theme::GetIndex (const ThemeItem eItem, const PropertyType eType) 983 { 984 switch(eType) 985 { 986 case PT_Image: 987 return eItem - __Pre_Image-1; 988 case PT_Color: 989 return eItem - __Image_Color-1; 990 case PT_Paint: 991 return eItem - __Color_Paint-1; 992 case PT_Integer: 993 return eItem - __Paint_Int-1; 994 case PT_Boolean: 995 return eItem - __Int_Bool-1; 996 case PT_Rectangle: 997 return eItem - __Bool_Rect-1; 998 999 default: 1000 OSL_ASSERT(false); 1001 return 0; 1002 } 1003 } 1004 1005 1006 1007 1008 Theme::VetoableListenerContainer* Theme::GetVetoableListeners ( 1009 const ThemeItem eItem, 1010 const bool bCreate) 1011 { 1012 VetoableListeners::iterator iContainer (maVetoableListeners.find(eItem)); 1013 if (iContainer != maVetoableListeners.end()) 1014 return &iContainer->second; 1015 else if (bCreate) 1016 { 1017 maVetoableListeners[eItem] = VetoableListenerContainer(); 1018 return &maVetoableListeners[eItem]; 1019 } 1020 else 1021 return NULL; 1022 } 1023 1024 1025 1026 1027 Theme::ChangeListenerContainer* Theme::GetChangeListeners ( 1028 const ThemeItem eItem, 1029 const bool bCreate) 1030 { 1031 ChangeListeners::iterator iContainer (maChangeListeners.find(eItem)); 1032 if (iContainer != maChangeListeners.end()) 1033 return &iContainer->second; 1034 else if (bCreate) 1035 { 1036 maChangeListeners[eItem] = ChangeListenerContainer(); 1037 return &maChangeListeners[eItem]; 1038 } 1039 else 1040 return NULL; 1041 } 1042 1043 1044 1045 1046 bool Theme::DoVetoableListenersVeto ( 1047 const VetoableListenerContainer* pListeners, 1048 const beans::PropertyChangeEvent& rEvent) const 1049 { 1050 if (pListeners == NULL) 1051 return false; 1052 1053 VetoableListenerContainer aListeners (*pListeners); 1054 try 1055 { 1056 for (VetoableListenerContainer::const_iterator 1057 iListener(aListeners.begin()), 1058 iEnd(aListeners.end()); 1059 iListener!=iEnd; 1060 ++iListener) 1061 { 1062 (*iListener)->vetoableChange(rEvent); 1063 } 1064 } 1065 catch(const beans::PropertyVetoException&) 1066 { 1067 return true; 1068 } 1069 catch(const Exception&) 1070 { 1071 // Ignore any other errors (such as disposed listeners). 1072 } 1073 return false; 1074 } 1075 1076 1077 1078 1079 void Theme::BroadcastPropertyChange ( 1080 const ChangeListenerContainer* pListeners, 1081 const beans::PropertyChangeEvent& rEvent) const 1082 { 1083 if (pListeners == NULL) 1084 return; 1085 1086 const ChangeListenerContainer aListeners (*pListeners); 1087 try 1088 { 1089 for (ChangeListenerContainer::const_iterator 1090 iListener(aListeners.begin()), 1091 iEnd(aListeners.end()); 1092 iListener!=iEnd; 1093 ++iListener) 1094 { 1095 (*iListener)->propertyChange(rEvent); 1096 } 1097 } 1098 catch(const Exception&) 1099 { 1100 // Ignore any errors (such as disposed listeners). 1101 } 1102 } 1103 1104 1105 1106 1107 void Theme::ProcessNewValue ( 1108 const Any& rValue, 1109 const ThemeItem eItem, 1110 const PropertyType eType) 1111 { 1112 const sal_Int32 nIndex (GetIndex (eItem, eType)); 1113 switch (eType) 1114 { 1115 case PT_Image: 1116 { 1117 ::rtl::OUString sURL; 1118 if (rValue >>= sURL) 1119 { 1120 maImages[nIndex] = Tools::GetImage(sURL, NULL); 1121 } 1122 break; 1123 } 1124 case PT_Color: 1125 { 1126 sal_Int32 nColorValue (0); 1127 if (rValue >>= nColorValue) 1128 { 1129 maColors[nIndex] = Color(nColorValue); 1130 } 1131 break; 1132 } 1133 case PT_Paint: 1134 { 1135 maPaints[nIndex] = Paint::Create(rValue); 1136 break; 1137 } 1138 case PT_Integer: 1139 { 1140 sal_Int32 nValue (0); 1141 if (rValue >>= nValue) 1142 { 1143 maIntegers[nIndex] = nValue; 1144 } 1145 break; 1146 } 1147 case PT_Boolean: 1148 { 1149 sal_Bool nValue (0); 1150 if (rValue >>= nValue) 1151 { 1152 maBooleans[nIndex] = (nValue==sal_True); 1153 if (eItem == Bool_IsHighContrastModeActive) 1154 { 1155 mbIsHighContrastModeSetManually = true; 1156 mbIsHighContrastMode = maBooleans[nIndex]; 1157 HandleDataChange(); 1158 } 1159 else if (eItem == Bool_UseSystemColors) 1160 { 1161 HandleDataChange(); 1162 } 1163 } 1164 break; 1165 } 1166 case PT_Rectangle: 1167 { 1168 awt::Rectangle aBox; 1169 if (rValue >>= aBox) 1170 { 1171 maRectangles[nIndex] = Rectangle( 1172 aBox.X, 1173 aBox.Y, 1174 aBox.Width, 1175 aBox.Height); 1176 } 1177 break; 1178 } 1179 case PT_Invalid: 1180 OSL_ASSERT(eType != PT_Invalid); 1181 throw RuntimeException(); 1182 } 1183 } 1184 1185 1186 1187 1188 } } // end of namespace sfx2::sidebar 1189