Пример #1
0
    def setup_ui(self):
        self.l = l = QVBoxLayout(self)
        self.h = h = QHBoxLayout()
        l.addLayout(h)

        self.la1 = la = QLabel(_('F&unction name:'))
        h.addWidget(la)
        self.fb = fb = FunctionBox(self)
        la.setBuddy(fb)
        h.addWidget(fb, stretch=10)

        self.la3 = la = QLabel(_('&Code:'))
        self.source_code = TextEdit(self)
        self.source_code.load_text('', 'python')
        la.setBuddy(self.source_code)
        l.addWidget(la), l.addWidget(self.source_code)

        if self._func_name:
            self.fb.setText(self._func_name)
            func = functions().get(self._func_name)
            if func is not None:
                self.source_code.setPlainText(func.source or ('\n' + EMPTY_FUNC))
        else:
            self.source_code.setPlainText('\n' + EMPTY_FUNC)

        self.la2 = la = QLabel(_(
            'For help with creating functions, see the <a href="%s">User Manual</a>') %
            localize_user_manual_link('https://manual.calibre-ebook.com/function_mode.html'))
        la.setOpenExternalLinks(True)
        l.addWidget(la)

        l.addWidget(self.bb)
Пример #2
0
    def __init__(self, parent, get_option, get_help, db=None, book_id=None):
        Widget.__init__(self, parent,
                ['enable_heuristics', 'markup_chapter_headings',
                 'italicize_common_cases', 'fix_indents',
                 'html_unwrap_factor', 'unwrap_lines',
                 'delete_blank_paragraphs',
                 'format_scene_breaks', 'replace_scene_breaks',
                 'dehyphenate', 'renumber_headings']
                )
        self.db, self.book_id = db, book_id
        self.rssb_defaults = [u'', u'<hr />', u'∗ ∗ ∗', u'• • •', u'♦ ♦ ♦',
                u'† †', u'‡ ‡ ‡', u'∞ ∞ ∞', u'¤ ¤ ¤', u'§']
        self.initialize_options(get_option, get_help, db, book_id)

        self.load_histories()

        self.opt_enable_heuristics.stateChanged.connect(self.enable_heuristics)
        self.opt_unwrap_lines.stateChanged.connect(self.enable_unwrap)

        self.enable_heuristics(self.opt_enable_heuristics.checkState())
        try:
            self.help_label.setText(self.help_label.text() % localize_user_manual_link(
                'https://manual.calibre-ebook.com/conversion.html#heuristic-processing'))
        except TypeError:
            pass  # link already localized
Пример #3
0
 def __init__(self):
     QWizardPage.__init__(self)
     self.setupUi(self)
     try:
         self.um_label.setText(self.um_label.text() % localize_user_manual_link('https://manual.calibre-ebook.com'))
     except TypeError:
         pass  # link already localized
Пример #4
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QGridLayout(self)

        def add_row(*args):
            r = l.rowCount()
            if len(args) == 1:
                l.addWidget(args[0], r, 0, 1, 2)
            else:
                la = QLabel(args[0])
                l.addWidget(la, r, 0, Qt.AlignRight), l.addWidget(args[1], r, 1)
                la.setBuddy(args[1])

        self.heading = la = QLabel('<h2>\xa0')
        add_row(la)
        self.helpl = la = QLabel(_('For help with snippets, see the <a href="%s">User Manual</a>') %
                                 localize_user_manual_link('https://manual.calibre-ebook.com/snippets.html'))
        la.setOpenExternalLinks(True)
        add_row(la)

        self.name = n = QLineEdit(self)
        n.setPlaceholderText(_('The name of this snippet'))
        add_row(_('&Name:'), n)

        self.trig = t = QLineEdit(self)
        t.setPlaceholderText(_('The text used to trigger this snippet'))
        add_row(_('Tri&gger:'), t)

        self.template = t = QPlainTextEdit(self)
        la.setBuddy(t)
        add_row(_('&Template:'), t)

        self.types = t = QListWidget(self)
        t.setFlow(t.LeftToRight)
        t.setWrapping(True), t.setResizeMode(t.Adjust), t.setSpacing(5)
        fm = t.fontMetrics()
        t.setMaximumHeight(2*(fm.ascent() + fm.descent()) + 25)
        add_row(_('&File types:'), t)
        t.setToolTip(_('Which file types this snippet should be active in'))

        self.frame = f = QFrame(self)
        f.setFrameShape(f.HLine)
        add_row(f)
        self.test = d = SnippetTextEdit('', self)
        d.snippet_manager.snip_func = self.snip_func
        d.setToolTip(_('You can test your snippet here'))
        d.setMaximumHeight(t.maximumHeight() + 15)
        add_row(_('T&est:'), d)

        i = QListWidgetItem(_('All'), t)
        i.setData(Qt.UserRole, '*')
        i.setCheckState(Qt.Checked)
        i.setFlags(i.flags() | Qt.ItemIsUserCheckable)
        for ftype in sorted(all_text_syntaxes):
            i = QListWidgetItem(ftype, t)
            i.setData(Qt.UserRole, ftype)
            i.setCheckState(Qt.Checked)
            i.setFlags(i.flags() | Qt.ItemIsUserCheckable)

        self.creating_snippet = False
Пример #5
0
    def __init__(self, parent, get_option, get_help, db=None, book_id=None):
        Widget.__init__(self, parent, [
            'override_profile_size', 'paper_size', 'custom_size',
            'preserve_cover_aspect_ratio', 'pdf_serif_family', 'unit',
            'pdf_sans_family', 'pdf_mono_family', 'pdf_standard_font',
            'pdf_default_font_size', 'pdf_mono_font_size', 'pdf_page_numbers',
            'pdf_footer_template', 'pdf_header_template', 'pdf_add_toc', 'toc_title',
        ])
        self.db, self.book_id = db, book_id
        try:
            self.hf_label.setText(self.hf_label.text() % localize_user_manual_link(
                'https://manual.calibre-ebook.com/conversion.html#converting-to-pdf'))
        except TypeError:
            pass  # link already localized

        for x in get_option('paper_size').option.choices:
            self.opt_paper_size.addItem(x)
        for x in get_option('unit').option.choices:
            self.opt_unit.addItem(x)
        for x in get_option('pdf_standard_font').option.choices:
            self.opt_pdf_standard_font.addItem(x)

        self.initialize_options(get_option, get_help, db, book_id)
        self.layout().setFieldGrowthPolicy(self.layout().ExpandingFieldsGrow)
        self.template_box.layout().setFieldGrowthPolicy(self.layout().AllNonFixedFieldsGrow)
Пример #6
0
 def __init__(self, parent=None):
     QWidget.__init__(self, parent)
     self.setupUi(self)
     try:
         self.example_label.setText(self.example_label.text() % localize_user_manual_link(
             'http://manual.calibre-ebook.com/xpath.html'))
     except TypeError:
         pass
Пример #7
0
 def __init__(self):
     QWizardPage.__init__(self)
     self.setupUi(self)
     try:
         self.instructions.setText(self.instructions.text() % localize_user_manual_link(
             'https://manual.calibre-ebook.com/faq.html#how-do-i-use-calibre-with-my-ipad-iphone-ipod-touch'))
     except TypeError:
         pass  # user manual link was already replaced
     self.instructions.setOpenExternalLinks(True)
     self.content_server.stateChanged[(int)].connect(self.set_port)
Пример #8
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.l = l = QVBoxLayout(self)

        self.la = la = QLabel(_(
            'For help with writing advanced news recipes, see the <a href="%s">User Manual</a>'
        ) % localize_user_manual_link('https://manual.calibre-ebook.com/news.html'))
        l.addWidget(la)

        self.editor = TextEdit(self)
        l.addWidget(self.editor)
Пример #9
0
 def __init__(self):
     QWizardPage.__init__(self)
     self.setupUi(self)
     self.registerField('library_location', self.location)
     self.button_change.clicked.connect(self.change)
     self.init_languages()
     self.language.currentIndexChanged[int].connect(self.change_language)
     self.location.textChanged.connect(self.location_text_changed)
     self.move_lib_label.setText(_(
         'If you are moving calibre from an old computer to a new one,'
         ' please read <a href="{0}">the instructions</a>.').format(
             localize_user_manual_link(
     'https://manual.calibre-ebook.com/faq.html#how-do-i-move-my-calibre-data-from-one-computer-to-another')))
Пример #10
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.setupUi(self)
        try:
            self.help_label.setText(self.help_label.text() % localize_user_manual_link(
                'https://manual.calibre-ebook.com/regexp.html'))
        except TypeError:
            pass  # link already localized

        self.test_button.clicked.connect(self.do_test)
        self.re.lineEdit().returnPressed[()].connect(self.do_test)
        self.filename.returnPressed[()].connect(self.do_test)
        connect_lambda(self.re.lineEdit().textChanged, self, lambda self, x: self.changed_signal.emit())
Пример #11
0
    def __init__(self, parent, get_option, get_help, db=None, book_id=None):
        # Dummy attributes to fool the Widget() option handler code. We handle
        # everything in our *handler methods.
        for i in range(1, 4):
            x = 'sr%d_'%i
            for y in ('search', 'replace'):
                z = x + y
                setattr(self, 'opt_'+z, z)
        self.opt_search_replace = 'search_replace'

        Widget.__init__(self, parent,
                ['search_replace',
                 'sr1_search', 'sr1_replace',
                 'sr2_search', 'sr2_replace',
                 'sr3_search', 'sr3_replace']
                )
        self.db, self.book_id = db, book_id

        self.sr_search.set_msg(_('&Search Regular Expression'))
        self.sr_search.set_book_id(book_id)
        self.sr_search.set_db(db)

        self.sr_search.doc_update.connect(self.update_doc)

        proto = QTableWidgetItem()
        proto.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable + Qt.ItemIsEnabled))
        self.search_replace.setItemPrototype(proto)
        self.search_replace.setColumnCount(2)
        self.search_replace.setColumnWidth(0, 320)
        self.search_replace.setColumnWidth(1, 320)
        self.search_replace.setHorizontalHeaderLabels([
            _('Search Regular Expression'), _('Replacement Text')])

        self.sr_add.clicked.connect(self.sr_add_clicked)
        self.sr_change.clicked.connect(self.sr_change_clicked)
        self.sr_remove.clicked.connect(self.sr_remove_clicked)
        self.sr_load.clicked.connect(self.sr_load_clicked)
        self.sr_save.clicked.connect(self.sr_save_clicked)
        self.sr_up.clicked.connect(self.sr_up_clicked)
        self.sr_down.clicked.connect(self.sr_down_clicked)
        self.search_replace.currentCellChanged.connect(self.sr_currentCellChanged)

        self.initialize_options(get_option, get_help, db, book_id)

        try:
            self.rh_label.setText(self.rh_label.text() % localize_user_manual_link(
                'https://manual.calibre-ebook.com/regexp.html'))
        except TypeError:
            pass  # link already localized
Пример #12
0
 def __init__(self, parent, get_option, get_help, db=None, book_id=None):
     Widget.__init__(self, parent,
             ['level1_toc', 'level2_toc', 'level3_toc',
             'toc_threshold', 'max_toc_links', 'no_chapters_in_toc',
             'use_auto_toc', 'toc_filter', 'duplicate_links_in_toc',
             ]
             )
     self.db, self.book_id = db, book_id
     self.initialize_options(get_option, get_help, db, book_id)
     self.opt_level1_toc.set_msg(_('Level &1 TOC (XPath expression):'))
     self.opt_level2_toc.set_msg(_('Level &2 TOC (XPath expression):'))
     self.opt_level3_toc.set_msg(_('Level &3 TOC (XPath expression):'))
     try:
         self.help_label.setText(self.help_label.text() % localize_user_manual_link(
             'https://manual.calibre-ebook.com/conversion.html#table-of-contents'))
     except TypeError:
         pass  # link already localized
Пример #13
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QVBoxLayout(self)
        self.h = h = QHBoxLayout()

        self.la = la = QLabel(self.MSG)
        la.setWordWrap(True)
        l.addWidget(la)
        l.addLayout(h)
        self.action = a = QComboBox(self)
        h.addWidget(a)
        for action, text in self.ACTION_MAP.iteritems():
            a.addItem(text, action)
        a.currentIndexChanged.connect(self.update_state)
        self.la1 = la = QLabel('\xa0' + self.SUBJECT + '\xa0')
        h.addWidget(la)
        self.match_type = q = QComboBox(self)
        h.addWidget(q)
        for action, text in self.MATCH_TYPE_MAP.iteritems():
            q.addItem(text, action)
        q.currentIndexChanged.connect(self.update_state)
        self.la2 = la = QLabel(':\xa0')
        h.addWidget(la)
        self.query = q = QueryEdit(self)
        h.addWidget(q)
        self.tag_editor_button = b = QToolButton(self)
        b.setIcon(QIcon(I('chapters.png')))
        b.setToolTip(_('Edit the list of tags with the tag editor'))
        h.addWidget(b), b.clicked.connect(self.edit_tags)
        b.setVisible(self.can_use_tag_editor)
        self.h2 = h = QHBoxLayout()
        l.addLayout(h)
        self.la3 = la = QLabel(self.REPLACE_TEXT + '\xa0')
        h.addWidget(la)
        self.replace = r = QLineEdit(self)
        h.addWidget(r)
        self.regex_help = la = QLabel('<p>' + self.REGEXP_HELP_TEXT % localize_user_manual_link(
        'https://manual.calibre-ebook.com/regexp.html'))
        la.setOpenExternalLinks(True)
        la.setWordWrap(True)
        l.addWidget(la)
        la.setVisible(False)
        l.addStretch(10)
        self.la3.setVisible(False), self.replace.setVisible(False)
        self.update_state()
