LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sfx2 / source / sidebar / Theme.cxx
blobc6238bb3def0f2c537b253a24d812c6e09c38585
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/sidebar/Theme.hxx>
21 #include <sidebar/Tools.hxx>
22 #include <sfx2/app.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/settings.hxx>
26 #include <tools/diagnose_ex.h>
28 using namespace css;
29 using namespace css::uno;
31 namespace sfx2::sidebar {
33 Theme& Theme::GetCurrentTheme()
35 OSL_ASSERT(SfxGetpApp());
36 return SfxGetpApp()->GetSidebarTheme();
39 Theme::Theme()
40 : ThemeInterfaceBase(m_aMutex),
41 mbIsHighContrastMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode()),
42 mbIsHighContrastModeSetManually(false)
44 SetupPropertyMaps();
47 Theme::~Theme()
51 Color Theme::GetColor (const ThemeItem eItem)
53 const PropertyType eType (GetPropertyType(eItem));
54 OSL_ASSERT(eType==PT_Color);
55 const sal_Int32 nIndex (GetIndex(eItem, eType));
56 const Theme& rTheme (GetCurrentTheme());
57 if (eType == PT_Color)
58 return rTheme.maColors[nIndex];
59 else
60 return COL_WHITE;
63 sal_Int32 Theme::GetInteger (const ThemeItem eItem)
65 const PropertyType eType (GetPropertyType(eItem));
66 OSL_ASSERT(eType==PT_Integer);
67 const sal_Int32 nIndex (GetIndex(eItem, eType));
68 const Theme& rTheme (GetCurrentTheme());
69 return rTheme.maIntegers[nIndex];
72 bool Theme::IsHighContrastMode()
74 const Theme& rTheme (GetCurrentTheme());
75 return rTheme.mbIsHighContrastMode;
78 void Theme::HandleDataChange()
80 Theme& rTheme (GetCurrentTheme());
82 if ( ! rTheme.mbIsHighContrastModeSetManually)
84 // Do not modify mbIsHighContrastMode when it was manually set.
85 GetCurrentTheme().mbIsHighContrastMode = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
86 rTheme.maRawValues[Bool_IsHighContrastModeActive] <<= GetCurrentTheme().mbIsHighContrastMode;
89 GetCurrentTheme().UpdateTheme();
92 void Theme::InitializeTheme()
94 setPropertyValue(
95 maPropertyIdToNameMap[Bool_UseSystemColors],
96 Any(false));
99 void Theme::UpdateTheme()
103 const StyleSettings& rStyle (Application::GetSettings().GetStyleSettings());
105 Color aBaseBackgroundColor (rStyle.GetDialogColor());
106 // UX says this should be a little brighter, but that looks off when compared to the other windows.
107 //aBaseBackgroundColor.IncreaseLuminance(7);
108 Color aSecondColor (aBaseBackgroundColor);
109 aSecondColor.DecreaseLuminance(15);
111 setPropertyValue(
112 maPropertyIdToNameMap[Color_DeckBackground],
113 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
115 setPropertyValue(
116 maPropertyIdToNameMap[Color_DeckTitleBarBackground],
117 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
118 setPropertyValue(
119 maPropertyIdToNameMap[Int_DeckSeparatorHeight],
120 Any(sal_Int32(1)));
121 setPropertyValue(
122 maPropertyIdToNameMap[Color_PanelBackground],
123 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
125 setPropertyValue(
126 maPropertyIdToNameMap[Color_PanelTitleBarBackground],
127 Any(sal_Int32(aSecondColor.GetRGBColor())));
128 setPropertyValue(
129 maPropertyIdToNameMap[Color_TabBarBackground],
130 Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
132 setPropertyValue(
133 maPropertyIdToNameMap[Color_Highlight],
134 Any(sal_Int32(rStyle.GetHighlightColor().GetRGBColor())));
135 setPropertyValue(
136 maPropertyIdToNameMap[Color_HighlightText],
137 Any(sal_Int32(rStyle.GetHighlightTextColor().GetRGBColor())));
139 catch(beans::UnknownPropertyException const &)
141 DBG_UNHANDLED_EXCEPTION("sfx", "unknown property");
142 OSL_ASSERT(false);
146 void SAL_CALL Theme::disposing()
148 SolarMutexGuard aGuard;
150 ChangeListeners aListeners;
151 aListeners.swap(maChangeListeners);
153 const lang::EventObject aEvent (static_cast<XWeak*>(this));
155 for (const auto& rContainer : aListeners)
157 for (const auto& rxListener : rContainer.second)
161 rxListener->disposing(aEvent);
163 catch(const Exception&)
170 Reference<beans::XPropertySet> Theme::GetPropertySet()
172 if (SfxGetpApp())
173 return Reference<beans::XPropertySet>(&GetCurrentTheme());
174 else
175 return Reference<beans::XPropertySet>();
178 Reference<beans::XPropertySetInfo> SAL_CALL Theme::getPropertySetInfo()
180 return Reference<beans::XPropertySetInfo>(this);
183 void SAL_CALL Theme::setPropertyValue (
184 const OUString& rsPropertyName,
185 const css::uno::Any& rValue)
187 SolarMutexGuard aGuard;
189 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
190 if (iId == maPropertyNameToIdMap.end())
191 throw beans::UnknownPropertyException(rsPropertyName);
193 const PropertyType eType (GetPropertyType(iId->second));
194 if (eType == PT_Invalid)
195 throw beans::UnknownPropertyException(rsPropertyName);
197 const ThemeItem eItem (iId->second);
199 if (rValue == maRawValues[eItem])
201 // Value is not different from the one in the property
202 // set => nothing to do.
203 return;
206 const Any aOldValue (maRawValues[eItem]);
208 const beans::PropertyChangeEvent aEvent(
209 static_cast<XWeak*>(this),
210 rsPropertyName,
211 false,
212 eItem,
213 aOldValue,
214 rValue);
216 if (DoVetoableListenersVeto(GetVetoableListeners(AnyItem_, false), aEvent))
217 return;
218 if (DoVetoableListenersVeto(GetVetoableListeners(eItem, false), aEvent))
219 return;
221 maRawValues[eItem] = rValue;
222 ProcessNewValue(rValue, eItem, eType);
224 BroadcastPropertyChange(GetChangeListeners(AnyItem_, false), aEvent);
225 BroadcastPropertyChange(GetChangeListeners(eItem, false), aEvent);
228 Any SAL_CALL Theme::getPropertyValue (
229 const OUString& rsPropertyName)
231 SolarMutexGuard aGuard;
233 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
234 if (iId == maPropertyNameToIdMap.end())
235 throw beans::UnknownPropertyException(rsPropertyName);
237 const PropertyType eType (GetPropertyType(iId->second));
238 if (eType == PT_Invalid)
239 throw beans::UnknownPropertyException(rsPropertyName);
241 const ThemeItem eItem (iId->second);
243 return maRawValues[eItem];
246 void SAL_CALL Theme::addPropertyChangeListener(
247 const OUString& rsPropertyName,
248 const css::uno::Reference<css::beans::XPropertyChangeListener>& rxListener)
250 SolarMutexGuard aGuard;
252 ThemeItem eItem (AnyItem_);
253 if (rsPropertyName.getLength() > 0)
255 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
256 if (iId == maPropertyNameToIdMap.end())
257 throw beans::UnknownPropertyException(rsPropertyName);
259 const PropertyType eType (GetPropertyType(iId->second));
260 if (eType == PT_Invalid)
261 throw beans::UnknownPropertyException(rsPropertyName);
263 eItem = iId->second;
265 ChangeListenerContainer* pListeners = GetChangeListeners(eItem, true);
266 if (pListeners != nullptr)
267 pListeners->push_back(rxListener);
270 void SAL_CALL Theme::removePropertyChangeListener(
271 const OUString& rsPropertyName,
272 const css::uno::Reference<css::beans::XPropertyChangeListener>& rxListener)
274 SolarMutexGuard aGuard;
276 ThemeItem eItem (AnyItem_);
277 if (rsPropertyName.getLength() > 0)
279 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
280 if (iId == maPropertyNameToIdMap.end())
281 throw beans::UnknownPropertyException(rsPropertyName);
283 const PropertyType eType (GetPropertyType(iId->second));
284 if (eType == PT_Invalid)
285 throw beans::UnknownPropertyException(rsPropertyName);
287 eItem = iId->second;
289 ChangeListenerContainer* pContainer = GetChangeListeners(eItem, false);
290 if (pContainer != nullptr)
292 ChangeListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
293 if (iListener != pContainer->end())
295 pContainer->erase(iListener);
297 // Remove the listener container when empty.
298 if (pContainer->empty())
299 maChangeListeners.erase(eItem);
304 void SAL_CALL Theme::addVetoableChangeListener(
305 const OUString& rsPropertyName,
306 const css::uno::Reference<css::beans::XVetoableChangeListener>& rxListener)
308 SolarMutexGuard aGuard;
310 ThemeItem eItem (AnyItem_);
311 if (rsPropertyName.getLength() > 0)
313 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
314 if (iId == maPropertyNameToIdMap.end())
315 throw beans::UnknownPropertyException(rsPropertyName);
317 const PropertyType eType (GetPropertyType(iId->second));
318 if (eType == PT_Invalid)
319 throw beans::UnknownPropertyException(rsPropertyName);
321 eItem = iId->second;
323 VetoableListenerContainer* pListeners = GetVetoableListeners(eItem, true);
324 if (pListeners != nullptr)
325 pListeners->push_back(rxListener);
328 void SAL_CALL Theme::removeVetoableChangeListener(
329 const OUString& rsPropertyName,
330 const css::uno::Reference<css::beans::XVetoableChangeListener>& rxListener)
332 SolarMutexGuard aGuard;
334 ThemeItem eItem (AnyItem_);
335 if (rsPropertyName.getLength() > 0)
337 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
338 if (iId == maPropertyNameToIdMap.end())
339 throw beans::UnknownPropertyException(rsPropertyName);
341 const PropertyType eType (GetPropertyType(iId->second));
342 if (eType == PT_Invalid)
343 throw beans::UnknownPropertyException(rsPropertyName);
345 eItem = iId->second;
347 VetoableListenerContainer* pContainer = GetVetoableListeners(eItem, false);
348 if (pContainer != nullptr)
350 VetoableListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
351 if (iListener != pContainer->end())
353 pContainer->erase(iListener);
354 // Remove container when empty.
355 if (pContainer->empty())
356 maVetoableListeners.erase(eItem);
361 css::uno::Sequence<css::beans::Property> SAL_CALL Theme::getProperties()
363 SolarMutexGuard aGuard;
365 ::std::vector<beans::Property> aProperties;
367 sal_Int32 const nEnd(End_);
368 for (sal_Int32 nItem(Begin_); nItem!=nEnd; ++nItem)
370 const ThemeItem eItem (static_cast<ThemeItem>(nItem));
371 const PropertyType eType (GetPropertyType(eItem));
372 if (eType == PT_Invalid)
373 continue;
375 const beans::Property aProperty(
376 maPropertyIdToNameMap[eItem],
377 eItem,
378 GetCppuType(eType),
380 aProperties.push_back(aProperty);
383 return css::uno::Sequence<css::beans::Property>(
384 aProperties.data(),
385 aProperties.size());
388 beans::Property SAL_CALL Theme::getPropertyByName (const OUString& rsPropertyName)
390 SolarMutexGuard aGuard;
392 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
393 if (iId == maPropertyNameToIdMap.end())
394 throw beans::UnknownPropertyException(rsPropertyName);
396 const PropertyType eType (GetPropertyType(iId->second));
397 if (eType == PT_Invalid)
398 throw beans::UnknownPropertyException(rsPropertyName);
400 const ThemeItem eItem (iId->second);
402 return beans::Property(
403 rsPropertyName,
404 eItem,
405 GetCppuType(eType),
409 sal_Bool SAL_CALL Theme::hasPropertyByName (const OUString& rsPropertyName)
411 SolarMutexGuard aGuard;
413 PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
414 if (iId == maPropertyNameToIdMap.end())
415 return false;
417 const PropertyType eType (GetPropertyType(iId->second));
418 if (eType == PT_Invalid)
419 return false;
421 return true;
424 void Theme::SetupPropertyMaps()
426 maPropertyIdToNameMap.resize(Post_Bool_);
427 maColors.resize(Color_Int_ - Pre_Color_ - 1);
428 maIntegers.resize(Int_Bool_ - Color_Int_ - 1);
429 maBooleans.resize(Post_Bool_ - Int_Bool_ - 1);
431 maPropertyNameToIdMap["Color_Highlight"]=Color_Highlight;
432 maPropertyIdToNameMap[Color_Highlight]="Color_Highlight";
434 maPropertyNameToIdMap["Color_HighlightText"]=Color_HighlightText;
435 maPropertyIdToNameMap[Color_HighlightText]="Color_HighlightText";
438 maPropertyNameToIdMap["Color_DeckBackground"]=Color_DeckBackground;
439 maPropertyIdToNameMap[Color_DeckBackground]="Color_DeckBackground";
441 maPropertyNameToIdMap["Color_DeckTitleBarBackground"]=Color_DeckTitleBarBackground;
442 maPropertyIdToNameMap[Color_DeckTitleBarBackground]="Color_DeckTitleBarBackground";
444 maPropertyNameToIdMap["Color_PanelBackground"]=Color_PanelBackground;
445 maPropertyIdToNameMap[Color_PanelBackground]="Color_PanelBackground";
447 maPropertyNameToIdMap["Color_PanelTitleBarBackground"]=Color_PanelTitleBarBackground;
448 maPropertyIdToNameMap[Color_PanelTitleBarBackground]="Color_PanelTitleBarBackground";
450 maPropertyNameToIdMap["Color_TabBarBackground"]=Color_TabBarBackground;
451 maPropertyIdToNameMap[Color_TabBarBackground]="Color_TabBarBackground";
454 maPropertyNameToIdMap["Int_DeckBorderSize"]=Int_DeckBorderSize;
455 maPropertyIdToNameMap[Int_DeckBorderSize]="Int_DeckBorderSize";
457 maPropertyNameToIdMap["Int_DeckSeparatorHeight"]=Int_DeckSeparatorHeight;
458 maPropertyIdToNameMap[Int_DeckSeparatorHeight]="Int_DeckSeparatorHeight";
460 maPropertyNameToIdMap["Int_DeckLeftPadding"]=Int_DeckLeftPadding;
461 maPropertyIdToNameMap[Int_DeckLeftPadding]="Int_DeckLeftPadding";
463 maPropertyNameToIdMap["Int_DeckTopPadding"]=Int_DeckTopPadding;
464 maPropertyIdToNameMap[Int_DeckTopPadding]="Int_DeckTopPadding";
466 maPropertyNameToIdMap["Int_DeckRightPadding"]=Int_DeckRightPadding;
467 maPropertyIdToNameMap[Int_DeckRightPadding]="Int_DeckRightPadding";
469 maPropertyNameToIdMap["Int_DeckBottomPadding"]=Int_DeckBottomPadding;
470 maPropertyIdToNameMap[Int_DeckBottomPadding]="Int_DeckBottomPadding";
473 maPropertyNameToIdMap["Bool_UseSystemColors"]=Bool_UseSystemColors;
474 maPropertyIdToNameMap[Bool_UseSystemColors]="Bool_UseSystemColors";
476 maPropertyNameToIdMap["Bool_IsHighContrastModeActive"]=Bool_IsHighContrastModeActive;
477 maPropertyIdToNameMap[Bool_IsHighContrastModeActive]="Bool_IsHighContrastModeActive";
479 maRawValues.resize(maPropertyIdToNameMap.size());
482 Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem)
484 switch(eItem)
486 case Color_Highlight:
487 case Color_HighlightText:
488 case Color_DeckBackground:
489 case Color_DeckTitleBarBackground:
490 case Color_PanelBackground:
491 case Color_PanelTitleBarBackground:
492 case Color_TabBarBackground:
493 return PT_Color;
495 case Int_DeckBorderSize:
496 case Int_DeckSeparatorHeight:
497 case Int_DeckLeftPadding:
498 case Int_DeckTopPadding:
499 case Int_DeckRightPadding:
500 case Int_DeckBottomPadding:
501 return PT_Integer;
503 case Bool_UseSystemColors:
504 case Bool_IsHighContrastModeActive:
505 return PT_Boolean;
507 default:
508 return PT_Invalid;
512 css::uno::Type const & Theme::GetCppuType (const PropertyType eType)
514 switch(eType)
516 case PT_Color:
517 return cppu::UnoType<sal_uInt32>::get();
519 case PT_Integer:
520 return cppu::UnoType<sal_Int32>::get();
522 case PT_Boolean:
523 return cppu::UnoType<sal_Bool>::get();
525 case PT_Invalid:
526 default:
527 return cppu::UnoType<void>::get();
531 sal_Int32 Theme::GetIndex (const ThemeItem eItem, const PropertyType eType)
533 switch(eType)
535 case PT_Color:
536 return eItem - Pre_Color_-1;
537 case PT_Integer:
538 return eItem - Color_Int_-1;
539 case PT_Boolean:
540 return eItem - Int_Bool_-1;
541 default:
542 OSL_ASSERT(false);
543 return 0;
547 Theme::VetoableListenerContainer* Theme::GetVetoableListeners (
548 const ThemeItem eItem,
549 const bool bCreate)
551 VetoableListeners::iterator iContainer (maVetoableListeners.find(eItem));
552 if (iContainer != maVetoableListeners.end())
553 return &iContainer->second;
554 else if (bCreate)
556 maVetoableListeners[eItem] = VetoableListenerContainer();
557 return &maVetoableListeners[eItem];
559 else
560 return nullptr;
563 Theme::ChangeListenerContainer* Theme::GetChangeListeners (
564 const ThemeItem eItem,
565 const bool bCreate)
567 ChangeListeners::iterator iContainer (maChangeListeners.find(eItem));
568 if (iContainer != maChangeListeners.end())
569 return &iContainer->second;
570 else if (bCreate)
572 maChangeListeners[eItem] = ChangeListenerContainer();
573 return &maChangeListeners[eItem];
575 else
576 return nullptr;
579 bool Theme::DoVetoableListenersVeto (
580 const VetoableListenerContainer* pListeners,
581 const beans::PropertyChangeEvent& rEvent)
583 if (pListeners == nullptr)
584 return false;
586 VetoableListenerContainer aListeners (*pListeners);
589 for (const auto& rxListener : aListeners)
591 rxListener->vetoableChange(rEvent);
594 catch(const beans::PropertyVetoException&)
596 return true;
598 catch(const Exception&)
600 // Ignore any other errors (such as disposed listeners).
602 return false;
605 void Theme::BroadcastPropertyChange (
606 const ChangeListenerContainer* pListeners,
607 const beans::PropertyChangeEvent& rEvent)
609 if (pListeners == nullptr)
610 return;
612 const ChangeListenerContainer aListeners (*pListeners);
615 for (const auto& rxListener : aListeners)
617 rxListener->propertyChange(rEvent);
620 catch(const Exception&)
622 // Ignore any errors (such as disposed listeners).
626 void Theme::ProcessNewValue (
627 const Any& rValue,
628 const ThemeItem eItem,
629 const PropertyType eType)
631 const sal_Int32 nIndex (GetIndex (eItem, eType));
632 switch (eType)
634 case PT_Color:
636 Color nColorValue;
637 if (rValue >>= nColorValue)
638 maColors[nIndex] = nColorValue;
639 break;
641 case PT_Integer:
643 sal_Int32 nValue (0);
644 if (rValue >>= nValue)
646 maIntegers[nIndex] = nValue;
648 break;
650 case PT_Boolean:
652 bool bValue (false);
653 if (rValue >>= bValue)
655 maBooleans[nIndex] = bValue;
656 if (eItem == Bool_IsHighContrastModeActive)
658 mbIsHighContrastModeSetManually = true;
659 mbIsHighContrastMode = maBooleans[nIndex];
660 HandleDataChange();
662 else if (eItem == Bool_UseSystemColors)
664 HandleDataChange();
667 break;
669 case PT_Invalid:
670 OSL_ASSERT(eType != PT_Invalid);
671 throw RuntimeException();
675 } // end of namespace sfx2::sidebar
677 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */