Use the gesture manager for touch support in the viewer panels

Harmonizes with the book list and is superior to plain QScroller
This commit is contained in:
Kovid Goyal 2022-03-08 15:22:46 +05:30
parent 5277bad302
commit 240aee0ee5
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 54 additions and 13 deletions

View File

@ -192,7 +192,7 @@ class GestureManager(QObject):
def close_open_menu(self): def close_open_menu(self):
m = getattr(self.parent(), 'context_menu', None) 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() m.close()
return True return True

View File

@ -7,11 +7,12 @@ from operator import itemgetter
from qt.core import ( from qt.core import (
QAbstractItemView, QAction, QComboBox, QGridLayout, QHBoxLayout, QIcon, QAbstractItemView, QAction, QComboBox, QGridLayout, QHBoxLayout, QIcon,
QInputDialog, QItemSelectionModel, QLabel, QListWidget, QListWidgetItem, 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 import choose_files, choose_save_file
from calibre.gui2.dialogs.confirm_delete import confirm 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.shortcuts import get_shortcut_for
from calibre.gui2.viewer.web_view import vprefs from calibre.gui2.viewer.web_view import vprefs
from calibre.utils.date import EPOCH, utcnow from calibre.utils.date import EPOCH, utcnow
@ -32,9 +33,18 @@ class BookmarksList(QListWidget):
self.addAction(ac) self.addAction(ac)
self.ac_delete = ac = QAction(QIcon(I('trash.png')), _('Remove this bookmark'), self) self.ac_delete = ac = QAction(QIcon(I('trash.png')), _('Remove this bookmark'), self)
self.addAction(ac) self.addAction(ac)
QScroller.grabGesture(self.viewport(), QScroller.ScrollerGestureType.TouchGesture) self.gesture_manager = GestureManager(self)
self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) 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 @property
def current_non_removed_item(self): def current_non_removed_item(self):
ans = self.currentItem() ans = self.currentItem()

View File

@ -10,7 +10,7 @@ from qt.core import (
QAbstractItemView, QColor, QDialog, QFont, QHBoxLayout, QIcon, QImage, QAbstractItemView, QColor, QDialog, QFont, QHBoxLayout, QIcon, QImage,
QItemSelectionModel, QKeySequence, QLabel, QMenu, QPainter, QPainterPath, QItemSelectionModel, QKeySequence, QLabel, QMenu, QPainter, QPainterPath,
QPalette, QPixmap, QPushButton, QRect, QSizePolicy, QStyle, Qt, QTextCursor, 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 ( from calibre.constants import (
@ -19,6 +19,7 @@ from calibre.constants import (
from calibre.ebooks.epub.cfi.parse import cfi_sort_key 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 import error_dialog, is_dark_theme, safe_open_url
from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.gestures import GestureManager
from calibre.gui2.library.annotations import ( from calibre.gui2.library.annotations import (
Details, Export as ExportBase, render_highlight_as_text, render_notes Details, Export as ExportBase, render_highlight_as_text, render_notes
) )
@ -175,9 +176,18 @@ class Highlights(QTreeWidget):
self.uuid_map = {} self.uuid_map = {}
self.section_font = QFont(self.font()) self.section_font = QFont(self.font())
self.section_font.setItalic(True) self.section_font.setItalic(True)
QScroller.grabGesture(self.viewport(), QScroller.ScrollerGestureType.TouchGesture) self.gesture_manager = GestureManager(self)
self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) 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): def show_context_menu(self, point):
index = self.indexAt(point) index = self.indexAt(point)
h = index.data(Qt.ItemDataRole.UserRole) h = index.data(Qt.ItemDataRole.UserRole)

View File

@ -6,14 +6,14 @@ import regex
from collections import Counter, OrderedDict from collections import Counter, OrderedDict
from html import escape from html import escape
from qt.core import ( from qt.core import (
QAbstractItemView, QCheckBox, QComboBox, QFont, QHBoxLayout, QIcon, QLabel, QAbstractItemView, QCheckBox, QComboBox, QFont, QHBoxLayout, QIcon, QLabel, Qt,
QScroller, Qt, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, pyqtSignal
pyqtSignal
) )
from threading import Thread from threading import Thread
from calibre.ebooks.conversion.search_replace import REGEX_FLAGS from calibre.ebooks.conversion.search_replace import REGEX_FLAGS
from calibre.gui2 import warning_dialog from calibre.gui2 import warning_dialog
from calibre.gui2.gestures import GestureManager
from calibre.gui2.progress_indicator import ProgressIndicator from calibre.gui2.progress_indicator import ProgressIndicator
from calibre.gui2.viewer.config import vprefs from calibre.gui2.viewer.config import vprefs
from calibre.gui2.viewer.web_view import get_data, get_manifest from calibre.gui2.viewer.web_view import get_data, get_manifest
@ -472,9 +472,18 @@ class Results(QTreeWidget): # {{{
self.section_map = {} self.section_map = {}
self.search_results = [] self.search_results = []
self.item_map = {} self.item_map = {}
QScroller.grabGesture(self.viewport(), QScroller.ScrollerGestureType.TouchGesture) self.gesture_manager = GestureManager(self)
self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) 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): def current_item_changed(self, current, previous):
if current is not None: if current is not None:
r = current.data(0, SEARCH_RESULT_ROLE) r = current.data(0, SEARCH_RESULT_ROLE)

View File

@ -6,12 +6,13 @@ import re
from functools import partial from functools import partial
from qt.core import ( from qt.core import (
QAbstractItemView, QApplication, QEvent, QFont, QHBoxLayout, QIcon, QMenu, QAbstractItemView, QApplication, QEvent, QFont, QHBoxLayout, QIcon, QMenu,
QModelIndex, QScroller, QStandardItem, QStandardItemModel, QStyledItemDelegate, QModelIndex, QStandardItem, QStandardItemModel, QStyledItemDelegate,
Qt, QToolButton, QToolTip, QTreeView, QWidget, pyqtSignal Qt, QToolButton, QToolTip, QTreeView, QWidget, pyqtSignal
) )
from calibre.gui2 import error_dialog from calibre.gui2 import error_dialog
from calibre.gui2.search_box import SearchBox2 from calibre.gui2.search_box import SearchBox2
from calibre.gui2.gestures import GestureManager
from calibre.utils.icu import primary_contains from calibre.utils.icu import primary_contains
@ -45,10 +46,20 @@ class TOCView(QTreeView):
self.setMouseTracking(True) self.setMouseTracking(True)
self.set_style_sheet() self.set_style_sheet()
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) 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) 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.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): def setModel(self, model):
QTreeView.setModel(self, model) QTreeView.setModel(self, model)
@ -113,7 +124,7 @@ class TOCView(QTreeView):
for x in self.model().items_at_depth(item.depth): for x in self.model().items_at_depth(item.depth):
self.expand(self.model().indexFromItem(x)) self.expand(self.model().indexFromItem(x))
def context_menu(self, pos): def show_context_menu(self, pos):
index = self.indexAt(pos) index = self.indexAt(pos)
m = QMenu(self) m = QMenu(self)
if index.isValid(): 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.addAction(QIcon.ic('minus.png'), _('Collapse all items at the level of {}').format(index.data()), partial(self.collapse_at_level, index))
m.addSeparator() m.addSeparator()
m.addAction(QIcon.ic('edit-copy.png'), _('Copy Table of Contents to clipboard'), self.copy_to_clipboard) 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)) m.exec(self.mapToGlobal(pos))
def copy_to_clipboard(self): def copy_to_clipboard(self):