Skip to content

Commit

Permalink
Implemented dynamic theme applying
Browse files Browse the repository at this point in the history
  • Loading branch information
Anton Pronin committed Sep 7, 2022
1 parent a2f4238 commit 7352f78
Show file tree
Hide file tree
Showing 23 changed files with 142 additions and 122 deletions.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Icon Theme]
Name=admc-icons
Name=AdmcDefault
Comment=icons for app admc

DisplayDepth=32
Expand Down
23 changes: 11 additions & 12 deletions src/admc/admc-icons.qrc
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<RCC>
<qresource prefix="/icons">
<file>admc-icons/64x64/emblem-system.svg</file>
<file>admc-icons/64x64/computer.svg</file>
<file>admc-icons/64x64/folder.svg</file>
<file>admc-icons/64x64/preferences-other.svg</file>
<file>admc-icons/64x64/network-server.svg</file>
<file>admc-icons/64x64/folder-templates.svg</file>
<file>admc-icons/64x64/system-users.svg</file>
<file>admc-icons/64x64/folder-documents.svg</file>
<file>admc-icons/64x64/avatar-default.svg</file>
<file>admc-icons/64x64/volume.svg</file>
<file>admc-icons/index.theme</file>
<file>admc-icons/theme</file>
<file>AdmcDefault/64x64/emblem-system.svg</file>
<file>AdmcDefault/64x64/computer.svg</file>
<file>AdmcDefault/64x64/folder.svg</file>
<file>AdmcDefault/64x64/preferences-other.svg</file>
<file>AdmcDefault/64x64/network-server.svg</file>
<file>AdmcDefault/64x64/folder-templates.svg</file>
<file>AdmcDefault/64x64/system-users.svg</file>
<file>AdmcDefault/64x64/folder-documents.svg</file>
<file>AdmcDefault/64x64/avatar-default.svg</file>
<file>AdmcDefault/64x64/volume.svg</file>
<file>AdmcDefault/index.theme</file>
</qresource>
<qresource prefix="/"/>
</RCC>
1 change: 0 additions & 1 deletion src/admc/admc-icons/theme

This file was deleted.

139 changes: 78 additions & 61 deletions src/admc/console_impls/select_theme_impl.cpp
Original file line number Diff line number Diff line change
@@ -1,88 +1,63 @@
#include <settings.h>
#include "select_theme_impl.h"
#include <QRegularExpression>
#include <QFile>
#include <QIcon>
#include <utils.h>
#include <qcoreapplication.h>
#include <qstandardpaths.h>
#include <qfiledialog.h>
#include <QDebug>
#include <QDirIterator>
#include <QSettings>
#include <QApplication>
#include <QAction>
#include <QtGlobal>
#include <QRegularExpression>
#include <settings.h>

SelectThemeImpl::SelectThemeImpl(ConsoleWidget *console_arg)
SelectThemeImpl::SelectThemeImpl(ConsoleWidget *console_arg, QMenu* menu)
: ConsoleImpl(console_arg)
{
}

QString SelectThemeImpl::read_theme_file()
{
QString result;
menu_theme = menu;

QString file_path = [&]() {
const QString caption = QCoreApplication::translate("select_theme_impl.cpp", "Choose app theme");
const QString dir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
const QString file_filter = QCoreApplication::translate("select_theme_impl.cpp", "System icon theme (*.theme)");
const QString out = QFileDialog::getOpenFileName(console, caption, dir, file_filter);

return out;
}();

QFile file(file_path);
if (!file.open(QIODevice::ReadOnly)) {
return QString();
}

return file.readAll();
user_icons_dir_path = QString(QDir::separator()).append("home")
.append(QDir::separator().toLatin1()).append(qgetenv("USER"))
.append(QDir::separator().toLatin1()).append(".icons")
.append(QDir::separator().toLatin1());
}

QString SelectThemeImpl::parse_theme_name(QString theme_file_content)
QList<QAction* >* SelectThemeImpl::generate_theme_action_list()
{
QRegularExpression regex(this->theme_name_regex_pattern);
auto matched_data = regex.match(theme_file_content, 0, QRegularExpression::PartialPreferCompleteMatch).captured();
auto active_theme_name = settings_get_variant(SETTING_app_active_theme).toString();
auto added_theme_names = get_available_theme_list();

QString result = matched_data.mid(theme_name_regex_pattern.length() - 2);

return result;
}

