Mercurial > minori
changeset 47:d8eb763e6661
information.cpp: add widgets to the list tab, and add an
"optional date" widget like taiga has so users can specify whether to
set the date or not
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Mon, 25 Sep 2023 00:43:38 -0400 |
parents | d0adc4aedfc8 |
children | e613772f41d5 |
files | CMakeLists.txt include/core/date.h include/core/session.h include/gui/dialog/information.h include/gui/widgets/optional_date.h src/core/date.cpp src/gui/dialog/information.cpp src/gui/pages/anime_list.cpp src/gui/pages/statistics.cpp src/gui/translate/anilist.cpp src/gui/widgets/optional_date.cpp src/services/anilist.cpp src/services/services.cpp |
diffstat | 13 files changed, 304 insertions(+), 189 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Sat Sep 23 01:02:15 2023 -0400 +++ b/CMakeLists.txt Mon Sep 25 00:43:38 2023 -0400 @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.16) project(minori LANGUAGES CXX) +# this should check for the target system, rather than +# the host system, for cross-compiling purposes if(APPLE) enable_language(OBJCXX) endif() @@ -51,6 +53,7 @@ # Custom widgets src/gui/widgets/sidebar.cpp src/gui/widgets/text.cpp + src/gui/widgets/optional_date.cpp # Dialogs src/gui/dialog/information.cpp @@ -80,8 +83,9 @@ list(APPEND SRC_FILES src/sys/win32/dark_theme.cpp) endif() -add_executable(minori ${SRC_FILES}) -set_property(TARGET minori PROPERTY CXX_STANDARD 20) +add_executable(minori WIN32 ${SRC_FILES}) +# There's a bug in JFMC++ that keeps me from setting this to C++11. +set_property(TARGET minori PROPERTY CXX_STANDARD 17) set_property(TARGET minori PROPERTY AUTOMOC ON) set_property(TARGET minori PROPERTY AUTORCC ON)
--- a/include/core/date.h Sat Sep 23 01:02:15 2023 -0400 +++ b/include/core/date.h Mon Sep 25 00:43:38 2023 -0400 @@ -8,6 +8,7 @@ Date(); Date(int32_t y); Date(int32_t y, int8_t m, int8_t d); + bool IsValid() const; void SetYear(int32_t y); void SetMonth(int8_t m); void SetDay(int8_t d);
--- a/include/core/session.h Sat Sep 23 01:02:15 2023 -0400 +++ b/include/core/session.h Mon Sep 25 00:43:38 2023 -0400 @@ -6,12 +6,15 @@ struct Session { Config config; Session() { timer.start(); } + void AppendRequest() { requests++; }; + int GetRequests() { return requests; }; int uptime() { return timer.elapsed(); } private: + int requests = 0; QElapsedTimer timer; }; extern Session session; -#endif // __core__session_h \ No newline at end of file +#endif // __core__session_h
--- a/include/gui/dialog/information.h Sat Sep 23 01:02:15 2023 -0400 +++ b/include/gui/dialog/information.h Mon Sep 25 00:43:38 2023 -0400 @@ -11,5 +11,9 @@ public: InformationDialog(const Anime::Anime& anime, std::function<void()> accept, QWidget* parent = nullptr); + + private: + int id; + void SaveData(); }; #endif // __gui__dialog__information_h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/gui/widgets/optional_date.h Mon Sep 25 00:43:38 2023 -0400 @@ -0,0 +1,24 @@ +#ifndef __gui__widgets__optional_date_h +#define __gui__widgets__optional_date_h +#include <QWidget> + +class QCheckBox; +class QDateEdit; +class QDate; + +class OptionalDate : public QWidget { + public: + OptionalDate(QWidget* parent = nullptr); + OptionalDate(bool enabled, QWidget* parent = nullptr); + QDateEdit* GetDateEdit(); + QCheckBox* GetCheckBox(); + void SetDate(QDate date); + void SetEnabled(bool enabled); + bool IsEnabled(); + + private: + QDateEdit* _dateedit; + QCheckBox* _checkbox; +}; + +#endif // __gui__widgets__optional_date_h
--- a/src/core/date.cpp Sat Sep 23 01:02:15 2023 -0400 +++ b/src/core/date.cpp Mon Sep 25 00:43:38 2023 -0400 @@ -85,9 +85,14 @@ return -1; } +bool Date::IsValid() const { + return year.get() && month.get() && day.get(); +} + bool Date::operator<(const Date& other) const { + int y = GetYear(), m = GetMonth(), d = GetDay(); int o_y = other.GetYear(), o_m = other.GetMonth(), o_d = other.GetDay(); - return std::tie(*year, *month, *day) < std::tie(o_y, o_m, o_d); + return std::tie(y, m, d) < std::tie(o_y, o_m, o_d); } bool Date::operator>(const Date& other) const { @@ -103,8 +108,8 @@ } QDate Date::GetAsQDate() const { - /* QDates don't (yet) support "missing" values */ - if (year.get() && month.get() && day.get()) + /* QDates don't support "missing" values, for good reason. */ + if (IsValid()) return QDate(*year, *month, *day); else return QDate();
--- a/src/gui/dialog/information.cpp Sat Sep 23 01:02:15 2023 -0400 +++ b/src/gui/dialog/information.cpp Mon Sep 25 00:43:38 2023 -0400 @@ -1,13 +1,16 @@ #include "gui/dialog/information.h" #include "core/anime.h" +#include "core/anime_db.h" #include "core/array.h" #include "core/strings.h" #include "gui/pages/anime_list.h" #include "gui/translate/anime.h" #include "gui/widgets/text.h" +#include "gui/widgets/optional_date.h" #include "gui/window.h" #include <QCheckBox> #include <QComboBox> +#include <QDateEdit> #include <QDebug> #include <QDialogButtonBox> #include <QLineEdit> @@ -20,6 +23,10 @@ /* 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 = Anime::db.items[id]; +} + InformationDialog::InformationDialog(const Anime::Anime& anime, std::function<void()> accept, QWidget* parent) : QDialog(parent) { setFixedSize(842, 613); @@ -116,23 +123,58 @@ sg_anime_list_content->layout()->setSpacing(5); sg_anime_list_content->layout()->setContentsMargins(12, 0, 0, 0); - /* Note: PLEASE find a way we can consolidate these. By ANY other means than - putting them in a separate function. Macros are very much preferred. */ -#define LAYOUT_HORIZ_SPACING 9 -#define LAYOUT_VERT_SPACING 5 - { +/* these macros make this a lot easier to edit */ +#define LAYOUT_HORIZ_SPACING 25 +#define LAYOUT_VERT_SPACING 5 +#define LAYOUT_ITEM_WIDTH 175 +/* Creates a subsection with a width of 175 */ +#define CREATE_SUBSECTION(x) \ + { \ + QWidget* subsection = new QWidget(section); \ + subsection->setLayout(new QVBoxLayout); \ + subsection->setFixedWidth(LAYOUT_ITEM_WIDTH); \ + subsection->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); \ + subsection->layout()->setSpacing(LAYOUT_VERT_SPACING); \ + subsection->layout()->setMargin(0); \ + x; \ + layout->addWidget(subsection); \ + } +/* Creates a section in the parent `a` */ +#define CREATE_SECTION(a, x) \ + { \ + QWidget* section = new QWidget(a); \ + QHBoxLayout* layout = new QHBoxLayout(section); \ + layout->setSpacing(LAYOUT_HORIZ_SPACING); \ + layout->setMargin(0); \ + x; \ + layout->addStretch(); \ + a->layout()->addWidget(section); \ + } +/* Creates a subsection that takes up whatever space is necessary */ +#define CREATE_FULL_WIDTH_SUBSECTION(x) \ + { \ + QWidget* subsection = new QWidget(section); \ + subsection->setLayout(new QVBoxLayout); \ + subsection->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); \ + subsection->layout()->setSpacing(LAYOUT_VERT_SPACING); \ + subsection->layout()->setMargin(0); \ + x; \ + layout->addWidget(subsection); \ + } +/* Creates a section in the parent `a` */ +#define CREATE_FULL_WIDTH_SECTION(a, x) \ + { \ + QWidget* section = new QWidget(a); \ + QHBoxLayout* layout = new QHBoxLayout(section); \ + layout->setSpacing(LAYOUT_HORIZ_SPACING); \ + layout->setMargin(0); \ + x; \ + a->layout()->addWidget(section); \ + } + + CREATE_SECTION(sg_anime_list_content, { /* Episodes watched section */ - QWidget* section = new QWidget(sg_anime_list_content); - QHBoxLayout* layout = new QHBoxLayout; - layout->setSpacing(LAYOUT_HORIZ_SPACING); - layout->setMargin(0); - section->setLayout(layout); - { - QWidget* subsection = new QWidget(section); - subsection->setLayout(new QVBoxLayout); - subsection->layout()->setSpacing(LAYOUT_VERT_SPACING); - subsection->layout()->setMargin(0); - + CREATE_SUBSECTION({ subsection->layout()->addWidget(new QLabel(tr("Episodes watched:"), subsection)); QSpinBox* spin_box = new QSpinBox(subsection); @@ -140,37 +182,17 @@ spin_box->setSingleStep(1); spin_box->setValue(anime.GetUserProgress()); subsection->layout()->addWidget(spin_box); - - layout->addWidget(subsection); - } - { - QWidget* subsection = new QWidget(section); - subsection->setLayout(new QVBoxLayout); - subsection->layout()->setSpacing(LAYOUT_VERT_SPACING); - subsection->layout()->setMargin(0); - + }); + CREATE_SUBSECTION({ subsection->layout()->addWidget(new QLabel(tr(" "), subsection)); QCheckBox* rewatched_checkbox = new QCheckBox("Rewatching"); subsection->layout()->addWidget(rewatched_checkbox); - - layout->addWidget(subsection); - } - sg_anime_list_content->layout()->addWidget(section); - } - { + }); + }); + CREATE_SECTION(sg_anime_list_content, { /* Status & score section */ - QWidget* section = new QWidget(sg_anime_list_content); - QHBoxLayout* layout = new QHBoxLayout; - layout->setSpacing(LAYOUT_HORIZ_SPACING); - layout->setMargin(0); - section->setLayout(layout); - { - QWidget* subsection = new QWidget(section); - subsection->setLayout(new QVBoxLayout); - subsection->layout()->setSpacing(LAYOUT_VERT_SPACING); - subsection->layout()->setMargin(0); - + CREATE_SUBSECTION({ subsection->layout()->addWidget(new QLabel(tr("Status:"), subsection)); QStringList string_list; @@ -180,15 +202,8 @@ QComboBox* combo_box = new QComboBox(subsection); combo_box->addItems(string_list); subsection->layout()->addWidget(combo_box); - - layout->addWidget(subsection); - } - { - QWidget* subsection = new QWidget(section); - subsection->setLayout(new QVBoxLayout); - subsection->layout()->setSpacing(LAYOUT_VERT_SPACING); - subsection->layout()->setMargin(0); - + }); + CREATE_SUBSECTION({ subsection->layout()->addWidget(new QLabel(tr("Score:"), subsection)); QSpinBox* spin_box = new QSpinBox(subsection); @@ -196,34 +211,35 @@ spin_box->setSingleStep(5); spin_box->setValue(anime.GetUserScore()); subsection->layout()->addWidget(spin_box); - - layout->addWidget(subsection); - } - sg_anime_list_content->layout()->addWidget(section); - } - { + }); + }); + CREATE_FULL_WIDTH_SECTION(sg_anime_list_content, { /* Notes section */ - QWidget* section = new QWidget(sg_anime_list_content); - QHBoxLayout* layout = new QHBoxLayout; - layout->setSpacing(LAYOUT_HORIZ_SPACING); - layout->setMargin(0); - section->setLayout(layout); - { - QWidget* subsection = new QWidget(section); - subsection->setLayout(new QVBoxLayout); - subsection->layout()->setSpacing(LAYOUT_VERT_SPACING); - subsection->layout()->setMargin(0); - + CREATE_FULL_WIDTH_SUBSECTION({ subsection->layout()->addWidget(new QLabel(tr("Notes:"), subsection)); QLineEdit* line_edit = new QLineEdit(QString::fromStdString(anime.GetUserNotes()), subsection); line_edit->setPlaceholderText(tr("Enter your notes about this anime")); subsection->layout()->addWidget(line_edit); + }); + }); + CREATE_SECTION(sg_anime_list_content, { + /* Dates section */ + CREATE_SUBSECTION({ + subsection->layout()->addWidget(new QLabel(tr("Date started:"), subsection)); - layout->addWidget(subsection); - } - sg_anime_list_content->layout()->addWidget(section); - } + OptionalDate* date = new OptionalDate(true, subsection); + date->SetDate(QDate(2000, 1, 1)); + subsection->layout()->addWidget(date); + }); + CREATE_SUBSECTION({ + subsection->layout()->addWidget(new QLabel(tr("Date completed:"), subsection)); + + OptionalDate* date = new OptionalDate(true, subsection); + date->SetDate(QDate(2000, 1, 1)); + subsection->layout()->addWidget(date); + }); + }); settings_widget->layout()->addWidget(new TextWidgets::Header(tr("Local settings"), settings_widget)); @@ -233,32 +249,24 @@ sg_local_content->layout()->setSpacing(5); sg_local_content->layout()->setContentsMargins(12, 0, 0, 0); - { + CREATE_FULL_WIDTH_SECTION(sg_local_content, { /* Alternative titles */ - QWidget* section = new QWidget(sg_local_content); - QHBoxLayout* layout = new QHBoxLayout; - layout->setSpacing(LAYOUT_HORIZ_SPACING); - layout->setMargin(0); - section->setLayout(layout); - { - QWidget* subsection = new QWidget(section); - subsection->setLayout(new QVBoxLayout); - subsection->layout()->setSpacing(LAYOUT_VERT_SPACING); - subsection->layout()->setMargin(0); - + CREATE_FULL_WIDTH_SUBSECTION({ subsection->layout()->addWidget(new QLabel(tr("Alternative titles:"), subsection)); QLineEdit* line_edit = new QLineEdit(QString::fromStdString(anime.GetUserNotes()), subsection); - line_edit->setPlaceholderText(tr("Enter alternative titles here, separated by a semicolon (i.e. Title 1; Title 2)")); + line_edit->setPlaceholderText( + tr("Enter alternative titles here, separated by a semicolon (i.e. Title 1; Title 2)")); subsection->layout()->addWidget(line_edit); QCheckBox* checkbox = new QCheckBox("Use the first alternative title to search for torrents"); subsection->layout()->addWidget(checkbox); - - layout->addWidget(subsection); - } - sg_local_content->layout()->addWidget(section); - } + }); + }); +#undef CREATE_SECTION +#undef CREATE_SUBSECTION +#undef CREATE_FULL_WIDTH_SECTION +#undef CREATE_FULL_WIDTH_SUBSECTION static_cast<QBoxLayout*>(settings_widget->layout())->addStretch();
--- a/src/gui/pages/anime_list.cpp Sat Sep 23 01:02:15 2023 -0400 +++ b/src/gui/pages/anime_list.cpp Mon Sep 25 00:43:38 2023 -0400 @@ -11,9 +11,9 @@ #include "gui/pages/anime_list.h" #include "core/anime.h" #include "core/anime_db.h" +#include "core/array.h" #include "core/session.h" #include "core/time.h" -#include "core/array.h" #include "gui/dialog/information.h" #include "gui/translate/anime.h" #include "services/anilist.h" @@ -99,33 +99,33 @@ QVariant AnimeListWidgetModel::headerData(const int section, const Qt::Orientation orientation, const int role) const { if (role == Qt::DisplayRole) { switch (section) { - case AL_TITLE: return tr("Anime title"); - case AL_PROGRESS: return tr("Progress"); - case AL_EPISODES: return tr("Episodes"); - case AL_TYPE: return tr("Type"); - case AL_SCORE: return tr("Score"); - case AL_SEASON: return tr("Season"); - case AL_STARTED: return tr("Date started"); - case AL_COMPLETED: return tr("Date completed"); - case AL_NOTES: return tr("Notes"); - case AL_AVG_SCORE: return tr("Average score"); - case AL_UPDATED: return tr("Last updated"); - default: return {}; + case AL_TITLE: return tr("Anime title"); + case AL_PROGRESS: return tr("Progress"); + case AL_EPISODES: return tr("Episodes"); + case AL_TYPE: return tr("Type"); + case AL_SCORE: return tr("Score"); + case AL_SEASON: return tr("Season"); + case AL_STARTED: return tr("Date started"); + case AL_COMPLETED: return tr("Date completed"); + case AL_NOTES: return tr("Notes"); + case AL_AVG_SCORE: return tr("Average score"); + case AL_UPDATED: return tr("Last updated"); + default: return {}; } } else if (role == Qt::TextAlignmentRole) { switch (section) { - case AL_TITLE: - case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - case AL_PROGRESS: - case AL_EPISODES: - case AL_TYPE: - case AL_SCORE: - case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter); - case AL_SEASON: - case AL_STARTED: - case AL_COMPLETED: - case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter); - default: return QAbstractListModel::headerData(section, orientation, role); + case AL_TITLE: + case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + case AL_PROGRESS: + case AL_EPISODES: + case AL_TYPE: + case AL_SCORE: + case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter); + case AL_SEASON: + case AL_STARTED: + case AL_COMPLETED: + case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter); + default: return QAbstractListModel::headerData(section, orientation, role); } } return QAbstractListModel::headerData(section, orientation, role); @@ -136,56 +136,56 @@ return QVariant(); switch (role) { case Qt::DisplayRole: - switch (index.column()) { - case AL_TITLE: return QString::fromUtf8(list[index.row()].GetUserPreferredTitle().c_str()); - case AL_PROGRESS: - return QString::number(list[index.row()].GetUserProgress()) + "/" + - QString::number(list[index.row()].GetEpisodes()); - case AL_EPISODES: return list[index.row()].GetEpisodes(); - case AL_SCORE: return list[index.row()].GetUserScore(); - case AL_TYPE: return QString::fromStdString(Translate::ToString(list[index.row()].GetFormat())); - case AL_SEASON: - return QString::fromStdString(Translate::ToString(list[index.row()].GetSeason())) + " " + - QString::number(list[index.row()].GetAirDate().GetYear()); - case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%"; - case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate(); - case AL_COMPLETED: return list[index.row()].GetUserDateCompleted().GetAsQDate(); - case AL_UPDATED: { - if (list[index.row()].GetUserTimeUpdated() == 0) - return QString("-"); - Time::Duration duration(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated()); - return QString::fromUtf8(duration.AsRelativeString().c_str()); - } - case AL_NOTES: return QString::fromUtf8(list[index.row()].GetUserNotes().c_str()); - default: return ""; - } - break; + switch (index.column()) { + case AL_TITLE: return QString::fromUtf8(list[index.row()].GetUserPreferredTitle().c_str()); + case AL_PROGRESS: + return QString::number(list[index.row()].GetUserProgress()) + "/" + + QString::number(list[index.row()].GetEpisodes()); + case AL_EPISODES: return list[index.row()].GetEpisodes(); + case AL_SCORE: return list[index.row()].GetUserScore(); + case AL_TYPE: return QString::fromStdString(Translate::ToString(list[index.row()].GetFormat())); + case AL_SEASON: + return QString::fromStdString(Translate::ToString(list[index.row()].GetSeason())) + " " + + QString::number(list[index.row()].GetAirDate().GetYear()); + case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%"; + case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate(); + case AL_COMPLETED: return list[index.row()].GetUserDateCompleted().GetAsQDate(); + case AL_UPDATED: { + if (list[index.row()].GetUserTimeUpdated() == 0) + return QString("-"); + Time::Duration duration(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated()); + return QString::fromUtf8(duration.AsRelativeString().c_str()); + } + case AL_NOTES: return QString::fromUtf8(list[index.row()].GetUserNotes().c_str()); + default: return ""; + } + break; case Qt::UserRole: - switch (index.column()) { - case AL_PROGRESS: return list[index.row()].GetUserProgress(); - case AL_TYPE: return static_cast<int>(list[index.row()].GetFormat()); - case AL_SEASON: return list[index.row()].GetAirDate().GetAsQDate(); - case AL_AVG_SCORE: return list[index.row()].GetAudienceScore(); - case AL_UPDATED: return QVariant::fromValue(list[index.row()].GetUserTimeUpdated()); - default: return data(index, Qt::DisplayRole); - } - break; + switch (index.column()) { + case AL_PROGRESS: return list[index.row()].GetUserProgress(); + case AL_TYPE: return static_cast<int>(list[index.row()].GetFormat()); + case AL_SEASON: return list[index.row()].GetAirDate().GetAsQDate(); + case AL_AVG_SCORE: return list[index.row()].GetAudienceScore(); + case AL_UPDATED: return QVariant::fromValue(list[index.row()].GetUserTimeUpdated()); + default: return data(index, Qt::DisplayRole); + } + break; case Qt::TextAlignmentRole: - switch (index.column()) { - case AL_TITLE: - case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); - case AL_PROGRESS: - case AL_EPISODES: - case AL_TYPE: - case AL_SCORE: - case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter); - case AL_SEASON: - case AL_STARTED: - case AL_COMPLETED: - case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter); - default: break; - } - break; + switch (index.column()) { + case AL_TITLE: + case AL_NOTES: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + case AL_PROGRESS: + case AL_EPISODES: + case AL_TYPE: + case AL_SCORE: + case AL_AVG_SCORE: return QVariant(Qt::AlignCenter | Qt::AlignVCenter); + case AL_SEASON: + case AL_STARTED: + case AL_COMPLETED: + case AL_UPDATED: return QVariant(Qt::AlignRight | Qt::AlignVCenter); + default: break; + } + break; } return QVariant(); } @@ -195,7 +195,7 @@ int i = 0; for (const auto& a : Anime::db.items) { if (a.second.IsInUserList() && a.first == id && a.second.GetUserStatus() == status) { - emit dataChanged(index(i), index(i)); + emit dataChanged(index(i), index(i)); } i++; } @@ -212,8 +212,8 @@ else { int count = 0; for (const auto& a : Anime::db.items) - if (a.second.IsInUserList() && a.second.GetUserStatus() == status) - count++; + if (a.second.IsInUserList() && a.second.GetUserStatus() == status) + count++; beginInsertRows(index(0), 0, count - 1); } @@ -221,7 +221,7 @@ for (const auto& a : Anime::db.items) { if (a.second.IsInUserList() && a.second.GetUserStatus() == status) { - list.push_back(a.second); + list.push_back(a.second); } } @@ -236,7 +236,7 @@ for (int i = 0, end = tree_view->header()->count(); i < end; i++) { if (!tree_view->isColumnHidden(i)) - count++; + count++; } return count; @@ -265,7 +265,7 @@ for (int i = 0; i < AnimeListWidgetModel::NB_COLUMNS; i++) { if (i == AnimeListWidgetModel::AL_TITLE) - continue; + continue; const auto column_name = sort_models[tab_bar->currentIndex()]->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); QAction* action = menu->addAction(column_name, this, [this, i](const bool checked) {
--- a/src/gui/pages/statistics.cpp Sat Sep 23 01:02:15 2023 -0400 +++ b/src/gui/pages/statistics.cpp Mon Sep 25 00:43:38 2023 -0400 @@ -29,7 +29,7 @@ anime_list_data = anime_list_paragraph->GetParagraph(); TextWidgets::LabelledTextParagraph* application_paragraph = - new TextWidgets::LabelledTextParagraph("Minori", "Uptime:", "", this); + new TextWidgets::LabelledTextParagraph("Minori", "Uptime:\nRequests made:", "", this); application_data = application_paragraph->GetParagraph(); layout()->addWidget(anime_list_paragraph); @@ -104,9 +104,12 @@ ts << Anime::db.GetScoreDeviation(); TextWidgets::SetPlainTextEditData(anime_list_data, string); + string = ""; + ts << QString::fromUtf8(SecondsToDateString(session.uptime() / 1000).c_str()) << '\n'; + ts << session.GetRequests(); /* Application */ // UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000)); - TextWidgets::SetPlainTextEditData(application_data, QString(SecondsToDateString(session.uptime() / 1000).c_str())); + TextWidgets::SetPlainTextEditData(application_data, string); } #include "gui/pages/moc_statistics.cpp"
--- a/src/gui/translate/anilist.cpp Sat Sep 23 01:02:15 2023 -0400 +++ b/src/gui/translate/anilist.cpp Mon Sep 25 00:43:38 2023 -0400 @@ -3,7 +3,7 @@ namespace Translate::AniList { Anime::SeriesStatus ToSeriesStatus(std::string status) { - std::unordered_map<std::string, Anime::SeriesStatus> map = { + const std::unordered_map<std::string, Anime::SeriesStatus> map = { {"FINISHED", Anime::SeriesStatus::FINISHED }, {"RELEASING", Anime::SeriesStatus::RELEASING }, {"NOT_YET_RELEASED", Anime::SeriesStatus::NOT_YET_RELEASED}, @@ -11,26 +11,26 @@ {"HIATUS", Anime::SeriesStatus::HIATUS } }; - if (!map.contains(status)) + if (map.find(status) == map.end()) return Anime::SeriesStatus::UNKNOWN; - return map[status]; + return map.at(status); } Anime::SeriesSeason ToSeriesSeason(std::string season) { - std::unordered_map<std::string, Anime::SeriesSeason> map = { + const std::unordered_map<std::string, Anime::SeriesSeason> map = { {"WINTER", Anime::SeriesSeason::WINTER}, {"SPRING", Anime::SeriesSeason::SPRING}, {"SUMMER", Anime::SeriesSeason::SUMMER}, {"FALL", Anime::SeriesSeason::FALL } }; - if (!map.contains(season)) + if (map.find(season) == map.end()) return Anime::SeriesSeason::UNKNOWN; - return map[season]; + return map.at(season); } Anime::SeriesFormat ToSeriesFormat(std::string format) { - std::unordered_map<std::string, enum Anime::SeriesFormat> map = { + const std::unordered_map<std::string, enum Anime::SeriesFormat> map = { {"TV", Anime::SeriesFormat::TV }, {"TV_SHORT", Anime::SeriesFormat::TV_SHORT}, {"MOVIE", Anime::SeriesFormat::MOVIE }, @@ -43,9 +43,9 @@ {"ONE_SHOT", Anime::SeriesFormat::ONE_SHOT} }; - if (!map.contains(format)) + if (map.find(format) == map.end()) return Anime::SeriesFormat::UNKNOWN; - return map[format]; + return map.at(format); } } // namespace Translate::AniList
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gui/widgets/optional_date.cpp Mon Sep 25 00:43:38 2023 -0400 @@ -0,0 +1,49 @@ +#include "gui/widgets/optional_date.h" +#include <QCheckBox> +#include <QDateEdit> +#include <QHBoxLayout> + +OptionalDate::OptionalDate(QWidget* parent) { + OptionalDate(false, parent); +} + +OptionalDate::OptionalDate(bool enabled, QWidget* parent) : QWidget(parent) { + QHBoxLayout* layout = new QHBoxLayout(this); + layout->setMargin(0); + + _checkbox = new QCheckBox(this); + _checkbox->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); + _checkbox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + + layout->addWidget(_checkbox); + + _dateedit = new QDateEdit(this); + _dateedit->setDisplayFormat("yyyy-MM-dd"); + _dateedit->setCalendarPopup(true); + _dateedit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + layout->addWidget(_dateedit); + + SetEnabled(enabled); + connect(_checkbox, &QCheckBox::stateChanged, this, [this](int state) { SetEnabled(state == Qt::Checked); }); +} + +void OptionalDate::SetEnabled(bool enabled) { + _dateedit->setEnabled(enabled); +} + +bool OptionalDate::IsEnabled() { + return _dateedit->isEnabled(); +} + +void OptionalDate::SetDate(QDate date) { + _dateedit->setDate(date); +} + +QDateEdit* OptionalDate::GetDateEdit() { + return _dateedit; +} + +QCheckBox* OptionalDate::GetCheckBox() { + return _checkbox; +}
--- a/src/services/anilist.cpp Sat Sep 23 01:02:15 2023 -0400 +++ b/src/services/anilist.cpp Mon Sep 25 00:43:38 2023 -0400 @@ -87,7 +87,7 @@ return; } - if (!map.contains(status)) { + if (map.find(status) == map.end()) { anime.SetUserStatus(Anime::ListStatus::NOT_IN_LIST); return; } @@ -107,7 +107,7 @@ if (anime.GetUserIsRewatching()) return "REWATCHING"; - if (!map.contains(anime.GetUserStatus())) + if (map.find(anime.GetUserStatus()) == map.end()) return "CURRENT"; return map[anime.GetUserStatus()]; }
--- a/src/services/services.cpp Sat Sep 23 01:02:15 2023 -0400 +++ b/src/services/services.cpp Mon Sep 25 00:43:38 2023 -0400 @@ -1,13 +1,27 @@ #include "services/services.h" #include "core/session.h" #include "services/anilist.h" +#include "gui/dialog/settings.h" +#include <QMessageBox> namespace Services { void Synchronize() { switch (session.config.service) { case Anime::Services::ANILIST: AniList::GetAnimeList(); break; - default: break; + default: { + QMessageBox msg; + msg.setInformativeText("It seems you haven't yet selected a service to use."); + msg.setText("Would you like to select one now?"); + msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msg.setDefaultButton(QMessageBox::Yes); + int ret = msg.exec(); + if (ret == QMessageBox::Yes) { + SettingsDialog dialog; + dialog.exec(); + } + break; + } } }