/* Copyright (C) 2013 Daniel Hrabovcak, Josh Ventura * This file is part of NaturalGM. * * NaturalGM is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, version 3 of the License, or (at your option) any later version. * * NaturalGM is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * NaturalGM. If not, see . **/ #ifndef _NGM_ICONMANAGER__HPP #define _NGM_ICONMANAGER__HPP #include #include #include #include #include #include class IconManager: public QObject { Q_OBJECT private: std::vector searchPaths; ///< List of paths to search for theme icons std::map extensionPriorities; ///< Mapping of known and preferred (or unpreferred) extensions std::map> pathCache; ///< Map intended to cache fully qualified paths and their respective priorities by unqualified icon names. std::map> iconCache; ///< Map intended to prevent loading the same icon twice. QString currentTheme; ///< The name of the current icon theme. void cachePathnames(); ///< Called to crawl the filesystem for icons, caching the most favorable name. void dumpCaches(); ///< Drop the caches; clear them and move their data to be collected. public: // Methods the main initializer and plugin initializers will use /// Default constructor. IconManager(); /// Add a path from which to check for icons. The most obvious is "icons/". void addSearchPath(const QString& path); /// Set the priority of a given extension. A smaller number indicates a higher priority; /// the default priority is zero. Thus, a file having an extension with a priority of /// zero is chosen over a file of the same name with an extension having a priority of /// one, but is swept aside in favor of such a file with a priority of -1. /// @param extension The extension whose priority is to be set. /// @param priority The priority; -10 is a higher priority than 0, which is higher than 10. void setExtensionPriority(const QString &extension, int priority); /// Set the current icon theme, by name. void setIconTheme(const QString& iconTheme); /// Grab a list of available icon theme names. const std::vector getAvailableIconThemes(); // Methods everyone will use /// Retrieve a QIcon for the current theme from its most basic name. /// @param iconName The unqualified name of this icon, eg, "LoadFile". std::shared_ptr getIcon(const QString &iconName); signals: /// Signaled when the current theme changes void iconThemeChanged(IconManager *manager); }; #endif // _NGM_ICONMANAGER__HPP /* Copyright (C) 2013 Josh Ventura * This file is part of NaturalGM. * * NaturalGM is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, version 3 of the License, or (at your option) any later version. * * NaturalGM is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * NaturalGM. If not, see . **/ #include "IconManager.hpp" #include #include using std::map; using std::set; using std::pair; using std::vector; using std::shared_ptr; IconManager::IconManager() {} void IconManager::addSearchPath(const QString& path) { QString nixPath = path; nixPath.replace('\\', '/'); if (!nixPath.endsWith('/')) nixPath.append('/'); searchPaths.push_back(nixPath); } void IconManager::setExtensionPriority(const QString &extension, int priority) { extensionPriorities[extension] = priority; } void IconManager::setIconTheme(const QString& iconTheme) { currentTheme = iconTheme; cachePathnames(); } const vector IconManager::getAvailableIconThemes() { set foundThemes; vector result; for (auto path = searchPaths.begin(); path != searchPaths.end(); ++path) { QDir dir(*path); if (dir.exists()) { QDirIterator dirit(dir); while (dirit.hasNext()) { QString theme = dirit.next(); if (foundThemes.find(theme) == foundThemes.end()) { foundThemes.insert(theme); result.push_back(theme); } } } } return result; } std::shared_ptr IconManager::getIcon(const QString &iconName) { auto iconIt = iconCache.find(iconName); if (iconIt != iconCache.end()) return iconIt->second; auto iconPathIt = pathCache.find(iconName); QIcon *allocIcon = (iconPathIt == pathCache.end()) ? new QIcon() : new QIcon(iconPathIt->first); std::shared_ptr result(allocIcon); iconCache[iconName] = result; return result; } void IconManager::cachePathnames() { pathCache.clear(); iconCache.clear(); for (auto path = searchPaths.begin(); path != searchPaths.end(); ++path) { QDir dir(*path); if (dir.exists()) { QDirIterator dirit(dir); while (dirit.hasNext()) { QString fn = dirit.next(); QString nixname = fn.replace('\\', '/'); QString filename; int fileNameStart = fn.lastIndexOf('/'); int extensionStart = fn.lastIndexOf('.', fileNameStart); int priority = 0; if (extensionStart != -1) { auto extit = extensionPriorities.find(nixname.mid(extensionStart + 1)); if (extit != extensionPriorities.end()) priority = extit->second; filename = nixname.mid(fileNameStart + 1, extensionStart - fileNameStart - 1); } else filename = nixname.mid(fileNameStart + 1); auto mapFile = pathCache.find(filename); if (mapFile == pathCache.end() || priority < mapFile->second.second) pathCache[filename] = pair(fn, priority); } } } }