This commit is contained in:
Kovid Goyal 2022-10-26 19:48:12 +05:30
commit 2fb78716f9
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
10 changed files with 112 additions and 60 deletions

View File

@ -8,9 +8,9 @@ from collections import namedtuple
from functools import partial from functools import partial
from qt.core import ( from qt.core import (
QAction, QApplication, QClipboard, QColor, QDialog, QEasingCurve, QIcon, QAction, QApplication, QClipboard, QColor, QDialog, QEasingCurve, QIcon,
QKeySequence, QLayout, QMenu, QMimeData, QPainter, QPen, QPixmap, QKeySequence, QMenu, QMimeData, QPainter, QPen, QPixmap,
QPropertyAnimation, QRect, QSize, QSizePolicy, Qt, QUrl, QWidget, pyqtProperty, QPropertyAnimation, QRect, QSize, QSizePolicy, Qt, QUrl, QWidget, pyqtProperty,
pyqtSignal QTimer, pyqtSignal
) )
from calibre import fit_image, sanitize_file_name from calibre import fit_image, sanitize_file_name
@ -30,6 +30,7 @@ from calibre.gui2.dialogs.confirm_delete import confirm, confirm as confirm_dele
from calibre.gui2.dnd import ( from calibre.gui2.dnd import (
dnd_get_files, dnd_get_image, dnd_has_extension, dnd_has_image, image_extensions dnd_get_files, dnd_get_image, dnd_has_extension, dnd_has_image, image_extensions
) )
from calibre.gui2.widgets import BasicSplitter
from calibre.gui2.widgets2 import HTMLDisplay from calibre.gui2.widgets2 import HTMLDisplay
from calibre.utils.config import tweaks from calibre.utils.config import tweaks
from calibre.utils.img import blend_image, image_from_x from calibre.utils.img import blend_image, image_from_x
@ -548,6 +549,9 @@ class CoverView(QWidget): # {{{
def setCurrentPixmapSize(self, val): def setCurrentPixmapSize(self, val):
self._current_pixmap_size = val self._current_pixmap_size = val
def minimumSizeHint(self):
return QSize(100, 100)
def do_layout(self): def do_layout(self):
if self.rect().width() == 0 or self.rect().height() == 0: if self.rect().width() == 0 or self.rect().height() == 0:
return return
@ -652,7 +656,7 @@ class CoverView(QWidget): # {{{
book_id = self.data.get('id') book_id = self.data.get('id')
if not book_id: if not book_id:
return return
from calibre.utils.img import image_from_x, remove_borders_from_image from calibre.utils.img import remove_borders_from_image
img = image_from_x(self.pixmap) img = image_from_x(self.pixmap)
nimg = remove_borders_from_image(img) nimg = remove_borders_from_image(img)
if nimg is not img: if nimg is not img:
@ -910,54 +914,56 @@ class BookInfo(HTMLDisplay):
# }}} # }}}
class DetailsLayout(QLayout): # {{{ class DetailsLayout(BasicSplitter): # {{{
def __init__(self, vertical, parent): def __init__(self, vertical, parent):
QLayout.__init__(self, parent) orientation = Qt.Orientation.Vertical if vertical else Qt.Orientation.Horizontal
BasicSplitter.__init__(self, orientation, parent)
self.vertical = vertical self.vertical = vertical
self.setCollapsible(0, True)
self._children = [] self._children = []
self.min_size = QSize(190, 200) if vertical else QSize(120, 120) self.min_size = QSize(190, 200) if vertical else QSize(120, 120)
self.setContentsMargins(0, 0, 0, 0) self.setContentsMargins(0, 0, 0, 0)
self.restore_geometry(gprefs, 'book_details_splitter')
self.splitterMoved.connect(self.do_splitter_moved)
def minimumSize(self): def minimumSize(self):
return QSize(self.min_size) return QSize(self.min_size)
def addItem(self, child): def addWidget(self, child):
if len(self._children) > 2: if len(self._children) > 2:
raise ValueError('This layout can only manage two children') raise ValueError('This layout can only manage two children')
self._children.append(child) self._children.append(child)
def itemAt(self, i):
try:
return self._children[i]
except:
pass
return None
def takeAt(self, i):
try:
self._children.pop(i)
except:
pass
return None
def count(self): def count(self):
return len(self._children) return len(self._children)
def sizeHint(self): def sizeHint(self):
return QSize(self.min_size) return QSize(self.min_size)
def restore_splitter_state(self):
s = gprefs.get('book_details_widget_splitter_state')
if s is not None:
self.restoreState(s)
self.setOrientation(Qt.Orientation.Vertical if self.vertical else Qt.Orientation.Horizontal)
def setGeometry(self, r): def setGeometry(self, r):
QLayout.setGeometry(self, r) BasicSplitter.setGeometry(self, r)
self.do_layout(r) self.do_layout(r)
self.restore_splitter_state()
def do_splitter_moved(self, *args):
gprefs['book_details_widget_splitter_state'] = bytearray(self.saveState())
self._children[0].do_layout()
def cover_height(self, r): def cover_height(self, r):
if not self._children[0].widget().isVisible(): if not self._children[0].isVisible():
return 0 return 0
mh = min(int(r.height()//2), int(4/3 * r.width())+1) mh = min(int(r.height()//2), int(4/3 * r.width())+1)
try: try:
ph = self._children[0].widget().pixmap.height() ph = self._children[0].pixmap.height()
except: except:
ph = 0 ph = 0
if ph > 0: if ph > 0:
@ -965,11 +971,11 @@ class DetailsLayout(QLayout): # {{{
return mh return mh
def cover_width(self, r): def cover_width(self, r):
if not self._children[0].widget().isVisible(): if not self._children[0].isVisible():
return 0 return 0
mw = 1 + int(3/4 * r.height()) mw = 1 + int(3/4 * r.height())
try: try:
pw = self._children[0].widget().pixmap.width() pw = self._children[0].pixmap.width()
except: except:
pw = 0 pw = 0
if pw > 0: if pw > 0:
@ -979,7 +985,11 @@ class DetailsLayout(QLayout): # {{{
def do_layout(self, rect): def do_layout(self, rect):
if len(self._children) != 2: if len(self._children) != 2:
return return
left, top, right, bottom = self.getContentsMargins() cm = self.contentsMargins()
left = cm.left()
top = cm.top()
right = cm.right()
bottom = cm.top()
r = rect.adjusted(+left, +top, -right, -bottom) r = rect.adjusted(+left, +top, -right, -bottom)
x = r.x() x = r.x()
y = r.y() y = r.y()
@ -987,20 +997,20 @@ class DetailsLayout(QLayout): # {{{
if self.vertical: if self.vertical:
ch = self.cover_height(r) ch = self.cover_height(r)
cover.setGeometry(QRect(x, y, r.width(), ch)) cover.setGeometry(QRect(x, y, r.width(), ch))
cover.widget().do_layout()
y += ch + 5 y += ch + 5
details.setGeometry(QRect(x, y, r.width(), r.height()-ch-5)) details.setGeometry(QRect(x, y, r.width(), r.height()-ch-5))
else: else:
cw = self.cover_width(r) cw = self.cover_width(r)
cover.setGeometry(QRect(x, y, cw, r.height())) cover.setGeometry(QRect(x, y, cw, r.height()))
cover.widget().do_layout()
x += cw + 5 x += cw + 5
details.setGeometry(QRect(x, y, r.width() - cw - 5, r.height())) details.setGeometry(QRect(x, y, r.width() - cw - 5, r.height()))
self.restore_splitter_state() # only required on first call to do_layout, but ...
self.save_geometry(gprefs, 'book_details_splitter')
cover.do_layout()
# }}} # }}}
class BookDetails(QWidget): # {{{ class BookDetails(DetailsLayout): # {{{
show_book_info = pyqtSignal() show_book_info = pyqtSignal()
open_containing_folder = pyqtSignal(int) open_containing_folder = pyqtSignal(int)
@ -1072,11 +1082,10 @@ class BookDetails(QWidget): # {{{
# }}} # }}}
def __init__(self, vertical, parent=None): def __init__(self, vertical, parent=None):
QWidget.__init__(self, parent) DetailsLayout.__init__(self, vertical, parent)
self.last_data = {} self.last_data = {}
self.setAcceptDrops(True) self.setAcceptDrops(True)
self._layout = DetailsLayout(vertical, self) self._layout = self
self.setLayout(self._layout)
self.current_path = '' self.current_path = ''
self.cover_view = CoverView(vertical, self) self.cover_view = CoverView(vertical, self)

View File

@ -6,7 +6,7 @@ import textwrap
from qt.core import ( from qt.core import (
QAction, QApplication, QBrush, QCheckBox, QDialog, QGridLayout, QAction, QApplication, QBrush, QCheckBox, QDialog, QGridLayout,
QHBoxLayout, QIcon, QKeySequence, QLabel, QListView, QModelIndex, QPalette, QHBoxLayout, QIcon, QKeySequence, QLabel, QListView, QModelIndex, QPalette,
QPixmap, QPushButton, QShortcut, QSize, QSplitter, Qt, QTimer, QToolButton, QPixmap, QPushButton, QShortcut, QSize, Qt, QTimer, QToolButton,
QVBoxLayout, QWidget, pyqtSignal, QDialogButtonBox QVBoxLayout, QWidget, pyqtSignal, QDialogButtonBox
) )
@ -17,7 +17,7 @@ from calibre.gui2.book_details import (
set_html set_html
) )
from calibre.gui2.ui import get_gui from calibre.gui2.ui import get_gui
from calibre.gui2.widgets import CoverView from calibre.gui2.widgets import CoverView, BasicSplitter
from calibre.gui2.widgets2 import Dialog, HTMLDisplay from calibre.gui2.widgets2 import Dialog, HTMLDisplay
@ -136,7 +136,7 @@ class BookInfo(QDialog):
QDialog.__init__(self, parent) QDialog.__init__(self, parent)
self.marked = None self.marked = None
self.gui = parent self.gui = parent
self.splitter = QSplitter(self) self.splitter = BasicSplitter(self)
self._l = l = QVBoxLayout(self) self._l = l = QVBoxLayout(self)
self.setLayout(l) self.setLayout(l)
l.addWidget(self.splitter) l.addWidget(self.splitter)

View File

@ -9,7 +9,7 @@ import os
import weakref import weakref
from qt.core import ( from qt.core import (
QApplication, QCheckBox, QCursor, QDialog, QDialogButtonBox, QGridLayout, QApplication, QCheckBox, QCursor, QDialog, QDialogButtonBox, QGridLayout,
QHBoxLayout, QIcon, QLabel, QLineEdit, QProgressBar, QPushButton, QSplitter, QHBoxLayout, QIcon, QLabel, QLineEdit, QProgressBar, QPushButton,
QStackedLayout, Qt, QTextEdit, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QStackedLayout, Qt, QTextEdit, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
QWidget, pyqtSignal QWidget, pyqtSignal
) )
@ -17,6 +17,7 @@ from threading import Thread
from calibre import as_unicode, prints from calibre import as_unicode, prints
from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.widgets import BasicSplitter
from calibre.library.check_library import CHECKS, CheckLibrary from calibre.library.check_library import CHECKS, CheckLibrary
from calibre.utils.recycle_bin import delete_file, delete_tree from calibre.utils.recycle_bin import delete_file, delete_tree
@ -125,13 +126,14 @@ class CheckLibraryDialog(QDialog):
self._tl = QHBoxLayout() self._tl = QHBoxLayout()
self.setLayout(self._tl) self.setLayout(self._tl)
self.splitter = QSplitter(self) self.splitter = BasicSplitter(self)
self.left = QWidget(self) self.left = QWidget(self)
self.splitter.addWidget(self.left) self.splitter.addWidget(self.left)
self.helpw = QTextEdit(self) self.helpw = QTextEdit(self)
self.splitter.addWidget(self.helpw) self.splitter.addWidget(self.helpw)
self._tl.addWidget(self.splitter) self._tl.addWidget(self.splitter)
self._layout = QVBoxLayout() self._layout = QVBoxLayout()
self._layout.setContentsMargins(0, 0, 0, 0)
self.left.setLayout(self._layout) self.left.setLayout(self._layout)
self.helpw.setReadOnly(True) self.helpw.setReadOnly(True)
self.helpw.setText(_('''\ self.helpw.setText(_('''\

View File

@ -23,7 +23,7 @@ from calibre.gui2.library.alternate_views import GridView
from calibre.gui2.library.views import BooksView, DeviceBooksView from calibre.gui2.library.views import BooksView, DeviceBooksView
from calibre.gui2.notify import get_notifier from calibre.gui2.notify import get_notifier
from calibre.gui2.tag_browser.ui import TagBrowserWidget from calibre.gui2.tag_browser.ui import TagBrowserWidget
from calibre.gui2.widgets import LayoutButton, Splitter from calibre.gui2.widgets import LayoutButton, Splitter, BasicSplitter
from calibre.utils.config import prefs from calibre.utils.config import prefs
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.utils.localization import localize_website_link from calibre.utils.localization import localize_website_link
@ -112,10 +112,10 @@ class LibraryViewMixin: # {{{
# }}} # }}}
class QuickviewSplitter(QSplitter): # {{{ class QuickviewSplitter(BasicSplitter): # {{{
def __init__(self, parent=None, orientation=Qt.Orientation.Vertical, qv_widget=None): def __init__(self, parent=None, orientation=Qt.Orientation.Vertical, qv_widget=None):
QSplitter.__init__(self, parent=parent, orientation=orientation) BasicSplitter.__init__(self, parent=parent, orientation=orientation)
self.splitterMoved.connect(self.splitter_moved) self.splitterMoved.connect(self.splitter_moved)
self.setChildrenCollapsible(False) self.setChildrenCollapsible(False)
self.qv_widget = qv_widget self.qv_widget = qv_widget
@ -124,7 +124,7 @@ class QuickviewSplitter(QSplitter): # {{{
gprefs['quickview_dialog_heights'] = self.sizes() gprefs['quickview_dialog_heights'] = self.sizes()
def resizeEvent(self, *args): def resizeEvent(self, *args):
QSplitter.resizeEvent(self, *args) BasicSplitter.resizeEvent(self, *args)
if self.sizes()[1] != 0: if self.sizes()[1] != 0:
gprefs['quickview_dialog_heights'] = self.sizes() gprefs['quickview_dialog_heights'] = self.sizes()

View File

@ -12,7 +12,7 @@ from functools import partial
from qt.core import ( from qt.core import (
QDialog, QDialogButtonBox, QFrame, QGridLayout, QGroupBox, QHBoxLayout, QIcon, QDialog, QDialogButtonBox, QFrame, QGridLayout, QGroupBox, QHBoxLayout, QIcon,
QInputDialog, QKeySequence, QMenu, QPushButton, QScrollArea, QShortcut, QSize, QInputDialog, QKeySequence, QMenu, QPushButton, QScrollArea, QShortcut, QSize,
QSizePolicy, QSpacerItem, QSplitter, Qt, QTabWidget, QToolButton, QVBoxLayout, QSizePolicy, QSpacerItem, Qt, QTabWidget, QToolButton, QVBoxLayout,
QWidget, pyqtSignal QWidget, pyqtSignal
) )
@ -29,6 +29,7 @@ from calibre.gui2.metadata.basic_widgets import (
TitleSortEdit, show_locked_file_error TitleSortEdit, show_locked_file_error
) )
from calibre.gui2.metadata.single_download import FullFetch from calibre.gui2.metadata.single_download import FullFetch
from calibre.gui2.widgets import BasicSplitter
from calibre.gui2.widgets2 import CenteredToolButton from calibre.gui2.widgets2 import CenteredToolButton
from calibre.library.comments import merge_comments as merge_two_comments from calibre.library.comments import merge_comments as merge_two_comments
from calibre.utils.date import local_tz from calibre.utils.date import local_tz
@ -731,13 +732,13 @@ class MetadataSingleDialogBase(QDialog):
# }}} # }}}
class Splitter(QSplitter): class Splitter(BasicSplitter):
frame_resized = pyqtSignal(object) frame_resized = pyqtSignal(object)
def resizeEvent(self, ev): def resizeEvent(self, ev):
self.frame_resized.emit(ev) self.frame_resized.emit(ev)
return QSplitter.resizeEvent(self, ev) return BasicSplitter.resizeEvent(self, ev)
class MetadataSingleDialog(MetadataSingleDialogBase): # {{{ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
@ -1039,7 +1040,7 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
QSizePolicy.Policy.Expanding)) QSizePolicy.Policy.Expanding))
wgl.addWidget(self.formats_manager) wgl.addWidget(self.formats_manager)
self.splitter = QSplitter(Qt.Orientation.Horizontal, tab1) self.splitter = BasicSplitter(Qt.Orientation.Horizontal, tab1)
tab1.l.addWidget(self.splitter) tab1.l.addWidget(self.splitter)
self.splitter.addWidget(self.cover) self.splitter.addWidget(self.cover)
self.splitter.addWidget(wsp) self.splitter.addWidget(wsp)
@ -1207,7 +1208,7 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
cover_layout.addLayout(hl) cover_layout.addLayout(hl)
sto(self.cover.buttons[-2], self.cover.buttons[-1]) sto(self.cover.buttons[-2], self.cover.buttons[-1])
# Splitter for both cover & formats boxes # Splitter for both cover & formats boxes
self.cover_and_formats = cover_and_formats = QSplitter(Qt.Orientation.Vertical) self.cover_and_formats = cover_and_formats = BasicSplitter(Qt.Orientation.Vertical)
# Put a very small margin on the left so that the word "Cover" doesn't # Put a very small margin on the left so that the word "Cover" doesn't
# touch the splitter # touch the splitter
cover_and_formats.setContentsMargins(1, 0, 0, 0) cover_and_formats.setContentsMargins(1, 0, 0, 0)

