diff src/gui/pages/anime_list.cc @ 366:886f66775f31

animone: add preliminary AT-SPI stuff anime_list: finish the regular singular right click menu
author Paper <paper@tflc.us>
date Sun, 17 Nov 2024 19:56:01 -0500
parents b5d6c27c308f
children
line wrap: on
line diff
--- a/src/gui/pages/anime_list.cc	Wed Oct 02 23:06:43 2024 -0400
+++ b/src/gui/pages/anime_list.cc	Sun Nov 17 19:56:01 2024 -0500
@@ -14,6 +14,7 @@
 #include "core/session.h"
 #include "core/strings.h"
 #include "core/time.h"
+#include "library/library.h"
 #include "gui/dialog/information.h"
 #include "gui/translate/anime.h"
 #include "services/services.h"
@@ -30,8 +31,11 @@
 #include <QThreadPool>
 #include <QRunnable>
 #include <QTreeView>
+#include <QDesktopServices>
+#include <QUrl>
 
-#include <set>
+#include <iostream>
+#include <vector>
 
 AnimeListPageUpdateEntryThread::AnimeListPageUpdateEntryThread(QObject* parent) : QThread(parent) {}
 
@@ -272,7 +276,7 @@
 			if (checked && (tree_view->columnWidth(i) <= 5))
 				tree_view->resizeColumnToContents(i);
 
-			// SaveSettings();
+			// FIXME save the state of this
 		});
 
 		action->setCheckable(true);