QMenu* SelectThemeImpl::format_theme_list(QString active_theme_name, QStringList available_app_theme_names)
{
auto available_theme_font = QApplication::font();
available_theme_font.setCapitalization(QFont::Capitalize);

QMenu app_themes;
for(int i = 0; i < available_app_theme_names.size(); ++i){
QString theme_name = available_app_theme_names.at(i);
QAction theme;
QList<QAction* > * app_themes = new QList<QAction* >();
for(int i = 0; i < added_theme_names.size(); ++i){
QString theme_name = added_theme_names.at(i);
QAction* theme_action = new QAction();

if (theme_name != active_theme_name) {
theme.setData(theme_name);
theme.setIconText(theme_name.toLower());
theme.setFont(available_theme_font);
theme_action->setText(theme_name.toLower());
theme_action->setFont(available_theme_font);
}
else {
theme.setData(active_theme_name);
theme.setIconText(active_theme_name);
theme_action->setText(active_theme_name);

auto active_theme_font = QApplication::font();
active_theme_font.setBold(true);
theme.setFont(active_theme_font);
theme_action->setFont(active_theme_font);
}

app_themes.addAction(& theme);
connect(theme_action, &QAction::triggered, [=](){ this->set_theme(theme_name); });

app_themes->append(theme_action);
}

return &app_themes;
return app_themes;
}

void SelectThemeImpl::add_theme_to_list(QString theme_name)
void SelectThemeImpl::set_theme(const QString& theme_name)
{
auto app_themes = settings_get_variant(SETTING_app_themes).toList();
app_themes.append(theme_name);

settings_set_variant(SETTING_app_themes, app_themes);
settings_set_variant(SETTING_app_active_theme, theme_name);
apply_theme(theme_name);
}

void SelectThemeImpl::apply_theme(QString theme_name)
Expand All @@ -91,16 +66,58 @@ void SelectThemeImpl::apply_theme(QString theme_name)
settings_set_variant(SETTING_app_active_theme, theme_name);
}

void SelectThemeImpl::apply_default_theme()
void SelectThemeImpl::restore_theme_menu()
{
QIcon::setThemeName(default_theme_name);
auto data = get_available_theme_list();

auto formatted_actions = generate_theme_action_list();

this->menu_theme->clear();
this->menu_theme->addActions(*formatted_actions);
}

QString SelectThemeImpl::add_new_theme()
QStringList SelectThemeImpl::get_themes_from_dir(QString path_to_dir)
{
QString theme_name = parse_theme_name(read_theme_file());
add_theme_to_list(theme_name);
apply_theme(theme_name);
QDirIterator it(path_to_dir, QStringList("index.theme"), QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDirIterator::Subdirectories);

QStringList files;

while(it.hasNext())
{
files << it.next();
}

return parse_theme_names(files);
}

QStringList SelectThemeImpl::parse_theme_names(const QStringList & theme_path_list)
{
QRegularExpression regex(this->theme_name_regex_pattern);

QStringList result;

for (int i = 0; i < theme_path_list.size(); ++i)
{
QFile theme_file(theme_path_list.at(i));

if(!theme_file.open(QIODevice::ReadOnly | QIODevice::Text))
{
continue;
}

auto matched_data = regex.match(theme_file.readAll(), 0, QRegularExpression::PartialPreferCompleteMatch).captured();

result << matched_data.mid(theme_name_regex_pattern.length() - 2);
}

return result;
}

QStringList SelectThemeImpl::get_available_theme_list()
{
auto available_theme_paths = get_themes_from_dir(this->system_icons_dir_path);
available_theme_paths.append(get_themes_from_dir(this->user_icons_dir_path));
available_theme_paths.append(get_themes_from_dir(this->app_theme_path));

return theme_name;
return available_theme_paths;
}
26 changes: 18 additions & 8 deletions src/admc/console_impls/select_theme_impl.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
#ifndef QUERY_THEME_IMPL_H
#define QUERY_THEME_IMPL_H
#include <QString>
#include <QMenu>
#include <QDir>
#include <console_widget/console_impl.h>

