From 5a33a788c72072db2cb05b8ae3e11f2b21e5778b Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Sun, 7 Jan 2024 00:05:03 -0800 Subject: [PATCH] qtutils: add text_width() and text_size() helper functions Use a utility function to calculate sizes using QFontMetrics. Signed-off-by: David Aguilar --- cola/qtutils.py | 30 ++++++++++++++++++++++++++++-- cola/widgets/browse.py | 2 +- cola/widgets/commitmsg.py | 4 ++-- cola/widgets/diff.py | 8 ++++---- cola/widgets/editremotes.py | 13 ++++++------- cola/widgets/main.py | 4 ++-- cola/widgets/standard.py | 6 ++---- cola/widgets/text.py | 7 +++---- 8 files changed, 48 insertions(+), 26 deletions(-) diff --git a/cola/qtutils.py b/cola/qtutils.py index 1046a5a9..a1d669d0 100644 --- a/cola/qtutils.py +++ b/cola/qtutils.py @@ -331,8 +331,7 @@ def prompt_n(msg, inputs): if len(k + v) > len(long_value): long_value = k + v - metrics = QtGui.QFontMetrics(dialog.font()) - min_width = min(720, metrics.width(long_value) + 100) + min_width = min(720, text_width(dialog.font(), long_value) + 100) dialog.setMinimumWidth(min_width) ok_b = ok_button(msg, enabled=False) @@ -1299,3 +1298,30 @@ def add_menu_actions(menu, menu_actions): if action is None: action = menu_separator(menu) menu.insertAction(first_action, action) + + +def fontmetrics_width(metrics, text): + """Get the width in pixels of specified text + + Calls QFontMetrics.horizontalAdvance() when available. + QFontMetricswidth() is deprecated. Qt 5.11 added horizontalAdvance(). + """ + if hasattr(metrics, 'horizontalAdvance'): + return metrics.horizontalAdvance(text) + return metrics.width(text) + + +def text_width(font, text): + """Get the width in pixels for the QFont and text""" + metrics = QtGui.QFontMetrics(font) + return fontmetrics_width(metrics, text) + + +def text_size(font, text): + """Return the width in pixels for the specified text + + :param font_or_widget: The QFont or widget providing the font to use. + :param text: The text to measure. + """ + metrics = QtGui.QFontMetrics(font) + return (fontmetrics_width(metrics, text), metrics.height()) diff --git a/cola/widgets/browse.py b/cola/widgets/browse.py index 51152d5f..4c54d659 100644 --- a/cola/widgets/browse.py +++ b/cola/widgets/browse.py @@ -221,7 +221,7 @@ class RepoTreeView(standard.TreeView): context, self, func=self.selected_paths ) - self.x_width = QtGui.QFontMetrics(self.font()).width('x') + self.x_width = qtutils.text_width(self.font(), 'x') self.size_columns(force=True) def index_expanded(self, index): diff --git a/cola/widgets/commitmsg.py b/cola/widgets/commitmsg.py index 7d8140af..373e7872 100644 --- a/cola/widgets/commitmsg.py +++ b/cola/widgets/commitmsg.py @@ -688,5 +688,5 @@ class CommitMessageTextEdit(SpellCheckTextEdit): def setFont(self, font): SpellCheckTextEdit.setFont(self, font) - metrics = self.fontMetrics() - self.setMinimumSize(QtCore.QSize(metrics.width('MMMM'), metrics.height() * 2)) + width, height = qtutils.text_size(font, 'MMMM') + self.setMinimumSize(QtCore.QSize(width, height * 2)) diff --git a/cola/widgets/diff.py b/cola/widgets/diff.py index 35550056..c5b7e5ed 100644 --- a/cola/widgets/diff.py +++ b/cola/widgets/diff.py @@ -222,8 +222,7 @@ class DiffTextEdit(VimHintedPlainTextEdit): """Override setFont() so that we can use a custom "block" cursor""" super().setFont(font) if prefs.block_cursor(self.context): - metrics = QtGui.QFontMetrics(font) - width = metrics.width('M') + width = qtutils.text_width(font, 'M') self.setCursorWidth(width) def _cursor_changed(self): @@ -351,8 +350,9 @@ class DiffLineNumbers(TextDecorator): self.parser = diffparse.DiffLines() self.formatter = diffparse.FormatDigits() - self.setFont(qtutils.diff_font(context)) - self._char_width = self.fontMetrics().width('0') + font = qtutils.diff_font(context) + self.setFont(font) + self._char_width = qtutils.text_width(font, 'M') QPalette = QtGui.QPalette self._palette = palette = self.palette() diff --git a/cola/widgets/editremotes.py b/cola/widgets/editremotes.py index baf516dc..09fcaeca 100644 --- a/cola/widgets/editremotes.py +++ b/cola/widgets/editremotes.py @@ -1,7 +1,6 @@ import operator from qtpy import QtCore -from qtpy import QtGui from qtpy import QtWidgets from qtpy.QtCore import Qt from qtpy.QtCore import Signal @@ -68,10 +67,9 @@ class RemoteEditor(standard.Dialog): self.info = text.VimHintedPlainTextEdit(context, hint, parent=self) self.info.setToolTip(tooltip) - font = self.info.font() - metrics = QtGui.QFontMetrics(font) - width = metrics.width('_' * 42) - height = metrics.height() * 13 + text_width, text_height = qtutils.text_size(self.info.font(), 'M') + width = text_width * 42 + height = text_height * 13 self.info.setMinimumWidth(width) self.info.setMinimumHeight(height) self.info_thread = RemoteInfoThread(context, self) @@ -407,9 +405,10 @@ class AddRemoteDialog(QtWidgets.QDialog): def lineedit(context, hint): + """Create a HintedLineEdit with a preset minimum width""" widget = text.HintedLineEdit(context, hint) - metrics = widget.fontMetrics() - widget.setMinimumWidth(metrics.width('M' * 32)) + width = qtutils.text_width(widget.font(), 'M') + widget.setMinimumWidth(width * 32) return widget diff --git a/cola/widgets/main.py b/cola/widgets/main.py index 7bf73d1a..d2b4bef3 100644 --- a/cola/widgets/main.py +++ b/cola/widgets/main.py @@ -152,8 +152,8 @@ class MainView(standard.MainWindow): self.position_label.setFont(font) # make the position label fixed size to avoid layout issues - metrics = self.position_label.fontMetrics() - width = metrics.width('99:999') + defs.spacing + text_width = qtutils.text_width(font, '99:999') + width = text_width + defs.spacing self.position_label.setMinimumWidth(width) editor = commitmsg.CommitMessageEditor(context, self) diff --git a/cola/widgets/standard.py b/cola/widgets/standard.py index a763f125..b8d6abdf 100644 --- a/cola/widgets/standard.py +++ b/cola/widgets/standard.py @@ -806,10 +806,8 @@ class SpinBox(QtWidgets.QSpinBox): self.setSingleStep(step) if value is not None: self.setValue(value) - - font = self.font() - metrics = QtGui.QFontMetrics(font) - width = max(self.minimumWidth(), metrics.width('MMMMMM')) + text_width = qtutils.text_width(self.font(), 'MMMMMM') + width = max(self.minimumWidth(), text_width) self.setMinimumWidth(width) diff --git a/cola/widgets/text.py b/cola/widgets/text.py index 7ed623ac..28fb2126 100644 --- a/cola/widgets/text.py +++ b/cola/widgets/text.py @@ -174,9 +174,7 @@ class BaseTextEditExtension(QtCore.QObject): def set_tabwidth(self, width): self._tabwidth = width - font = self.widget.font() - metrics = QtGui.QFontMetrics(font) - pixels = metrics.width('M' * width) + pixels = qtutils.text_width(self.widget.font(), 'M') * width self.widget.setTabStopWidth(pixels) def selected_line(self): @@ -1152,7 +1150,8 @@ class LineNumbers(TextDecorator): def width_hint(self): document = self.editor.document() digits = int(math.log(max(1, document.blockCount()), 10)) + 2 - return defs.large_margin + self.fontMetrics().width('0') * digits + text_width = qtutils.text_width(self.font(), '0') + return defs.large_margin + (text_width * digits) def set_highlighted(self, line_number): """Set the line to highlight""" -- 2.11.4.GIT