From b2898e4f14b3af402262dfb93ceb7e48c38565bc Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Sat, 19 Feb 2022 11:44:53 +0000 Subject: [PATCH] Enhancement #1961464: add ability to import and export the edit metadata custom column field list. --- src/calibre/gui2/custom_column_widgets.py | 7 +++- src/calibre/gui2/preferences/look_feel.py | 39 +++++++++++++++++-- src/calibre/gui2/preferences/look_feel.ui | 46 +++++++++++++++++++++++ 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index df0adbae45..bc55707ac5 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -759,10 +759,13 @@ def column_is_comments(key, fm): fm[key].get('display', {}).get('interpret_as') != 'short-text') -def get_field_list(db, use_defaults=False): +def get_field_list(db, use_defaults=False, pref_data_override=None): fm = db.field_metadata fields = fm.custom_field_keys(include_composites=False) - displayable = db.prefs.get('edit_metadata_custom_columns_to_display', None) + if pref_data_override is not None: + displayable = pref_data_override + else: + displayable = db.prefs.get('edit_metadata_custom_columns_to_display', None) if use_defaults or displayable is None: fields.sort(key=partial(field_sort_key, fm=fm)) return [(k, True) for k in fields] diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 9b76a08c2c..571dacf8b0 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -21,7 +21,7 @@ from calibre import human_readable from calibre.ebooks.metadata.book.render import DEFAULT_AUTHOR_LINK from calibre.constants import ismacos, iswindows from calibre.ebooks.metadata.sources.prefs import msprefs -from calibre.gui2 import default_author_link +from calibre.gui2 import default_author_link, choose_save_file, choose_files from calibre.gui2.custom_column_widgets import get_field_list as em_get_field_list from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.gui2.preferences import ConfigWidgetBase, test_widget, CommaSeparatedList @@ -333,10 +333,10 @@ class EMDisplayedFields(DisplayedFields): # {{{ def __init__(self, db, parent=None): DisplayedFields.__init__(self, db, parent) - def initialize(self, use_defaults=False): + def initialize(self, use_defaults=False, pref_data_override=None): self.beginResetModel() self.fields = [[x[0], x[1]] for x in - em_get_field_list(self.db, use_defaults=use_defaults)] + em_get_field_list(self.db, use_defaults=use_defaults, pref_data_override=pref_data_override)] self.endResetModel() self.changed = True @@ -567,6 +567,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): lambda self: move_field_up(self.em_display_order, self.em_display_model)) connect_lambda(self.em_down_button.clicked, self, lambda self: move_field_down(self.em_display_order, self.em_display_model)) + self.em_export_layout_button.clicked.connect(self.em_export_layout) + self.em_import_layout_button.clicked.connect(self.em_import_layout) + self.em_reset_layout_button.clicked.connect(self.em_reset_layout) self.qv_display_model = QVDisplayedFields(self.gui.current_db, self.qv_display_order) @@ -640,6 +643,36 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.sections_view.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) self.tabWidget.currentWidget().setFocus(Qt.FocusReason.OtherFocusReason) + def em_export_layout(self): + filename = choose_save_file(self, 'em_import_export_field_list', + _('Save column list to file'), + filters=[(_('Column list'), ['json'])]) + if filename: + try: + with open(filename, 'w') as f: + json.dump(self.em_display_model.fields, f, indent=1) + except Exception as err: + error_dialog(self, _('Export field layout'), + _('

Could not write field list. Error:
%s')%err, show=True) + + def em_import_layout(self): + filename = choose_files(self, 'em_import_export_field_list', + _('Load column list from file'), + filters=[(_('Column list'), ['json'])]) + if filename: + try: + with open(filename[0]) as f: + fields = json.load(f) + self.em_display_model.initialize(pref_data_override=fields) + self.changed_signal.emit() + except Exception as err: + error_dialog(self, _('Import layout'), + _('

Could not read field list. Error:
%s')%err, show=True) + + def em_reset_layout(self): + self.em_display_model.initialize(use_defaults=True) + self.changed_signal.emit() + def choose_icon_theme(self): from calibre.gui2.icon_theme import ChooseTheme d = ChooseTheme(self) diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui index 4e7c3ea94d..3038e0b225 100644 --- a/src/calibre/gui2/preferences/look_feel.ui +++ b/src/calibre/gui2/preferences/look_feel.ui @@ -987,6 +987,47 @@ A value of zero means calculate automatically. + + + + + + Export list + + + <p>Click this button to write the current display +settings to a file. This could be useful if you have several libraries with similar +structure and you want to use the same column order for each one.</p> + + + + + + + Import list + + + <p>Click this button to set the list to one +previously exported. This could be useful if you have several libraries with +similar structure and you want to use the same column order for each one. Columns +in the imported list that aren't in the current library are ignored. Columns in +the library that are not in the imported list are put at the end and marked +as displayable.</p> + + + + + + + Reset list + + + <p>Click this button to reset the list to its default order.</p> + + + + + @@ -1624,6 +1665,11 @@ column being examined (the left-hand pane)

calibre/gui2/widgets2.h
1 + + FlowLayout + QLayout +
calibre/gui2/widgets2.h
+