view src/gui/window.cc @ 113:32afe0e940bf

window: remove tiny little debug thing
author Paper <mrpapersonic@gmail.com>
date Mon, 06 Nov 2023 13:48:11 -0500
parents 80f49f623d30
children ab191e28e69d
line wrap: on
line source

#include "gui/window.h"
#include "core/anime_db.h"
#include "core/config.h"
#include "core/session.h"
#include "core/strings.h"
#include "gui/theme.h"
#include "gui/dialog/about.h"
#include "gui/dialog/settings.h"
#include "gui/pages/anime_list.h"
#include "gui/pages/history.h"
#include "gui/pages/now_playing.h"
#include "gui/pages/search.h"
#include "gui/pages/seasons.h"
#include "gui/pages/statistics.h"
#include "gui/pages/torrents.h"
#include "gui/widgets/sidebar.h"
#include "services/services.h"
#include "track/media.h"
#include <QActionGroup>
#include <QApplication>
#include <QDebug>
#include <QFile>
#include <QHBoxLayout>
#include <QMainWindow>
#include <QMenuBar>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QStackedWidget>
#include <QTextStream>
#include <QThreadPool>
#include <QTimer>
#include <QToolBar>
#include <QToolButton>
#include <iostream>
#ifdef MACOSX
#	include "sys/osx/dark_theme.h"
#elif defined(WIN32)
#	include "sys/win32/dark_theme.h"
#endif

enum class Pages {
	NOW_PLAYING,

	ANIME_LIST,
	HISTORY,
	STATISTICS,

	SEARCH,
	SEASONS,
	TORRENTS
};

MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
	setWindowIcon(QIcon(":/favicon.png"));

	main_widget = new QWidget(this);
	/*QHBoxLayout* layout = */new QHBoxLayout(main_widget);

	AddMainWidgets();

	setCentralWidget(main_widget);

	CreateBars();

	QTimer* timer = new QTimer(this);
	connect(timer, &QTimer::timeout, this, [this] {
		NowPlayingPage* page = reinterpret_cast<NowPlayingPage*>(stack->widget(static_cast<int>(Pages::NOW_PLAYING)));

		Filesystem::Path p = Track::Media::GetCurrentPlaying();
		std::unordered_map<std::string, std::string> elements = Track::Media::GetFileElements(p);
		int id = Anime::db.GetAnimeFromTitle(elements["title"]);
		if (id <= 0) {
			page->SetDefault();
			return;
		}

		page->SetPlaying(Anime::db.items[id], elements);
	});
	timer->start(5000);
}

void MainWindow::AddMainWidgets() {
	int page = static_cast<int>(Pages::ANIME_LIST);
	if (sidebar) {
		main_widget->layout()->removeWidget(sidebar);
		delete sidebar;
	}

	if (stack) {
		page = stack->currentIndex();
		main_widget->layout()->removeWidget(stack);
		delete stack;
	}

	sidebar = new SideBar(main_widget);
	sidebar->setFixedWidth(128);
	sidebar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);

	sidebar->AddItem(tr("Now Playing"), SideBar::CreateIcon(":/icons/16x16/film.png"));
	sidebar->AddSeparator();
	sidebar->AddItem(tr("Anime List"), SideBar::CreateIcon(":/icons/16x16/document-list.png"));
	sidebar->AddItem(tr("History"), SideBar::CreateIcon(":/icons/16x16/clock-history-frame.png"));
	sidebar->AddItem(tr("Statistics"), SideBar::CreateIcon(":/icons/16x16/chart.png"));
	sidebar->AddSeparator();
	sidebar->AddItem(tr("Search"), SideBar::CreateIcon(":/icons/16x16/magnifier.png"));
	sidebar->AddItem(tr("Seasons"), SideBar::CreateIcon(":/icons/16x16/calendar.png"));
	sidebar->AddItem(tr("Torrents"), SideBar::CreateIcon(":/icons/16x16/feed.png"));

	stack = new QStackedWidget(main_widget);
	stack->addWidget(new NowPlayingPage(main_widget));
	stack->addWidget(new AnimeListPage(main_widget));
	stack->addWidget(new HistoryPage(main_widget));
	stack->addWidget(new StatisticsPage(main_widget));
	stack->addWidget(new SearchPage(main_widget));
	stack->addWidget(new SeasonsPage(main_widget));
	stack->addWidget(new TorrentsPage(main_widget));

	connect(sidebar, &SideBar::CurrentItemChanged, stack, &QStackedWidget::setCurrentIndex);
	sidebar->SetCurrentItem(page);

	main_widget->layout()->addWidget(sidebar);
	main_widget->layout()->addWidget(stack);
}

