mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-11-04 03:27:00 -05:00 
			
		
		
		
	Edit metadata custom column widgets.
- Add tweaks to move the elision point and to disable elision. - Fix some problems with the tooltips - Make the gutter between the label and the widget the same as the standard fields - Various other cleanups
This commit is contained in:
		
							parent
							
								
									9aeaacfb01
								
							
						
					
					
						commit
						d1b0b457ea
					
				@ -404,12 +404,19 @@ metadata_single_use_2_cols_for_custom_fields = True
 | 
				
			|||||||
# metadata_edit_custom_column_order = ['#genre', '#mytags', '#etc']
 | 
					# metadata_edit_custom_column_order = ['#genre', '#mytags', '#etc']
 | 
				
			||||||
metadata_edit_custom_column_order = []
 | 
					metadata_edit_custom_column_order = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: Edit metadata custom column label length
 | 
					#: Edit metadata custom column label width and elision point
 | 
				
			||||||
# Set the length of custom column labels shown in the edit metadata dialogs.
 | 
					# Set the width of custom column labels shown in the edit metadata dialogs.
 | 
				
			||||||
# Labels longer than this length will be elided. The length is computed by
 | 
					# If metadata_edit_elide_labels is True then labels wider than the width
 | 
				
			||||||
# multiplying the average width of characters in the font by the number below.
 | 
					# will be elided, otherwise they will be word wrapped. The maximum width is
 | 
				
			||||||
 | 
					# computed by multiplying the average width of characters in the font by the
 | 
				
			||||||
 | 
					# appropriate number.
 | 
				
			||||||
 | 
					# Set the elision point to 'middle' to put the elipsis (…) in the middle of
 | 
				
			||||||
 | 
					# the label, 'right' to put it at the right end of the label, and 'left' to
 | 
				
			||||||
 | 
					# put it at the left end.
 | 
				
			||||||
 | 
					metadata_edit_elide_labels = True
 | 
				
			||||||
metadata_edit_bulk_cc_label_length = 25
 | 
					metadata_edit_bulk_cc_label_length = 25
 | 
				
			||||||
metadata_edit_single_cc_label_length = 12
 | 
					metadata_edit_single_cc_label_length = 12
 | 
				
			||||||
 | 
					metadata_edit_elision_point = 'right'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: The number of seconds to wait before sending emails
 | 
					#: The number of seconds to wait before sending emails
 | 
				
			||||||
# The number of seconds to wait before sending emails when using a
 | 
					# The number of seconds to wait before sending emails when using a
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,14 @@ def label_string(txt):
 | 
				
			|||||||
    return txt
 | 
					    return txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_tooltip(col_metadata, add_index=False):
 | 
				
			||||||
 | 
					    key = col_metadata['label'] + ('_index' if add_index else '')
 | 
				
			||||||
 | 
					    label = col_metadata['name'] + (_(' index') if add_index else '')
 | 
				
			||||||
 | 
					    description = col_metadata.get('display', {}).get('description', '')
 | 
				
			||||||
 | 
					    return '{0} (#{1}){2} {3}'.format(
 | 
				
			||||||
 | 
					                  label, key, ':' if description else '', description).strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Base(object):
 | 
					class Base(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, db, col_id, parent=None):
 | 
					    def __init__(self, db, col_id, parent=None):
 | 
				
			||||||
@ -52,18 +60,13 @@ class Base(object):
 | 
				
			|||||||
        self.initial_val = self.widgets = None
 | 
					        self.initial_val = self.widgets = None
 | 
				
			||||||
        self.signals_to_disconnect = []
 | 
					        self.signals_to_disconnect = []
 | 
				
			||||||
        self.setup_ui(parent)
 | 
					        self.setup_ui(parent)
 | 
				
			||||||
        key = db.field_metadata.label_to_key(self.col_metadata['label'],
 | 
					        description = get_tooltip(self.col_metadata)
 | 
				
			||||||
                                                       prefer_custom=True)
 | 
					 | 
				
			||||||
        description = self.col_metadata.get('display', {}).get('description', '')
 | 
					 | 
				
			||||||
        if description:
 | 
					 | 
				
			||||||
            description = key + ': ' + description
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            description = key
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
 | 
					            self.widgets[0].setToolTip(description)
 | 
				
			||||||
            self.widgets[1].setToolTip(description)
 | 
					            self.widgets[1].setToolTip(description)
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                self.widgets[0].setToolTip(description)
 | 
					                self.widgets[1].setToolTip(description)
 | 
				
			||||||
            except:
 | 
					            except:
 | 
				
			||||||
                pass
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -111,7 +114,7 @@ class Base(object):
 | 
				
			|||||||
