view src/gui/dialog/settings/application.cc @ 187:9613d72b097e

*: multiple performance improvements like marking `static const` when it makes sense... date: change old stupid heap-based method to a structure which should make copying the thing actually make a copy. also many performance-based changes, like removing the std::tie dependency and forward-declaring nlohmann json *: replace every instance of QString::fromUtf8 to Strings::ToQString. the main difference is that our function will always convert exactly what is in the string, while some other times it would only convert up to the nearest NUL byte
author Paper <mrpapersonic@gmail.com>
date Wed, 06 Dec 2023 13:43:54 -0500
parents 80f49f623d30
children 649786bae914
line wrap: on
line source

#include "core/session.h"
#include "core/strings.h"
#include "gui/dialog/settings.h"
#include "gui/theme.h"
#include "gui/locale.h"
#include <QCheckBox>
#include <QComboBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QSizePolicy>
#include <QVBoxLayout>
#include <algorithm>

QWidget* SettingsPageApplication::CreateAnimeListWidget() {
	QWidget* result = new QWidget(this);
	result->setAutoFillBackground(true);
	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

	QVBoxLayout* full_layout = new QVBoxLayout(result);

	{
		/* Actions */
		QGroupBox* actions_group_box = new QGroupBox(tr("Actions"), result);
		actions_group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

		QHBoxLayout* actions_layout = new QHBoxLayout(actions_group_box);

		{
			/* Actions/Double click */
			QWidget* double_click_widget = new QWidget(actions_group_box);
			QLabel* dc_combo_box_label = new QLabel(tr("Double click:"), double_click_widget);
			QComboBox* dc_combo_box = new QComboBox(double_click_widget);
			dc_combo_box->addItem(tr("View anime info"));

			QVBoxLayout* double_click_layout = new QVBoxLayout(double_click_widget);
			double_click_layout->addWidget(dc_combo_box_label);
			double_click_layout->addWidget(dc_combo_box);
			double_click_layout->setContentsMargins(0, 0, 0, 0);

			actions_layout->addWidget(double_click_widget);
		}

		{
			/* Actions/Middle click */
			QWidget* middle_click_widget = new QWidget(actions_group_box);
			QLabel* mc_combo_box_label = new QLabel(tr("Middle click:"), middle_click_widget);
			QComboBox* mc_combo_box = new QComboBox(middle_click_widget);
			mc_combo_box->addItem(tr("Play next episode"));

			QVBoxLayout* middle_click_layout = new QVBoxLayout(middle_click_widget);
			middle_click_layout->addWidget(mc_combo_box_label);
			middle_click_layout->addWidget(mc_combo_box);
			middle_click_layout->setContentsMargins(0, 0, 0, 0);
			
			actions_layout->addWidget(middle_click_widget);
		}

		full_layout->addWidget(actions_group_box);
	}

	{
		/* Appearance */
		QGroupBox* appearance_group_box = new QGroupBox(tr("Appearance"), result);
		appearance_group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

		QVBoxLayout* appearance_layout = new QVBoxLayout(appearance_group_box);

		{
			/* Title language */
			{
				QLabel* lang_combo_box_label = new QLabel(tr("Title language preference:"), appearance_group_box);
				appearance_layout->addWidget(lang_combo_box_label);
			}
			{
				QComboBox* lang_combo_box = new QComboBox(appearance_group_box);
				lang_combo_box->addItem(tr("Romaji"));
				lang_combo_box->addItem(tr("Native"));
				lang_combo_box->addItem(tr("English"));
				connect(lang_combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
				        [this](int index) { language = static_cast<Anime::TitleLanguage>(index); });
				lang_combo_box->setCurrentIndex(static_cast<int>(language));
				appearance_layout->addWidget(lang_combo_box);
			}
		}

		{
			/* Application theme */
			{
				QLabel* theme_combo_box_label = new QLabel(tr("Application theme:"), appearance_group_box);
				appearance_layout->addWidget(theme_combo_box_label);
			}

			{
				QComboBox* theme_combo_box = new QComboBox(appearance_group_box);
				theme_combo_box->addItem(tr("Default"));
				theme_combo_box->addItem(tr("Light"));
				theme_combo_box->addItem(tr("Dark"));
				connect(theme_combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
					    [this](int index) { theme = static_cast<Themes>(index); });
				theme_combo_box->setCurrentIndex(static_cast<int>(theme));
				appearance_layout->addWidget(theme_combo_box);
			}
		}

		{
			/* Application locale */
			{
				QLabel* locale_combo_box_label = new QLabel(tr("Set application locale:"), appearance_group_box);
				appearance_layout->addWidget(locale_combo_box_label);
			}

			{
				QComboBox* locale_combo_box = new QComboBox(appearance_group_box);
				const auto& available_locales = session.config.locale.GetAvailableLocales();
				for (const auto& l : available_locales)
					locale_combo_box->addItem(Strings::ToQString(Locale::GetLocaleFullName(l)), l);

				connect(locale_combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
					    [this, locale_combo_box](int) { locale = locale_combo_box->currentData().toLocale(); });

				for (size_t i = 0; i < available_locales.size(); i++)
					if (available_locales[i] == locale)
						locale_combo_box->setCurrentIndex(i);
				appearance_layout->addWidget(locale_combo_box);
			}
		}

		{
			/* Application theme */
			{
				QLabel* theme_combo_box_label = new QLabel(tr("Application theme:"), appearance_group_box);
				appearance_layout->addWidget(theme_combo_box_label);
			}

			{
				QComboBox* theme_combo_box = new QComboBox(appearance_group_box);
				theme_combo_box->addItem(tr("Default"));
				theme_combo_box->addItem(tr("Light"));
				theme_combo_box->addItem(tr("Dark"));
				connect(theme_combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
					    [this](int index) { theme = static_cast<Themes>(index); });
				theme_combo_box->setCurrentIndex(static_cast<int>(theme));
				appearance_layout->addWidget(theme_combo_box);
			}
		}

		{
			/* Hopefully I made this easy to parse... */
			QCheckBox* hl_above_anime_box = new QCheckBox(tr("Display highlighted anime above others"), appearance_group_box);
			hl_above_anime_box->setCheckState(highlighted_anime_above_others ? Qt::Checked : Qt::Unchecked);
			hl_above_anime_box->setEnabled(highlight_anime_if_available);
			hl_above_anime_box->setContentsMargins(10, 0, 0, 0);

			connect(hl_above_anime_box, &QCheckBox::stateChanged, this,
			        [this](int state) { highlight_anime_if_available = !(state == Qt::Unchecked); });

			{
				/* This is here because the above checkbox actually depends on it to be checked. */
				QCheckBox* hl_anime_box = new QCheckBox(tr("Highlight anime if next episode is available in library folders"), appearance_group_box);
				hl_anime_box->setCheckState(highlight_anime_if_available ? Qt::Checked : Qt::Unchecked);

				connect(hl_anime_box, &QCheckBox::stateChanged, this, [this, hl_above_anime_box](int state) {
					highlight_anime_if_available = !(state == Qt::Unchecked);
					hl_above_anime_box->setEnabled(state);
				});

				appearance_layout->addWidget(hl_anime_box);
			}

			appearance_layout->addWidget(hl_above_anime_box);
		}

		full_layout->addWidget(appearance_group_box);
	}

	{
		/* Progress */
		QGroupBox* progress_group_box = new QGroupBox(tr("Progress"), result);
		progress_group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

		QVBoxLayout* progress_layout = new QVBoxLayout(progress_group_box);

		{
			QCheckBox* progress_display_aired_episodes =
			    new QCheckBox(tr("Display aired episodes (estimated)"), progress_group_box);
			connect(progress_display_aired_episodes, &QCheckBox::stateChanged, this,
			        [this](int state) { display_aired_episodes = !(state == Qt::Unchecked); });
			progress_display_aired_episodes->setCheckState(display_aired_episodes ? Qt::Checked : Qt::Unchecked);
			progress_layout->addWidget(progress_display_aired_episodes);
		}
		{
			QCheckBox* progress_display_available_episodes =
			    new QCheckBox(tr("Display available episodes in library folders"), progress_group_box);
			connect(progress_display_available_episodes, &QCheckBox::stateChanged, this,
			        [this](int state) { display_available_episodes = !(state == Qt::Unchecked); });
			progress_display_available_episodes->setCheckState(display_available_episodes ? Qt::Checked : Qt::Unchecked);
			progress_layout->addWidget(progress_display_available_episodes);
		}

		full_layout->addWidget(progress_group_box);
	}

	full_layout->setSpacing(10);
	full_layout->addStretch();

	return result;
}

void SettingsPageApplication::SaveInfo() {
	session.config.anime_list.language = language;
	session.config.anime_list.highlighted_anime_above_others = highlighted_anime_above_others;
	session.config.anime_list.highlight_anime_if_available = highlight_anime_if_available;
	session.config.anime_list.display_aired_episodes = display_aired_episodes;
	session.config.anime_list.display_available_episodes = display_available_episodes;
	session.config.theme.SetTheme(theme);
	session.config.locale.SetActiveLocale(locale);
}

SettingsPageApplication::SettingsPageApplication(QWidget* parent) : SettingsPage(parent, tr("Application")) {
	language = session.config.anime_list.language;
	theme = session.config.theme.GetTheme();
	locale = session.config.locale.GetLocale();
	highlighted_anime_above_others = session.config.anime_list.highlighted_anime_above_others;
	highlight_anime_if_available = session.config.anime_list.highlight_anime_if_available;
	display_aired_episodes = session.config.anime_list.display_aired_episodes;
	display_available_episodes = session.config.anime_list.display_available_episodes;
	AddTab(CreateAnimeListWidget(), tr("Anime list"));
}