Пример #14
0
    def __init__(self, parent, get_option, get_help, db=None, book_id=None):
        Widget.__init__(self, parent, OPTIONS['pipe']['heuristics'])
        self.db, self.book_id = db, book_id
        self.rssb_defaults = [u'', u'<hr />', u'∗ ∗ ∗', u'• • •', u'♦ ♦ ♦',
                u'† †', u'‡ ‡ ‡', u'∞ ∞ ∞', u'¤ ¤ ¤', u'§']
        self.initialize_options(get_option, get_help, db, book_id)

        self.load_histories()

        self.opt_enable_heuristics.stateChanged.connect(self.enable_heuristics)
        self.opt_unwrap_lines.stateChanged.connect(self.enable_unwrap)

        self.enable_heuristics(self.opt_enable_heuristics.checkState())
        try:
            self.help_label.setText(self.help_label.text() % localize_user_manual_link(
                'https://manual.calibre-ebook.com/conversion.html#heuristic-processing'))
        except TypeError:
            pass  # link already localized
Пример #15
0
def get_parser(usage):
    parser = OptionParser(usage)
    go = parser.add_option_group(_('GLOBAL OPTIONS'))
    go.is_global_options = True
    go.add_option(
        '--library-path',
        '--with-library',
        default=None,
        help=_(
            'Path to the calibre library. Default is to use the path stored in the settings.'
            ' You can also connect to a calibre Content server to perform actions on'
            ' remote libraries. To do so use a URL of the form: http://hostname:port/#library_id'
            ' for example, http://localhost:8080/#mylibrary. library_id is the library id'
            ' of the library you want to connect to on the Content server. You can use'
            ' the special library_id value of - to get a list of library ids available'
            ' on the server. For details on how to setup access via a Content server, see'
            ' {}.'
        ).format(localize_user_manual_link(
            'https://manual.calibre-ebook.com/generated/en/calibredb.html'
        ))
    )
    go.add_option(
        '-h', '--help', help=_('show this help message and exit'), action='help'
    )
    go.add_option(
        '--version',
        help=_("show program's version number and exit"),
        action='version'
    )
    go.add_option(
        '--username',
        help=_('Username for connecting to a calibre Content server')
    )
    go.add_option(
        '--password',
        help=_('Password for connecting to a calibre Content server.'
               ' To read the password from standard input, use the special value: {0}.'
               ' To read the password from a file, use: {1} (i.e. <f: followed by the full path to the file and a trailing >).'
               ' The angle brackets in the above are required, remember to escape them or use quotes'
               ' for your shell.').format(
                   '<stdin>', '<f:C:/path/to/file>' if iswindows else '<f:/path/to/file>')
    )

    return parser
Пример #16
0
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        try:
            self.sh_label.setText(self.sh_label.text() % localize_user_manual_link(
                'https://manual.calibre-ebook.com/gui.html#the-search-interface'))
        except TypeError:
            pass  # link already localized

        self.buttonBox.accepted.connect(self.advanced_search_button_pushed)
        self.tab_2_button_box.accepted.connect(self.accept)
        self.tab_2_button_box.rejected.connect(self.reject)
        self.clear_button.clicked.connect(self.clear_button_pushed)
        self.adv_search_used = False
        self.mc = ''

        self.tabWidget.setCurrentIndex(0)
        self.tabWidget.currentChanged[int].connect(self.tab_changed)
        self.tab_changed(0)
Пример #17
0
    def __init__(self, parent=None, base_font_size=0.0, font_key=None):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        try:
            self.wh_label.setText(self.wh_label.text() % localize_user_manual_link(
                'https://manual.calibre-ebook.com/conversion.html#font-size-rescaling'))
        except TypeError:
            pass  # link already localized

        self.default_font_key       = font_key
        self.default_base_font_size = base_font_size
        self.buttonBox.clicked.connect(self.button_clicked)
        self.button_use_default.clicked.connect(self.use_default)

        for x in ('input_base_font_size', 'input_font_size',
                'output_base_font_size'):
            getattr(self, x).valueChanged.connect(self.calculate)
        self.font_size_key.textChanged.connect(self.calculate)

        self.initialize()
Пример #18
0
    def __init__(self, parent, get_option, get_help, db=None, book_id=None):
        Widget.__init__(self, parent, OPTIONS['output']['pdf'])
        self.db, self.book_id = db, book_id
        try:
            self.hf_label.setText(self.hf_label.text() % localize_user_manual_link(
                'https://manual.calibre-ebook.com/conversion.html#converting-to-pdf'))
        except TypeError:
            pass  # link already localized

        for x in get_option('paper_size').option.choices:
            self.opt_paper_size.addItem(x)
        for x in get_option('unit').option.choices:
            self.opt_unit.addItem(x)
        for x in get_option('pdf_standard_font').option.choices:
            self.opt_pdf_standard_font.addItem(x)

        self.initialize_options(get_option, get_help, db, book_id)
        self.layout().setFieldGrowthPolicy(self.layout().ExpandingFieldsGrow)
        self.template_box.layout().setFieldGrowthPolicy(self.layout().AllNonFixedFieldsGrow)
        self.toggle_margins()
        self.profile_size_toggled()
Пример #19
0
    def __init__(self, parent, text, mi=None, fm=None, color_field=None,
                 icon_field_key=None, icon_rule_kind=None, doing_emblem=False,
                 text_is_placeholder=False):
        QDialog.__init__(self, parent)
        Ui_TemplateDialog.__init__(self)
        self.setupUi(self)

        self.coloring = color_field is not None
        self.iconing = icon_field_key is not None
        self.embleming = doing_emblem

        cols = []
        if fm is not None:
            for key in sorted(displayable_columns(fm),
                              key=lambda(k): sort_key(fm[k]['name']) if k != color_row_key else 0):
                if key == color_row_key and not self.coloring:
                    continue
                from calibre.gui2.preferences.coloring import all_columns_string
                name = all_columns_string if key == color_row_key else fm[key]['name']
                if name:
                    cols.append((name, key))

        self.color_layout.setVisible(False)
        self.icon_layout.setVisible(False)

        if self.coloring:
            self.color_layout.setVisible(True)
            for n1, k1 in cols:
                self.colored_field.addItem(n1, k1)
            self.colored_field.setCurrentIndex(self.colored_field.findData(color_field))
        elif self.iconing or self.embleming:
            self.icon_layout.setVisible(True)
            if self.embleming:
                self.icon_kind_label.setVisible(False)
                self.icon_kind.setVisible(False)
                self.icon_chooser_label.setVisible(False)
                self.icon_field.setVisible(False)

            for n1, k1 in cols:
                self.icon_field.addItem(n1, k1)
            self.icon_file_names = []
            d = os.path.join(config_dir, 'cc_icons')
            if os.path.exists(d):
                for icon_file in os.listdir(d):
                    icon_file = icu_lower(icon_file)
                    if os.path.exists(os.path.join(d, icon_file)):
                        if icon_file.endswith('.png'):
                            self.icon_file_names.append(icon_file)
            self.icon_file_names.sort(key=sort_key)
            self.update_filename_box()

            if self.iconing:
                dex = 0
                from calibre.gui2.preferences.coloring import icon_rule_kinds
                for i,tup in enumerate(icon_rule_kinds):
                    txt,val = tup
                    self.icon_kind.addItem(txt, userData=(val))
                    if val == icon_rule_kind:
                        dex = i
                self.icon_kind.setCurrentIndex(dex)
                self.icon_field.setCurrentIndex(self.icon_field.findData(icon_field_key))

        if mi:
            self.mi = mi
        else:
            self.mi = Metadata(_('Title'), [_('Author')])
            self.mi.author_sort = _('Author Sort')
            self.mi.series = ngettext('Series', 'Series', 1)
            self.mi.series_index = 3
            self.mi.rating = 4.0
            self.mi.tags = [_('Tag 1'), _('Tag 2')]
            self.mi.languages = ['eng']
            self.mi.id = 1
            if fm is not None:
                self.mi.set_all_user_metadata(fm.custom_field_metadata())
            else:
                # No field metadata. Grab a copy from the current library so
                # that we can validate any custom column names. The values for
                # the columns will all be empty, which in some very unusual
                # cases might cause formatter errors. We can live with that.
                from calibre.gui2.ui import get_gui
                self.mi.set_all_user_metadata(
                      get_gui().current_db.new_api.field_metadata.custom_field_metadata())

        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.last_text = ''
        self.highlighter = TemplateHighlighter(self.textbox.document())
        self.textbox.cursorPositionChanged.connect(self.text_cursor_changed)
        self.textbox.textChanged.connect(self.textbox_changed)

        self.textbox.setTabStopWidth(10)
        self.source_code.setTabStopWidth(10)
        self.documentation.setReadOnly(True)
        self.source_code.setReadOnly(True)

        if text is not None:
            if text_is_placeholder:
                self.textbox.setPlaceholderText(text)
            else:
                self.textbox.setPlainText(text)
        self.buttonBox.button(QDialogButtonBox.Ok).setText(_('&OK'))
        self.buttonBox.button(QDialogButtonBox.Cancel).setText(_('&Cancel'))
        self.color_copy_button.clicked.connect(self.color_to_clipboard)
        self.filename_button.clicked.connect(self.filename_button_clicked)
        self.icon_copy_button.clicked.connect(self.icon_to_clipboard)

        try:
            with open(P('template-functions.json'), 'rb') as f:
                self.builtin_source_dict = json.load(f, encoding='utf-8')
        except:
            self.builtin_source_dict = {}

        self.funcs = formatter_functions().get_functions()
        self.builtins = formatter_functions().get_builtins()

        func_names = sorted(self.funcs)
        self.function.clear()
        self.function.addItem('')
        self.function.addItems(func_names)
        self.function.setCurrentIndex(0)
        self.function.currentIndexChanged[str].connect(self.function_changed)
        self.textbox_changed()
        self.rule = (None, '')

        tt = _('Template language tutorial')
        self.template_tutorial.setText(
            '<a href="%s">%s</a>' % (
                localize_user_manual_link('http://manual.calibre-ebook.com/template_lang.html'), tt))
        tt = _('Template function reference')
        self.template_func_reference.setText(
            '<a href="%s">%s</a>' % (
                localize_user_manual_link('http://manual.calibre-ebook.com/template_ref.html'), tt))

        self.font_size_box.setValue(gprefs['gpm_template_editor_font_size'])
        self.font_size_box.valueChanged.connect(self.font_size_changed)
