xref: /aoo41x/main/sfx2/source/sidebar/Theme.cxx (revision 2b6825c7)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include "precompiled_sfx2.hxx"
23 
24 #include "sfx2/sidebar/Theme.hxx"
25 #include "Paint.hxx"
26 #include "SidebarResource.hxx"
27 #include "sfx2/sidebar/Tools.hxx"
28 
29 #include <tools/svborder.hxx>
30 #include <tools/rc.hxx>
31 #include <vcl/svapp.hxx>
32 
33 using namespace css;
34 using namespace cssu;
35 
36 
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_CloseIndicator],
389             Any(
390                 mbIsHighContrastMode
391                     ? A2S("private:graphicrepository/res/commandimagelist/lch_decrementlevel.png")
392                     : A2S("private:graphicrepository/res/commandimagelist/lc_decrementlevel.png")));
393         setPropertyValue(
394             maPropertyIdToNameMap[Image_ToolBoxItemSeparator],
395             Any(
396                 A2S("private:graphicrepository/sfx2/res/separator.png")));
397 
398         // ToolBox
399 
400         /*
401         // Separator style
402         setPropertyValue(
403             maPropertyIdToNameMap[Paint_ToolBoxBackground],
404             Any(sal_Int32(rStyle.GetMenuColor().GetRGBColor())));
405         setPropertyValue(
406             maPropertyIdToNameMap[Paint_ToolBoxBorderTopLeft],
407             Any());
408         setPropertyValue(
409             maPropertyIdToNameMap[Paint_ToolBoxBorderCenterCorners],
410             Any());
411         setPropertyValue(
412             maPropertyIdToNameMap[Paint_ToolBoxBorderBottomRight],
413             Any());
414         setPropertyValue(
415             maPropertyIdToNameMap[Rect_ToolBoxPadding],
416             Any(awt::Rectangle(2,2,2,2)));
417         setPropertyValue(
418             maPropertyIdToNameMap[Rect_ToolBoxBorder],
419             Any(awt::Rectangle(0,0,0,0)));
420         setPropertyValue(
421             maPropertyIdToNameMap[Bool_UseToolBoxItemSeparator],
422             Any(true));
423 
424         */
425 
426         // Gradient style
427         Color aGradientStop2 (aBaseBackgroundColor);
428         aGradientStop2.IncreaseLuminance(17);
429         Color aToolBoxBorderColor (aBaseBackgroundColor);
430         aToolBoxBorderColor.DecreaseLuminance(12);
431         setPropertyValue(
432             maPropertyIdToNameMap[Paint_ToolBoxBackground],
433             Any(Tools::VclToAwtGradient(Gradient(
434                         GRADIENT_LINEAR,
435                         aBaseBackgroundColor.GetRGBColor(),
436                         aGradientStop2.GetRGBColor()
437                         ))));
438         setPropertyValue(
439             maPropertyIdToNameMap[Paint_ToolBoxBorderTopLeft],
440             mbIsHighContrastMode
441                 ? Any(util::Color(sal_uInt32(0x00ff00)))
442                 : Any(util::Color(aToolBoxBorderColor.GetRGBColor())));
443         setPropertyValue(
444             maPropertyIdToNameMap[Paint_ToolBoxBorderCenterCorners],
445             mbIsHighContrastMode
446                 ? Any(util::Color(sal_uInt32(0x00ff00)))
447                 : Any(util::Color(aToolBoxBorderColor.GetRGBColor())));
448         setPropertyValue(
449             maPropertyIdToNameMap[Paint_ToolBoxBorderBottomRight],
450             mbIsHighContrastMode
451                 ? Any(util::Color(sal_uInt32(0x00ff00)))
452                 : Any(util::Color(aToolBoxBorderColor.GetRGBColor())));
453         setPropertyValue(
454             maPropertyIdToNameMap[Rect_ToolBoxPadding],
455             Any(awt::Rectangle(2,2,2,2)));
456         setPropertyValue(
457             maPropertyIdToNameMap[Rect_ToolBoxBorder],
458             Any(awt::Rectangle(1,1,1,1)));
459         setPropertyValue(
460             maPropertyIdToNameMap[Bool_UseToolBoxItemSeparator],
461             Any(false));
462     }
463     catch(beans::UnknownPropertyException& rException)
464     {
465         OSL_TRACE("unknown property: %s",
466             OUStringToOString(
467                 rException.Message,
468                 RTL_TEXTENCODING_ASCII_US).getStr());
469         OSL_ASSERT(false);
470     }
471 }
472 
473 
474 
475 
476 void SAL_CALL Theme::disposing (void)
477 {
478     ChangeListeners aListeners;
479     maChangeListeners.swap(aListeners);
480 
481     const lang::EventObject aEvent (static_cast<XWeak*>(this));
482 
483     for (ChangeListeners::const_iterator
484              iContainer(maChangeListeners.begin()),
485              iContainerEnd(maChangeListeners.end());
486          iContainerEnd!=iContainerEnd;
487          ++iContainerEnd)
488     {
489         for (ChangeListenerContainer::const_iterator
490                  iListener(iContainer->second.begin()),
491                  iEnd(iContainer->second.end());
492              iListener!=iEnd;
493              ++iListener)
494         {
495             try
496             {
497                 (*iListener)->disposing(aEvent);
498             }
499             catch(const Exception&)
500             {
501             }
502         }
503     }
504 }
505 
506 
507 
508 
509 Reference<beans::XPropertySet> Theme::GetPropertySet (void)
510 {
511     return Reference<beans::XPropertySet>(static_cast<XWeak*>(&GetCurrentTheme()), UNO_QUERY);
512 }
513 
514 
515 
516 
517 Reference<beans::XPropertySetInfo> SAL_CALL Theme::getPropertySetInfo (void)
518     throw(cssu::RuntimeException)
519 {
520     return Reference<beans::XPropertySetInfo>(this);
521 }
522 
523 
524 
525 
526 void SAL_CALL Theme::setPropertyValue (
527     const ::rtl::OUString& rsPropertyName,
528     const cssu::Any& rValue)
529     throw(cssu::RuntimeException)
530 {
531     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
532     if (iId == maPropertyNameToIdMap.end())
533         throw beans::UnknownPropertyException(rsPropertyName, NULL);
534 
535     const PropertyType eType (GetPropertyType(iId->second));
536     if (eType == PT_Invalid)
537         throw beans::UnknownPropertyException(rsPropertyName, NULL);
538 
539     const ThemeItem eItem (iId->second);
540 
541     if (rValue == maRawValues[eItem])
542     {
543         // Value is not different from the one in the property
544         // set => nothing to do.
545         return;
546     }
547 
548     const Any aOldValue (maRawValues[eItem]);
549 
550     const beans::PropertyChangeEvent aEvent(
551         static_cast<XWeak*>(this),
552         rsPropertyName,
553         sal_False,
554         eItem,
555         aOldValue,
556         rValue);
557 
558     if (DoVetoableListenersVeto(GetVetoableListeners(__AnyItem, false), aEvent))
559         return;
560     if (DoVetoableListenersVeto(GetVetoableListeners(eItem, false), aEvent))
561         return;
562 
563     maRawValues[eItem] = rValue;
564     ProcessNewValue(rValue, eItem, eType);
565 
566     BroadcastPropertyChange(GetChangeListeners(__AnyItem, false), aEvent);
567     BroadcastPropertyChange(GetChangeListeners(eItem, false), aEvent);
568 }
569 
570 
571 
572 
573 Any SAL_CALL Theme::getPropertyValue (
574     const ::rtl::OUString& rsPropertyName)
575     throw(css::beans::UnknownPropertyException,
576         css::lang::WrappedTargetException,
577         cssu::RuntimeException)
578 {
579     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
580     if (iId == maPropertyNameToIdMap.end())
581         throw beans::UnknownPropertyException();
582 
583     const PropertyType eType (GetPropertyType(iId->second));
584     if (eType == PT_Invalid)
585         throw beans::UnknownPropertyException();
586 
587     const ThemeItem eItem (iId->second);
588 
589     return maRawValues[eItem];
590 }
591 
592 
593 
594 
595 void SAL_CALL Theme::addPropertyChangeListener(
596     const ::rtl::OUString& rsPropertyName,
597     const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener)
598     throw(css::beans::UnknownPropertyException,
599         css::lang::WrappedTargetException,
600         cssu::RuntimeException)
601 {
602     ThemeItem eItem (__AnyItem);
603     if (rsPropertyName.getLength() > 0)
604     {
605         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
606         if (iId == maPropertyNameToIdMap.end())
607             throw beans::UnknownPropertyException();
608 
609         const PropertyType eType (GetPropertyType(iId->second));
610         if (eType == PT_Invalid)
611             throw beans::UnknownPropertyException();
612 
613         eItem = iId->second;
614     }
615     ChangeListenerContainer* pListeners = GetChangeListeners(eItem, true);
616     if (pListeners != NULL)
617         pListeners->push_back(rxListener);
618 }
619 
620 
621 
622 
623 void SAL_CALL Theme::removePropertyChangeListener(
624     const ::rtl::OUString& rsPropertyName,
625     const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener)
626     throw(css::beans::UnknownPropertyException,
627         css::lang::WrappedTargetException,
628         cssu::RuntimeException)
629 {
630     ThemeItem eItem (__AnyItem);
631     if (rsPropertyName.getLength() > 0)
632     {
633         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
634         if (iId == maPropertyNameToIdMap.end())
635             throw beans::UnknownPropertyException();
636 
637         const PropertyType eType (GetPropertyType(iId->second));
638         if (eType == PT_Invalid)
639             throw beans::UnknownPropertyException();
640 
641         eItem = iId->second;
642     }
643     ChangeListenerContainer* pContainer = GetChangeListeners(eItem, false);
644     if (pContainer != NULL)
645     {
646         ChangeListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
647         if (iListener != pContainer->end())
648         {
649             pContainer->erase(iListener);
650 
651             // Remove the listener container when empty.
652             if (pContainer->empty())
653                 maChangeListeners.erase(eItem);
654         }
655     }
656 }
657 
658 
659 
660 
661 void SAL_CALL Theme::addVetoableChangeListener(
662     const ::rtl::OUString& rsPropertyName,
663     const cssu::Reference<css::beans::XVetoableChangeListener>& rxListener)
664     throw(css::beans::UnknownPropertyException,
665         css::lang::WrappedTargetException,
666         cssu::RuntimeException)
667 {
668     ThemeItem eItem (__AnyItem);
669     if (rsPropertyName.getLength() > 0)
670     {
671         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
672         if (iId == maPropertyNameToIdMap.end())
673             throw beans::UnknownPropertyException();
674 
675         const PropertyType eType (GetPropertyType(iId->second));
676         if (eType == PT_Invalid)
677             throw beans::UnknownPropertyException();
678 
679         eItem = iId->second;
680     }
681     VetoableListenerContainer* pListeners = GetVetoableListeners(eItem, true);
682     if (pListeners != NULL)
683         pListeners->push_back(rxListener);
684 }
685 
686 
687 
688 
689 void SAL_CALL Theme::removeVetoableChangeListener(
690     const ::rtl::OUString& rsPropertyName,
691     const cssu::Reference<css::beans::XVetoableChangeListener>& rxListener)
692     throw(css::beans::UnknownPropertyException,
693         css::lang::WrappedTargetException,
694         cssu::RuntimeException)
695 {
696     ThemeItem eItem (__AnyItem);
697     if (rsPropertyName.getLength() > 0)
698     {
699         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
700         if (iId == maPropertyNameToIdMap.end())
701             throw beans::UnknownPropertyException();
702 
703         const PropertyType eType (GetPropertyType(iId->second));
704         if (eType == PT_Invalid)
705             throw beans::UnknownPropertyException();
706 
707         eItem = iId->second;
708     }
709     VetoableListenerContainer* pContainer = GetVetoableListeners(eItem, false);
710     if (pContainer != NULL)
711     {
712         VetoableListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
713         if (iListener != pContainer->end())
714         {
715             pContainer->erase(iListener);
716             // Remove container when empty.
717             if (pContainer->empty())
718                 maVetoableListeners.erase(eItem);
719         }
720     }
721 }
722 
723 
724 
725 
726 cssu::Sequence<css::beans::Property> SAL_CALL Theme::getProperties (void)
727     throw(cssu::RuntimeException)
728 {
729     ::std::vector<beans::Property> aProperties;
730 
731     for (sal_Int32 nItem(__Begin),nEnd(__End); nItem!=nEnd; ++nItem)
732     {
733         const ThemeItem eItem (static_cast<ThemeItem>(nItem));
734         const PropertyType eType (GetPropertyType(eItem));
735         if (eType == PT_Invalid)
736             continue;
737 
738         const beans::Property aProperty(
739             maPropertyIdToNameMap[eItem],
740             eItem,
741             GetCppuType(eType),
742             0);
743         aProperties.push_back(aProperty);
744     }
745 
746     return cssu::Sequence<css::beans::Property>(
747         &aProperties.front(),
748         aProperties.size());
749 }
750 
751 
752 
753 
754 beans::Property SAL_CALL Theme::getPropertyByName (const ::rtl::OUString& rsPropertyName)
755     throw(css::beans::UnknownPropertyException,
756         cssu::RuntimeException)
757 {
758     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
759     if (iId == maPropertyNameToIdMap.end())
760         throw beans::UnknownPropertyException();
761 
762     const PropertyType eType (GetPropertyType(iId->second));
763     if (eType == PT_Invalid)
764         throw beans::UnknownPropertyException();
765 
766     const ThemeItem eItem (iId->second);
767 
768     return beans::Property(
769         rsPropertyName,
770         eItem,
771         GetCppuType(eType),
772         0);
773 }
774 
775 
776 
777 
778 sal_Bool SAL_CALL Theme::hasPropertyByName (const ::rtl::OUString& rsPropertyName)
779     throw(cssu::RuntimeException)
780 {
781     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
782     if (iId == maPropertyNameToIdMap.end())
783         return sal_False;
784 
785     const PropertyType eType (GetPropertyType(iId->second));
786     if (eType == PT_Invalid)
787         return sal_False;
788 
789     return sal_True;
790 }
791 
792 
793 
794 
795 void Theme::SetupPropertyMaps (void)
796 {
797     maPropertyIdToNameMap.resize(__Post_Rect);
798     maImages.resize(__Image_Color - __Pre_Image - 1);
799     maColors.resize(__Color_Paint - __Image_Color - 1);
800     maPaints.resize(__Paint_Int - __Color_Paint - 1);
801     maIntegers.resize(__Int_Bool - __Paint_Int - 1);
802     maBooleans.resize(__Bool_Rect - __Int_Bool - 1);
803     maRectangles.resize(__Post_Rect - __Bool_Rect - 1);
804 
805     #define AddEntry(e) maPropertyNameToIdMap[A2S(#e)]=e; maPropertyIdToNameMap[e]=A2S(#e)
806 
807     AddEntry(Image_Grip);
808     AddEntry(Image_Expand);
809     AddEntry(Image_Collapse);
810     AddEntry(Image_TabBarMenu);
811     AddEntry(Image_PanelMenu);
812     AddEntry(Image_ToolBoxItemSeparator);
813     AddEntry(Image_Closer);
814     AddEntry(Image_CloseIndicator);
815 
816     AddEntry(Color_DeckTitleFont);
817     AddEntry(Color_PanelTitleFont);
818     AddEntry(Color_TabMenuSeparator);
819     AddEntry(Color_TabItemBorder);
820     AddEntry(Color_DropDownBorder);
821     AddEntry(Color_Highlight);
822     AddEntry(Color_HighlightText);
823 
824     AddEntry(Paint_DeckBackground);
825     AddEntry(Paint_DeckTitleBarBackground);
826     AddEntry(Paint_PanelBackground);
827     AddEntry(Paint_PanelTitleBarBackground);
828     AddEntry(Paint_TabBarBackground);
829     AddEntry(Paint_TabItemBackgroundNormal);
830     AddEntry(Paint_TabItemBackgroundHighlight);
831     AddEntry(Paint_HorizontalBorder);
832     AddEntry(Paint_VerticalBorder);
833     AddEntry(Paint_ToolBoxBackground);
834     AddEntry(Paint_ToolBoxBorderTopLeft);
835     AddEntry(Paint_ToolBoxBorderCenterCorners);
836     AddEntry(Paint_ToolBoxBorderBottomRight);
837     AddEntry(Paint_DropDownBackground);
838 
839     AddEntry(Int_DeckTitleBarHeight);
840     AddEntry(Int_DeckBorderSize);
841     AddEntry(Int_DeckSeparatorHeight);
842     AddEntry(Int_PanelTitleBarHeight);
843     AddEntry(Int_TabMenuPadding);
844     AddEntry(Int_TabMenuSeparatorPadding);
845     AddEntry(Int_TabItemWidth);
846     AddEntry(Int_TabItemHeight);
847     AddEntry(Int_DeckLeftPadding);
848     AddEntry(Int_DeckTopPadding);
849     AddEntry(Int_DeckRightPadding);
850     AddEntry(Int_DeckBottomPadding);
851     AddEntry(Int_TabBarLeftPadding);
852     AddEntry(Int_TabBarTopPadding);
853     AddEntry(Int_TabBarRightPadding);
854     AddEntry(Int_TabBarBottomPadding);
855     AddEntry(Int_ButtonCornerRadius);
856 
857     AddEntry(Bool_UseSymphonyIcons);
858     AddEntry(Bool_UseSystemColors);
859     AddEntry(Bool_UseToolBoxItemSeparator);
860     AddEntry(Bool_IsHighContrastModeActive);
861 
862     AddEntry(Rect_ToolBoxPadding);
863     AddEntry(Rect_ToolBoxBorder);
864 
865     #undef AddEntry
866 
867     maRawValues.resize(maPropertyIdToNameMap.size());
868 }
869 
870 
871 
872 
873 Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem)
874 {
875     switch(eItem)
876     {
877         case Image_Grip:
878         case Image_Expand:
879         case Image_Collapse:
880         case Image_TabBarMenu:
881         case Image_PanelMenu:
882         case Image_ToolBoxItemSeparator:
883         case Image_Closer:
884         case Image_CloseIndicator:
885             return PT_Image;
886 
887         case Color_DeckTitleFont:
888         case Color_PanelTitleFont:
889         case Color_TabMenuSeparator:
890         case Color_TabItemBorder:
891         case Color_DropDownBorder:
892         case Color_Highlight:
893         case Color_HighlightText:
894             return PT_Color;
895 
896         case Paint_DeckBackground:
897         case Paint_DeckTitleBarBackground:
898         case Paint_PanelBackground:
899         case Paint_PanelTitleBarBackground:
900         case Paint_TabBarBackground:
901         case Paint_TabItemBackgroundNormal:
902         case Paint_TabItemBackgroundHighlight:
903         case Paint_HorizontalBorder:
904         case Paint_VerticalBorder:
905         case Paint_ToolBoxBackground:
906         case Paint_ToolBoxBorderTopLeft:
907         case Paint_ToolBoxBorderCenterCorners:
908         case Paint_ToolBoxBorderBottomRight:
909         case Paint_DropDownBackground:
910             return PT_Paint;
911 
912         case Int_DeckTitleBarHeight:
913         case Int_DeckBorderSize:
914         case Int_DeckSeparatorHeight:
915         case Int_PanelTitleBarHeight:
916         case Int_TabMenuPadding:
917         case Int_TabMenuSeparatorPadding:
918         case Int_TabItemWidth:
919         case Int_TabItemHeight:
920         case Int_DeckLeftPadding:
921         case Int_DeckTopPadding:
922         case Int_DeckRightPadding:
923         case Int_DeckBottomPadding:
924         case Int_TabBarLeftPadding:
925         case Int_TabBarTopPadding:
926         case Int_TabBarRightPadding:
927         case Int_TabBarBottomPadding:
928         case Int_ButtonCornerRadius:
929             return PT_Integer;
930 
931         case Bool_UseSymphonyIcons:
932         case Bool_UseSystemColors:
933         case Bool_UseToolBoxItemSeparator:
934         case Bool_IsHighContrastModeActive:
935             return PT_Boolean;
936 
937         case Rect_ToolBoxBorder:
938         case Rect_ToolBoxPadding:
939             return PT_Rectangle;
940 
941         default:
942             return PT_Invalid;
943     }
944 }
945 
946 
947 
948 
949 cssu::Type Theme::GetCppuType (const PropertyType eType)
950 {
951     switch(eType)
952     {
953         case PT_Image:
954             return getCppuType((rtl::OUString*)NULL);
955 
956         case PT_Color:
957             return getCppuType((sal_uInt32*)NULL);
958 
959         case PT_Paint:
960             return getCppuVoidType();
961 
962         case PT_Integer:
963             return getCppuType((sal_Int32*)NULL);
964 
965         case PT_Boolean:
966             return getCppuType((sal_Bool*)NULL);
967 
968         case PT_Rectangle:
969             return getCppuType((awt::Rectangle*)NULL);
970 
971         case PT_Invalid:
972         default:
973             return getCppuVoidType();
974     }
975 }
976 
977 
978 
979 
980 sal_Int32 Theme::GetIndex (const ThemeItem eItem, const PropertyType eType)
981 {
982     switch(eType)
983     {
984         case PT_Image:
985             return eItem - __Pre_Image-1;
986         case PT_Color:
987             return eItem - __Image_Color-1;
988         case PT_Paint:
989             return eItem - __Color_Paint-1;
990         case PT_Integer:
991             return eItem - __Paint_Int-1;
992         case PT_Boolean:
993             return eItem - __Int_Bool-1;
994         case PT_Rectangle:
995             return eItem - __Bool_Rect-1;
996 
997         default:
998             OSL_ASSERT(false);
999             return 0;
1000     }
1001 }
1002 
1003 
1004 
1005 
1006 Theme::VetoableListenerContainer* Theme::GetVetoableListeners (
1007     const ThemeItem eItem,
1008     const bool bCreate)
1009 {
1010     VetoableListeners::iterator iContainer (maVetoableListeners.find(eItem));
1011     if (iContainer != maVetoableListeners.end())
1012         return &iContainer->second;
1013     else if (bCreate)
1014     {
1015         maVetoableListeners[eItem] = VetoableListenerContainer();
1016         return &maVetoableListeners[eItem];
1017     }
1018     else
1019         return NULL;
1020 }
1021 
1022 
1023 
1024 
1025 Theme::ChangeListenerContainer* Theme::GetChangeListeners (
1026     const ThemeItem eItem,
1027     const bool bCreate)
1028 {
1029     ChangeListeners::iterator iContainer (maChangeListeners.find(eItem));
1030     if (iContainer != maChangeListeners.end())
1031         return &iContainer->second;
1032     else if (bCreate)
1033     {
1034         maChangeListeners[eItem] = ChangeListenerContainer();
1035         return &maChangeListeners[eItem];
1036     }
1037     else
1038         return NULL;
1039 }
1040 
1041 
1042 
1043 
1044 bool Theme::DoVetoableListenersVeto (
1045     const VetoableListenerContainer* pListeners,
1046     const beans::PropertyChangeEvent& rEvent) const
1047 {
1048     if (pListeners == NULL)
1049         return false;
1050 
1051     VetoableListenerContainer aListeners (*pListeners);
1052     try
1053     {
1054         for (VetoableListenerContainer::const_iterator
1055                  iListener(aListeners.begin()),
1056                  iEnd(aListeners.end());
1057              iListener!=iEnd;
1058              ++iListener)
1059         {
1060             (*iListener)->vetoableChange(rEvent);
1061         }
1062     }
1063     catch(const beans::PropertyVetoException&)
1064     {
1065         return true;
1066     }
1067     catch(const Exception&)
1068     {
1069         // Ignore any other errors (such as disposed listeners).
1070     }
1071     return false;
1072 }
1073 
1074 
1075 
1076 
1077 void Theme::BroadcastPropertyChange (
1078     const ChangeListenerContainer* pListeners,
1079     const beans::PropertyChangeEvent& rEvent) const
1080 {
1081     if (pListeners == NULL)
1082         return;
1083 
1084     const ChangeListenerContainer aListeners (*pListeners);
1085     try
1086     {
1087         for (ChangeListenerContainer::const_iterator
1088                  iListener(aListeners.begin()),
1089                  iEnd(aListeners.end());
1090              iListener!=iEnd;
1091              ++iListener)
1092         {
1093             (*iListener)->propertyChange(rEvent);
1094         }
1095     }
1096     catch(const Exception&)
1097     {
1098         // Ignore any errors (such as disposed listeners).
1099     }
1100 }
1101 
1102 
1103 
1104 
1105 void Theme::ProcessNewValue (
1106     const Any& rValue,
1107     const ThemeItem eItem,
1108     const PropertyType eType)
1109 {
1110     const sal_Int32 nIndex (GetIndex (eItem, eType));
1111     switch (eType)
1112     {
1113         case PT_Image:
1114         {
1115             ::rtl::OUString sURL;
1116             if (rValue >>= sURL)
1117             {
1118                 maImages[nIndex] = Tools::GetImage(sURL, NULL);
1119             }
1120             break;
1121         }
1122         case PT_Color:
1123         {
1124             sal_Int32 nColorValue (0);
1125             if (rValue >>= nColorValue)
1126             {
1127                 maColors[nIndex] = Color(nColorValue);
1128             }
1129             break;
1130         }
1131         case PT_Paint:
1132         {
1133             maPaints[nIndex] = Paint::Create(rValue);
1134             break;
1135         }
1136         case PT_Integer:
1137         {
1138             sal_Int32 nValue (0);
1139             if (rValue >>= nValue)
1140             {
1141                 maIntegers[nIndex] = nValue;
1142             }
1143             break;
1144         }
1145         case PT_Boolean:
1146         {
1147             sal_Bool nValue (0);
1148             if (rValue >>= nValue)
1149             {
1150                 maBooleans[nIndex] = (nValue==sal_True);
1151                 if (eItem == Bool_IsHighContrastModeActive)
1152                 {
1153                     mbIsHighContrastModeSetManually = true;
1154                     mbIsHighContrastMode = maBooleans[nIndex];
1155                     HandleDataChange();
1156                 }
1157                 else if (eItem == Bool_UseSystemColors)
1158                 {
1159                     HandleDataChange();
1160                 }
1161             }
1162             break;
1163         }
1164         case PT_Rectangle:
1165         {
1166             awt::Rectangle aBox;
1167             if (rValue >>= aBox)
1168             {
1169                 maRectangles[nIndex] = Rectangle(
1170                     aBox.X,
1171                     aBox.Y,
1172                     aBox.Width,
1173                     aBox.Height);
1174             }
1175             break;
1176         }
1177         case PT_Invalid:
1178             OSL_ASSERT(eType != PT_Invalid);
1179             throw RuntimeException();
1180     }
1181 }
1182 
1183 
1184 
1185 
1186 } } // end of namespace sfx2::sidebar
1187