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