Пример #20
0
    def __init__(self,
                 parent,
                 text,
                 mi=None,
                 fm=None,
                 color_field=None,
                 icon_field_key=None,
                 icon_rule_kind=None,
                 doing_emblem=False,
                 text_is_placeholder=False,
                 dialog_is_st_editor=False,
                 global_vars=None,
                 all_functions=None,
                 builtin_functions=None):
        QDialog.__init__(self, parent)
        Ui_TemplateDialog.__init__(self)
        self.setupUi(self)

        self.coloring = color_field is not None
        self.iconing = icon_field_key is not None
        self.embleming = doing_emblem
        self.dialog_is_st_editor = dialog_is_st_editor
        if global_vars is None:
            self.global_vars = {}
        else:
            self.global_vars = global_vars

        cols = []
        if fm is not None:
            for key in sorted(
                    displayable_columns(fm),
                    key=lambda k: sort_key(fm[k]['name']
                                           if k != color_row_key else 0)):
                if key == color_row_key and not self.coloring:
                    continue
                from calibre.gui2.preferences.coloring import all_columns_string
                name = all_columns_string if key == color_row_key else fm[key][
                    'name']
                if name:
                    cols.append((name, key))

        self.color_layout.setVisible(False)
        self.icon_layout.setVisible(False)

        if self.coloring:
            self.color_layout.setVisible(True)
            for n1, k1 in cols:
                self.colored_field.addItem(
                    n1 + (' (' + k1 + ')' if k1 != color_row_key else ''), k1)
            self.colored_field.setCurrentIndex(
                self.colored_field.findData(color_field))
        elif self.iconing or self.embleming:
            self.icon_layout.setVisible(True)
            if self.embleming:
                self.icon_kind_label.setVisible(False)
                self.icon_kind.setVisible(False)
                self.icon_chooser_label.setVisible(False)
                self.icon_field.setVisible(False)

            for n1, k1 in cols:
                self.icon_field.addItem('{} ({})'.format(n1, k1), k1)
            self.icon_file_names = []
            d = os.path.join(config_dir, 'cc_icons')
            if os.path.exists(d):
                for icon_file in os.listdir(d):
                    icon_file = icu_lower(icon_file)
                    if os.path.exists(os.path.join(d, icon_file)):
                        if icon_file.endswith('.png'):
                            self.icon_file_names.append(icon_file)
            self.icon_file_names.sort(key=sort_key)
            self.update_filename_box()

            if self.iconing:
                dex = 0
                from calibre.gui2.preferences.coloring import icon_rule_kinds
                for i, tup in enumerate(icon_rule_kinds):
                    txt, val = tup
                    self.icon_kind.addItem(txt, userData=(val))
                    if val == icon_rule_kind:
                        dex = i
                self.icon_kind.setCurrentIndex(dex)
                self.icon_field.setCurrentIndex(
                    self.icon_field.findData(icon_field_key))

        if dialog_is_st_editor:
            self.buttonBox.setVisible(False)
        else:
            self.new_doc_label.setVisible(False)
            self.new_doc.setVisible(False)
            self.template_name_label.setVisible(False)
            self.template_name.setVisible(False)

        if mi:
            if not isinstance(mi, list):
                mi = (mi, )
        else:
            mi = Metadata(_('Title'), [_('Author')])
            mi.author_sort = _('Author Sort')
            mi.series = ngettext('Series', 'Series', 1)
            mi.series_index = 3
            mi.rating = 4.0
            mi.tags = [_('Tag 1'), _('Tag 2')]
            mi.languages = ['eng']
            mi.id = 1
            if fm is not None:
                mi.set_all_user_metadata(fm.custom_field_metadata())
            else:
                # No field metadata. Grab a copy from the current library so
                # that we can validate any custom column names. The values for
                # the columns will all be empty, which in some very unusual
                # cases might cause formatter errors. We can live with that.
                from calibre.gui2.ui import get_gui
                mi.set_all_user_metadata(get_gui(
                ).current_db.new_api.field_metadata.custom_field_metadata())
            for col in mi.get_all_user_metadata(False):
                mi.set(col, (col, ), 0)
            mi = (mi, )
        self.mi = mi

        # Set up the display table
        self.table_column_widths = None
        try:
            self.table_column_widths = \
                        gprefs.get('template_editor_table_widths', None)
        except:
            pass
        tv = self.template_value
        tv.setRowCount(len(mi))
        tv.setColumnCount(2)
        tv.setHorizontalHeaderLabels((_('Book title'), _('Template value')))
        tv.horizontalHeader().setStretchLastSection(True)
        tv.horizontalHeader().sectionResized.connect(self.table_column_resized)
        # Set the height of the table
        h = tv.rowHeight(0) * min(len(mi), 5)
        h += 2 * tv.frameWidth() + tv.horizontalHeader().height()
        tv.setMinimumHeight(h)
        tv.setMaximumHeight(h)
        # Set the size of the title column
        if self.table_column_widths:
            tv.setColumnWidth(0, self.table_column_widths[0])
        else:
            tv.setColumnWidth(0, tv.fontMetrics().averageCharWidth() * 10)
        # Use our own widget to get rid of elision. setTextElideMode() doesn't work
        for r in range(0, len(mi)):
            w = QLineEdit(tv)
            w.setReadOnly(True)
            tv.setCellWidget(r, 0, w)
            w = QLineEdit(tv)
            w.setReadOnly(True)
            tv.setCellWidget(r, 1, w)
        tv.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)

        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowType.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.all_functions = all_functions if all_functions else formatter_functions(
        ).get_functions()
        self.builtins = (builtin_functions if builtin_functions else
                         formatter_functions().get_builtins_and_aliases())

        self.last_text = ''
        self.highlighter = TemplateHighlighter(self.textbox.document(),
                                               builtin_functions=self.builtins)
        self.textbox.cursorPositionChanged.connect(self.text_cursor_changed)
        self.textbox.textChanged.connect(self.textbox_changed)
        self.textbox.setFont(self.get_current_font())

        self.textbox.setTabStopWidth(10)
        self.source_code.setTabStopWidth(10)
        self.documentation.setReadOnly(True)
        self.source_code.setReadOnly(True)

        if text is not None:
            if text_is_placeholder:
                self.textbox.setPlaceholderText(text)
                self.textbox.clear()
                text = ''
            else:
                self.textbox.setPlainText(text)
        else:
            text = ''
        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(
            _('&OK'))
        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(
            _('&Cancel'))

        self.color_copy_button.clicked.connect(self.color_to_clipboard)
        self.filename_button.clicked.connect(self.filename_button_clicked)
        self.icon_copy_button.clicked.connect(self.icon_to_clipboard)

        try:
            with open(P('template-functions.json'), 'rb') as f:
                self.builtin_source_dict = json.load(f, encoding='utf-8')
        except:
            self.builtin_source_dict = {}

        func_names = sorted(self.all_functions)
        self.function.clear()
        self.function.addItem('')
        for f in func_names:
            self.function.addItem(
                '{}  --  {}'.format(
                    f, self.function_type_string(f, longform=False)), f)
        self.function.setCurrentIndex(0)
        self.function.currentIndexChanged.connect(self.function_changed)
        self.display_values(text)
        self.rule = (None, '')

        tt = _('Template language tutorial')
        self.template_tutorial.setText(
            '<a href="%s">%s</a>' % (localize_user_manual_link(
                'https://manual.calibre-ebook.com/template_lang.html'), tt))
        tt = _('Template function reference')
        self.template_func_reference.setText(
            '<a href="%s">%s</a>' % (localize_user_manual_link(
                'https://manual.calibre-ebook.com/generated/en/template_ref.html'
            ), tt))

        s = gprefs.get('template_editor_break_on_print', False)
        self.go_button.setEnabled(s)
        self.remove_all_button.setEnabled(s)
        self.set_all_button.setEnabled(s)
        self.toggle_button.setEnabled(s)
        self.breakpoint_line_box.setEnabled(s)
        self.breakpoint_line_box_label.setEnabled(s)
        self.break_box.setChecked(s)
        self.break_box.stateChanged.connect(self.break_box_changed)
        self.go_button.clicked.connect(self.go_button_pressed)
        self.textbox.setFocus()
        self.set_up_font_boxes()
        self.toggle_button.clicked.connect(self.toggle_button_pressed)
        self.remove_all_button.clicked.connect(self.remove_all_button_pressed)
        self.set_all_button.clicked.connect(self.set_all_button_pressed)

        self.load_button.clicked.connect(self.load_template)
        self.save_button.clicked.connect(self.save_template)
        # Now geometry
        try:
            geom = gprefs.get('template_editor_dialog_geometry', None)
            if geom is not None:
                QApplication.instance().safe_restore_geometry(
                    self, QByteArray(geom))
        except Exception:
            pass
Пример #21
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QGridLayout(self)

        def add_row(*args):
            r = l.rowCount()
            if len(args) == 1:
                l.addWidget(args[0], r, 0, 1, 2)
            else:
                la = QLabel(args[0])
                l.addWidget(la, r, 0,
                            Qt.AlignRight), l.addWidget(args[1], r, 1)
                la.setBuddy(args[1])

        self.heading = la = QLabel('<h2>\xa0')
        add_row(la)
        self.helpl = la = QLabel(
            _('For help with snippets, see the <a href="%s">User Manual</a>') %
            localize_user_manual_link(
                'https://manual.calibre-ebook.com/snippets.html'))
        la.setOpenExternalLinks(True)
        add_row(la)

        self.name = n = QLineEdit(self)
        n.setPlaceholderText(_('The name of this snippet'))
        add_row(_('&Name:'), n)

        self.trig = t = QLineEdit(self)
        t.setPlaceholderText(_('The text used to trigger this snippet'))
        add_row(_('Tri&gger:'), t)

        self.template = t = QPlainTextEdit(self)
        la.setBuddy(t)
        add_row(_('&Template:'), t)

        self.types = t = QListWidget(self)
        t.setFlow(t.LeftToRight)
        t.setWrapping(True), t.setResizeMode(t.Adjust), t.setSpacing(5)
        fm = t.fontMetrics()
        t.setMaximumHeight(2 * (fm.ascent() + fm.descent()) + 25)
        add_row(_('&File types:'), t)
        t.setToolTip(_('Which file types this snippet should be active in'))

        self.frame = f = QFrame(self)
        f.setFrameShape(f.HLine)
        add_row(f)
        self.test = d = SnippetTextEdit('', self)
        d.snippet_manager.snip_func = self.snip_func
        d.setToolTip(_('You can test your snippet here'))
        d.setMaximumHeight(t.maximumHeight() + 15)
        add_row(_('T&est:'), d)

        i = QListWidgetItem(_('All'), t)
        i.setData(Qt.UserRole, '*')
        i.setCheckState(Qt.Checked)
        i.setFlags(i.flags() | Qt.ItemIsUserCheckable)
        for ftype in sorted(all_text_syntaxes):
            i = QListWidgetItem(ftype, t)
            i.setData(Qt.UserRole, ftype)
            i.setCheckState(Qt.Checked)
            i.setFlags(i.flags() | Qt.ItemIsUserCheckable)

        self.creating_snippet = False
Пример #22
0
 def show_help(self, *args):
     open_url(QUrl(localize_user_manual_link('http://manual.calibre-ebook.com')))
