xref: /core/vcl/source/app/IconThemeSelector.cxx (revision 40dde438)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  */
9 
10 #include <comphelper/lok.hxx>
11 
12 #include <IconThemeSelector.hxx>
13 
14 #include <tools/color.hxx>
15 #include <vcl/IconThemeInfo.hxx>
16 #include <vcl/settings.hxx>
17 #include <vcl/svapp.hxx>
18 #include <config_mpl.h>
19 
20 #include <algorithm>
21 
22 namespace vcl {
23 
24 namespace {
25 
26     class SameTheme
27     {
28     private:
29         const OUString& m_rThemeId;
30     public:
SameTheme(const OUString & rThemeId)31         explicit SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
operator ()(const vcl::IconThemeInfo & rInfo)32         bool operator()(const vcl::IconThemeInfo &rInfo)
33         {
34             return m_rThemeId == rInfo.GetThemeId();
35         }
36     };
37 
icon_theme_is_in_installed_themes(const OUString & theme,const std::vector<IconThemeInfo> & installedThemes)38 bool icon_theme_is_in_installed_themes(const OUString& theme,
39         const std::vector<IconThemeInfo>& installedThemes)
40 {
41     return std::any_of(installedThemes.begin(), installedThemes.end(),
42                        SameTheme(theme));
43 }
44 
45 } // end anonymous namespace
46 
IconThemeSelector()47 IconThemeSelector::IconThemeSelector()
48     : mUseHighContrastTheme(false)
49     , mPreferDarkIconTheme(false)
50 {
51 }
52 
53 /*static*/ OUString
GetIconThemeForDesktopEnvironment(const OUString & desktopEnvironment,bool bPreferDarkIconTheme)54 IconThemeSelector::GetIconThemeForDesktopEnvironment(const OUString& desktopEnvironment, bool bPreferDarkIconTheme)
55 {
56     if (comphelper::LibreOfficeKit::isActive())
57     {
58         if (!bPreferDarkIconTheme)
59             return u"colibre"_ustr;
60         else
61             return u"colibre_dark"_ustr;
62     }
63 
64 #ifdef _WIN32
65     (void)desktopEnvironment;
66     if (!bPreferDarkIconTheme)
67         return "colibre";
68     else
69         return "colibre_dark";
70 #else
71     OUString r;
72     if ( desktopEnvironment.equalsIgnoreAsciiCase("plasma5") ||
73          desktopEnvironment.equalsIgnoreAsciiCase("plasma6") ||
74          desktopEnvironment.equalsIgnoreAsciiCase("lxqt") ) {
75         if (!bPreferDarkIconTheme)
76             r = "breeze";
77         else
78             r = "breeze_dark";
79     }
80     else if ( desktopEnvironment.equalsIgnoreAsciiCase("macosx") ) {
81         if (!bPreferDarkIconTheme)
82             r = "sukapura_svg";
83         else
84             r = "sukapura_dark_svg";
85     }
86     else if ( desktopEnvironment.equalsIgnoreAsciiCase("gnome") ||
87          desktopEnvironment.equalsIgnoreAsciiCase("mate") ||
88          desktopEnvironment.equalsIgnoreAsciiCase("unity") ) {
89         if (!bPreferDarkIconTheme)
90             r = "elementary";
91         else
92             r = "sifr_dark";
93     } else
94     {
95         if (!bPreferDarkIconTheme)
96             r = FALLBACK_LIGHT_ICON_THEME_ID;
97         else
98             r = FALLBACK_DARK_ICON_THEME_ID;
99     }
100     return r;
101 #endif // _WIN32
102 }
103 
104 OUString
SelectIconThemeForDesktopEnvironment(const std::vector<IconThemeInfo> & installedThemes,const OUString & desktopEnvironment) const105 IconThemeSelector::SelectIconThemeForDesktopEnvironment(
106         const std::vector<IconThemeInfo>& installedThemes,
107         const OUString& desktopEnvironment) const
108 {
109     if (!mPreferredIconTheme.isEmpty()) {
110         if (icon_theme_is_in_installed_themes(mPreferredIconTheme, installedThemes)) {
111             return mPreferredIconTheme;
112         }
113     }
114 
115     OUString themeForDesktop = GetIconThemeForDesktopEnvironment(desktopEnvironment, mPreferDarkIconTheme);
116     if (icon_theme_is_in_installed_themes(themeForDesktop, installedThemes)) {
117         return themeForDesktop;
118     }
119 
120     return ReturnFallback(installedThemes);
121 }
122 
123 OUString
SelectIconTheme(const std::vector<IconThemeInfo> & installedThemes,const OUString & theme) const124 IconThemeSelector::SelectIconTheme(
125         const std::vector<IconThemeInfo>& installedThemes,
126         const OUString& theme) const
127 {
128     if (mUseHighContrastTheme) {
129         const Color aCol(Application::GetSettings().GetStyleSettings().GetWindowColor());
130         const OUString name(aCol.IsDark() ? IconThemeInfo::HIGH_CONTRAST_ID_DARK
131                                           : IconThemeInfo::HIGH_CONTRAST_ID_BRIGHT);
132         if (icon_theme_is_in_installed_themes(name, installedThemes)) {
133             return name;
134         }
135     }
136 
137     if (icon_theme_is_in_installed_themes(theme, installedThemes)) {
138         return theme;
139     }
140 
141     return ReturnFallback(installedThemes);
142 }
143 
144 void
SetUseHighContrastTheme(bool v)145 IconThemeSelector::SetUseHighContrastTheme(bool v)
146 {
147     mUseHighContrastTheme = v;
148 }
149 
150 bool
SetPreferredIconTheme(const OUString & theme,bool bDarkIconTheme)151 IconThemeSelector::SetPreferredIconTheme(const OUString& theme, bool bDarkIconTheme)
152 {
153     // lower case theme name, and (tdf#120175) replace - with _
154     // see icon-themes/README
155     OUString sIconTheme = theme.toAsciiLowerCase().replace('-','_');
156 
157     const bool bChanged = mPreferredIconTheme != sIconTheme || mPreferDarkIconTheme != bDarkIconTheme;
158     if (bChanged)
159     {
160         mPreferredIconTheme = sIconTheme;
161         mPreferDarkIconTheme = bDarkIconTheme;
162     }
163     return bChanged;
164 }
165 
166 bool
operator ==(const vcl::IconThemeSelector & other) const167 IconThemeSelector::operator==(const vcl::IconThemeSelector& other) const
168 {
169     if (this == &other) {
170         return true;
171     }
172     if (mPreferredIconTheme != other.mPreferredIconTheme) {
173         return false;
174     }
175     if (mPreferDarkIconTheme != other.mPreferDarkIconTheme) {
176         return false;
177     }
178     if (mUseHighContrastTheme != other.mUseHighContrastTheme) {
179         return false;
180     }
181     return true;
182 }
183 
184 bool
operator !=(const vcl::IconThemeSelector & other) const185 IconThemeSelector::operator!=(const vcl::IconThemeSelector& other) const
186 {
187     return !(*this == other);
188 }
189 
190 /*static*/ OUString
ReturnFallback(const std::vector<IconThemeInfo> & installedThemes)191 IconThemeSelector::ReturnFallback(const std::vector<IconThemeInfo>& installedThemes)
192 {
193     if (!installedThemes.empty()) {
194         return installedThemes.front().GetThemeId();
195     }
196     else {
197         return FALLBACK_LIGHT_ICON_THEME_ID;
198     }
199 }
200 
201 } /* namespace vcl */
202 
203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
204