#include "main_window.hpp" #include "config.hpp" #include "settings.hpp" #include #include #include #include #include #include #include #include namespace getsuyomi { using fud::FudStatus; GetsuyomiApp::GetsuyomiApp() : QMainWindow(nullptr), m_getsuyomi{new Getsuyomi(this)} { readSettings(); } FudStatus GetsuyomiApp::setup() { setCentralWidget(m_getsuyomi); QCoreApplication::setApplicationName(AppName); QCoreApplication::setApplicationVersion(AppVersionString); setWindowTitle(AppName); auto envResult = getUserConfig(); if (envResult.isError()) { qCritical("Failure %s", fud::FudStatusToString(envResult.getError())); return envResult.getError(); } m_config = envResult.getOkay(); createActions(); createMenus(); createToolBar(); constexpr int minimumWidth = 640; constexpr int minimumHeight = 480; setMinimumSize(minimumWidth, minimumHeight); /* TODO: Wire up a proper status bar */ statusBar()->addWidget(new QLabel("Status bar")); show(); return FudStatus::Success; } void GetsuyomiApp::createActions() { m_openFile = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::DocumentOpen), tr("&Open File"), this); connect(m_openFile, &QAction::triggered, this, &GetsuyomiApp::openFile); m_openDirectory = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::FolderOpen), tr("Open &Directory"), this); connect(m_openDirectory, &QAction::triggered, this, &GetsuyomiApp::openDirectory); m_quitAction = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::ApplicationExit), tr("&Quit"), this); connect(m_quitAction, &QAction::triggered, this, &GetsuyomiApp::quit); m_settingsAction = new QAction(QIcon("resources/gear.svg"), tr("&Settings"), this); connect(m_settingsAction, &QAction::triggered, this, &GetsuyomiApp::configure); m_aboutApp = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::HelpAbout), tr("&About"), this); connect(m_aboutApp, &QAction::triggered, this, &GetsuyomiApp::aboutApp); m_nextAction = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::GoNext), tr("Next"), this); connect(m_nextAction, &QAction::triggered, this, &GetsuyomiApp::next); m_backAction = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::GoPrevious), tr("Back"), this); connect(m_backAction, &QAction::triggered, this, &GetsuyomiApp::back); m_setSinglePageLayout = new QAction(QIcon("../resources/pageSingle.png"), tr("Single Page Layout"), this); connect(m_setSinglePageLayout, &QAction::triggered, this, &GetsuyomiApp::setSinglePageLayout); m_setDualPageLayout = new QAction(QIcon("../resources/pageDual.png"), tr("Dual Page Layout"), this); connect(m_setDualPageLayout, &QAction::triggered, this, &GetsuyomiApp::setDualPageLayout); m_setMangaLayout = new QAction(QIcon("../resources/pageManga.png"), tr("Manga Page Layout"), this); connect(m_setMangaLayout, &QAction::triggered, this, &GetsuyomiApp::setMangaLayout); m_setPageLayoutGroup = new QActionGroup(this); m_setPageLayoutGroup->addAction(m_setSinglePageLayout); m_setPageLayoutGroup->addAction(m_setDualPageLayout); m_setPageLayoutGroup->addAction(m_setMangaLayout); m_setPageLayoutGroup->setExclusionPolicy(QActionGroup::ExclusionPolicy::Exclusive); bindShortcuts(); } void GetsuyomiApp::bindShortcuts() { m_openFile->setShortcuts(m_config.openFileShortcuts); m_openFile->setStatusTip(tr("Open a file")); m_openDirectory->setShortcuts(m_config.openDirectoryShortcuts); m_openDirectory->setStatusTip(tr("Open a directory")); m_quitAction->setShortcuts(m_config.quitShortcuts); m_quitAction->setStatusTip(tr("Quit")); m_settingsAction->setShortcuts(m_config.settingsShortcuts); m_settingsAction->setStatusTip(tr("Configure getsuyomi")); m_nextAction->setShortcuts(m_config.nextShortcuts); m_nextAction->setStatusTip(tr("Next")); m_backAction->setShortcuts(m_config.backShortcuts); m_backAction->setStatusTip(tr("Back")); m_setSinglePageLayout->setShortcuts(m_config.singlePageShortcuts); m_setSinglePageLayout->setStatusTip(tr("Set Single Page Layout")); m_setDualPageLayout->setShortcuts(m_config.dualPageShortcuts); m_setDualPageLayout->setStatusTip(tr("Set Dual Page Layout")); m_setMangaLayout->setShortcuts(m_config.mangaPageShortcuts); m_setMangaLayout->setStatusTip(tr("Set Manga Page Layout")); } void GetsuyomiApp::createMenus() { m_fileMenu = menuBar()->addMenu(tr("&File")); m_fileMenu->addAction(m_openFile); m_fileMenu->addAction(m_openDirectory); m_fileMenu->addAction(m_quitAction); m_settingsMenu = menuBar()->addMenu(tr("&Settings")); m_settingsMenu->addAction(m_settingsAction); m_helpMenu = menuBar()->addMenu(tr("&Help")); m_helpMenu->addAction(m_aboutApp); } void GetsuyomiApp::createToolBar() { m_toolBar = addToolBar(tr("&Navigation")); m_toolBar->setObjectName("Navigation"); // goto first m_toolBar->addAction(m_backAction); m_toolBar->addAction(m_nextAction); // goto last m_toolBar->addSeparator(); m_toolBar->addAction(m_setSinglePageLayout); m_toolBar->addAction(m_setDualPageLayout); m_toolBar->addAction(m_setMangaLayout); } void GetsuyomiApp::openFile() { auto dialog = QFileDialog( this, tr("Open Archive"), m_lastOpenedDirectory, tr("Archive types (*.zip *.cbz *.cbr *.gz)")); dialog.setFileMode(QFileDialog::ExistingFile); QString filename; if (dialog.exec()) { auto filenames = dialog.selectedFiles(); if (filenames.length() == 0) { qWarning("No files selected."); return; } else if (filenames.length() > 1) { qWarning("Too many files selected %llu.", filenames.length()); return; } filename = filenames[0]; m_lastOpenedDirectory = dialog.directory().absolutePath(); qDebug("Last opened directory is %s", qPrintable(m_lastOpenedDirectory)); } else { qWarning("File dialog did not execute"); return; } if (filename.endsWith(".zip")) { auto* archive = new ZipArchive(filename); if (!archive->valid()) { qCritical("Failed to change archive"); } else { m_getsuyomi->setArchive(archive); } } else { qCritical("Unsupported file extension"); } } void GetsuyomiApp::openDirectory() { auto dialog = QFileDialog(this, tr("Open Directory"), m_lastOpenedDirectory); dialog.setFileMode(QFileDialog::Directory); QString directoryName; if (dialog.exec()) { auto filenames = dialog.selectedFiles(); if (filenames.length() == 0) { qWarning("No files selected."); return; } else if (filenames.length() > 1) { qWarning("Too many files selected %llu.", filenames.length()); return; } directoryName = filenames[0]; m_lastOpenedDirectory = dialog.directory().absolutePath(); } else { qWarning("File dialog did not execute"); return; } qDebug("Opened directory %s", qPrintable(directoryName)); } void GetsuyomiApp::quit() { QCoreApplication::quit(); } void GetsuyomiApp::configure() { Settings settings(this, m_config.shortcuts()); if (!settings.valid()) { qCritical("Invalid settings"); return; } if (settings.exec()) { const auto& shortcuts = settings.shortcuts(); setUserConfig(m_config, shortcuts.shortcutMap()); bindShortcuts(); auto saveStatus = shortcuts.save(m_config.configFilename); if (saveStatus != FudStatus::Success) { qWarning("Failed to save shortcuts."); } } } void GetsuyomiApp::aboutApp() { /* TODO: proper implementation */ QMessageBox::about(this, "About Getsuyomi", "A comic book reading app."); } void GetsuyomiApp::next() { m_getsuyomi->next(); } void GetsuyomiApp::back() { m_getsuyomi->back(); } void GetsuyomiApp::setSinglePageLayout() { m_getsuyomi->setPageLayout(PageLayout::Single); m_setSinglePageLayout->setEnabled(false); m_setDualPageLayout->setEnabled(true); m_setMangaLayout->setEnabled(true); } void GetsuyomiApp::setDualPageLayout() { m_getsuyomi->setPageLayout(PageLayout::Dual); m_setSinglePageLayout->setEnabled(true); m_setDualPageLayout->setEnabled(false); m_setMangaLayout->setEnabled(true); } void GetsuyomiApp::setMangaLayout() { m_getsuyomi->setPageLayout(PageLayout::Manga); m_setSinglePageLayout->setEnabled(true); m_setDualPageLayout->setEnabled(true); m_setMangaLayout->setEnabled(false); } void GetsuyomiApp::closeEvent(QCloseEvent* event) { writeSettings(); QMainWindow::closeEvent(event); } void GetsuyomiApp::readSettings() { QSettings settings{AppVendor, AppName}; restoreGeometry(settings.value("geometry").toByteArray()); restoreState(settings.value("windowState").toByteArray()); m_lastOpenedDirectory = settings.value("lastOpenedDirectory", QDir::homePath()).toString(); } void GetsuyomiApp::writeSettings() { QSettings settings{AppVendor, AppName}; settings.setValue("geometry", saveGeometry()); settings.setValue("windowState", saveState()); settings.setValue("lastOpenedDirectory", m_lastOpenedDirectory); settings.sync(); } } // namespace getsuyomi