/src/libreoffice/vcl/source/app/UserResourceScanner.cxx
Line | Count | Source |
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/UserResourceScanner.hxx> |
11 | | |
12 | | #include <sal/config.h> |
13 | | #include <sal/log.hxx> |
14 | | |
15 | | #include <salhelper/linkhelper.hxx> |
16 | | #include <unotools/pathoptions.hxx> |
17 | | #include <o3tl/string_view.hxx> |
18 | | |
19 | | #include <deque> |
20 | | |
21 | | namespace vcl |
22 | | { |
23 | | namespace |
24 | | { |
25 | | OUString convertToAbsolutePath(const OUString& path) |
26 | 0 | { |
27 | 0 | salhelper::LinkResolver resolver(0); |
28 | 0 | osl::FileBase::RC rc = resolver.fetchFileStatus(path); |
29 | 0 | if (rc != osl::FileBase::E_None) |
30 | 0 | { |
31 | 0 | SAL_INFO("vcl.app", "Could not resolve path '" << path << "' to search for icon themes."); |
32 | 0 | if (rc == osl::FileBase::E_MULTIHOP) |
33 | 0 | { |
34 | 0 | throw std::runtime_error("Provided a recursive symlink to an icon theme directory that " |
35 | 0 | "could not be resolved."); |
36 | 0 | } |
37 | 0 | } |
38 | 0 | return resolver.m_aStatus.getFileURL(); |
39 | 0 | } |
40 | | } |
41 | | |
42 | | namespace file |
43 | | { |
44 | | // read the status of a file. Returns false if the status could not be determined. |
45 | | bool readFileStatus(osl::FileStatus& status, const OUString& file) |
46 | 0 | { |
47 | 0 | osl::DirectoryItem dirItem; |
48 | 0 | osl::FileBase::RC retvalGet = osl::DirectoryItem::get(file, dirItem); |
49 | 0 | if (retvalGet != osl::FileBase::E_None) |
50 | 0 | { |
51 | 0 | if (retvalGet == osl::FileBase::E_NOENT) |
52 | 0 | SAL_INFO("vcl.app", "Directory doesn't exist '" << file << "'."); |
53 | 0 | else |
54 | 0 | SAL_INFO("vcl.app", "Could not determine status for file '" |
55 | 0 | << file << "' Return code: '" << retvalGet << "'."); |
56 | 0 | return false; |
57 | 0 | } |
58 | 0 | osl::FileBase::RC retvalStatus = dirItem.getFileStatus(status); |
59 | 0 | if (retvalStatus != osl::FileBase::E_None) |
60 | 0 | { |
61 | 0 | SAL_INFO("vcl.app", "Could not determine status for file '" << file << "'."); |
62 | 0 | return false; |
63 | 0 | } |
64 | 0 | return true; |
65 | 0 | } |
66 | | |
67 | | void splitPathString(std::u16string_view aPathString, std::deque<OUString>& rPaths) |
68 | 0 | { |
69 | 0 | sal_Int32 nIndex = 0; |
70 | 0 | do |
71 | 0 | { |
72 | 0 | rPaths.push_front(OUString(o3tl::getToken(aPathString, 0, ';', nIndex))); |
73 | 0 | } while (nIndex >= 0); |
74 | 0 | } |
75 | | } |
76 | | |
77 | 22 | UserResourceScanner::UserResourceScanner() = default; |
78 | | |
79 | | void UserResourceScanner::addPaths(std::u16string_view aPathString) |
80 | 0 | { |
81 | 0 | std::deque<OUString> aPaths; |
82 | 0 | vcl::file::splitPathString(aPathString, aPaths); |
83 | |
|
84 | 0 | for (const auto& path : aPaths) |
85 | 0 | { |
86 | 0 | osl::FileStatus aFileStatus(osl_FileStatus_Mask_Type); |
87 | |
|
88 | 0 | if (!vcl::file::readFileStatus(aFileStatus, path)) |
89 | 0 | continue; |
90 | | |
91 | 0 | if (!aFileStatus.isDirectory()) |
92 | 0 | { |
93 | 0 | SAL_INFO("vcl.app", "Can not search for resource files in '" |
94 | 0 | << path << "'. It is not a directory."); |
95 | 0 | continue; |
96 | 0 | } |
97 | | |
98 | 0 | std::vector<OUString> aResourcePaths = readFilesFromPath(path); |
99 | |
|
100 | 0 | if (aResourcePaths.empty()) |
101 | 0 | { |
102 | 0 | SAL_INFO("vcl.app", |
103 | 0 | "Could not find any file in the provided directory ('" << path << "'."); |
104 | 0 | continue; |
105 | 0 | } |
106 | | |
107 | 0 | for (auto const& iconThemePath : aResourcePaths) |
108 | 0 | addResource(iconThemePath); |
109 | 0 | } |
110 | 0 | } |
111 | | |
112 | | std::vector<OUString> UserResourceScanner::readFilesFromPath(const OUString& dir) |
113 | 0 | { |
114 | 0 | std::vector<OUString> found; |
115 | 0 | SAL_INFO("vcl", "Scanning directory '" << dir << " for potential resource files."); |
116 | | |
117 | 0 | osl::Directory dirToScan(dir); |
118 | 0 | osl::FileBase::RC retvalOpen = dirToScan.open(); |
119 | 0 | if (retvalOpen != osl::FileBase::E_None) |
120 | 0 | return found; |
121 | | |
122 | 0 | osl::DirectoryItem directoryItem; |
123 | 0 | while (dirToScan.getNextItem(directoryItem) == osl::FileBase::E_None) |
124 | 0 | { |
125 | 0 | osl::FileStatus status(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL |
126 | 0 | | osl_FileStatus_Mask_FileName); |
127 | 0 | osl::FileBase::RC retvalStatus = directoryItem.getFileStatus(status); |
128 | 0 | if (retvalStatus != osl::FileBase::E_None) |
129 | 0 | continue; |
130 | | |
131 | 0 | OUString filename = convertToAbsolutePath(status.getFileURL()); |
132 | 0 | if (isValidResource(filename)) |
133 | 0 | found.push_back(filename); |
134 | 0 | } |
135 | |
|
136 | 0 | return found; |
137 | 0 | } |
138 | | |
139 | | } // end namespace vcl |
140 | | |
141 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |