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