View File

@ -19,7 +19,7 @@ from qt.core import (
QWidget, QTableView, QGridLayout, QPalette, QTimer, pyqtSignal, QWidget, QTableView, QGridLayout, QPalette, QTimer, pyqtSignal,
QAbstractTableModel, QSize, QListView, QPixmap, QModelIndex, QAbstractTableModel, QSize, QListView, QPixmap, QModelIndex,
QAbstractListModel, QRect, QTextBrowser, QStringListModel, QMenu, QItemSelectionModel, QAbstractListModel, QRect, QTextBrowser, QStringListModel, QMenu, QItemSelectionModel,
QCursor, QHBoxLayout, QPushButton, QSizePolicy, QSplitter, QAbstractItemView) QCursor, QHBoxLayout, QPushButton, QSizePolicy, QAbstractItemView)
from calibre.customize.ui import metadata_plugins from calibre.customize.ui import metadata_plugins
from calibre.ebooks.metadata import authors_to_string, rating_to_stars from calibre.ebooks.metadata import authors_to_string, rating_to_stars
@ -29,6 +29,7 @@ from calibre.ebooks.metadata.book.base import Metadata
from calibre.ebooks.metadata.opf2 import OPF from calibre.ebooks.metadata.opf2 import OPF
from calibre.gui2 import error_dialog, rating_font, gprefs from calibre.gui2 import error_dialog, rating_font, gprefs
from calibre.gui2.progress_indicator import SpinAnimator from calibre.gui2.progress_indicator import SpinAnimator
from calibre.gui2.widgets import BasicSplitter
from calibre.gui2.widgets2 import HTMLDisplay from calibre.gui2.widgets2 import HTMLDisplay
from calibre.utils.date import (utcnow, fromordinal, format_date, from calibre.utils.date import (utcnow, fromordinal, format_date,
UNDEFINED_DATE, as_utc) UNDEFINED_DATE, as_utc)
@ -445,7 +446,7 @@ class IdentifyWidget(QWidget): # {{{
self.top.setWordWrap(True) self.top.setWordWrap(True)
l.addWidget(self.top) l.addWidget(self.top)
self.splitter = s = QSplitter(self) self.splitter = s = BasicSplitter(self)
s.setChildrenCollapsible(False) s.setChildrenCollapsible(False)
l.addWidget(s, 100) l.addWidget(s, 100)
self.results_view = ResultsView(self) self.results_view = ResultsView(self)

