A simpler solution for word wrapping in the tweaks list view

This commit is contained in:
Kovid Goyal 2021-12-13 20:02:53 +05:30
parent c171839304
commit a445a73e66
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -6,14 +6,12 @@
import textwrap import textwrap
from collections import OrderedDict from collections import OrderedDict
from functools import partial from functools import partial
from math import ceil, floor
from operator import attrgetter from operator import attrgetter
from qt.core import ( from qt.core import (
QAbstractListModel, QApplication, QDialog, QDialogButtonBox, QFont, QGridLayout, QAbstractItemView, QAbstractListModel, QApplication, QComboBox, QDialog,
QGroupBox, QIcon, QLabel, QListView, QMenu, QModelIndex, QPlainTextEdit, QComboBox, QDialogButtonBox, QFont, QGridLayout, QGroupBox, QIcon, QItemSelectionModel,
QPushButton, QSizePolicy, QSplitter, QStyle, QStyledItemDelegate, QAbstractItemView, QItemSelectionModel, QLabel, QListView, QMenu, QModelIndex, QPlainTextEdit, QPushButton, QSizePolicy,
QStyleOptionViewItem, Qt, QVBoxLayout, QWidget, pyqtSignal, QTextDocument QSplitter, Qt, QVBoxLayout, QWidget, pyqtSignal
) )
from calibre import isbytestring from calibre import isbytestring
@ -62,22 +60,6 @@ class AdaptSQP(SearchQueryParser):
pass pass
class Delegate(QStyledItemDelegate): # {{{
def __init__(self, view):
QStyledItemDelegate.__init__(self, view)
self.view = view
def paint(self, p, opt, idx):
copy = QStyleOptionViewItem(opt)
copy.showDecorationSelected = True
if self.view.currentIndex() == idx:
copy.state |= QStyle.StateFlag.State_HasFocus
QStyledItemDelegate.paint(self, p, copy, idx)
# }}}
class Tweak: # {{{ class Tweak: # {{{
def __init__(self, name, doc, var_names, defaults, custom): def __init__(self, name, doc, var_names, defaults, custom):
@ -140,11 +122,6 @@ class Tweak: # {{{
# }}} # }}}
# This is the width of the tweaks list view. Add the vertical scrollbar and
# the margins to it.
tweaks_list_minimum_width = 280
class Tweaks(QAbstractListModel, AdaptSQP): # {{{ class Tweaks(QAbstractListModel, AdaptSQP): # {{{
def __init__(self, parent=None): def __init__(self, parent=None):
@ -162,17 +139,7 @@ class Tweaks(QAbstractListModel, AdaptSQP): # {{{
except: except:
return None return None
if role == Qt.ItemDataRole.DisplayRole: if role == Qt.ItemDataRole.DisplayRole:
# Compute the display length of the string then word wrap it so it return tweak.name
# fits in minimum_width. This seems much harder than it should be.
d = QTextDocument()
d.setDocumentMargin(0)
if tweak.is_customized:
d.setHtml('<b>' + tweak.name + '</b')
else:
d.setHtml(tweak.name)
avg_char_width = ceil(d.size().width()/len(tweak.name))
num_chars_per_line = int(floor(tweaks_list_minimum_width/avg_char_width))
return textwrap.fill(tweak.name, num_chars_per_line)
if role == Qt.ItemDataRole.FontRole and tweak.is_customized: if role == Qt.ItemDataRole.FontRole and tweak.is_customized:
ans = QFont() ans = QFont()
ans.setBold(True) ans.setBold(True)
@ -390,12 +357,8 @@ class TweaksView(QListView):
self.setAlternatingRowColors(True) self.setAlternatingRowColors(True)
self.setSpacing(5) self.setSpacing(5)
self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel) self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
# Compute the size of the display area. Tweak strings are wrapped so that self.setMinimumWidth(300)
# they fit in tweaks_list_minimum_width, so we need to add the size of self.setWordWrap(True)
# the scrollbar and a heuristic for margins
min_width = (tweaks_list_minimum_width + 20 +
QApplication.instance().style().pixelMetric(QStyle.PixelMetric.PM_ScrollBarExtent))
self.setMinimumWidth(min_width)
def currentChanged(self, cur, prev): def currentChanged(self, cur, prev):
QListView.currentChanged(self, cur, prev) QListView.currentChanged(self, cur, prev)
@ -472,8 +435,6 @@ class ConfigWidget(ConfigWidgetBase):
def genesis(self, gui): def genesis(self, gui):
self.gui = gui self.gui = gui
self.delegate = Delegate(self.tweaks_view)
self.tweaks_view.setItemDelegate(self.delegate)
self.tweaks_view.current_changed.connect(self.current_changed) self.tweaks_view.current_changed.connect(self.current_changed)
self.view = self.tweaks_view self.view = self.tweaks_view
self.highlighter = PythonHighlighter(self.edit_tweak.document()) self.highlighter = PythonHighlighter(self.edit_tweak.document())