class SimpleText(Base):
 | 
					class SimpleText(Base):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_ui(self, parent):
 | 
					    def setup_ui(self, parent):
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', parent),
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), parent),
 | 
				
			||||||
                        QLineEdit(parent)]
 | 
					                        QLineEdit(parent)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setter(self, val):
 | 
					    def setter(self, val):
 | 
				
			||||||
@ -151,7 +154,7 @@ class LongText(Base):
 | 
				
			|||||||
class Bool(Base):
 | 
					class Bool(Base):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_ui(self, parent):
 | 
					    def setup_ui(self, parent):
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', parent)]
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), parent)]
 | 
				
			||||||
        w = QWidget(parent)
 | 
					        w = QWidget(parent)
 | 
				
			||||||
        self.widgets.append(w)
 | 
					        self.widgets.append(w)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -214,7 +217,7 @@ class Int(Base):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def setup_ui(self, parent):
 | 
					    def setup_ui(self, parent):
 | 
				
			||||||
        self.was_none = False
 | 
					        self.was_none = False
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', parent),
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), parent),
 | 
				
			||||||
                ClearingSpinBox(parent)]
 | 
					                ClearingSpinBox(parent)]
 | 
				
			||||||
        w = self.widgets[1]
 | 
					        w = self.widgets[1]
 | 
				
			||||||
        w.setRange(-1000000, 100000000)
 | 
					        w.setRange(-1000000, 100000000)
 | 
				
			||||||
@ -247,7 +250,7 @@ class Int(Base):
 | 
				
			|||||||
class Float(Int):
 | 
					class Float(Int):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_ui(self, parent):
 | 
					    def setup_ui(self, parent):
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', parent),
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), parent),
 | 
				
			||||||
                ClearingDoubleSpinBox(parent)]
 | 
					                ClearingDoubleSpinBox(parent)]
 | 
				
			||||||
        w = self.widgets[1]
 | 
					        w = self.widgets[1]
 | 
				
			||||||
        w.setRange(-1000000., float(100000000))
 | 
					        w.setRange(-1000000., float(100000000))
 | 
				
			||||||
@ -262,7 +265,7 @@ class Rating(Base):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def setup_ui(self, parent):
 | 
					    def setup_ui(self, parent):
 | 
				
			||||||
        allow_half_stars = self.col_metadata['display'].get('allow_half_stars', False)
 | 
					        allow_half_stars = self.col_metadata['display'].get('allow_half_stars', False)
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', parent),
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), parent),
 | 
				
			||||||
                        RatingEditor(parent=parent, is_half_star=allow_half_stars)]
 | 
					                        RatingEditor(parent=parent, is_half_star=allow_half_stars)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setter(self, val):
 | 
					    def setter(self, val):
 | 
				
			||||||
@ -299,7 +302,7 @@ class DateTime(Base):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def setup_ui(self, parent):
 | 
					    def setup_ui(self, parent):
 | 
				
			||||||
        cm = self.col_metadata
 | 
					        cm = self.col_metadata
 | 
				
			||||||
        self.widgets = [QLabel(label_string(cm['name'])+':', parent)]
 | 
					        self.widgets = [QLabel(label_string(cm['name']), parent)]
 | 
				
			||||||
        w = QWidget(parent)
 | 
					        w = QWidget(parent)
 | 
				
			||||||
        self.widgets.append(w)
 | 
					        self.widgets.append(w)
 | 
				
			||||||
        l = QHBoxLayout()
 | 
					        l = QHBoxLayout()
 | 
				
			||||||