View File

@ -2,10 +2,11 @@
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
from qt.core import QSplitter, QTableView from qt.core import QTableView
from calibre.gui2.library import DEFAULT_SORT from calibre.gui2.library import DEFAULT_SORT
from calibre.gui2 import gprefs from calibre.gui2 import gprefs
from calibre.gui2.widgets import BasicSplitter
class PinTableView(QTableView): class PinTableView(QTableView):
@ -124,10 +125,10 @@ class PinTableView(QTableView):
self.apply_state(state) self.apply_state(state)
class PinContainer(QSplitter): class PinContainer(BasicSplitter):
def __init__(self, books_view, parent=None): def __init__(self, books_view, parent=None):
QSplitter.__init__(self, parent) BasicSplitter.__init__(self, parent)
self.setChildrenCollapsible(False) self.setChildrenCollapsible(False)
self.books_view = books_view self.books_view = books_view
self.addWidget(books_view) self.addWidget(books_view)

View File

@ -11,7 +11,7 @@ from calibre import isbytestring, prepare_string_for_xml
from calibre.gui2 import error_dialog, info_dialog from calibre.gui2 import error_dialog, info_dialog
from calibre.gui2.preferences import AbortCommit, ConfigWidgetBase, test_widget from calibre.gui2.preferences import AbortCommit, ConfigWidgetBase, test_widget
from calibre.gui2.search_box import SearchBox2 from calibre.gui2.search_box import SearchBox2
from calibre.gui2.widgets import PythonHighlighter from calibre.gui2.widgets import PythonHighlighter, BasicSplitter
from calibre.utils.config_base import (default_tweaks_raw, exec_tweaks, from calibre.utils.config_base import (default_tweaks_raw, exec_tweaks,
normalize_tweak, read_custom_tweaks, normalize_tweak, read_custom_tweaks,
write_custom_tweaks) write_custom_tweaks)
@ -22,7 +22,7 @@ from qt.core import (QAbstractItemView, QAbstractListModel, QApplication,
QComboBox, QDialog, QDialogButtonBox, QFont, QGridLayout, QComboBox, QDialog, QDialogButtonBox, QFont, QGridLayout,
QGroupBox, QIcon, QItemSelectionModel, QLabel, QListView, QGroupBox, QIcon, QItemSelectionModel, QLabel, QListView,
QMenu, QModelIndex, QPlainTextEdit, QPushButton, QMenu, QModelIndex, QPlainTextEdit, QPushButton,
QSizePolicy, QSplitter, Qt, QVBoxLayout, QWidget, QSizePolicy, Qt, QVBoxLayout, QWidget,
pyqtSignal) pyqtSignal)
ROOT = QModelIndex() ROOT = QModelIndex()
@ -371,7 +371,7 @@ class ConfigWidget(ConfigWidgetBase):
_("Values for the tweaks are shown below. Edit them to change the behavior of calibre." _("Values for the tweaks are shown below. Edit them to change the behavior of calibre."
" Your changes will only take effect <b>after a restart</b> of calibre.")) " Your changes will only take effect <b>after a restart</b> of calibre."))
l.addWidget(la), la.setWordWrap(True) l.addWidget(la), la.setWordWrap(True)
self.splitter = s = QSplitter(self) self.splitter = s = BasicSplitter(self)
s.setChildrenCollapsible(False) s.setChildrenCollapsible(False)
l.addWidget(s, 10) l.addWidget(s, 10)

