xref: /trunk/main/sfx2/source/sidebar/Theme.cxx (revision b9e67834)
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       maPropertyNameToIdMap(),
66       maPropertyIdToNameMap(),
67       maRawValues(),
68       maChangeListeners(),
69       maVetoableListeners()
70 
71 {
72     SetupPropertyMaps();
73 }
74 
75 
76 
77 
78 Theme::~Theme (void)
79 {
80 }
81 
82 
83 
84 
85 Image Theme::GetImage (const ThemeItem eItem)
86 {
87     const PropertyType eType (GetPropertyType(eItem));
88     OSL_ASSERT(eType==PT_Image);
89     const sal_Int32 nIndex (GetIndex(eItem, eType));
90     const Theme& rTheme (GetCurrentTheme());
91     return rTheme.maImages[nIndex];
92 }
93 
94 
95 
96 
97 Color Theme::GetColor (const ThemeItem eItem)
98 {
99     const PropertyType eType (GetPropertyType(eItem));
100     OSL_ASSERT(eType==PT_Color);
101     const sal_Int32 nIndex (GetIndex(eItem, eType));
102     const Theme& rTheme (GetCurrentTheme());
103     return rTheme.maColors[nIndex];
104 }
105 
106 
107 
108 
109 const Paint& Theme::GetPaint (const ThemeItem eItem)
110 {
111     const PropertyType eType (GetPropertyType(eItem));
112     OSL_ASSERT(eType==PT_Paint);
113     const sal_Int32 nIndex (GetIndex(eItem, eType));
114     const Theme& rTheme (GetCurrentTheme());
115     return rTheme.maPaints[nIndex];
116 }
117 
118 
119 
120 
121 sal_Int32 Theme::GetInteger (const ThemeItem eItem)
122 {
123     const PropertyType eType (GetPropertyType(eItem));
124     OSL_ASSERT(eType==PT_Integer);
125     const sal_Int32 nIndex (GetIndex(eItem, eType));
126     const Theme& rTheme (GetCurrentTheme());
127     return rTheme.maIntegers[nIndex];
128 }
129 
130 
131 
132 
133 bool Theme::GetBoolean (const ThemeItem eItem)
134 {
135     const PropertyType eType (GetPropertyType(eItem));
136     OSL_ASSERT(eType==PT_Boolean);
137     const sal_Int32 nIndex (GetIndex(eItem, eType));
138     const Theme& rTheme (GetCurrentTheme());
139     return rTheme.maBooleans[nIndex];
140 }
141 
142 
143 
144 
145 bool Theme::IsHighContrastMode (void)
146 {
147     const Theme& rTheme (GetCurrentTheme());
148     return rTheme.mbIsHighContrastMode;
149 }
150 
151 
152 
153 
154 void Theme::HandleDataChange (void)
155 {
156     GetCurrentTheme().mbIsHighContrastMode = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
157     GetCurrentTheme().InitializeTheme();
158 }
159 
160 
161 
162 
163 void Theme::InitializeTheme (void)
164 {
165     SidebarResource aLocalResource;
166 
167     try
168     {
169         setPropertyValue(
170             maPropertyIdToNameMap[Paint_DeckBackground],
171             Any(sal_Int32(mbIsHighContrastMode ? 0x000000 : 0xf0f0f0)));
172         setPropertyValue(
173             maPropertyIdToNameMap[Paint_DeckTitleBarBackground],
174             Any(sal_Int32(mbIsHighContrastMode ? 0x000000 :0xf0f0f0)));
175         setPropertyValue(
176             maPropertyIdToNameMap[Int_DeckLeftPadding],
177             Any(sal_Int32(2)));
178         setPropertyValue(
179             maPropertyIdToNameMap[Int_DeckTopPadding],
180             Any(sal_Int32(2)));
181         setPropertyValue(
182             maPropertyIdToNameMap[Int_DeckRightPadding],
183             Any(sal_Int32(2)));
184         setPropertyValue(
185             maPropertyIdToNameMap[Int_DeckBottomPadding],
186             Any(sal_Int32(2)));
187         setPropertyValue(
188             maPropertyIdToNameMap[Int_DeckBorderSize],
189             Any(sal_Int32(1)));
190         setPropertyValue(
191             maPropertyIdToNameMap[Int_DeckSeparatorHeight],
192             Any(sal_Int32(1)));
193         setPropertyValue(
194             maPropertyIdToNameMap[Color_DeckTitleFont],
195             Any(sal_Int32(mbIsHighContrastMode ? 0x00ff00 : 0x262626)));
196         setPropertyValue(
197             maPropertyIdToNameMap[Int_DeckTitleBarHeight],
198             Any(sal_Int32(26)));
199 
200         setPropertyValue(
201             maPropertyIdToNameMap[Paint_PanelBackground],
202             Any(sal_Int32(mbIsHighContrastMode ? 0x000000 : 0xffffff)));
203         setPropertyValue(
204             maPropertyIdToNameMap[Paint_PanelTitleBarBackground],
205             Any(sal_Int32(mbIsHighContrastMode ? 0x000000 : 0xb2b2b2)));
206         setPropertyValue(
207             maPropertyIdToNameMap[Color_PanelTitleFont],
208             Any(sal_Int32(mbIsHighContrastMode ? 0x00ff00 : 0x262626)));
209         setPropertyValue(
210             maPropertyIdToNameMap[Int_PanelTitleBarHeight],
211             Any(sal_Int32(26)));
212 
213         setPropertyValue(
214             maPropertyIdToNameMap[Paint_TabBarBackground],
215             Any(sal_Int32(mbIsHighContrastMode ? 0x000000 : 0xf0f0f0)));
216         setPropertyValue(
217             maPropertyIdToNameMap[Int_TabBarLeftPadding],
218             Any(sal_Int32(2)));
219         setPropertyValue(
220             maPropertyIdToNameMap[Int_TabBarTopPadding],
221             Any(sal_Int32(2)));
222         setPropertyValue(
223             maPropertyIdToNameMap[Int_TabBarRightPadding],
224             Any(sal_Int32(2)));
225         setPropertyValue(
226             maPropertyIdToNameMap[Int_TabBarBottomPadding],
227             Any(sal_Int32(2)));
228 
229         setPropertyValue(
230             maPropertyIdToNameMap[Int_TabMenuPadding],
231             Any(sal_Int32(6)));
232         setPropertyValue(
233             maPropertyIdToNameMap[Color_TabMenuSeparator],
234             Any(sal_Int32(mbIsHighContrastMode ? 0x00ff00 : 0xbfbfbf)));
235         setPropertyValue(
236             maPropertyIdToNameMap[Int_TabMenuSeparatorPadding],
237             Any(sal_Int32(7)));
238 
239         setPropertyValue(
240             maPropertyIdToNameMap[Int_TabItemWidth],
241             Any(sal_Int32(32)));
242         setPropertyValue(
243             maPropertyIdToNameMap[Int_TabItemHeight],
244             Any(sal_Int32(32)));
245         setPropertyValue(
246             maPropertyIdToNameMap[Color_TabItemBorder],
247             Any(sal_Int32(mbIsHighContrastMode ? 0x00ff00 : 0xbfbfbf)));
248         setPropertyValue(
249             maPropertyIdToNameMap[Paint_TabItemBackground],
250             Any(sal_Int32(mbIsHighContrastMode ? 0x000000 : 0xffffff)));
251 
252         setPropertyValue(
253             maPropertyIdToNameMap[Paint_HorizontalBorder],
254             Any(sal_Int32(mbIsHighContrastMode ? 0xff00ff000 : 0xd9d9d9)));
255         setPropertyValue(
256             maPropertyIdToNameMap[Paint_VerticalBorder],
257             Any(sal_Int32(mbIsHighContrastMode ? 0xff00ff000 : 0xd9d9d9)));
258 
259         setPropertyValue(
260             maPropertyIdToNameMap[Image_Grip],
261             Any(
262                 mbIsHighContrastMode
263                     ? A2S("private:graphicrepository/sfx2/res/grip_hc.png")
264                     : A2S("private:graphicrepository/sfx2/res/grip.png")));
265         setPropertyValue(
266             maPropertyIdToNameMap[Image_Expand],
267             Any(
268                 mbIsHighContrastMode
269                     ? A2S("private:graphicrepository/res/plus_sch.png")
270                     : A2S("private:graphicrepository/res/plus.png")));
271         setPropertyValue(
272             maPropertyIdToNameMap[Image_Collapse],
273             Any(
274                 mbIsHighContrastMode
275                     ? A2S("private:graphicrepository/res/minus_sch.png")
276                     : A2S("private:graphicrepository/res/minus.png")));
277         setPropertyValue(
278             maPropertyIdToNameMap[Image_Menu],
279             Any(
280                 mbIsHighContrastMode
281                     ? A2S("private:graphicrepository/sfx2/res/menu_ch.png")
282                     : A2S("private:graphicrepository/sfx2/res/menu.png")));
283 
284         setPropertyValue(
285             maPropertyIdToNameMap[Bool_UseSymphonyIcons],
286             Any(true));
287     }
288     catch(beans::UnknownPropertyException&)
289     {
290         OSL_ASSERT(false);
291     }
292 }
293 
294 
295 
296 
297 void SAL_CALL Theme::disposing (void)
298 {
299     ChangeListeners aListeners;
300     maChangeListeners.swap(aListeners);
301 
302     const lang::EventObject aEvent (static_cast<XWeak*>(this));
303 
304     for (ChangeListeners::const_iterator
305              iContainer(maChangeListeners.begin()),
306              iContainerEnd(maChangeListeners.end());
307          iContainerEnd!=iContainerEnd;
308          ++iContainerEnd)
309     {
310         for (ChangeListenerContainer::const_iterator
311                  iListener(iContainer->second.begin()),
312                  iEnd(iContainer->second.end());
313              iListener!=iEnd;
314              ++iListener)
315         {
316             try
317             {
318                 (*iListener)->disposing(aEvent);
319             }
320             catch(const Exception&)
321             {
322             }
323         }
324     }
325 }
326 
327 
328 
329 
330 Reference<beans::XPropertySet> Theme::GetPropertySet (void)
331 {
332     return Reference<beans::XPropertySet>(static_cast<XWeak*>(&GetCurrentTheme()), UNO_QUERY);
333 }
334 
335 
336 
337 
338 Reference<beans::XPropertySetInfo> SAL_CALL Theme::getPropertySetInfo (void)
339     throw(cssu::RuntimeException)
340 {
341     return Reference<beans::XPropertySetInfo>();
342 }
343 
344 
345 
346 
347 void SAL_CALL Theme::setPropertyValue (
348     const ::rtl::OUString& rsPropertyName,
349     const cssu::Any& rValue)
350     throw(cssu::RuntimeException)
351 {
352     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
353     if (iId == maPropertyNameToIdMap.end())
354         throw beans::UnknownPropertyException();
355 
356     const PropertyType eType (GetPropertyType(iId->second));
357     if (eType == PT_Invalid)
358         throw beans::UnknownPropertyException();
359 
360     const ThemeItem eItem (iId->second);
361 
362     if (rValue == maRawValues[eItem])
363     {
364         // Value is not different from the one in the property
365         // set => nothing to do.
366         return;
367     }
368 
369     const Any aOldValue (maRawValues[eItem]);
370 
371     const beans::PropertyChangeEvent aEvent(
372         static_cast<XWeak*>(this),
373         rsPropertyName,
374         sal_False,
375         eItem,
376         aOldValue,
377         rValue);
378 
379     if (DoVetoableListenersVeto(GetVetoableListeners(__AnyItem, false), aEvent))
380         return;
381     if (DoVetoableListenersVeto(GetVetoableListeners(eItem, false), aEvent))
382         return;
383 
384     maRawValues[eItem] = rValue;
385     ProcessNewValue(rValue, eItem, eType);
386 
387     BroadcastPropertyChange(GetChangeListeners(__AnyItem, false), aEvent);
388     BroadcastPropertyChange(GetChangeListeners(eItem, false), aEvent);
389 }
390 
391 
392 
393 
394 Any SAL_CALL Theme::getPropertyValue (
395     const ::rtl::OUString& rsPropertyName)
396     throw(css::beans::UnknownPropertyException,
397         css::lang::WrappedTargetException,
398         cssu::RuntimeException)
399 {
400     PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
401     if (iId == maPropertyNameToIdMap.end())
402         throw beans::UnknownPropertyException();
403 
404     const PropertyType eType (GetPropertyType(iId->second));
405     if (eType == PT_Invalid)
406         throw beans::UnknownPropertyException();
407 
408     const ThemeItem eItem (iId->second);
409 
410     return maRawValues[eItem];
411 }
412 
413 
414 
415 
416 void SAL_CALL Theme::addPropertyChangeListener(
417     const ::rtl::OUString& rsPropertyName,
418     const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener)
419     throw(css::beans::UnknownPropertyException,
420         css::lang::WrappedTargetException,
421         cssu::RuntimeException)
422 {
423     ThemeItem eItem (__AnyItem);
424     if (rsPropertyName.getLength() > 0)
425     {
426         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
427         if (iId == maPropertyNameToIdMap.end())
428             throw beans::UnknownPropertyException();
429 
430         const PropertyType eType (GetPropertyType(iId->second));
431         if (eType == PT_Invalid)
432             throw beans::UnknownPropertyException();
433 
434         eItem = iId->second;
435     }
436     ChangeListenerContainer* pListeners = GetChangeListeners(eItem, true);
437     if (pListeners != NULL)
438         pListeners->push_back(rxListener);
439 }
440 
441 
442 
443 
444 void SAL_CALL Theme::removePropertyChangeListener(
445     const ::rtl::OUString& rsPropertyName,
446     const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener)
447     throw(css::beans::UnknownPropertyException,
448         css::lang::WrappedTargetException,
449         cssu::RuntimeException)
450 {
451     ThemeItem eItem (__AnyItem);
452     if (rsPropertyName.getLength() > 0)
453     {
454         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
455         if (iId == maPropertyNameToIdMap.end())
456             throw beans::UnknownPropertyException();
457 
458         const PropertyType eType (GetPropertyType(iId->second));
459         if (eType == PT_Invalid)
460             throw beans::UnknownPropertyException();
461 
462         eItem = iId->second;
463     }
464     ChangeListenerContainer* pContainer = GetChangeListeners(eItem, false);
465     if (pContainer != NULL)
466     {
467         ChangeListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
468         if (iListener != pContainer->end())
469         {
470             pContainer->erase(iListener);
471 
472             // Remove the listener container when empty.
473             if (pContainer->empty())
474                 maChangeListeners.erase(eItem);
475         }
476     }
477 }
478 
479 
480 
481 
482 void SAL_CALL Theme::addVetoableChangeListener(
483     const ::rtl::OUString& rsPropertyName,
484     const cssu::Reference<css::beans::XVetoableChangeListener>& rxListener)
485     throw(css::beans::UnknownPropertyException,
486         css::lang::WrappedTargetException,
487         cssu::RuntimeException)
488 {
489     ThemeItem eItem (__AnyItem);
490     if (rsPropertyName.getLength() > 0)
491     {
492         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
493         if (iId == maPropertyNameToIdMap.end())
494             throw beans::UnknownPropertyException();
495 
496         const PropertyType eType (GetPropertyType(iId->second));
497         if (eType == PT_Invalid)
498             throw beans::UnknownPropertyException();
499 
500         eItem = iId->second;
501     }
502     VetoableListenerContainer* pListeners = GetVetoableListeners(eItem, true);
503     if (pListeners != NULL)
504         pListeners->push_back(rxListener);
505 }
506 
507 
508 
509 
510 void SAL_CALL Theme::removeVetoableChangeListener(
511     const ::rtl::OUString& rsPropertyName,
512     const cssu::Reference<css::beans::XVetoableChangeListener>& rxListener)
513     throw(css::beans::UnknownPropertyException,
514         css::lang::WrappedTargetException,
515         cssu::RuntimeException)
516 {
517     ThemeItem eItem (__AnyItem);
518     if (rsPropertyName.getLength() > 0)
519     {
520         PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
521         if (iId == maPropertyNameToIdMap.end())
522             throw beans::UnknownPropertyException();
523 
524         const PropertyType eType (GetPropertyType(iId->second));
525         if (eType == PT_Invalid)
526             throw beans::UnknownPropertyException();
527 
528         eItem = iId->second;
529     }
530     VetoableListenerContainer* pContainer = GetVetoableListeners(eItem, false);
531     if (pContainer != NULL)
532     {
533         VetoableListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
534         if (iListener != pContainer->end())
535         {
536             pContainer->erase(iListener);
537             // Remove container when empty.
538             if (pContainer->empty())
539                 maVetoableListeners.erase(eItem);
540         }
541     }
542 }
543 
544 
545 
546 
547 void Theme::SetupPropertyMaps (void)
548 {
549     maPropertyIdToNameMap.resize(__Post_Bool);
550     maImages.resize(__Image_Color - __Pre_Image - 1);
551     maColors.resize(__Color_Paint - __Image_Color - 1);
552     maPaints.resize(__Paint_Int - __Color_Paint - 1);
553     maIntegers.resize(__Int_Bool - __Paint_Int - 1);
554     maBooleans.resize(__Post_Bool - __Int_Bool - 1);
555 
556     #define AddEntry(e) maPropertyNameToIdMap[A2S(#e)]=e; maPropertyIdToNameMap[e]=A2S(#e)
557     AddEntry(Image_Grip);
558     AddEntry(Image_Expand);
559     AddEntry(Image_Collapse);
560     AddEntry(Image_Menu);
561 
562     AddEntry(Color_DeckTitleFont);
563     AddEntry(Color_PanelTitleFont);
564     AddEntry(Color_TabMenuSeparator);
565     AddEntry(Color_TabItemBorder);
566 
567     AddEntry(Paint_DeckBackground);
568     AddEntry(Paint_DeckTitleBarBackground);
569     AddEntry(Paint_PanelBackground);
570     AddEntry(Paint_PanelTitleBarBackground);
571     AddEntry(Paint_TabBarBackground);
572     AddEntry(Paint_TabItemBackground);
573     AddEntry(Paint_HorizontalBorder);
574     AddEntry(Paint_VerticalBorder);
575 
576     AddEntry(Int_DeckTitleBarHeight);
577     AddEntry(Int_DeckBorderSize);
578     AddEntry(Int_DeckSeparatorHeight);
579     AddEntry(Int_PanelTitleBarHeight);
580     AddEntry(Int_TabMenuPadding);
581     AddEntry(Int_TabMenuSeparatorPadding);
582     AddEntry(Int_TabItemWidth);
583     AddEntry(Int_TabItemHeight);
584     AddEntry(Int_DeckLeftPadding);
585     AddEntry(Int_DeckTopPadding);
586     AddEntry(Int_DeckRightPadding);
587     AddEntry(Int_DeckBottomPadding);
588     AddEntry(Int_TabBarLeftPadding);
589     AddEntry(Int_TabBarTopPadding);
590     AddEntry(Int_TabBarRightPadding);
591     AddEntry(Int_TabBarBottomPadding);
592 
593     AddEntry(Bool_UseSymphonyIcons);
594     #undef AddEntry
595 
596     maRawValues.resize(maPropertyIdToNameMap.size());
597 }
598 
599 
600 
601 
602 Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem)
603 {
604     switch(eItem)
605     {
606         case Image_Grip:
607         case Image_Expand:
608         case Image_Collapse:
609         case Image_Menu:
610             return PT_Image;
611 
612         case Color_DeckTitleFont:
613         case Color_PanelTitleFont:
614         case Color_TabMenuSeparator:
615         case Color_TabItemBorder:
616             return PT_Color;
617 
618         case Paint_DeckBackground:
619         case Paint_DeckTitleBarBackground:
620         case Paint_PanelBackground:
621         case Paint_PanelTitleBarBackground:
622         case Paint_TabBarBackground:
623         case Paint_TabItemBackground:
624         case Paint_HorizontalBorder:
625         case Paint_VerticalBorder:
626             return PT_Paint;
627 
628         case Int_DeckTitleBarHeight:
629         case Int_DeckBorderSize:
630         case Int_DeckSeparatorHeight:
631         case Int_PanelTitleBarHeight:
632         case Int_TabMenuPadding:
633         case Int_TabMenuSeparatorPadding:
634         case Int_TabItemWidth:
635         case Int_TabItemHeight:
636         case Int_DeckLeftPadding:
637         case Int_DeckTopPadding:
638         case Int_DeckRightPadding:
639         case Int_DeckBottomPadding:
640         case Int_TabBarLeftPadding:
641         case Int_TabBarTopPadding:
642         case Int_TabBarRightPadding:
643         case Int_TabBarBottomPadding:
644             return PT_Integer;
645 
646         case Bool_UseSymphonyIcons:
647             return PT_Boolean;
648 
649         default:
650             return PT_Invalid;
651     }
652 }
653 
654 
655 
656 
657 sal_Int32 Theme::GetIndex (const ThemeItem eItem, const PropertyType eType)
658 {
659     switch(eType)
660     {
661         case PT_Image:
662             return eItem - __Pre_Image-1;
663         case PT_Color:
664             return eItem - __Image_Color-1;
665         case PT_Paint:
666             return eItem - __Color_Paint-1;
667         case PT_Integer:
668             return eItem - __Paint_Int-1;
669         case PT_Boolean:
670             return eItem - __Int_Bool-1;
671 
672         default:
673             OSL_ASSERT(false);
674             return 0;
675     }
676 }
677 
678 
679 
680 
681 Theme::VetoableListenerContainer* Theme::GetVetoableListeners (
682     const ThemeItem eItem,
683     const bool bCreate)
684 {
685     VetoableListeners::iterator iContainer (maVetoableListeners.find(eItem));
686     if (iContainer != maVetoableListeners.end())
687         return &iContainer->second;
688     else if (bCreate)
689     {
690         maVetoableListeners[eItem] = VetoableListenerContainer();
691         return &maVetoableListeners[eItem];
692     }
693     else
694         return NULL;
695 }
696 
697 
698 
699 
700 Theme::ChangeListenerContainer* Theme::GetChangeListeners (
701     const ThemeItem eItem,
702     const bool bCreate)
703 {
704     ChangeListeners::iterator iContainer (maChangeListeners.find(eItem));
705     if (iContainer != maChangeListeners.end())
706         return &iContainer->second;
707     else if (bCreate)
708     {
709         maChangeListeners[eItem] = ChangeListenerContainer();
710         return &maChangeListeners[eItem];
711     }
712     else
713         return NULL;
714 }
715 
716 
717 
718 
719 bool Theme::DoVetoableListenersVeto (
720     const VetoableListenerContainer* pListeners,
721     const beans::PropertyChangeEvent& rEvent) const
722 {
723     if (pListeners == NULL)
724         return false;
725 
726     VetoableListenerContainer aListeners (*pListeners);
727     try
728     {
729         for (VetoableListenerContainer::const_iterator
730                  iListener(aListeners.begin()),
731                  iEnd(aListeners.end());
732              iListener!=iEnd;
733              ++iListener)
734         {
735             (*iListener)->vetoableChange(rEvent);
736         }
737     }
738     catch(const beans::PropertyVetoException&)
739     {
740         return true;
741     }
742     catch(const Exception&)
743     {
744         // Ignore any other errors (such as disposed listeners).
745     }
746     return false;
747 }
748 
749 
750 
751 
752 void Theme::BroadcastPropertyChange (
753     const ChangeListenerContainer* pListeners,
754     const beans::PropertyChangeEvent& rEvent) const
755 {
756     if (pListeners == NULL)
757         return;
758 
759     const ChangeListenerContainer aListeners (*pListeners);
760     try
761     {
762         for (ChangeListenerContainer::const_iterator
763                  iListener(aListeners.begin()),
764                  iEnd(aListeners.end());
765              iListener!=iEnd;
766              ++iListener)
767         {
768             (*iListener)->propertyChange(rEvent);
769         }
770     }
771     catch(const Exception&)
772     {
773         // Ignore any errors (such as disposed listeners).
774     }
775 }
776 
777 
778 
779 
780 void Theme::ProcessNewValue (
781     const Any& rValue,
782     const ThemeItem eItem,
783     const PropertyType eType)
784 {
785     const sal_Int32 nIndex (GetIndex (eItem, eType));
786     switch (eType)
787     {
788         case PT_Image:
789         {
790             ::rtl::OUString sURL;
791             if (rValue >>= sURL)
792             {
793                 maImages[nIndex] = Tools::GetImage(sURL, NULL);
794             }
795             break;
796         }
797         case PT_Color:
798         {
799             sal_Int32 nColorValue;
800             if (rValue >>= nColorValue)
801             {
802                 maColors[nIndex] = Color(nColorValue);
803             }
804             break;
805         }
806         case PT_Paint:
807         {
808             sal_Int32 nColorValue;
809             if (rValue >>= nColorValue)
810             {
811                 maPaints[nIndex] = Paint(Color(nColorValue));
812             }
813             break;
814         }
815         case PT_Integer:
816         {
817             sal_Int32 nValue;
818             if (rValue >>= nValue)
819             {
820                 maIntegers[nIndex] = nValue;
821             }
822             break;
823         }
824         case PT_Boolean:
825         {
826             sal_Bool nValue;
827             if (rValue >>= nValue)
828             {
829                 maBooleans[nIndex] = (nValue==sal_True);
830             }
831             break;
832         }
833         case PT_Invalid:
834             OSL_ASSERT(eType != PT_Invalid);
835             throw RuntimeException();
836     }
837 }
838 
839 
840 
841 
842 } } // end of namespace sfx2::sidebar
843