@@ -290,7 +294,7 @@
 }
 
 void AnimeListPage::DisplayListMenu() {
-	QMenu* menu = new QMenu(this);
+	QMenu *const menu = new QMenu(this);
 	menu->setAttribute(Qt::WA_DeleteOnClose);
 	menu->setToolTipsVisible(true);
 
@@ -303,14 +307,71 @@
 	for (const auto& index : selection.indexes()) {
 		if (!index.isValid())
 			continue;
-		Anime::Anime* anime = source_model->GetAnimeFromIndex(index);
+
+		Anime::Anime *const anime = source_model->GetAnimeFromIndex(index);
 		if (!anime)
 			continue;
+
 		animes.insert(&Anime::db.items[anime->GetId()]);
 	}
 
-	menu->addAction(tr("Information"), [this, animes] {
-		for (auto& anime : animes) {
+	if (animes.size() > 1) {
+		// menu in Taiga:
+		//
+		// Set date started ->
+		//   Clear
+		//   Set to date started airing
+		// Set date completed ->
+		//   Clear
+		//   Set to date finished airing
+		//   Set to last updated
+		// Set episode...
+		// Set score ->
+		//   0
+		//   10
+		//   ...
+		//   100
+		// Set status ->
+		//   Currently watching
+		//   ...
+		//   Plan to watch
+		// Set notes...
+		// ----------------
+		// Invert selection
+		// ----------------
+		// Delete from list... <Del>
+	} else if (animes.size() > 0) {
+		// menu in Taiga:
+		//
+		// Information
+		// Search ->
+		//   AniDB
+		//   AniList
+		//   Anime News Network
+		//   Kitsu
+		//   MyAnimeList
+		//   Reddit
+		//   Wikipedia
+		//   YouTube
+		//   ----------------
+		//   Custom RSS feed
+		//   Nyaa.si
+		// ----------------
+		// Edit
+		// Delete from list... <Del>
+		// ----------------
+		// Open folder <Ctrl+O>
+		// Scan available episodes <F5>
+		// ----------------
+		// Play episode ->
+		//   grid of episodes (dunno how to implement this)
+		// Play last episode (#<episode>)
+		// Play next episode (#<episode>) <Ctrl+N>
+		// Play random episode <Ctrl+R> (why?)
+
+		Anime::Anime *anime = *animes.begin();
+
+		menu->addAction(tr("Information"), [this, anime] {
 			InformationDialog* dialog = new InformationDialog(
 				anime, [this](Anime::Anime* anime) { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this);
 
@@ -318,11 +379,11 @@
 			dialog->raise();
 			dialog->activateWindow();
 			connect(dialog, &InformationDialog::finished, dialog, &InformationDialog::deleteLater);
-		}
-	});
-	menu->addSeparator();
-	menu->addAction(tr("Edit"), [this, animes] {
-		for (auto& anime : animes) {
+		});
+
+		menu->addSeparator();
+
+		menu->addAction(tr("Edit"), [this, anime] {
 			InformationDialog* dialog = new InformationDialog(
 				anime, [this](Anime::Anime* anime) { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MY_LIST, this);
 
@@ -330,14 +391,80 @@
 			dialog->raise();
 			dialog->activateWindow();
 			connect(dialog, &InformationDialog::finished, dialog, &InformationDialog::deleteLater);
+		});
+		menu->addAction(tr("Delete from list..."), [this, anime] {
+			RemoveAnime(anime->GetId());
+		}, QKeySequence(QKeySequence::Delete));
+
+		menu->addSeparator();
+
+		menu->addAction(tr("Open folder"), [this, anime] {
+			std::optional<std::filesystem::path> path = Library::db.GetAnimeFolder(anime->GetId());
+			if (!path) // ...
+				return;
+
+			QDesktopServices::openUrl(QUrl::fromLocalFile(Strings::ToQString(path.value().u8string())));
+		});
+		menu->addAction(tr("Scan available episodes"), [this, anime] {
+			Library::db.Refresh(anime->GetId());
+		});
+
+		menu->addSeparator();
+
+		{
+			QMenu *submenu = menu->addMenu(tr("Play episode"));
+
+			// this submenu actually uses win32 API magic to
+			// make a *grid* of episodes (weird!)
+
+			(void)submenu;
 		}
-	});
-	menu->addAction(tr("Delete from list..."), [this, animes] {
-		for (auto& anime : animes) {
-			RemoveAnime(anime->GetId());
+
+		const int progress = anime->GetUserProgress();
+		const int episodes = anime->GetEpisodes();
+
+		// I think this is right?
+		if (progress > 0) {
+			menu->addAction(tr("Play last episode (#%1)").arg(progress), [this, anime, progress] {
+				const int id = anime->GetId();
+
+				if (Library::db.items.find(id) == Library::db.items.end()
+					|| Library::db.items[id].find(progress) == Library::db.items[id].end())
+					return;
+
+				QDesktopServices::openUrl(QUrl::fromLocalFile(Strings::ToQString(Library::db.items[id][progress].u8string())));
+			});
 		}
-	});
-	menu->popup(QCursor::pos());
+
+		if (progress < episodes) {
+			menu->addAction(tr("Play next episode (#%1)").arg(progress + 1), [this, anime, progress] {
+				const int id = anime->GetId();
+
+				if (Library::db.items.find(id) == Library::db.items.end()
+					|| Library::db.items[id].find(progress + 1) == Library::db.items[id].end())
+					return;
+
+				QDesktopServices::openUrl(QUrl::fromLocalFile(Strings::ToQString(Library::db.items[id][progress + 1].u8string())));
+			}, QKeySequence(Qt::CTRL | Qt::Key_N));
+		}
+
+		menu->addAction(tr("Play random episode"), [this, anime, episodes] {
+			const int id = anime->GetId();
+
+			std::uniform_int_distribution<int> distrib(1, episodes);
+			const int episode = distrib(session.gen);
+
+			if (Library::db.items.find(id) == Library::db.items.end()
+				|| Library::db.items[id].find(episode) == Library::db.items[id].end())
+				return;
+
+			QDesktopServices::openUrl(QUrl::fromLocalFile(Strings::ToQString(Library::db.items[id][episode].u8string())));
+		}, QKeySequence(Qt::CTRL | Qt::Key_R));
+
+		menu->popup(QCursor::pos());
+	} else {
+		// Where are we now?
+	}
 }
 
 void AnimeListPage::ItemDoubleClicked() {