Files
waylight/src/IconRegistry.cpp

113 lines
2.8 KiB
C++
Raw Normal View History

#include "IconRegistry.hpp"
#include <cstdlib>
#include <filesystem>
#include <ranges>
#include <stdexcept>
#include <mini/ini.h>
IconTheme::IconTheme(std::filesystem::path const &themes_directory_path)
{
for (auto const &dir :
std::filesystem::directory_iterator(themes_directory_path)) {
if (!dir.is_directory())
continue;
auto const index_path = dir.path() / "index.theme";
if (std::filesystem::is_regular_file(index_path))
continue;
mINI::INIFile ini_file(index_path);
mINI::INIStructure ini;
ini_file.read(ini);
auto const &directories { ini["Icon Theme"]["Directories"] };
for (auto const &&dir_entry : directories | std::views::split(':')) {
auto const dir_entry_str { std::string(
dir_entry.begin(), dir_entry.end()) };
auto const path { std::filesystem::path(dir_entry_str) };
auto const path_actual { dir.path() / path };
if (!std::filesystem::is_directory(path_actual))
continue;
auto const &type_raw { ini[dir_entry_str]["Type"] };
DirectoryEntry::Type type;
if (type_raw == "Fixed") {
type = DirectoryEntry::Type::Fixed;
} else if (type_raw == "Scalable") {
type = DirectoryEntry::Type::Scalable;
} else if (type_raw == "Threshold") {
type = DirectoryEntry::Type::Threshold;
} else {
continue;
}
auto const &context_raw { ini[dir_entry_str]["context"] };
DirectoryEntry::Context context;
if (context_raw == "Actions") {
context = DirectoryEntry::Context::Actions;
} else if (type_raw == "Devices") {
context = DirectoryEntry::Context::Devices;
} else if (type_raw == "FileSystems") {
context = DirectoryEntry::Context::FileSystems;
} else if (type_raw == "MomeTypes") {
context = DirectoryEntry::Context::MimeTypes;
} else {
continue;
}
int size { std::atoi(ini[dir_entry_str]["Size"].c_str()) };
m_directories.push_back({
.path = path,
.size = size,
.type = type,
.context = context,
});
}
}
}
IconRegistry::IconRegistry()
{
std::vector<std::filesystem::path> theme_directory_paths;
{
auto const *env { getenv("HOME") };
if (env && *env) {
theme_directory_paths.push_back(
std::filesystem::path(env) / ".icons");
}
}
{
auto const *env { getenv("XDG_DATA_DIRS") };
if (env && *env) {
theme_directory_paths.push_back(
std::filesystem::path(env) / "icons");
}
}
{
std::filesystem::path const path { "/usr/share/pixmaps" };
if (std::filesystem::exists(path))
theme_directory_paths.push_back(path);
}
for (auto &&path : std::move(theme_directory_paths)
| std::views::filter([](std::filesystem::path &path) {
return std::filesystem::is_directory(path);
})) {
try {
m_themes.push_back({ path });
} catch (...) {
}
}
if (m_themes.empty()) {
throw std::runtime_error("Could not find any icon themes.");
}
}