Пример #23
0
    def create_actions(self):
        group = _('Global Actions')

        def reg(icon,
                text,
                target,
                sid,
                keys,
                description,
                toolbar_allowed=False):
            if not isinstance(icon, QIcon):
                icon = QIcon(I(icon))
            ac = actions[sid] = QAction(icon, text, self) if icon else QAction(
                text, self)
            ac.setObjectName('action-' + sid)
            if toolbar_allowed:
                toolbar_actions[sid] = ac
            if target is not None:
                ac.triggered.connect(target)
            if isinstance(keys, type('')):
                keys = (keys, )
            self.keyboard.register_shortcut(sid,
                                            unicode(ac.text()).replace(
                                                '&', ''),
                                            default_keys=keys,
                                            description=description,
                                            action=ac,
                                            group=group)
            self.addAction(ac)
            return ac

        def treg(icon, text, target, sid, keys, description):
            return reg(icon,
                       text,
                       target,
                       sid,
                       keys,
                       description,
                       toolbar_allowed=icon is not None)

        self.action_new_file = treg('document-new.png',
                                    _('&New file (images/fonts/HTML/etc.)'),
                                    self.boss.add_file, 'new-file', (),
                                    _('Create a new file in the current book'))
        self.action_import_files = treg('document-import.png',
                                        _('&Import files into book'),
                                        self.boss.add_files, 'new-files', (),
                                        _('Import files into book'))
        self.action_open_book = treg('document_open.png', _('Open &book'),
                                     self.boss.open_book, 'open-book',
                                     'Ctrl+O', _('Open a new book'))
        # Qt does not generate shortcut overrides for cmd+arrow on os x which
        # means these shortcuts interfere with editing
        self.action_global_undo = treg(
            'back.png', _('&Revert to before'), self.boss.do_global_undo,
            'global-undo', () if isosx else 'Ctrl+Left',
            _('Revert book to before the last action (Undo)'))
        self.action_global_redo = treg(
            'forward.png', _('&Revert to after'), self.boss.do_global_redo,
            'global-redo', () if isosx else 'Ctrl+Right',
            _('Revert book state to after the next action (Redo)'))
        self.action_save = treg('save.png', _('&Save'), self.boss.save_book,
                                'save-book', 'Ctrl+S', _('Save book'))
        self.action_save.setEnabled(False)
        self.action_save_copy = treg('save.png', _('Save a &copy'),
                                     self.boss.save_copy,
                                     'save-copy', 'Ctrl+Alt+S',
                                     _('Save a copy of the book'))
        self.action_quit = treg('window-close.png', _('&Quit'), self.boss.quit,
                                'quit', 'Ctrl+Q', _('Quit'))
        self.action_preferences = treg('config.png', _('&Preferences'),
                                       self.boss.preferences, 'preferences',
                                       'Ctrl+P', _('Preferences'))
        self.action_new_book = treg('plus.png', _('Create &new, empty book'),
                                    self.boss.new_book, 'new-book', (),
                                    _('Create a new, empty book'))
        self.action_import_book = treg(
            'add_book.png', _('&Import an HTML or DOCX file as a new book'),
            self.boss.import_book, 'import-book', (),
            _('Import an HTML or DOCX file as a new book'))
        self.action_quick_edit = treg(
            'modified.png', _('&Quick open a file to edit'),
            self.boss.quick_open, 'quick-open', ('Ctrl+T'),
            _('Quickly open a file from the book to edit it'))

        # Editor actions
        group = _('Editor actions')
        self.action_editor_undo = reg('edit-undo.png', _('&Undo'),
                                      self.boss.do_editor_undo, 'editor-undo',
                                      'Ctrl+Z', _('Undo typing'))
        self.action_editor_redo = reg('edit-redo.png', _('&Redo'),
                                      self.boss.do_editor_redo, 'editor-redo',
                                      'Ctrl+Y', _('Redo typing'))
        self.action_editor_cut = reg('edit-cut.png', _('C&ut text'),
                                     self.boss.do_editor_cut, 'editor-cut', (
                                         'Ctrl+X',
                                         'Shift+Delete',
                                     ), _('Cut text'))
        self.action_editor_copy = reg('edit-copy.png', _('&Copy to clipboard'),
                                      self.boss.do_editor_copy, 'editor-copy',
                                      ('Ctrl+C', 'Ctrl+Insert'),
                                      _('Copy to clipboard'))
        self.action_editor_paste = reg('edit-paste.png',
                                       _('&Paste from clipboard'),
                                       self.boss.do_editor_paste,
                                       'editor-paste', (
                                           'Ctrl+V',
                                           'Shift+Insert',
                                       ), _('Paste from clipboard'))
        self.action_editor_cut.setEnabled(False)
        self.action_editor_copy.setEnabled(False)
        self.action_editor_undo.setEnabled(False)
        self.action_editor_redo.setEnabled(False)

        # Tool actions
        group = _('Tools')
        self.action_toc = treg('toc.png', _('&Edit Table of Contents'),
                               self.boss.edit_toc, 'edit-toc', (),
                               _('Edit Table of Contents'))
        self.action_inline_toc = treg('chapters.png',
                                      _('&Insert inline Table of Contents'),
                                      self.boss.insert_inline_toc,
                                      'insert-inline-toc', (),
                                      _('Insert inline Table of Contents'))
        self.action_fix_html_current = reg('html-fix.png', _('&Fix HTML'),
                                           partial(self.boss.fix_html, True),
                                           'fix-html-current', (),
                                           _('Fix HTML in the current file'))
        self.action_fix_html_all = treg('html-fix.png',
                                        _('&Fix HTML - all files'),
                                        partial(self.boss.fix_html, False),
                                        'fix-html-all', (),
                                        _('Fix HTML in all files'))
        self.action_pretty_current = reg('beautify.png',
                                         _('&Beautify current file'),
                                         partial(self.boss.pretty_print, True),
                                         'pretty-current', (),
                                         _('Beautify current file'))
        self.action_pretty_all = treg('beautify.png', _('&Beautify all files'),
                                      partial(self.boss.pretty_print,
                                              False), 'pretty-all', (),
                                      _('Beautify all files'))
        self.action_insert_char = treg('character-set.png',
                                       _('&Insert special character'),
                                       self.boss.insert_character,
                                       'insert-character', (),
                                       _('Insert special character'))
        self.action_rationalize_folders = treg('mimetypes/dir.png',
                                               _('&Arrange into folders'),
                                               self.boss.rationalize_folders,
                                               'rationalize-folders', (),
                                               _('Arrange into folders'))
        self.action_set_semantics = treg('tags.png', _('Set &Semantics'),
                                         self.boss.set_semantics,
                                         'set-semantics', (),
                                         _('Set Semantics'))
        self.action_filter_css = treg('filter.png',
                                      _('&Filter style information'),
                                      self.boss.filter_css, 'filter-css', (),
                                      _('Filter style information'))
        self.action_manage_fonts = treg('font.png', _('Manage &fonts'),
                                        self.boss.manage_fonts, 'manage-fonts',
                                        (), _('Manage fonts in the book'))
        self.action_add_cover = treg('default_cover.png', _('Add &cover'),
                                     self.boss.add_cover, 'add-cover', (),
                                     _('Add a cover to the book'))
        self.action_reports = treg(
            'reports.png', _('&Reports'), self.boss.show_reports,
            'show-reports', ('Ctrl+Shift+R', ),
            _('Show a report on various aspects of the book'))
        self.action_check_external_links = treg(
            'insert-link.png', _('Check &external links'),
            self.boss.check_external_links, 'check-external-links', (),
            _('Check external links in the book'))

        def ereg(icon, text, target, sid, keys, description):
            return reg(icon, text, partial(self.boss.editor_action, target),
                       sid, keys, description)

        register_text_editor_actions(ereg, self.palette())

        # Polish actions
        group = _('Polish Book')
        self.action_subset_fonts = treg(
            'subset-fonts.png', _('&Subset embedded fonts'),
            partial(self.boss.polish, 'subset', _('Subset fonts')),
            'subset-fonts', (), _('Subset embedded fonts'))
        self.action_embed_fonts = treg(
            'embed-fonts.png', _('&Embed referenced fonts'),
            partial(self.boss.polish, 'embed', _('Embed fonts')),
            'embed-fonts', (), _('Embed referenced fonts'))
        self.action_smarten_punctuation = treg(
            'smarten-punctuation.png', _('&Smarten punctuation'),
            partial(self.boss.polish, 'smarten_punctuation',
                    _('Smarten punctuation')), 'smarten-punctuation', (),
            _('Smarten punctuation'))
        self.action_remove_unused_css = treg(
            'edit-clear.png', _('Remove &unused CSS rules'),
            partial(self.boss.polish, 'remove_unused_css',
                    _('Remove unused CSS rules')), 'remove-unused-css', (),
            _('Remove unused CSS rules'))

        # Preview actions
        group = _('Preview')
        self.action_auto_reload_preview = reg('auto-reload.png',
                                              _('Auto reload preview'), None,
                                              'auto-reload-preview', (),
                                              _('Auto reload preview'))
        self.action_auto_sync_preview = reg(
            'sync-right.png', _('Sync preview position to editor position'),
            None, 'sync-preview-to-editor', (),
            _('Sync preview position to editor position'))
        self.action_reload_preview = reg('view-refresh.png',
                                         _('Refresh preview'), None,
                                         'reload-preview', ('F5', ),
                                         _('Refresh preview'))
        self.action_split_in_preview = reg(
            'auto_author_sort.png', _('Split this file'), None,
            'split-in-preview', (), _('Split file in the preview panel'))
        self.action_find_next_preview = reg('arrow-down.png', _('Find Next'),
                                            None, 'find-next-preview', (),
                                            _('Find next in preview'))
        self.action_find_prev_preview = reg('arrow-up.png', _('Find Previous'),
                                            None, 'find-prev-preview', (),
                                            _('Find previous in preview'))

        # Search actions
        group = _('Search')
        self.action_find = treg('search.png', _('&Find/Replace'),
                                self.boss.show_find, 'find-replace',
                                ('Ctrl+F', ), _('Show the Find/Replace panel'))

        def sreg(name,
                 text,
                 action,
                 overrides={},
                 keys=(),
                 description=None,
                 icon=None):
            return reg(
                icon, text,
                partial(self.boss.search_action_triggered, action, overrides),
                name, keys, description or text.replace('&', ''))

        self.action_find_next = sreg('find-next', _('Find &Next'), 'find',
                                     {'direction': 'down'}, ('F3', 'Ctrl+G'),
                                     _('Find next match'))
        self.action_find_previous = sreg('find-previous', _('Find &Previous'),
                                         'find', {'direction': 'up'},
                                         ('Shift+F3', 'Shift+Ctrl+G'),
                                         _('Find previous match'))
        self.action_replace = sreg('replace',
                                   _('Replace'),
                                   'replace',
                                   keys=('Ctrl+R'),
                                   description=_('Replace current match'))
        self.action_replace_next = sreg(
            'replace-next', _('&Replace and find next'), 'replace-find',
            {'direction': 'down'}, ('Ctrl+]'),
            _('Replace current match and find next'))
        self.action_replace_previous = sreg(
            'replace-previous', _('R&eplace and find previous'),
            'replace-find', {'direction': 'up'}, ('Ctrl+['),
            _('Replace current match and find previous'))
        self.action_replace_all = sreg('replace-all',
                                       _('Replace &all'),
                                       'replace-all',
                                       keys=('Ctrl+A'),
                                       description=_('Replace all matches'))
        self.action_count = sreg('count-matches',
                                 _('&Count all'),
                                 'count',
                                 keys=('Ctrl+N'),
                                 description=_('Count number of matches'))
        self.action_mark = reg(
            None, _('&Mark selected text'), self.boss.mark_selected_text,
            'mark-selected-text', ('Ctrl+Shift+M', ),
            _('Mark selected text or unmark already marked text'))
        self.action_mark.default_text = self.action_mark.text()
        self.action_go_to_line = reg(None, _('Go to &line'),
                                     self.boss.go_to_line_number,
                                     'go-to-line-number', ('Ctrl+.', ),
                                     _('Go to line number'))
        self.action_saved_searches = treg('folder_saved_search.png',
                                          _('Sa&ved searches'),
                                          self.boss.saved_searches,
                                          'saved-searches', (),
                                          _('Show the saved searches dialog'))

        # Check Book actions
        group = _('Check Book')
        self.action_check_book = treg('debug.png', _('&Check Book'),
                                      self.boss.check_requested, 'check-book',
                                      ('F7'), _('Check book for errors'))
        self.action_spell_check_book = treg(
            'spell-check.png', _('Check &spelling'),
            self.boss.spell_check_requested, 'spell-check-book', ('Alt+F7'),
            _('Check book for spelling errors'))
        self.action_check_book_next = reg(
            'forward.png', _('&Next error'),
            partial(self.check_book.next_error, delta=1), 'check-book-next',
            ('Ctrl+F7'), _('Show next error'))
        self.action_check_book_previous = reg(
            'back.png', _('&Previous error'),
            partial(self.check_book.next_error, delta=-1),
            'check-book-previous', ('Ctrl+Shift+F7'), _('Show previous error'))
        self.action_spell_check_next = reg('forward.png',
                                           _('&Next spelling mistake'),
                                           self.boss.next_spell_error,
                                           'spell-next', ('F8'),
                                           _('Go to next spelling mistake'))

        # Miscellaneous actions
        group = _('Miscellaneous')
        self.action_create_checkpoint = treg(
            'marked.png', _('&Create checkpoint'), self.boss.create_checkpoint,
            'create-checkpoint', (),
            _('Create a checkpoint with the current state of the book'))
        self.action_close_current_tab = reg('window-close.png',
                                            _('&Close current tab'),
                                            self.central.close_current_editor,
                                            'close-current-tab', 'Ctrl+W',
                                            _('Close the currently open tab'))
        self.action_close_all_but_current_tab = reg(
            'edit-clear.png', _('&Close other tabs'),
            self.central.close_all_but_current_editor,
            'close-all-but-current-tab', 'Ctrl+Alt+W',
            _('Close all tabs except the current tab'))
        self.action_help = treg(
            'help.png', _('User &Manual'), lambda: open_url(
                QUrl(
                    localize_user_manual_link(
                        'http://manual.calibre-ebook.com/edit.html'))),
            'user-manual', 'F1', _('Show User Manual'))
        self.action_browse_images = treg(
            'view-image.png', _('&Browse images in book'),
            self.boss.browse_images, 'browse-images', (),
            _('Browse images in the books visually'))
        self.action_multiple_split = treg(
            'auto_author_sort.png', _('&Split at multiple locations'),
            self.boss.multisplit, 'multisplit', (),
            _('Split HTML file at multiple locations'))
        self.action_compare_book = treg('diff.png',
                                        _('&Compare to another book'),
                                        self.boss.compare_book, 'compare-book',
                                        (), _('Compare to another book'))
        self.action_manage_snippets = treg('snippets.png',
                                           _('Manage &Snippets'),
                                           self.boss.manage_snippets,
                                           'manage-snippets', (),
                                           _('Manage user created snippets'))

        self.plugin_menu_actions = []

        create_plugin_actions(actions, toolbar_actions,
                              self.plugin_menu_actions)
