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
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
    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)
Exemple #6
0
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()
Exemple #8
0
    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()
Exemple #9
0
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()
Exemple #10
0
 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
Exemple #11
0
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
Exemple #12
0
 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()
Exemple #14
0
 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()
Exemple #15
0
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
Exemple #17
0
 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
Exemple #18
0
    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)
Exemple #19
0
    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)
Exemple #20
0
    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)
Exemple #21
0
    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)
Exemple #22
0
    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)