def createEditor(self, parent, option, index): if self.db and hasattr(self.db, self.items_func_name): col = self.col if col is None: # We have not specified an explicit column, so we need # to lookup a column name. The calibre one will rely on stuff # on the model, we will rely on a callback function instead col = self.col_fn(index.column()) editor = EditWithComplete(parent) editor.set_separator(self.sep) editor.set_space_before_sep(self.space_before_sep) if self.sep == '&': editor.set_add_separator( tweaks.get('authors_completer_append_separator', False)) if col.startswith('#'): all_items = list( self.db.all_custom( label=self.db.field_metadata.key_to_label(col))) else: all_items = getattr(self.db, self.items_func_name)() editor.update_items_cache(all_items) for item in sorted(all_items, key=sort_key): editor.addItem(item) ct = convert_qvariant(index.data(Qt.DisplayRole)) editor.show_initial_value(ct) else: editor = EnLineEdit(parent) return editor
def convert(self, oeb, output_path, input_plugin, opts, log): from calibre.utils.config import tweaks from calibre.ebooks.mobi.writer2.resources import Resources self.log, self.opts, self.oeb = log, opts, oeb mobi_type = tweaks.get('test_mobi_output_type', 'old') if self.is_periodical: mobi_type = 'old' # Amazon does not support KF8 periodicals create_kf8 = mobi_type in ('new', 'both') remove_html_cover(self.oeb, self.log) resources = Resources(oeb, opts, self.is_periodical, add_fonts=create_kf8) self.check_for_periodical() if create_kf8: # Split on pagebreaks so that the resulting KF8 works better with # calibre's viewer, which does not support CSS page breaks from calibre.ebooks.oeb.transforms.split import Split Split()(self.oeb, self.opts) kf8 = self.create_kf8(resources, for_joint=mobi_type == 'both') if create_kf8 else None if mobi_type == 'new': kf8.write(output_path) extract_mobi(output_path, opts) return self.log('Creating MOBI 6 output') self.write_mobi(input_plugin, output_path, kf8, resources)
def __init__(self, parent, book_id, fmts, db): QDialog.__init__(self, parent) self.setWindowIcon(QIcon(I('unpack-book.png'))) self.book_id, self.fmts, self.db_ref = book_id, fmts, weakref.ref(db) self._exploded = None self._cleanup_dirs = [] self._cleanup_files = [] self.setup_ui() self.setWindowTitle(_('Unpack book') + ' - ' + db.title(book_id, index_is_id=True)) button = self.fmt_choice_buttons[0] button_map = {str(x.text()):x for x in self.fmt_choice_buttons} of = prefs['output_format'].upper() df = tweaks.get('default_tweak_format', None) lf = gprefs.get('last_tweak_format', None) if df and df.lower() == 'remember' and lf in button_map: button = button_map[lf] elif df and df.upper() in button_map: button = button_map[df.upper()] elif of in button_map: button = button_map[of] button.setChecked(True) self.init_state() for button in self.fmt_choice_buttons: button.toggled.connect(self.init_state)
def __init__(self, parent, book_id, fmts, db): QDialog.__init__(self, parent) self.book_id, self.fmts, self.db_ref = book_id, fmts, weakref.ref(db) self._exploded = None self._cleanup_dirs = [] self._cleanup_files = [] self.setup_ui() self.setWindowTitle(_('Tweak Book') + ' - ' + db.title(book_id, index_is_id=True)) button = self.fmt_choice_buttons[0] button_map = {unicode(x.text()):x for x in self.fmt_choice_buttons} of = prefs['output_format'].upper() df = tweaks.get('default_tweak_format', None) lf = gprefs.get('last_tweak_format', None) if df and df.lower() == 'remember' and lf in button_map: button = button_map[lf] elif df and df.upper() in button_map: button = button_map[df.upper()] elif of in button_map: button = button_map[of] button.setChecked(True) self.init_state() for button in self.fmt_choice_buttons: button.toggled.connect(self.init_state)
def convert(self, oeb, output_path, input_plugin, opts, log): from calibre.utils.config import tweaks from calibre.ebooks.mobi.writer2.resources import Resources self.log, self.opts, self.oeb = log, opts, oeb mobi_type = tweaks.get('test_mobi_output_type', 'old') if self.is_periodical: mobi_type = 'old' # Amazon does not support KF8 periodicals create_kf8 = mobi_type in ('new', 'both') remove_html_cover(self.oeb, self.log) resources = Resources(oeb, opts, self.is_periodical, add_fonts=create_kf8) self.check_for_periodical() if create_kf8: # Split on pagebreaks so that the resulting KF8 works better with # calibre's viewer, which does not support CSS page breaks from calibre.ebooks.oeb.transforms.split import Split Split()(self.oeb, self.opts) kf8 = self.create_kf8(resources, for_joint=mobi_type=='both' ) if create_kf8 else None if mobi_type == 'new': kf8.write(output_path) extract_mobi(output_path, opts) return self.log('Creating MOBI 6 output') self.write_mobi(input_plugin, output_path, kf8, resources)
def fuzzy_it(text, patterns=None): fuzzy_title_patterns = [ (re.compile(pat, re.IGNORECASE), repl) for pat, repl in [( r'[\[\](){}<>\'";,:#]', ''), (tweaks.get('title_sort_articles', r'^(a|the|an)\s+'), ''), (r'[-._]', ' '), (r'\s+', ' ')] ] if not patterns: patterns = fuzzy_title_patterns text = text.strip().lower() for pat, repl in patterns: text = pat.sub(repl, text) return text.strip()
def __init__(self, shortcuts, parent=None, debug_javascript=False): QWebPage.__init__(self, parent) self.setObjectName("py_bridge") self.in_paged_mode = tweaks.get('viewer_test_paged_mode', False) # Use this to pass arbitrary JSON encodable objects between python and # javascript. In python get/set the value as: self.bridge_value. In # javascript, get/set the value as: py_bridge.value self.bridge_value = None self.first_load = True self.debug_javascript = debug_javascript self.anchor_positions = {} self.index_anchors = set() self.current_language = None self.loaded_javascript = False self.js_loader = JavaScriptLoader( dynamic_coffeescript=self.debug_javascript) self.initial_left_margin = self.initial_right_margin = u'' self.in_fullscreen_mode = False self.setLinkDelegationPolicy(self.DelegateAllLinks) self.scroll_marks = [] self.shortcuts = shortcuts pal = self.palette() pal.setBrush(QPalette.Background, QColor(0xee, 0xee, 0xee)) self.setPalette(pal) self.page_position = PagePosition(self) settings = self.settings() # Fonts load_builtin_fonts() self.set_font_settings() # Security settings.setAttribute(QWebSettings.JavaEnabled, False) settings.setAttribute(QWebSettings.PluginsEnabled, False) settings.setAttribute(QWebSettings.JavascriptCanOpenWindows, False) settings.setAttribute(QWebSettings.JavascriptCanAccessClipboard, False) # Miscellaneous settings.setAttribute(QWebSettings.LinksIncludedInFocusChain, True) settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True) self.set_user_stylesheet() self.misc_config() # Load javascript self.mainFrame().javaScriptWindowObjectCleared.connect( self.add_window_objects) self.turn_off_internal_scrollbars()
def fuzzy_it(text, patterns=None): fuzzy_title_patterns = [(re.compile(pat, re.IGNORECASE), repl) for pat, repl in [ (r'[\[\](){}<>\'";,:#]', ''), (tweaks.get('title_sort_articles', r'^(a|the|an)\s+'), ''), (r'[-._]', ' '), (r'\s+', ' ') ]] if not patterns: patterns = fuzzy_title_patterns text = text.strip().lower() for pat, repl in patterns: text = pat.sub(repl, text) return text.strip()
def __init__(self, gui): sc = _('Shift+Alt+G') LayoutButton.__init__(self, I('grid.png'), _('Cover Grid'), parent=gui, shortcut=sc) if tweaks.get('use_new_db', False): self.set_state_to_show() self.action_toggle = QAction(self.icon(), _('Toggle') + ' ' + self.label, self) gui.addAction(self.action_toggle) gui.keyboard.register_shortcut('grid view toggle' + self.label, unicode(self.action_toggle.text()), default_keys=(sc,), action=self.action_toggle) self.action_toggle.triggered.connect(self.toggle) self.toggled.connect(self.update_state) self.grid_enabled = True else: self.setVisible(False) self.grid_enabled = False
def compile_user_function(name, doc, arg_count, eval_func): def replace_func(mo): return mo.group().replace('\t', ' ') func = ' ' + '\n '.join( [tabs.sub(replace_func, line) for line in eval_func.splitlines()]) prog = ''' from calibre.utils.formatter_functions import FormatterUserFunction from calibre.utils.formatter_functions import formatter_functions class UserFunction(FormatterUserFunction): ''' + func locals_ = {} if DEBUG and tweaks.get('enable_template_debug_printing', False): print prog exec prog in locals_ cls = locals_['UserFunction'](name, doc, arg_count, eval_func) return cls
def __init__(self, parent=None): QStatusBar.__init__(self, parent) self.version = get_version() self.base_msg = '%s %s' % (__appname__, self.version) if tweaks.get('use_new_db', False): self.base_msg += ' [newdb]' self.device_string = '' self.update_label = UpdateLabel('') self.total = self.current = self.selected = self.library_total = 0 self.addPermanentWidget(self.update_label) self.update_label.setVisible(False) self._font = QFont() self._font.setBold(True) self.setFont(self._font) self.defmsg = QLabel('') self.defmsg.setFont(self._font) self.addWidget(self.defmsg) self.set_label()
def fuzzy_it(text, patterns=None): # Changes from Find Duplicates are to strip everything in () and [] brackets # rather than just the brackets themselves. # Also to replace an ampersand with the word 'and' fuzzy_title_patterns = [ (re.compile(pat, re.IGNORECASE), repl) for pat, repl in [(r'(\[.*\])', ''), (r'(\(.*\))', ''), ( r'&', ' and '), ( r'[{}<>\'";,:#\?]', ''), (tweaks.get('title_sort_articles', r'^(a|the|an)\s+'), ''), (r'[-._]', ' '), (r'\s+', ' ')] ] if not patterns: patterns = fuzzy_title_patterns text = text.strip().lower() for pat, repl in patterns: text = pat.sub(repl, text) return text.strip()
def compile_user_function(name, doc, arg_count, eval_func): def replace_func(mo): return mo.group().replace("\t", " ") func = " " + "\n ".join([tabs.sub(replace_func, line) for line in eval_func.splitlines()]) prog = ( """ from calibre.utils.formatter_functions import FormatterUserFunction from calibre.utils.formatter_functions import formatter_functions class UserFunction(FormatterUserFunction): """ + func ) locals_ = {} if DEBUG and tweaks.get("enable_template_debug_printing", False): print prog exec prog in locals_ cls = locals_["UserFunction"](name, doc, arg_count, eval_func) return cls
def get_font_or_default(font_name): default_font = tweaks.get('generate_cover_title_font', None) if default_font is None: default_font = P('fonts/liberation/LiberationSerif-Bold.ttf') font_path = default_font if font_name: found_font = font_scanner.legacy_fonts_for_family(font_name) if len(found_font) == 0: if DEBUG: prints('Could not find font: ', font_name) else: # Assume 'normal' always in dict, else use default # {'normal': (path_to_font, friendly name)} if 'normal' in found_font: font_path = found_font['normal'][0] else: # Couldn't find 'normal' so just use first value if it exists font_path = found_font[list(found_font.keys())[0]][0] if not font_path or not os.access(font_path, os.R_OK): font_path = default_font return font_path
def __init__(self, gui): sc = _('Shift+Alt+G') LayoutButton.__init__(self, I('grid.png'), _('Cover Grid'), parent=gui, shortcut=sc) if tweaks.get('use_new_db', False): self.set_state_to_show() self.action_toggle = QAction(self.icon(), _('Toggle') + ' ' + self.label, self) gui.addAction(self.action_toggle) gui.keyboard.register_shortcut('grid view toggle' + self.label, unicode(self.action_toggle.text()), default_keys=(sc, ), action=self.action_toggle) self.action_toggle.triggered.connect(self.toggle) self.toggled.connect(self.update_state) self.grid_enabled = True else: self.setVisible(False) self.grid_enabled = False
def initialize_prefs(self, default_prefs, restore_all_prefs, progress_callback): # {{{ self.prefs = DBPrefs(self) if default_prefs is not None and not self._exists: progress_callback(None, len(default_prefs)) # Only apply default prefs to a new database for i, key in enumerate(default_prefs): # be sure that prefs not to be copied are listed below if restore_all_prefs or key not in frozenset( ['news_to_be_synced']): self.prefs[key] = default_prefs[key] progress_callback(_('restored preference ') + key, i + 1) if 'field_metadata' in default_prefs: fmvals = [ f for f in default_prefs['field_metadata'].values() if f['is_custom'] ] progress_callback(None, len(fmvals)) for i, f in enumerate(fmvals): progress_callback( _('creating custom column ') + f['label'], i) self.create_custom_column(f['label'], f['name'], f['datatype'], (f['is_multiple'] is not None and len(f['is_multiple']) > 0), f['is_editable'], f['display']) defs = self.prefs.defaults defs['gui_restriction'] = defs['cs_restriction'] = '' defs['categories_using_hierarchy'] = [] defs['column_color_rules'] = [] defs['column_icon_rules'] = [] defs['grouped_search_make_user_categories'] = [] defs['similar_authors_search_key'] = 'authors' defs['similar_authors_match_kind'] = 'match_any' defs['similar_publisher_search_key'] = 'publisher' defs['similar_publisher_match_kind'] = 'match_any' defs['similar_tags_search_key'] = 'tags' defs['similar_tags_match_kind'] = 'match_all' defs['similar_series_search_key'] = 'series' defs['similar_series_match_kind'] = 'match_any' defs['book_display_fields'] = [ ('title', False), ('authors', True), ('formats', True), ('series', True), ('identifiers', True), ('tags', True), ('path', True), ('publisher', False), ('rating', False), ('author_sort', False), ('sort', False), ('timestamp', False), ('uuid', False), ('comments', True), ('id', False), ('pubdate', False), ('last_modified', False), ('size', False), ('languages', False), ] defs['virtual_libraries'] = {} defs['virtual_lib_on_startup'] = defs['cs_virtual_lib_on_startup'] = '' # Migrate the bool tristate tweak defs['bools_are_tristate'] = \ tweaks.get('bool_custom_columns_are_tristate', 'yes') == 'yes' if self.prefs.get('bools_are_tristate') is None: self.prefs.set('bools_are_tristate', defs['bools_are_tristate']) # Migrate column coloring rules if self.prefs.get('column_color_name_1', None) is not None: from calibre.library.coloring import migrate_old_rule old_rules = [] for i in range(1, 6): col = self.prefs.get('column_color_name_' + str(i), None) templ = self.prefs.get('column_color_template_' + str(i), None) if col and templ: try: del self.prefs['column_color_name_' + str(i)] rules = migrate_old_rule(self.field_metadata, templ) for templ in rules: old_rules.append((col, templ)) except: pass if old_rules: self.prefs['column_color_rules'] += old_rules # Migrate saved search and user categories to db preference scheme def migrate_preference(key, default): oldval = prefs[key] if oldval != default: self.prefs[key] = oldval prefs[key] = default if key not in self.prefs: self.prefs[key] = default migrate_preference('user_categories', {}) migrate_preference('saved_searches', {}) # migrate grouped_search_terms if self.prefs.get('grouped_search_terms', None) is None: try: ogst = tweaks.get('grouped_search_terms', {}) ngst = {} for t in ogst: ngst[icu_lower(t)] = ogst[t] self.prefs.set('grouped_search_terms', ngst) except: pass # migrate the gui_restriction preference to a virtual library gr_pref = self.prefs.get('gui_restriction', None) if gr_pref: virt_libs = self.prefs.get('virtual_libraries', {}) virt_libs[gr_pref] = 'search:"' + gr_pref + '"' self.prefs['virtual_libraries'] = virt_libs self.prefs['gui_restriction'] = '' self.prefs['virtual_lib_on_startup'] = gr_pref # migrate the cs_restriction preference to a virtual library gr_pref = self.prefs.get('cs_restriction', None) if gr_pref: virt_libs = self.prefs.get('virtual_libraries', {}) virt_libs[gr_pref] = 'search:"' + gr_pref + '"' self.prefs['virtual_libraries'] = virt_libs self.prefs['cs_restriction'] = '' self.prefs['cs_virtual_lib_on_startup'] = gr_pref # Rename any user categories with names that differ only in case user_cats = self.prefs.get('user_categories', []) catmap = {} for uc in user_cats: ucl = icu_lower(uc) if ucl not in catmap: catmap[ucl] = [] catmap[ucl].append(uc) cats_changed = False for uc in catmap: if len(catmap[uc]) > 1: prints('found user category case overlap', catmap[uc]) cat = catmap[uc][0] suffix = 1 while icu_lower((cat + unicode(suffix))) in catmap: suffix += 1 prints('Renaming user category %s to %s' % (cat, cat + unicode(suffix))) user_cats[cat + unicode(suffix)] = user_cats[cat] del user_cats[cat] cats_changed = True if cats_changed: self.prefs.set('user_categories', user_cats)
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)) 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) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) 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_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)) 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) self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection) self.tabWidget.currentChanged.connect(self.tab_changed) 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 initialize_prefs(self, default_prefs, restore_all_prefs, progress_callback): # {{{ self.prefs = DBPrefs(self) if default_prefs is not None and not self._exists: progress_callback(None, len(default_prefs)) # Only apply default prefs to a new database for i, key in enumerate(default_prefs): # be sure that prefs not to be copied are listed below if restore_all_prefs or key not in frozenset(['news_to_be_synced']): self.prefs[key] = default_prefs[key] progress_callback(_('restored preference ') + key, i+1) if 'field_metadata' in default_prefs: fmvals = [f for f in default_prefs['field_metadata'].values() if f['is_custom']] progress_callback(None, len(fmvals)) for i, f in enumerate(fmvals): progress_callback(_('creating custom column ') + f['label'], i) self.create_custom_column(f['label'], f['name'], f['datatype'], (f['is_multiple'] is not None and len(f['is_multiple']) > 0), f['is_editable'], f['display']) defs = self.prefs.defaults defs['gui_restriction'] = defs['cs_restriction'] = '' defs['categories_using_hierarchy'] = [] defs['column_color_rules'] = [] defs['column_icon_rules'] = [] defs['grouped_search_make_user_categories'] = [] defs['similar_authors_search_key'] = 'authors' defs['similar_authors_match_kind'] = 'match_any' defs['similar_publisher_search_key'] = 'publisher' defs['similar_publisher_match_kind'] = 'match_any' defs['similar_tags_search_key'] = 'tags' defs['similar_tags_match_kind'] = 'match_all' defs['similar_series_search_key'] = 'series' defs['similar_series_match_kind'] = 'match_any' defs['book_display_fields'] = [ ('title', False), ('authors', True), ('formats', True), ('series', True), ('identifiers', True), ('tags', True), ('path', True), ('publisher', False), ('rating', False), ('author_sort', False), ('sort', False), ('timestamp', False), ('uuid', False), ('comments', True), ('id', False), ('pubdate', False), ('last_modified', False), ('size', False), ('languages', False), ] defs['virtual_libraries'] = {} defs['virtual_lib_on_startup'] = defs['cs_virtual_lib_on_startup'] = '' # Migrate the bool tristate tweak defs['bools_are_tristate'] = \ tweaks.get('bool_custom_columns_are_tristate', 'yes') == 'yes' if self.prefs.get('bools_are_tristate') is None: self.prefs.set('bools_are_tristate', defs['bools_are_tristate']) # Migrate column coloring rules if self.prefs.get('column_color_name_1', None) is not None: from calibre.library.coloring import migrate_old_rule old_rules = [] for i in range(1, 6): col = self.prefs.get('column_color_name_'+str(i), None) templ = self.prefs.get('column_color_template_'+str(i), None) if col and templ: try: del self.prefs['column_color_name_'+str(i)] rules = migrate_old_rule(self.field_metadata, templ) for templ in rules: old_rules.append((col, templ)) except: pass if old_rules: self.prefs['column_color_rules'] += old_rules # Migrate saved search and user categories to db preference scheme def migrate_preference(key, default): oldval = prefs[key] if oldval != default: self.prefs[key] = oldval prefs[key] = default if key not in self.prefs: self.prefs[key] = default migrate_preference('user_categories', {}) migrate_preference('saved_searches', {}) # migrate grouped_search_terms if self.prefs.get('grouped_search_terms', None) is None: try: ogst = tweaks.get('grouped_search_terms', {}) ngst = {} for t in ogst: ngst[icu_lower(t)] = ogst[t] self.prefs.set('grouped_search_terms', ngst) except: pass # migrate the gui_restriction preference to a virtual library gr_pref = self.prefs.get('gui_restriction', None) if gr_pref: virt_libs = self.prefs.get('virtual_libraries', {}) virt_libs[gr_pref] = 'search:"' + gr_pref + '"' self.prefs['virtual_libraries'] = virt_libs self.prefs['gui_restriction'] = '' self.prefs['virtual_lib_on_startup'] = gr_pref # migrate the cs_restriction preference to a virtual library gr_pref = self.prefs.get('cs_restriction', None) if gr_pref: virt_libs = self.prefs.get('virtual_libraries', {}) virt_libs[gr_pref] = 'search:"' + gr_pref + '"' self.prefs['virtual_libraries'] = virt_libs self.prefs['cs_restriction'] = '' self.prefs['cs_virtual_lib_on_startup'] = gr_pref # Rename any user categories with names that differ only in case user_cats = self.prefs.get('user_categories', []) catmap = {} for uc in user_cats: ucl = icu_lower(uc) if ucl not in catmap: catmap[ucl] = [] catmap[ucl].append(uc) cats_changed = False for uc in catmap: if len(catmap[uc]) > 1: prints('found user category case overlap', catmap[uc]) cat = catmap[uc][0] suffix = 1 while icu_lower((cat + unicode(suffix))) in catmap: suffix += 1 prints('Renaming user category %s to %s'%(cat, cat+unicode(suffix))) user_cats[cat + unicode(suffix)] = user_cats[cat] del user_cats[cat] cats_changed = True if cats_changed: self.prefs.set('user_categories', user_cats)