@ -478,7 +481,7 @@ class Text(Base):
 | 
				
			|||||||
            w.set_separator(None)
 | 
					            w.set_separator(None)
 | 
				
			||||||
            w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
 | 
					            w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
 | 
				
			||||||
            w.setMinimumContentsLength(25)
 | 
					            w.setMinimumContentsLength(25)
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', parent), w]
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), parent), w]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def initialize(self, book_id):
 | 
					    def initialize(self, book_id):
 | 
				
			||||||
        values = list(self.db.all_custom(num=self.col_id))
 | 
					        values = list(self.db.all_custom(num=self.col_id))
 | 
				
			||||||
@ -551,15 +554,18 @@ class Series(Base):
 | 
				
			|||||||
        w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
 | 
					        w.setSizeAdjustPolicy(w.AdjustToMinimumContentsLengthWithIcon)
 | 
				
			||||||
        w.setMinimumContentsLength(25)
 | 
					        w.setMinimumContentsLength(25)
 | 
				
			||||||
        self.name_widget = w
 | 
					        self.name_widget = w
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', parent), w]
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), parent), w]
 | 
				
			||||||
        w.editTextChanged.connect(self.series_changed)
 | 
					        w.editTextChanged.connect(self.series_changed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.widgets.append(QLabel(label_string(self.col_metadata['name'])+_(' index:'), parent))
 | 
					        w = QLabel(label_string(self.col_metadata['name'])+_(' index'), parent)
 | 
				
			||||||
 | 
					        w.setToolTip(get_tooltip(self.col_metadata, add_index=True))
 | 
				
			||||||
 | 
					        self.widgets.append(w)
 | 
				
			||||||
        w = QDoubleSpinBox(parent)
 | 
					        w = QDoubleSpinBox(parent)
 | 
				
			||||||
        w.setRange(-10000., float(100000000))
 | 
					        w.setRange(-10000., float(100000000))
 | 
				
			||||||
        w.setDecimals(2)
 | 
					        w.setDecimals(2)
 | 
				
			||||||
        w.setSingleStep(1)
 | 
					        w.setSingleStep(1)
 | 
				
			||||||
        self.idx_widget=w
 | 
					        self.idx_widget=w
 | 
				
			||||||
 | 
					        w.setToolTip(get_tooltip(self.col_metadata, add_index=True))
 | 
				
			||||||
        self.widgets.append(w)
 | 
					        self.widgets.append(w)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def initialize(self, book_id):
 | 
					    def initialize(self, book_id):
 | 
				
			||||||
@ -625,7 +631,7 @@ class Enumeration(Base):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def setup_ui(self, parent):
 | 
					    def setup_ui(self, parent):
 | 
				
			||||||
        self.parent = parent
 | 
					        self.parent = parent
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', parent),
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), parent),
 | 
				
			||||||
                QComboBox(parent)]
 | 
					                QComboBox(parent)]
 | 
				
			||||||
        w = self.widgets[1]
 | 
					        w = self.widgets[1]
 | 
				
			||||||
        vals = self.col_metadata['display']['enum_values']
 | 
					        vals = self.col_metadata['display']['enum_values']
 | 
				
			||||||
