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