Пример #24
0
    def __init__(self,
                 parent,
                 text,
                 mi=None,
                 fm=None,
                 color_field=None,
                 icon_field_key=None,
                 icon_rule_kind=None,
                 doing_emblem=False,
                 text_is_placeholder=False,
                 dialog_is_st_editor=False,
                 global_vars=None,
                 all_functions=None,
                 builtin_functions=None):
        QDialog.__init__(self, parent)
        Ui_TemplateDialog.__init__(self)
        self.setupUi(self)

        self.coloring = color_field is not None
        self.iconing = icon_field_key is not None
        self.embleming = doing_emblem
        self.dialog_is_st_editor = dialog_is_st_editor
        if global_vars is None:
            self.global_vars = {}
        else:
            self.global_vars = global_vars

        cols = []
        self.fm = fm
        if fm is not None:
            for key in sorted(
                    displayable_columns(fm),
                    key=lambda k: sort_key(fm[k]['name']
                                           if k != color_row_key else 0)):
                if key == color_row_key and not self.coloring:
                    continue
                from calibre.gui2.preferences.coloring import all_columns_string
                name = all_columns_string if key == color_row_key else fm[key][
                    'name']
                if name:
                    cols.append((name, key))

        self.color_layout.setVisible(False)
        self.icon_layout.setVisible(False)

        if self.coloring:
            self.color_layout.setVisible(True)
            for n1, k1 in cols:
                self.colored_field.addItem(
                    n1 + (' (' + k1 + ')' if k1 != color_row_key else ''), k1)
            self.colored_field.setCurrentIndex(
                self.colored_field.findData(color_field))
        elif self.iconing or self.embleming:
            self.icon_layout.setVisible(True)
            if self.embleming:
                self.icon_kind_label.setVisible(False)
                self.icon_kind.setVisible(False)
                self.icon_chooser_label.setVisible(False)
                self.icon_field.setVisible(False)

            for n1, k1 in cols:
                self.icon_field.addItem(f'{n1} ({k1})', k1)
            self.icon_file_names = []
            d = os.path.join(config_dir, 'cc_icons')
            if os.path.exists(d):
                for icon_file in os.listdir(d):
                    icon_file = icu_lower(icon_file)
                    if os.path.exists(os.path.join(d, icon_file)):
                        if icon_file.endswith('.png'):
                            self.icon_file_names.append(icon_file)
            self.icon_file_names.sort(key=sort_key)
            self.update_filename_box()

            if self.iconing:
                dex = 0
                from calibre.gui2.preferences.coloring import icon_rule_kinds
                for i, tup in enumerate(icon_rule_kinds):
                    txt, val = tup
                    self.icon_kind.addItem(txt, userData=(val))
                    if val == icon_rule_kind:
                        dex = i
                self.icon_kind.setCurrentIndex(dex)
                self.icon_field.setCurrentIndex(
                    self.icon_field.findData(icon_field_key))

        self.setup_saved_template_editor(not dialog_is_st_editor,
                                         dialog_is_st_editor)
        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowType.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.all_functions = all_functions if all_functions else formatter_functions(
        ).get_functions()
        self.builtins = (builtin_functions if builtin_functions else
                         formatter_functions().get_builtins_and_aliases())

        # Set up the display table
        self.table_column_widths = None
        try:
            self.table_column_widths = \
                        gprefs.get('template_editor_table_widths', None)
        except:
            pass
        self.set_mi(mi, fm)

        self.last_text = ''
        self.highlighter = TemplateHighlighter(self.textbox.document(),
                                               builtin_functions=self.builtins)
        self.textbox.cursorPositionChanged.connect(self.text_cursor_changed)
        self.textbox.textChanged.connect(self.textbox_changed)
        self.set_editor_font()

        self.documentation.setReadOnly(True)
        self.source_code.setReadOnly(True)

        if text is not None:
            if text_is_placeholder:
                self.textbox.setPlaceholderText(text)
                self.textbox.clear()
                text = ''
            else:
                self.textbox.setPlainText(text)
        else:
            text = ''
        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(
            _('&OK'))
        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(
            _('&Cancel'))

        self.color_copy_button.clicked.connect(self.color_to_clipboard)
        self.filename_button.clicked.connect(self.filename_button_clicked)
        self.icon_copy_button.clicked.connect(self.icon_to_clipboard)

        try:
            with open(P('template-functions.json'), 'rb') as f:
                self.builtin_source_dict = json.load(f, encoding='utf-8')
        except:
            self.builtin_source_dict = {}

        func_names = sorted(self.all_functions)
        self.function.clear()
        self.function.addItem('')
        for f in func_names:
            self.function.addItem(
                '{}  --  {}'.format(
                    f, self.function_type_string(f, longform=False)), f)
        self.function.setCurrentIndex(0)
        self.function.currentIndexChanged.connect(self.function_changed)
        self.rule = (None, '')

        tt = _('Template language tutorial')
        self.template_tutorial.setText('<a href="{}">{}</a>'.format(
            localize_user_manual_link(
                'https://manual.calibre-ebook.com/template_lang.html'), tt))
        tt = _('Template function reference')
        self.template_func_reference.setText('<a href="{}">{}</a>'.format(
            localize_user_manual_link(
                'https://manual.calibre-ebook.com/generated/en/template_ref.html'
            ), tt))

        s = gprefs.get('template_editor_break_on_print', False)
        self.go_button.setEnabled(s)
        self.remove_all_button.setEnabled(s)
        self.set_all_button.setEnabled(s)
        self.toggle_button.setEnabled(s)
        self.breakpoint_line_box.setEnabled(s)
        self.breakpoint_line_box_label.setEnabled(s)
        self.break_box.setChecked(s)
        self.break_box.stateChanged.connect(self.break_box_changed)
        self.go_button.clicked.connect(self.go_button_pressed)
        self.textbox.setFocus()
        self.set_up_font_boxes()
        self.toggle_button.clicked.connect(self.toggle_button_pressed)
        self.remove_all_button.clicked.connect(self.remove_all_button_pressed)
        self.set_all_button.clicked.connect(self.set_all_button_pressed)

        self.load_button.clicked.connect(self.load_template_from_file)
        self.save_button.clicked.connect(self.save_template)

        self.set_word_wrap(
            gprefs.get('gpm_template_editor_word_wrap_mode', True))
        self.textbox.setContextMenuPolicy(
            Qt.ContextMenuPolicy.CustomContextMenu)
        self.textbox.customContextMenuRequested.connect(self.show_context_menu)
        # Now geometry
        try:
            geom = gprefs.get('template_editor_dialog_geometry', None)
            if geom is not None:
                QApplication.instance().safe_restore_geometry(
                    self, QByteArray(geom))
        except Exception:
            pass
Пример #25
0
    def __init__(self, gui, existing_names, editing=None):
        QDialog.__init__(self, gui)

        self.gui = gui
        self.existing_names = existing_names

        if editing:
            self.setWindowTitle(_('Edit virtual library'))
        else:
            self.setWindowTitle(_('Create virtual library'))
        self.setWindowIcon(QIcon(I('lt.png')))

        gl = QGridLayout()
        self.setLayout(gl)
        self.la1 = la1 = QLabel(_('Virtual library &name:'))
        gl.addWidget(la1, 0, 0)
        self.vl_name = QComboBox()
        self.vl_name.setEditable(True)
        self.vl_name.lineEdit().setMaxLength(MAX_VIRTUAL_LIBRARY_NAME_LENGTH)
        la1.setBuddy(self.vl_name)
        gl.addWidget(self.vl_name, 0, 1)
        self.editing = editing

        self.saved_searches_label = sl = QTextBrowser(self)
        sl.viewport().setAutoFillBackground(False)
        gl.addWidget(sl, 2, 0, 1, 2)

        self.la2 = la2 = QLabel(_('&Search expression:'))
        gl.addWidget(la2, 1, 0)
        self.vl_text = QLineEdit()
        self.vl_text.textChanged.connect(self.search_text_changed)
        la2.setBuddy(self.vl_text)
        gl.addWidget(self.vl_text, 1, 1)
        self.vl_text.setText(_build_full_search_string(self.gui))

        self.sl = sl = QLabel('<p>'+_('Create a virtual library based on: ')+
            ('<a href="author.{0}">{0}</a>, '
            '<a href="tag.{1}">{1}</a>, '
            '<a href="publisher.{2}">{2}</a>, '
            '<a href="series.{3}">{3}</a>, '
            '<a href="search.{4}">{4}</a>.').format(_('Authors'), _('Tags'),
                                            _('Publishers'), _('Series'), _('Saved searches')))
        sl.setWordWrap(True)
        sl.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        sl.linkActivated.connect(self.link_activated)
        gl.addWidget(sl, 3, 0, 1, 2)
        gl.setRowStretch(3,10)

        self.hl = hl = QLabel(_('''
            <h2>Virtual libraries</h2>

            <p>Using <i>virtual libraries</i> you can restrict calibre to only show
            you books that match a search. When a virtual library is in effect, calibre
            behaves as though the library contains only the matched books. The Tag browser
            display only the tags/authors/series/etc. that belong to the matched books and any searches
            you do will only search within the books in the virtual library. This
            is a good way to partition your large library into smaller and easier to work with subsets.</p>

            <p>For example you can use a Virtual library to only show you books with the Tag <i>"Unread"</i>
            or only books by <i>"My favorite author"</i> or only books in a particular series.</p>

            <p>More information and examples are available in the
            <a href="%s">User Manual</a>.</p>
            ''') % localize_user_manual_link('https://manual.calibre-ebook.com/virtual_libraries.html'))
        hl.setWordWrap(True)
        hl.setOpenExternalLinks(True)
        hl.setFrameStyle(hl.StyledPanel)
        gl.addWidget(hl, 0, 3, 4, 1)

        bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        gl.addWidget(bb, 4, 0, 1, 0)

        if editing:
            db = self.gui.current_db
            virt_libs = db.prefs.get('virtual_libraries', {})
            for dex,vl in enumerate(sorted(virt_libs.keys(), key=sort_key)):
                self.vl_name.addItem(vl, virt_libs.get(vl, ''))
                if vl == editing:
                    self.vl_name.setCurrentIndex(dex)
                    self.original_index = dex
            self.original_search = virt_libs.get(editing, '')
            self.vl_text.setText(self.original_search)
            self.new_name = editing
            self.vl_name.currentIndexChanged[int].connect(self.name_index_changed)
            self.vl_name.lineEdit().textEdited.connect(self.name_text_edited)

        self.resize(self.sizeHint()+QSize(150, 25))
Пример #26
0
    def __init__(self,
                 parent,
                 text,
                 mi=None,
                 fm=None,
                 color_field=None,
                 icon_field_key=None,
                 icon_rule_kind=None,
                 doing_emblem=False,
                 text_is_placeholder=False):
        QDialog.__init__(self, parent)
        Ui_TemplateDialog.__init__(self)
        self.setupUi(self)

        self.coloring = color_field is not None
        self.iconing = icon_field_key is not None
        self.embleming = doing_emblem

        cols = []
        if fm is not None:
            for key in sorted(displayable_columns(fm),
                              key=lambda k: sort_key(fm[k]['name'])
                              if k != color_row_key else 0):
                if key == color_row_key and not self.coloring:
                    continue
                from calibre.gui2.preferences.coloring import all_columns_string
                name = all_columns_string if key == color_row_key else fm[key][
                    'name']
                if name:
                    cols.append((name, key))

        self.color_layout.setVisible(False)
        self.icon_layout.setVisible(False)

        if self.coloring:
            self.color_layout.setVisible(True)
            for n1, k1 in cols:
                self.colored_field.addItem(n1, k1)
            self.colored_field.setCurrentIndex(
                self.colored_field.findData(color_field))
        elif self.iconing or self.embleming:
            self.icon_layout.setVisible(True)
            if self.embleming:
                self.icon_kind_label.setVisible(False)
                self.icon_kind.setVisible(False)
                self.icon_chooser_label.setVisible(False)
                self.icon_field.setVisible(False)

            for n1, k1 in cols:
                self.icon_field.addItem(n1, k1)
            self.icon_file_names = []
            d = os.path.join(config_dir, 'cc_icons')
            if os.path.exists(d):
                for icon_file in os.listdir(d):
                    icon_file = icu_lower(icon_file)
                    if os.path.exists(os.path.join(d, icon_file)):
                        if icon_file.endswith('.png'):
                            self.icon_file_names.append(icon_file)
            self.icon_file_names.sort(key=sort_key)
            self.update_filename_box()

            if self.iconing:
                dex = 0
                from calibre.gui2.preferences.coloring import icon_rule_kinds
                for i, tup in enumerate(icon_rule_kinds):
                    txt, val = tup
                    self.icon_kind.addItem(txt, userData=(val))
                    if val == icon_rule_kind:
                        dex = i
                self.icon_kind.setCurrentIndex(dex)
                self.icon_field.setCurrentIndex(
                    self.icon_field.findData(icon_field_key))

        if mi:
            self.mi = mi
        else:
            self.mi = Metadata(_('Title'), [_('Author')])
            self.mi.author_sort = _('Author Sort')
            self.mi.series = ngettext('Series', 'Series', 1)
            self.mi.series_index = 3
            self.mi.rating = 4.0
            self.mi.tags = [_('Tag 1'), _('Tag 2')]
            self.mi.languages = ['eng']
            self.mi.id = 1
            if fm is not None:
                self.mi.set_all_user_metadata(fm.custom_field_metadata())
            else:
                # No field metadata. Grab a copy from the current library so
                # that we can validate any custom column names. The values for
                # the columns will all be empty, which in some very unusual
                # cases might cause formatter errors. We can live with that.
                from calibre.gui2.ui import get_gui
                self.mi.set_all_user_metadata(get_gui(
                ).current_db.new_api.field_metadata.custom_field_metadata())

        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.last_text = ''
        self.highlighter = TemplateHighlighter(self.textbox.document())
        self.textbox.cursorPositionChanged.connect(self.text_cursor_changed)
        self.textbox.textChanged.connect(self.textbox_changed)

        self.textbox.setTabStopWidth(10)
        self.source_code.setTabStopWidth(10)
        self.documentation.setReadOnly(True)
        self.source_code.setReadOnly(True)

        if text is not None:
            if text_is_placeholder:
                self.textbox.setPlaceholderText(text)
            else:
                self.textbox.setPlainText(text)
        self.buttonBox.button(QDialogButtonBox.Ok).setText(_('&OK'))
        self.buttonBox.button(QDialogButtonBox.Cancel).setText(_('&Cancel'))
        self.color_copy_button.clicked.connect(self.color_to_clipboard)
        self.filename_button.clicked.connect(self.filename_button_clicked)
        self.icon_copy_button.clicked.connect(self.icon_to_clipboard)

        try:
            with open(P('template-functions.json'), 'rb') as f:
                self.builtin_source_dict = json.load(f, encoding='utf-8')
        except:
            self.builtin_source_dict = {}

        self.funcs = formatter_functions().get_functions()
        self.builtins = formatter_functions().get_builtins()

        func_names = sorted(self.funcs)
        self.function.clear()
        self.function.addItem('')
        self.function.addItems(func_names)
        self.function.setCurrentIndex(0)
        self.function.currentIndexChanged[str].connect(self.function_changed)
        self.textbox_changed()
        self.rule = (None, '')

        tt = _('Template language tutorial')
        self.template_tutorial.setText(
            '<a href="%s">%s</a>' % (localize_user_manual_link(
                'https://manual.calibre-ebook.com/template_lang.html'), tt))
        tt = _('Template function reference')
        self.template_func_reference.setText(
            '<a href="%s">%s</a>' % (localize_user_manual_link(
                'https://manual.calibre-ebook.com/generated/en/template_ref.html'
            ), tt))

        self.font_size_box.setValue(gprefs['gpm_template_editor_font_size'])
        self.font_size_box.valueChanged.connect(self.font_size_changed)
