diff --git a/.gear/admc.spec b/.gear/admc.spec index 431c96cf..062f0375 100644 --- a/.gear/admc.spec +++ b/.gear/admc.spec @@ -28,6 +28,7 @@ BuildRequires: libkrb5-devel Requires: libsasl2 Requires: libsasl2-plugin-gssapi +Requires: icon-theme-ActiveDirectory Source0: %name-%version.tar diff --git a/src/admc/admc_ru.ts b/src/admc/admc_ru.ts index fb286191..f6be1301 100644 --- a/src/admc/admc_ru.ts +++ b/src/admc/admc_ru.ts @@ -1899,6 +1899,12 @@ View &Вид + + + &Theme + Theme + &Тема + &Preferences diff --git a/src/admc/console_impls/query_folder_impl.cpp b/src/admc/console_impls/query_folder_impl.cpp index 663614ff..c1737425 100644 --- a/src/admc/console_impls/query_folder_impl.cpp +++ b/src/admc/console_impls/query_folder_impl.cpp @@ -31,6 +31,7 @@ #include "globals.h" #include "settings.h" #include "utils.h" +#include "icon_manager/icon_manager.h" #include #include @@ -341,7 +342,10 @@ void console_query_tree_init(ConsoleWidget *console) { const QList root_row = console->add_scope_item(ItemType_QueryFolder, console->domain_info_index()); auto root = root_row[0]; root->setText(QCoreApplication::translate("query", "Saved Queries")); - root->setIcon(QIcon::fromTheme("folder")); + + const QIcon create_query_folder_icon = g_icon_manager->get_object_icon("folder-query"); + root->setIcon(create_query_folder_icon); + root->setDragEnabled(false); root->setData(true, QueryItemRole_IsRoot); @@ -533,7 +537,9 @@ QModelIndex console_query_folder_create(ConsoleWidget *console, const QString &n void console_query_folder_load(const QList &row, const QString &name, const QString &description) { QStandardItem *main_item = row[0]; main_item->setData(description, QueryItemRole_Description); - main_item->setIcon(QIcon::fromTheme("folder")); + + const QIcon create_query_folder_icon = g_icon_manager->get_object_icon("folder-query"); + main_item->setIcon(create_query_folder_icon); main_item->setData(false, QueryItemRole_IsRoot); row[QueryColumn_Name]->setText(name); diff --git a/src/admc/console_impls/query_item_impl.cpp b/src/admc/console_impls/query_item_impl.cpp index 0b82dcdd..34f452d7 100644 --- a/src/admc/console_impls/query_item_impl.cpp +++ b/src/admc/console_impls/query_item_impl.cpp @@ -30,6 +30,7 @@ #include "globals.h" #include "settings.h" #include "utils.h" +#include "icon_manager/icon_manager.h" #include #include @@ -41,8 +42,6 @@ #define QUERY_ROOT "QUERY_ROOT" -const QString query_item_icon = "emblem-system"; - QueryItemImpl::QueryItemImpl(ConsoleWidget *console_arg) : ConsoleImpl(console_arg) { query_folder_impl = nullptr; @@ -68,7 +67,9 @@ void QueryItemImpl::fetch(const QModelIndex &index) { // NOTE: reset icon and tooltip in case query is in the // "out of date" state QStandardItem *item = console->get_item(index); - item->setIcon(QIcon::fromTheme(query_item_icon)); + + const QIcon create_query_item = g_icon_manager->get_object_icon("query-item"); + item->setIcon(create_query_item); item->setToolTip(""); const QString filter = index.data(QueryItemRole_Filter).toString(); @@ -197,7 +198,9 @@ void console_query_item_load(const QList row, const QString &na main_item->setData(filter_state, QueryItemRole_FilterState); main_item->setData(base, QueryItemRole_Base); main_item->setData(scope_is_children, QueryItemRole_ScopeIsChildren); - main_item->setIcon(QIcon::fromTheme(query_item_icon)); + + const QIcon create_query_item = g_icon_manager->get_object_icon("query-item"); + main_item->setIcon(create_query_item); row[QueryColumn_Name]->setText(name); row[QueryColumn_Description]->setText(description); diff --git a/src/admc/icon_manager/icon_manager.cpp b/src/admc/icon_manager/icon_manager.cpp index 3e1e1b7d..92f3f064 100644 --- a/src/admc/icon_manager/icon_manager.cpp +++ b/src/admc/icon_manager/icon_manager.cpp @@ -3,6 +3,7 @@ #include "utils.h" #include "ad_utils.h" #include "ad_object.h" +#include "settings.h" #include #include @@ -11,28 +12,44 @@ IconManager::IconManager() { } +void IconManager::icon_theme(QString icon_theme) +{ + if (icon_theme != default_theme && icon_theme != "") + settings_set_variant(SETTING_icons_theme, icon_theme); + else + settings_set_variant(SETTING_icons_theme, ""); + + if (icon_theme != "") + QIcon::setThemeName(icon_theme); + else + QIcon::setThemeName(default_theme); + + icon_theme_name = icon_theme; +} + void IconManager::init() { // NOTE: use a list of possible icons because // default icon themes for different DE's don't // fully intersect - category_to_icon_list = { - {"Domain-DNS", {"network-server"}}, - {"Container", {"folder"}}, - {OBJECT_CATEGORY_OU, {"folder-documents"}}, - {OBJECT_CATEGORY_GROUP, {"system-users"}}, - {OBJECT_CATEGORY_PERSON, {"avatar-default", "avatar-default-symbolic"}}, - {"Computer", {"computer"}}, - {"Group-Policy-Container", {"preferences-other"}}, - {"Volume", {"folder-templates"}}, - - // Some custom icons for one-off objects - {"Builtin-Domain", {"emblem-system", "emblem-system-symbolic"}}, - {"Configuration", {"emblem-system", "emblem-system-symbolic"}}, - {"Lost-And-Found", {"emblem-system", "emblem-system-symbolic"}}, - {"Infrastructure-Update", {"emblem-system", "emblem-system-symbolic"}}, - {"ms-DS-Quota-Container", {"emblem-system", "emblem-system-symbolic"}}, - }; + bool default_theme = icon_theme_name == QIcon::fallbackThemeName(); + + category_to_icon_list["Domain-DNS"] = {"network-server"}; + category_to_icon_list["Container"] = {"folder"}; + category_to_icon_list[OBJECT_CATEGORY_OU] = {"folder-documents"}; + category_to_icon_list[OBJECT_CATEGORY_GROUP] = {"system-users"}; + category_to_icon_list[OBJECT_CATEGORY_PERSON] = {"avatar-default", "avatar-default-symbolic"}; + category_to_icon_list["Computer"] = {"computer"}; + category_to_icon_list["Group-Policy-Container"] = {"preferences-other"}; + category_to_icon_list["Volume"] = {"folder-templates"}; + // Some custom icons for one-off objects + category_to_icon_list ["Builtin-Domain"] = {default_theme ? QList({"emblem-system", "emblem-system-symbolic"}) : QList({"folder"})}; + category_to_icon_list["Configuration"] = {"emblem-system", "emblem-system-symbolic"}; + category_to_icon_list["Lost-And-Found"] = {default_theme ? QList({"emblem-system", "emblem-system-symbolic"}) : QList({"folder"})}; + category_to_icon_list["Infrastructure-Update"] = {"emblem-system", "emblem-system-symbolic"}; + category_to_icon_list["ms-DS-Quota-Container"] = {default_theme ? QList({"emblem-system", "emblem-system-symbolic"}) : QList({"folder"})}; + category_to_icon_list["folder-query"] = {default_theme ? QList({"emblem-system", "emblem-system-symbolic"}) : QList({"folder-query"})}; + category_to_icon_list["query-item"] = {default_theme ? QList({"emblem-system", "emblem-system-symbolic"}) : QList({"query-item"})}; // NOTE: This is the icon used when no icon is // defined for some object category @@ -152,3 +169,11 @@ void IconManager::set_icon_for_type(const QIcon &icon, ItemIconType icon_type) { type_index_icons_array[icon_type] = icon; } + +void IconManager::set_icons_for_actions(const QHash actions) +{ + for (const QString &category : actions.keys()){ + const QIcon icon = get_object_icon(category); + actions[category]->setIcon(icon); + } +} diff --git a/src/admc/icon_manager/icon_manager.h b/src/admc/icon_manager/icon_manager.h index cccdd351..09718eff 100644 --- a/src/admc/icon_manager/icon_manager.h +++ b/src/admc/icon_manager/icon_manager.h @@ -6,6 +6,7 @@ #include #include #include +#include enum ItemIconType { ItemIconType_Policy_Clean, @@ -35,17 +36,22 @@ class IconManager final { public: explicit IconManager(); + QString default_theme; + void icon_theme(QString); void init(); const QIcon& get_icon_for_type(ItemIconType icon_type) const; QIcon get_object_icon(const AdObject &object) const; QIcon get_object_icon(const QString& object_category) const; void set_icon_for_type(const QIcon &icon, ItemIconType icon_type); + void set_icons_for_actions(const QHash); private: QIcon type_index_icons_array[ItemIconType_LAST]; QMap> category_to_icon_list; + QString error_icon; + QString icon_theme_name; //Enums positions where scope item icon can be overlayed //by another icon diff --git a/src/admc/main.cpp b/src/admc/main.cpp index f503bd89..06f38ec6 100644 --- a/src/admc/main.cpp +++ b/src/admc/main.cpp @@ -53,6 +53,8 @@ int main(int argc, char **argv) { app.setOrganizationDomain(ADMC_ORGANIZATION_DOMAIN); app.setWindowIcon(QIcon(":/admc/admc.ico")); + g_icon_manager->default_theme = QIcon::themeName(); + g_icon_manager->icon_theme(settings_get_variant(SETTING_icons_theme).toString()); g_icon_manager->init(); const QLocale saved_locale = settings_get_variant(SETTING_locale).toLocale(); diff --git a/src/admc/main_window.cpp b/src/admc/main_window.cpp index 286af426..6dee9be1 100644 --- a/src/admc/main_window.cpp +++ b/src/admc/main_window.cpp @@ -190,6 +190,48 @@ MainWindow::MainWindow(AdInterface &ad, QWidget *parent) open_changelog(); } + // + // Setup theme action + // + QList> pair = settings_get_themes(); + auto theme_group = new QActionGroup(this); + for (const QPair &theme : pair){ + QString name_theme = theme.first; + QString display_name = theme.second; + const auto action = new QAction(display_name, theme_group); + + action->setCheckable(true); + theme_group->addAction(action); + + bool is_checked; + const QString current_theme = settings_get_variant(SETTING_icons_theme).toString(); + current_theme == name_theme ? is_checked = true : is_checked = false; + + action->setChecked(is_checked); + ui->menu_theme->addAction(action); + + connect( + action, &QAction::triggered, + this, + [this, name_theme](bool checked) { + if (checked == false) + return; + + g_icon_manager->icon_theme(name_theme); + g_icon_manager->init(); + + QHash icons_tool_bar = { + {OBJECT_CATEGORY_PERSON, ui->action_create_user}, + {OBJECT_CATEGORY_GROUP, ui->action_create_group}, + {OBJECT_CATEGORY_OU, ui->action_create_ou} + }; + g_icon_manager->set_icons_for_actions(icons_tool_bar); + + update(); + reload_console_tree(); + }); + } + // // Setup language actions // diff --git a/src/admc/main_window.ui b/src/admc/main_window.ui index 5a2b3b80..4655fc47 100644 --- a/src/admc/main_window.ui +++ b/src/admc/main_window.ui @@ -20,7 +20,7 @@ 0 0 800 - 27 + 19 @@ -42,6 +42,11 @@ &View + + + &Theme + + @@ -53,6 +58,7 @@ + diff --git a/src/admc/settings.cpp b/src/admc/settings.cpp index e218250e..6e014bd3 100644 --- a/src/admc/settings.cpp +++ b/src/admc/settings.cpp @@ -22,6 +22,8 @@ #include "config.h" #include "connection_options_dialog.h" +#include "globals.h" +#include "icon_manager/icon_manager.h" #include #include @@ -112,3 +114,32 @@ void settings_set_variant(const QString setting, const QVariant &value) { settings.setValue(setting, value); } + +QList> settings_get_themes(){ + QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, "/usr/share/alt-management-console"); + QSettings set("icon-theme"); + set.setIniCodec("UTF-8"); + + QList> list; + QString display_name; + if (settings_get_variant(SETTING_locale).toLocale() == QLocale::Russian){ + display_name = "DISPLAY_NAME[ru]"; + list.push_back({g_icon_manager->default_theme, "Системная"}); + } + else{ + display_name = "DISPLAY_NAME"; + list.push_back({g_icon_manager->default_theme, "System"}); + } + + QStringList all_themes = set.childGroups(); + for (QString &theme : all_themes) + { + QPair pair; + set.beginGroup(theme); + pair.first = set.value("NAME").toString(); + pair.second = set.value(display_name).toString(); + set.endGroup(); + list.push_back(pair); + } + return list; +} diff --git a/src/admc/settings.h b/src/admc/settings.h index 39d5f60c..6722d7bc 100644 --- a/src/admc/settings.h +++ b/src/admc/settings.h @@ -133,7 +133,8 @@ DEFINE_SETTING(SETTING_last_opened_version); DEFINE_SETTING(SETTING_object_filter); DEFINE_SETTING(SETTING_object_filter_enabled); DEFINE_SETTING(SETTING_object_display_limit); -DEFINE_SETTING(SETTING_custom_domain) +DEFINE_SETTING(SETTING_custom_domain); +DEFINE_SETTING(SETTING_icons_theme); // Feature flags // @@ -166,4 +167,6 @@ bool settings_restore_geometry(const QString setting, QWidget *widget); void settings_save_header_state(const QString setting, QHeaderView *header); bool settings_restore_header_state(const QString setting, QHeaderView *header); +QList> settings_get_themes(); + #endif /* SETTINGS_H */