class SelectThemeImpl : public ConsoleImpl
{
Q_OBJECT
public:
SelectThemeImpl(ConsoleWidget *console_arg);
SelectThemeImpl(ConsoleWidget *console_arg, QMenu* menu_theme);
void apply_theme(QString theme_name);
void apply_default_theme();
QString add_new_theme();
QMenu* format_theme_list(QString active_theme_name, QStringList available_app_themes);
QList<QAction* >* generate_theme_action_list();
void restore_theme_menu();

private slots:
void set_theme(const QString& themeName);
QStringList get_available_theme_list();

private:
QString read_theme_file();
QString parse_theme_name(QString theme_file_name);
void add_theme_to_list(QString theme_name);
QStringList parse_theme_names(const QStringList & theme_path_list);
QStringList get_themes_from_dir(QString path_to_dir);

QMenu * menu_theme;

const QString app_theme_path = ":/icons";
const QString system_icons_dir_path = "/usr/share/icons";
QString user_icons_dir_path;

const QString theme_name_regex_pattern = "Name=.*";
const QString default_theme_name = "admc-icons";
};

#endif // QUERY_THEME_IMPL_H
8 changes: 4 additions & 4 deletions src/admc/console_widget/console_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,6 @@ void ConsoleWidget::set_actions(const ConsoleWidgetActions &actions_arg) {
view_type_group->addAction(d->actions.view_icons);
view_type_group->addAction(d->actions.view_list);
view_type_group->addAction(d->actions.view_detail);
view_type_group->addAction(d->actions.view_theme);

connect(
d->actions.navigate_up, &QAction::triggered,
Expand All @@ -791,9 +790,6 @@ void ConsoleWidget::set_actions(const ConsoleWidgetActions &actions_arg) {
connect(
d->actions.view_detail, &QAction::triggered,
d, &ConsoleWidgetPrivate::on_view_detail);
// connect(
// d->actions.view_theme, &QAction::triggered,
// d, &ConsoleWidgetPrivate::on)
connect(
d->actions.toggle_console_tree, &QAction::triggered,
d, &ConsoleWidgetPrivate::on_toggle_console_tree);
Expand Down Expand Up @@ -824,6 +820,10 @@ void ConsoleWidgetPrivate::update_navigation_actions() {
actions.navigate_forward->setEnabled(!targets_future.isEmpty());
}

void ConsoleWidget::update_view() {
d->on_refresh();
}

void ConsoleWidgetPrivate::update_view_actions() {
ConsoleImpl *impl = get_current_scope_impl();
const bool results_view_exists = (impl->view() != nullptr);
Expand Down
2 changes: 1 addition & 1 deletion src/admc/console_widget/console_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class ConsoleWidgetActions final {
QAction *view_icons;
QAction *view_list;
QAction *view_detail;
QAction *view_theme;
QAction *toggle_console_tree;
QAction *toggle_description_bar;
};
Expand All @@ -97,6 +96,7 @@ class ConsoleWidget final : public QWidget {
// NOTE: must be called before restore_state(), so that
// action state is restored
void set_actions(const ConsoleWidgetActions &actions_arg);
void update_view();

// NOTE: you must register all impl's before adding
// items
Expand Down
7 changes: 2 additions & 5 deletions src/admc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ int main(int argc, char **argv) {
app.setOrganizationDomain(ADMC_ORGANIZATION_DOMAIN);
app.setWindowIcon(QIcon(":/admc/admc.ico"));

QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << ":/icons");

QIcon::setThemeName("admc-icons");

const QLocale saved_locale = settings_get_variant(SETTING_locale).toLocale();

QTranslator translator;
Expand Down Expand Up @@ -90,6 +86,8 @@ int main(int argc, char **argv) {
qDebug() << "Failed to load qt base translation";
}



load_connection_options();

// In case of failure to connect to AD and load
Expand Down Expand Up @@ -119,7 +117,6 @@ int main(int argc, char **argv) {

if (ad.is_connected()) {
load_g_adconfig(ad);

first_main_window = new MainWindow(ad);
first_main_window->show();
} else {
Expand Down
Loading

0 comments on commit 7352f78

Please sign in to comment.