Mercurial > minori
view src/gui/dialog/information.cc @ 327:b5d6c27c308f
anime: refactor Anime::SeriesSeason to Season class
ToLocalString has also been altered to take in both season
and year because lots of locales actually treat formatting
seasons differently! most notably is Russian which adds a
suffix at the end to notate seasons(??)
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Thu, 13 Jun 2024 01:49:18 -0400 |
parents | 5d3c9b31aa6e |
children | 6b0768158dcd |
line wrap: on
line source
#include "gui/dialog/information.h" #include "core/anime.h" #include "core/anime_db.h" #include "core/session.h" #include "core/strings.h" #include "gui/pages/anime_list.h" #include "gui/translate/anime.h" #include "gui/widgets/anime_info.h" #include "gui/widgets/optional_date.h" #include "gui/widgets/poster.h" #include "gui/widgets/text.h" #include "gui/window.h" #include <QCheckBox> #include <QComboBox> #include <QDateEdit> #include <QDebug> #include <QDialogButtonBox> #include <QLabel> #include <QLineEdit> #include <QPlainTextEdit> #include <QSpinBox> #include <QStringList> #include <QTextStream> #include <QVBoxLayout> #include <functional> #include <iostream> #ifdef WIN32 # include "sys/win32/dark_theme.h" #endif /* TODO: Taiga disables rendering of the tab widget entirely when the anime is not part of a list, which sucks. Think of a better way to implement this later. */ void InformationDialog::SaveData(Anime::Anime* anime) { if (!anime->IsInUserList()) return; anime->SetUserProgress(_progress); anime->SetUserScore(_score); anime->SetUserIsRewatching(_rewatching); anime->SetUserStatus(_status); anime->SetUserNotes(_notes); anime->SetUserDateStarted(_started); anime->SetUserDateCompleted(_completed); } InformationDialog::InformationDialog(Anime::Anime* anime, std::function<void(Anime::Anime*)> accept, enum Pages page, QWidget* parent) : QDialog(parent) { /* ack. lots of brackets here, but MUCH, MUCH MUCH better than what it used to be */ setFixedSize(842, 613); setWindowTitle(tr("Anime Information")); setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); { QPalette pal; pal.setColor(QPalette::Window, pal.color(QPalette::Base)); setPalette(pal); } QVBoxLayout* full_layout = new QVBoxLayout(this); { /* this handles the actual page. */ QWidget* widget = new QWidget(this); QHBoxLayout* layout = new QHBoxLayout(widget); { /* Sidebar */ QWidget* sidebar = new QWidget(widget); QVBoxLayout* sidebar_layout = new QVBoxLayout(sidebar); { /* Poster */ Poster* poster = new Poster(*anime, sidebar); sidebar_layout->addWidget(poster); } sidebar_layout->setContentsMargins(0, 0, 0, 0); sidebar_layout->addStretch(); layout->addWidget(sidebar); } { /* ... everything else. */ QWidget* main_widget = new QWidget(widget); QVBoxLayout* main_layout = new QVBoxLayout(main_widget); main_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); { /* Anime title */ TextWidgets::Title* anime_title = new TextWidgets::Title(Strings::ToQString(anime->GetUserPreferredTitle()), main_widget); main_layout->addWidget(anime_title); } { /* Tab widget, contains main info and settings */ QTabWidget* tabbed_widget = new QTabWidget(main_widget); tabbed_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); { /* Main information */ AnimeInfoWidget* main_information_widget = new AnimeInfoWidget(*anime, tabbed_widget); tabbed_widget->addTab(main_information_widget, tr("Main information")); } if (anime->IsInUserList()) { /* My list and settings */ QWidget* settings_widget = new QWidget(tabbed_widget); settings_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); QVBoxLayout* settings_layout = new QVBoxLayout(settings_widget); settings_layout->addWidget(new TextWidgets::Header(tr("Anime list"), settings_widget)); { /* Anime List */ QWidget* sg_anime_list_content = new QWidget(settings_widget); constexpr int LAYOUT_HORIZ_SPACING = 25; constexpr int LAYOUT_VERT_SPACING = 5; constexpr int LAYOUT_ITEM_WIDTH = 175; QVBoxLayout* al_layout = new QVBoxLayout(sg_anime_list_content); al_layout->setSpacing(LAYOUT_VERT_SPACING); al_layout->setContentsMargins(12, 0, 0, 0); /* Helper function for creating sections, reduces clutter. */ const auto CREATE_SECTION = [](QWidget* parent, std::function<void(QWidget*, QGridLayout*)> x) { QWidget* section = new QWidget(parent); QGridLayout* layout = new QGridLayout(section); layout->setHorizontalSpacing(LAYOUT_HORIZ_SPACING); layout->setVerticalSpacing(LAYOUT_VERT_SPACING); layout->setContentsMargins(0, 0, 0, 0); x(section, layout); parent->layout()->addWidget(section); }; CREATE_SECTION(sg_anime_list_content, [this, &anime](QWidget* section, QGridLayout* layout) { { /* Episodes watched... */ layout->addWidget(new QLabel(tr("Episodes watched:"), section), 0, 0); QSpinBox* spin_box = new QSpinBox(section); connect(spin_box, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int i) { _progress = i; }); spin_box->setRange(0, anime->GetEpisodes()); spin_box->setSingleStep(1); spin_box->setValue(_progress = anime->GetUserProgress()); spin_box->setFixedWidth(LAYOUT_ITEM_WIDTH); layout->addWidget(spin_box, 1, 0); } { /* Rewatching? */ QCheckBox* checkbox = new QCheckBox(tr("Rewatching")); connect(checkbox, QOverload<int>::of(&QCheckBox::stateChanged), this, [this](int state) { _rewatching = (state == Qt::Checked); }); checkbox->setCheckState((_rewatching = anime->GetUserIsRewatching()) ? Qt::Checked : Qt::Unchecked); checkbox->setFixedWidth(LAYOUT_ITEM_WIDTH); layout->addWidget(checkbox, 1, 1); } layout->setColumnStretch(layout->columnCount(), 1); }); CREATE_SECTION(sg_anime_list_content, [this, &anime](QWidget* section, QGridLayout* layout) { { /* Status */ layout->addWidget(new QLabel(tr("Status:"), section), 0, 0); QComboBox* combo_box = new QComboBox(section); _status = anime->GetUserStatus(); for (unsigned int i = 0; i < Anime::ListStatuses.size(); i++) { combo_box->addItem(Strings::ToQString(Translate::ToLocalString(Anime::ListStatuses[i])), static_cast<int>(Anime::ListStatuses[i])); if (Anime::ListStatuses[i] == _status) combo_box->setCurrentIndex(i); } connect(combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this, combo_box](int) { _status = static_cast<Anime::ListStatus>(combo_box->currentData().toInt()); }); /* this should NEVER, EVER, be NOT_IN_LIST */ combo_box->setFixedWidth(LAYOUT_ITEM_WIDTH); layout->addWidget(combo_box, 1, 0); } { /* Score */ layout->addWidget(new QLabel(tr("Score:"), section), 0, 1); QSpinBox* spin_box = new QSpinBox(section); connect(spin_box, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int i) { _score = i; }); spin_box->setRange(0, 100); spin_box->setSingleStep(5); spin_box->setValue(_score = anime->GetUserScore()); spin_box->setFixedWidth(LAYOUT_ITEM_WIDTH); layout->addWidget(spin_box, 1, 1); } layout->setColumnStretch(layout->columnCount(), 1); }); CREATE_SECTION(sg_anime_list_content, [this, &anime](QWidget* section, QGridLayout* layout) { layout->addWidget(new QLabel(tr("Notes:"), section), 0, 0); QLineEdit* line_edit = new QLineEdit(section); connect(line_edit, &QLineEdit::textChanged, this, [this](const QString& text) { /* this sucks but I don't really want to implement anything smarter :) */ _notes = Strings::ToUtf8String(text); }); line_edit->setText(Strings::ToQString(_notes = anime->GetUserNotes())); line_edit->setPlaceholderText(tr("Enter your notes about this anime")); layout->addWidget(line_edit, 1, 0); }); CREATE_SECTION(sg_anime_list_content, [this, &anime](QWidget* section, QGridLayout* layout) { /* Started */ { layout->addWidget(new QLabel(tr("Date started:"), section), 0, 0); OptionalDate* date = new OptionalDate(true, section); connect(date, &OptionalDate::DataChanged, this, [this](bool enabled, Date date) { _started = enabled ? date : Date(); }); date->setFixedWidth(LAYOUT_ITEM_WIDTH); _started = anime->GetUserDateStarted(); if (!_started.IsValid()) { date->SetEnabled(false); _started = anime->GetStartedDate(); } date->SetDate(_started); layout->addWidget(date, 1, 0); } /* Completed */ { layout->addWidget(new QLabel(tr("Date completed:"), section), 0, 1); OptionalDate* date = new OptionalDate(true, section); connect(date, &OptionalDate::DataChanged, this, [this](bool enabled, Date date) { _completed = enabled ? date : Date(); }); date->setFixedWidth(LAYOUT_ITEM_WIDTH); _completed = anime->GetUserDateCompleted(); if (!_completed.IsValid()) { date->SetEnabled(false); _completed = anime->GetCompletedDate(); } date->SetDate(_completed); layout->addWidget(date, 1, 1); } layout->setColumnStretch(layout->columnCount(), 1); }); settings_layout->addWidget(sg_anime_list_content); } /* { // commenting this out until it actually gets implemented :) settings_layout->addWidget(new TextWidgets::Header(tr("Local settings"), settings_widget)); QWidget* sg_local_content = new QWidget(settings_widget); QVBoxLayout* sg_local_layout = new QVBoxLayout(sg_local_content); sg_local_layout->setSpacing(5); sg_local_layout->setContentsMargins(12, 0, 0, 0); CREATE_SECTION(sg_local_content, [this, &anime](QWidget* section, QGridLayout* layout){ layout->addWidget(new QLabel(tr("Alternative titles:"), section), 0, 0); QLineEdit* line_edit = new QLineEdit("", section); line_edit->setPlaceholderText( tr("Enter alternative titles here, separated by a semicolon (i.e. Title 1; Title 2)")); layout->addWidget(line_edit, 1, 0); QCheckBox* checkbox = new QCheckBox(tr("Use the first alternative title to search for torrents")); layout->addWidget(checkbox, 2, 0); }); settings_layout->addWidget(sg_local_content); } */ settings_layout->addStretch(); tabbed_widget->addTab(settings_widget, tr("My list and settings")); } tabbed_widget->setCurrentIndex(static_cast<int>(page)); main_layout->addWidget(tabbed_widget); main_layout->setContentsMargins(0, 0, 0, 0); main_layout->setSpacing(12); } layout->addWidget(main_widget); } layout->setSpacing(12); layout->setContentsMargins(0, 0, 0, 0); full_layout->addWidget(widget); } { /* Dialog box buttons */ QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); connect(button_box, &QDialogButtonBox::accepted, this, [this, accept, anime] { SaveData(anime); accept(anime); QDialog::accept(); }); connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject); full_layout->addWidget(button_box, 0, Qt::AlignBottom); } } void InformationDialog::showEvent(QShowEvent* event) { QDialog::showEvent(event); #ifdef WIN32 win32::SetTitleBarsToBlack(session.config.theme.IsInDarkTheme()); #endif }