Пример #27
0
 def show_help(self, *args):
     open_url(
         QUrl(localize_user_manual_link('http://manual.calibre-ebook.com')))
Пример #28
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QVBoxLayout(self)
        self.h = h = QHBoxLayout()

        self.la = la = QLabel(self.MSG)
        la.setWordWrap(True)
        l.addWidget(la)
        l.addLayout(h)
        english_sentence = '{preamble} {property} {match_type} {query}'
        sentence = _('{preamble} {property} {match_type} {query}')
        if set(sentence.split()) != set(english_sentence.split()):
            sentence = english_sentence
        parts = sentence.split()
        for clause in parts:
            if clause == '{preamble}':
                self.preamble = w = QLabel(_('If the &property:'))
            elif clause == '{property}':
                self.property = w = QLineEdit(self)
                w.setToolTip(
                    _('The name of a CSS property, for example: font-size\n'
                      'Do not use shorthand properties, they will not work.\n'
                      'For instance use margin-top, not margin.'))
            elif clause == '{match_type}':
                self.match_type = w = QComboBox(self)
                for action, text in iteritems(MATCH_TYPE_MAP):
                    w.addItem(text, action)
                w.currentIndexChanged.connect(self.update_state)
            elif clause == '{query}':
                self.query = w = QLineEdit(self)
            h.addWidget(w)
            if clause is not parts[-1]:
                h.addWidget(QLabel('\xa0'))
        self.preamble.setBuddy(self.property)

        self.h2 = h = QHBoxLayout()
        l.addLayout(h)
        english_sentence = '{action} {action_data}'
        sentence = _('{action} {action_data}')
        if set(sentence.split()) != set(english_sentence.split()):
            sentence = english_sentence
        parts = sentence.split()
        for clause in parts:
            if clause == '{action}':
                self.action = w = QComboBox(self)
                for action, text in iteritems(ACTION_MAP):
                    w.addItem(text, action)
                w.currentIndexChanged.connect(self.update_state)
            elif clause == '{action_data}':
                self.action_data = w = QLineEdit(self)
            h.addWidget(w)
            if clause is not parts[-1]:
                h.addWidget(QLabel('\xa0'))

        self.regex_help = la = QLabel(
            '<p>' + RE.REGEXP_HELP_TEXT % localize_user_manual_link(
                'https://manual.calibre-ebook.com/regexp.html'))
        la.setOpenExternalLinks(True)
        la.setWordWrap(True)
        l.addWidget(la)
        l.addStretch(10)

        self.update_state()
Пример #29
0
 def show_help(self, which):
     if which == 'viewer':
         safe_open_url(
             localize_user_manual_link(
                 'https://manual.calibre-ebook.com/viewer.html'))
Пример #30
0
def create_option_parser():
    parser = opts_to_parser(
        '%prog ' + _(
            '''[options] [path to library folder...]

Start the calibre Content server. The calibre Content server exposes your
calibre libraries over the internet. You can specify the path to the library
folders as arguments to %prog. If you do not specify any paths, all the
libraries that the main calibre program knows about will be used.
'''))
    parser.add_option(
        '--log',
        default=None,
        help=_(
            'Path to log file for server log. This log contains server information and errors, not access logs. By default it is written to stdout.'
        ))
    parser.add_option(
        '--access-log',
        default=None,
        help=_(
            'Path to the access log file. This log contains information'
            ' about clients connecting to the server and making requests. By'
            ' default no access logging is done.'))
    parser.add_option(
        '--custom-list-template', help=_(
            'Path to a JSON file containing a template for the custom book list mode.'
            ' The easiest way to create such a template file is to go to Preferences->'
            ' Sharing over the net-> Book list template in calibre, create the'
            ' template and export it.'
    ))
    if not iswindows and not isosx:
        # Does not work on macOS because if we fork() we cannot connect to Core
        # Serives which is needed by the QApplication() constructor, which in
        # turn is needed by ensure_app()
        parser.add_option(
            '--daemonize',
            default=False,
            action='store_true',
            help=_('Run process in background as a daemon (Linux only).'))
    parser.add_option(
        '--pidfile', default=None, help=_('Write process PID to the specified file'))
    parser.add_option(
        '--auto-reload',
        default=False,
        action='store_true',
        help=_(
            'Automatically reload server when source code changes. Useful'
            ' for development. You should also specify a small value for the'
            ' shutdown timeout.'))
    parser.add_option(
        '--manage-users',
        default=False,
        action='store_true',
        help=_(
            'Manage the database of users allowed to connect to this server.'
            ' See also the %s option.') % '--userdb')
    parser.get_option('--userdb').help = _(
        'Path to the user database to use for authentication. The database'
        ' is a SQLite file. To create it use {0}. You can read more'
        ' about managing users at: {1}'
    ).format(
        '--manage-users',
        localize_user_manual_link(
            'https://manual.calibre-ebook.com/server.html#managing-user-accounts-from-the-command-line-only'
        ))

    return parser
Пример #31
0
output_file. output_file can also be of the special format .EXT where \
EXT is the output file extension. In this case, the name of the output \
file is derived from the name of the input file. Note that the filenames must \
not start with a hyphen. Finally, if output_file has no extension, then \
it is treated as a directory and an "open e-book" (OEB) consisting of HTML \
files is written to that directory. These files are the files that would \
normally have been passed to the output plugin.

After specifying the input \
and output file you can customize the conversion by specifying various \
options. The available options depend on the input and output file types. \
To get help on them specify the input and output file and then use the -h \
option.

For full documentation of the conversion system see
''') + localize_user_manual_link('https://manual.calibre-ebook.com/conversion.html')

HEURISTIC_OPTIONS = ['markup_chapter_headings',
                      'italicize_common_cases', 'fix_indents',
                      'html_unwrap_factor', 'unwrap_lines',
                      'delete_blank_paragraphs', 'format_scene_breaks',
                      'dehyphenate', 'renumber_headings',
                      'replace_scene_breaks']

DEFAULT_TRUE_OPTIONS = HEURISTIC_OPTIONS + ['remove_fake_margins']


def print_help(parser, log):
    parser.print_help()

Пример #32
0
def create_option_parser():
    parser = opts_to_parser(
        '%prog ' + _(
            '''[options] [path to library folder...]

Start the calibre Content server. The calibre Content server exposes your
calibre libraries over the internet. You can specify the path to the library
folders as arguments to %prog. If you do not specify any paths, all the
libraries that the main calibre program knows about will be used.
'''))
    parser.add_option(
        '--log',
        default=None,
        help=_(
            'Path to log file for server log. This log contains server information and errors, not access logs. By default it is written to stdout.'
        ))
    parser.add_option(
        '--access-log',
        default=None,
        help=_(
            'Path to the access log file. This log contains information'
            ' about clients connecting to the server and making requests. By'
            ' default no access logging is done.'))
    parser.add_option(
        '--custom-list-template', help=_(
            'Path to a JSON file containing a template for the custom book list mode.'
            ' The easiest way to create such a template file is to go to Preferences->'
            ' Sharing over the net-> Book list template in calibre, create the'
            ' template and export it.'
    ))
    if not iswindows and not isosx:
        # Does not work on macOS because if we fork() we cannot connect to Core
        # Serives which is needed by the QApplication() constructor, which in
        # turn is needed by ensure_app()
        parser.add_option(
            '--daemonize',
            default=False,
            action='store_true',
            help=_('Run process in background as a daemon (Linux only).'))
    parser.add_option(
        '--pidfile', default=None, help=_('Write process PID to the specified file'))
    parser.add_option(
        '--auto-reload',
        default=False,
        action='store_true',
        help=_(
            'Automatically reload server when source code changes. Useful'
            ' for development. You should also specify a small value for the'
            ' shutdown timeout.'))
    parser.add_option(
        '--manage-users',
        default=False,
        action='store_true',
        help=_(
            'Manage the database of users allowed to connect to this server.'
            ' See also the %s option.') % '--userdb')
    parser.get_option('--userdb').help = _(
        'Path to the user database to use for authentication. The database'
        ' is a SQLite file. To create it use {0}. You can read more'
        ' about managing users at: {1}'
    ).format(
        '--manage-users',
        localize_user_manual_link(
            'https://manual.calibre-ebook.com/server.html#managing-user-accounts-from-the-command-line-only'
        ))

    return parser
Пример #33
0
    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.um_label.setText(self.um_label.text() % localize_user_manual_link('http://manual.calibre-ebook.com/gui.html#the-search-interface'))
        for val, text in [(0, '')] + [(i, date(2010, i, 1).strftime('%B')) for i in xrange(1, 13)]:
            self.date_month.addItem(text, val)
        for val, text in [('today', _('Today')), ('yesterday', _('Yesterday')), ('thismonth', _('This month'))]:
            self.date_human.addItem(text, val)
        self.date_year.setValue(now().year)
        self.date_day.setSpecialValueText(u' \xa0')
        vals = [((v['search_terms'] or [k])[0], v['name'] or k) for k, v in db.field_metadata.iteritems() if v.get('datatype', None) == 'datetime']
        for k, v in sorted(vals, key=lambda (k, v): sort_key(v)):
            self.date_field.addItem(v, k)

        self.date_year.valueChanged.connect(lambda : self.sel_date.setChecked(True))
        self.date_month.currentIndexChanged.connect(lambda : self.sel_date.setChecked(True))
        self.date_day.valueChanged.connect(lambda : self.sel_date.setChecked(True))
        self.date_daysago.valueChanged.connect(lambda : self.sel_daysago.setChecked(True))
        self.date_human.currentIndexChanged.connect(lambda : self.sel_human.setChecked(True))
        init_dateop(self.dateop_date)
        self.sel_date.setChecked(True)
        self.mc = ''
        searchables = sorted(db.field_metadata.searchable_fields(),
                             key=lambda x: sort_key(x if x[0] != '#' else x[1:]))
        self.general_combo.addItems(searchables)

        all_authors = db.all_authors()
        all_authors.sort(key=lambda x : sort_key(x[1]))
        self.authors_box.setEditText('')
        self.authors_box.set_separator('&')
        self.authors_box.set_space_before_sep(True)
        self.authors_box.set_add_separator(tweaks['authors_completer_append_separator'])
        self.authors_box.update_items_cache(db.all_author_names())

        all_series = db.all_series()
        all_series.sort(key=lambda x : sort_key(x[1]))
        self.series_box.set_separator(None)
        self.series_box.update_items_cache([x[1] for x in all_series])
        self.series_box.show_initial_value('')

        all_tags = db.all_tags()
        self.tags_box.update_items_cache(all_tags)

        self.box_last_values = copy.deepcopy(box_values)
        if self.box_last_values:
            for k,v in self.box_last_values.items():
                if k == 'general_index':
                    continue
                getattr(self, k).setText(v)
            self.general_combo.setCurrentIndex(
                    self.general_combo.findText(self.box_last_values['general_index']))

        self.clear_button.clicked.connect(self.clear_button_pushed)

        current_tab = gprefs.get('advanced search dialog current tab', 0)
        self.tabWidget.setCurrentIndex(current_tab)
        if current_tab == 1:
            self.matchkind.setCurrentIndex(last_matchkind)

        self.tabWidget.currentChanged[int].connect(self.tab_changed)
        self.tab_changed(current_tab)
        self.resize(self.sizeHint())
Пример #34
0
output_file. output_file can also be of the special format .EXT where \
EXT is the output file extension. In this case, the name of the output \
file is derived from the name of the input file. Note that the filenames must \
not start with a hyphen. Finally, if output_file has no extension, then \
it is treated as a directory and an "open e-book" (OEB) consisting of HTML \
files is written to that directory. These files are the files that would \
normally have been passed to the output plugin.

After specifying the input \
and output file you can customize the conversion by specifying various \
options. The available options depend on the input and output file types. \
To get help on them specify the input and output file and then use the -h \
option.

For full documentation of the conversion system see
''') + localize_user_manual_link(
    'https://manual.calibre-ebook.com/conversion.html')