View File

@ -434,6 +434,9 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
# layout button. We need to let a book be selected in the book list # layout button. We need to let a book be selected in the book list
# before initializing quickview, so run it after an event loop tick # before initializing quickview, so run it after an event loop tick
QTimer.singleShot(0, self.start_quickview) QTimer.singleShot(0, self.start_quickview)
# Force repaint of the book details splitter because it otherwise ends
# up with the wrong size. I don't know why.
QTimer.singleShot(0, self.bd_splitter.repaint)
def start_quickview(self): def start_quickview(self):
from calibre.gui2.actions.show_quickview import get_quickview_action_plugin from calibre.gui2.actions.show_quickview import get_quickview_action_plugin

View File

@ -980,13 +980,48 @@ class PythonHighlighter(QSyntaxHighlighter): # {{{
# Splitter {{{ # Splitter {{{
class BasicSplitterHandle(QSplitterHandle):
class SplitterHandle(QSplitterHandle): def __init__(self, orientation, splitter):
QSplitterHandle.__init__(self, orientation, splitter)
self.handle_width = splitter.handleWidth()
def paintEvent(self, event):
rect = event.rect()
painter = QPainter(self)
# draw the separator bar.
painter.setPen(Qt.NoPen)
palette = QApplication.palette()
painter.setBrush(palette.color(QPalette.ColorGroup.Normal, QPalette.ColorRole.AlternateBase))
painter.drawRect(rect)
# draw the dots
painter.setBrush(palette.color(QPalette.ColorGroup.Normal, QPalette.ColorRole.Shadow))
horizontal = self.orientation() == Qt.Orientation.Horizontal
dot_count = 6
dot_size = int(max(1, self.handle_width/2))
start_point = max(0, int((rect.height()/2 if horizontal else rect.width()/2) - (dot_count*dot_size/2)))
for i in range(dot_count):
# Move the rect to leave 2 dot spaces between the dots
if horizontal:
dot_rect = QRect(1, start_point + i*dot_size*3, dot_size, dot_size)
else:
dot_rect = QRect(start_point + i*dot_size*3, 1, dot_size, dot_size)
painter.drawRect(dot_rect)
painter.end()
class BasicSplitter(QSplitter):
def createHandle(self):
return BasicSplitterHandle(self.orientation(), self)
class SplitterHandle(BasicSplitterHandle):
double_clicked = pyqtSignal(object) double_clicked = pyqtSignal(object)
def __init__(self, orientation, splitter): def __init__(self, orientation, splitter):
QSplitterHandle.__init__(self, orientation, splitter) BasicSplitterHandle.__init__(self, orientation, splitter)
splitter.splitterMoved.connect(self.splitter_moved, splitter.splitterMoved.connect(self.splitter_moved,
type=Qt.ConnectionType.QueuedConnection) type=Qt.ConnectionType.QueuedConnection)
self.double_clicked.connect(splitter.double_clicked, self.double_clicked.connect(splitter.double_clicked,
@ -1066,7 +1101,7 @@ class LayoutButton(QToolButton):
return QToolButton.mouseReleaseEvent(self, ev) return QToolButton.mouseReleaseEvent(self, ev)
class Splitter(QSplitter): class Splitter(BasicSplitter):
state_changed = pyqtSignal(object) state_changed = pyqtSignal(object)
reapply_sizes = pyqtSignal(object) reapply_sizes = pyqtSignal(object)
@ -1075,7 +1110,7 @@ class Splitter(QSplitter):
initial_side_size=120, connect_button=True, initial_side_size=120, connect_button=True,
orientation=Qt.Orientation.Horizontal, side_index=0, parent=None, orientation=Qt.Orientation.Horizontal, side_index=0, parent=None,
shortcut=None, hide_handle_on_single_panel=True): shortcut=None, hide_handle_on_single_panel=True):
QSplitter.__init__(self, parent) BasicSplitter.__init__(self, parent)
self.reapply_sizes.connect(self.setSizes, type=Qt.ConnectionType.QueuedConnection) self.reapply_sizes.connect(self.setSizes, type=Qt.ConnectionType.QueuedConnection)
self.hide_handle_on_single_panel = hide_handle_on_single_panel self.hide_handle_on_single_panel = hide_handle_on_single_panel
if hide_handle_on_single_panel: if hide_handle_on_single_panel:
@ -1189,7 +1224,7 @@ class Splitter(QSplitter):
def do_resize(self, *args): def do_resize(self, *args):
orig = self.desired_side_size orig = self.desired_side_size
QSplitter.resizeEvent(self, self._resize_ev) BasicSplitter.resizeEvent(self, self._resize_ev)
if orig > 20 and self.desired_show: if orig > 20 and self.desired_show:
c = 0 c = 0
while abs(self.side_index_size - orig) > 10 and c < 5: while abs(self.side_index_size - orig) > 10 and c < 5: