Line data Source code
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 <vcl/IconThemeScanner.hxx>
11 :
12 : #include <config_folders.h>
13 : #include <osl/file.hxx>
14 : #include <rtl/bootstrap.hxx>
15 :
16 : #include <vcl/svapp.hxx>
17 : #include <vcl/IconThemeInfo.hxx>
18 :
19 : namespace vcl {
20 :
21 : namespace {
22 :
23 : bool
24 0 : search_path_is_valid(const OUString& dir)
25 : {
26 0 : osl::DirectoryItem dirItem;
27 0 : osl::FileBase::RC retvalGet = osl::DirectoryItem::get(dir, dirItem);
28 0 : if (retvalGet != osl::FileBase::E_None) {
29 0 : return false;
30 : }
31 0 : osl::FileStatus fileStatus(osl_FileStatus_Mask_Type);
32 0 : osl::FileBase::RC retvalStatus = dirItem.getFileStatus(fileStatus);
33 0 : if (retvalStatus != osl::FileBase::E_None) {
34 0 : return false;
35 : }
36 :
37 0 : if (!fileStatus.isDirectory()) {
38 0 : return false;
39 : }
40 0 : return true;
41 : }
42 :
43 : }
44 :
45 0 : IconThemeScanner::IconThemeScanner()
46 0 : {;}
47 :
48 : bool
49 0 : IconThemeScanner::ScanDirectoryForIconThemes(const OUString& path)
50 : {
51 0 : bool pathIsValid = search_path_is_valid(path);
52 0 : if (!pathIsValid) {
53 0 : return false;
54 : }
55 0 : std::vector<OUString> iconThemePaths = ReadIconThemesFromPath(path);
56 0 : if (iconThemePaths.empty()) {
57 0 : return false;
58 : }
59 0 : mFoundIconThemes.clear();
60 0 : for (std::vector<OUString>::iterator aI = iconThemePaths.begin(); aI != iconThemePaths.end(); ++aI)
61 : {
62 0 : AddIconThemeByPath(*aI);
63 : }
64 0 : return true;
65 : }
66 :
67 : bool
68 0 : IconThemeScanner::AddIconThemeByPath(const OUString &url)
69 : {
70 0 : if (!IconThemeInfo::UrlCanBeParsed(url)) {
71 0 : return false;
72 : }
73 0 : IconThemeInfo newTheme(url);
74 0 : mFoundIconThemes.push_back(newTheme);
75 0 : return true;
76 : }
77 :
78 : /*static*/ std::vector<OUString>
79 0 : IconThemeScanner::ReadIconThemesFromPath(const OUString& dir)
80 : {
81 0 : std::vector<OUString> found;
82 :
83 0 : osl::Directory dirToScan(dir);
84 0 : osl::FileBase::RC retvalOpen = dirToScan.open();
85 0 : if (retvalOpen != osl::FileBase::E_None) {
86 0 : return found;
87 : }
88 :
89 0 : osl::DirectoryItem directoryItem;
90 0 : while (dirToScan.getNextItem(directoryItem) == osl::FileBase::E_None) {
91 0 : osl::FileStatus status(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName);
92 0 : osl::FileBase::RC retvalStatus = directoryItem.getFileStatus(status);
93 0 : if (retvalStatus != osl::FileBase::E_None) {
94 0 : continue;
95 : }
96 0 : if (!status.isRegular()) {
97 0 : continue;
98 : }
99 0 : if (!FileIsValidIconTheme(status.getFileURL())) {
100 0 : continue;
101 : }
102 0 : OUString entry;
103 0 : entry = status.getFileURL();
104 0 : found.push_back(entry);
105 0 : }
106 0 : return found;
107 : }
108 :
109 : /*static*/ bool
110 0 : IconThemeScanner::FileIsValidIconTheme(const OUString& filename)
111 : {
112 : // check whether we can construct a IconThemeInfo from it
113 0 : if (!IconThemeInfo::UrlCanBeParsed(filename)) {
114 0 : return false;
115 : }
116 :
117 : // check whether the file is a regular file
118 0 : osl::DirectoryItem dirItem;
119 0 : osl::FileBase::RC retvalGet = osl::DirectoryItem::get(filename, dirItem);
120 0 : if (retvalGet != osl::FileBase::E_None) {
121 0 : return false;
122 : }
123 0 : osl::FileStatus fileStatus(osl_FileStatus_Mask_Type);
124 0 : osl::FileBase::RC retvalStatus = dirItem.getFileStatus(fileStatus);
125 0 : if (retvalStatus != osl::FileBase::E_None) {
126 0 : return false;
127 : }
128 0 : if (!fileStatus.isRegular()) {
129 0 : return false;
130 : }
131 0 : return true;
132 : }
133 :
134 : bool
135 0 : IconThemeScanner::IconThemeIsInstalled(const OUString& themeId) const
136 : {
137 0 : return IconThemeInfo::IconThemeIsInVector(mFoundIconThemes, themeId);
138 : }
139 :
140 : /*static*/ boost::shared_ptr<IconThemeScanner>
141 0 : IconThemeScanner::Create(const OUString &path)
142 : {
143 0 : boost::shared_ptr<IconThemeScanner> retval(new IconThemeScanner);
144 0 : retval->ScanDirectoryForIconThemes(path);
145 0 : return retval;
146 : }
147 :
148 : /*static*/ OUString
149 0 : IconThemeScanner::GetStandardIconThemePath()
150 : {
151 0 : OUString url( "$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/config/" );
152 0 : rtl::Bootstrap::expandMacros(url);
153 0 : return url;
154 : }
155 :
156 0 : IconThemeScanner::~IconThemeScanner()
157 0 : {;}
158 :
159 : namespace
160 : {
161 : class SameTheme :
162 : public std::unary_function<const vcl::IconThemeInfo &, bool>
163 : {
164 : private:
165 : const OUString& m_rThemeId;
166 : public:
167 0 : SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
168 0 : bool operator()(const vcl::IconThemeInfo &rInfo)
169 : {
170 0 : return m_rThemeId == rInfo.GetThemeId();
171 : }
172 : };
173 : }
174 :
175 : const vcl::IconThemeInfo&
176 0 : IconThemeScanner::GetIconThemeInfo(const OUString& themeId)
177 : {
178 : std::vector<IconThemeInfo>::iterator info = std::find_if(mFoundIconThemes.begin(), mFoundIconThemes.end(),
179 0 : SameTheme(themeId));
180 0 : if (info == mFoundIconThemes.end()) {
181 0 : throw std::runtime_error("Requested information on not-installed icon theme");
182 : }
183 0 : return *info;
184 : }
185 :
186 : } // end namespace vcl
187 :
188 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|