Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix enhancement #190009: Width of custom date columns. #1258

Merged
merged 2 commits into from
Oct 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions resources/default_tweaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,13 @@
# metadata_edit_custom_column_order = ['#genre', '#mytags', '#etc']
metadata_edit_custom_column_order = []

#: Edit metadata custom column label width
# Set the width of custom column labels shown in the edit metadata dialogs.
# Labels longer than this length will be elided. The width is computed by
# multiplying the average width of characters in the font by the number provided.
metadata_edit_bulk_cc_label_width = 25
metadata_edit_single_cc_label_width = 12

#: The number of seconds to wait before sending emails
# The number of seconds to wait before sending emails when using a
# public email server like GMX/Hotmail/Gmail. Default is: 5 minutes
Expand Down
83 changes: 35 additions & 48 deletions src/calibre/gui2/custom_column_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
import os
from functools import partial

from PyQt5.Qt import (QComboBox, QLabel, QSpinBox, QDoubleSpinBox,
from PyQt5.Qt import (Qt, QComboBox, QLabel, QSpinBox, QDoubleSpinBox,
QDateTime, QGroupBox, QVBoxLayout, QSizePolicy, QGridLayout, QUrl,
QSpacerItem, QIcon, QCheckBox, QWidget, QHBoxLayout, QLineEdit,
QPushButton, QMessageBox, QToolButton, QPlainTextEdit)
QMessageBox, QToolButton, QPlainTextEdit)

from calibre.utils.date import qt_to_dt, now, as_local_time, as_utc, internal_iso_format_string
from calibre.gui2.complete2 import EditWithComplete
from calibre.gui2.comments_editor import Editor as CommentsEditor
from calibre.gui2 import UNDEFINED_QDATETIME, error_dialog
from calibre.gui2 import UNDEFINED_QDATETIME, error_dialog, elided_text
from calibre.gui2.dialogs.tag_editor import TagEditor
from calibre.utils.config import tweaks
from calibre.utils.icu import sort_key
Expand Down Expand Up @@ -161,32 +161,22 @@ def setup_ui(self, parent):
self.combobox = QComboBox(parent)
l.addWidget(self.combobox)

t = _('Yes')
c = QPushButton(t, parent)
width = c.fontMetrics().boundingRect(t).width() + 7
c.setMaximumWidth(width)
c = QToolButton(parent)
c.setText(_('Yes'))
l.addWidget(c)
c.clicked.connect(self.set_to_yes)

t = _('No')
c = QPushButton(t, parent)
width = c.fontMetrics().boundingRect(t).width() + 7
c.setMaximumWidth(width)
c = QToolButton(parent)
c.setText(_('No'))
l.addWidget(c)
c.clicked.connect(self.set_to_no)

if self.db.new_api.pref('bools_are_tristate'):
t = _('Clear')
c = QPushButton(t, parent)
width = c.fontMetrics().boundingRect(t).width() + 7
c.setMaximumWidth(width)
c = QToolButton(parent)
c.setText(_('Clear'))
l.addWidget(c)
c.clicked.connect(self.set_to_cleared)

c = QLabel('', parent)
c.setMaximumWidth(1)
l.addWidget(c, 1)

w = self.combobox
items = [_('Yes'), _('No'), _('Undefined')]
icons = [I('ok.png'), I('list_remove.png'), I('blank.png')]
Expand Down Expand Up @@ -326,15 +316,16 @@ def setup_ui(self, parent):
dte.setMinimumDateTime(UNDEFINED_QDATETIME)
dte.setSpecialValueText(_('Undefined'))
l.addWidget(dte)

self.today_button = QToolButton(parent)
self.today_button.setText(_('Today'))
self.today_button.clicked.connect(dte.set_to_today)
l.addWidget(self.today_button)

self.clear_button = QToolButton(parent)
self.clear_button.setIcon(QIcon(I('trash.png')))
self.clear_button.clicked.connect(dte.set_to_clear)
l.addWidget(self.clear_button)
l.addStretch(1)

def setter(self, val):
if val is None:
Expand Down Expand Up @@ -755,7 +746,7 @@ def widget_factory(typ, key):
turnover_point = count + 1000
ans = []
column = row = base_row = max_row = 0
minimum_label = 0
label_width = 0
for key in cols:
if not fm[key]['is_editable']:
continue # this almost never happens
Expand All @@ -780,6 +771,7 @@ def widget_factory(typ, key):
comments_not_in_tweak = 0

l = QGridLayout()
l.setHorizontalSpacing(0)
if is_comments:
layout.addLayout(l, row, column, layout_rows_for_comments, 1)
layout.setColumnStretch(column, 100)
Expand All @@ -790,33 +782,28 @@ def widget_factory(typ, key):
row += 1
for c in range(0, len(w.widgets), 2):
if not is_comments:
w.widgets[c].setWordWrap(True)
'''
It seems that there is something strange with wordwrapped labels
with some fonts. Apparently one part of QT thinks it is showing
a single line and sizes the line vertically accordingly. Another
part thinks there isn't enough space and wraps the label. The
result is two lines in a single line space, cutting off parts of
the lines. It doesn't happen with every font, nor with every
"long" label.

This change works around the problem by setting the maximum
display width and telling QT to respect that width.

While here I implemented an arbitrary minimum label length so
that there is a better chance that the field edit boxes line up.
'''
if minimum_label == 0:
minimum_label = w.widgets[c].fontMetrics().boundingRect('smallLabel').width()
label_width = w.widgets[c].fontMetrics().boundingRect(w.widgets[c].text()).width()
# Set the label column width to a fixed size. Elide labels that
# don't fit
wij = w.widgets[c]
if label_width == 0:
font_metrics = wij.fontMetrics()
if bulk:
label_width = (font_metrics.averageCharWidth() *
tweaks['metadata_edit_bulk_cc_label_length'])
else:
label_width = (font_metrics.averageCharWidth() *
tweaks['metadata_edit_single_cc_label_length'])
wij.setMaximumWidth(label_width)
if c == 0:
w.widgets[0].setMaximumWidth(label_width)
w.widgets[0].setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
l.setColumnMinimumWidth(0, minimum_label)
else:
w.widgets[0].setMaximumWidth(max(w.widgets[0].maximumWidth(), label_width))
w.widgets[c].setBuddy(w.widgets[c+1])
l.addWidget(w.widgets[c], c, 0)
wij.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
l.setColumnMinimumWidth(0, label_width)
wij.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
t = unicode_type(wij.text())
wij.setToolTip(t[1:-1] if t.startswith('&') else t[:-1])
wij.setText(elided_text(t+' ', font=font_metrics,
width=label_width, pos='right'))
wij.setBuddy(w.widgets[c+1])
l.addWidget(wij, c, 0)
l.addWidget(w.widgets[c+1], c, 1)
else:
l.addWidget(w.widgets[0], 0, 0, 1, 2)
Expand Down Expand Up @@ -1306,7 +1293,7 @@ def setup_ui(self, parent):
w = RemoveTags(parent, values)
w.remove_tags_button.clicked.connect(self.edit_remove)
self.widgets.append(QLabel(label_string(self.col_metadata['name'])+': ' +
_('tags to remove'), parent))
_('tags to remove') + ':', parent))
self.widgets.append(w)
self.removing_widget = w
self.main_widget.set_separator(',')
Expand Down