#include "main_window_viewer.h" #include "configuration.h" #include "viewer.h" #include "goto_dialog.h" #include "custom_widgets.h" #include "options_dialog.h" #include "check_new_version.h" #include "comic.h" #include "bookmarks_dialog.h" #include "width_slider.h" #include "qnaturalsorting.h" #include "help_about_dialog.h" #include "yacreader_tool_bar_stretch.h" #include "comic_db.h" #include "yacreader_local_client.h" #include "yacreader_global.h" #include "edit_shortcuts_dialog.h" #include "shortcuts_manager.h" #include "whats_new_controller.h" #include #include #include #include #include #include #include #include #include #include #include #include MainWindowViewer::MainWindowViewer() : QMainWindow(), fullscreen(false), toolbars(true), currentDirectory("."), currentDirectoryImgDest("."), isClient(false) { loadConfiguration(); setupUI(); afterLaunchTasks(); } void MainWindowViewer::afterLaunchTasks() { WhatsNewController whatsNewController; whatsNewController.showWhatsNewIfNeeded(this); } MainWindowViewer::~MainWindowViewer() { delete settings; delete viewer; delete had; // delete sliderAction; delete openAction; delete openFolderAction; delete openLatestComicAction; delete saveImageAction; delete openComicOnTheLeftAction; delete openComicOnTheRightAction; delete goToPageOnTheLeftAction; delete goToPageOnTheRightAction; delete adjustHeightAction; delete adjustWidthAction; delete leftRotationAction; delete rightRotationAction; delete doublePageAction; delete doubleMangaPageAction; delete increasePageZoomAction; delete decreasePageZoomAction; delete resetZoomAction; delete goToPageAction; delete optionsAction; delete helpAboutAction; delete showMagnifyingGlassAction; delete setBookmarkAction; delete showBookmarksAction; delete showShorcutsAction; delete showInfoAction; delete closeAction; delete showDictionaryAction; delete adjustToFullSizeAction; delete fitToPageAction; delete showFlowAction; } void MainWindowViewer::loadConfiguration() { settings = new QSettings(YACReader::getSettingsPath() + "/YACReader.ini", QSettings::IniFormat); Configuration &config = Configuration::getConfiguration(); config.load(settings); currentDirectory = config.getDefaultPath(); fullscreen = config.getFullScreen(); } void MainWindowViewer::setupUI() { // setUnifiedTitleAndToolBarOnMac(true); viewer = new Viewer(this); connect(viewer, &Viewer::comicLoaded, this, [this] { if (viewer->magnifyingGlassIsVisible()) setMglassActionsEnabled(true); setLoadedComicActionsEnabled(true); }); connect(viewer, &Viewer::magnifyingGlassVisibilityChanged, this, &MainWindowViewer::setMglassActionsEnabled); connect(viewer, &Viewer::reset, this, &MainWindowViewer::processReset); // detected end of comic connect(viewer, &Viewer::openNextComic, this, &MainWindowViewer::openNextComic); // detected start of comic connect(viewer, &Viewer::openPreviousComic, this, &MainWindowViewer::openPreviousComic); setCentralWidget(viewer); QScreen *screen = window()->screen(); if (screen == nullptr) { screen = QApplication::screens().constFirst(); } int heightDesktopResolution = screen != nullptr ? screen->size().height() : 600; int widthDesktopResolution = screen != nullptr ? screen->size().height() : 1024; int height, width; height = static_cast(heightDesktopResolution * 0.84); width = static_cast(height * 0.70); Configuration &conf = Configuration::getConfiguration(); if (!restoreGeometry(conf.getGeometry())) { move(QPoint((widthDesktopResolution - width) / 2, ((heightDesktopResolution - height) - 40) / 2)); resize(QSize(width, height)); } had = new HelpAboutDialog(this); // TODO load data had->loadAboutInformation(":/files/about.html"); had->loadHelp(":/files/helpYACReader.html"); optionsDialog = new OptionsDialog(this); connect(optionsDialog, &QDialog::accepted, viewer, &Viewer::updateOptions); connect(optionsDialog, &YACReaderOptionsDialog::optionsChanged, this, &MainWindowViewer::reloadOptions); connect(optionsDialog, &OptionsDialog::changedFilters, viewer, &Viewer::updateFilters); connect(optionsDialog, &OptionsDialog::changedImageOptions, viewer, &Viewer::updatePage); optionsDialog->restoreOptions(settings); // shortcutsDialog = new ShortcutsDialog(this); editShortcutsDialog = new EditShortcutsDialog(this); connect(optionsDialog, &YACReaderOptionsDialog::editShortcuts, editShortcutsDialog, &QWidget::show); createActions(); setUpShortcutsManagement(); disableActions(); disablePreviousNextComicActions(); createToolBars(); setWindowTitle("YACReader"); checkNewVersion(); viewer->setFocusPolicy(Qt::StrongFocus); previousWindowFlags = windowFlags(); previousPos = pos(); previousSize = size(); if (fullscreen) toFullScreen(); if (conf.getMaximized()) showMaximized(); setAcceptDrops(true); if (Configuration::getConfiguration().getShowToolbars() && !Configuration::getConfiguration().getFullScreen()) showToolBars(); else hideToolBars(); } void MainWindowViewer::createActions() { openAction = new QAction(tr("&Open"), this); openAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/open"))); openAction->setToolTip(tr("Open a comic")); openAction->setData(OPEN_ACTION_Y); openAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_ACTION_Y)); connect(openAction, &QAction::triggered, this, QOverload<>::of(&MainWindowViewer::open)); #ifdef Q_OS_MAC newInstanceAction = new QAction(tr("New instance"), this); newInstanceAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(NEW_INSTANCE_ACTION_Y)); connect(newInstanceAction, &QAction::triggered, [=]() { QStringList possiblePaths { QDir::cleanPath(QCoreApplication::applicationDirPath() + "/../../../") }; possiblePaths += QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); for (auto &&ypath : possiblePaths) { QString yacreaderPath = QDir::cleanPath(ypath + "/YACReader.app"); if (QFileInfo(yacreaderPath).exists()) { QStringList parameters { "-n", "-a", yacreaderPath }; QProcess::startDetached("open", parameters); break; } } }); newInstanceAction->setData(NEW_INSTANCE_ACTION_Y); #endif openFolderAction = new QAction(tr("Open Folder"), this); openFolderAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openFolder"))); openFolderAction->setToolTip(tr("Open image folder")); openFolderAction->setData(OPEN_FOLDER_ACTION_Y); openFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_FOLDER_ACTION_Y)); connect(openFolderAction, &QAction::triggered, this, &MainWindowViewer::openFolder); openLatestComicAction = addActionWithShortcut(tr("Open latest comic"), OPEN_LATEST_COMIC_Y); openLatestComicAction->setToolTip(tr("Open the latest comic opened in the previous reading session")); connect(openLatestComicAction, &QAction::triggered, this, &MainWindowViewer::openLatestComic); QAction *recentFileAction = nullptr; // TODO: Replace limit with a configurable value for (int i = 0; i < Configuration::getConfiguration().getOpenRecentSize(); i++) { recentFileAction = new QAction(this); recentFileAction->setVisible(false); QObject::connect(recentFileAction, &QAction::triggered, this, &MainWindowViewer::openRecent); recentFilesActionList.append(recentFileAction); } clearRecentFilesAction = new QAction(tr("Clear"), this); clearRecentFilesAction->setToolTip(tr("Clear open recent list")); connect(clearRecentFilesAction, &QAction::triggered, this, &MainWindowViewer::clearRecentFiles); saveImageAction = new QAction(tr("Save"), this); saveImageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/save"))); saveImageAction->setToolTip(tr("Save current page")); saveImageAction->setData(SAVE_IMAGE_ACTION_Y); saveImageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SAVE_IMAGE_ACTION_Y)); connect(saveImageAction, &QAction::triggered, this, &MainWindowViewer::saveImage); openComicOnTheLeftAction = new QAction(tr("Previous Comic"), this); openComicOnTheLeftAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openPrevious"))); openComicOnTheLeftAction->setToolTip(tr("Open previous comic")); openComicOnTheLeftAction->setData(OPEN_PREVIOUS_COMIC_ACTION_Y); openComicOnTheLeftAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_PREVIOUS_COMIC_ACTION_Y)); connect(openComicOnTheLeftAction, &QAction::triggered, this, &MainWindowViewer::openLeftComic); openComicOnTheRightAction = new QAction(tr("Next Comic"), this); openComicOnTheRightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openNext"))); openComicOnTheRightAction->setToolTip(tr("Open next comic")); openComicOnTheRightAction->setData(OPEN_NEXT_COMIC_ACTION_Y); openComicOnTheRightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_NEXT_COMIC_ACTION_Y)); connect(openComicOnTheRightAction, &QAction::triggered, this, &MainWindowViewer::openRightComic); goToPageOnTheLeftAction = new QAction(tr("&Previous"), this); goToPageOnTheLeftAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/previous"))); goToPageOnTheLeftAction->setShortcutContext(Qt::WidgetShortcut); goToPageOnTheLeftAction->setToolTip(tr("Go to previous page")); goToPageOnTheLeftAction->setData(PREV_ACTION_Y); goToPageOnTheLeftAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(PREV_ACTION_Y)); connect(goToPageOnTheLeftAction, &QAction::triggered, viewer, &Viewer::left); goToPageOnTheRightAction = new QAction(tr("&Next"), this); goToPageOnTheRightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/next"))); goToPageOnTheRightAction->setShortcutContext(Qt::WidgetShortcut); goToPageOnTheRightAction->setToolTip(tr("Go to next page")); goToPageOnTheRightAction->setData(NEXT_ACTION_Y); goToPageOnTheRightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(NEXT_ACTION_Y)); connect(goToPageOnTheRightAction, &QAction::triggered, viewer, &Viewer::right); adjustHeightAction = new QAction(tr("Fit Height"), this); adjustHeightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/toHeight"))); // adjustWidth->setCheckable(true); adjustHeightAction->setToolTip(tr("Fit image to height")); // adjustWidth->setIcon(QIcon(":/images/fitWidth.svg")); adjustHeightAction->setData(ADJUST_HEIGHT_ACTION_Y); adjustHeightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_HEIGHT_ACTION_Y)); adjustHeightAction->setCheckable(true); connect(adjustHeightAction, &QAction::triggered, this, &MainWindowViewer::fitToHeight); adjustWidthAction = new QAction(tr("Fit Width"), this); adjustWidthAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/toWidth"))); // adjustWidth->setCheckable(true); adjustWidthAction->setToolTip(tr("Fit image to width")); // adjustWidth->setIcon(QIcon(":/images/fitWidth.svg")); adjustWidthAction->setData(ADJUST_WIDTH_ACTION_Y); adjustWidthAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_WIDTH_ACTION_Y)); adjustWidthAction->setCheckable(true); connect(adjustWidthAction, &QAction::triggered, this, &MainWindowViewer::fitToWidth); adjustToFullSizeAction = new QAction(tr("Show full size"), this); adjustToFullSizeAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/full"))); adjustToFullSizeAction->setCheckable(false); adjustToFullSizeAction->setData(ADJUST_TO_FULL_SIZE_ACTION_Y); adjustToFullSizeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_TO_FULL_SIZE_ACTION_Y)); adjustToFullSizeAction->setCheckable(true); connect(adjustToFullSizeAction, &QAction::triggered, this, &MainWindowViewer::adjustToFullSizeSwitch); fitToPageAction = new QAction(tr("Fit to page"), this); fitToPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/fitToPage"))); fitToPageAction->setData(FIT_TO_PAGE_ACTION_Y); fitToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FIT_TO_PAGE_ACTION_Y)); fitToPageAction->setCheckable(true); connect(fitToPageAction, &QAction::triggered, this, &MainWindowViewer::fitToPageSwitch); // fit modes have to be exclusive and checkable auto fitModes = new QActionGroup(this); fitModes->addAction(adjustHeightAction); fitModes->addAction(adjustWidthAction); fitModes->addAction(adjustToFullSizeAction); fitModes->addAction(fitToPageAction); switch (Configuration::getConfiguration().getFitMode()) { case YACReader::FitMode::ToWidth: adjustWidthAction->setChecked(true); break; case YACReader::FitMode::ToHeight: adjustHeightAction->setChecked(true); break; case YACReader::FitMode::FullRes: adjustToFullSizeAction->setChecked(true); break; case YACReader::FitMode::FullPage: fitToPageAction->setChecked(true); break; default: fitToPageAction->setChecked(true); } resetZoomAction = new QAction(tr("Reset zoom"), this); resetZoomAction->setData(RESET_ZOOM_ACTION_Y); resetZoomAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RESET_ZOOM_ACTION_Y)); connect(resetZoomAction, &QAction::triggered, this, &MainWindowViewer::resetZoomLevel); showZoomSliderlAction = new QAction(tr("Show zoom slider"), this); showZoomSliderlAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/zoom"))); increasePageZoomAction = new QAction(tr("Zoom+"), this); increasePageZoomAction->setData(ZOOM_PLUS_ACTION_Y); increasePageZoomAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_PLUS_ACTION_Y)); connect(increasePageZoomAction, &QAction::triggered, this, &MainWindowViewer::increasePageZoomLevel); decreasePageZoomAction = new QAction(tr("Zoom-"), this); decreasePageZoomAction->setData(ZOOM_MINUS_ACTION_Y); decreasePageZoomAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ZOOM_MINUS_ACTION_Y)); connect(decreasePageZoomAction, &QAction::triggered, this, &MainWindowViewer::decreasePageZoomLevel); leftRotationAction = new QAction(tr("Rotate image to the left"), this); leftRotationAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/rotateL"))); leftRotationAction->setData(LEFT_ROTATION_ACTION_Y); leftRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(LEFT_ROTATION_ACTION_Y)); connect(leftRotationAction, &QAction::triggered, viewer, &Viewer::rotateLeft); rightRotationAction = new QAction(tr("Rotate image to the right"), this); rightRotationAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/rotateR"))); rightRotationAction->setData(RIGHT_ROTATION_ACTION_Y); rightRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RIGHT_ROTATION_ACTION_Y)); connect(rightRotationAction, &QAction::triggered, viewer, &Viewer::rotateRight); doublePageAction = new QAction(tr("Double page mode"), this); doublePageAction->setToolTip(tr("Switch to double page mode")); doublePageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/doublePage"))); doublePageAction->setCheckable(true); doublePageAction->setChecked(Configuration::getConfiguration().getDoublePage()); doublePageAction->setData(DOUBLE_PAGE_ACTION_Y); doublePageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DOUBLE_PAGE_ACTION_Y)); connect(doublePageAction, &QAction::triggered, viewer, &Viewer::doublePageSwitch); // inversed pictures mode doubleMangaPageAction = new QAction(tr("Double page manga mode"), this); doubleMangaPageAction->setToolTip(tr("Reverse reading order in double page mode")); doubleMangaPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/doubleMangaPage"))); doubleMangaPageAction->setCheckable(true); doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage()); doubleMangaPageAction->setData(DOUBLE_MANGA_PAGE_ACTION_Y); doubleMangaPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DOUBLE_MANGA_PAGE_ACTION_Y)); connect(doubleMangaPageAction, &QAction::triggered, viewer, &Viewer::doubleMangaPageSwitch); connect(doubleMangaPageAction, &QAction::triggered, this, &MainWindowViewer::doubleMangaPageSwitch); goToPageAction = new QAction(tr("Go To"), this); goToPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/goto"))); goToPageAction->setToolTip(tr("Go to page ...")); goToPageAction->setData(GO_TO_PAGE_ACTION_Y); goToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_PAGE_ACTION_Y)); connect(goToPageAction, &QAction::triggered, viewer, &Viewer::showGoToDialog); optionsAction = new QAction(tr("Options"), this); optionsAction->setToolTip(tr("YACReader options")); optionsAction->setData(OPTIONS_ACTION_Y); optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_Y)); optionsAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/options"))); connect(optionsAction, &QAction::triggered, optionsDialog, &OptionsDialog::show); helpAboutAction = new QAction(tr("Help"), this); helpAboutAction->setToolTip(tr("Help, About YACReader")); helpAboutAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/help"))); helpAboutAction->setData(HELP_ABOUT_ACTION_Y); helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_Y)); connect(helpAboutAction, &QAction::triggered, had, &QWidget::show); showMagnifyingGlassAction = new QAction(tr("Magnifying glass"), this); showMagnifyingGlassAction->setToolTip(tr("Switch Magnifying glass")); showMagnifyingGlassAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/magnifyingGlass"))); showMagnifyingGlassAction->setCheckable(true); showMagnifyingGlassAction->setData(SHOW_MAGNIFYING_GLASS_ACTION_Y); showMagnifyingGlassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_MAGNIFYING_GLASS_ACTION_Y)); connect(showMagnifyingGlassAction, &QAction::triggered, viewer, &Viewer::magnifyingGlassSwitch); setBookmarkAction = new QAction(tr("Set bookmark"), this); setBookmarkAction->setToolTip(tr("Set a bookmark on the current page")); setBookmarkAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/bookmark"))); setBookmarkAction->setCheckable(true); setBookmarkAction->setData(SET_BOOKMARK_ACTION_Y); setBookmarkAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_BOOKMARK_ACTION_Y)); connect(setBookmarkAction, &QAction::triggered, viewer, &Viewer::setBookmark); connect(viewer, &Viewer::pageAvailable, setBookmarkAction, &QAction::setEnabled); connect(viewer, &Viewer::pageIsBookmark, setBookmarkAction, &QAction::setChecked); showBookmarksAction = new QAction(tr("Show bookmarks"), this); showBookmarksAction->setToolTip(tr("Show the bookmarks of the current comic")); showBookmarksAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/showBookmarks"))); showBookmarksAction->setData(SHOW_BOOKMARKS_ACTION_Y); showBookmarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_BOOKMARKS_ACTION_Y)); connect(showBookmarksAction, &QAction::triggered, viewer->getBookmarksDialog(), &QWidget::show); showShorcutsAction = new QAction(tr("Show keyboard shortcuts"), this); showShorcutsAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/shortcuts"))); showShorcutsAction->setData(SHOW_SHORCUTS_ACTION_Y); showShorcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_SHORCUTS_ACTION_Y)); connect(showShorcutsAction, &QAction::triggered, editShortcutsDialog, &QWidget::show); showInfoAction = new QAction(tr("Show Info"), this); showInfoAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/info"))); showInfoAction->setData(SHOW_INFO_ACTION_Y); showInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_INFO_ACTION_Y)); connect(showInfoAction, &QAction::triggered, viewer, &Viewer::informationSwitch); closeAction = new QAction(tr("Close"), this); closeAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/close"))); closeAction->setData(CLOSE_ACTION_Y); closeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CLOSE_ACTION_Y)); connect(closeAction, &QAction::triggered, this, &QWidget::close); showDictionaryAction = new QAction(tr("Show Dictionary"), this); showDictionaryAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/translator"))); // showDictionaryAction->setCheckable(true); showDictionaryAction->setData(SHOW_DICTIONARY_ACTION_Y); showDictionaryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_DICTIONARY_ACTION_Y)); connect(showDictionaryAction, &QAction::triggered, viewer, &Viewer::translatorSwitch); showFlowAction = new QAction(tr("Show go to flow"), this); showFlowAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/flow"))); showFlowAction->setData(SHOW_FLOW_ACTION_Y); showFlowAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_FLOW_ACTION_Y)); connect(showFlowAction, &QAction::triggered, viewer, &Viewer::goToFlowSwitch); showEditShortcutsAction = new QAction(tr("Edit shortcuts"), this); showEditShortcutsAction->setData(SHOW_EDIT_SHORTCUTS_ACTION_Y); showEditShortcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_EDIT_SHORTCUTS_ACTION_Y)); connect(showEditShortcutsAction, &QAction::triggered, editShortcutsDialog, &QWidget::show); } QAction *MainWindowViewer::addActionWithShortcut(const QString &text, const QString &shortcutKey) { auto *const action = new QAction(text, this); action->setData(shortcutKey); action->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(shortcutKey)); addAction(action); return action; } void MainWindowViewer::createToolBars() { #ifdef Q_OS_MAC comicToolBar = new YACReaderMacOSXToolbar(this); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) comicToolBar->setIconSize(QSize(18, 18)); #endif #else comicToolBar = addToolBar(tr("&File")); #endif #ifndef Q_OS_MAC comicToolBar->setStyleSheet("QToolBar{border:none;}"); comicToolBar->setIconSize(QSize(18, 18)); #endif #ifdef Q_OS_MAC comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction)); #else auto recentmenu = new QMenu(tr("Open recent")); recentmenu->addActions(recentFilesActionList); recentmenu->addSeparator(); recentmenu->addAction(clearRecentFilesAction); refreshRecentFilesActionList(); auto tb = new QToolButton(); auto open = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction); tb->addAction(open); tb->addAction(actionWithCustomIcon(QIcon(), openLatestComicAction)); tb->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction)); tb->addAction(recentmenu->menuAction()); tb->setPopupMode(QToolButton::MenuButtonPopup); tb->setDefaultAction(open); comicToolBar->addWidget(tb); #endif comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/save")), saveImageAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openPrevious")), openComicOnTheLeftAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openNext")), openComicOnTheRightAction)); comicToolBar->addSeparator(); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/previous")), goToPageOnTheLeftAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/next")), goToPageOnTheRightAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/goto")), goToPageAction)); comicToolBar->addSeparator(); auto adjustToWidthTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/toWidth")), adjustWidthAction); comicToolBar->addAction(adjustToWidthTBAction); auto adjustToHeightTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/toHeight")), adjustHeightAction); comicToolBar->addAction(adjustToHeightTBAction); auto adjustToFullSizeTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/full")), adjustToFullSizeAction); comicToolBar->addAction(adjustToFullSizeAction); auto fitToPageTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/fitToPage")), fitToPageAction); comicToolBar->addAction(fitToPageTBAction); auto fitModes = new QActionGroup(this); fitModes->addAction(adjustToWidthTBAction); fitModes->addAction(adjustToHeightTBAction); fitModes->addAction(adjustToFullSizeTBAction); fitModes->addAction(fitToPageTBAction); zoomSliderAction = new YACReaderSlider(this); zoomSliderAction->hide(); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/zoom")), showZoomSliderlAction)); connect(showZoomSliderlAction, &QAction::triggered, this, &MainWindowViewer::toggleFitToWidthSlider); connect(zoomSliderAction, &YACReaderSlider::zoomRatioChanged, viewer, &Viewer::updateZoomRatio); connect(viewer, &Viewer::zoomUpdated, zoomSliderAction, &YACReaderSlider::updateZoomRatio); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/rotateL")), leftRotationAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/rotateR")), rightRotationAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/doublePage")), doublePageAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/doubleMangaPage")), doubleMangaPageAction)); comicToolBar->addSeparator(); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/magnifyingGlass")), showMagnifyingGlassAction)); comicToolBar->addSeparator(); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/bookmark")), setBookmarkAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/showBookmarks")), showBookmarksAction)); comicToolBar->addSeparator(); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/translator")), showDictionaryAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/flow")), showFlowAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/info")), showInfoAction)); #ifdef Q_OS_MAC comicToolBar->addStretch(); #else comicToolBar->addWidget(new YACReaderToolBarStretch()); #endif comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/shortcuts")), showShorcutsAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/options")), optionsAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/help")), helpAboutAction)); #ifndef Q_OS_MAC comicToolBar->setMovable(false); #endif viewer->addAction(openAction); viewer->addAction(openFolderAction); viewer->addAction(saveImageAction); viewer->addAction(openComicOnTheLeftAction); viewer->addAction(openComicOnTheRightAction); YACReader::addSperator(viewer); viewer->addAction(goToPageOnTheLeftAction); viewer->addAction(goToPageOnTheRightAction); viewer->addAction(goToPageAction); viewer->addAction(adjustHeightAction); viewer->addAction(adjustWidthAction); viewer->addAction(adjustToFullSizeAction); viewer->addAction(fitToPageAction); viewer->addAction(leftRotationAction); viewer->addAction(rightRotationAction); viewer->addAction(doublePageAction); viewer->addAction(doubleMangaPageAction); YACReader::addSperator(viewer); viewer->addAction(showMagnifyingGlassAction); viewer->addAction(increasePageZoomAction); viewer->addAction(decreasePageZoomAction); viewer->addAction(resetZoomAction); YACReader::addSperator(viewer); viewer->addAction(setBookmarkAction); viewer->addAction(showBookmarksAction); YACReader::addSperator(viewer); viewer->addAction(showDictionaryAction); viewer->addAction(showFlowAction); viewer->addAction(showInfoAction); YACReader::addSperator(viewer); viewer->addAction(showShorcutsAction); viewer->addAction(showEditShortcutsAction); viewer->addAction(optionsAction); viewer->addAction(helpAboutAction); YACReader::addSperator(viewer); viewer->addAction(closeAction); viewer->setContextMenuPolicy(Qt::ActionsContextMenu); // MacOSX app menus #ifdef Q_OS_MAC auto menuBar = this->menuBar(); // about / preferences // TODO // file auto fileMenu = new QMenu(tr("File")); fileMenu->addAction(newInstanceAction); fileMenu->addSeparator(); fileMenu->addAction(openAction); fileMenu->addAction(openLatestComicAction); fileMenu->addAction(openFolderAction); fileMenu->addSeparator(); fileMenu->addAction(saveImageAction); fileMenu->addSeparator(); auto recentmenu = new QMenu(tr("Open recent")); recentmenu->addActions(recentFilesActionList); recentmenu->addSeparator(); recentmenu->addAction(clearRecentFilesAction); refreshRecentFilesActionList(); fileMenu->addMenu(recentmenu); fileMenu->addSeparator(); fileMenu->addAction(closeAction); auto editMenu = new QMenu(tr("Edit")); editMenu->addAction(leftRotationAction); editMenu->addAction(rightRotationAction); auto viewMenu = new QMenu(tr("View")); viewMenu->addAction(adjustHeightAction); viewMenu->addAction(adjustWidthAction); viewMenu->addAction(fitToPageAction); viewMenu->addAction(adjustToFullSizeAction); viewMenu->addSeparator(); viewMenu->addAction(increasePageZoomAction); viewMenu->addAction(decreasePageZoomAction); viewMenu->addAction(resetZoomAction); viewMenu->addAction(showZoomSliderlAction); viewMenu->addSeparator(); viewMenu->addAction(doublePageAction); viewMenu->addAction(doubleMangaPageAction); viewMenu->addSeparator(); viewMenu->addAction(showMagnifyingGlassAction); auto goMenu = new QMenu(tr("Go")); goMenu->addAction(goToPageOnTheLeftAction); goMenu->addAction(goToPageOnTheRightAction); goMenu->addAction(goToPageAction); goMenu->addSeparator(); goMenu->addAction(setBookmarkAction); goMenu->addAction(showBookmarksAction); auto windowMenu = new QMenu(tr("Window")); windowMenu->addAction(optionsAction); // this action goes to MacOS's Preference menu by Qt windowMenu->addAction(showShorcutsAction); windowMenu->addAction(showFlowAction); windowMenu->addAction(showInfoAction); windowMenu->addAction(showDictionaryAction); auto helpMenu = new QMenu(tr("Help")); helpMenu->addAction(helpAboutAction); menuBar->addMenu(fileMenu); menuBar->addMenu(editMenu); menuBar->addMenu(viewMenu); menuBar->addMenu(goMenu); menuBar->addMenu(windowMenu); menuBar->addMenu(helpMenu); // tool bar // QMenu * toolbarMenu = new QMenu(tr("Toolbar")); // toolbarMenu->addAction(); // TODO // menu->addMenu(toolbarMenu); // attach toolbar comicToolBar->attachToWindow(this); #endif } void MainWindowViewer::refreshRecentFilesActionList() { QStringList recentFilePaths = Configuration::getConfiguration().openRecentList(); // TODO: Replace limit with something configurable int iteration = (recentFilePaths.size() < Configuration::getConfiguration().getOpenRecentSize()) ? recentFilePaths.size() : Configuration::getConfiguration().getOpenRecentSize(); for (int i = 0; i < iteration; i++) { QString strippedName = QFileInfo(recentFilePaths.at(i)).fileName(); recentFilesActionList.at(i)->setText(strippedName); recentFilesActionList.at(i)->setData(recentFilePaths.at(i)); recentFilesActionList.at(i)->setVisible(true); } for (int i = iteration; i < Configuration::getConfiguration().getOpenRecentSize(); i++) { recentFilesActionList.at(i)->setVisible(false); } } void MainWindowViewer::clearRecentFiles() { Configuration::getConfiguration().clearOpenRecentList(); refreshRecentFilesActionList(); } void MainWindowViewer::openRecent() { auto action = qobject_cast(sender()); openComicFromRecentAction(action); } void MainWindowViewer::openLatestComic() { if (recentFilesActionList.isEmpty()) { return; } openComicFromRecentAction(recentFilesActionList[0]); } void MainWindowViewer::openComicFromRecentAction(QAction *action) { if (action == nullptr) { return; } QFileInfo info1(action->data().toString()); if (info1.exists()) { if (info1.isFile()) { openComicFromPath(action->data().toString()); } else if (info1.isDir()) { openFolderFromPath(action->data().toString()); } } else { viewer->resetContent(); viewer->showMessageErrorOpening(); } } void MainWindowViewer::reloadOptions() { viewer->updateConfig(settings); } void MainWindowViewer::open() { QFileDialog openDialog; #ifndef use_unarr QString pathFile = openDialog.getOpenFileName(this, tr("Open Comic"), currentDirectory, tr("Comic files") + "(*.cbr *.cbz *.rar *.zip *.tar *.pdf *.7z *.cb7 *.arj *.cbt)"); #else QString pathFile = openDialog.getOpenFileName(this, tr("Open Comic"), currentDirectory, tr("Comic files") + "(*.cbr *.cbz *.rar *.zip *.tar *.pdf *.cbt)"); #endif if (!pathFile.isEmpty()) { openComicFromPath(pathFile); } } void MainWindowViewer::open(QString path, ComicDB &comic, QList &siblings) { QFileInfo fi(path); if (!comic.info.title.isNull() && !comic.info.title.toString().isEmpty()) setWindowTitle("YACReader - " + comic.info.title.toString()); else setWindowTitle("YACReader - " + fi.fileName()); viewer->setMangaWithoutStoringSetting(comic.info.manga.toBool()); doubleMangaPageAction->setChecked(comic.info.manga.toBool()); viewer->open(path, comic); enableActions(); int index = siblings.indexOf(comic); updatePrevNextActions(index > 0, index + 1 < siblings.count()); optionsDialog->setFilters(currentComicDB.info.brightness, currentComicDB.info.contrast, currentComicDB.info.gamma); } void MainWindowViewer::open(QString path, qint64 comicId, qint64 libraryId, YACReader::OpenComicSource source) { currentDirectory = path; this->libraryId = libraryId; this->source = source; enableActions(); currentComicDB.id = comicId; YACReaderLocalClient client; int tries = 1; bool success = false; while (!(success = client.requestComicInfo(libraryId, currentComicDB, siblingComics, source)) && tries != 0) tries--; if (success) { isClient = true; open(path + currentComicDB.path, currentComicDB, siblingComics); } else { isClient = false; QMessageBox::information(this, "Connection Error", "Unable to connect to YACReaderLibrary"); // error } optionsDialog->setFilters(currentComicDB.info.brightness, currentComicDB.info.contrast, currentComicDB.info.gamma); } void MainWindowViewer::openComicFromPath(QString pathFile) { doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage()); openComic(pathFile); isClient = false; // this method is used for direct openings updatePrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); } // isClient shouldn't be modified when a siblinig comic is opened void MainWindowViewer::openSiblingComic(QString pathFile) { openComic(pathFile); } void MainWindowViewer::openComic(QString pathFile) { QFileInfo fi(pathFile); currentDirectory = fi.dir().absolutePath(); getSiblingComics(fi.absolutePath(), fi.fileName()); setWindowTitle("YACReader - " + fi.fileName()); enableActions(); viewer->open(pathFile); Configuration::getConfiguration().updateOpenRecentList(fi.absoluteFilePath()); refreshRecentFilesActionList(); } void MainWindowViewer::openFolder() { QFileDialog openDialog; QString pathDir = openDialog.getExistingDirectory(this, tr("Open folder"), currentDirectory); if (!pathDir.isEmpty()) { openFolderFromPath(pathDir); isClient = false; } } void MainWindowViewer::openFolderFromPath(QString pathDir) { currentDirectory = pathDir; // TODO ?? QFileInfo fi(pathDir); getSiblingComics(fi.absolutePath(), fi.fileName()); setWindowTitle("YACReader - " + fi.fileName()); enableActions(); viewer->open(pathDir); Configuration::getConfiguration().updateOpenRecentList(fi.absoluteFilePath()); refreshRecentFilesActionList(); } void MainWindowViewer::openFolderFromPath(QString pathDir, QString atFileName) { currentDirectory = pathDir; // TODO ?? QFileInfo fi(pathDir); getSiblingComics(fi.absolutePath(), fi.fileName()); setWindowTitle("YACReader - " + fi.fileName()); enableActions(); QDir d(pathDir); d.setFilter(QDir::Files | QDir::NoDotAndDotDot); d.setNameFilters(Comic::getSupportedImageFormats()); d.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); QStringList list = d.entryList(); std::sort(list.begin(), list.end(), naturalSortLessThanCI); int i = 0; foreach (QString path, list) { if (path.endsWith(atFileName)) break; i++; } int index = 0; if (i < list.count()) index = i; viewer->open(pathDir, index); } void MainWindowViewer::saveImage() { QFileDialog saveDialog; QString pathFile = saveDialog.getSaveFileName(this, tr("Save current page"), currentDirectoryImgDest + "/" + tr("page_%1.jpg").arg(viewer->getIndex()), tr("Image files (*.jpg)")); if (!pathFile.isEmpty()) { QFileInfo fi(pathFile); currentDirectoryImgDest = fi.absolutePath(); const QPixmap p = viewer->pixmap(); if (!p.isNull()) { p.save(pathFile); } } } void MainWindowViewer::enableActions() { setActionsEnabled(true); #ifdef Q_OS_MAC activateWindow(); raise(); #endif } void MainWindowViewer::disableActions() { setActionsEnabled(false); setMglassActionsEnabled(false); setLoadedComicActionsEnabled(false); setBookmarkAction->setEnabled(false); } void MainWindowViewer::disablePreviousNextComicActions() { for (auto *a : { openComicOnTheLeftAction, openComicOnTheRightAction }) a->setEnabled(false); } void MainWindowViewer::mouseDoubleClickEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { toggleFullScreen(); event->accept(); } } void MainWindowViewer::toggleFullScreen() { fullscreen ? toNormal() : toFullScreen(); Configuration::getConfiguration().setFullScreen(fullscreen = !fullscreen); } #ifdef Q_OS_WIN // fullscreen mode in Windows for preventing this bug: QTBUG-41309 https://bugreports.qt.io/browse/QTBUG-41309 void MainWindowViewer::toFullScreen() { fromMaximized = this->isMaximized(); hideToolBars(); viewer->hide(); viewer->fullscreen = true; // TODO, change by the right use of windowState(); previousWindowFlags = windowFlags(); previousPos = pos(); previousSize = size(); showNormal(); setWindowFlags(previousWindowFlags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); QRect r = windowHandle()->screen()->geometry(); r.setHeight(r.height() + 1); setGeometry(r); show(); viewer->show(); if (viewer->magnifyingGlassIsVisible()) viewer->showMagnifyingGlass(); } void MainWindowViewer::toNormal() { // show all viewer->hide(); viewer->fullscreen = false; // TODO, change by the right use of windowState(); // viewer->hideMagnifyingGlass(); setWindowFlags(previousWindowFlags); move(previousPos); resize(previousSize); show(); if (fromMaximized) showMaximized(); if (Configuration::getConfiguration().getShowToolbars()) showToolBars(); viewer->show(); if (viewer->magnifyingGlassIsVisible()) viewer->showMagnifyingGlass(); } #else void MainWindowViewer::toFullScreen() { fromMaximized = this->isMaximized(); hideToolBars(); viewer->hide(); viewer->fullscreen = true; // TODO, change by the right use of windowState(); setWindowState(Qt::WindowFullScreen); viewer->show(); if (viewer->magnifyingGlassIsVisible()) viewer->showMagnifyingGlass(); } void MainWindowViewer::toNormal() { // show all viewer->hide(); viewer->fullscreen = false; // TODO, change by the right use of windowState(); // viewer->hideMagnifyingGlass(); if (fromMaximized) showMaximized(); else showNormal(); if (Configuration::getConfiguration().getShowToolbars()) showToolBars(); viewer->show(); if (viewer->magnifyingGlassIsVisible()) viewer->showMagnifyingGlass(); } #endif void MainWindowViewer::toggleToolBars() { toolbars ? hideToolBars() : showToolBars(); Configuration::getConfiguration().setShowToolbars(toolbars); #ifndef Q_OS_MAC comicToolBar->setMovable(false); #endif } void MainWindowViewer::hideToolBars() { // hide all this->comicToolBar->hide(); toolbars = false; } void MainWindowViewer::showToolBars() { this->comicToolBar->show(); toolbars = true; } void MainWindowViewer::fitToWidth() { Configuration::getConfiguration().setFitMode(YACReader::FitMode::ToWidth); viewer->setZoomFactor(100); viewer->updatePage(); } void MainWindowViewer::fitToHeight() { Configuration::getConfiguration().setFitMode(YACReader::FitMode::ToHeight); viewer->setZoomFactor(100); viewer->updatePage(); } void MainWindowViewer::toggleWidthHeight() { // Only switch to "Fit to height" when we're in "Fit to width" if (Configuration::getConfiguration().getFitMode() == YACReader::FitMode::ToWidth) { adjustHeightAction->trigger(); } // Default to "Fit to width" in all other cases else { adjustWidthAction->trigger(); } } void MainWindowViewer::checkNewVersion() { Configuration &conf = Configuration::getConfiguration(); QDate lastCheck = conf.getLastVersionCheck(); QDate current = QDate::currentDate(); if (lastCheck.isNull() || lastCheck.daysTo(current) >= conf.getNumDaysBetweenVersionChecks()) { versionChecker = new HttpVersionChecker(); connect(versionChecker, &HttpVersionChecker::newVersionDetected, this, &MainWindowViewer::newVersion); QTimer::singleShot(100, versionChecker, &HttpVersionChecker::get); conf.setLastVersionCheck(current); } } void MainWindowViewer::processReset() { disableActions(); if (!isClient || siblingComics.size() <= 1) disablePreviousNextComicActions(); } void MainWindowViewer::setUpShortcutsManagement() { QList allActions; QList tmpList; editShortcutsDialog->addActionsGroup(tr("Comics"), QIcon(":/images/shortcuts_group_comics.svg"), tmpList = { openAction, openLatestComicAction, openFolderAction, saveImageAction, openComicOnTheLeftAction, openComicOnTheRightAction }); allActions << tmpList; auto *const toggleFullScreenAction = addActionWithShortcut(tr("Toggle fullscreen mode"), TOGGLE_FULL_SCREEN_ACTION_Y); connect(toggleFullScreenAction, &QAction::triggered, this, &MainWindowViewer::toggleFullScreen); auto *const toggleToolbarsAction = addActionWithShortcut(tr("Hide/show toolbar"), TOGGLE_TOOL_BARS_ACTION_Y); connect(toggleToolbarsAction, &QAction::triggered, this, &MainWindowViewer::toggleToolBars); editShortcutsDialog->addActionsGroup(tr("General"), QIcon(":/images/shortcuts_group_general.svg"), tmpList = QList() << optionsAction << helpAboutAction << showShorcutsAction << showInfoAction << closeAction << showDictionaryAction << showFlowAction << toggleFullScreenAction << toggleToolbarsAction << showEditShortcutsAction #ifdef Q_OS_MAC << newInstanceAction #endif ); allActions << tmpList; auto *const sizeUpMglassAction = addActionWithShortcut(tr("Size up magnifying glass"), SIZE_UP_MGLASS_ACTION_Y); connect(sizeUpMglassAction, &QAction::triggered, viewer, &Viewer::magnifyingGlassSizeUp); auto *const sizeDownMglassAction = addActionWithShortcut(tr("Size down magnifying glass"), SIZE_DOWN_MGLASS_ACTION_Y); connect(sizeDownMglassAction, &QAction::triggered, viewer, &Viewer::magnifyingGlassSizeDown); auto *const zoomInMglassAction = addActionWithShortcut(tr("Zoom in magnifying glass"), ZOOM_IN_MGLASS_ACTION_Y); connect(zoomInMglassAction, &QAction::triggered, viewer, &Viewer::magnifyingGlassZoomIn); auto *const zoomOutMglassAction = addActionWithShortcut(tr("Zoom out magnifying glass"), ZOOM_OUT_MGLASS_ACTION_Y); connect(zoomOutMglassAction, &QAction::triggered, viewer, &Viewer::magnifyingGlassZoomOut); mglassActions = { sizeUpMglassAction, sizeDownMglassAction, zoomInMglassAction, zoomOutMglassAction }; editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), QIcon(":/images/shortcuts_group_mglass.svg"), tmpList = QList() << showMagnifyingGlassAction << mglassActions); allActions << tmpList; auto *const toggleFitToScreenAction = addActionWithShortcut(tr("Toggle between fit to width and fit to height"), CHANGE_FIT_ACTION_Y); connect(toggleFitToScreenAction, &QAction::triggered, this, &MainWindowViewer::toggleWidthHeight); editShortcutsDialog->addActionsGroup(tr("Page adjustement"), QIcon(":/images/shortcuts_group_page.svg"), tmpList = QList() << adjustHeightAction << adjustWidthAction << toggleFitToScreenAction << leftRotationAction << rightRotationAction << doublePageAction << doubleMangaPageAction << adjustToFullSizeAction << fitToPageAction << increasePageZoomAction << decreasePageZoomAction << resetZoomAction); allActions << tmpList; auto *const autoScrollForwardAction = addActionWithShortcut(tr("Autoscroll down"), AUTO_SCROLL_FORWARD_ACTION_Y); connect(autoScrollForwardAction, &QAction::triggered, viewer, &Viewer::scrollForward); auto *const autoScrollBackwardAction = addActionWithShortcut(tr("Autoscroll up"), AUTO_SCROLL_BACKWARD_ACTION_Y); connect(autoScrollBackwardAction, &QAction::triggered, viewer, &Viewer::scrollBackward); auto *const autoScrollForwardHorizontalFirstAction = addActionWithShortcut(tr("Autoscroll forward, horizontal first"), AUTO_SCROLL_FORWARD_HORIZONTAL_FIRST_ACTION_Y); connect(autoScrollForwardHorizontalFirstAction, &QAction::triggered, viewer, &Viewer::scrollForwardHorizontalFirst); auto *const autoScrollBackwardHorizontalFirstAction = addActionWithShortcut(tr("Autoscroll backward, horizontal first"), AUTO_SCROLL_BACKWARD_HORIZONTAL_FIRST_ACTION_Y); connect(autoScrollBackwardHorizontalFirstAction, &QAction::triggered, viewer, &Viewer::scrollBackwardHorizontalFirst); auto *const autoScrollForwardVerticalFirstAction = addActionWithShortcut(tr("Autoscroll forward, vertical first"), AUTO_SCROLL_FORWARD_VERTICAL_FIRST_ACTION_Y); connect(autoScrollForwardVerticalFirstAction, &QAction::triggered, viewer, &Viewer::scrollForwardVerticalFirst); auto *const autoScrollBackwardVerticalFirstAction = addActionWithShortcut(tr("Autoscroll backward, vertical first"), AUTO_SCROLL_BACKWARD_VERTICAL_FIRST_ACTION_Y); connect(autoScrollBackwardVerticalFirstAction, &QAction::triggered, viewer, &Viewer::scrollBackwardVerticalFirst); auto *const moveDownAction = addActionWithShortcut(tr("Move down"), MOVE_DOWN_ACTION_Y); connect(moveDownAction, &QAction::triggered, viewer, [this] { viewer->moveView(Qt::Key_Down); }); auto *const moveUpAction = addActionWithShortcut(tr("Move up"), MOVE_UP_ACTION_Y); connect(moveUpAction, &QAction::triggered, viewer, [this] { viewer->moveView(Qt::Key_Up); }); auto *const moveLeftAction = addActionWithShortcut(tr("Move left"), MOVE_LEFT_ACTION_Y); connect(moveLeftAction, &QAction::triggered, viewer, [this] { viewer->moveView(Qt::Key_Left); }); auto *const moveRightAction = addActionWithShortcut(tr("Move right"), MOVE_RIGHT_ACTION_Y); connect(moveRightAction, &QAction::triggered, viewer, [this] { viewer->moveView(Qt::Key_Right); }); auto *const goToFirstPageAction = addActionWithShortcut(tr("Go to the first page"), GO_TO_FIRST_PAGE_ACTION_Y); connect(goToFirstPageAction, &QAction::triggered, viewer, &Viewer::goToFirstPage); auto *const goToLastPageAction = addActionWithShortcut(tr("Go to the last page"), GO_TO_LAST_PAGE_ACTION_Y); connect(goToLastPageAction, &QAction::triggered, viewer, &Viewer::goToLastPage); loadedComicActions = { autoScrollForwardAction, autoScrollBackwardAction, autoScrollForwardHorizontalFirstAction, autoScrollBackwardHorizontalFirstAction, autoScrollForwardVerticalFirstAction, autoScrollBackwardVerticalFirstAction, moveDownAction, moveUpAction, moveLeftAction, moveRightAction, goToFirstPageAction, goToLastPageAction }; editShortcutsDialog->addActionsGroup(tr("Reading"), QIcon(":/images/shortcuts_group_reading.svg"), tmpList = QList() << goToPageOnTheRightAction << goToPageOnTheLeftAction << setBookmarkAction << showBookmarksAction << loadedComicActions << goToPageAction); allActions << tmpList; ShortcutsManager::getShortcutsManager().registerActions(allActions); } void MainWindowViewer::doubleMangaPageSwitch() { if (isClient) { int index = siblingComics.indexOf(currentComicDB); updatePrevNextActions(index > 0, index + 1 < siblingComics.size()); } else { updatePrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); } } void MainWindowViewer::toggleFitToWidthSlider() { int y; #ifdef Q_OS_MAC y = 0; #else y = this->comicToolBar->frameSize().height(); #endif if (zoomSliderAction->isVisible()) { zoomSliderAction->hide(); } else { zoomSliderAction->move(250, y); zoomSliderAction->show(); } } void MainWindowViewer::newVersion() { QMessageBox msgBox; msgBox.setText(tr("There is a new version available")); msgBox.setInformativeText(tr("Do you want to download the new version?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Ignore | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); msgBox.button(QMessageBox::Ignore)->setText(tr("Remind me in 14 days")); msgBox.button(QMessageBox::No)->setText(tr("Not now")); msgBox.setWindowFlags(Qt::WindowStaysOnTopHint); msgBox.setModal(true); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Yes: QDesktopServices::openUrl(QUrl("http://www.yacreader.com")); break; case QMessageBox::No: Configuration::getConfiguration().setNumDaysBetweenVersionChecks(1); break; case QMessageBox::Ignore: Configuration::getConfiguration().setNumDaysBetweenVersionChecks(14); break; } } void MainWindowViewer::closeEvent(QCloseEvent *event) { if (isClient) sendComic(); viewer->save(); Configuration &conf = Configuration::getConfiguration(); if (!fullscreen && !isMaximized()) conf.setGeometry(saveGeometry()); conf.setMaximized(isMaximized()); event->accept(); } void MainWindowViewer::openPreviousComic() { if (!siblingComics.isEmpty() && isClient) { sendComic(); int currentIndex = siblingComics.indexOf(currentComicDB); if (currentIndex == -1) return; if (currentIndex - 1 >= 0 && currentIndex - 1 < siblingComics.count()) { siblingComics[currentIndex] = currentComicDB; // updated currentComicDB = siblingComics.at(currentIndex - 1); open(currentDirectory + currentComicDB.path, currentComicDB, siblingComics); } return; } if (!previousComicPath.isEmpty()) { openSiblingComic(previousComicPath); } } void MainWindowViewer::openNextComic() { if (!siblingComics.isEmpty() && isClient) { sendComic(); int currentIndex = siblingComics.indexOf(currentComicDB); if (currentIndex == -1) return; if (currentIndex + 1 > 0 && currentIndex + 1 < siblingComics.count()) { siblingComics[currentIndex] = currentComicDB; // updated currentComicDB = siblingComics.at(currentIndex + 1); open(currentDirectory + currentComicDB.path, currentComicDB, siblingComics); } return; } if (!nextComicPath.isEmpty()) { openSiblingComic(nextComicPath); } } void MainWindowViewer::openLeftComic() { if (viewer->getIsMangaMode()) { openNextComic(); } else { openPreviousComic(); } } void MainWindowViewer::openRightComic() { if (viewer->getIsMangaMode()) { openPreviousComic(); } else { openNextComic(); } } void MainWindowViewer::getSiblingComics(QString path, QString currentComic) { QDir d(path); d.setFilter(QDir::Files | QDir::NoDotAndDotDot); #ifndef use_unarr d.setNameFilters(QStringList() << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.7z" << "*.cb7" << "*.arj" << "*.cbt"); #else d.setNameFilters(QStringList() << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.cbt"); #endif d.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); QStringList list = d.entryList(); std::sort(list.begin(), list.end(), naturalSortLessThanCI); int index = list.indexOf(currentComic); if (index == -1) // comic not found { /*QFile f(QCoreApplication::applicationDirPath()+"/errorLog.txt"); if(!f.open(QIODevice::WriteOnly)) { QMessageBox::critical(NULL,tr("Saving error log file...."),tr("There was a problem saving YACReader error log file. Please, check if you have enough permissions in the YACReader root folder.")); } else { QTextStream txtS(&f); txtS << "METHOD : MainWindowViewer::getSiblingComics" << '\n'; txtS << "ERROR : current comic not found in its own path" << '\n'; txtS << path << '\n'; txtS << currentComic << '\n'; txtS << "Comic list count : " + list.count() << '\n'; foreach(QString s, list){ txtS << s << '\n'; } f.close(); }*/ } previousComicPath = nextComicPath = ""; if (index > 0) { previousComicPath = path + "/" + list.at(index - 1); } if (index + 1 < list.count()) { nextComicPath = path + "/" + list.at(index + 1); } updatePrevNextActions(index > 0, index + 1 < list.count()); } void MainWindowViewer::setActionsEnabled(bool enabled) { // TODO enable goTo and showInfo (or update) when numPages emited const auto actions = { saveImageAction, goToPageOnTheLeftAction, goToPageOnTheRightAction, adjustHeightAction, adjustWidthAction, goToPageAction, leftRotationAction, rightRotationAction, showMagnifyingGlassAction, doublePageAction, doubleMangaPageAction, adjustToFullSizeAction, fitToPageAction, showZoomSliderlAction, increasePageZoomAction, decreasePageZoomAction, resetZoomAction, showBookmarksAction, showInfoAction, showDictionaryAction, showFlowAction }; for (auto *a : actions) a->setEnabled(enabled); } void MainWindowViewer::setMglassActionsEnabled(bool enabled) { for (auto *a : std::as_const(mglassActions)) a->setEnabled(enabled); } void MainWindowViewer::setLoadedComicActionsEnabled(bool enabled) { for (auto *a : std::as_const(loadedComicActions)) a->setEnabled(enabled); } void MainWindowViewer::dropEvent(QDropEvent *event) { QList urlList; QString fName; QFileInfo info; if (event->mimeData()->hasUrls()) { urlList = event->mimeData()->urls(); if (urlList.size() > 0) { fName = urlList[0].toLocalFile(); // convert first QUrl to local path info.setFile(fName); // information about file if (info.isFile()) { QStringList imageSuffixs = Comic::getSupportedImageLiteralFormats(); if (imageSuffixs.contains(info.suffix())) // image dropped openFolderFromPath(info.absoluteDir().absolutePath(), info.fileName()); else openComicFromPath(fName); // if is file, setText } else if (info.isDir()) openFolderFromPath(fName); isClient = false; } } event->acceptProposedAction(); } void MainWindowViewer::dragEnterEvent(QDragEnterEvent *event) { // accept just text/uri-list mime format if (event->mimeData()->hasFormat("text/uri-list")) { event->acceptProposedAction(); isClient = false; } } void MainWindowViewer::adjustToFullSizeSwitch() { Configuration::getConfiguration().setFitMode(YACReader::FitMode::FullRes); viewer->setZoomFactor(100); viewer->updatePage(); } void MainWindowViewer::fitToPageSwitch() { Configuration::getConfiguration().setFitMode(YACReader::FitMode::FullPage); viewer->setZoomFactor(100); viewer->updatePage(); } void MainWindowViewer::resetZoomLevel() { viewer->setZoomFactor(100); viewer->updatePage(); } void MainWindowViewer::increasePageZoomLevel() { viewer->increaseZoomFactor(); } void MainWindowViewer::decreasePageZoomLevel() { viewer->decreaseZoomFactor(); } void MainWindowViewer::sendComic() { auto client = new YACReaderLocalClient; connect(client, &YACReaderLocalClient::finished, client, &YACReaderLocalClient::deleteLater); currentComicDB.info.lastTimeOpened = QDateTime::currentMSecsSinceEpoch() / 1000; viewer->updateComic(currentComicDB); int currentIndex = siblingComics.indexOf(currentComicDB); bool sendNextComicInfo = (currentComicDB.info.currentPage == currentComicDB.info.numPages) && (currentIndex + 1 > 0 && currentIndex + 1 < siblingComics.count()); if (sendNextComicInfo) { ComicDB &nextComic = siblingComics[currentIndex + 1]; nextComic.info.hasBeenOpened = true; int retries = 1; while (!client->sendComicInfo(libraryId, currentComicDB, nextComic.id) && retries != 0) retries--; } else { int retries = 1; while (!client->sendComicInfo(libraryId, currentComicDB) && retries != 0) retries--; } } void MainWindowViewer::updatePrevNextActions(bool thereIsPrevious, bool thereIsNext) { if (thereIsPrevious) { if (viewer->getIsMangaMode()) { openComicOnTheRightAction->setDisabled(false); } else { openComicOnTheLeftAction->setDisabled(false); } } else { if (viewer->getIsMangaMode()) { openComicOnTheRightAction->setDisabled(true); } else { openComicOnTheLeftAction->setDisabled(true); } } if (thereIsNext) { if (viewer->getIsMangaMode()) { openComicOnTheLeftAction->setDisabled(false); } else { openComicOnTheRightAction->setDisabled(false); } } else { if (viewer->getIsMangaMode()) { openComicOnTheLeftAction->setDisabled(true); } else { openComicOnTheRightAction->setDisabled(true); } } if (viewer->getIsMangaMode()) { openComicOnTheLeftAction->setToolTip(tr("Open next comic")); openComicOnTheRightAction->setToolTip(tr("Open previous comic")); goToPageOnTheLeftAction->setToolTip(tr("Go to next page")); goToPageOnTheRightAction->setToolTip(tr("Go to previous page")); } else { openComicOnTheLeftAction->setToolTip(tr("Open previous comic")); openComicOnTheRightAction->setToolTip(tr("Open next comic")); goToPageOnTheLeftAction->setToolTip(tr("Go to previous page")); goToPageOnTheRightAction->setToolTip(tr("Go to next page")); } }