diff options
Diffstat (limited to 'vcl/source/app/UserResourceScanner.cxx')
-rw-r--r-- | vcl/source/app/UserResourceScanner.cxx | 137 |
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: */ |