void MainWindow::CreateBars() {
	/* Menu Bar */
	QAction* action;
	QMenuBar* menubar = new QMenuBar(this);
	QMenu* menu = menubar->addMenu(tr("&File"));

	QMenu* submenu = menu->addMenu(tr("&Library folders"));
	action = submenu->addAction(tr("&Add new folder..."));

	action = menu->addAction(tr("&Scan available episodes"));

	menu->addSeparator();

	action = menu->addAction(tr("Play &next episode"));
	action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
	action = menu->addAction(tr("Play &random episode"));
	action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));

	menu->addSeparator();

	action = menu->addAction(tr("E&xit"), qApp, &QApplication::quit);

	menu = menubar->addMenu(tr("&Services"));
	action = menu->addAction(tr("Synchronize &list"), [this] { AsyncSynchronize(stack); });
	action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));

	menu->addSeparator();

	submenu = menu->addMenu(tr("&AniList"));
	action = submenu->addAction(tr("Go to my &profile"));
	action = submenu->addAction(tr("Go to my &stats"));

	submenu = menu->addMenu(tr("&Kitsu"));
	action = submenu->addAction(tr("Go to my &feed"));
	action = submenu->addAction(tr("Go to my &library"));
	action = submenu->addAction(tr("Go to my &profile"));

	submenu = menu->addMenu(tr("&MyAnimeList"));
	action = submenu->addAction(tr("Go to my p&anel"));
	action = submenu->addAction(tr("Go to my &profile"));
	action = submenu->addAction(tr("Go to my &history"));

	menu = menubar->addMenu(tr("&Tools"));
	submenu = menu->addMenu(tr("&Export anime list"));
	action = submenu->addAction(tr("Export as &Markdown..."));
	action = submenu->addAction(tr("Export as MyAnimeList &XML..."));

	menu->addSeparator();

	action = menu->addAction(tr("Enable anime &recognition"));
	action->setCheckable(true);
	action = menu->addAction(tr("Enable auto &sharing"));
	action->setCheckable(true);
	action = menu->addAction(tr("Enable &auto synchronization"));
	action->setCheckable(true);

	menu->addSeparator();

	action = menu->addAction(tr("&Settings"), [this] {
		SettingsDialog dialog(this);
		dialog.exec();
	});
	action->setMenuRole(QAction::PreferencesRole);

	menu = menubar->addMenu(tr("&View"));

	std::map<QAction*, int> page_to_index_map = {};

	QActionGroup* pages_group = new QActionGroup(this);
	pages_group->setExclusive(true);

	action = pages_group->addAction(menu->addAction(tr("&Now Playing")));
	action->setCheckable(true);
	page_to_index_map[action] = 0;

	action = pages_group->addAction(menu->addAction(tr("&Anime List")));
	page_to_index_map[action] = 1;
	action->setCheckable(true);
	action->setChecked(true);

	action = pages_group->addAction(menu->addAction(tr("&History")));
	action->setCheckable(true);
	page_to_index_map[action] = 2;

	action = pages_group->addAction(menu->addAction(tr("&Statistics")));
	action->setCheckable(true);
	page_to_index_map[action] = 3;

	action = pages_group->addAction(menu->addAction(tr("S&earch")));
	action->setCheckable(true);
	page_to_index_map[action] = 4;

	action = pages_group->addAction(menu->addAction(tr("Se&asons")));
	action->setCheckable(true);
	page_to_index_map[action] = 5;

	action = pages_group->addAction(menu->addAction(tr("&Torrents")));
	action->setCheckable(true);
	page_to_index_map[action] = 6;

	connect(sidebar, &SideBar::CurrentItemChanged, this,
	        [pages_group](int index) { pages_group->actions()[index]->setChecked(true); });

	connect(pages_group, &QActionGroup::triggered, this,
	        [this, page_to_index_map](QAction* action) { sidebar->SetCurrentItem(page_to_index_map.at(action)); });

	menu->addSeparator();
	menu->addAction(tr("Show sidebar"));

	menu = menubar->addMenu(tr("&Help"));
	action = menu->addAction(tr("&About Minori"), this, [this] {
		AboutWindow dialog(this);
		dialog.exec();
	});
	action = menu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
	action->setMenuRole(QAction::AboutQtRole);

	/* QMainWindow will delete the old one for us,
	   according to the docs */
	setMenuBar(menubar);

	/* Toolbar */
	/* remove old toolbar(s) */
	QList<QToolBar*> toolbars = findChildren<QToolBar*>();
	for (auto& t : toolbars) {
		removeToolBar(t);
		delete t;
	}

	QToolBar* toolbar = new QToolBar(this);
	toolbar->addAction(QIcon(":/icons/24x24/arrow-circle-double-135.png"), tr("&Synchronize"),
	                   [this] { AsyncSynchronize(stack); });
	toolbar->addSeparator();

	QToolButton* button = new QToolButton(toolbar);

	menu = new QMenu(button);
	action = menu->addAction(tr("Add new folder..."));

	button->setMenu(menu);
	button->setIcon(QIcon(":/icons/24x24/folder-open.png"));
	button->setPopupMode(QToolButton::InstantPopup);
	toolbar->addWidget(button);

	button = new QToolButton(toolbar);

	menu = new QMenu(button);
	action = menu->addAction(tr("Placeholder"));

	button->setMenu(menu);
	button->setIcon(QIcon(":/icons/24x24/application-export.png"));
	button->setPopupMode(QToolButton::InstantPopup);
	toolbar->addWidget(button);

	toolbar->addSeparator();
	toolbar->addAction(QIcon(":/icons/24x24/gear.png"), tr("S&ettings"), [this] {
		SettingsDialog dialog(this);
		dialog.exec();
	});
	addToolBar(toolbar);
}

