class ConfigWidget(ConfigWidgetBase, Ui_Form): size_calculated = pyqtSignal(object) def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('show_rating_in_cover_browser', gprefs) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[ (_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) if islinux or isbsd: self.opt_systray_icon.setEnabled(False) self.opt_systray_icon.setText(_('System tray icon is disabled because of bugs in Qt 5')) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) self.search_library_for_author_button.clicked.connect( lambda : self.opt_default_author_link.setText('search-calibre')) choices = set([k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False))]) choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) fm = db.field_metadata choices = sorted(((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x:sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence('F11', QKeySequence.PortableText), QKeySequence( 'Ctrl+Shift+F', QKeySequence.PortableText)] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%( _(' or ').join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton(_('Change &background image'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton(_('Restore &default appearance'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) self.cover_grid_smaller_cover.clicked.connect(partial(self.resize_cover, True)) self.cover_grid_larger_cover.clicked.connect(partial(self.resize_cover, False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum(self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum(self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect(self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect(self.update_aspect_ratio) @property def current_cover_size(self): cval = self.opt_cover_grid_height.value() wval = self.opt_cover_grid_width.value() if cval < 0.1: dpi = self.opt_cover_grid_height.logicalDpiY() cval = auto_height(self.opt_cover_grid_height) / dpi / CM_TO_INCH if wval < 0.1: wval = 0.75 * cval return wval, cval def update_aspect_ratio(self, *args): width, height = self.current_cover_size ar = width / height self.cover_grid_aspect_ratio.setText(_('Current aspect ratio (width/height): %.2g') % ar) def resize_cover(self, smaller): wval, cval = self.current_cover_size ar = wval / cval delta = 0.2 * (-1 if smaller else 1) cval += delta cval = max(0, cval) self.opt_cover_grid_height.setValue(cval) self.opt_cover_grid_width.setValue(cval * ar) def cg_reset_size(self): self.opt_cover_grid_width.setValue(0) self.opt_cover_grid_height.setValue(0) def initialize(self): ConfigWidgetBase.initialize(self) font = gprefs['font'] if font is not None: font = list(font) font.append(gprefs.get('font_stretch', QFont.Unstretched)) self.current_font = self.initial_font = font self.update_font_display() self.display_model.initialize() db = self.gui.current_db try: idx = self.gui.library_view.currentIndex().row() mi = db.get_metadata(idx, index_is_id=False) except: mi=None self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules') self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules') self.grid_rules.initialize(db.field_metadata, db.prefs, mi, 'cover_grid_icon_rules') self.set_cg_color(gprefs['cover_grid_color']) self.set_cg_texture(gprefs['cover_grid_texture']) self.update_aspect_ratio() def open_cg_cache(self): open_local_file(self.gui.grid_view.thumbnail_cache.location) def update_cg_cache_size(self, size): self.cover_grid_current_disk_cache.setText( _('Current space used: %s') % human_readable(size)) def tab_changed(self, index): if self.tabWidget.currentWidget() is self.cover_grid_tab: self.show_current_cache_usage() def show_current_cache_usage(self): t = Thread(target=self.calc_cache_size) t.daemon = True t.start() def calc_cache_size(self): self.size_calculated.emit(self.gui.grid_view.thumbnail_cache.current_size) def set_cg_color(self, val): self.cg_bg_widget.bcol = QColor(*val) self.cg_bg_widget.update_brush() def set_cg_texture(self, val): self.cg_bg_widget.btex = val self.cg_bg_widget.update_brush() def empty_cache(self): self.gui.grid_view.thumbnail_cache.empty() self.calc_cache_size() def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) ofont = self.current_font self.current_font = None if ofont is not None: self.changed_signal.emit() self.update_font_display() self.display_model.restore_defaults() self.edit_rules.clear() self.icon_rules.clear() self.grid_rules.clear() self.changed_signal.emit() self.set_cg_color(gprefs.defaults['cover_grid_color']) self.set_cg_texture(gprefs.defaults['cover_grid_texture']) def change_cover_grid_color(self): col = QColorDialog.getColor(self.cg_bg_widget.bcol, self.gui, _('Choose background color for cover grid')) if col.isValid(): col = tuple(col.getRgb())[:3] self.set_cg_color(col) self.changed_signal.emit() if self.cg_bg_widget.btex: if question_dialog( self, _('Remove background image?'), _('There is currently a background image set, so the color' ' you have chosen will not be visible. Remove the background image?')): self.set_cg_texture(None) def change_cover_grid_texture(self): from calibre.gui2.preferences.texture_chooser import TextureChooser d = TextureChooser(parent=self, initial=self.cg_bg_widget.btex) if d.exec_() == d.Accepted: self.set_cg_texture(d.texture) self.changed_signal.emit() def restore_cover_grid_appearance(self): self.set_cg_color(gprefs.defaults['cover_grid_color']) self.set_cg_texture(gprefs.defaults['cover_grid_texture']) self.changed_signal.emit() def build_font_obj(self): font_info = qt_app.original_font if self.current_font is None else self.current_font font = QFont(*(font_info[:4])) font.setStretch(font_info[4]) return font def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) name = unicode(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + ' [%dpt]'%fi.pointSize()) def move_df_up(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, -1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def move_df_down(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, 1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def change_font(self, *args): fd = QFontDialog(self.build_font_obj(), self) if fd.exec_() == fd.Accepted: font = fd.selectedFont() fi = QFontInfo(font) self.current_font = [unicode(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch()] self.update_font_display() self.changed_signal.emit() def commit(self, *args): rr = ConfigWidgetBase.commit(self, *args) if self.current_font != self.initial_font: gprefs['font'] = (self.current_font[:4] if self.current_font else None) gprefs['font_stretch'] = (self.current_font[4] if self.current_font is not None else QFont.Unstretched) QApplication.setFont(self.font_display.font()) rr = True self.display_model.commit() self.edit_rules.commit(self.gui.current_db.prefs) self.icon_rules.commit(self.gui.current_db.prefs) self.grid_rules.commit(self.gui.current_db.prefs) gprefs['cover_grid_color'] = tuple(self.cg_bg_widget.bcol.getRgb())[:3] gprefs['cover_grid_texture'] = self.cg_bg_widget.btex return rr def refresh_gui(self, gui): m = gui.library_view.model() m.beginResetModel(), m.endResetModel() self.update_font_display() gui.tags_view.reread_collapse_parameters() gui.library_view.refresh_book_details() if hasattr(gui.cover_flow, 'setShowReflections'): gui.cover_flow.setShowReflections(gprefs['cover_browser_reflections']) gui.cover_flow.setPreserveAspectRatio(gprefs['cb_preserve_aspect_ratio']) gui.library_view.refresh_row_sizing() gui.grid_view.refresh_settings()
def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('show_rating_in_cover_browser', gprefs) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[ (_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) if islinux or isbsd: self.opt_systray_icon.setEnabled(False) self.opt_systray_icon.setText(_('System tray icon is disabled because of bugs in Qt 5')) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) self.search_library_for_author_button.clicked.connect( lambda : self.opt_default_author_link.setText('search-calibre')) choices = set([k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False))]) choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) fm = db.field_metadata choices = sorted(((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x:sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence('F11', QKeySequence.PortableText), QKeySequence( 'Ctrl+Shift+F', QKeySequence.PortableText)] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%( _(' or ').join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton(_('Change &background image'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton(_('Restore &default appearance'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) self.cover_grid_smaller_cover.clicked.connect(partial(self.resize_cover, True)) self.cover_grid_larger_cover.clicked.connect(partial(self.resize_cover, False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum(self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum(self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect(self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect(self.update_aspect_ratio)
class ConfigWidget(ConfigWidgetBase, Ui_Form): size_calculated = pyqtSignal(object) def genesis(self, gui): self.gui = gui if not ismacos and not iswindows: self.label_widget_style.setVisible(False) self.opt_ui_style.setVisible(False) db = gui.library_view.model().db r = self.register try: self.icon_theme_title = json.loads(I('icon-theme.json', data=True))['name'] except Exception: self.icon_theme_title = _('Default icons') self.icon_theme.setText( _('Icon theme: <b>%s</b>') % self.icon_theme_title) self.commit_icon_theme = None self.icon_theme_button.clicked.connect(self.choose_icon_theme) self.default_author_link = DefaultAuthorLink( self.default_author_link_container) self.default_author_link.changed_signal.connect(self.changed_signal) r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('hidpi', gprefs, restart_required=True, choices=[(_('Automatic'), 'auto'), (_('On'), 'on'), (_('Off'), 'off')]) if ismacos: self.opt_hidpi.setVisible(False), self.label_hidpi.setVisible( False) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('dnd_merge', gprefs) r('wrap_toolbar_text', gprefs, restart_required=True) r('show_layout_buttons', gprefs, restart_required=True) r('row_numbers_in_book_list', gprefs) r('tag_browser_old_look', gprefs) r('tag_browser_hide_empty_categories', gprefs) r('tag_browser_always_autocollapse', gprefs) r('tag_browser_show_tooltips', gprefs) r('tag_browser_allow_keyboard_focus', gprefs) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size_multiple', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('tag_browser_show_counts', gprefs) r('tag_browser_item_padding', gprefs) r('books_autoscroll_time', gprefs) r('qv_respects_vls', gprefs) r('qv_dclick_changes_column', gprefs) r('qv_retkey_changes_column', gprefs) r('qv_follows_column', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('cover_browser_title_template', db.prefs) fm = db.field_metadata r('cover_browser_subtitle_field', db.prefs, choices=[(_('No subtitle'), 'none')] + sorted( (fm[k].get('name'), k) for k in fm.all_field_keys() if fm[k].get('name'))) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[(_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) r('booklist_grid', gprefs) r('book_details_comments_heading_pos', gprefs, choices=[(_('Never'), 'hide'), (_('Above text'), 'above'), (_('Beside text'), 'side')]) self.cover_browser_title_template_button.clicked.connect( self.edit_cb_title_template) self.id_links_button.clicked.connect(self.edit_id_link_rules) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(key=lambda x: x[1].lower()) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) r('cb_double_click_to_activate', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('tags_browser_collapse_fl_at', gprefs) choices = { k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False)) } choices |= {'search'} r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList, choices=sorted(choices, key=sort_key)) choices -= {'authors', 'publisher', 'formats', 'news', 'identifiers'} r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(choices, key=sort_key)) fm = db.field_metadata choices = sorted( ((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x: sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) connect_lambda( self.df_up_button.clicked, self, lambda self: move_field_up( self.field_display_order, self.display_model)) connect_lambda( self.df_down_button.clicked, self, lambda self: move_field_down( self.field_display_order, self.display_model)) self.qv_display_model = QVDisplayedFields(self.gui.current_db, self.qv_display_order) self.qv_display_model.dataChanged.connect(self.changed_signal) self.qv_display_order.setModel(self.qv_display_model) connect_lambda( self.qv_up_button.clicked, self, lambda self: move_field_up( self.qv_display_order, self.qv_display_model)) connect_lambda( self.qv_down_button.clicked, self, lambda self: move_field_down( self.qv_display_order, self.qv_display_model)) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column &coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column &icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [ QKeySequence('F11', QKeySequence.SequenceFormat.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.SequenceFormat.PortableText) ] keys = [ str(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in keys ] self.fs_help_msg.setText( self.fs_help_msg.text() % (QKeySequence(QKeySequence.StandardKey.FullScreen).toString( QKeySequence.SequenceFormat.NativeText))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.ConnectionType.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton( _('Change &background image'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton( _('Restore default &appearance'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) connect_lambda(self.cover_grid_smaller_cover.clicked, self, lambda self: self.resize_cover(True)) connect_lambda(self.cover_grid_larger_cover.clicked, self, lambda self: self.resize_cover(False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum( self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum( self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect( self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect( self.update_aspect_ratio) self.opt_book_details_css.textChanged.connect(self.changed_signal) from calibre.gui2.tweak_book.editor.text import get_highlighter, get_theme self.css_highlighter = get_highlighter('css')() self.css_highlighter.apply_theme(get_theme(None)) self.css_highlighter.set_document(self.opt_book_details_css.document()) def choose_icon_theme(self): from calibre.gui2.icon_theme import ChooseTheme d = ChooseTheme(self) if d.exec_() == QDialog.DialogCode.Accepted: self.commit_icon_theme = d.commit_changes self.icon_theme_title = d.new_theme_title or _('Default icons') self.icon_theme.setText( _('Icon theme: <b>%s</b>') % self.icon_theme_title) self.changed_signal.emit() def edit_id_link_rules(self): if IdLinksEditor(self).exec_() == QDialog.DialogCode.Accepted: self.changed_signal.emit() @property def current_cover_size(self): cval = self.opt_cover_grid_height.value() wval = self.opt_cover_grid_width.value() if cval < 0.1: dpi = self.opt_cover_grid_height.logicalDpiY() cval = auto_height(self.opt_cover_grid_height) / dpi / CM_TO_INCH if wval < 0.1: wval = 0.75 * cval return wval, cval def update_aspect_ratio(self, *args): width, height = self.current_cover_size ar = width / height self.cover_grid_aspect_ratio.setText( _('Current aspect ratio (width/height): %.2g') % ar) def resize_cover(self, smaller): wval, cval = self.current_cover_size ar = wval / cval delta = 0.2 * (-1 if smaller else 1) cval += delta cval = max(0, cval) self.opt_cover_grid_height.setValue(cval) self.opt_cover_grid_width.setValue(cval * ar) def cg_reset_size(self): self.opt_cover_grid_width.setValue(0) self.opt_cover_grid_height.setValue(0) def edit_cb_title_template(self): t = TemplateDialog(self, self.opt_cover_browser_title_template.text(), fm=self.gui.current_db.field_metadata) t.setWindowTitle(_('Edit template for caption')) if t.exec_(): self.opt_cover_browser_title_template.setText(t.rule[1]) def initialize(self): ConfigWidgetBase.initialize(self) self.default_author_link.value = default_author_link() font = gprefs['font'] if font is not None: font = list(font) font.append(gprefs.get('font_stretch', QFont.Stretch.Unstretched)) self.current_font = self.initial_font = font self.update_font_display() self.display_model.initialize() self.qv_display_model.initialize() db = self.gui.current_db try: idx = self.gui.library_view.currentIndex().row() mi = db.get_metadata(idx, index_is_id=False) except: mi = None self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules') self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules') self.grid_rules.initialize(db.field_metadata, db.prefs, mi, 'cover_grid_icon_rules') self.set_cg_color(gprefs['cover_grid_color']) self.set_cg_texture(gprefs['cover_grid_texture']) self.update_aspect_ratio() self.opt_book_details_css.blockSignals(True) self.opt_book_details_css.setPlainText( P('templates/book_details.css', data=True).decode('utf-8')) self.opt_book_details_css.blockSignals(False) self.tb_focus_label.setVisible( self.opt_tag_browser_allow_keyboard_focus.isChecked()) def open_cg_cache(self): open_local_file(self.gui.grid_view.thumbnail_cache.location) def update_cg_cache_size(self, size): self.cover_grid_current_disk_cache.setText( _('Current space used: %s') % human_readable(size)) def tab_changed(self, index): if self.tabWidget.currentWidget() is self.cover_grid_tab: self.show_current_cache_usage() def show_current_cache_usage(self): t = Thread(target=self.calc_cache_size) t.daemon = True t.start() def calc_cache_size(self): self.size_calculated.emit( self.gui.grid_view.thumbnail_cache.current_size) def set_cg_color(self, val): self.cg_bg_widget.bcol = QColor(*val) self.cg_bg_widget.update_brush() def set_cg_texture(self, val): self.cg_bg_widget.btex = val self.cg_bg_widget.update_brush() def empty_cache(self): self.gui.grid_view.thumbnail_cache.empty() self.calc_cache_size() def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) self.default_author_link.value = DEFAULT_AUTHOR_LINK ofont = self.current_font self.current_font = None if ofont is not None: self.changed_signal.emit() self.update_font_display() self.display_model.restore_defaults() self.qv_display_model.restore_defaults() self.edit_rules.clear() self.icon_rules.clear() self.grid_rules.clear() self.changed_signal.emit() self.set_cg_color(gprefs.defaults['cover_grid_color']) self.set_cg_texture(gprefs.defaults['cover_grid_texture']) self.opt_book_details_css.setPlainText( P('templates/book_details.css', allow_user_override=False, data=True).decode('utf-8')) def change_cover_grid_color(self): col = QColorDialog.getColor( self.cg_bg_widget.bcol, self.gui, _('Choose background color for the Cover grid')) if col.isValid(): col = tuple(col.getRgb())[:3] self.set_cg_color(col) self.changed_signal.emit() if self.cg_bg_widget.btex: if question_dialog( self, _('Remove background image?'), _('There is currently a background image set, so the color' ' you have chosen will not be visible. Remove the background image?' )): self.set_cg_texture(None) def change_cover_grid_texture(self): from calibre.gui2.preferences.texture_chooser import TextureChooser d = TextureChooser(parent=self, initial=self.cg_bg_widget.btex) if d.exec_() == QDialog.DialogCode.Accepted: self.set_cg_texture(d.texture) self.changed_signal.emit() def restore_cover_grid_appearance(self): self.set_cg_color(gprefs.defaults['cover_grid_color']) self.set_cg_texture(gprefs.defaults['cover_grid_texture']) self.changed_signal.emit() def build_font_obj(self): font_info = qt_app.original_font if self.current_font is None else self.current_font font = QFont(*(font_info[:4])) font.setStretch(font_info[4]) return font def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) name = str(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + ' [%dpt]' % fi.pointSize()) def change_font(self, *args): fd = QFontDialog(self.build_font_obj(), self) if fd.exec_() == QDialog.DialogCode.Accepted: font = fd.selectedFont() fi = QFontInfo(font) self.current_font = [ str(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch() ] self.update_font_display() self.changed_signal.emit() def commit(self, *args): with BusyCursor(): rr = ConfigWidgetBase.commit(self, *args) if self.current_font != self.initial_font: gprefs['font'] = (self.current_font[:4] if self.current_font else None) gprefs['font_stretch'] = (self.current_font[4] if self.current_font is not None else QFont.Stretch.Unstretched) QApplication.setFont(self.font_display.font()) rr = True self.display_model.commit() self.qv_display_model.commit() self.edit_rules.commit(self.gui.current_db.prefs) self.icon_rules.commit(self.gui.current_db.prefs) self.grid_rules.commit(self.gui.current_db.prefs) gprefs['cover_grid_color'] = tuple( self.cg_bg_widget.bcol.getRgb())[:3] gprefs['cover_grid_texture'] = self.cg_bg_widget.btex if self.commit_icon_theme is not None: self.commit_icon_theme() rr = True gprefs['default_author_link'] = self.default_author_link.value bcss = self.opt_book_details_css.toPlainText().encode('utf-8') defcss = P('templates/book_details.css', data=True, allow_user_override=False) if defcss == bcss: bcss = None set_data('templates/book_details.css', bcss) return rr def refresh_gui(self, gui): gui.book_details.book_info.refresh_css() m = gui.library_view.model() m.beginResetModel(), m.endResetModel() self.update_font_display() gui.tags_view.set_look_and_feel() gui.tags_view.reread_collapse_parameters() gui.library_view.refresh_book_details(force=True) gui.library_view.refresh_grid() gui.library_view.set_row_header_visibility() gui.cover_flow.setShowReflections(gprefs['cover_browser_reflections']) gui.cover_flow.setPreserveAspectRatio( gprefs['cb_preserve_aspect_ratio']) gui.cover_flow.setActivateOnDoubleClick( gprefs['cb_double_click_to_activate']) gui.update_cover_flow_subtitle_font() gui.cover_flow.template_inited = False for view in 'library memory card_a card_b'.split(): getattr(gui, view + '_view').set_row_header_visibility() gui.library_view.refresh_row_sizing() gui.grid_view.refresh_settings() gui.update_auto_scroll_timeout() qv = get_quickview_action_plugin() if qv: qv.refill_quickview()
def genesis(self, gui): self.gui = gui if not ismacos and not iswindows: self.label_widget_style.setVisible(False) self.opt_ui_style.setVisible(False) db = gui.library_view.model().db r = self.register try: self.icon_theme_title = json.loads(I('icon-theme.json', data=True))['name'] except Exception: self.icon_theme_title = _('Default icons') self.icon_theme.setText( _('Icon theme: <b>%s</b>') % self.icon_theme_title) self.commit_icon_theme = None self.icon_theme_button.clicked.connect(self.choose_icon_theme) self.default_author_link = DefaultAuthorLink( self.default_author_link_container) self.default_author_link.changed_signal.connect(self.changed_signal) r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('hidpi', gprefs, restart_required=True, choices=[(_('Automatic'), 'auto'), (_('On'), 'on'), (_('Off'), 'off')]) if ismacos: self.opt_hidpi.setVisible(False), self.label_hidpi.setVisible( False) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('dnd_merge', gprefs) r('wrap_toolbar_text', gprefs, restart_required=True) r('show_layout_buttons', gprefs, restart_required=True) r('row_numbers_in_book_list', gprefs) r('tag_browser_old_look', gprefs) r('tag_browser_hide_empty_categories', gprefs) r('tag_browser_always_autocollapse', gprefs) r('tag_browser_show_tooltips', gprefs) r('tag_browser_allow_keyboard_focus', gprefs) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size_multiple', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('tag_browser_show_counts', gprefs) r('tag_browser_item_padding', gprefs) r('books_autoscroll_time', gprefs) r('qv_respects_vls', gprefs) r('qv_dclick_changes_column', gprefs) r('qv_retkey_changes_column', gprefs) r('qv_follows_column', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('cover_browser_title_template', db.prefs) fm = db.field_metadata r('cover_browser_subtitle_field', db.prefs, choices=[(_('No subtitle'), 'none')] + sorted( (fm[k].get('name'), k) for k in fm.all_field_keys() if fm[k].get('name'))) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[(_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) r('booklist_grid', gprefs) r('book_details_comments_heading_pos', gprefs, choices=[(_('Never'), 'hide'), (_('Above text'), 'above'), (_('Beside text'), 'side')]) self.cover_browser_title_template_button.clicked.connect( self.edit_cb_title_template) self.id_links_button.clicked.connect(self.edit_id_link_rules) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(key=lambda x: x[1].lower()) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) r('cb_double_click_to_activate', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('tags_browser_collapse_fl_at', gprefs) choices = { k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False)) } choices |= {'search'} r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList, choices=sorted(choices, key=sort_key)) choices -= {'authors', 'publisher', 'formats', 'news', 'identifiers'} r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(choices, key=sort_key)) fm = db.field_metadata choices = sorted( ((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x: sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) connect_lambda( self.df_up_button.clicked, self, lambda self: move_field_up( self.field_display_order, self.display_model)) connect_lambda( self.df_down_button.clicked, self, lambda self: move_field_down( self.field_display_order, self.display_model)) self.qv_display_model = QVDisplayedFields(self.gui.current_db, self.qv_display_order) self.qv_display_model.dataChanged.connect(self.changed_signal) self.qv_display_order.setModel(self.qv_display_model) connect_lambda( self.qv_up_button.clicked, self, lambda self: move_field_up( self.qv_display_order, self.qv_display_model)) connect_lambda( self.qv_down_button.clicked, self, lambda self: move_field_down( self.qv_display_order, self.qv_display_model)) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column &coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column &icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [ QKeySequence('F11', QKeySequence.SequenceFormat.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.SequenceFormat.PortableText) ] keys = [ str(x.toString(QKeySequence.SequenceFormat.NativeText)) for x in keys ] self.fs_help_msg.setText( self.fs_help_msg.text() % (QKeySequence(QKeySequence.StandardKey.FullScreen).toString( QKeySequence.SequenceFormat.NativeText))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.ConnectionType.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton( _('Change &background image'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton( _('Restore default &appearance'), self) b.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) connect_lambda(self.cover_grid_smaller_cover.clicked, self, lambda self: self.resize_cover(True)) connect_lambda(self.cover_grid_larger_cover.clicked, self, lambda self: self.resize_cover(False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum( self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum( self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect( self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect( self.update_aspect_ratio) self.opt_book_details_css.textChanged.connect(self.changed_signal) from calibre.gui2.tweak_book.editor.text import get_highlighter, get_theme self.css_highlighter = get_highlighter('css')() self.css_highlighter.apply_theme(get_theme(None)) self.css_highlighter.set_document(self.opt_book_details_css.document())
class ConfigWidget(ConfigWidgetBase, Ui_Form): size_calculated = pyqtSignal(object) def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size_multiple', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('show_rating_in_cover_browser', gprefs) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[(_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) self.search_library_for_author_button.clicked.connect( lambda: self.opt_default_author_link.setText('search-calibre')) choices = set([ k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False)) ]) choices -= set( ['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) fm = db.field_metadata choices = sorted( ((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x: sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [ QKeySequence('F11', QKeySequence.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText) ] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText( unicode(self.fs_help_msg.text()) % (_(' or ').join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton( _('Change &background image'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton( _('Restore &default appearance'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) self.cover_grid_smaller_cover.clicked.connect( partial(self.resize_cover, True)) self.cover_grid_larger_cover.clicked.connect( partial(self.resize_cover, False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum( self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum( self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect( self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect( self.update_aspect_ratio) @property def current_cover_size(self): cval = self.opt_cover_grid_height.value() wval = self.opt_cover_grid_width.value() if cval < 0.1: dpi = self.opt_cover_grid_height.logicalDpiY() cval = auto_height(self.opt_cover_grid_height) / dpi / CM_TO_INCH if wval < 0.1: wval = 0.75 * cval return wval, cval def update_aspect_ratio(self, *args): width, height = self.current_cover_size ar = width / height self.cover_grid_aspect_ratio.setText( _('Current aspect ratio (width/height): %.2g') % ar) def resize_cover(self, smaller): wval, cval = self.current_cover_size ar = wval / cval delta = 0.2 * (-1 if smaller else 1) cval += delta cval = max(0, cval) self.opt_cover_grid_height.setValue(cval) self.opt_cover_grid_width.setValue(cval * ar) def cg_reset_size(self): self.opt_cover_grid_width.setValue(0) self.opt_cover_grid_height.setValue(0) def initialize(self): ConfigWidgetBase.initialize(self) font = gprefs['font'] if font is not None: font = list(font) font.append(gprefs.get('font_stretch', QFont.Unstretched)) self.current_font = self.initial_font = font self.update_font_display() self.display_model.initialize() db = self.gui.current_db try: idx = self.gui.library_view.currentIndex().row() mi = db.get_metadata(idx, index_is_id=False) except: mi = None self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules') self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules') self.grid_rules.initialize(db.field_metadata, db.prefs, mi, 'cover_grid_icon_rules') self.set_cg_color(gprefs['cover_grid_color']) self.set_cg_texture(gprefs['cover_grid_texture']) self.update_aspect_ratio() def open_cg_cache(self): open_local_file(self.gui.grid_view.thumbnail_cache.location) def update_cg_cache_size(self, size): self.cover_grid_current_disk_cache.setText( _('Current space used: %s') % human_readable(size)) def tab_changed(self, index): if self.tabWidget.currentWidget() is self.cover_grid_tab: self.show_current_cache_usage() def show_current_cache_usage(self): t = Thread(target=self.calc_cache_size) t.daemon = True t.start() def calc_cache_size(self): self.size_calculated.emit( self.gui.grid_view.thumbnail_cache.current_size) def set_cg_color(self, val): self.cg_bg_widget.bcol = QColor(*val) self.cg_bg_widget.update_brush() def set_cg_texture(self, val): self.cg_bg_widget.btex = val self.cg_bg_widget.update_brush() def empty_cache(self): self.gui.grid_view.thumbnail_cache.empty() self.calc_cache_size() def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) ofont = self.current_font self.current_font = None if ofont is not None: self.changed_signal.emit() self.update_font_display() self.display_model.restore_defaults() self.edit_rules.clear() self.icon_rules.clear() self.grid_rules.clear() self.changed_signal.emit() self.set_cg_color(gprefs.defaults['cover_grid_color']) self.set_cg_texture(gprefs.defaults['cover_grid_texture']) def change_cover_grid_color(self): col = QColorDialog.getColor( self.cg_bg_widget.bcol, self.gui, _('Choose background color for cover grid')) if col.isValid(): col = tuple(col.getRgb())[:3] self.set_cg_color(col) self.changed_signal.emit() if self.cg_bg_widget.btex: if question_dialog( self, _('Remove background image?'), _('There is currently a background image set, so the color' ' you have chosen will not be visible. Remove the background image?' )): self.set_cg_texture(None) def change_cover_grid_texture(self): from calibre.gui2.preferences.texture_chooser import TextureChooser d = TextureChooser(parent=self, initial=self.cg_bg_widget.btex) if d.exec_() == d.Accepted: self.set_cg_texture(d.texture) self.changed_signal.emit() def restore_cover_grid_appearance(self): self.set_cg_color(gprefs.defaults['cover_grid_color']) self.set_cg_texture(gprefs.defaults['cover_grid_texture']) self.changed_signal.emit() def build_font_obj(self): font_info = qt_app.original_font if self.current_font is None else self.current_font font = QFont(*(font_info[:4])) font.setStretch(font_info[4]) return font def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) name = unicode(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + ' [%dpt]' % fi.pointSize()) def move_df_up(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, -1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def move_df_down(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, 1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def change_font(self, *args): fd = QFontDialog(self.build_font_obj(), self) if fd.exec_() == fd.Accepted: font = fd.selectedFont() fi = QFontInfo(font) self.current_font = [ unicode(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch() ] self.update_font_display() self.changed_signal.emit() def commit(self, *args): rr = ConfigWidgetBase.commit(self, *args) if self.current_font != self.initial_font: gprefs['font'] = (self.current_font[:4] if self.current_font else None) gprefs['font_stretch'] = (self.current_font[4] if self.current_font is not None else QFont.Unstretched) QApplication.setFont(self.font_display.font()) rr = True self.display_model.commit() self.edit_rules.commit(self.gui.current_db.prefs) self.icon_rules.commit(self.gui.current_db.prefs) self.grid_rules.commit(self.gui.current_db.prefs) gprefs['cover_grid_color'] = tuple(self.cg_bg_widget.bcol.getRgb())[:3] gprefs['cover_grid_texture'] = self.cg_bg_widget.btex return rr def refresh_gui(self, gui): m = gui.library_view.model() m.beginResetModel(), m.endResetModel() self.update_font_display() gui.tags_view.reread_collapse_parameters() gui.library_view.refresh_book_details() if hasattr(gui.cover_flow, 'setShowReflections'): gui.cover_flow.setShowReflections( gprefs['cover_browser_reflections']) gui.cover_flow.setPreserveAspectRatio( gprefs['cb_preserve_aspect_ratio']) gui.library_view.refresh_row_sizing() gui.grid_view.refresh_settings()
def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size_multiple', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('show_rating_in_cover_browser', gprefs) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[(_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) self.search_library_for_author_button.clicked.connect( lambda: self.opt_default_author_link.setText('search-calibre')) choices = set([ k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False)) ]) choices -= set( ['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) fm = db.field_metadata choices = sorted( ((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x: sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [ QKeySequence('F11', QKeySequence.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText) ] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText( unicode(self.fs_help_msg.text()) % (_(' or ').join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton( _('Change &background image'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton( _('Restore &default appearance'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) self.cover_grid_smaller_cover.clicked.connect( partial(self.resize_cover, True)) self.cover_grid_larger_cover.clicked.connect( partial(self.resize_cover, False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum( self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum( self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect( self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect( self.update_aspect_ratio)
def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r("gui_layout", config, restart_required=True, choices=[(_("Wide"), "wide"), (_("Narrow"), "narrow")]) r( "ui_style", gprefs, restart_required=True, choices=[(_("System default"), "system"), (_("Calibre style"), "calibre")], ) r("book_list_tooltips", gprefs) r("tag_browser_old_look", gprefs, restart_required=True) r("bd_show_cover", gprefs) r("bd_overlay_cover_size", gprefs) r("cover_grid_width", gprefs) r("cover_grid_height", gprefs) r("cover_grid_cache_size", gprefs) r("cover_grid_spacing", gprefs) r("cover_grid_show_title", gprefs) r("cover_flow_queue_length", config, restart_required=True) r("cover_browser_reflections", gprefs) r("extra_row_spacing", gprefs) def get_esc_lang(l): if l == "en": return "English" return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = "en" items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != "en": items.append(("en", get_esc_lang("en"))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r("language", prefs, choices=choices, restart_required=True) r("show_avg_rating", config) r("disable_animations", config) r("systray_icon", config, restart_required=True) r("show_splash_screen", gprefs) r("disable_tray_notification", config) r("use_roman_numerals_for_series_number", config) r("separate_cover_flow", config, restart_required=True) r("cb_fullscreen", gprefs) choices = [(_("Off"), "off"), (_("Small"), "small"), (_("Medium"), "medium"), (_("Large"), "large")] r("toolbar_icon_size", gprefs, choices=choices) choices = [(_("If there is enough room"), "auto"), (_("Always"), "always"), (_("Never"), "never")] r("toolbar_text", gprefs, choices=choices) choices = [(_("Disabled"), "disable"), (_("By first letter"), "first letter"), (_("Partitioned"), "partition")] r("tags_browser_partition_method", gprefs, choices=choices) r("tags_browser_collapse_at", gprefs) r("default_author_link", gprefs) r("tag_browser_dont_collapse", gprefs, setting=CommaSeparatedList) choices = set( [ k for k in db.field_metadata.all_field_keys() if ( db.field_metadata[k]["is_category"] and (db.field_metadata[k]["datatype"] in ["text", "series", "enumeration"]) and not db.field_metadata[k]["display"].get("is_names", False) ) or ( db.field_metadata[k]["datatype"] in ["composite"] and db.field_metadata[k]["display"].get("make_category", False) ) ] ) choices -= set(["authors", "publisher", "formats", "news", "identifiers"]) choices |= set(["search"]) self.opt_categories_using_hierarchy.update_items_cache(choices) r( "categories_using_hierarchy", db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key), ) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I("format-fill-color.png")), _("Column coloring")) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I("icon_choose.png")), _("Column icons")) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence("F11", QKeySequence.PortableText), QKeySequence("Ctrl+Shift+F", QKeySequence.PortableText)] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode(self.fs_help_msg.text()) % (_(" or ").join(keys))) self.cover_grid_color_button.clicked.connect(self.change_cover_grid_color) if not tweaks.get("use_new_db", False): for i in range(self.tabWidget.count()): if self.tabWidget.widget(i) is self.cover_grid_tab: self.tabWidget.removeTab(i)
def genesis(self, gui): self.gui = gui if not isosx and not iswindows: self.label_widget_style.setVisible(False) self.opt_ui_style.setVisible(False) db = gui.library_view.model().db r = self.register try: self.icon_theme_title = json.loads(I('icon-theme.json', data=True))['name'] except Exception: self.icon_theme_title = _('Default icons') self.icon_theme.setText(_('Icon theme: <b>%s</b>') % self.icon_theme_title) self.commit_icon_theme = None self.icon_theme_button.clicked.connect(self.choose_icon_theme) self.default_author_link = DefaultAuthorLink(self.default_author_link_container) self.default_author_link.changed_signal.connect(self.changed_signal) r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('hidpi', gprefs, restart_required=True, choices=[(_('Automatic'), 'auto'), (_('On'), 'on'), (_('Off'), 'off')]) if isosx: self.opt_hidpi.setVisible(False), self.label_hidpi.setVisible(False) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('show_layout_buttons', gprefs, restart_required=True) r('row_numbers_in_book_list', gprefs) r('tag_browser_old_look', gprefs) r('tag_browser_hide_empty_categories', gprefs) r('tag_browser_show_tooltips', gprefs) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size_multiple', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('tag_browser_show_counts', gprefs) r('tag_browser_item_padding', gprefs) r('qv_respects_vls', gprefs) r('qv_dclick_changes_column', gprefs) r('qv_retkey_changes_column', gprefs) r('qv_follows_column', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('cover_browser_title_template', db.prefs) fm = db.field_metadata r('cover_browser_subtitle_field', db.prefs, choices=[(_('No subtitle'), 'none')] + sorted( (fm[k].get('name'), k) for k in fm.all_field_keys() if fm[k].get('name') )) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[ (_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) r('book_details_narrow_comments_layout', gprefs, choices=[(_('Float'), 'float'), (_('Columns'), 'columns')]) self.opt_book_details_narrow_comments_layout.setToolTip(textwrap.fill(_( 'Choose how the text is laid out when using the "Narrow" user interface layout.' ' A value of "Float" means that the comments text will wrap around' ' the other metadata fields, while a value of "Columns" means that' ' the comments will be in a separate fixed width column.'))) self.cover_browser_title_template_button.clicked.connect(self.edit_cb_title_template) self.id_links_button.clicked.connect(self.edit_id_link_rules) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) choices = set([k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False))]) choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) fm = db.field_metadata choices = sorted(((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x:sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(partial(move_field_up, self.field_display_order, self.display_model)) self.df_down_button.clicked.connect(partial(move_field_down, self.field_display_order, self.display_model)) self.qv_display_model = QVDisplayedFields(self.gui.current_db, self.qv_display_order) self.qv_display_model.dataChanged.connect(self.changed_signal) self.qv_display_order.setModel(self.qv_display_model) self.qv_up_button.clicked.connect(partial(move_field_up, self.qv_display_order, self.qv_display_model)) self.qv_down_button.clicked.connect(partial(move_field_down, self.qv_display_order, self.qv_display_model)) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column &coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column &icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence('F11', QKeySequence.PortableText), QKeySequence( 'Ctrl+Shift+F', QKeySequence.PortableText)] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%( _(' or ').join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton(_('Change &background image'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton(_('Restore &default appearance'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) self.cover_grid_smaller_cover.clicked.connect(partial(self.resize_cover, True)) self.cover_grid_larger_cover.clicked.connect(partial(self.resize_cover, False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum(self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum(self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect(self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect(self.update_aspect_ratio)
class ConfigWidget(ConfigWidgetBase, Ui_Form): size_calculated = pyqtSignal(object) def genesis(self, gui): self.gui = gui if not isosx and not iswindows: self.label_widget_style.setVisible(False) self.opt_ui_style.setVisible(False) db = gui.library_view.model().db r = self.register try: self.icon_theme_title = json.loads(I('icon-theme.json', data=True))['name'] except Exception: self.icon_theme_title = _('Default icons') self.icon_theme.setText(_('Icon theme: <b>%s</b>') % self.icon_theme_title) self.commit_icon_theme = None self.icon_theme_button.clicked.connect(self.choose_icon_theme) self.default_author_link = DefaultAuthorLink(self.default_author_link_container) self.default_author_link.changed_signal.connect(self.changed_signal) r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('hidpi', gprefs, restart_required=True, choices=[(_('Automatic'), 'auto'), (_('On'), 'on'), (_('Off'), 'off')]) if isosx: self.opt_hidpi.setVisible(False), self.label_hidpi.setVisible(False) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('dnd_merge', gprefs) r('wrap_toolbar_text', gprefs, restart_required=True) r('show_layout_buttons', gprefs, restart_required=True) r('row_numbers_in_book_list', gprefs) r('tag_browser_old_look', gprefs) r('tag_browser_hide_empty_categories', gprefs) r('tag_browser_show_tooltips', gprefs) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) r('cover_grid_height', gprefs) r('cover_grid_cache_size_multiple', gprefs) r('cover_grid_disk_cache_size', gprefs) r('cover_grid_spacing', gprefs) r('cover_grid_show_title', gprefs) r('tag_browser_show_counts', gprefs) r('tag_browser_item_padding', gprefs) r('qv_respects_vls', gprefs) r('qv_dclick_changes_column', gprefs) r('qv_retkey_changes_column', gprefs) r('qv_follows_column', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) r('cover_browser_title_template', db.prefs) fm = db.field_metadata r('cover_browser_subtitle_field', db.prefs, choices=[(_('No subtitle'), 'none')] + sorted( (fm[k].get('name'), k) for k in fm.all_field_keys() if fm[k].get('name') )) r('emblem_size', gprefs) r('emblem_position', gprefs, choices=[ (_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')]) r('book_list_extra_row_spacing', gprefs) r('booklist_grid', gprefs) r('book_details_narrow_comments_layout', gprefs, choices=[(_('Float'), 'float'), (_('Columns'), 'columns')]) self.opt_book_details_narrow_comments_layout.setToolTip(textwrap.fill(_( 'Choose how the text is laid out when using the "Narrow" user interface layout.' ' A value of "Float" means that the comments text will wrap around' ' the other metadata fields, while a value of "Columns" means that' ' the comments will be in a separate fixed width column.'))) self.cover_browser_title_template_button.clicked.connect(self.edit_cb_title_template) self.id_links_button.clicked.connect(self.edit_id_link_rules) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(key=lambda x: x[1].lower()) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) r('cb_preserve_aspect_ratio', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) choices = {k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and ( db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration' ]) and not db.field_metadata[k]['display'].get('is_names', False)) or ( db.field_metadata[k]['datatype'] in ['composite' ] and db.field_metadata[k]['display'].get('make_category', False))} choices -= {'authors', 'publisher', 'formats', 'news', 'identifiers'} choices |= {'search'} self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) fm = db.field_metadata choices = sorted(((fm[k]['name'], k) for k in fm.displayable_field_keys() if fm[k]['name']), key=lambda x:sort_key(x[0])) r('field_under_covers_in_grid', db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) connect_lambda(self.df_up_button.clicked, self, lambda self: move_field_up(self.field_display_order, self.display_model)) connect_lambda(self.df_down_button.clicked, self, lambda self: move_field_down(self.field_display_order, self.display_model)) self.qv_display_model = QVDisplayedFields(self.gui.current_db, self.qv_display_order) self.qv_display_model.dataChanged.connect(self.changed_signal) self.qv_display_order.setModel(self.qv_display_model) connect_lambda(self.qv_up_button.clicked, self, lambda self: move_field_up(self.qv_display_order, self.qv_display_model)) connect_lambda(self.qv_down_button.clicked, self, lambda self: move_field_down(self.qv_display_order, self.qv_display_model)) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column &coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column &icons')) self.grid_rules = EditRules(self.emblems_tab) self.grid_rules.changed.connect(self.changed_signal) self.emblems_tab.setLayout(QVBoxLayout()) self.emblems_tab.layout().addWidget(self.grid_rules) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence('F11', QKeySequence.PortableText), QKeySequence( 'Ctrl+Shift+F', QKeySequence.PortableText)] keys = [unicode_type(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode_type(self.fs_help_msg.text())%( _(' or ').join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_('Change &color'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton(_('Change &background image'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton(_('Restore &default appearance'), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) connect_lambda(self.cover_grid_smaller_cover.clicked, self, lambda self: self.resize_cover(True)) connect_lambda(self.cover_grid_larger_cover.clicked, self, lambda self: self.resize_cover(False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum(self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum(self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect(self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect(self.update_aspect_ratio) def choose_icon_theme(self): from calibre.gui2.icon_theme import ChooseTheme d = ChooseTheme(self) if d.exec_() == d.Accepted: self.commit_icon_theme = d.commit_changes self.icon_theme_title = d.new_theme_title or _('Default icons') self.icon_theme.setText(_('Icon theme: <b>%s</b>') % self.icon_theme_title) self.changed_signal.emit() def edit_id_link_rules(self): if IdLinksEditor(self).exec_() == Dialog.Accepted: self.changed_signal.emit() @property def current_cover_size(self): cval = self.opt_cover_grid_height.value() wval = self.opt_cover_grid_width.value() if cval < 0.1: dpi = self.opt_cover_grid_height.logicalDpiY() cval = auto_height(self.opt_cover_grid_height) / dpi / CM_TO_INCH if wval < 0.1: wval = 0.75 * cval return wval, cval def update_aspect_ratio(self, *args): width, height = self.current_cover_size ar = width / height self.cover_grid_aspect_ratio.setText(_('Current aspect ratio (width/height): %.2g') % ar) def resize_cover(self, smaller): wval, cval = self.current_cover_size ar = wval / cval delta = 0.2 * (-1 if smaller else 1) cval += delta cval = max(0, cval) self.opt_cover_grid_height.setValue(cval) self.opt_cover_grid_width.setValue(cval * ar) def cg_reset_size(self): self.opt_cover_grid_width.setValue(0) self.opt_cover_grid_height.setValue(0) def edit_cb_title_template(self): t = TemplateDialog(self, self.opt_cover_browser_title_template.text(), fm=self.gui.current_db.field_metadata) t.setWindowTitle(_('Edit template for caption')) if t.exec_(): self.opt_cover_browser_title_template.setText(t.rule[1]) def initialize(self): ConfigWidgetBase.initialize(self) self.default_author_link.value = default_author_link() font = gprefs['font'] if font is not None: font = list(font) font.append(gprefs.get('font_stretch', QFont.Unstretched)) self.current_font = self.initial_font = font self.update_font_display() self.display_model.initialize() self.qv_display_model.initialize() db = self.gui.current_db try: idx = self.gui.library_view.currentIndex().row() mi = db.get_metadata(idx, index_is_id=False) except: mi=None self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules') self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules') self.grid_rules.initialize(db.field_metadata, db.prefs, mi, 'cover_grid_icon_rules') self.set_cg_color(gprefs['cover_grid_color']) self.set_cg_texture(gprefs['cover_grid_texture']) self.update_aspect_ratio() def open_cg_cache(self): open_local_file(self.gui.grid_view.thumbnail_cache.location) def update_cg_cache_size(self, size): self.cover_grid_current_disk_cache.setText( _('Current space used: %s') % human_readable(size)) def tab_changed(self, index): if self.tabWidget.currentWidget() is self.cover_grid_tab: self.show_current_cache_usage() def show_current_cache_usage(self): t = Thread(target=self.calc_cache_size) t.daemon = True t.start() def calc_cache_size(self): self.size_calculated.emit(self.gui.grid_view.thumbnail_cache.current_size) def set_cg_color(self, val): self.cg_bg_widget.bcol = QColor(*val) self.cg_bg_widget.update_brush() def set_cg_texture(self, val): self.cg_bg_widget.btex = val self.cg_bg_widget.update_brush() def empty_cache(self): self.gui.grid_view.thumbnail_cache.empty() self.calc_cache_size() def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) self.default_author_link.value = DEFAULT_AUTHOR_LINK ofont = self.current_font self.current_font = None if ofont is not None: self.changed_signal.emit() self.update_font_display() self.display_model.restore_defaults() self.qv_display_model.restore_defaults() self.edit_rules.clear() self.icon_rules.clear() self.grid_rules.clear() self.changed_signal.emit() self.set_cg_color(gprefs.defaults['cover_grid_color']) self.set_cg_texture(gprefs.defaults['cover_grid_texture']) def change_cover_grid_color(self): col = QColorDialog.getColor(self.cg_bg_widget.bcol, self.gui, _('Choose background color for the Cover grid')) if col.isValid(): col = tuple(col.getRgb())[:3] self.set_cg_color(col) self.changed_signal.emit() if self.cg_bg_widget.btex: if question_dialog( self, _('Remove background image?'), _('There is currently a background image set, so the color' ' you have chosen will not be visible. Remove the background image?')): self.set_cg_texture(None) def change_cover_grid_texture(self): from calibre.gui2.preferences.texture_chooser import TextureChooser d = TextureChooser(parent=self, initial=self.cg_bg_widget.btex) if d.exec_() == d.Accepted: self.set_cg_texture(d.texture) self.changed_signal.emit() def restore_cover_grid_appearance(self): self.set_cg_color(gprefs.defaults['cover_grid_color']) self.set_cg_texture(gprefs.defaults['cover_grid_texture']) self.changed_signal.emit() def build_font_obj(self): font_info = qt_app.original_font if self.current_font is None else self.current_font font = QFont(*(font_info[:4])) font.setStretch(font_info[4]) return font def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) name = unicode_type(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + ' [%dpt]'%fi.pointSize()) def change_font(self, *args): fd = QFontDialog(self.build_font_obj(), self) if fd.exec_() == fd.Accepted: font = fd.selectedFont() fi = QFontInfo(font) self.current_font = [unicode_type(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch()] self.update_font_display() self.changed_signal.emit() def commit(self, *args): with BusyCursor(): rr = ConfigWidgetBase.commit(self, *args) if self.current_font != self.initial_font: gprefs['font'] = (self.current_font[:4] if self.current_font else None) gprefs['font_stretch'] = (self.current_font[4] if self.current_font is not None else QFont.Unstretched) QApplication.setFont(self.font_display.font()) rr = True self.display_model.commit() self.qv_display_model.commit() self.edit_rules.commit(self.gui.current_db.prefs) self.icon_rules.commit(self.gui.current_db.prefs) self.grid_rules.commit(self.gui.current_db.prefs) gprefs['cover_grid_color'] = tuple(self.cg_bg_widget.bcol.getRgb())[:3] gprefs['cover_grid_texture'] = self.cg_bg_widget.btex if self.commit_icon_theme is not None: self.commit_icon_theme() rr = True gprefs['default_author_link'] = self.default_author_link.value return rr def refresh_gui(self, gui): m = gui.library_view.model() m.beginResetModel(), m.endResetModel() self.update_font_display() gui.tags_view.set_look_and_feel() gui.tags_view.reread_collapse_parameters() gui.library_view.refresh_book_details() gui.library_view.refresh_grid() gui.library_view.set_row_header_visibility() gui.cover_flow.setShowReflections(gprefs['cover_browser_reflections']) gui.cover_flow.setPreserveAspectRatio(gprefs['cb_preserve_aspect_ratio']) gui.update_cover_flow_subtitle_font() gui.cover_flow.template_inited = False for view in 'library memory card_a card_b'.split(): getattr(gui, view + '_view').set_row_header_visibility() gui.library_view.refresh_row_sizing() gui.grid_view.refresh_settings() qv = get_quickview_action_plugin() if qv: qv.refill_quickview()
class ConfigWidget(ConfigWidgetBase, Ui_Form): def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r("gui_layout", config, restart_required=True, choices=[(_("Wide"), "wide"), (_("Narrow"), "narrow")]) r( "ui_style", gprefs, restart_required=True, choices=[(_("System default"), "system"), (_("Calibre style"), "calibre")], ) r("book_list_tooltips", gprefs) r("tag_browser_old_look", gprefs, restart_required=True) r("bd_show_cover", gprefs) r("bd_overlay_cover_size", gprefs) r("cover_grid_width", gprefs) r("cover_grid_height", gprefs) r("cover_grid_cache_size", gprefs) r("cover_grid_spacing", gprefs) r("cover_grid_show_title", gprefs) r("cover_flow_queue_length", config, restart_required=True) r("cover_browser_reflections", gprefs) r("extra_row_spacing", gprefs) def get_esc_lang(l): if l == "en": return "English" return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = "en" items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != "en": items.append(("en", get_esc_lang("en"))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r("language", prefs, choices=choices, restart_required=True) r("show_avg_rating", config) r("disable_animations", config) r("systray_icon", config, restart_required=True) r("show_splash_screen", gprefs) r("disable_tray_notification", config) r("use_roman_numerals_for_series_number", config) r("separate_cover_flow", config, restart_required=True) r("cb_fullscreen", gprefs) choices = [(_("Off"), "off"), (_("Small"), "small"), (_("Medium"), "medium"), (_("Large"), "large")] r("toolbar_icon_size", gprefs, choices=choices) choices = [(_("If there is enough room"), "auto"), (_("Always"), "always"), (_("Never"), "never")] r("toolbar_text", gprefs, choices=choices) choices = [(_("Disabled"), "disable"), (_("By first letter"), "first letter"), (_("Partitioned"), "partition")] r("tags_browser_partition_method", gprefs, choices=choices) r("tags_browser_collapse_at", gprefs) r("default_author_link", gprefs) r("tag_browser_dont_collapse", gprefs, setting=CommaSeparatedList) choices = set( [ k for k in db.field_metadata.all_field_keys() if ( db.field_metadata[k]["is_category"] and (db.field_metadata[k]["datatype"] in ["text", "series", "enumeration"]) and not db.field_metadata[k]["display"].get("is_names", False) ) or ( db.field_metadata[k]["datatype"] in ["composite"] and db.field_metadata[k]["display"].get("make_category", False) ) ] ) choices -= set(["authors", "publisher", "formats", "news", "identifiers"]) choices |= set(["search"]) self.opt_categories_using_hierarchy.update_items_cache(choices) r( "categories_using_hierarchy", db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key), ) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I("format-fill-color.png")), _("Column coloring")) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I("icon_choose.png")), _("Column icons")) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence("F11", QKeySequence.PortableText), QKeySequence("Ctrl+Shift+F", QKeySequence.PortableText)] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode(self.fs_help_msg.text()) % (_(" or ").join(keys))) self.cover_grid_color_button.clicked.connect(self.change_cover_grid_color) if not tweaks.get("use_new_db", False): for i in range(self.tabWidget.count()): if self.tabWidget.widget(i) is self.cover_grid_tab: self.tabWidget.removeTab(i) def initialize(self): ConfigWidgetBase.initialize(self) font = gprefs["font"] if font is not None: font = list(font) font.append(gprefs.get("font_stretch", QFont.Unstretched)) self.current_font = self.initial_font = font self.update_font_display() self.display_model.initialize() db = self.gui.current_db try: idx = self.gui.library_view.currentIndex().row() mi = db.get_metadata(idx, index_is_id=False) except: mi = None self.edit_rules.initialize(db.field_metadata, db.prefs, mi, "column_color_rules") self.icon_rules.initialize(db.field_metadata, db.prefs, mi, "column_icon_rules") self.set_cg_color(gprefs["cover_grid_color"]) def set_cg_color(self, val): pal = QPalette() pal.setColor(QPalette.Window, QColor(*val)) self.cover_grid_color_label.setPalette(pal) def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) ofont = self.current_font self.current_font = None if ofont is not None: self.changed_signal.emit() self.update_font_display() self.display_model.restore_defaults() self.edit_rules.clear() self.icon_rules.clear() self.changed_signal.emit() self.set_cg_color(gprefs.defaults["cover_grid_color"]) def change_cover_grid_color(self): col = QColorDialog.getColor( self.cover_grid_color_label.palette().color(QPalette.Window), self.gui, _("Choose background color for cover grid"), ) if col.isValid(): col = tuple(col.getRgb())[:3] self.set_cg_color(col) self.changed_signal.emit() def build_font_obj(self): font_info = self.current_font if font_info is not None: font = QFont(*(font_info[:4])) font.setStretch(font_info[4]) else: font = qt_app.original_font return font def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) name = unicode(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + " [%dpt]" % fi.pointSize()) def move_df_up(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, -1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def move_df_down(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, 1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def change_font(self, *args): fd = QFontDialog(self.build_font_obj(), self) if fd.exec_() == fd.Accepted: font = fd.selectedFont() fi = QFontInfo(font) self.current_font = [unicode(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch()] self.update_font_display() self.changed_signal.emit() def commit(self, *args): rr = ConfigWidgetBase.commit(self, *args) if self.current_font != self.initial_font: gprefs["font"] = self.current_font[:4] if self.current_font else None gprefs["font_stretch"] = self.current_font[4] if self.current_font is not None else QFont.Unstretched QApplication.setFont(self.font_display.font()) rr = True self.display_model.commit() self.edit_rules.commit(self.gui.current_db.prefs) self.icon_rules.commit(self.gui.current_db.prefs) gprefs["cover_grid_color"] = tuple(self.cover_grid_color_label.palette().color(QPalette.Window).getRgb())[:3] return rr def refresh_gui(self, gui): gui.library_view.model().reset() self.update_font_display() gui.tags_view.reread_collapse_parameters() gui.library_view.refresh_book_details() if hasattr(gui.cover_flow, "setShowReflections"): gui.cover_flow.setShowReflections(gprefs["cover_browser_reflections"]) gui.library_view.refresh_row_sizing() gui.grid_view.refresh_settings()
def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('cover_flow_queue_length', config, restart_required=True) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() \ if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) choices = set([ k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False)) ]) choices -= set( ['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.tabWidget.setCurrentIndex(0) keys = [ QKeySequence('F11', QKeySequence.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText) ] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText( unicode(self.fs_help_msg.text()) % (_(' or ').join(keys)))
class ConfigWidget(ConfigWidgetBase, Ui_Form): def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices=[(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices=[(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('cover_flow_queue_length', config, restart_required=True) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() \ if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) choices = set([ k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False)) ]) choices -= set( ['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.tabWidget.setCurrentIndex(0) keys = [ QKeySequence('F11', QKeySequence.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText) ] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText( unicode(self.fs_help_msg.text()) % (_(' or ').join(keys))) def initialize(self): ConfigWidgetBase.initialize(self) font = gprefs['font'] if font is not None: font = list(font) font.append(gprefs.get('font_stretch', QFont.Unstretched)) self.current_font = self.initial_font = font self.update_font_display() self.display_model.initialize() db = self.gui.current_db try: idx = self.gui.library_view.currentIndex().row() mi = db.get_metadata(idx, index_is_id=False) except: mi = None self.edit_rules.initialize(db.field_metadata, db.prefs, mi) def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) ofont = self.current_font self.current_font = None if ofont is not None: self.changed_signal.emit() self.update_font_display() self.display_model.restore_defaults() self.edit_rules.clear() self.changed_signal.emit() def build_font_obj(self): font_info = self.current_font if font_info is not None: font = QFont(*(font_info[:4])) font.setStretch(font_info[4]) else: font = qt_app.original_font return font def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) name = unicode(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + ' [%dpt]' % fi.pointSize()) def move_df_up(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, -1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def move_df_down(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, 1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def change_font(self, *args): fd = QFontDialog(self.build_font_obj(), self) if fd.exec_() == fd.Accepted: font = fd.selectedFont() fi = QFontInfo(font) self.current_font = [ unicode(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch() ] self.update_font_display() self.changed_signal.emit() def commit(self, *args): rr = ConfigWidgetBase.commit(self, *args) if self.current_font != self.initial_font: gprefs['font'] = (self.current_font[:4] if self.current_font else None) gprefs['font_stretch'] = (self.current_font[4] if self.current_font is not None else QFont.Unstretched) QApplication.setFont(self.font_display.font()) rr = True self.display_model.commit() self.edit_rules.commit(self.gui.current_db.prefs) return rr def refresh_gui(self, gui): gui.library_view.model().reset() self.update_font_display() gui.tags_view.reread_collapse_parameters() gui.library_view.refresh_book_details()
def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices= [(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices= [(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() \ if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) choices = set([k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False))]) choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column icons')) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence('F11', QKeySequence.PortableText), QKeySequence( 'Ctrl+Shift+F', QKeySequence.PortableText)] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%( _(' or ').join(keys)))
class ConfigWidget(ConfigWidgetBase, Ui_Form): def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r('gui_layout', config, restart_required=True, choices= [(_('Wide'), 'wide'), (_('Narrow'), 'narrow')]) r('ui_style', gprefs, restart_required=True, choices= [(_('System default'), 'system'), (_('Calibre style'), 'calibre')]) r('book_list_tooltips', gprefs) r('tag_browser_old_look', gprefs, restart_required=True) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_flow_queue_length', config, restart_required=True) r('cover_browser_reflections', gprefs) def get_esc_lang(l): if l == 'en': return 'English' return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = 'en' items = [(l, get_esc_lang(l)) for l in available_translations() \ if l != lang] if lang != 'en': items.append(('en', get_esc_lang('en'))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r('language', prefs, choices=choices, restart_required=True) r('show_avg_rating', config) r('disable_animations', config) r('systray_icon', config, restart_required=True) r('show_splash_screen', gprefs) r('disable_tray_notification', config) r('use_roman_numerals_for_series_number', config) r('separate_cover_flow', config, restart_required=True) r('cb_fullscreen', gprefs) choices = [(_('Off'), 'off'), (_('Small'), 'small'), (_('Medium'), 'medium'), (_('Large'), 'large')] r('toolbar_icon_size', gprefs, choices=choices) choices = [(_('If there is enough room'), 'auto'), (_('Always'), 'always'), (_('Never'), 'never')] r('toolbar_text', gprefs, choices=choices) choices = [(_('Disabled'), 'disable'), (_('By first letter'), 'first letter'), (_('Partitioned'), 'partition')] r('tags_browser_partition_method', gprefs, choices=choices) r('tags_browser_collapse_at', gprefs) r('default_author_link', gprefs) r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList) choices = set([k for k in db.field_metadata.all_field_keys() if (db.field_metadata[k]['is_category'] and (db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and not db.field_metadata[k]['display'].get('is_names', False)) or (db.field_metadata[k]['datatype'] in ['composite'] and db.field_metadata[k]['display'].get('make_category', False))]) choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers']) choices |= set(['search']) self.opt_categories_using_hierarchy.update_items_cache(choices) r('categories_using_hierarchy', db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key)) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I('format-fill-color.png')), _('Column coloring')) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I('icon_choose.png')), _('Column icons')) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence('F11', QKeySequence.PortableText), QKeySequence( 'Ctrl+Shift+F', QKeySequence.PortableText)] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%( _(' or ').join(keys))) def initialize(self): ConfigWidgetBase.initialize(self) font = gprefs['font'] if font is not None: font = list(font) font.append(gprefs.get('font_stretch', QFont.Unstretched)) self.current_font = self.initial_font = font self.update_font_display() self.display_model.initialize() db = self.gui.current_db try: idx = self.gui.library_view.currentIndex().row() mi = db.get_metadata(idx, index_is_id=False) except: mi=None self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules') self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules') def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) ofont = self.current_font self.current_font = None if ofont is not None: self.changed_signal.emit() self.update_font_display() self.display_model.restore_defaults() self.edit_rules.clear() self.icon_rules.clear() self.changed_signal.emit() def build_font_obj(self): font_info = self.current_font if font_info is not None: font = QFont(*(font_info[:4])) font.setStretch(font_info[4]) else: font = qt_app.original_font return font def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) name = unicode(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + ' [%dpt]'%fi.pointSize()) def move_df_up(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, -1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def move_df_down(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, 1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def change_font(self, *args): fd = QFontDialog(self.build_font_obj(), self) if fd.exec_() == fd.Accepted: font = fd.selectedFont() fi = QFontInfo(font) self.current_font = [unicode(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch()] self.update_font_display() self.changed_signal.emit() def commit(self, *args): rr = ConfigWidgetBase.commit(self, *args) if self.current_font != self.initial_font: gprefs['font'] = (self.current_font[:4] if self.current_font else None) gprefs['font_stretch'] = (self.current_font[4] if self.current_font is not None else QFont.Unstretched) QApplication.setFont(self.font_display.font()) rr = True self.display_model.commit() self.edit_rules.commit(self.gui.current_db.prefs) self.icon_rules.commit(self.gui.current_db.prefs) return rr def refresh_gui(self, gui): gui.library_view.model().reset() self.update_font_display() gui.tags_view.reread_collapse_parameters() gui.library_view.refresh_book_details() if hasattr(gui.cover_flow, 'setShowReflections'): gui.cover_flow.setShowReflections(gprefs['cover_browser_reflections'])
class ConfigWidget(ConfigWidgetBase, Ui_Form): size_calculated = pyqtSignal(object) def genesis(self, gui): self.gui = gui db = gui.library_view.model().db r = self.register r("gui_layout", config, restart_required=True, choices=[(_("Wide"), "wide"), (_("Narrow"), "narrow")]) r( "ui_style", gprefs, restart_required=True, choices=[(_("System default"), "system"), (_("Calibre style"), "calibre")], ) r("book_list_tooltips", gprefs) r("tag_browser_old_look", gprefs, restart_required=True) r("bd_show_cover", gprefs) r("bd_overlay_cover_size", gprefs) r("cover_grid_width", gprefs) r("cover_grid_height", gprefs) r("cover_grid_cache_size", gprefs) r("cover_grid_disk_cache_size", gprefs) r("cover_grid_spacing", gprefs) r("cover_grid_show_title", gprefs) r("cover_flow_queue_length", config, restart_required=True) r("cover_browser_reflections", gprefs) r("extra_row_spacing", gprefs) def get_esc_lang(l): if l == "en": return "English" return get_language(l) lang = get_lang() if lang is None or lang not in available_translations(): lang = "en" items = [(l, get_esc_lang(l)) for l in available_translations() if l != lang] if lang != "en": items.append(("en", get_esc_lang("en"))) items.sort(cmp=lambda x, y: cmp(x[1].lower(), y[1].lower())) choices = [(y, x) for x, y in items] # Default language is the autodetected one choices = [(get_language(lang), lang)] + choices r("language", prefs, choices=choices, restart_required=True) r("show_avg_rating", config) r("disable_animations", config) r("systray_icon", config, restart_required=True) r("show_splash_screen", gprefs) r("disable_tray_notification", config) r("use_roman_numerals_for_series_number", config) r("separate_cover_flow", config, restart_required=True) r("cb_fullscreen", gprefs) choices = [(_("Off"), "off"), (_("Small"), "small"), (_("Medium"), "medium"), (_("Large"), "large")] r("toolbar_icon_size", gprefs, choices=choices) choices = [(_("If there is enough room"), "auto"), (_("Always"), "always"), (_("Never"), "never")] r("toolbar_text", gprefs, choices=choices) choices = [(_("Disabled"), "disable"), (_("By first letter"), "first letter"), (_("Partitioned"), "partition")] r("tags_browser_partition_method", gprefs, choices=choices) r("tags_browser_collapse_at", gprefs) r("default_author_link", gprefs) r("tag_browser_dont_collapse", gprefs, setting=CommaSeparatedList) choices = set( [ k for k in db.field_metadata.all_field_keys() if ( db.field_metadata[k]["is_category"] and (db.field_metadata[k]["datatype"] in ["text", "series", "enumeration"]) and not db.field_metadata[k]["display"].get("is_names", False) ) or ( db.field_metadata[k]["datatype"] in ["composite"] and db.field_metadata[k]["display"].get("make_category", False) ) ] ) choices -= set(["authors", "publisher", "formats", "news", "identifiers"]) choices |= set(["search"]) self.opt_categories_using_hierarchy.update_items_cache(choices) r( "categories_using_hierarchy", db.prefs, setting=CommaSeparatedList, choices=sorted(list(choices), key=sort_key), ) fm = db.field_metadata choices = sorted( ((fm[k]["name"], k) for k in fm.displayable_field_keys() if fm[k]["name"]), key=lambda x: sort_key(x[0]) ) r("field_under_covers_in_grid", db.prefs, choices=choices) self.current_font = self.initial_font = None self.change_font_button.clicked.connect(self.change_font) self.display_model = DisplayedFields(self.gui.current_db, self.field_display_order) self.display_model.dataChanged.connect(self.changed_signal) self.field_display_order.setModel(self.display_model) self.df_up_button.clicked.connect(self.move_df_up) self.df_down_button.clicked.connect(self.move_df_down) self.edit_rules = EditRules(self.tabWidget) self.edit_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.edit_rules, QIcon(I("format-fill-color.png")), _("Column coloring")) self.icon_rules = EditRules(self.tabWidget) self.icon_rules.changed.connect(self.changed_signal) self.tabWidget.addTab(self.icon_rules, QIcon(I("icon_choose.png")), _("Column icons")) self.tabWidget.setCurrentIndex(0) keys = [QKeySequence("F11", QKeySequence.PortableText), QKeySequence("Ctrl+Shift+F", QKeySequence.PortableText)] keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys] self.fs_help_msg.setText(unicode(self.fs_help_msg.text()) % (_(" or ").join(keys))) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) l = self.cg_background_box.layout() self.cg_bg_widget = w = Background(self) l.addWidget(w, 0, 0, 3, 1) self.cover_grid_color_button = b = QPushButton(_("Change &color"), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 0, 1) b.clicked.connect(self.change_cover_grid_color) self.cover_grid_texture_button = b = QPushButton(_("Change &background image"), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 1, 1) b.clicked.connect(self.change_cover_grid_texture) self.cover_grid_default_appearance_button = b = QPushButton(_("Restore &default appearance"), self) b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) l.addWidget(b, 2, 1) b.clicked.connect(self.restore_cover_grid_appearance) self.cover_grid_empty_cache.clicked.connect(self.empty_cache) self.cover_grid_open_cache.clicked.connect(self.open_cg_cache) self.cover_grid_smaller_cover.clicked.connect(partial(self.resize_cover, True)) self.cover_grid_larger_cover.clicked.connect(partial(self.resize_cover, False)) self.cover_grid_reset_size.clicked.connect(self.cg_reset_size) self.opt_cover_grid_disk_cache_size.setMinimum(self.gui.grid_view.thumbnail_cache.min_disk_cache) self.opt_cover_grid_disk_cache_size.setMaximum(self.gui.grid_view.thumbnail_cache.min_disk_cache * 100) self.opt_cover_grid_width.valueChanged.connect(self.update_aspect_ratio) self.opt_cover_grid_height.valueChanged.connect(self.update_aspect_ratio) @property def current_cover_size(self): cval = self.opt_cover_grid_height.value() wval = self.opt_cover_grid_width.value() if cval < 0.1: dpi = self.opt_cover_grid_height.logicalDpiY() cval = auto_height(self.opt_cover_grid_height) / dpi / CM_TO_INCH if wval < 0.1: wval = 0.75 * cval return wval, cval def update_aspect_ratio(self, *args): width, height = self.current_cover_size ar = width / height self.cover_grid_aspect_ratio.setText(_("Current aspect ratio (width/height): %.2g") % ar) def resize_cover(self, smaller): wval, cval = self.current_cover_size ar = wval / cval delta = 0.2 * (-1 if smaller else 1) cval += delta cval = max(0, cval) self.opt_cover_grid_height.setValue(cval) self.opt_cover_grid_width.setValue(cval * ar) def cg_reset_size(self): self.opt_cover_grid_width.setValue(0) self.opt_cover_grid_height.setValue(0) def initialize(self): ConfigWidgetBase.initialize(self) font = gprefs["font"] if font is not None: font = list(font) font.append(gprefs.get("font_stretch", QFont.Unstretched)) self.current_font = self.initial_font = font self.update_font_display() self.display_model.initialize() db = self.gui.current_db try: idx = self.gui.library_view.currentIndex().row() mi = db.get_metadata(idx, index_is_id=False) except: mi = None self.edit_rules.initialize(db.field_metadata, db.prefs, mi, "column_color_rules") self.icon_rules.initialize(db.field_metadata, db.prefs, mi, "column_icon_rules") self.set_cg_color(gprefs["cover_grid_color"]) self.set_cg_texture(gprefs["cover_grid_texture"]) self.update_aspect_ratio() def open_cg_cache(self): open_local_file(self.gui.grid_view.thumbnail_cache.location) def update_cg_cache_size(self, size): self.cover_grid_current_disk_cache.setText(_("Current space used: %s") % human_readable(size)) def tab_changed(self, index): if self.tabWidget.currentWidget() is self.cover_grid_tab: self.show_current_cache_usage() def show_current_cache_usage(self): t = Thread(target=self.calc_cache_size) t.daemon = True t.start() def calc_cache_size(self): self.size_calculated.emit(self.gui.grid_view.thumbnail_cache.current_size) def set_cg_color(self, val): self.cg_bg_widget.bcol = QColor(*val) self.cg_bg_widget.update_brush() def set_cg_texture(self, val): self.cg_bg_widget.btex = val self.cg_bg_widget.update_brush() def empty_cache(self): self.gui.grid_view.thumbnail_cache.empty() self.calc_cache_size() def restore_defaults(self): ConfigWidgetBase.restore_defaults(self) ofont = self.current_font self.current_font = None if ofont is not None: self.changed_signal.emit() self.update_font_display() self.display_model.restore_defaults() self.edit_rules.clear() self.icon_rules.clear() self.changed_signal.emit() self.set_cg_color(gprefs.defaults["cover_grid_color"]) self.set_cg_texture(gprefs.defaults["cover_grid_texture"]) def change_cover_grid_color(self): col = QColorDialog.getColor(self.cg_bg_widget.bcol, self.gui, _("Choose background color for cover grid")) if col.isValid(): col = tuple(col.getRgb())[:3] self.set_cg_color(col) self.changed_signal.emit() if self.cg_bg_widget.btex: if question_dialog( self, _("Remove background image?"), _( "There is currently a background image set, so the color" " you have chosen will not be visible. Remove the background image?" ), ): self.set_cg_texture(None) def change_cover_grid_texture(self): from calibre.gui2.preferences.texture_chooser import TextureChooser d = TextureChooser(parent=self, initial=self.cg_bg_widget.btex) if d.exec_() == d.Accepted: self.set_cg_texture(d.texture) self.changed_signal.emit() def restore_cover_grid_appearance(self): self.set_cg_color(gprefs.defaults["cover_grid_color"]) self.set_cg_texture(gprefs.defaults["cover_grid_texture"]) self.changed_signal.emit() def build_font_obj(self): font_info = self.current_font if font_info is not None: font = QFont(*(font_info[:4])) font.setStretch(font_info[4]) else: font = qt_app.original_font return font def update_font_display(self): font = self.build_font_obj() fi = QFontInfo(font) name = unicode(fi.family()) self.font_display.setFont(font) self.font_display.setText(name + " [%dpt]" % fi.pointSize()) def move_df_up(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, -1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def move_df_down(self): idx = self.field_display_order.currentIndex() if idx.isValid(): idx = self.display_model.move(idx, 1) if idx is not None: sm = self.field_display_order.selectionModel() sm.select(idx, sm.ClearAndSelect) self.field_display_order.setCurrentIndex(idx) def change_font(self, *args): fd = QFontDialog(self.build_font_obj(), self) if fd.exec_() == fd.Accepted: font = fd.selectedFont() fi = QFontInfo(font) self.current_font = [unicode(fi.family()), fi.pointSize(), fi.weight(), fi.italic(), font.stretch()] self.update_font_display() self.changed_signal.emit() def commit(self, *args): rr = ConfigWidgetBase.commit(self, *args) if self.current_font != self.initial_font: gprefs["font"] = self.current_font[:4] if self.current_font else None gprefs["font_stretch"] = self.current_font[4] if self.current_font is not None else QFont.Unstretched QApplication.setFont(self.font_display.font()) rr = True self.display_model.commit() self.edit_rules.commit(self.gui.current_db.prefs) self.icon_rules.commit(self.gui.current_db.prefs) gprefs["cover_grid_color"] = tuple(self.cg_bg_widget.bcol.getRgb())[:3] gprefs["cover_grid_texture"] = self.cg_bg_widget.btex return rr def refresh_gui(self, gui): gui.library_view.model().reset() self.update_font_display() gui.tags_view.reread_collapse_parameters() gui.library_view.refresh_book_details() if hasattr(gui.cover_flow, "setShowReflections"): gui.cover_flow.setShowReflections(gprefs["cover_browser_reflections"]) gui.library_view.refresh_row_sizing() gui.grid_view.refresh_settings()