Mercurial > minori
changeset 77:6f7385bd334c
*: update
formatted all source files, no more subclassing QThread... many other
changes :)
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Fri, 06 Oct 2023 06:18:53 -0400 |
parents | 3364fadc8a36 |
children | 1ce00c1c8ddc |
files | .clang-format include/core/http.h include/gui/pages/anime_list.h src/core/config.cpp src/core/date.cpp src/core/http.cpp src/core/strings.cpp src/gui/dialog/about.cpp src/gui/dialog/information.cpp src/gui/dialog/settings.cpp src/gui/pages/anime_list.cpp src/gui/widgets/poster.cpp src/gui/widgets/sidebar.cpp src/gui/widgets/text.cpp src/gui/window.cpp src/services/anilist.cpp |
diffstat | 16 files changed, 125 insertions(+), 150 deletions(-) [+] |
line wrap: on
line diff
--- a/.clang-format Wed Oct 04 01:46:33 2023 -0400 +++ b/.clang-format Fri Oct 06 06:18:53 2023 -0400 @@ -11,6 +11,7 @@ IndentAccessModifiers: true IndentPPDirectives: AfterHash +BreakArrays: true BreakBeforeBraces: Attach BreakStringLiterals: true @@ -25,6 +26,8 @@ AllowShortFunctionsOnASingleLine: InlineOnly AllowShortCaseLabelsOnASingleLine: true +Cpp11BracedListStyle: true + --- Language: Cpp Standard: Cpp11
--- a/include/core/http.h Wed Oct 04 01:46:33 2023 -0400 +++ b/include/core/http.h Fri Oct 06 06:18:53 2023 -0400 @@ -1,32 +1,14 @@ #ifndef __core__http_h #define __core__http_h -#include <QThread> +#include <QByteArray> #include <string> #include <vector> -class QObject; - namespace HTTP { -class HttpGetThread : public QThread { - Q_OBJECT - - public: - HttpGetThread(std::string url, std::vector<std::string> headers = {}, QObject* parent = nullptr); - - private: - static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata); - void run() override; - std::string _url; - std::vector<std::string> _headers; - - signals: - void resultReady(const QByteArray& arr); -}; - -/* Performs a basic (blocking) post request */ -std::string PerformBasicPostRequest(std::string url, std::string data, std::vector<std::string> headers = {}); +QByteArray Get(std::string url, std::vector<std::string> headers = {}); +QByteArray Post(std::string url, std::string data, std::vector<std::string> headers = {}); } // namespace HTTP
--- a/include/gui/pages/anime_list.h Wed Oct 04 01:46:33 2023 -0400 +++ b/include/gui/pages/anime_list.h Fri Oct 06 06:18:53 2023 -0400 @@ -54,7 +54,6 @@ int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role) const override; QVariant headerData(const int section, const Qt::Orientation orientation, const int role) const override; - void UpdateAnime(int id); void RefreshList(); Anime::Anime* GetAnimeFromIndex(QModelIndex index); @@ -82,6 +81,8 @@ void resizeEvent(QResizeEvent* e) override; void RefreshList(); void RefreshTabs(); + void UpdateAnime(int id); + void RemoveAnime(int id); private slots: void DisplayColumnHeaderMenu();
--- a/src/core/config.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/core/config.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -53,8 +53,8 @@ std::ifstream config(cfg_path.GetPath(), std::ifstream::in); auto config_js = nlohmann::json::parse(config); service = StringToService[JSON::GetString(config_js, "/General/Service"_json_pointer)]; - anime_list.language = StringToAnimeTitleMap[JSON::GetString( - config_js, "/Anime List/Display only aired episodes"_json_pointer, "Romaji")]; + anime_list.language = + StringToAnimeTitleMap[JSON::GetString(config_js, "/Anime List/Title language"_json_pointer, "Romaji")]; anime_list.display_aired_episodes = JSON::GetBoolean(config_js, "/Anime List/Display only aired episodes"_json_pointer, true); anime_list.display_available_episodes = @@ -76,7 +76,7 @@ if (!cfg_path.GetParent().Exists()) cfg_path.GetParent().CreateDirectories(); std::ofstream config(cfg_path.GetPath(), std::ofstream::out | std::ofstream::trunc); - // clang-format off + /* clang-format off */ nlohmann::json config_js = { {"General", { {"Service", ServiceToString[service]} @@ -99,7 +99,7 @@ {"Theme", ThemeToString[theme]} }} }; - // clang-format on + /* clang-format on */ config << std::setw(4) << config_js << std::endl; config.close(); return 0;
--- a/src/core/date.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/core/date.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -105,18 +105,18 @@ } nlohmann::json Date::GetAsAniListJson() const { - nlohmann::json result; + nlohmann::json result = {}; if (year.get()) - result.insert(result.end(), {"year", *year}); + result["year"] = *year; else - result.insert(result.end(), {"year", nullptr}); + result["year"] = nullptr; if (month.get()) - result.insert(result.end(), {"month", *month}); + result["month"] = *month; else - result.insert(result.end(), {"month", nullptr}); + result["month"] = nullptr; if (day.get()) - result.insert(result.end(), {"day", *day}); + result["day"] = *day; else - result.insert(result.end(), {"day", nullptr}); + result["day"] = nullptr; return result; }
--- a/src/core/http.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/core/http.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -2,33 +2,28 @@ #include "core/session.h" #include <QByteArray> #include <QMessageBox> -#include <QThread> #include <curl/curl.h> #include <string> #include <vector> namespace HTTP { -HttpGetThread::HttpGetThread(std::string url, std::vector<std::string> headers, QObject* parent) : QThread(parent) { - _url = url; - _headers = headers; -} - -size_t HttpGetThread::WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { +static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { reinterpret_cast<QByteArray*>(userdata)->append(reinterpret_cast<char*>(contents), size * nmemb); return size * nmemb; } -void HttpGetThread::run() { +QByteArray Get(std::string url, std::vector<std::string> headers) { struct curl_slist* list = NULL; QByteArray userdata; CURL* curl = curl_easy_init(); if (curl) { - for (const std::string& h : _headers) { + for (const std::string& h : headers) { list = curl_slist_append(list, h.c_str()); } - curl_easy_setopt(curl, CURLOPT_URL, _url.c_str()); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &userdata); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback); /* Use system certs... useful on Windows. */ @@ -42,18 +37,13 @@ box.exec(); } } - emit resultReady(userdata); + return userdata; } -static size_t CurlWriteStringCallback(void* contents, size_t size, size_t nmemb, void* userdata) { - reinterpret_cast<std::string*>(userdata)->append(reinterpret_cast<char*>(contents), size * nmemb); - return size * nmemb; -} +QByteArray Post(std::string url, std::string data, std::vector<std::string> headers) { + struct curl_slist* list = NULL; + QByteArray userdata; -/* Performs a basic (blocking) post request */ -std::string PerformBasicPostRequest(std::string url, std::string data, std::vector<std::string> headers) { - struct curl_slist* list = NULL; - std::string userdata; CURL* curl = curl_easy_init(); if (curl) { for (const std::string& h : headers) { @@ -63,24 +53,19 @@ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &userdata); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlWriteStringCallback); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback); /* Use system certs... useful on Windows. */ curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); CURLcode res = curl_easy_perform(curl); session.IncrementRequests(); - curl_slist_free_all(list); curl_easy_cleanup(curl); if (res != CURLE_OK) { QMessageBox box(QMessageBox::Icon::Critical, "", QString("curl_easy_perform(curl) failed!: ") + QString(curl_easy_strerror(res))); box.exec(); - return ""; } - return userdata; } - return ""; + return userdata; } } // namespace HTTP - -#include "core/moc_http.cpp"
--- a/src/core/strings.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/core/strings.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -96,7 +96,11 @@ std::string ToUtf8String(const QString& string) { QByteArray ba = string.toUtf8(); - return std::string(ba.data(), ba.size()); + return std::string(ba.constData(), ba.size()); +} + +std::string ToUtf8String(const QByteArray& ba) { + return std::string(ba.constData(), ba.size()); } QString ToQString(const std::string& string) {
--- a/src/gui/dialog/about.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/gui/dialog/about.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -16,17 +16,17 @@ #define SET_TITLE_FONT(font, format, cursor) \ { \ - font = cursor.charFormat().font(); \ - font.setPixelSize(16); \ - format.setFont(font); \ + QFont fnt; \ + fnt.setPixelSize(16); \ + format.setFont(fnt); \ cursor.setCharFormat(format); \ } #define SET_PARAGRAPH_FONT(font, format, cursor) \ { \ - font = cursor.charFormat().font(); \ - font.setPixelSize(12); \ - format.setFont(font); \ + QFont fnt; \ + fnt.setPixelSize(12); \ + format.setFont(fnt); \ cursor.setCharFormat(format); \ } @@ -48,12 +48,18 @@ #define SET_FORMAT_HYPERLINK(format, cursor, link) \ { \ + font = cursor.charFormat().font(); \ + font.setUnderline(true); \ + format.setFont(font); \ format.setAnchor(true); \ format.setAnchorHref(link); \ cursor.setCharFormat(format); \ } #define UNSET_FORMAT_HYPERLINK(format, cursor) \ { \ + font = cursor.charFormat().font(); \ + font.setUnderline(false); \ + format.setFont(font); \ format.setAnchor(false); \ format.setAnchorHref(""); \ cursor.setCharFormat(format); \
--- a/src/gui/dialog/information.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/gui/dialog/information.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -235,7 +235,7 @@ CREATE_FULL_WIDTH_SUBSECTION({ subsection_layout->addWidget(new QLabel(tr("Alternative titles:"), subsection)); - QLineEdit* line_edit = new QLineEdit(Strings::ToQString(anime.GetUserNotes()), subsection); + QLineEdit* line_edit = new QLineEdit("", subsection); line_edit->setPlaceholderText( tr("Enter alternative titles here, separated by a semicolon (i.e. Title 1; Title 2)")); subsection_layout->addWidget(line_edit);
--- a/src/gui/dialog/settings.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/gui/dialog/settings.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -16,7 +16,7 @@ page_title->setFrameShadow(QFrame::Sunken); QFont font(page_title->font()); - font.setPixelSize(13); + font.setPixelSize(12); font.setWeight(QFont::Bold); page_title->setFont(font); @@ -75,10 +75,6 @@ sidebar->setIconSize(QSize(24, 24)); sidebar->setFrameShape(QFrame::Box); - QFont font(sidebar->font()); - font.setPixelSize(12); - sidebar->setFont(font); - QPalette pal(sidebar->palette()); sidebar->SetBackgroundColor(pal.color(QPalette::Base));
--- a/src/gui/pages/anime_list.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/gui/pages/anime_list.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -26,7 +26,8 @@ #include <QShortcut> #include <QStylePainter> #include <QStyledItemDelegate> -#include <cmath> +#include <QThreadPool> +#include <set> AnimeListPageDelegate::AnimeListPageDelegate(QObject* parent) : QStyledItemDelegate(parent) { } @@ -191,33 +192,19 @@ return QVariant(); } -void AnimeListPageModel::UpdateAnime(int id) { - /* meh... it might be better to just reinit the entire list */ - 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)); - } - i++; - } -} - Anime::Anime* AnimeListPageModel::GetAnimeFromIndex(QModelIndex index) { return &list.at(index.row()); } void AnimeListPageModel::RefreshList() { bool has_children = !!rowCount(index(0)); - if (has_children) - beginResetModel(); - else { - int count = 0; - for (const auto& a : Anime::db.items) - if (a.second.IsInUserList() && a.second.GetUserStatus() == status) - count++; - beginInsertRows(index(0), 0, count - 1); + if (!has_children) { + beginInsertRows(QModelIndex(), 0, 0); + endInsertRows(); } + beginResetModel(); + list.clear(); for (const auto& a : Anime::db.items) { @@ -226,10 +213,7 @@ } } - if (has_children) - endResetModel(); - else - endInsertRows(); + endResetModel(); } int AnimeListPage::VisibleColumnsCount() const { @@ -258,6 +242,19 @@ tree_view->setColumnHidden(AnimeListPageModel::AL_NOTES, true); } +void AnimeListPage::UpdateAnime(int id) { + QThreadPool::globalInstance()->start([this, id] { + Services::UpdateAnimeEntry(id); + Refresh(); + }); +} + +void AnimeListPage::RemoveAnime(int id) { + Anime::Anime& anime = Anime::db.items[id]; + anime.RemoveFromUserList(); + Refresh(); +} + void AnimeListPage::DisplayColumnHeaderMenu() { QMenu* menu = new QMenu(this); menu->setAttribute(Qt::WA_DeleteOnClose); @@ -301,32 +298,35 @@ menu->setTitle(tr("Column visibility")); menu->setToolTipsVisible(true); + AnimeListPageModel* source_model = + reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); const QItemSelection selection = sort_models[tab_bar->currentIndex()]->mapSelectionToSource(tree_view->selectionModel()->selection()); - if (!selection.indexes().first().isValid()) { - return; + + std::set<Anime::Anime*> animes; + for (const auto& index : selection.indexes()) { + if (!index.isValid()) + continue; + Anime::Anime* anime = source_model->GetAnimeFromIndex(index); + if (anime) + animes.insert(anime); } - QAction* action = menu->addAction(tr("Information"), [this, selection] { - AnimeListPageModel* source_model = - reinterpret_cast<AnimeListPageModel*>(sort_models[tab_bar->currentIndex()]->sourceModel()); - const QModelIndex index = source_model->index(selection.indexes().first().row()); - Anime::Anime* anime = source_model->GetAnimeFromIndex(index); - if (!anime) { - return; - } + QAction* action = menu->addAction(tr("Information"), [this, animes] { + for (auto& anime : animes) { + InformationDialog* dialog = new InformationDialog( + *anime, [this, anime] { UpdateAnime(anime->GetId()); }, this); - InformationDialog* dialog = new InformationDialog( - *anime, - [this, anime] { - Services::UpdateAnimeEntry(anime->GetId()); - Refresh(); - }, - this); - - dialog->show(); - dialog->raise(); - dialog->activateWindow(); + dialog->show(); + dialog->raise(); + dialog->activateWindow(); + } + }); + menu->addSeparator(); + action = menu->addAction(tr("Delete from list..."), [this, animes] { + for (auto& anime : animes) { + RemoveAnime(anime->GetId()); + } }); menu->popup(QCursor::pos()); } @@ -346,12 +346,7 @@ Anime::Anime* anime = source_model->GetAnimeFromIndex(index); InformationDialog* dialog = new InformationDialog( - *anime, - [this, anime] { - Services::UpdateAnimeEntry(anime->GetId()); - Refresh(); - }, - this); + *anime, [this, anime] { UpdateAnime(anime->GetId()); }, this); dialog->show(); dialog->raise();
--- a/src/gui/widgets/poster.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/gui/widgets/poster.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -12,6 +12,7 @@ #include <QLabel> #include <QMessageBox> #include <QPixmap> +#include <QThreadPool> #include <QUrl> #include <curl/curl.h> @@ -26,10 +27,10 @@ const Anime::Anime& anime = Anime::db.items[id]; - HTTP::HttpGetThread* image_thread = new HTTP::HttpGetThread(anime.GetPosterUrl(), {}, this); - connect(image_thread, &HTTP::HttpGetThread::resultReady, this, &Poster::ImageDownloadFinished); - connect(image_thread, &HTTP::HttpGetThread::finished, image_thread, &QObject::deleteLater); - image_thread->start(); + QThreadPool::globalInstance()->start([this, anime] { + QByteArray ba = HTTP::Get(anime.GetPosterUrl(), {}); + ImageDownloadFinished(ba); + }); QPixmap pixmap = QPixmap::fromImage(img);
--- a/src/gui/widgets/sidebar.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/gui/widgets/sidebar.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -16,10 +16,6 @@ SetBackgroundColor(Qt::transparent); - QFont font; - font.setPixelSize(12); - setFont(font); - connect(this, &QListWidget::currentRowChanged, this, [this](int index) { emit CurrentItemChanged(RemoveSeparatorsFromIndex(index)); }); }
--- a/src/gui/widgets/text.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/gui/widgets/text.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -1,5 +1,6 @@ #include "gui/widgets/text.h" #include "core/session.h" +#include <QDebug> #include <QFrame> #include <QLabel> #include <QTextBlock> @@ -16,8 +17,6 @@ QFont font = static_text_title->font(); font.setWeight(QFont::Bold); static_text_title->setFont(font); - /* FIXME: is this needed? */ - static_text_title->setFixedHeight(16); static_text_line = new QFrame(this); static_text_line->setFrameShape(QFrame::HLine); @@ -76,6 +75,7 @@ Line::Line(QString text, QWidget* parent) : QLineEdit(text, parent) { setFrame(false); setReadOnly(true); + setCursorPosition(0); /* displays left text first */ QPalette pal; pal.setColor(QPalette::Window, Qt::transparent);
--- a/src/gui/window.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/gui/window.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -27,6 +27,7 @@ #include <QPlainTextEdit> #include <QStackedWidget> #include <QTextStream> +#include <QThreadPool> #include <QTimer> #include <QToolBar> #include <QToolButton> @@ -48,6 +49,13 @@ TORRENTS }; +static void AsyncSynchronize(QStackedWidget* stack) { + QThreadPool::globalInstance()->start([stack] { + Services::Synchronize(); + reinterpret_cast<AnimeListPage*>(stack->widget(static_cast<int>(Pages::ANIME_LIST)))->Refresh(); + }); +} + MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { main_widget = new QWidget(parent); @@ -98,10 +106,7 @@ action = menu->addAction(tr("E&xit"), qApp, &QApplication::quit); menu = menubar->addMenu(tr("&Services")); - action = menu->addAction(tr("Synchronize &list"), [stack] { - Services::Synchronize(); - reinterpret_cast<AnimeListPage*>(stack->widget(static_cast<int>(Pages::ANIME_LIST)))->Refresh(); - }); + action = menu->addAction(tr("Synchronize &list"), [stack] { AsyncSynchronize(stack); }); action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S)); menu->addSeparator(); @@ -199,10 +204,8 @@ /* Toolbar */ QToolBar* toolbar = new QToolBar(this); - toolbar->addAction(QIcon(":/icons/24x24/arrow-circle-double-135.png"), tr("&Synchronize"), [stack] { - Services::Synchronize(); - reinterpret_cast<AnimeListPage*>(stack->widget(static_cast<int>(Pages::ANIME_LIST)))->Refresh(); - }); + toolbar->addAction(QIcon(":/icons/24x24/arrow-circle-double-135.png"), tr("&Synchronize"), + [stack] { AsyncSynchronize(stack); }); toolbar->addSeparator(); QToolButton* button = new QToolButton(toolbar);
--- a/src/services/anilist.cpp Wed Oct 04 01:46:33 2023 -0400 +++ b/src/services/anilist.cpp Fri Oct 06 06:18:53 2023 -0400 @@ -7,6 +7,7 @@ #include "core/session.h" #include "core/strings.h" #include "gui/translate/anilist.h" +#include <QByteArray> #include <QDesktopServices> #include <QInputDialog> #include <QLineEdit> @@ -40,7 +41,7 @@ std::string SendRequest(std::string data) { std::vector<std::string> headers = {"Authorization: Bearer " + account.AuthToken(), "Accept: application/json", "Content-Type: application/json"}; - return HTTP::PerformBasicPostRequest("https://graphql.anilist.co", data, headers); + return Strings::ToUtf8String(HTTP::Post("https://graphql.anilist.co", data, headers)); } void ParseListStatus(std::string status, Anime::Anime& anime) { @@ -255,13 +256,13 @@ * Date completedAt **/ Anime::Anime& anime = Anime::db.items[id]; - const std::string query = - "mutation ($media_id: Int, $progress: Int, $status: MediaListStatus, $score: Int, $notes: String) {\n" - " SaveMediaListEntry (mediaId: $media_id, progress: $progress, status: $status, scoreRaw: $score, notes: " - "$notes) {\n" - " id\n" - " }\n" - "}\n"; + const std::string query = "mutation ($media_id: Int, $progress: Int, $status: MediaListStatus, $score: Int, " + "$notes: String, $start: FuzzyDateInput, $comp: FuzzyDateInput) {\n" + " SaveMediaListEntry (mediaId: $media_id, progress: $progress, status: $status, " + "scoreRaw: $score, notes: $notes, startedAt: $start, completedAt: $comp) {\n" + " id\n" + " }\n" + "}\n"; // clang-format off nlohmann::json json = { {"query", query}, @@ -270,7 +271,9 @@ {"progress", anime.GetUserProgress()}, {"status", ListStatusToString(anime)}, {"score", anime.GetUserScore()}, - {"notes", anime.GetUserNotes()} + {"notes", anime.GetUserNotes()}, + {"start", anime.GetUserDateStarted().GetAsAniListJson()}, + {"comp", anime.GetUserDateCompleted().GetAsAniListJson()} }} }; // clang-format on