HEURISTIC_OPTIONS = [
    'markup_chapter_headings', 'italicize_common_cases', 'fix_indents',
    'html_unwrap_factor', 'unwrap_lines', 'delete_blank_paragraphs',
    'format_scene_breaks', 'dehyphenate', 'renumber_headings',
    'replace_scene_breaks'
]

DEFAULT_TRUE_OPTIONS = HEURISTIC_OPTIONS + ['remove_fake_margins']


def print_help(parser, log):
    parser.print_help()

Пример #35
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QVBoxLayout(self)
        self.h = h = QHBoxLayout()

        self.la = la = QLabel(self.MSG)
        la.setWordWrap(True)
        l.addWidget(la)
        l.addLayout(h)
        english_sentence = '{preamble} {property} {match_type} {query}'
        sentence = _('{preamble} {property} {match_type} {query}')
        if set(sentence.split()) != set(english_sentence.split()):
            sentence = english_sentence
        parts = sentence.split()
        for clause in parts:
            if clause == '{preamble}':
                self.preamble = w = QLabel(_('If the &property:'))
            elif clause == '{property}':
                self.property = w = QLineEdit(self)
                w.setToolTip(_('The name of a CSS property, for example: font-size\n'
                               'Do not use shorthand properties, they will not work.\n'
                               'For instance use margin-top, not margin.'))
            elif clause == '{match_type}':
                self.match_type = w = QComboBox(self)
                for action, text in iteritems(MATCH_TYPE_MAP):
                    w.addItem(text, action)
                w.currentIndexChanged.connect(self.update_state)
            elif clause == '{query}':
                self.query = w = QLineEdit(self)
            h.addWidget(w)
            if clause is not parts[-1]:
                h.addWidget(QLabel('\xa0'))
        self.preamble.setBuddy(self.property)

        self.h2 = h = QHBoxLayout()
        l.addLayout(h)
        english_sentence = '{action} {action_data}'
        sentence = _('{action} {action_data}')
        if set(sentence.split()) != set(english_sentence.split()):
            sentence = english_sentence
        parts = sentence.split()
        for clause in parts:
            if clause == '{action}':
                self.action = w = QComboBox(self)
                for action, text in iteritems(ACTION_MAP):
                    w.addItem(text, action)
                w.currentIndexChanged.connect(self.update_state)
            elif clause == '{action_data}':
                self.action_data = w = QLineEdit(self)
            h.addWidget(w)
            if clause is not parts[-1]:
                h.addWidget(QLabel('\xa0'))

        self.regex_help = la = QLabel('<p>' + RE.REGEXP_HELP_TEXT % localize_user_manual_link(
        'https://manual.calibre-ebook.com/regexp.html'))
        la.setOpenExternalLinks(True)
        la.setWordWrap(True)
        l.addWidget(la)
        l.addStretch(10)

        self.update_state()
Пример #36
0
    def create_actions(self):
        group = _('Global Actions')

        def reg(icon, text, target, sid, keys, description, toolbar_allowed=False):
            if not isinstance(icon, QIcon):
                icon = QIcon(I(icon))
            ac = actions[sid] = QAction(icon, text, self) if icon else QAction(text, self)
            ac.setObjectName('action-' + sid)
            if toolbar_allowed:
                toolbar_actions[sid] = ac
            if target is not None:
                ac.triggered.connect(target)
            if isinstance(keys, type('')):
                keys = (keys,)
            self.keyboard.register_shortcut(
                sid, unicode(ac.text()).replace('&', ''), default_keys=keys, description=description, action=ac, group=group)
            self.addAction(ac)
            return ac
        def treg(icon, text, target, sid, keys, description):
            return reg(icon, text, target, sid, keys, description, toolbar_allowed=icon is not None)

        self.action_new_file = treg('document-new.png', _('&New file (images/fonts/HTML/etc.)'), self.boss.add_file,
                                   'new-file', (), _('Create a new file in the current book'))
        self.action_import_files = treg('document-import.png', _('&Import files into book'), self.boss.add_files, 'new-files', (), _('Import files into book'))
        self.action_open_book = treg('document_open.png', _('Open &book'), self.boss.open_book, 'open-book', 'Ctrl+O', _('Open a new book'))
        self.action_open_book_folder = treg('mimetypes/dir.png', _('Open &folder (unzipped EPUB) as book'), partial(self.boss.open_book, open_folder=True),
                                            'open-folder-as-book', (), _('Open a folder (unzipped EPUB) as a book'))
        # Qt does not generate shortcut overrides for cmd+arrow on os x which
        # means these shortcuts interfere with editing
        self.action_global_undo = treg('back.png', _('&Revert to before'), self.boss.do_global_undo, 'global-undo', () if isosx else 'Ctrl+Left',
                                      _('Revert book to before the last action (Undo)'))
        self.action_global_redo = treg('forward.png', _('&Revert to after'), self.boss.do_global_redo, 'global-redo', () if isosx else 'Ctrl+Right',
                                      _('Revert book state to after the next action (Redo)'))
        self.action_save = treg('save.png', _('&Save'), self.boss.save_book, 'save-book', 'Ctrl+S', _('Save book'))
        self.action_save.setEnabled(False)
        self.action_save_copy = treg('save.png', _('Save a &copy'), self.boss.save_copy, 'save-copy', 'Ctrl+Alt+S', _('Save a copy of the book'))
        self.action_quit = treg('window-close.png', _('&Quit'), self.boss.quit, 'quit', 'Ctrl+Q', _('Quit'))
        self.action_preferences = treg('config.png', _('&Preferences'), self.boss.preferences, 'preferences', 'Ctrl+P', _('Preferences'))
        self.action_new_book = treg('plus.png', _('Create &new, empty book'), self.boss.new_book, 'new-book', (), _('Create a new, empty book'))
        self.action_import_book = treg('add_book.png', _('&Import an HTML or DOCX file as a new book'),
                                      self.boss.import_book, 'import-book', (), _('Import an HTML or DOCX file as a new book'))
        self.action_quick_edit = treg('modified.png', _('&Quick open a file to edit'), self.boss.quick_open, 'quick-open', ('Ctrl+T'), _(
            'Quickly open a file from the book to edit it'))

        # Editor actions
        group = _('Editor actions')
        self.action_editor_undo = reg('edit-undo.png', _('&Undo'), self.boss.do_editor_undo, 'editor-undo', 'Ctrl+Z',
                                      _('Undo typing'))
        self.action_editor_redo = reg('edit-redo.png', _('&Redo'), self.boss.do_editor_redo, 'editor-redo', 'Ctrl+Y',
                                      _('Redo typing'))
        self.action_editor_cut = reg('edit-cut.png', _('C&ut text'), self.boss.do_editor_cut, 'editor-cut', ('Ctrl+X', 'Shift+Delete', ),
                                      _('Cut text'))
        self.action_editor_copy = reg('edit-copy.png', _('&Copy to clipboard'), self.boss.do_editor_copy, 'editor-copy', ('Ctrl+C', 'Ctrl+Insert'),
                                      _('Copy to clipboard'))
        self.action_editor_paste = reg('edit-paste.png', _('&Paste from clipboard'), self.boss.do_editor_paste, 'editor-paste', ('Ctrl+V', 'Shift+Insert', ),
                                      _('Paste from clipboard'))
        self.action_editor_cut.setEnabled(False)
        self.action_editor_copy.setEnabled(False)
        self.action_editor_undo.setEnabled(False)
        self.action_editor_redo.setEnabled(False)

        # Tool actions
        group = _('Tools')
        self.action_toc = treg('toc.png', _('&Edit Table of Contents'), self.boss.edit_toc, 'edit-toc', (), _('Edit Table of Contents'))
        self.action_inline_toc = treg('chapters.png', _('&Insert inline Table of Contents'),
                                     self.boss.insert_inline_toc, 'insert-inline-toc', (), _('Insert inline Table of Contents'))
        self.action_fix_html_current = reg('html-fix.png', _('&Fix HTML'), partial(self.boss.fix_html, True), 'fix-html-current', (),
                                           _('Fix HTML in the current file'))
        self.action_fix_html_all = treg('html-fix.png', _('&Fix HTML - all files'), partial(self.boss.fix_html, False), 'fix-html-all', (),
                                       _('Fix HTML in all files'))
        self.action_pretty_current = reg('beautify.png', _('&Beautify current file'), partial(self.boss.pretty_print, True), 'pretty-current', (),
                                           _('Beautify current file'))
        self.action_pretty_all = treg('beautify.png', _('&Beautify all files'), partial(self.boss.pretty_print, False), 'pretty-all', (),
                                       _('Beautify all files'))
        self.action_insert_char = treg('character-set.png', _('&Insert special character'), self.boss.insert_character, 'insert-character', (),
                                      _('Insert special character'))
        self.action_rationalize_folders = treg('mimetypes/dir.png', _('&Arrange into folders'), self.boss.rationalize_folders, 'rationalize-folders', (),
                                      _('Arrange into folders'))
        self.action_set_semantics = treg('tags.png', _('Set &Semantics'), self.boss.set_semantics, 'set-semantics', (),
                                        _('Set Semantics'))
        self.action_filter_css = treg('filter.png', _('&Filter style information'), self.boss.filter_css, 'filter-css', (),
                                     _('Filter style information'))
        self.action_manage_fonts = treg('font.png', _('Manage &fonts'), self.boss.manage_fonts, 'manage-fonts', (), _('Manage fonts in the book'))
        self.action_add_cover = treg('default_cover.png', _('Add &cover'), self.boss.add_cover, 'add-cover', (), _('Add a cover to the book'))
        self.action_reports = treg(
            'reports.png', _('&Reports'), self.boss.show_reports, 'show-reports', ('Ctrl+Shift+R',), _('Show a report on various aspects of the book'))
        self.action_check_external_links = treg('insert-link.png', _('Check &external links'), self.boss.check_external_links, 'check-external-links', (), _(
            'Check external links in the book'))

        def ereg(icon, text, target, sid, keys, description):
            return reg(icon, text, partial(self.boss.editor_action, target), sid, keys, description)
        register_text_editor_actions(ereg, self.palette())

        # Polish actions
        group = _('Polish Book')
        self.action_subset_fonts = treg(
            'subset-fonts.png', _('&Subset embedded fonts'), partial(
                self.boss.polish, 'subset', _('Subset fonts')), 'subset-fonts', (), _('Subset embedded fonts'))
        self.action_embed_fonts = treg(
            'embed-fonts.png', _('&Embed referenced fonts'), partial(
                self.boss.polish, 'embed', _('Embed fonts')), 'embed-fonts', (), _('Embed referenced fonts'))
        self.action_smarten_punctuation = treg(
            'smarten-punctuation.png', _('&Smarten punctuation'), partial(
                self.boss.polish, 'smarten_punctuation', _('Smarten punctuation')), 'smarten-punctuation', (), _('Smarten punctuation'))
        self.action_remove_unused_css = treg(
            'edit-clear.png', _('Remove &unused CSS rules'), partial(
                self.boss.polish, 'remove_unused_css', _('Remove unused CSS rules')), 'remove-unused-css', (), _('Remove unused CSS rules'))

        # Preview actions
        group = _('Preview')
        self.action_auto_reload_preview = reg('auto-reload.png', _('Auto reload preview'), None, 'auto-reload-preview', (), _('Auto reload preview'))
        self.action_auto_sync_preview = reg('sync-right.png', _('Sync preview position to editor position'), None, 'sync-preview-to-editor', (), _(
            'Sync preview position to editor position'))
        self.action_reload_preview = reg('view-refresh.png', _('Refresh preview'), None, 'reload-preview', ('F5',), _('Refresh preview'))
        self.action_split_in_preview = reg('auto_author_sort.png', _('Split this file'), None, 'split-in-preview', (), _(
            'Split file in the preview panel'))
        self.action_find_next_preview = reg('arrow-down.png', _('Find Next'), None, 'find-next-preview', (), _('Find next in preview'))
        self.action_find_prev_preview = reg('arrow-up.png', _('Find Previous'), None, 'find-prev-preview', (), _('Find previous in preview'))

        # Search actions
        group = _('Search')
        self.action_find = treg('search.png', _('&Find/Replace'), self.boss.show_find, 'find-replace', ('Ctrl+F',), _('Show the Find/Replace panel'))
        def sreg(name, text, action, overrides={}, keys=(), description=None, icon=None):
            return reg(icon, text, partial(self.boss.search_action_triggered, action, overrides), name, keys, description or text.replace('&', ''))
        self.action_find_next = sreg('find-next', _('Find &Next'),
                                     'find', {'direction':'down'}, ('F3', 'Ctrl+G'), _('Find next match'))
        self.action_find_previous = sreg('find-previous', _('Find &Previous'),
                                         'find', {'direction':'up'}, ('Shift+F3', 'Shift+Ctrl+G'), _('Find previous match'))
        self.action_replace = sreg('replace', _('Replace'),
                                   'replace', keys=('Ctrl+R'), description=_('Replace current match'))
        self.action_replace_next = sreg('replace-next', _('&Replace and find next'),
                                        'replace-find', {'direction':'down'}, ('Ctrl+]'), _('Replace current match and find next'))
        self.action_replace_previous = sreg('replace-previous', _('R&eplace and find previous'),
                                        'replace-find', {'direction':'up'}, ('Ctrl+['), _('Replace current match and find previous'))
        self.action_replace_all = sreg('replace-all', _('Replace &all'),
                                   'replace-all', keys=('Ctrl+A'), description=_('Replace all matches'))
        self.action_count = sreg('count-matches', _('&Count all'),
                                   'count', keys=('Ctrl+N'), description=_('Count number of matches'))
        self.action_mark = reg(None, _('&Mark selected text'), self.boss.mark_selected_text, 'mark-selected-text', ('Ctrl+Shift+M',),
                               _('Mark selected text or unmark already marked text'))
        self.action_mark.default_text = self.action_mark.text()
        self.action_go_to_line = reg(None, _('Go to &line'), self.boss.go_to_line_number, 'go-to-line-number', ('Ctrl+.',), _('Go to line number'))
        self.action_saved_searches = treg('folder_saved_search.png', _('Sa&ved searches'),
                                          self.boss.saved_searches, 'saved-searches', (), _('Show the saved searches dialog'))

        # Check Book actions
        group = _('Check Book')
        self.action_check_book = treg('debug.png', _('&Check Book'), self.boss.check_requested, 'check-book', ('F7'), _('Check book for errors'))
        self.action_spell_check_book = treg('spell-check.png', _('Check &spelling'), self.boss.spell_check_requested, 'spell-check-book', ('Alt+F7'), _(
            'Check book for spelling errors'))
        self.action_check_book_next = reg('forward.png', _('&Next error'), partial(
            self.check_book.next_error, delta=1), 'check-book-next', ('Ctrl+F7'), _('Show next error'))
        self.action_check_book_previous = reg('back.png', _('&Previous error'), partial(
            self.check_book.next_error, delta=-1), 'check-book-previous', ('Ctrl+Shift+F7'), _('Show previous error'))
        self.action_spell_check_next = reg('forward.png', _('&Next spelling mistake'),
            self.boss.next_spell_error, 'spell-next', ('F8'), _('Go to next spelling mistake'))

        # Miscellaneous actions
        group = _('Miscellaneous')
        self.action_create_checkpoint = treg(
            'marked.png', _('&Create checkpoint'), self.boss.create_checkpoint, 'create-checkpoint', (), _(
                'Create a checkpoint with the current state of the book'))
        self.action_close_current_tab = reg(
            'window-close.png', _('&Close current tab'), self.central.close_current_editor, 'close-current-tab', 'Ctrl+W', _(
                'Close the currently open tab'))
        self.action_close_all_but_current_tab = reg(
            'edit-clear.png', _('&Close other tabs'), self.central.close_all_but_current_editor, 'close-all-but-current-tab', 'Ctrl+Alt+W', _(
                'Close all tabs except the current tab'))
        self.action_help = treg(
            'help.png', _('User &Manual'), lambda : open_url(QUrl(localize_user_manual_link(
                'http://manual.calibre-ebook.com/edit.html'))), 'user-manual', 'F1', _(
                'Show User Manual'))
        self.action_browse_images = treg(
            'view-image.png', _('&Browse images in book'), self.boss.browse_images, 'browse-images', (), _(
                'Browse images in the books visually'))
        self.action_multiple_split = treg(
            'auto_author_sort.png', _('&Split at multiple locations'), self.boss.multisplit, 'multisplit', (), _(
                'Split HTML file at multiple locations'))
        self.action_compare_book = treg('diff.png', _('&Compare to another book'), self.boss.compare_book, 'compare-book', (), _(
            'Compare to another book'))
        self.action_manage_snippets = treg(
            'snippets.png', _('Manage &Snippets'), self.boss.manage_snippets, 'manage-snippets', (), _(
                'Manage user created snippets'))

        self.plugin_menu_actions = []

        create_plugin_actions(actions, toolbar_actions, self.plugin_menu_actions)