@ -747,9 +753,12 @@ def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, pa
 | 
				
			|||||||
    ans = []
 | 
					    ans = []
 | 
				
			||||||
    column = row = base_row = max_row = 0
 | 
					    column = row = base_row = max_row = 0
 | 
				
			||||||
    label_width = 0
 | 
					    label_width = 0
 | 
				
			||||||
 | 
					    do_elision = tweaks['metadata_edit_elide_labels']
 | 
				
			||||||
 | 
					    elide_pos = tweaks['metadata_edit_elision_point']
 | 
				
			||||||
 | 
					    elide_pos = elide_pos if elide_pos in {'left', 'middle', 'right'} else 'right'
 | 
				
			||||||
    for key in cols:
 | 
					    for key in cols:
 | 
				
			||||||
        if not fm[key]['is_editable']:
 | 
					        if not fm[key]['is_editable']:
 | 
				
			||||||
            continue  # this almost never happens
 | 
					            continue  # The job spy plugin can change is_editable
 | 
				
			||||||
        dt = fm[key]['datatype']
 | 
					        dt = fm[key]['datatype']
 | 
				
			||||||
        if dt == 'composite' or (bulk and dt == 'comments'):
 | 
					        if dt == 'composite' or (bulk and dt == 'comments'):
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
@ -771,7 +780,6 @@ def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, pa
 | 
				
			|||||||
                comments_not_in_tweak = 0
 | 
					                comments_not_in_tweak = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        l = QGridLayout()
 | 
					        l = QGridLayout()
 | 
				
			||||||
        l.setHorizontalSpacing(0)
 | 
					 | 
				
			||||||
        if is_comments:
 | 
					        if is_comments:
 | 
				
			||||||
            layout.addLayout(l, row, column, layout_rows_for_comments, 1)
 | 
					            layout.addLayout(l, row, column, layout_rows_for_comments, 1)
 | 
				
			||||||
            layout.setColumnStretch(column, 100)
 | 
					            layout.setColumnStretch(column, 100)
 | 
				
			||||||
@ -787,21 +795,26 @@ def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, pa
 | 
				
			|||||||
                wij = w.widgets[c]
 | 
					                wij = w.widgets[c]
 | 
				
			||||||
                if label_width == 0:
 | 
					                if label_width == 0:
 | 
				
			||||||
                    font_metrics = wij.fontMetrics()
 | 
					                    font_metrics = wij.fontMetrics()
 | 
				
			||||||
 | 
					                    colon_width = font_metrics.width(':')
 | 
				
			||||||
                    if bulk:
 | 
					                    if bulk:
 | 
				
			||||||
                        label_width = (font_metrics.averageCharWidth() *
 | 
					                        label_width = (font_metrics.averageCharWidth() *
 | 
				
			||||||
                                       tweaks['metadata_edit_bulk_cc_label_length'])
 | 
					                               tweaks['metadata_edit_bulk_cc_label_length']) - colon_width
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
                        label_width = (font_metrics.averageCharWidth() *
 | 
					                        label_width = (font_metrics.averageCharWidth() *
 | 
				
			||||||
                                       tweaks['metadata_edit_single_cc_label_length'])
 | 
					                               tweaks['metadata_edit_single_cc_label_length']) - colon_width
 | 
				
			||||||
                wij.setMaximumWidth(label_width)
 | 
					                wij.setMaximumWidth(label_width)
 | 
				
			||||||
                if c == 0:
 | 
					                if c == 0:
 | 
				
			||||||
                    wij.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
 | 
					                    wij.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
 | 
				
			||||||
                    l.setColumnMinimumWidth(0, label_width)
 | 
					                    l.setColumnMinimumWidth(0, label_width)
 | 
				
			||||||
                wij.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
 | 
					                wij.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
 | 
				
			||||||
                t = unicode_type(wij.text())
 | 
					                t = unicode_type(wij.text())
 | 
				
			||||||
                wij.setToolTip(t[1:-1] if t.startswith('&') else t[:-1])
 | 
					                if t:
 | 
				
			||||||
                wij.setText(elided_text(t+' ', font=font_metrics,
 | 
					                    if do_elision:
 | 
				
			||||||
                                        width=label_width, pos='right'))
 | 
					                        wij.setText(elided_text(t, font=font_metrics,
 | 
				
			||||||
 | 
					                                            width=label_width, pos=elide_pos) + ':')
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        wij.setText(t + ':')
 | 
				
			||||||
 | 
					                        wij.setWordWrap(True)
 | 
				
			||||||
                wij.setBuddy(w.widgets[c+1])
 | 
					                wij.setBuddy(w.widgets[c+1])
 | 
				
			||||||
                l.addWidget(wij, c, 0)
 | 
					                l.addWidget(wij, c, 0)
 | 
				
			||||||
                l.addWidget(w.widgets[c+1], c, 1)
 | 
					                l.addWidget(w.widgets[c+1], c, 1)
 | 
				
			||||||
