Files
libreoffice/vcl/source/app/IconThemeScanner.cxx

186 lines
4.8 KiB
C++
Raw Normal View History

/*
* 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