void MainWindow::SetActivePage(QWidget* page) {
	this->setCentralWidget(page);
}

void MainWindow::AsyncSynchronize(QStackedWidget* stack) {
	if (session.config.service == Anime::Services::NONE) {
		QMessageBox msg;
		msg.setWindowTitle(tr("Error synchronizing with service!"));
		msg.setText(tr("It seems you haven't yet selected a service to use."));
		msg.setInformativeText(tr("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();
		}
	}
	QThreadPool::globalInstance()->start([stack] {
		Services::Synchronize();
		reinterpret_cast<AnimeListPage*>(stack->widget(static_cast<int>(Pages::ANIME_LIST)))->Refresh();
	});
}

void MainWindow::RetranslateUI() {
	/* This kinda sucks but nobody's really going to be changing
	   the application language all the time :p */
	setUpdatesEnabled(false);
	AddMainWidgets();
	CreateBars();
	setUpdatesEnabled(true);
}

void MainWindow::changeEvent(QEvent* event) {
	if (event) { /* is this really necessary */
		switch (event->type()) {
			// this event is send if a translator is loaded
			case QEvent::LanguageChange:
				RetranslateUI();
				break;

			default:
				break;
		}
	}
	QMainWindow::changeEvent(event);
}

void MainWindow::showEvent(QShowEvent* event) {
	QMainWindow::showEvent(event);
#ifdef WIN32
	/* Technically this *should* be
	   session.config.theme.IsInDarkTheme() && win32::IsInDarkTheme()
	   but I prefer the title bar being black even when light mode
	   is enabled :/ */
	win32::SetTitleBarsToBlack(session.config.theme.IsInDarkTheme());
#endif
}

void MainWindow::closeEvent(QCloseEvent* event) {
	session.config.Save();
	event->accept();
}

#include "gui/moc_window.cpp"