xref: /trunk/main/sfx2/source/sidebar/Theme.cxx (revision 38b885b74d08288e2136f990676957bd24aa340d)
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     throw(cssu::RuntimeException)
470 {
471     return Reference<beans::XPropertySetInfo>(this);
472 }
473 
setPropertyValue(const::rtl::OUString & rsPropertyName,const cssu::Any & rValue)474 void SAL_CALL Theme::setPropertyValue (
475     const ::rtl::OUString& rsPropertyName,
476     const cssu::Any& rValue)
477     throw(cssu::RuntimeException)
478 {
479     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
480     if (iId == maPropertyNameToIdMap.end())
481         throw beans::UnknownPropertyException(rsPropertyName, NULL);
482 
483     const PropertyType eType (GetPropertyType(iId->second));
484     if (eType == PT_Invalid)
485         throw beans::UnknownPropertyException(rsPropertyName, NULL);
486 
487     const ThemeItem eItem (iId->second);
488 
489     if (rValue == maRawValues[eItem])
490     {
491         // Value is not different from the one in the property
492         // set => nothing to do.
493         return;
494     }
495 
496     const Any aOldValue (maRawValues[eItem]);
497 
498     const beans::PropertyChangeEvent aEvent(
499         static_cast<XWeak*>(this),
500         rsPropertyName,
501         sal_False,
502         eItem,
503         aOldValue,
504         rValue);
505 
506     if (DoVetoableListenersVeto(GetVetoableListeners(__AnyItem, false), aEvent))
507         return;
508     if (DoVetoableListenersVeto(GetVetoableListeners(eItem, false), aEvent))
509         return;
510 
511     maRawValues[eItem] = rValue;
512     ProcessNewValue(rValue, eItem, eType);
513 
514     BroadcastPropertyChange(GetChangeListeners(__AnyItem, false), aEvent);
515     BroadcastPropertyChange(GetChangeListeners(eItem, false), aEvent);
516 }
517 
getPropertyValue(const::rtl::OUString & rsPropertyName)518 Any SAL_CALL Theme::getPropertyValue (
519     const ::rtl::OUString& rsPropertyName)
520     throw(css::beans::UnknownPropertyException,
521         css::lang::WrappedTargetException,
522         cssu::RuntimeException)
523 {
524     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
525     if (iId == maPropertyNameToIdMap.end())
526         throw beans::UnknownPropertyException();
527 
528     const PropertyType eType (GetPropertyType(iId->second));
529     if (eType == PT_Invalid)
530         throw beans::UnknownPropertyException();
531 
532     const ThemeItem eItem (iId->second);
533 
534     return maRawValues[eItem];
535 }
536 
addPropertyChangeListener(const::rtl::OUString & rsPropertyName,const cssu::Reference<css::beans::XPropertyChangeListener> & rxListener)537 void SAL_CALL Theme::addPropertyChangeListener(
538     const ::rtl::OUString& rsPropertyName,
539     const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener)
540     throw(css::beans::UnknownPropertyException,
541         css::lang::WrappedTargetException,
542         cssu::RuntimeException)
543 {
544     ThemeItem eItem (__AnyItem);
545     if (rsPropertyName.getLength() > 0)
546     {
547         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
548         if (iId == maPropertyNameToIdMap.end())
549             throw beans::UnknownPropertyException();
550 
551         const PropertyType eType (GetPropertyType(iId->second));
552         if (eType == PT_Invalid)
553             throw beans::UnknownPropertyException();
554 
555         eItem = iId->second;
556     }
557     ChangeListenerContainer* pListeners = GetChangeListeners(eItem, true);
558     if (pListeners != NULL)
559         pListeners->push_back(rxListener);
560 }
561 
removePropertyChangeListener(const::rtl::OUString & rsPropertyName,const cssu::Reference<css::beans::XPropertyChangeListener> & rxListener)562 void SAL_CALL Theme::removePropertyChangeListener(
563     const ::rtl::OUString& rsPropertyName,
564     const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener)
565     throw(css::beans::UnknownPropertyException,
566         css::lang::WrappedTargetException,
567         cssu::RuntimeException)
568 {
569     ThemeItem eItem (__AnyItem);
570     if (rsPropertyName.getLength() > 0)
571     {
572         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
573         if (iId == maPropertyNameToIdMap.end())
574             throw beans::UnknownPropertyException();
575 
576         const PropertyType eType (GetPropertyType(iId->second));
577         if (eType == PT_Invalid)
578             throw beans::UnknownPropertyException();
579 
580         eItem = iId->second;
581     }
582     ChangeListenerContainer* pContainer = GetChangeListeners(eItem, false);
583     if (pContainer != NULL)
584     {
585         ChangeListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
586         if (iListener != pContainer->end())
587         {
588             pContainer->erase(iListener);
589 
590             // Remove the listener container when empty.
591             if (pContainer->empty())
592                 maChangeListeners.erase(eItem);
593         }
594     }
595 }
596 
addVetoableChangeListener(const::rtl::OUString & rsPropertyName,const cssu::Reference<css::beans::XVetoableChangeListener> & rxListener)597 void SAL_CALL Theme::addVetoableChangeListener(
598     const ::rtl::OUString& rsPropertyName,
599     const cssu::Reference<css::beans::XVetoableChangeListener>& 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     VetoableListenerContainer* pListeners = GetVetoableListeners(eItem, true);
618     if (pListeners != NULL)
619         pListeners->push_back(rxListener);
620 }
621 
removeVetoableChangeListener(const::rtl::OUString & rsPropertyName,const cssu::Reference<css::beans::XVetoableChangeListener> & rxListener)622 void SAL_CALL Theme::removeVetoableChangeListener(
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* pContainer = GetVetoableListeners(eItem, false);
643     if (pContainer != NULL)
644     {
645         VetoableListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
646         if (iListener != pContainer->end())
647         {
648             pContainer->erase(iListener);
649             // Remove container when empty.
650             if (pContainer->empty())
651                 maVetoableListeners.erase(eItem);
652         }
653     }
654 }
655 
getProperties(void)656 cssu::Sequence<css::beans::Property> SAL_CALL Theme::getProperties (void)
657     throw(cssu::RuntimeException)
658 {
659     ::std::vector<beans::Property> aProperties;
660 
661     for (sal_Int32 nItem(__Begin),nEnd(__End); nItem!=nEnd; ++nItem)
662     {
663         const ThemeItem eItem (static_cast<ThemeItem>(nItem));
664         const PropertyType eType (GetPropertyType(eItem));
665         if (eType == PT_Invalid)
666             continue;
667 
668         const beans::Property aProperty(
669             maPropertyIdToNameMap[eItem],
670             eItem,
671             GetCppuType(eType),
672             0);
673         aProperties.push_back(aProperty);
674     }
675 
676     return cssu::Sequence<css::beans::Property>(
677         &aProperties.front(),
678         aProperties.size());
679 }
680 
getPropertyByName(const::rtl::OUString & rsPropertyName)681 beans::Property SAL_CALL Theme::getPropertyByName (const ::rtl::OUString& rsPropertyName)
682     throw(css::beans::UnknownPropertyException,
683         cssu::RuntimeException)
684 {
685     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
686     if (iId == maPropertyNameToIdMap.end())
687         throw beans::UnknownPropertyException();
688 
689     const PropertyType eType (GetPropertyType(iId->second));
690     if (eType == PT_Invalid)
691         throw beans::UnknownPropertyException();
692 
693     const ThemeItem eItem (iId->second);
694 
695     return beans::Property(
696         rsPropertyName,
697         eItem,
698         GetCppuType(eType),
699         0);
700 }
701 
hasPropertyByName(const::rtl::OUString & rsPropertyName)702 sal_Bool SAL_CALL Theme::hasPropertyByName (const ::rtl::OUString& rsPropertyName)
703     throw(cssu::RuntimeException)
704 {
705     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
706     if (iId == maPropertyNameToIdMap.end())
707         return sal_False;
708 
709     const PropertyType eType (GetPropertyType(iId->second));
710     if (eType == PT_Invalid)
711         return sal_False;
712 
713     return sal_True;
714 }
715 
SetupPropertyMaps(void)716 void Theme::SetupPropertyMaps (void)
717 {
718     maPropertyIdToNameMap.resize(__Post_Rect);
719     maImages.resize(__Image_Color - __Pre_Image - 1);
720     maColors.resize(__Color_Paint - __Image_Color - 1);
721     maPaints.resize(__Paint_Int - __Color_Paint - 1);
722     maIntegers.resize(__Int_Bool - __Paint_Int - 1);
723     maBooleans.resize(__Bool_Rect - __Int_Bool - 1);
724     maRectangles.resize(__Post_Rect - __Bool_Rect - 1);
725 
726     #define AddEntry(e) maPropertyNameToIdMap[A2S(#e)]=e; maPropertyIdToNameMap[e]=A2S(#e)
727 
728     AddEntry(Image_Grip);
729     AddEntry(Image_Expand);
730     AddEntry(Image_Collapse);
731     AddEntry(Image_TabBarMenu);
732     AddEntry(Image_PanelMenu);
733     AddEntry(Image_ToolBoxItemSeparator);
734     AddEntry(Image_Closer);
735     AddEntry(Image_CloseIndicator);
736 
737     AddEntry(Color_DeckTitleFont);
738     AddEntry(Color_PanelTitleFont);
739     AddEntry(Color_TabMenuSeparator);
740     AddEntry(Color_TabItemBorder);
741     AddEntry(Color_DropDownBorder);
742     AddEntry(Color_Highlight);
743     AddEntry(Color_HighlightText);
744 
745     AddEntry(Paint_DeckBackground);
746     AddEntry(Paint_DeckTitleBarBackground);
747     AddEntry(Paint_PanelBackground);
748     AddEntry(Paint_PanelTitleBarBackground);
749     AddEntry(Paint_TabBarBackground);
750     AddEntry(Paint_TabItemBackgroundNormal);
751     AddEntry(Paint_TabItemBackgroundHighlight);
752     AddEntry(Paint_HorizontalBorder);
753     AddEntry(Paint_VerticalBorder);
754     AddEntry(Paint_ToolBoxBackground);
755     AddEntry(Paint_ToolBoxBorderTopLeft);
756     AddEntry(Paint_ToolBoxBorderCenterCorners);
757     AddEntry(Paint_ToolBoxBorderBottomRight);
758     AddEntry(Paint_DropDownBackground);
759 
760     AddEntry(Int_DeckTitleBarHeight);
761     AddEntry(Int_DeckBorderSize);
762     AddEntry(Int_DeckSeparatorHeight);
763     AddEntry(Int_PanelTitleBarHeight);
764     AddEntry(Int_TabMenuPadding);
765     AddEntry(Int_TabMenuSeparatorPadding);
766     AddEntry(Int_TabItemWidth);
767     AddEntry(Int_TabItemHeight);
768     AddEntry(Int_DeckLeftPadding);
769     AddEntry(Int_DeckTopPadding);
770     AddEntry(Int_DeckRightPadding);
771     AddEntry(Int_DeckBottomPadding);
772     AddEntry(Int_TabBarLeftPadding);
773     AddEntry(Int_TabBarTopPadding);
774     AddEntry(Int_TabBarRightPadding);
775     AddEntry(Int_TabBarBottomPadding);
776     AddEntry(Int_ButtonCornerRadius);
777 
778     AddEntry(Bool_UseSymphonyIcons);
779     AddEntry(Bool_UseSystemColors);
780     AddEntry(Bool_UseToolBoxItemSeparator);
781     AddEntry(Bool_IsHighContrastModeActive);
782 
783     AddEntry(Rect_ToolBoxPadding);
784     AddEntry(Rect_ToolBoxBorder);
785 
786     #undef AddEntry
787 
788     maRawValues.resize(maPropertyIdToNameMap.size());
789 }
790 
GetPropertyType(const ThemeItem eItem)791 Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem)
792 {
793     switch(eItem)
794     {
795         case Image_Grip:
796         case Image_Expand:
797         case Image_Collapse:
798         case Image_TabBarMenu:
799         case Image_PanelMenu:
800         case Image_ToolBoxItemSeparator:
801         case Image_Closer:
802         case Image_CloseIndicator:
803             return PT_Image;
804 
805         case Color_DeckTitleFont:
806         case Color_PanelTitleFont:
807         case Color_TabMenuSeparator:
808         case Color_TabItemBorder:
809         case Color_DropDownBorder:
810         case Color_Highlight:
811         case Color_HighlightText:
812             return PT_Color;
813 
814         case Paint_DeckBackground:
815         case Paint_DeckTitleBarBackground:
816         case Paint_PanelBackground:
817         case Paint_PanelTitleBarBackground:
818         case Paint_TabBarBackground:
819         case Paint_TabItemBackgroundNormal:
820         case Paint_TabItemBackgroundHighlight:
821         case Paint_HorizontalBorder:
822         case Paint_VerticalBorder:
823         case Paint_ToolBoxBackground:
824         case Paint_ToolBoxBorderTopLeft:
825         case Paint_ToolBoxBorderCenterCorners:
826         case Paint_ToolBoxBorderBottomRight:
827         case Paint_DropDownBackground:
828             return PT_Paint;
829 
830         case Int_DeckTitleBarHeight:
831         case Int_DeckBorderSize:
832         case Int_DeckSeparatorHeight:
833         case Int_PanelTitleBarHeight:
834         case Int_TabMenuPadding:
835         case Int_TabMenuSeparatorPadding:
836         case Int_TabItemWidth:
837         case Int_TabItemHeight:
838         case Int_DeckLeftPadding:
839         case Int_DeckTopPadding:
840         case Int_DeckRightPadding:
841         case Int_DeckBottomPadding:
842         case Int_TabBarLeftPadding:
843         case Int_TabBarTopPadding:
844         case Int_TabBarRightPadding:
845         case Int_TabBarBottomPadding:
846         case Int_ButtonCornerRadius:
847             return PT_Integer;
848 
849         case Bool_UseSymphonyIcons:
850         case Bool_UseSystemColors:
851         case Bool_UseToolBoxItemSeparator:
852         case Bool_IsHighContrastModeActive:
853             return PT_Boolean;
854 
855         case Rect_ToolBoxBorder:
856         case Rect_ToolBoxPadding:
857             return PT_Rectangle;
858 
859         default:
860             return PT_Invalid;
861     }
862 }
863 
GetCppuType(const PropertyType eType)864 cssu::Type Theme::GetCppuType (const PropertyType eType)
865 {
866     switch(eType)
867     {
868         case PT_Image:
869             return getCppuType((rtl::OUString*)NULL);
870 
871         case PT_Color:
872             return getCppuType((sal_uInt32*)NULL);
873 
874         case PT_Paint:
875             return getCppuVoidType();
876 
877         case PT_Integer:
878             return getCppuType((sal_Int32*)NULL);
879 
880         case PT_Boolean:
881             return getCppuType((sal_Bool*)NULL);
882 
883         case PT_Rectangle:
884             return getCppuType((awt::Rectangle*)NULL);
885 
886         case PT_Invalid:
887         default:
888             return getCppuVoidType();
889     }
890 }
891 
GetIndex(const ThemeItem eItem,const PropertyType eType)892 sal_Int32 Theme::GetIndex (const ThemeItem eItem, const PropertyType eType)
893 {
894     switch(eType)
895     {
896         case PT_Image:
897             return eItem - __Pre_Image-1;
898         case PT_Color:
899             return eItem - __Image_Color-1;
900         case PT_Paint:
901             return eItem - __Color_Paint-1;
902         case PT_Integer:
903             return eItem - __Paint_Int-1;
904         case PT_Boolean:
905             return eItem - __Int_Bool-1;
906         case PT_Rectangle:
907             return eItem - __Bool_Rect-1;
908 
909         default:
910             OSL_ASSERT(false);
911             return 0;
912     }
913 }
914 
GetVetoableListeners(const ThemeItem eItem,const bool bCreate)915 Theme::VetoableListenerContainer* Theme::GetVetoableListeners (
916     const ThemeItem eItem,
917     const bool bCreate)
918 {
919     VetoableListeners::iterator iContainer (maVetoableListeners.find(eItem));
920     if (iContainer != maVetoableListeners.end())
921         return &iContainer->second;
922     else if (bCreate)
923     {
924         maVetoableListeners[eItem] = VetoableListenerContainer();
925         return &maVetoableListeners[eItem];
926     }
927     else
928         return NULL;
929 }
930 
GetChangeListeners(const ThemeItem eItem,const bool bCreate)931 Theme::ChangeListenerContainer* Theme::GetChangeListeners (
932     const ThemeItem eItem,
933     const bool bCreate)
934 {
935     ChangeListeners::iterator iContainer (maChangeListeners.find(eItem));
936     if (iContainer != maChangeListeners.end())
937         return &iContainer->second;
938     else if (bCreate)
939     {
940         maChangeListeners[eItem] = ChangeListenerContainer();
941         return &maChangeListeners[eItem];
942     }
943     else
944         return NULL;
945 }
946 
DoVetoableListenersVeto(const VetoableListenerContainer * pListeners,const beans::PropertyChangeEvent & rEvent) const947 bool Theme::DoVetoableListenersVeto (
948     const VetoableListenerContainer* pListeners,
949     const beans::PropertyChangeEvent& rEvent) const
950 {
951     if (pListeners == NULL)
952         return false;
953 
954     VetoableListenerContainer aListeners (*pListeners);
955     try
956     {
957         for (VetoableListenerContainer::const_iterator
958                  iListener(aListeners.begin()),
959                  iEnd(aListeners.end());
960              iListener!=iEnd;
961              ++iListener)
962         {
963             (*iListener)->vetoableChange(rEvent);
964         }
965     }
966     catch(const beans::PropertyVetoException&)
967     {
968         return true;
969     }
970     catch(const Exception&)
971     {
972         // Ignore any other errors (such as disposed listeners).
973     }
974     return false;
975 }
976 
BroadcastPropertyChange(const ChangeListenerContainer * pListeners,const beans::PropertyChangeEvent & rEvent) const977 void Theme::BroadcastPropertyChange (
978     const ChangeListenerContainer* pListeners,
979     const beans::PropertyChangeEvent& rEvent) const
980 {
981     if (pListeners == NULL)
982         return;
983 
984     const ChangeListenerContainer aListeners (*pListeners);
985     try
986     {
987         for (ChangeListenerContainer::const_iterator
988                  iListener(aListeners.begin()),
989                  iEnd(aListeners.end());
990              iListener!=iEnd;
991              ++iListener)
992         {
993             (*iListener)->propertyChange(rEvent);
994         }
995     }
996     catch(const Exception&)
997     {
998         // Ignore any errors (such as disposed listeners).
999     }
1000 }
1001 
ProcessNewValue(const Any & rValue,const ThemeItem eItem,const PropertyType eType)1002 void Theme::ProcessNewValue (
1003     const Any& rValue,
1004     const ThemeItem eItem,
1005     const PropertyType eType)
1006 {
1007     const sal_Int32 nIndex (GetIndex (eItem, eType));
1008     switch (eType)
1009     {
1010         case PT_Image:
1011         {
1012             ::rtl::OUString sURL;
1013             if (rValue >>= sURL)
1014             {
1015                 maImages[nIndex] = Tools::GetImage(sURL, NULL);
1016             }
1017             break;
1018         }
1019         case PT_Color:
1020         {
1021             sal_Int32 nColorValue (0);
1022             if (rValue >>= nColorValue)
1023             {
1024                 maColors[nIndex] = Color(nColorValue);
1025             }
1026             break;
1027         }
1028         case PT_Paint:
1029         {
1030             maPaints[nIndex] = Paint::Create(rValue);
1031             break;
1032         }
1033         case PT_Integer:
1034         {
1035             sal_Int32 nValue (0);
1036             if (rValue >>= nValue)
1037             {
1038                 maIntegers[nIndex] = nValue;
1039             }
1040             break;
1041         }
1042         case PT_Boolean:
1043         {
1044             sal_Bool nValue (0);
1045             if (rValue >>= nValue)
1046             {
1047                 maBooleans[nIndex] = (nValue==sal_True);
1048                 if (eItem == Bool_IsHighContrastModeActive)
1049                 {
1050                     mbIsHighContrastModeSetManually = true;
1051                     mbIsHighContrastMode = maBooleans[nIndex];
1052                     HandleDataChange();
1053                 }
1054                 else if (eItem == Bool_UseSystemColors)
1055                 {
1056                     HandleDataChange();
1057                 }
1058             }
1059             break;
1060         }
1061         case PT_Rectangle:
1062         {
1063             awt::Rectangle aBox;
1064             if (rValue >>= aBox)
1065             {
1066                 maRectangles[nIndex] = Rectangle(
1067                     aBox.X,
1068                     aBox.Y,
1069                     aBox.Width,
1070                     aBox.Height);
1071             }
1072             break;
1073         }
1074         case PT_Invalid:
1075             OSL_ASSERT(eType != PT_Invalid);
1076             throw RuntimeException();
1077     }
1078 }
1079 
1080 } } // end of namespace sfx2::sidebar
1081 
1082 /* vim: set noet sw=4 ts=4: */
1083