From 240aee0ee5d126e9bcce25bff93f8cc9731c5569 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 8 Mar 2022 15:22:46 +0530 Subject: [PATCH] Use the gesture manager for touch support in the viewer panels Harmonizes with the book list and is superior to plain QScroller --- src/calibre/gui2/gestures.py | 2 +- src/calibre/gui2/viewer/bookmarks.py | 14 ++++++++++++-- src/calibre/gui2/viewer/highlights.py | 14 ++++++++++++-- src/calibre/gui2/viewer/search.py | 17 +++++++++++++---- src/calibre/gui2/viewer/toc.py | 20 ++++++++++++++++---- 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/calibre/gui2/gestures.py b/src/calibre/gui2/gestures.py index 73a25e773e..973b560122 100644 --- a/src/calibre/gui2/gestures.py +++ b/src/calibre/gui2/gestures.py @@ -192,7 +192,7 @@ class GestureManager(QObject): def close_open_menu(self): m = getattr(self.parent(), 'context_menu', None) - if m is not None and m.isVisible(): + if m is not None and hasattr(m, 'isVisible') and m.isVisible(): m.close() return True diff --git a/src/calibre/gui2/viewer/bookmarks.py b/src/calibre/gui2/viewer/bookmarks.py index b9cb03a145..9b467a436d 100644 --- a/src/calibre/gui2/viewer/bookmarks.py +++ b/src/calibre/gui2/viewer/bookmarks.py @@ -7,11 +7,12 @@ from operator import itemgetter from qt.core import ( QAbstractItemView, QAction, QComboBox, QGridLayout, QHBoxLayout, QIcon, QInputDialog, QItemSelectionModel, QLabel, QListWidget, QListWidgetItem, - QPushButton, QScroller, Qt, QWidget, pyqtSignal + QPushButton, Qt, QWidget, pyqtSignal ) from calibre.gui2 import choose_files, choose_save_file from calibre.gui2.dialogs.confirm_delete import confirm +from calibre.gui2.gestures import GestureManager from calibre.gui2.viewer.shortcuts import get_shortcut_for from calibre.gui2.viewer.web_view import vprefs from calibre.utils.date import EPOCH, utcnow @@ -32,9 +33,18 @@ class BookmarksList(QListWidget): self.addAction(ac) self.ac_delete = ac = QAction(QIcon(I('trash.png')), _('Remove this bookmark'), self) self.addAction(ac) - QScroller.grabGesture(self.viewport(), QScroller.ScrollerGestureType.TouchGesture) + self.gesture_manager = GestureManager(self) self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) + def viewportEvent(self, ev): + try: + ret = self.gesture_manager.handle_event(ev) + except AttributeError: + ret = None + if ret is not None: + return ret + return super().viewportEvent(ev) + @property def current_non_removed_item(self): ans = self.currentItem() diff --git a/src/calibre/gui2/viewer/highlights.py b/src/calibre/gui2/viewer/highlights.py index 9d648b51ba..c52049b272 100644 --- a/src/calibre/gui2/viewer/highlights.py +++ b/src/calibre/gui2/viewer/highlights.py @@ -10,7 +10,7 @@ from qt.core import ( QAbstractItemView, QColor, QDialog, QFont, QHBoxLayout, QIcon, QImage, QItemSelectionModel, QKeySequence, QLabel, QMenu, QPainter, QPainterPath, QPalette, QPixmap, QPushButton, QRect, QSizePolicy, QStyle, Qt, QTextCursor, - QTextEdit, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, pyqtSignal, QScroller + QTextEdit, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, pyqtSignal ) from calibre.constants import ( @@ -19,6 +19,7 @@ from calibre.constants import ( from calibre.ebooks.epub.cfi.parse import cfi_sort_key from calibre.gui2 import error_dialog, is_dark_theme, safe_open_url from calibre.gui2.dialogs.confirm_delete import confirm +from calibre.gui2.gestures import GestureManager from calibre.gui2.library.annotations import ( Details, Export as ExportBase, render_highlight_as_text, render_notes ) @@ -175,9 +176,18 @@ class Highlights(QTreeWidget): self.uuid_map = {} self.section_font = QFont(self.font()) self.section_font.setItalic(True) - QScroller.grabGesture(self.viewport(), QScroller.ScrollerGestureType.TouchGesture) + self.gesture_manager = GestureManager(self) self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) + def viewportEvent(self, ev): + try: + ret = self.gesture_manager.handle_event(ev) + except AttributeError: + ret = None + if ret is not None: + return ret + return super().viewportEvent(ev) + def show_context_menu(self, point): index = self.indexAt(point) h = index.data(Qt.ItemDataRole.UserRole) diff --git a/src/calibre/gui2/viewer/search.py b/src/calibre/gui2/viewer/search.py index 800fc86ea8..cfd719d61b 100644 --- a/src/calibre/gui2/viewer/search.py +++ b/src/calibre/gui2/viewer/search.py @@ -6,14 +6,14 @@ import regex from collections import Counter, OrderedDict from html import escape from qt.core import ( - QAbstractItemView, QCheckBox, QComboBox, QFont, QHBoxLayout, QIcon, QLabel, - QScroller, Qt, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, - pyqtSignal + QAbstractItemView, QCheckBox, QComboBox, QFont, QHBoxLayout, QIcon, QLabel, Qt, + QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, pyqtSignal ) from threading import Thread from calibre.ebooks.conversion.search_replace import REGEX_FLAGS from calibre.gui2 import warning_dialog +from calibre.gui2.gestures import GestureManager from calibre.gui2.progress_indicator import ProgressIndicator from calibre.gui2.viewer.config import vprefs from calibre.gui2.viewer.web_view import get_data, get_manifest @@ -472,9 +472,18 @@ class Results(QTreeWidget): # {{{ self.section_map = {} self.search_results = [] self.item_map = {} - QScroller.grabGesture(self.viewport(), QScroller.ScrollerGestureType.TouchGesture) + self.gesture_manager = GestureManager(self) self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) + def viewportEvent(self, ev): + try: + ret = self.gesture_manager.handle_event(ev) + except AttributeError: + ret = None + if ret is not None: + return ret + return super().viewportEvent(ev) + def current_item_changed(self, current, previous): if current is not None: r = current.data(0, SEARCH_RESULT_ROLE) diff --git a/src/calibre/gui2/viewer/toc.py b/src/calibre/gui2/viewer/toc.py index 0b0a975b17..6c22d5d108 100644 --- a/src/calibre/gui2/viewer/toc.py +++ b/src/calibre/gui2/viewer/toc.py @@ -6,12 +6,13 @@ import re from functools import partial from qt.core import ( QAbstractItemView, QApplication, QEvent, QFont, QHBoxLayout, QIcon, QMenu, - QModelIndex, QScroller, QStandardItem, QStandardItemModel, QStyledItemDelegate, + QModelIndex, QStandardItem, QStandardItemModel, QStyledItemDelegate, Qt, QToolButton, QToolTip, QTreeView, QWidget, pyqtSignal ) from calibre.gui2 import error_dialog from calibre.gui2.search_box import SearchBox2 +from calibre.gui2.gestures import GestureManager from calibre.utils.icu import primary_contains @@ -45,10 +46,20 @@ class TOCView(QTreeView): self.setMouseTracking(True) self.set_style_sheet() self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) - self.customContextMenuRequested.connect(self.context_menu) + self.context_menu = None + self.customContextMenuRequested.connect(self.show_context_menu) QApplication.instance().palette_changed.connect(self.set_style_sheet, type=Qt.ConnectionType.QueuedConnection) - QScroller.grabGesture(self.viewport(), QScroller.ScrollerGestureType.TouchGesture) self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) + self.gesture_manager = GestureManager(self) + + def viewportEvent(self, ev): + try: + ret = self.gesture_manager.handle_event(ev) + except AttributeError: + ret = None + if ret is not None: + return ret + return super().viewportEvent(ev) def setModel(self, model): QTreeView.setModel(self, model) @@ -113,7 +124,7 @@ class TOCView(QTreeView): for x in self.model().items_at_depth(item.depth): self.expand(self.model().indexFromItem(x)) - def context_menu(self, pos): + def show_context_menu(self, pos): index = self.indexAt(pos) m = QMenu(self) if index.isValid(): @@ -127,6 +138,7 @@ class TOCView(QTreeView): m.addAction(QIcon.ic('minus.png'), _('Collapse all items at the level of {}').format(index.data()), partial(self.collapse_at_level, index)) m.addSeparator() m.addAction(QIcon.ic('edit-copy.png'), _('Copy Table of Contents to clipboard'), self.copy_to_clipboard) + self.context_menu = m m.exec(self.mapToGlobal(pos)) def copy_to_clipboard(self):