@ -859,10 +872,9 @@ class BulkBase(Base):
 | 
				
			|||||||
        val = self.normalize_ui_val(val)
 | 
					        val = self.normalize_ui_val(val)
 | 
				
			||||||
        self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
 | 
					        self.db.set_custom_bulk(book_ids, val, num=self.col_id, notify=notify)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_widgets(self, parent, main_widget_class, extra_label_text='',
 | 
					    def make_widgets(self, parent, main_widget_class, add_tags_edit_button=False):
 | 
				
			||||||
                     add_tags_edit_button=False):
 | 
					 | 
				
			||||||
        w = QWidget(parent)
 | 
					        w = QWidget(parent)
 | 
				
			||||||
        self.widgets = [QLabel(label_string(self.col_metadata['name'])+':', w), w]
 | 
					        self.widgets = [QLabel(label_string(self.col_metadata['name']), w), w]
 | 
				
			||||||
        l = QHBoxLayout()
 | 
					        l = QHBoxLayout()
 | 
				
			||||||
        l.setContentsMargins(0, 0, 0, 0)
 | 
					        l.setContentsMargins(0, 0, 0, 0)
 | 
				
			||||||
        w.setLayout(l)
 | 
					        w.setLayout(l)
 | 
				
			||||||
@ -1282,9 +1294,7 @@ class BulkText(BulkBase):
 | 
				
			|||||||
        values.sort(key=sort_key)
 | 
					        values.sort(key=sort_key)
 | 
				
			||||||
        if self.col_metadata['is_multiple']:
 | 
					        if self.col_metadata['is_multiple']:
 | 
				
			||||||
            is_tags = not self.col_metadata['display'].get('is_names', False)
 | 
					            is_tags = not self.col_metadata['display'].get('is_names', False)
 | 
				
			||||||
            self.make_widgets(parent, EditWithComplete,
 | 
					            self.make_widgets(parent, EditWithComplete, add_tags_edit_button=is_tags)
 | 
				
			||||||
                              extra_label_text=_('tags to add'),
 | 
					 | 
				
			||||||
                              add_tags_edit_button=is_tags)
 | 
					 | 
				
			||||||
            self.main_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
 | 
					            self.main_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
 | 
				
			||||||
            self.adding_widget = self.main_widget
 | 
					            self.adding_widget = self.main_widget
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1292,8 +1302,12 @@ class BulkText(BulkBase):
 | 
				
			|||||||
                self.edit_tags_button.clicked.connect(self.edit_add)
 | 
					                self.edit_tags_button.clicked.connect(self.edit_add)
 | 
				
			||||||
                w = RemoveTags(parent, values)
 | 
					                w = RemoveTags(parent, values)
 | 
				
			||||||
                w.remove_tags_button.clicked.connect(self.edit_remove)
 | 
					                w.remove_tags_button.clicked.connect(self.edit_remove)
 | 
				
			||||||
                self.widgets.append(QLabel(label_string(self.col_metadata['name'])+': ' +
 | 
					                l = QLabel(label_string(self.col_metadata['name'])+': ' +
 | 
				
			||||||
                                           _('tags to remove') + ':', parent))
 | 
					                                           _('tags to remove'), parent)
 | 
				
			||||||
 | 
					                tt = get_tooltip(self.col_metadata) + ': ' + _('tags to remove')
 | 
				
			||||||
 | 
					                l.setToolTip(tt)
 | 
				
			||||||
 | 
					                self.widgets.append(l)
 | 
				
			||||||
 | 
					                w.setToolTip(tt)
 | 
				
			||||||
                self.widgets.append(w)
 | 
					                self.widgets.append(w)
 | 
				
			||||||
                self.removing_widget = w
 | 
					                self.removing_widget = w
 | 
				
			||||||
                self.main_widget.set_separator(',')
 | 
					                self.main_widget.set_separator(',')
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user