diff options
author | Tobias Lippert <drtl@fastmail.fm> | 2014-02-09 00:53:28 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2014-02-21 17:23:50 +0000 |
commit | 076a7eacca48f203f0a8b9aa537e88fea9a88409 (patch) | |
tree | cd95446ac0b80b29658fa2a44030dacb5304a63d /vcl/source/app/IconThemeScanner.cxx | |
parent | 1ec263e25d8606c70ac2089d5ceea22750d25daf (diff) |
Bug #63962 Dynamically scan the config directory for icon themes
The hard-coded icon themes have been replaced by a dynamic list
which is filled by scanning the config directory
Conflicts:
include/vcl/settings.hxx
vcl/source/app/settings.cxx
vcl/source/window/window.cxx
Change-Id: Ie3680ffe27d06e375acf22753e036cb6ddabc4ed
Reviewed-on: https://gerrit.libreoffice.org/7935
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source/app/IconThemeScanner.cxx')
-rw-r--r-- | vcl/source/app/IconThemeScanner.cxx | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/vcl/source/app/IconThemeScanner.cxx b/vcl/source/app/IconThemeScanner.cxx new file mode 100644 index 000000000000..e6a6a130b92f --- /dev/null +++ b/vcl/source/app/IconThemeScanner.cxx @@ -0,0 +1,185 @@ +/* + * 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/IconThemeScanner.hxx> + +#include <config_folders.h> +#include <osl/file.hxx> +#include <rtl/bootstrap.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/IconThemeInfo.hxx> + +namespace vcl { + +namespace { + +bool +search_path_is_valid(const OUString& dir) +{ + osl::DirectoryItem dirItem; + osl::FileBase::RC retvalGet = osl::DirectoryItem::get(dir, dirItem); + if (retvalGet != osl::FileBase::RC::E_None) { + return false; + } + osl::FileStatus fileStatus(osl_FileStatus_Mask_Type); + osl::FileBase::RC retvalStatus = dirItem.getFileStatus(fileStatus); + if (retvalStatus != osl::FileBase::RC::E_None) { + return false; + } + + if (!fileStatus.isDirectory()) { + return false; + } + return true; +} + +} + +IconThemeScanner::IconThemeScanner() +{;} + +bool +IconThemeScanner::ScanDirectoryForIconThemes(const OUString& path) +{ + bool pathIsValid = search_path_is_valid(path); + if (!pathIsValid) { + return false; + } + std::vector<OUString> iconThemePaths = ReadIconThemesFromPath(path); + if (iconThemePaths.empty()) { + return false; + } + mFoundIconThemes.clear(); + for (const OUString& pathToTheme : iconThemePaths) { + AddIconThemeByPath(pathToTheme); + } + return true; +} + +bool +IconThemeScanner::AddIconThemeByPath(const OUString &url) +{ + if (!IconThemeInfo::UrlCanBeParsed(url)) { + return false; + } + IconThemeInfo newTheme{url}; + mFoundIconThemes.push_back(newTheme); + return true; +} + +/*static*/ std::vector<OUString> +IconThemeScanner::ReadIconThemesFromPath(const OUString& dir) +{ + std::vector<OUString> found; + + osl::Directory dirToScan(dir); + osl::FileBase::RC retvalOpen = dirToScan.open(); + if (retvalOpen != osl::FileBase::RC::E_None) { + return found; + } + + osl::DirectoryItem directoryItem; + while (dirToScan.getNextItem(directoryItem) == osl::FileBase::RC::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::RC::E_None) { + continue; + } + if (!status.isRegular()) { + continue; + } + if (!FileIsValidIconTheme(status.getFileURL())) { + continue; + } + OUString entry; + entry = status.getFileURL(); + found.push_back(entry); + } + return found; +} + +/*static*/ bool +IconThemeScanner::FileIsValidIconTheme(const OUString& filename) +{ + // check whether we can construct a IconThemeInfo from it + if (!IconThemeInfo::UrlCanBeParsed(filename)) { + return false; + } + + // check whether the file is a regular file + osl::DirectoryItem dirItem; + osl::FileBase::RC retvalGet = osl::DirectoryItem::get(filename, dirItem); + if (retvalGet != osl::FileBase::RC::E_None) { + return false; + } + osl::FileStatus fileStatus(osl_FileStatus_Mask_Type); + osl::FileBase::RC retvalStatus = dirItem.getFileStatus(fileStatus); + if (retvalStatus != osl::FileBase::RC::E_None) { + return false; + } + if (!fileStatus.isRegular()) { + return false; + } + return true; +} + +bool +IconThemeScanner::IconThemeIsInstalled(const OUString& themeId) const +{ + return IconThemeInfo::IconThemeIsInVector(mFoundIconThemes, themeId); +} + +/*static*/ boost::shared_ptr<IconThemeScanner> +IconThemeScanner::Create(const OUString &path) +{ + boost::shared_ptr<IconThemeScanner> retval(new IconThemeScanner{}); + retval->ScanDirectoryForIconThemes(path); + return retval; +} + +/*static*/ OUString +IconThemeScanner::GetStandardIconThemePath() +{ + OUString url( "$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/config/" ); + rtl::Bootstrap::expandMacros(url); + return url; +} + +IconThemeScanner::~IconThemeScanner() +{;} + +namespace +{ + class SameTheme : + public std::unary_function<const vcl::IconThemeInfo &, bool> + { + private: + const OUString& m_rThemeId; + public: + SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {} + bool operator()(const vcl::IconThemeInfo &rInfo) + { + return m_rThemeId == rInfo.GetThemeId(); + } + }; +} + +const vcl::IconThemeInfo& +IconThemeScanner::GetIconThemeInfo(const OUString& themeId) +{ + std::vector<IconThemeInfo>::iterator info = std::find_if(mFoundIconThemes.begin(), mFoundIconThemes.end(), + SameTheme(themeId)); + if (info == mFoundIconThemes.end()) { + throw std::runtime_error("Requested information on not-installed icon theme"); + } + return *info; +} + + +} // end namespace vcl |