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