1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include <vcl/IconThemeInfo.hxx>
11 #include <rtl/character.hxx>
16 // constants for theme ids and display names. (The theme id for high contrast is used
17 // outside of this class and hence made public in IconThemeInfo.)
21 constexpr OUStringLiteral
HELPIMG_FAKE_THEME(u
"helpimg");
24 filename_from_url(std::u16string_view url
)
26 size_t slashPosition
= url
.rfind( '/' );
27 if (slashPosition
== std::u16string_view::npos
) {
30 OUString
filename( url
.substr( slashPosition
+1 ) );
34 } // end anonymous namespace
38 const sal_Unicode ICON_THEME_PACKAGE_PREFIX
[] = u
"images_";
40 const sal_Unicode EXTENSION_FOR_ICON_PACKAGES
[] = u
".zip";
42 IconThemeInfo::IconThemeInfo()
46 IconThemeInfo::IconThemeInfo(const OUString
& urlToFile
)
47 : mUrlToFile(urlToFile
)
49 OUString filename
= filename_from_url(urlToFile
);
50 if (filename
.isEmpty()) {
51 throw std::runtime_error("invalid URL passed to IconThemeInfo()");
54 mThemeId
= FileNameToThemeId(filename
);
55 mDisplayName
= ThemeIdToDisplayName(mThemeId
);
60 IconThemeInfo::SizeByThemeName(std::u16string_view themeName
)
62 if (themeName
== u
"galaxy") { //kept for compiler because of unused parameter 'themeName'
63 return Size( 26, 26 );
66 return Size( 24, 24 );
71 IconThemeInfo::UrlCanBeParsed(std::u16string_view url
)
73 OUString fname
= filename_from_url(url
);
74 if (fname
.isEmpty()) {
78 if (!fname
.startsWithIgnoreAsciiCase(ICON_THEME_PACKAGE_PREFIX
)) {
82 if (!fname
.endsWithIgnoreAsciiCase(EXTENSION_FOR_ICON_PACKAGES
)) {
86 if (fname
.indexOf(HELPIMG_FAKE_THEME
) != -1 ) {
94 IconThemeInfo::FileNameToThemeId(std::u16string_view filename
)
97 size_t positionOfLastDot
= filename
.rfind(EXTENSION_FOR_ICON_PACKAGES
);
98 if (positionOfLastDot
== std::u16string_view::npos
) { // means index not found
99 throw std::runtime_error("IconThemeInfo::FileNameToThemeId() called with invalid filename.");
101 size_t positionOfFirstUnderscore
= filename
.find(ICON_THEME_PACKAGE_PREFIX
);
102 if (positionOfFirstUnderscore
== std::u16string_view::npos
) { // means index not found. Use the whole name instead
103 throw std::runtime_error("IconThemeInfo::FileNameToThemeId() called with invalid filename.");
105 positionOfFirstUnderscore
+= RTL_CONSTASCII_LENGTH(ICON_THEME_PACKAGE_PREFIX
);
106 r
= filename
.substr(positionOfFirstUnderscore
, positionOfLastDot
- positionOfFirstUnderscore
);
111 IconThemeInfo::ThemeIdToDisplayName(const OUString
& themeId
)
113 if (themeId
.isEmpty()) {
114 throw std::runtime_error("IconThemeInfo::ThemeIdToDisplayName() called with invalid id.");
117 // Strip _svg and _dark filename "extensions"
118 OUString aDisplayName
= themeId
;
120 bool bIsSvg
= aDisplayName
.endsWith("_svg", &aDisplayName
);
121 bool bIsDark
= aDisplayName
.endsWith("_dark", &aDisplayName
);
122 if (!bIsSvg
&& bIsDark
)
123 bIsSvg
= aDisplayName
.endsWith("_svg", &aDisplayName
);
125 // make the first letter uppercase
126 sal_Unicode firstLetter
= aDisplayName
[0];
127 if (rtl::isAsciiLowerCase(firstLetter
))
129 aDisplayName
= OUStringChar(sal_Unicode(rtl::toAsciiUpperCase(firstLetter
))) + aDisplayName
.subView(1);
132 // replacing underscores with spaces of multi words pack name.
133 aDisplayName
= aDisplayName
.replace('_', ' ');
135 if (bIsSvg
&& bIsDark
)
136 aDisplayName
+= " (SVG + dark)";
138 aDisplayName
+= " (SVG)";
140 aDisplayName
+= " (dark)";
150 const OUString
& m_rThemeId
;
152 explicit SameTheme(const OUString
&rThemeId
) : m_rThemeId(rThemeId
) {}
153 bool operator()(const vcl::IconThemeInfo
&rInfo
)
155 return m_rThemeId
== rInfo
.GetThemeId();
160 /*static*/ const vcl::IconThemeInfo
&
161 IconThemeInfo::FindIconThemeById(const std::vector
<vcl::IconThemeInfo
>& themes
, const OUString
& themeId
)
163 std::vector
<vcl::IconThemeInfo
>::const_iterator it
= std::find_if(themes
.begin(), themes
.end(),
165 if (it
== themes
.end())
167 throw std::runtime_error("Could not find theme id in theme vector.");
173 IconThemeInfo::IconThemeIsInVector(const std::vector
<vcl::IconThemeInfo
>& themes
, const OUString
& themeId
)
175 return std::any_of(themes
.begin(), themes
.end(), SameTheme(themeId
));
178 } // end namespace vcl
180 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */