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