Пример #37
0
    def __init__(self, gui, existing_names, editing=None):
        QDialog.__init__(self, gui)

        self.gui = gui
        self.existing_names = existing_names

        if editing:
            self.setWindowTitle(_('Edit virtual library'))
        else:
            self.setWindowTitle(_('Create virtual library'))
        self.setWindowIcon(QIcon(I('lt.png')))

        gl = QGridLayout()
        self.setLayout(gl)
        self.la1 = la1 = QLabel(_('Virtual library &name:'))
        gl.addWidget(la1, 0, 0)
        self.vl_name = QComboBox()
        self.vl_name.setEditable(True)
        self.vl_name.lineEdit().setMaxLength(MAX_VIRTUAL_LIBRARY_NAME_LENGTH)
        la1.setBuddy(self.vl_name)
        gl.addWidget(self.vl_name, 0, 1)
        self.editing = editing

        self.saved_searches_label = QLabel('')
        self.saved_searches_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        gl.addWidget(self.saved_searches_label, 2, 0, 1, 2)

        self.la2 = la2 = QLabel(_('&Search expression:'))
        gl.addWidget(la2, 1, 0)
        self.vl_text = QLineEdit()
        self.vl_text.textChanged.connect(self.search_text_changed)
        la2.setBuddy(self.vl_text)
        gl.addWidget(self.vl_text, 1, 1)
        self.vl_text.setText(_build_full_search_string(self.gui))

        self.sl = sl = QLabel('<p>'+_('Create a virtual library based on: ')+
            ('<a href="author.{0}">{0}</a>, '
            '<a href="tag.{1}">{1}</a>, '
            '<a href="publisher.{2}">{2}</a>, '
            '<a href="series.{3}">{3}</a>, '
            '<a href="search.{4}">{4}</a>.').format(_('Authors'), _('Tags'),
                                            _('Publishers'), _('Series'), _('Saved Searches')))
        sl.setWordWrap(True)
        sl.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        sl.linkActivated.connect(self.link_activated)
        gl.addWidget(sl, 3, 0, 1, 2)
        gl.setRowStretch(3,10)

        self.hl = hl = QLabel(_('''
            <h2>Virtual Libraries</h2>

            <p>Using <i>virtual libraries</i> you can restrict calibre to only show
            you books that match a search. When a virtual library is in effect, calibre
            behaves as though the library contains only the matched books. The Tag Browser
            display only the tags/authors/series/etc. that belong to the matched books and any searches
            you do will only search within the books in the virtual library. This
            is a good way to partition your large library into smaller and easier to work with subsets.</p>

            <p>For example you can use a Virtual Library to only show you books with the Tag <i>"Unread"</i>
            or only books by <i>"My Favorite Author"</i> or only books in a particular series.</p>

            <p>More information and examples are available in the
            <a href="%s">User Manual</a>.</p>
            ''') % localize_user_manual_link('http://manual.calibre-ebook.com/virtual_libraries.html'))
        hl.setWordWrap(True)
        hl.setOpenExternalLinks(True)
        hl.setFrameStyle(hl.StyledPanel)
        gl.addWidget(hl, 0, 3, 4, 1)

        bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        gl.addWidget(bb, 4, 0, 1, 0)

        if editing:
            db = self.gui.current_db
            virt_libs = db.prefs.get('virtual_libraries', {})
            for dex,vl in enumerate(sorted(virt_libs.keys(), key=sort_key)):
                self.vl_name.addItem(vl, virt_libs.get(vl, ''))
                if vl == editing:
                    self.vl_name.setCurrentIndex(dex)
                    self.original_index = dex
            self.original_search = virt_libs.get(editing, '')
            self.vl_text.setText(self.original_search)
            self.new_name = editing
            self.vl_name.currentIndexChanged[int].connect(self.name_index_changed)
            self.vl_name.lineEdit().textEdited.connect(self.name_text_edited)

        self.resize(self.sizeHint()+QSize(150, 25))
Пример #38
0
    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.um_label.setText(self.um_label.text() % localize_user_manual_link(
            'http://manual.calibre-ebook.com/gui.html#the-search-interface'))
        for val, text in [(0, '')] + [(i, date(2010, i, 1).strftime('%B'))
                                      for i in xrange(1, 13)]:
            self.date_month.addItem(text, val)
        for val, text in [('today', _('Today')), ('yesterday', _('Yesterday')),
                          ('thismonth', _('This month'))]:
            self.date_human.addItem(text, val)
        self.date_year.setValue(now().year)
        self.date_day.setSpecialValueText(u' \xa0')
        vals = [((v['search_terms'] or [k])[0], v['name'] or k)
                for k, v in db.field_metadata.iteritems()
                if v.get('datatype', None) == 'datetime']
        for k, v in sorted(vals, key=lambda (k, v): sort_key(v)):
            self.date_field.addItem(v, k)

        self.date_year.valueChanged.connect(
            lambda: self.sel_date.setChecked(True))
        self.date_month.currentIndexChanged.connect(
            lambda: self.sel_date.setChecked(True))
        self.date_day.valueChanged.connect(
            lambda: self.sel_date.setChecked(True))
        self.date_daysago.valueChanged.connect(
            lambda: self.sel_daysago.setChecked(True))
        self.date_human.currentIndexChanged.connect(
            lambda: self.sel_human.setChecked(True))
        init_dateop(self.dateop_date)
        self.sel_date.setChecked(True)
        self.mc = ''
        searchables = sorted(db.field_metadata.searchable_fields(),
                             key=lambda x: sort_key(x
                                                    if x[0] != '#' else x[1:]))
        self.general_combo.addItems(searchables)

        all_authors = db.all_authors()
        all_authors.sort(key=lambda x: sort_key(x[1]))
        self.authors_box.setEditText('')
        self.authors_box.set_separator('&')
        self.authors_box.set_space_before_sep(True)
        self.authors_box.set_add_separator(
            tweaks['authors_completer_append_separator'])
        self.authors_box.update_items_cache(db.all_author_names())

        all_series = db.all_series()
        all_series.sort(key=lambda x: sort_key(x[1]))
        self.series_box.set_separator(None)
        self.series_box.update_items_cache([x[1] for x in all_series])
        self.series_box.show_initial_value('')

        all_tags = db.all_tags()
        self.tags_box.update_items_cache(all_tags)

        self.box_last_values = copy.deepcopy(box_values)
        if self.box_last_values:
            for k, v in self.box_last_values.items():
                if k == 'general_index':
                    continue
                getattr(self, k).setText(v)
            self.general_combo.setCurrentIndex(
                self.general_combo.findText(
                    self.box_last_values['general_index']))

        self.clear_button.clicked.connect(self.clear_button_pushed)

        current_tab = gprefs.get('advanced search dialog current tab', 0)
        self.tabWidget.setCurrentIndex(current_tab)
        if current_tab == 1:
            self.matchkind.setCurrentIndex(last_matchkind)

        self.tabWidget.currentChanged[int].connect(self.tab_changed)
        self.tab_changed(current_tab)
        self.resize(self.sizeHint())
Пример #39
0
 def set_move_lib_label_text(self):
     self.move_lib_label.setText(_(
         'If you are moving calibre from an old computer to a new one,'
         ' please read <a href="{0}">the instructions</a>.').format(
             localize_user_manual_link(
     'https://manual.calibre-ebook.com/faq.html#how-do-i-move-my-calibre-data-from-one-computer-to-another')))