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