From 4b9221128c4a6b08997a3a8f0b686b1a6d18434f Mon Sep 17 00:00:00 2001 From: BasioMeusPuga Date: Wed, 31 Oct 2018 10:39:21 +0530 Subject: [PATCH] Implement single/double page modes for comics/pdfs --- TODO | 5 ++- lector/__main__.py | 13 +++++- lector/contentwidgets.py | 94 ++++++++++++++++++++++++++++++++-------- lector/toolbars.py | 53 +++++++++++----------- 4 files changed, 117 insertions(+), 48 deletions(-) diff --git a/TODO b/TODO index 6145f82..73ad79a 100644 --- a/TODO +++ b/TODO @@ -61,10 +61,12 @@ TODO ✓ Make the bookmark dock float over the reading area ✓ Spacebar should not cut off lines at the top ✓ Track open bookmark windows so they can be closed quickly at exit + Double page / column view + ✓ For comics + Caching is current non fuctional Annotations ✓ Text Annotation preview in listView - Image Adjust key navigation according to viewport dimensions Search document using QTextCursor Filetypes: @@ -106,7 +108,6 @@ TODO Include icons for filetype emblems Comic view modes Continuous paging - Double pages Ignore a / the / numbers for sorting purposes ? Add only one file type if multiple are present ? Create emblem per filetype diff --git a/lector/__main__.py b/lector/__main__.py index 38fd91a..000ab73 100755 --- a/lector/__main__.py +++ b/lector/__main__.py @@ -179,6 +179,10 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): self.bookToolBar.singlePageButton.triggered.connect(self.change_page_view) self.bookToolBar.doublePageButton.triggered.connect(self.change_page_view) + if self.settings['page_view_button'] == 'singlePageButton': + self.bookToolBar.singlePageButton.setChecked(True) + else: + self.bookToolBar.doublePageButton.setChecked(True) for count, i in enumerate(self.display_profiles): self.bookToolBar.profileBox.setItemData(count, i, QtCore.Qt.UserRole) @@ -765,8 +769,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): #____________________________________________ def change_page_view(self): - self.settings['page_view_button'] = self.sender().objectName() - print(self.sender().objectName()) + self.settings['page_view_button'] = self.sender().objectName() + chapter_number = self.bookToolBar.tocBox.currentIndex() + + # Switch page to whatever index is selected in the tocBox + current_tab = self.tabWidget.currentWidget() + required_content = current_tab.metadata['content'][chapter_number][1] + current_tab.contentView.loadImage(required_content) def search_book(self, search_text): current_tab = self.tabWidget.currentIndex() diff --git a/lector/contentwidgets.py b/lector/contentwidgets.py index 6733478..c94ddc5 100644 --- a/lector/contentwidgets.py +++ b/lector/contentwidgets.py @@ -73,36 +73,58 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView): self.generate_graphicsview_context_menu) def loadImage(self, current_page): - # TODO - # For double page view: 2 before, 2 after all_pages = [i[1] for i in self.parent.metadata['content']] + current_page_index = all_pages.index(current_page) + + double_page_mode = False + if (self.main_window.settings['page_view_button'] == 'doublePageButton' + and (current_page_index != 0 and current_page_index != len(all_pages) - 1)): + double_page_mode = True def load_page(current_page): - image_pixmap = QtGui.QPixmap() + def page_loader(page): + # TODO Maybe pdf image res needs a setting? + pixmap = QtGui.QPixmap() + if self.filetype in ('cbz', 'cbr'): + page_data = self.book.read(page) + pixmap.loadFromData(page_data) + elif self.filetype == 'pdf': + page_data = self.book.page(current_page) + page_qimage = page_data.renderToImage(400, 400) + pixmap.convertFromImage(page_qimage) + return pixmap - if self.filetype in ('cbz', 'cbr'): - page_data = self.book.read(current_page) - image_pixmap.loadFromData(page_data) - elif self.filetype == 'pdf': - page_data = self.book.page(current_page) - page_qimage = page_data.renderToImage(400, 400) # TODO Maybe this needs a setting? - image_pixmap.convertFromImage(page_qimage) - return image_pixmap + firstPixmap = page_loader(current_page) + if not double_page_mode: + return firstPixmap + + next_page = all_pages[current_page_index + 1] + secondPixmap = page_loader(next_page) + + bigPixmap = QtGui.QPixmap( + firstPixmap.width() + secondPixmap.width() + 5, + firstPixmap.height()) + bigPixmap.fill(QtCore.Qt.transparent) + imagePainter = QtGui.QPainter(bigPixmap) + imagePainter.drawPixmap(0, 0, firstPixmap) + imagePainter.drawPixmap(firstPixmap.width() + 5, 0, secondPixmap) + imagePainter.end() + return bigPixmap def generate_image_cache(current_page): print('Building image cache') current_page_index = all_pages.index(current_page) # Image caching for single and double page views - if self.main_window.settings['page_view_button'] == 'singlePageButton': - page_indices = (-1, 0, 1, 2) - else: - # 2 page view - page_indices = (-2, -1, 0, 1, 2, 3) + page_indices = (-1, 0, 1, 2) + + index_modifier = 0 + if double_page_mode: + index_modifier = 1 for i in page_indices: try: - this_page = all_pages[current_page_index + i] + this_page = all_pages[current_page_index + i + index_modifier] this_pixmap = load_page(this_page) self.image_cache[i + 1] = (this_page, this_pixmap) except IndexError: @@ -131,7 +153,9 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView): # No return happened so the image isn't in the cache generate_image_cache(current_page) - if self.main_window.settings['caching_enabled']: + # TODO + # Get caching working for double page view + if not double_page_mode and self.main_window.settings['caching_enabled']: return_pixmap = None while not return_pixmap: return_pixmap = check_cache(current_page) @@ -267,6 +291,18 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView): viewSubMenu.setIcon( self.main_window.QImageFactory.get_image('mail-thread-watch')) + singlePageAction = doublePageAction = 'It\'s hammer time' + if self.main_window.settings['page_view_button'] == 'doublePageButton': + singlePageAction = viewSubMenu.addAction( + self.main_window.QImageFactory.get_image('page-single'), + self._translate('PliantQGraphicsView', 'Single page view')) + else: + doublePageAction = viewSubMenu.addAction( + self.main_window.QImageFactory.get_image('page-double'), + self._translate('PliantQGraphicsView', 'Double page view')) + + viewSubMenu.addSeparator() + zoominAction = viewSubMenu.addAction( self.main_window.QImageFactory.get_image('zoom-in'), self._translate('PliantQGraphicsView', 'Zoom in (+)')) @@ -297,6 +333,12 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView): action = contextMenu.exec_(self.sender().mapToGlobal(position)) + if action == singlePageAction: + self.main_window.bookToolBar.singlePageButton.trigger() + + if action == doublePageAction: + self.main_window.bookToolBar.doublePageButton.trigger() + if action == saveAction: dialog_prompt = self._translate('Main_UI', 'Save page as...') extension_string = self._translate('Main_UI', 'Images') @@ -647,8 +689,22 @@ class PliantWidgetsCommonFunctions: if (current_toc_index < max_toc_index and direction == 1) or ( current_toc_index > 0 and direction == -1): + + # Special cases for double page view + def get_modifier(): + if (self.main_window.settings['page_view_button'] == 'singlePageButton' + or not self.are_we_doing_images_only): + return 0 + + if (current_toc_index == 0 + or current_toc_index % 2 == 0 + or current_toc_index == max_toc_index): + return 0 + if current_toc_index % 2 == 1: + return direction + self.main_window.bookToolBar.tocBox.setCurrentIndex( - current_toc_index + direction) + current_toc_index + direction + get_modifier()) # Set page position depending on if the chapter number is increasing or decreasing if direction == 1 or was_button_pressed: diff --git a/lector/toolbars.py b/lector/toolbars.py index 79a3b8e..01c49e0 100644 --- a/lector/toolbars.py +++ b/lector/toolbars.py @@ -68,26 +68,6 @@ class BookToolBar(QtWidgets.QToolBar): self._translate('BookToolBar', 'Reset profile'), self) - # Single and double page view buttons - self.singlePageButton = QtWidgets.QAction( - image_factory.get_image('page-single'), - self._translate('BookToolBar', 'View as single page'), - self) - self.singlePageButton.setObjectName('singlePageButton') - self.singlePageButton.setCheckable(True) - - self.doublePageButton = QtWidgets.QAction( - image_factory.get_image('page-double'), - self._translate('BookToolBar', 'View as double page'), - self) - self.doublePageButton.setObjectName('doublePageButton') - self.doublePageButton.setCheckable(True) - - self.pageViewButtons = QtWidgets.QActionGroup(self) - self.pageViewButtons.setExclusive(True) - self.pageViewButtons.addAction(self.singlePageButton) - self.pageViewButtons.addAction(self.doublePageButton) - # Add buttons self.addAction(self.fontButton) self.fontButton.setCheckable(True) @@ -100,9 +80,6 @@ class BookToolBar(QtWidgets.QToolBar): self.addAction(self.bookmarkButton) self.bookmarkButton.setCheckable(True) self.addSeparator() - self.addAction(self.singlePageButton) - self.addAction(self.doublePageButton) - self.addSeparator() self.addAction(self.distractionFreeButton) self.addAction(self.fullscreenButton) @@ -230,6 +207,26 @@ class BookToolBar(QtWidgets.QToolBar): i.setVisible(False) # Comic view modification + # Single and double page view buttons + self.singlePageButton = QtWidgets.QAction( + image_factory.get_image('page-single'), + self._translate('BookToolBar', 'View as single page'), + self) + self.singlePageButton.setObjectName('singlePageButton') + self.singlePageButton.setCheckable(True) + + self.doublePageButton = QtWidgets.QAction( + image_factory.get_image('page-double'), + self._translate('BookToolBar', 'View as double page'), + self) + self.doublePageButton.setObjectName('doublePageButton') + self.doublePageButton.setCheckable(True) + + self.pageViewButtons = QtWidgets.QActionGroup(self) + self.pageViewButtons.setExclusive(True) + self.pageViewButtons.addAction(self.singlePageButton) + self.pageViewButtons.addAction(self.doublePageButton) + self.zoomIn = QtWidgets.QAction( image_factory.get_image('zoom-in'), self._translate('BookToolBar', 'Zoom in'), @@ -265,15 +262,20 @@ class BookToolBar(QtWidgets.QToolBar): self.comicBGColor.setObjectName('comicBGColor') self.comicSeparator1 = self.addSeparator() + self.addAction(self.singlePageButton) + self.addAction(self.doublePageButton) + self.comicSeparator2 = self.addSeparator() self.addAction(self.zoomIn) self.addAction(self.zoomOut) self.addAction(self.fitWidth) self.addAction(self.bestFit) self.addAction(self.originalSize) - self.comicSeparator2 = self.addSeparator() + self.comicSeparator3 = self.addSeparator() self.comicBGColorAction = self.addWidget(self.comicBGColor) self.comicActions = [ + self.singlePageButton, + self.doublePageButton, self.comicBGColorAction, self.zoomIn, self.zoomOut, @@ -281,7 +283,8 @@ class BookToolBar(QtWidgets.QToolBar): self.bestFit, self.originalSize, self.comicSeparator1, - self.comicSeparator2] + self.comicSeparator2, + self.comicSeparator3] for i in self.comicActions: i.setVisible(False)