18e65dd08STakeshi Abe /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2076a7eacSTobias Lippert /*
3076a7eacSTobias Lippert * This file is part of the LibreOffice project.
4076a7eacSTobias Lippert *
5076a7eacSTobias Lippert * This Source Code Form is subject to the terms of the Mozilla Public
6076a7eacSTobias Lippert * License, v. 2.0. If a copy of the MPL was not distributed with this
7076a7eacSTobias Lippert * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8076a7eacSTobias Lippert */
9076a7eacSTobias Lippert
10076a7eacSTobias Lippert #include <vcl/IconThemeInfo.hxx>
11076a7eacSTobias Lippert #include <rtl/character.hxx>
12076a7eacSTobias Lippert
13076a7eacSTobias Lippert #include <stdexcept>
14076a7eacSTobias Lippert #include <algorithm>
15076a7eacSTobias Lippert
16e6dfaf9fSStephan Bergmann // constants for theme ids and display names. (The theme id for high contrast is used
17e6dfaf9fSStephan Bergmann // outside of this class and hence made public in IconThemeInfo.)
182a0118a9STobias Lippert
19076a7eacSTobias Lippert namespace {
20076a7eacSTobias Lippert
21de74d98cSCaolán McNamara constexpr OUStringLiteral HELPIMG_FAKE_THEME(u"helpimg");
227e7b9652SKatarina Behrens
23076a7eacSTobias Lippert OUString
filename_from_url(std::u16string_view url)24239752d3SNoel Grandin filename_from_url(std::u16string_view url)
25076a7eacSTobias Lippert {
26239752d3SNoel Grandin size_t slashPosition = url.rfind( '/' );
27239752d3SNoel Grandin if (slashPosition == std::u16string_view::npos) {
281fdb0e18SArnaud Versini return OUString();
29076a7eacSTobias Lippert }
30239752d3SNoel Grandin OUString filename( url.substr( slashPosition+1 ) );
31076a7eacSTobias Lippert return filename;
32076a7eacSTobias Lippert }
33076a7eacSTobias Lippert
342a0118a9STobias Lippert } // end anonymous namespace
35076a7eacSTobias Lippert
36076a7eacSTobias Lippert namespace vcl {
37076a7eacSTobias Lippert
38239752d3SNoel Grandin const sal_Unicode ICON_THEME_PACKAGE_PREFIX[] = u"images_";
39076a7eacSTobias Lippert
40239752d3SNoel Grandin const sal_Unicode EXTENSION_FOR_ICON_PACKAGES[] = u".zip";
41076a7eacSTobias Lippert
IconThemeInfo()42076a7eacSTobias Lippert IconThemeInfo::IconThemeInfo()
43076a7eacSTobias Lippert {
44076a7eacSTobias Lippert }
45076a7eacSTobias Lippert
IconThemeInfo(const OUString & urlToFile)46076a7eacSTobias Lippert IconThemeInfo::IconThemeInfo(const OUString& urlToFile)
47076a7eacSTobias Lippert : mUrlToFile(urlToFile)
48076a7eacSTobias Lippert {
49076a7eacSTobias Lippert OUString filename = filename_from_url(urlToFile);
50076a7eacSTobias Lippert if (filename.isEmpty()) {
51076a7eacSTobias Lippert throw std::runtime_error("invalid URL passed to IconThemeInfo()");
52076a7eacSTobias Lippert }
53076a7eacSTobias Lippert
54076a7eacSTobias Lippert mThemeId = FileNameToThemeId(filename);
55076a7eacSTobias Lippert mDisplayName = ThemeIdToDisplayName(mThemeId);
56076a7eacSTobias Lippert
57076a7eacSTobias Lippert }
58076a7eacSTobias Lippert
59076a7eacSTobias Lippert /*static*/ Size
SizeByThemeName(std::u16string_view themeName)608332d6d8SNoel IconThemeInfo::SizeByThemeName(std::u16string_view themeName)
61076a7eacSTobias Lippert {
628332d6d8SNoel if (themeName == u"galaxy") { //kept for compiler because of unused parameter 'themeName'
6360413c98Sheiko tietze return Size( 26, 26 );
6460413c98Sheiko tietze }
6560413c98Sheiko tietze else {
6660413c98Sheiko tietze return Size( 24, 24 );
6760413c98Sheiko tietze }
68076a7eacSTobias Lippert }
69076a7eacSTobias Lippert
70076a7eacSTobias Lippert /*static*/ bool
UrlCanBeParsed(std::u16string_view url)71239752d3SNoel Grandin IconThemeInfo::UrlCanBeParsed(std::u16string_view url)
72076a7eacSTobias Lippert {
73076a7eacSTobias Lippert OUString fname = filename_from_url(url);
74076a7eacSTobias Lippert if (fname.isEmpty()) {
75076a7eacSTobias Lippert return false;
76076a7eacSTobias Lippert }
77076a7eacSTobias Lippert
78076a7eacSTobias Lippert if (!fname.startsWithIgnoreAsciiCase(ICON_THEME_PACKAGE_PREFIX)) {
79076a7eacSTobias Lippert return false;
80076a7eacSTobias Lippert }
81076a7eacSTobias Lippert
8279b6edcbSCaolán McNamara if (!fname.endsWithIgnoreAsciiCase(EXTENSION_FOR_ICON_PACKAGES)) {
83076a7eacSTobias Lippert return false;
84076a7eacSTobias Lippert }
85076a7eacSTobias Lippert
867e7b9652SKatarina Behrens if (fname.indexOf(HELPIMG_FAKE_THEME) != -1 ) {
877e7b9652SKatarina Behrens return false;
887e7b9652SKatarina Behrens }
897e7b9652SKatarina Behrens
90076a7eacSTobias Lippert return true;
91076a7eacSTobias Lippert }
92076a7eacSTobias Lippert
93076a7eacSTobias Lippert /*static*/ OUString
FileNameToThemeId(std::u16string_view filename)94239752d3SNoel Grandin IconThemeInfo::FileNameToThemeId(std::u16string_view filename)
95076a7eacSTobias Lippert {
96076a7eacSTobias Lippert OUString r;
97239752d3SNoel Grandin size_t positionOfLastDot = filename.rfind(EXTENSION_FOR_ICON_PACKAGES);
98239752d3SNoel Grandin if (positionOfLastDot == std::u16string_view::npos) { // means index not found
99076a7eacSTobias Lippert throw std::runtime_error("IconThemeInfo::FileNameToThemeId() called with invalid filename.");
100076a7eacSTobias Lippert }
101239752d3SNoel Grandin size_t positionOfFirstUnderscore = filename.find(ICON_THEME_PACKAGE_PREFIX);
102239752d3SNoel Grandin if (positionOfFirstUnderscore == std::u16string_view::npos) { // means index not found. Use the whole name instead
103076a7eacSTobias Lippert throw std::runtime_error("IconThemeInfo::FileNameToThemeId() called with invalid filename.");
104076a7eacSTobias Lippert }
105076a7eacSTobias Lippert positionOfFirstUnderscore += RTL_CONSTASCII_LENGTH(ICON_THEME_PACKAGE_PREFIX);
106239752d3SNoel Grandin r = filename.substr(positionOfFirstUnderscore, positionOfLastDot - positionOfFirstUnderscore);
107076a7eacSTobias Lippert return r;
108076a7eacSTobias Lippert }
109076a7eacSTobias Lippert
110076a7eacSTobias Lippert /*static*/ OUString
ThemeIdToDisplayName(const OUString & themeId)111076a7eacSTobias Lippert IconThemeInfo::ThemeIdToDisplayName(const OUString& themeId)
112076a7eacSTobias Lippert {
113076a7eacSTobias Lippert if (themeId.isEmpty()) {
114076a7eacSTobias Lippert throw std::runtime_error("IconThemeInfo::ThemeIdToDisplayName() called with invalid id.");
115076a7eacSTobias Lippert }
116076a7eacSTobias Lippert
117b0dbd78dSJan-Marek Glogowski // Strip _svg and _dark filename "extensions"
118b0dbd78dSJan-Marek Glogowski OUString aDisplayName = themeId;
1192a0118a9STobias Lippert
120b0dbd78dSJan-Marek Glogowski bool bIsSvg = aDisplayName.endsWith("_svg", &aDisplayName);
121b0dbd78dSJan-Marek Glogowski bool bIsDark = aDisplayName.endsWith("_dark", &aDisplayName);
122b0dbd78dSJan-Marek Glogowski if (!bIsSvg && bIsDark)
123b0dbd78dSJan-Marek Glogowski bIsSvg = aDisplayName.endsWith("_svg", &aDisplayName);
124a06954bfSRizal Muttaqin
125*02b740a7SZain Iftikhar // make the first letter uppercase
126*02b740a7SZain Iftikhar sal_Unicode firstLetter = aDisplayName[0];
127*02b740a7SZain Iftikhar if (rtl::isAsciiLowerCase(firstLetter))
128b0dbd78dSJan-Marek Glogowski {
129*02b740a7SZain Iftikhar aDisplayName = OUStringChar(sal_Unicode(rtl::toAsciiUpperCase(firstLetter))) + aDisplayName.subView(1);
130076a7eacSTobias Lippert }
1312a0118a9STobias Lippert
132*02b740a7SZain Iftikhar // replacing underscores with spaces of multi words pack name.
133*02b740a7SZain Iftikhar aDisplayName = aDisplayName.replace('_', ' ');
134*02b740a7SZain Iftikhar
135b0dbd78dSJan-Marek Glogowski if (bIsSvg && bIsDark)
136b0dbd78dSJan-Marek Glogowski aDisplayName += " (SVG + dark)";
137b0dbd78dSJan-Marek Glogowski else if (bIsSvg)
138b0dbd78dSJan-Marek Glogowski aDisplayName += " (SVG)";
139b0dbd78dSJan-Marek Glogowski else if (bIsDark)
140b0dbd78dSJan-Marek Glogowski aDisplayName += " (dark)";
141b0dbd78dSJan-Marek Glogowski
142b0dbd78dSJan-Marek Glogowski return aDisplayName;
143076a7eacSTobias Lippert }
144076a7eacSTobias Lippert
145076a7eacSTobias Lippert namespace
146076a7eacSTobias Lippert {
147c4ddf6cdSJochen Nitschke class SameTheme
148076a7eacSTobias Lippert {
149076a7eacSTobias Lippert private:
150076a7eacSTobias Lippert const OUString& m_rThemeId;
151076a7eacSTobias Lippert public:
SameTheme(const OUString & rThemeId)152acad8441SCaolán McNamara explicit SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
operator ()(const vcl::IconThemeInfo & rInfo)153076a7eacSTobias Lippert bool operator()(const vcl::IconThemeInfo &rInfo)
154076a7eacSTobias Lippert {
155076a7eacSTobias Lippert return m_rThemeId == rInfo.GetThemeId();
156076a7eacSTobias Lippert }
157076a7eacSTobias Lippert };
158076a7eacSTobias Lippert }
159076a7eacSTobias Lippert
160076a7eacSTobias Lippert /*static*/ const vcl::IconThemeInfo&
FindIconThemeById(const std::vector<vcl::IconThemeInfo> & themes,const OUString & themeId)161076a7eacSTobias Lippert IconThemeInfo::FindIconThemeById(const std::vector<vcl::IconThemeInfo>& themes, const OUString& themeId)
162076a7eacSTobias Lippert {
163076a7eacSTobias Lippert std::vector<vcl::IconThemeInfo>::const_iterator it = std::find_if(themes.begin(), themes.end(),
164076a7eacSTobias Lippert SameTheme(themeId));
165076a7eacSTobias Lippert if (it == themes.end())
166076a7eacSTobias Lippert {
167076a7eacSTobias Lippert throw std::runtime_error("Could not find theme id in theme vector.");
168076a7eacSTobias Lippert }
169076a7eacSTobias Lippert return *it;
170076a7eacSTobias Lippert }
171076a7eacSTobias Lippert
172076a7eacSTobias Lippert /*static*/ bool
IconThemeIsInVector(const std::vector<vcl::IconThemeInfo> & themes,const OUString & themeId)173076a7eacSTobias Lippert IconThemeInfo::IconThemeIsInVector(const std::vector<vcl::IconThemeInfo>& themes, const OUString& themeId)
174076a7eacSTobias Lippert {
1756a26624dSTakeshi Abe return std::any_of(themes.begin(), themes.end(), SameTheme(themeId));
176076a7eacSTobias Lippert }
177076a7eacSTobias Lippert
178076a7eacSTobias Lippert } // end namespace vcl
179076a7eacSTobias Lippert
1808e65dd08STakeshi Abe /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
181