xref: /trunk/main/sfx2/source/sidebar/Theme.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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