summaryrefslogtreecommitdiff
path: root/vcl/source/app/UserResourceScanner.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/app/UserResourceScanner.cxx')
-rw-r--r--vcl/source/app/UserResourceScanner.cxx137
1 files changed, 137 insertions, 0 deletions
diff --git a/vcl/source/app/UserResourceScanner.cxx b/vcl/source/app/UserResourceScanner.cxx
new file mode 100644
index 000000000000..353004712c44
--- /dev/null
+++ b/vcl/source/app/UserResourceScanner.cxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vcl/UserResourceScanner.hxx>
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <salhelper/linkhelper.hxx>
+#include <unotools/pathoptions.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <deque>
+
+namespace vcl
+{
+namespace
+{
+OUString convertToAbsolutePath(const OUString& path)
+{
+ salhelper::LinkResolver resolver(0);
+ osl::FileBase::RC rc = resolver.fetchFileStatus(path);
+ if (rc != osl::FileBase::E_None)
+ {
+ SAL_WARN("vcl.app", "Could not resolve path '" << path << "' to search for icon themes.");
+ if (rc == osl::FileBase::E_MULTIHOP)
+ {
+ throw std::runtime_error("Provided a recursive symlink to an icon theme directory that "
+ "could not be resolved.");
+ }
+ }
+ return resolver.m_aStatus.getFileURL();
+}
+}
+
+namespace file
+{
+// read the status of a file. Returns false if the status could not be determined.
+bool readFileStatus(osl::FileStatus& status, const OUString& file)
+{
+ osl::DirectoryItem dirItem;
+ osl::FileBase::RC retvalGet = osl::DirectoryItem::get(file, dirItem);
+ if (retvalGet != osl::FileBase::E_None)
+ {
+ SAL_WARN("vcl.app", "Could not determine status for file '" << file << "'.");
+ return false;
+ }
+ osl::FileBase::RC retvalStatus = dirItem.getFileStatus(status);
+ if (retvalStatus != osl::FileBase::E_None)
+ {
+ SAL_WARN("vcl.app", "Could not determine status for file '" << file << "'.");
+ return false;
+ }
+ return true;
+}
+
+void splitPathString(std::u16string_view aPathString, std::deque<OUString>& rPaths)
+{
+ sal_Int32 nIndex = 0;
+ do
+ {
+ rPaths.push_front(OUString(o3tl::getToken(aPathString, 0, ';', nIndex)));
+ } while (nIndex >= 0);
+}
+}
+
+UserResourceScanner::UserResourceScanner() = default;
+
+void UserResourceScanner::addPaths(std::u16string_view aPathString)
+{
+ std::deque<OUString> aPaths;
+ vcl::file::splitPathString(aPathString, aPaths);
+
+ for (const auto& path : aPaths)
+ {
+ osl::FileStatus aFileStatus(osl_FileStatus_Mask_Type);
+
+ if (!vcl::file::readFileStatus(aFileStatus, path))
+ continue;
+
+ if (!aFileStatus.isDirectory())
+ {
+ SAL_INFO("vcl.app", "Can not search for resource files in '"
+ << path << "'. It is not a directory.");
+ continue;
+ }
+
+ std::vector<OUString> aResourcePaths = readFilesFromPath(path);
+
+ if (aResourcePaths.empty())
+ {
+ SAL_WARN("vcl.app",
+ "Could not find any file in the provided directory ('" << path << "'.");
+ continue;
+ }
+
+ for (auto const& iconThemePath : aResourcePaths)
+ addResource(iconThemePath);
+ }
+}
+
+std::vector<OUString> UserResourceScanner::readFilesFromPath(const OUString& dir)
+{
+ std::vector<OUString> found;
+ SAL_INFO("vcl", "Scanning directory '" << dir << " for potential resource files.");
+
+ osl::Directory dirToScan(dir);
+ osl::FileBase::RC retvalOpen = dirToScan.open();
+ if (retvalOpen != osl::FileBase::E_None)
+ return found;
+
+ osl::DirectoryItem directoryItem;
+ while (dirToScan.getNextItem(directoryItem) == osl::FileBase::E_None)
+ {
+ osl::FileStatus status(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL
+ | osl_FileStatus_Mask_FileName);
+ osl::FileBase::RC retvalStatus = directoryItem.getFileStatus(status);
+ if (retvalStatus != osl::FileBase::E_None)
+ continue;
+
+ OUString filename = convertToAbsolutePath(status.getFileURL());
+ if (isValidResource(filename))
+ found.push_back(filename);
+ }
+
+ return found;
+}
+
+} // end namespace vcl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */