comparison src/gui/window.cc @ 258:862d0d8619f6

*: HUUUGE changes animia has been renamed to animone, so instead of thinking of a health condition, you think of a beautiful flower :) I've also edited some of the code for animone, but I have no idea if it even works or not because I don't have a mac or windows machine lying around. whoops! ... anyway, all of the changes divergent from Anisthesia are now licensed under BSD. it's possible that I could even rewrite most of the code to where I don't even have to keep the MIT license, but that's thinking too far into the future I've been slacking off on implementing the anime seasons page, mostly out of laziness. I think I'd have to create another db file specifically for the seasons anyway, this code is being pushed *primarily* because the hard drive it's on is failing! yay :)
author Paper <paper@paper.us.eu.org>
date Mon, 01 Apr 2024 02:43:44 -0400
parents fe702c8f161f
children f31305b9f60a
comparison
equal deleted inserted replaced
257:699a20c57dc8 258:862d0d8619f6
1 #include "gui/window.h" 1 #include "gui/window.h"
2 #include "core/anime_db.h" 2 #include "core/anime_db.h"
3 #include "core/config.h" 3 #include "core/config.h"
4 #include "core/session.h" 4 #include "core/session.h"
5 #include "core/strings.h" 5 #include "core/strings.h"
6 #include "gui/theme.h"
7 #include "gui/dialog/about.h" 6 #include "gui/dialog/about.h"
8 #include "gui/dialog/settings.h" 7 #include "gui/dialog/settings.h"
9 #include "gui/pages/anime_list.h" 8 #include "gui/pages/anime_list.h"
10 #include "gui/pages/history.h" 9 #include "gui/pages/history.h"
11 #include "gui/pages/now_playing.h" 10 #include "gui/pages/now_playing.h"
12 #include "gui/pages/search.h" 11 #include "gui/pages/search.h"
13 #include "gui/pages/seasons.h" 12 #include "gui/pages/seasons.h"
14 #include "gui/pages/statistics.h" 13 #include "gui/pages/statistics.h"
15 #include "gui/pages/torrents.h" 14 #include "gui/pages/torrents.h"
15 #include "gui/theme.h"
16 #include "gui/widgets/sidebar.h" 16 #include "gui/widgets/sidebar.h"
17 #include "library/library.h"
17 #include "services/services.h" 18 #include "services/services.h"
18 #include "track/media.h" 19 #include "track/media.h"
19 #include "library/library.h"
20 20
21 #include "anitomy/anitomy.h" 21 #include "anitomy/anitomy.h"
22 22
23 #include <QActionGroup> 23 #include <QActionGroup>
24 #include <QApplication> 24 #include <QApplication>
70 qRegisterMetaType<std::vector<std::string>>(); 70 qRegisterMetaType<std::vector<std::string>>();
71 71
72 /* This thread will be destroyed on 72 /* This thread will be destroyed on
73 * close of the program OR on the destruction 73 * close of the program OR on the destruction
74 * of MainWindow 74 * of MainWindow
75 */ 75 */
76 thread.reset(new PlayingThread(this)); 76 thread.reset(new PlayingThread(this));
77 77
78 connect(thread.get(), &PlayingThread::Done, this, [page](const std::vector<std::string>& files) { 78 connect(thread.get(), &PlayingThread::Done, this, [page](const std::vector<std::string>& files) {
79 for (const auto& file : files) { 79 for (const auto& file : files) {
80 anitomy::Anitomy anitomy; 80 anitomy::Anitomy anitomy;
81 anitomy.Parse(Strings::ToWstring(file)); 81 anitomy.Parse(Strings::ToWstring(file));
82 82
83 const auto& elements = anitomy.elements(); 83 const auto& elements = anitomy.elements();
84 const std::string title = Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle)); 84 const std::string title = Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle));
85 std::cout << title << std::endl;
86 85
87 int id = Anime::db.GetAnimeFromTitle(title); 86 int id = Anime::db.GetAnimeFromTitle(title);
88 if (id <= 0) 87 if (id <= 0)
89 continue; 88 continue;
90 89
169 168
170 UpdateFolderMenu(); 169 UpdateFolderMenu();
171 } 170 }
172 171
173 { 172 {
174 menu->addAction(tr("&Scan available episodes"), []{ 173 menu->addAction(tr("&Scan available episodes"), [] { Library::SearchLibraryFolders(); });
175 Library::SearchLibraryFolders();
176 });
177 } 174 }
178 175
179 menu->addSeparator(); 176 menu->addSeparator();
180 177
181 // { 178 // {
182 // QAction* action = menu->addAction(tr("Play &next episode")); 179 // QAction* action = menu->addAction(tr("Play &next episode"));
183 // action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N)); 180 // action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
184 // } 181 // }
185 // 182 //
186 // { 183 // {
187 // QAction* action = menu->addAction(tr("Play &random episode")); 184 // QAction* action = menu->addAction(tr("Play &random episode"));
188 // action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R)); 185 // action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
189 // } 186 // }
190 187
191 menu->addSeparator(); 188 menu->addSeparator();
192 189
193 { 190 {
194 QAction* action = menu->addAction(tr("E&xit"), this, &MainWindow::close); 191 QAction* action = menu->addAction(tr("E&xit"), this, &MainWindow::close);
201 QMenu* menu = menubar->addMenu(tr("&Services")); 198 QMenu* menu = menubar->addMenu(tr("&Services"));
202 { 199 {
203 { 200 {
204 sync_action = menu->addAction(tr("Synchronize &list")); 201 sync_action = menu->addAction(tr("Synchronize &list"));
205 202
206 connect(sync_action, &QAction::triggered, this, [this, sync_action]{ 203 connect(sync_action, &QAction::triggered, this,
207 AsyncSynchronize(sync_action, stack.get()); 204 [this, sync_action] { AsyncSynchronize(sync_action, stack.get()); });
208 });
209 205
210 sync_action->setIcon(QIcon(":/icons/24x24/arrow-circle-double-135.png")); 206 sync_action->setIcon(QIcon(":/icons/24x24/arrow-circle-double-135.png"));
211 sync_action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S)); 207 sync_action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));
212 } 208 }
213 209
214 // menu->addSeparator(); 210 // menu->addSeparator();
215 // 211 //
216 // { 212 // {
217 // /* AniList */ 213 // /* AniList */
218 // QMenu* submenu = menu->addMenu(tr("&AniList")); 214 // QMenu* submenu = menu->addMenu(tr("&AniList"));
219 // QAction* action = submenu->addAction(tr("Go to my &profile")); 215 // QAction* action = submenu->addAction(tr("Go to my &profile"));
220 // action = submenu->addAction(tr("Go to my &stats")); 216 // action = submenu->addAction(tr("Go to my &stats"));
221 // } 217 // }
222 // 218 //
223 // { 219 // {
224 // /* Kitsu */ 220 // /* Kitsu */
225 // QMenu* submenu = menu->addMenu(tr("&Kitsu")); 221 // QMenu* submenu = menu->addMenu(tr("&Kitsu"));
226 // QAction* action = submenu->addAction(tr("Go to my &feed")); 222 // QAction* action = submenu->addAction(tr("Go to my &feed"));
227 // action = submenu->addAction(tr("Go to my &library")); 223 // action = submenu->addAction(tr("Go to my &library"));
228 // action = submenu->addAction(tr("Go to my &profile")); 224 // action = submenu->addAction(tr("Go to my &profile"));
229 // } 225 // }
230 // { 226 // {
231 // QMenu* submenu = menu->addMenu(tr("&MyAnimeList")); 227 // QMenu* submenu = menu->addMenu(tr("&MyAnimeList"));
232 // QAction* action = submenu->addAction(tr("Go to my p&anel")); 228 // QAction* action = submenu->addAction(tr("Go to my p&anel"));
233 // action = submenu->addAction(tr("Go to my &profile")); 229 // action = submenu->addAction(tr("Go to my &profile"));
234 // action = submenu->addAction(tr("Go to my &history")); 230 // action = submenu->addAction(tr("Go to my &history"));
235 // } 231 // }
236 } 232 }
237 } 233 }
238 234
239 { 235 {
240 /* Tools */ 236 /* Tools */
241 QMenu* menu = menubar->addMenu(tr("&Tools")); 237 QMenu* menu = menubar->addMenu(tr("&Tools"));
242 // { 238 // {
243 // /* Export anime list */ 239 // /* Export anime list */
244 // QMenu* submenu = menu->addMenu(tr("&Export anime list")); 240 // QMenu* submenu = menu->addMenu(tr("&Export anime list"));
245 // 241 //
246 // { 242 // {
247 // /* Markdown export */ 243 // /* Markdown export */
248 // QAction* action = submenu->addAction(tr("Export as &Markdown...")); 244 // QAction* action = submenu->addAction(tr("Export as &Markdown..."));
249 // } 245 // }
250 // 246 //
251 // { 247 // {
252 // /* XML export */ 248 // /* XML export */
253 // QAction* action = submenu->addAction(tr("Export as MyAnimeList &XML...")); 249 // QAction* action = submenu->addAction(tr("Export as MyAnimeList &XML..."));
254 // } 250 // }
255 // } 251 // }
256 // menu->addSeparator(); 252 // menu->addSeparator();
257 // 253 //
258 // { 254 // {
259 // QAction* action = menu->addAction(tr("Enable anime &recognition")); 255 // QAction* action = menu->addAction(tr("Enable anime &recognition"));
260 // action->setCheckable(true); 256 // action->setCheckable(true);
261 // } 257 // }
262 // 258 //
263 // { 259 // {
264 // QAction* action = menu->addAction(tr("Enable auto &sharing")); 260 // QAction* action = menu->addAction(tr("Enable auto &sharing"));
265 // action->setCheckable(true); 261 // action->setCheckable(true);
266 // } 262 // }
267 // 263 //
268 // { 264 // {
269 // QAction* action = menu->addAction(tr("Enable &auto synchronization")); 265 // QAction* action = menu->addAction(tr("Enable &auto synchronization"));
270 // action->setCheckable(true); 266 // action->setCheckable(true);
271 // } 267 // }
272 // 268 //
273 // menu->addSeparator(); 269 // menu->addSeparator();
274 270
275 { 271 {
276 QAction* action = menu->addAction(tr("&Settings"), [this] { 272 QAction* action = menu->addAction(tr("&Settings"), [this] {
277 SettingsDialog dialog(this); 273 SettingsDialog dialog(this);
278 dialog.exec(); 274 dialog.exec();
292 pages_group->setExclusive(true); 288 pages_group->setExclusive(true);
293 289
294 { 290 {
295 QAction* action = pages_group->addAction(menu->addAction(tr("&Now Playing"))); 291 QAction* action = pages_group->addAction(menu->addAction(tr("&Now Playing")));
296 action->setCheckable(true); 292 action->setCheckable(true);
297 connect(action, &QAction::toggled, this, [this] { 293 connect(action, &QAction::toggled, this, [this] { sidebar->SetCurrentItem(0); });
298 sidebar->SetCurrentItem(0);
299 });
300 } 294 }
301 295
302 { 296 {
303 QAction* action = pages_group->addAction(menu->addAction(tr("&Anime List"))); 297 QAction* action = pages_group->addAction(menu->addAction(tr("&Anime List")));
304 action->setCheckable(true); 298 action->setCheckable(true);
305 action->setChecked(true); 299 action->setChecked(true);
306 connect(action, &QAction::toggled, this, [this] { 300 connect(action, &QAction::toggled, this, [this] { sidebar->SetCurrentItem(1); });
307 sidebar->SetCurrentItem(1);
308 });
309 } 301 }
310 302
311 { 303 {
312 QAction* action = pages_group->addAction(menu->addAction(tr("&History"))); 304 QAction* action = pages_group->addAction(menu->addAction(tr("&History")));
313 action->setCheckable(true); 305 action->setCheckable(true);
314 connect(action, &QAction::toggled, this, [this] { 306 connect(action, &QAction::toggled, this, [this] { sidebar->SetCurrentItem(2); });
315 sidebar->SetCurrentItem(2);
316 });
317 } 307 }
318 308
319 { 309 {
320 QAction* action = pages_group->addAction(menu->addAction(tr("&Statistics"))); 310 QAction* action = pages_group->addAction(menu->addAction(tr("&Statistics")));
321 action->setCheckable(true); 311 action->setCheckable(true);
322 connect(action, &QAction::toggled, this, [this] { 312 connect(action, &QAction::toggled, this, [this] { sidebar->SetCurrentItem(3); });
323 sidebar->SetCurrentItem(3);
324 });
325 } 313 }
326 314
327 { 315 {
328 QAction* action = pages_group->addAction(menu->addAction(tr("S&earch"))); 316 QAction* action = pages_group->addAction(menu->addAction(tr("S&earch")));
329 action->setCheckable(true); 317 action->setCheckable(true);
330 connect(action, &QAction::toggled, this, [this] { 318 connect(action, &QAction::toggled, this, [this] { sidebar->SetCurrentItem(4); });
331 sidebar->SetCurrentItem(4);
332 });
333 } 319 }
334 320
335 { 321 {
336 QAction* action = pages_group->addAction(menu->addAction(tr("Se&asons"))); 322 QAction* action = pages_group->addAction(menu->addAction(tr("Se&asons")));
337 action->setCheckable(true); 323 action->setCheckable(true);
338 connect(action, &QAction::toggled, this, [this] { 324 connect(action, &QAction::toggled, this, [this] { sidebar->SetCurrentItem(5); });
339 sidebar->SetCurrentItem(5);
340 });
341 } 325 }
342 326
343 { 327 {
344 QAction* action = pages_group->addAction(menu->addAction(tr("&Torrents"))); 328 QAction* action = pages_group->addAction(menu->addAction(tr("&Torrents")));
345 action->setCheckable(true); 329 action->setCheckable(true);
346 connect(action, &QAction::toggled, this, [this] { 330 connect(action, &QAction::toggled, this, [this] { sidebar->SetCurrentItem(6); });
347 sidebar->SetCurrentItem(6);
348 });
349 } 331 }
350 332
351 /* pain in my ass */ 333 /* pain in my ass */
352 connect(sidebar.get(), &SideBar::CurrentItemChanged, this, [pages_group](int index) { 334 connect(sidebar.get(), &SideBar::CurrentItemChanged, this, [pages_group](int index) {
353 QAction* checked = pages_group->checkedAction(); 335 QAction* checked = pages_group->checkedAction();
362 }); 344 });
363 } 345 }
364 346
365 menu->addSeparator(); 347 menu->addSeparator();
366 348
367 // { 349 // {
368 // QAction* action = menu->addAction(tr("Show sidebar")); 350 // QAction* action = menu->addAction(tr("Show sidebar"));
369 // } 351 // }
370 } 352 }
371 353
372 { 354 {
373 /* Help */ 355 /* Help */
374 QMenu* menu = menubar->addMenu(tr("&Help")); 356 QMenu* menu = menubar->addMenu(tr("&Help"));
387 action->setMenuRole(QAction::AboutQtRole); 369 action->setMenuRole(QAction::AboutQtRole);
388 } 370 }
389 } 371 }
390 /* QMainWindow will delete the old one for us, 372 /* QMainWindow will delete the old one for us,
391 * according to the docs 373 * according to the docs
392 */ 374 */
393 setMenuBar(menubar); 375 setMenuBar(menubar);
394 376
395 /* Toolbar */ 377 /* Toolbar */
396 378
397 /* remove old toolbar(s) */ 379 /* remove old toolbar(s) */
408 390
409 toolbar->addSeparator(); 391 toolbar->addSeparator();
410 392
411 { 393 {
412 QToolButton* button = new QToolButton(toolbar); 394 QToolButton* button = new QToolButton(toolbar);
413 { 395 { button->setMenu(folder_menu); }
414 button->setMenu(folder_menu);
415 }
416 button->setIcon(QIcon(":/icons/24x24/folder-open.png")); 396 button->setIcon(QIcon(":/icons/24x24/folder-open.png"));
417 button->setPopupMode(QToolButton::InstantPopup); 397 button->setPopupMode(QToolButton::InstantPopup);
418 toolbar->addWidget(button); 398 toolbar->addWidget(button);
419 } 399 }
420 400
422 QToolButton* button = new QToolButton(toolbar); 402 QToolButton* button = new QToolButton(toolbar);
423 403
424 { 404 {
425 /* links */ 405 /* links */
426 QMenu* menu = new QMenu(button); 406 QMenu* menu = new QMenu(button);
427 menu->addAction("Hibari", []{ 407 menu->addAction("Hibari", [] { QDesktopServices::openUrl(QUrl("https://hb.wopian.me/")); });
428 QDesktopServices::openUrl(QUrl("https://hb.wopian.me/")); 408 menu->addAction("MALgraph", [] { QDesktopServices::openUrl(QUrl("https://graph.anime.plus/")); });
429 });
430 menu->addAction("MALgraph", []{
431 QDesktopServices::openUrl(QUrl("https://graph.anime.plus/"));
432 });
433 menu->addSeparator(); 409 menu->addSeparator();
434 menu->addAction("AniChart", []{ 410 menu->addAction("AniChart", [] { QDesktopServices::openUrl(QUrl("https://anichart.net/airing")); });
435 QDesktopServices::openUrl(QUrl("https://anichart.net/airing")); 411 menu->addAction("Monthly.moe",
436 }); 412 [] { QDesktopServices::openUrl(QUrl("https://www.monthly.moe/weekly")); });
437 menu->addAction("Monthly.moe", []{ 413 menu->addAction("Senpai Anime Charts",
438 QDesktopServices::openUrl(QUrl("https://www.monthly.moe/weekly")); 414 [] { QDesktopServices::openUrl(QUrl("https://www.senpai.moe/?mode=calendar")); });
439 });
440 menu->addAction("Senpai Anime Charts", []{
441 QDesktopServices::openUrl(QUrl("https://www.senpai.moe/?mode=calendar"));
442 });
443 menu->addSeparator(); 415 menu->addSeparator();
444 menu->addAction("Anime Streaming Search Engine", []{ 416 menu->addAction("Anime Streaming Search Engine",
445 QDesktopServices::openUrl(QUrl("https://because.moe/")); 417 [] { QDesktopServices::openUrl(QUrl("https://because.moe/")); });
446 }); 418 menu->addAction("The Fansub Database", [] { QDesktopServices::openUrl(QUrl("https://fansubdb.com")); });
447 menu->addAction("The Fansub Database", []{
448 QDesktopServices::openUrl(QUrl("https://fansubdb.com"));
449 });
450 419
451 button->setMenu(menu); 420 button->setMenu(menu);
452 } 421 }
453 422
454 button->setIcon(QIcon(":/icons/24x24/application-export.png")); 423 button->setIcon(QIcon(":/icons/24x24/application-export.png"));
475 444
476 /* add in all of our existing folders... */ 445 /* add in all of our existing folders... */
477 std::size_t i = 0; 446 std::size_t i = 0;
478 for (const auto& path : session.config.library.paths) { 447 for (const auto& path : session.config.library.paths) {
479 const QString folder = Strings::ToQString(path); 448 const QString folder = Strings::ToQString(path);
480 QAction* action = folder_menu->addAction(folder, [folder]{ 449 QAction* action =
481 QDesktopServices::openUrl(QUrl::fromLocalFile(folder)); 450 folder_menu->addAction(folder, [folder] { QDesktopServices::openUrl(QUrl::fromLocalFile(folder)); });
482 });
483 451
484 if (i < 9) { 452 if (i < 9) {
485 /* Qt::Key_1 is equivalent to 1 in ASCII, so we can use the same 453 /* Qt::Key_1 is equivalent to 1 in ASCII, so we can use the same
486 * stupid `'0' + i` trick here 454 * stupid `'0' + i` trick here
487 */ 455 */
488 action->setShortcut(QKeySequence(Qt::ALT | static_cast<Qt::Modifier>(Qt::Key_1 + i))); 456 action->setShortcut(QKeySequence(Qt::ALT | static_cast<Qt::Modifier>(Qt::Key_1 + i)));
489 } else if (i == 9) { 457 } else if (i == 9) {
490 action->setShortcut(QKeySequence(Qt::ALT | Qt::Key_0)); 458 action->setShortcut(QKeySequence(Qt::ALT | Qt::Key_0));
491 } 459 }
492 /* don't bother with a shortcut in case of more... */ 460 /* don't bother with a shortcut in case of more... */
494 } 462 }
495 463
496 folder_menu->addSeparator(); 464 folder_menu->addSeparator();
497 465
498 { 466 {
499 folder_menu->addAction(tr("&Add new folder..."), [this]{ 467 folder_menu->addAction(tr("&Add new folder..."), [this] {
500 const QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), 468 const QString dir =
501 QDir::homePath(), 469 QFileDialog::getExistingDirectory(this, tr("Open Directory"), QDir::homePath(),
502 QFileDialog::ShowDirsOnly 470 QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
503 | QFileDialog::DontResolveSymlinks);
504 if (dir.isEmpty()) 471 if (dir.isEmpty())
505 return; 472 return;
506 session.config.library.paths.insert(Strings::ToUtf8String(dir)); 473 session.config.library.paths.insert(Strings::ToUtf8String(dir));
507 UpdateFolderMenu(); 474 UpdateFolderMenu();
508 }); 475 });
547 514
548 void MainWindow::changeEvent(QEvent* event) { 515 void MainWindow::changeEvent(QEvent* event) {
549 if (event) { /* is this really necessary */ 516 if (event) { /* is this really necessary */
550 switch (event->type()) { 517 switch (event->type()) {
551 // this event is send if a translator is loaded 518 // this event is send if a translator is loaded
552 case QEvent::LanguageChange: 519 case QEvent::LanguageChange: RetranslateUI(); break;
553 RetranslateUI(); 520
554 break; 521 default: break;
555
556 default:
557 break;
558 } 522 }
559 } 523 }
560 QMainWindow::changeEvent(event); 524 QMainWindow::changeEvent(event);
561 } 525 }
562 526