Example #1
0
    def __InitData(self, sizeX, sizeY):
        self.__size = QSize(sizeX, sizeY)

        self.__board = QPixmap(
            self.__size)  # Make a new QPixmap as paint board,350px * 250px
        self.__board.fill(Qt.white)  #Fill the paint board with white

        self.__IsEmpty = True  #board is empty by default
        self.EraserMode = False  #eraser mode is disabled by default

        self.__lastPos = None
        self.__currentPos = QPoint(0, 0)

        self.__painter = QPainter()

        self.__thickness = 1  #default pen thickness is 1
        self.__penColor = QColor("black")  #default color is black
        self.__colorList = QColor.colorNames()  #get the list of colors
Example #2
0
    def __init__(self, parent, text, mi=None, fm=None, color_field=None):
        QDialog.__init__(self, parent)
        Ui_TemplateDialog.__init__(self)
        self.setupUi(self)

        self.coloring = color_field is not None
        if self.coloring:
            cols = sorted([k for k in displayable_columns(fm)])
            self.colored_field.addItems(cols)
            self.colored_field.setCurrentIndex(self.colored_field.findText(color_field))
            colors = QColor.colorNames()
            colors.sort()
            self.color_name.addItems(colors)
        else:
            self.colored_field.setVisible(False)
            self.colored_field_label.setVisible(False)
            self.color_chooser_label.setVisible(False)
            self.color_name.setVisible(False)
            self.color_copy_button.setVisible(False)
        if mi:
            self.mi = mi
        else:
            self.mi = Metadata(None, None)

        # 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:
            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)

        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="http://manual.calibre-ebook.com/template_lang.html">'
                '%s</a>'%tt)
        tt = _('Template function reference')
        self.template_func_reference.setText(
                '<a href="http://manual.calibre-ebook.com/template_ref.html">'
                '%s</a>'%tt)
Example #3
0
    def __init__(self, parent, text, mi=None, fm=None, color_field=None,
                 icon_field_key=None, icon_rule_kind=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

        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))
            colors = QColor.colorNames()
            colors.sort()
            self.color_name.addItems(colors)
        elif self.iconing:
            self.icon_layout.setVisible(True)
            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()
            self.icon_with_text.setChecked(True)
            if icon_rule_kind == 'icon_only':
                self.icon_without_text.setChecked(True)
            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 = _('Series')
            self.mi.series_index = 3
            self.mi.rating = 4.0
            self.mi.tags = [_('Tag 1'), _('Tag 2')]
            self.mi.languages = ['eng']
            if fm is not None:
                self.mi.set_all_user_metadata(fm.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:
            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="http://manual.calibre-ebook.com/template_lang.html">'
                '%s</a>'%tt)
        tt = _('Template function reference')
        self.template_func_reference.setText(
                '<a href="http://manual.calibre-ebook.com/template_ref.html">'
                '%s</a>'%tt)
Example #4
0
    def __init__(self, fm, parent=None):
        QDialog.__init__(self, parent)
        self.fm = fm

        self.setWindowIcon(QIcon(I('format-fill-color.png')))
        self.setWindowTitle(_('Create/edit a column coloring rule'))

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        self.l1 = l1 = QLabel(_('Create a coloring rule by'
            ' filling in the boxes below'))
        l.addWidget(l1, 0, 0, 1, 5)

        self.f1 = QFrame(self)
        self.f1.setFrameShape(QFrame.HLine)
        l.addWidget(self.f1, 1, 0, 1, 5)

        self.l2 = l2 = QLabel(_('Set the color of the column:'))
        l.addWidget(l2, 2, 0)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 2, 1)

        self.l3 = l3 = QLabel(_('to'))
        l.addWidget(l3, 2, 2)

        self.color_box = QComboBox(self)
        self.color_label = QLabel('Sample text Sample text')
        self.color_label.setTextFormat(Qt.RichText)
        l.addWidget(self.color_box, 2, 3)
        l.addWidget(self.color_label, 2, 4)
        l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 5)

        self.l4 = l4 = QLabel(
            _('Only if the following conditions are all satisfied:'))
        l.addWidget(l4, 3, 0, 1, 6)

        self.scroll_area = sa = QScrollArea(self)
        sa.setMinimumHeight(300)
        sa.setMinimumWidth(950)
        sa.setWidgetResizable(True)
        l.addWidget(sa, 4, 0, 1, 6)

        self.add_button = b = QPushButton(QIcon(I('plus.png')),
                _('Add another condition'))
        l.addWidget(b, 5, 0, 1, 6)
        b.clicked.connect(self.add_blank_condition)

        self.l5 = l5 = QLabel(_('You can disable a condition by'
            ' blanking all of its boxes'))
        l.addWidget(l5, 6, 0, 1, 6)

        self.bb = bb = QDialogButtonBox(
                QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        l.addWidget(bb, 7, 0, 1, 6)

        self.conditions_widget = QWidget(self)
        sa.setWidget(self.conditions_widget)
        self.conditions_widget.setLayout(QVBoxLayout())
        self.conditions_widget.layout().setAlignment(Qt.AlignTop)
        self.conditions = []

        for b in (self.column_box, self.color_box):
            b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
            b.setMinimumContentsLength(15)

        for key in sorted(
                displayable_columns(fm),
                key=sort_key):
            name = fm[key]['name']
            if name:
                self.column_box.addItem(key, key)
        self.column_box.setCurrentIndex(0)

        self.color_box.addItems(QColor.colorNames())
        self.color_box.setCurrentIndex(0)

        self.update_color_label()
        self.color_box.currentIndexChanged.connect(self.update_color_label)
        self.resize(self.sizeHint())
Example #5
0
    def __init__(self, parent, editing, standard_colheads, standard_colnames):
        QDialog.__init__(self, parent)
        Ui_QCreateCustomColumn.__init__(self)
        self.setupUi(self)
        self.setWindowTitle(_('Create a custom column'))
        self.heading_label.setText(_('Create a custom column'))
        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()
                            & (~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.simple_error = partial(error_dialog,
                                    self,
                                    show=True,
                                    show_copy_button=False)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)
        self.shortcuts.linkActivated.connect(self.shortcut_activated)
        text = '<p>' + _('Quick create:')
        for col, name in [('isbn', _('ISBN')), ('formats', _('Formats')),
                          ('yesno', _('Yes/No')), ('tags', _('Tags')),
                          ('series', _('Series')), ('rating', _('Rating')),
                          ('people', _("People's names"))]:
            text += ' <a href="col:%s">%s</a>,' % (col, name)
        text = text[:-1]
        self.shortcuts.setText(text)

        for sort_by in [_('Text'), _('Number'), _('Date'), _('Yes/No')]:
            self.composite_sort_by.addItem(sort_by)

        self.parent = parent
        self.editing_col = editing
        self.standard_colheads = standard_colheads
        self.standard_colnames = standard_colnames
        self.column_type_box.setMaxVisibleItems(len(self.column_types))
        for t in self.column_types:
            self.column_type_box.addItem(self.column_types[t]['text'])
        self.column_type_box.currentIndexChanged.connect(self.datatype_changed)
        if not self.editing_col:
            self.datatype_changed()
            self.exec_()
            return
        self.setWindowTitle(_('Edit a custom column'))
        self.heading_label.setText(_('Edit a custom column'))
        self.shortcuts.setVisible(False)
        idx = parent.opt_columns.currentRow()
        if idx < 0:
            self.simple_error(_('No column selected'),
                              _('No column has been selected'))
            return
        col = unicode(
            parent.opt_columns.item(idx).data(Qt.UserRole).toString())
        if col not in parent.custcols:
            self.simple_error(
                '', _('Selected column is not a user-defined column'))
            return

        c = parent.custcols[col]
        self.column_name_box.setText(c['label'])
        self.column_heading_box.setText(c['name'])
        ct = c['datatype']
        if c['is_multiple']:
            ct = '*' + ct
        self.orig_column_number = c['colnum']
        self.orig_column_name = col
        column_numbers = dict(
            map(lambda x: (self.column_types[x]['datatype'], x),
                self.column_types))
        self.column_type_box.setCurrentIndex(column_numbers[ct])
        self.column_type_box.setEnabled(False)
        if ct == 'datetime':
            if c['display'].get('date_format', None):
                self.date_format_box.setText(c['display'].get(
                    'date_format', ''))
        elif ct in ['composite', '*composite']:
            self.composite_box.setText(c['display'].get(
                'composite_template', ''))
            sb = c['display'].get('composite_sort', 'text')
            vals = ['text', 'number', 'date', 'bool']
            if sb in vals:
                sb = vals.index(sb)
            else:
                sb = 0
            self.composite_sort_by.setCurrentIndex(sb)
            self.composite_make_category.setChecked(c['display'].get(
                'make_category', False))
            self.composite_contains_html.setChecked(c['display'].get(
                'contains_html', False))
        elif ct == 'enumeration':
            self.enum_box.setText(','.join(c['display'].get('enum_values',
                                                            [])))
            self.enum_colors.setText(','.join(c['display'].get(
                'enum_colors', [])))
        elif ct in ['int', 'float']:
            if c['display'].get('number_format', None):
                self.number_format_box.setText(c['display'].get(
                    'number_format', ''))
        self.datatype_changed()
        if ct in ['text', 'composite', 'enumeration']:
            self.use_decorations.setChecked(c['display'].get(
                'use_decorations', False))
        elif ct == '*text':
            self.is_names.setChecked(c['display'].get('is_names', False))

        all_colors = [unicode(s) for s in list(QColor.colorNames())]
        self.enum_colors_label.setToolTip('<p>' + ', '.join(all_colors) +
                                          '</p>')

        self.composite_contains_html.setToolTip(
            '<p>' +
            _('If checked, this column will be displayed as HTML in '
              'book details and the content server. This can be used to '
              'construct links with the template language. For example, '
              'the template '
              '<pre>&lt;big&gt;&lt;b&gt;{title}&lt;/b&gt;&lt;/big&gt;'
              '{series:| [|}{series_index:| [|]]}</pre>'
              'will create a field displaying the title in bold large '
              'characters, along with the series, for example <br>"<big><b>'
              'An Oblique Approach</b></big> [Belisarius [1]]". The template '
              '<pre>&lt;a href="http://www.beam-ebooks.de/ebook/{identifiers'
              ':select(beam)}"&gt;Beam book&lt;/a&gt;</pre> '
              'will generate a link to the book on the Beam ebooks site.') +
            '</p>')
        self.exec_()
Example #6
0
    def accept(self):
        col = unicode(self.column_name_box.text()).strip()
        if not col:
            return self.simple_error('', _('No lookup name was provided'))
        if col.startswith('#'):
            col = col[1:]
        if re.match('^\w*$',
                    col) is None or not col[0].isalpha() or col.lower() != col:
            return self.simple_error(
                '',
                _('The lookup name must contain only '
                  'lower case letters, digits and underscores, and start with a letter'
                  ))
        if col.endswith('_index'):
            return self.simple_error(
                '',
                _('Lookup names cannot end with _index, '
                  'because these names are reserved for the index of a series column.'
                  ))
        col_heading = unicode(self.column_heading_box.text()).strip()
        col_type = self.column_types[
            self.column_type_box.currentIndex()]['datatype']
        if col_type[0] == '*':
            col_type = col_type[1:]
            is_multiple = True
        else:
            is_multiple = False
        if not col_heading:
            return self.simple_error('', _('No column heading was provided'))

        db = self.parent.gui.library_view.model().db
        key = db.field_metadata.custom_field_prefix + col
        bad_col = False
        if key in self.parent.custcols:
            if not self.editing_col or \
                    self.parent.custcols[key]['colnum'] != self.orig_column_number:
                bad_col = True
        if bad_col:
            return self.simple_error(
                '',
                _('The lookup name %s is already used') % col)

        bad_head = False
        for t in self.parent.custcols:
            if self.parent.custcols[t]['name'] == col_heading:
                if not self.editing_col or \
                        self.parent.custcols[t]['colnum'] != self.orig_column_number:
                    bad_head = True
        for t in self.standard_colheads:
            if self.standard_colheads[t] == col_heading:
                bad_head = True
        if bad_head:
            return self.simple_error(
                '',
                _('The heading %s is already used') % col_heading)

        display_dict = {}

        if col_type == 'datetime':
            if unicode(self.date_format_box.text()).strip():
                display_dict = {
                    'date_format':
                    unicode(self.date_format_box.text()).strip()
                }
            else:
                display_dict = {'date_format': None}
        elif col_type == 'composite':
            if not unicode(self.composite_box.text()).strip():
                return self.simple_error(
                    '', _('You must enter a template for'
                          ' composite columns'))
            display_dict = {
                'composite_template':
                unicode(self.composite_box.text()).strip(),
                'composite_sort':
                ['text', 'number', 'date',
                 'bool'][self.composite_sort_by.currentIndex()],
                'make_category':
                self.composite_make_category.isChecked(),
                'contains_html':
                self.composite_contains_html.isChecked(),
            }
        elif col_type == 'enumeration':
            if not unicode(self.enum_box.text()).strip():
                return self.simple_error(
                    '',
                    _('You must enter at least one'
                      ' value for enumeration columns'))
            l = [
                v.strip() for v in unicode(self.enum_box.text()).split(',')
                if v.strip()
            ]
            l_lower = [v.lower() for v in l]
            for i, v in enumerate(l_lower):
                if v in l_lower[i + 1:]:
                    return self.simple_error(
                        '',
                        _('The value "{0}" is in the '
                          'list more than once, perhaps with different case').
                        format(l[i]))
            c = unicode(self.enum_colors.text())
            if c:
                c = [
                    v.strip()
                    for v in unicode(self.enum_colors.text()).split(',')
                ]
            else:
                c = []
            if len(c) != 0 and len(c) != len(l):
                return self.simple_error(
                    '',
                    _('The colors box must be empty or '
                      'contain the same number of items as the value box'))
            for tc in c:
                if tc not in QColor.colorNames():
                    return self.simple_error(
                        '',
                        _('The color {0} is unknown').format(tc))

            display_dict = {'enum_values': l, 'enum_colors': c}
        elif col_type == 'text' and is_multiple:
            display_dict = {'is_names': self.is_names.isChecked()}
        elif col_type in ['int', 'float']:
            if unicode(self.number_format_box.text()).strip():
                display_dict = {
                    'number_format':
                    unicode(self.number_format_box.text()).strip()
                }
            else:
                display_dict = {'number_format': None}

        if col_type in ['text', 'composite', 'enumeration'
                        ] and not is_multiple:
            display_dict['use_decorations'] = self.use_decorations.checkState()

        if not self.editing_col:
            self.parent.custcols[key] = {
                'label': col,
                'name': col_heading,
                'datatype': col_type,
                'display': display_dict,
                'normalized': None,
                'colnum': None,
                'is_multiple': is_multiple,
            }
            item = QListWidgetItem(col_heading, self.parent.opt_columns)
            item.setData(Qt.UserRole, QVariant(key))
            item.setData(Qt.DecorationRole, QVariant(QIcon(I('column.png'))))
            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable
                          | Qt.ItemIsSelectable)
            item.setCheckState(Qt.Checked)
        else:
            idx = self.parent.opt_columns.currentRow()
            item = self.parent.opt_columns.item(idx)
            item.setText(col_heading)
            self.parent.custcols[self.orig_column_name]['label'] = col
            self.parent.custcols[self.orig_column_name]['name'] = col_heading
            self.parent.custcols[self.orig_column_name]['display'].update(
                display_dict)
            self.parent.custcols[self.orig_column_name]['*edited'] = True
            self.parent.custcols[self.orig_column_name]['*must_restart'] = True
        QDialog.accept(self)
Example #7
0
    def __init__(self, fm, pref_name, parent=None):
        QDialog.__init__(self, parent)
        self.fm = fm

        if pref_name == 'column_color_rules':
            self.rule_kind = 'color'
            rule_text = _('coloring')
        else:
            self.rule_kind = 'icon'
            rule_text = _('icon')

        self.setWindowIcon(QIcon(I('format-fill-color.png')))
        self.setWindowTitle(
            _('Create/edit a column {0} rule').format(rule_text))

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        self.l1 = l1 = QLabel(
            _('Create a column {0} rule by'
              ' filling in the boxes below'.format(rule_text)))
        l.addWidget(l1, 0, 0, 1, 8)

        self.f1 = QFrame(self)
        self.f1.setFrameShape(QFrame.HLine)
        l.addWidget(self.f1, 1, 0, 1, 8)

        self.l2 = l2 = QLabel(_('Set the'))
        l.addWidget(l2, 2, 0)

        if self.rule_kind == 'color':
            l.addWidget(QLabel(_('color')))
        else:
            self.kind_box = QComboBox(self)
            for tt, t in icon_rule_kinds:
                self.kind_box.addItem(tt, t)
            l.addWidget(self.kind_box, 2, 1)

        self.l3 = l3 = QLabel(_('of the column:'))
        l.addWidget(l3, 2, 2)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 2, 3)

        self.l4 = l4 = QLabel(_('to'))
        l.addWidget(l4, 2, 4)

        if self.rule_kind == 'color':
            self.color_box = QComboBox(self)
            self.color_label = QLabel('Sample text Sample text')
            self.color_label.setTextFormat(Qt.RichText)
            l.addWidget(self.color_box, 2, 5)
            l.addWidget(self.color_label, 2, 6)
            l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 7)
        else:
            self.filename_box = QComboBox()
            self.filename_box.setInsertPolicy(
                self.filename_box.InsertAlphabetically)
            d = os.path.join(config_dir, 'cc_icons')
            self.icon_file_names = []
            if os.path.exists(d):
                for icon_file in os.listdir(d):
                    icon_file = 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()

            l.addWidget(self.filename_box, 2, 5)
            self.filename_button = QPushButton(QIcon(I('document_open.png')),
                                               _('&Add icon'))
            l.addWidget(self.filename_button, 2, 6)
            l.addWidget(QLabel(_('Icons should be square or landscape')), 2, 7)
            l.setColumnStretch(7, 10)

        self.l5 = l5 = QLabel(
            _('Only if the following conditions are all satisfied:'))
        l.addWidget(l5, 3, 0, 1, 7)

        self.scroll_area = sa = QScrollArea(self)
        sa.setMinimumHeight(300)
        sa.setMinimumWidth(950)
        sa.setWidgetResizable(True)
        l.addWidget(sa, 4, 0, 1, 8)

        self.add_button = b = QPushButton(QIcon(I('plus.png')),
                                          _('Add another condition'))
        l.addWidget(b, 5, 0, 1, 8)
        b.clicked.connect(self.add_blank_condition)

        self.l6 = l6 = QLabel(
            _('You can disable a condition by'
              ' blanking all of its boxes'))
        l.addWidget(l6, 6, 0, 1, 8)

        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok
                                        | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        l.addWidget(bb, 7, 0, 1, 8)

        self.conditions_widget = QWidget(self)
        sa.setWidget(self.conditions_widget)
        self.conditions_widget.setLayout(QVBoxLayout())
        self.conditions_widget.layout().setAlignment(Qt.AlignTop)
        self.conditions = []

        if self.rule_kind == 'color':
            for b in (self.column_box, self.color_box):
                b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
                b.setMinimumContentsLength(15)

        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 self.rule_kind != 'color':
                continue
            name = all_columns_string if key == color_row_key else fm[key][
                'name']
            if name:
                self.column_box.addItem(name, key)
        self.column_box.setCurrentIndex(0)

        if self.rule_kind == 'color':
            self.color_box.addItems(QColor.colorNames())
            self.color_box.setCurrentIndex(0)
            self.update_color_label()
            self.color_box.currentIndexChanged.connect(self.update_color_label)
        else:
            self.filename_button.clicked.connect(self.filename_button_clicked)

        self.resize(self.sizeHint())
Example #8
0
    def __init__(self, parent, editing, standard_colheads, standard_colnames):
        QDialog.__init__(self, parent)
        Ui_QCreateCustomColumn.__init__(self)
        self.setupUi(self)
        self.setWindowTitle(_('Create a custom column'))
        self.heading_label.setText(_('Create a custom column'))
        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.simple_error = partial(error_dialog, self, show=True,
            show_copy_button=False)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)
        self.shortcuts.linkActivated.connect(self.shortcut_activated)
        text = '<p>'+_('Quick create:')
        for col, name in [('isbn', _('ISBN')), ('formats', _('Formats')),
                ('yesno', _('Yes/No')),
                ('tags', _('Tags')), ('series', _('Series')), ('rating',
                    _('Rating')), ('people', _("People's names"))]:
            text += ' <a href="col:%s">%s</a>,'%(col, name)
        text = text[:-1]
        self.shortcuts.setText(text)

        for sort_by in [_('Text'), _('Number'), _('Date'), _('Yes/No')]:
            self.composite_sort_by.addItem(sort_by)

        self.parent = parent
        self.editing_col = editing
        self.standard_colheads = standard_colheads
        self.standard_colnames = standard_colnames
        self.column_type_box.setMaxVisibleItems(len(self.column_types))
        for t in self.column_types:
            self.column_type_box.addItem(self.column_types[t]['text'])
        self.column_type_box.currentIndexChanged.connect(self.datatype_changed)
        if not self.editing_col:
            self.datatype_changed()
            self.exec_()
            return
        self.setWindowTitle(_('Edit a custom column'))
        self.heading_label.setText(_('Edit a custom column'))
        self.shortcuts.setVisible(False)
        idx = parent.opt_columns.currentRow()
        if idx < 0:
            self.simple_error(_('No column selected'),
                    _('No column has been selected'))
            return
        col = unicode(parent.opt_columns.item(idx).data(Qt.UserRole).toString())
        if col not in parent.custcols:
            self.simple_error('', _('Selected column is not a user-defined column'))
            return

        c = parent.custcols[col]
        self.column_name_box.setText(c['label'])
        self.column_heading_box.setText(c['name'])
        ct = c['datatype']
        if c['is_multiple']:
            ct = '*' + ct
        self.orig_column_number = c['colnum']
        self.orig_column_name = col
        column_numbers = dict(map(lambda x:(self.column_types[x]['datatype'], x),
                                  self.column_types))
        self.column_type_box.setCurrentIndex(column_numbers[ct])
        self.column_type_box.setEnabled(False)
        if ct == 'datetime':
            if c['display'].get('date_format', None):
                self.date_format_box.setText(c['display'].get('date_format', ''))
        elif ct in ['composite', '*composite']:
            self.composite_box.setText(c['display'].get('composite_template', ''))
            sb = c['display'].get('composite_sort', 'text')
            vals = ['text', 'number', 'date', 'bool']
            if sb in vals:
                sb = vals.index(sb)
            else:
                sb = 0
            self.composite_sort_by.setCurrentIndex(sb)
            self.composite_make_category.setChecked(
                                c['display'].get('make_category', False))
            self.composite_contains_html.setChecked(
                                c['display'].get('contains_html', False))
        elif ct == 'enumeration':
            self.enum_box.setText(','.join(c['display'].get('enum_values', [])))
            self.enum_colors.setText(','.join(c['display'].get('enum_colors', [])))
        elif ct in ['int', 'float']:
            if c['display'].get('number_format', None):
                self.number_format_box.setText(c['display'].get('number_format', ''))
        self.datatype_changed()
        if ct in ['text', 'composite', 'enumeration']:
            self.use_decorations.setChecked(c['display'].get('use_decorations', False))
        elif ct == '*text':
            self.is_names.setChecked(c['display'].get('is_names', False))

        all_colors = [unicode(s) for s in list(QColor.colorNames())]
        self.enum_colors_label.setToolTip('<p>' + ', '.join(all_colors) + '</p>')

        self.composite_contains_html.setToolTip('<p>' +
                _('If checked, this column will be displayed as HTML in '
                  'book details and the content server. This can be used to '
                  'construct links with the template language. For example, '
                  'the template '
                  '<pre>&lt;big&gt;&lt;b&gt;{title}&lt;/b&gt;&lt;/big&gt;'
                  '{series:| [|}{series_index:| [|]]}</pre>'
                  'will create a field displaying the title in bold large '
                  'characters, along with the series, for example <br>"<big><b>'
                  'An Oblique Approach</b></big> [Belisarius [1]]". The template '
                  '<pre>&lt;a href="http://www.beam-ebooks.de/ebook/{identifiers'
                  ':select(beam)}"&gt;Beam book&lt;/a&gt;</pre> '
                  'will generate a link to the book on the Beam ebooks site.')
                        + '</p>')
        self.exec_()
Example #9
0
    def accept(self):
        col = unicode(self.column_name_box.text()).strip()
        if not col:
            return self.simple_error('', _('No lookup name was provided'))
        if col.startswith('#'):
            col = col[1:]
        if re.match('^\w*$', col) is None or not col[0].isalpha() or col.lower() != col:
            return self.simple_error('', _('The lookup name must contain only '
                    'lower case letters, digits and underscores, and start with a letter'))
        if col.endswith('_index'):
            return self.simple_error('', _('Lookup names cannot end with _index, '
                    'because these names are reserved for the index of a series column.'))
        col_heading = unicode(self.column_heading_box.text()).strip()
        col_type = self.column_types[self.column_type_box.currentIndex()]['datatype']
        if col_type[0] == '*':
            col_type = col_type[1:]
            is_multiple = True
        else:
            is_multiple = False
        if not col_heading:
            return self.simple_error('', _('No column heading was provided'))

        db = self.parent.gui.library_view.model().db
        key = db.field_metadata.custom_field_prefix+col
        bad_col = False
        if key in self.parent.custcols:
            if not self.editing_col or \
                    self.parent.custcols[key]['colnum'] != self.orig_column_number:
                bad_col = True
        if bad_col:
            return self.simple_error('', _('The lookup name %s is already used')%col)

        bad_head = False
        for t in self.parent.custcols:
            if self.parent.custcols[t]['name'] == col_heading:
                if not self.editing_col or \
                        self.parent.custcols[t]['colnum'] != self.orig_column_number:
                    bad_head = True
        for t in self.standard_colheads:
            if self.standard_colheads[t] == col_heading:
                bad_head = True
        if bad_head:
            return self.simple_error('', _('The heading %s is already used')%col_heading)

        display_dict = {}

        if col_type == 'datetime':
            if unicode(self.date_format_box.text()).strip():
                display_dict = {'date_format':unicode(self.date_format_box.text()).strip()}
            else:
                display_dict = {'date_format': None}
        elif col_type == 'composite':
            if not unicode(self.composite_box.text()).strip():
                return self.simple_error('', _('You must enter a template for'
                    ' composite columns'))
            display_dict = {'composite_template':unicode(self.composite_box.text()).strip(),
                            'composite_sort': ['text', 'number', 'date', 'bool']
                                        [self.composite_sort_by.currentIndex()],
                            'make_category': self.composite_make_category.isChecked(),
                            'contains_html': self.composite_contains_html.isChecked(),
                        }
        elif col_type == 'enumeration':
            if not unicode(self.enum_box.text()).strip():
                return self.simple_error('', _('You must enter at least one'
                    ' value for enumeration columns'))
            l = [v.strip() for v in unicode(self.enum_box.text()).split(',') if v.strip()]
            l_lower = [v.lower() for v in l]
            for i,v in enumerate(l_lower):
                if v in l_lower[i+1:]:
                    return self.simple_error('', _('The value "{0}" is in the '
                    'list more than once, perhaps with different case').format(l[i]))
            c = unicode(self.enum_colors.text())
            if c:
                c = [v.strip() for v in unicode(self.enum_colors.text()).split(',')]
            else:
                c = []
            if len(c) != 0 and len(c) != len(l):
                return self.simple_error('', _('The colors box must be empty or '
                'contain the same number of items as the value box'))
            for tc in c:
                if tc not in QColor.colorNames():
                    return self.simple_error('',
                            _('The color {0} is unknown').format(tc))

            display_dict = {'enum_values': l, 'enum_colors': c}
        elif col_type == 'text' and is_multiple:
            display_dict = {'is_names': self.is_names.isChecked()}
        elif col_type in ['int', 'float']:
            if unicode(self.number_format_box.text()).strip():
                display_dict = {'number_format':unicode(self.number_format_box.text()).strip()}
            else:
                display_dict = {'number_format': None}

        if col_type in ['text', 'composite', 'enumeration'] and not is_multiple:
            display_dict['use_decorations'] = self.use_decorations.checkState()

        if not self.editing_col:
            self.parent.custcols[key] = {
                    'label':col,
                    'name':col_heading,
                    'datatype':col_type,
                    'display':display_dict,
                    'normalized':None,
                    'colnum':None,
                    'is_multiple':is_multiple,
                }
            item = QListWidgetItem(col_heading, self.parent.opt_columns)
            item.setData(Qt.UserRole, QVariant(key))
            item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable|Qt.ItemIsSelectable)
            item.setCheckState(Qt.Checked)
        else:
            idx = self.parent.opt_columns.currentRow()
            item = self.parent.opt_columns.item(idx)
            item.setText(col_heading)
            self.parent.custcols[self.orig_column_name]['label'] = col
            self.parent.custcols[self.orig_column_name]['name'] = col_heading
            self.parent.custcols[self.orig_column_name]['display'].update(display_dict)
            self.parent.custcols[self.orig_column_name]['*edited'] = True
            self.parent.custcols[self.orig_column_name]['*must_restart'] = True
        QDialog.accept(self)
Example #10
0
    def __init__(self, parent, editing, standard_colheads, standard_colnames):
        QDialog.__init__(self, parent)
        Ui_QCreateCustomColumn.__init__(self)
        self.setupUi(self)
        self.setWindowTitle(_("Create a custom column"))
        self.heading_label.setText(_("Create a custom column"))
        # Remove help icon on title bar
        icon = self.windowIcon()
        self.setWindowFlags(self.windowFlags() & (~Qt.WindowContextHelpButtonHint))
        self.setWindowIcon(icon)

        self.simple_error = partial(error_dialog, self, show=True, show_copy_button=False)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)
        self.shortcuts.linkActivated.connect(self.shortcut_activated)
        text = "<p>" + _("Quick create:")
        for col, name in [
            ("isbn", _("ISBN")),
            ("formats", _("Formats")),
            ("yesno", _("Yes/No")),
            ("tags", _("Tags")),
            ("series", _("Series")),
            ("rating", _("Rating")),
            ("people", _("People's names")),
        ]:
            text += ' <a href="col:%s">%s</a>,' % (col, name)
        text = text[:-1]
        self.shortcuts.setText(text)

        for sort_by in [_("Text"), _("Number"), _("Date"), _("Yes/No")]:
            self.composite_sort_by.addItem(sort_by)

        self.parent = parent
        self.editing_col = editing
        self.standard_colheads = standard_colheads
        self.standard_colnames = standard_colnames
        self.column_type_box.setMaxVisibleItems(len(self.column_types))
        for t in self.column_types:
            self.column_type_box.addItem(self.column_types[t]["text"])
        self.column_type_box.currentIndexChanged.connect(self.datatype_changed)
        if not self.editing_col:
            self.datatype_changed()
            self.exec_()
            return
        self.setWindowTitle(_("Edit a custom column"))
        self.heading_label.setText(_("Edit a custom column"))
        self.shortcuts.setVisible(False)
        idx = parent.opt_columns.currentRow()
        if idx < 0:
            self.simple_error(_("No column selected"), _("No column has been selected"))
            return
        col = unicode(parent.opt_columns.item(idx).data(Qt.UserRole).toString())
        if col not in parent.custcols:
            self.simple_error("", _("Selected column is not a user-defined column"))
            return

        c = parent.custcols[col]
        self.column_name_box.setText(c["label"])
        self.column_heading_box.setText(c["name"])
        ct = c["datatype"]
        if c["is_multiple"]:
            ct = "*" + ct
        self.orig_column_number = c["colnum"]
        self.orig_column_name = col
        column_numbers = dict(map(lambda x: (self.column_types[x]["datatype"], x), self.column_types))
        self.column_type_box.setCurrentIndex(column_numbers[ct])
        self.column_type_box.setEnabled(False)
        if ct == "datetime":
            if c["display"].get("date_format", None):
                self.date_format_box.setText(c["display"].get("date_format", ""))
        elif ct in ["composite", "*composite"]:
            self.composite_box.setText(c["display"].get("composite_template", ""))
            sb = c["display"].get("composite_sort", "text")
            vals = ["text", "number", "date", "bool"]
            if sb in vals:
                sb = vals.index(sb)
            else:
                sb = 0
            self.composite_sort_by.setCurrentIndex(sb)
            self.composite_make_category.setChecked(c["display"].get("make_category", False))
            self.composite_contains_html.setChecked(c["display"].get("contains_html", False))
        elif ct == "enumeration":
            self.enum_box.setText(",".join(c["display"].get("enum_values", [])))
            self.enum_colors.setText(",".join(c["display"].get("enum_colors", [])))
        elif ct in ["int", "float"]:
            if c["display"].get("number_format", None):
                self.number_format_box.setText(c["display"].get("number_format", ""))
        self.datatype_changed()
        if ct in ["text", "composite", "enumeration"]:
            self.use_decorations.setChecked(c["display"].get("use_decorations", False))
        elif ct == "*text":
            self.is_names.setChecked(c["display"].get("is_names", False))

        all_colors = [unicode(s) for s in list(QColor.colorNames())]
        self.enum_colors_label.setToolTip("<p>" + ", ".join(all_colors) + "</p>")

        self.composite_contains_html.setToolTip(
            "<p>"
            + _(
                "If checked, this column will be displayed as HTML in "
                "book details and the content server. This can be used to "
                "construct links with the template language. For example, "
                "the template "
                "<pre>&lt;big&gt;&lt;b&gt;{title}&lt;/b&gt;&lt;/big&gt;"
                "{series:| [|}{series_index:| [|]]}</pre>"
                "will create a field displaying the title in bold large "
                'characters, along with the series, for example <br>"<big><b>'
                'An Oblique Approach</b></big> [Belisarius [1]]". The template '
                '<pre>&lt;a href="http://www.beam-ebooks.de/ebook/{identifiers'
                ':select(beam)}"&gt;Beam book&lt;/a&gt;</pre> '
                "will generate a link to the book on the Beam ebooks site."
            )
            + "</p>"
        )
        self.exec_()
Example #11
0
    def accept(self):
        col = unicode(self.column_name_box.text()).strip()
        if not col:
            return self.simple_error("", _("No lookup name was provided"))
        if col.startswith("#"):
            col = col[1:]
        if re.match("^\w*$", col) is None or not col[0].isalpha() or col.lower() != col:
            return self.simple_error(
                "",
                _(
                    "The lookup name must contain only "
                    "lower case letters, digits and underscores, and start with a letter"
                ),
            )
        if col.endswith("_index"):
            return self.simple_error(
                "",
                _(
                    "Lookup names cannot end with _index, "
                    "because these names are reserved for the index of a series column."
                ),
            )
        col_heading = unicode(self.column_heading_box.text()).strip()
        col_type = self.column_types[self.column_type_box.currentIndex()]["datatype"]
        if col_type[0] == "*":
            col_type = col_type[1:]
            is_multiple = True
        else:
            is_multiple = False
        if not col_heading:
            return self.simple_error("", _("No column heading was provided"))

        db = self.parent.gui.library_view.model().db
        key = db.field_metadata.custom_field_prefix + col
        bad_col = False
        if key in self.parent.custcols:
            if not self.editing_col or self.parent.custcols[key]["colnum"] != self.orig_column_number:
                bad_col = True
        if bad_col:
            return self.simple_error("", _("The lookup name %s is already used") % col)

        bad_head = False
        for t in self.parent.custcols:
            if self.parent.custcols[t]["name"] == col_heading:
                if not self.editing_col or self.parent.custcols[t]["colnum"] != self.orig_column_number:
                    bad_head = True
        for t in self.standard_colheads:
            if self.standard_colheads[t] == col_heading:
                bad_head = True
        if bad_head:
            return self.simple_error("", _("The heading %s is already used") % col_heading)

        display_dict = {}

        if col_type == "datetime":
            if unicode(self.date_format_box.text()).strip():
                display_dict = {"date_format": unicode(self.date_format_box.text()).strip()}
            else:
                display_dict = {"date_format": None}
        elif col_type == "composite":
            if not unicode(self.composite_box.text()).strip():
                return self.simple_error("", _("You must enter a template for" " composite columns"))
            display_dict = {
                "composite_template": unicode(self.composite_box.text()).strip(),
                "composite_sort": ["text", "number", "date", "bool"][self.composite_sort_by.currentIndex()],
                "make_category": self.composite_make_category.isChecked(),
                "contains_html": self.composite_contains_html.isChecked(),
            }
        elif col_type == "enumeration":
            if not unicode(self.enum_box.text()).strip():
                return self.simple_error("", _("You must enter at least one" " value for enumeration columns"))
            l = [v.strip() for v in unicode(self.enum_box.text()).split(",") if v.strip()]
            l_lower = [v.lower() for v in l]
            for i, v in enumerate(l_lower):
                if v in l_lower[i + 1 :]:
                    return self.simple_error(
                        "",
                        _('The value "{0}" is in the ' "list more than once, perhaps with different case").format(l[i]),
                    )
            c = unicode(self.enum_colors.text())
            if c:
                c = [v.strip() for v in unicode(self.enum_colors.text()).split(",")]
            else:
                c = []
            if len(c) != 0 and len(c) != len(l):
                return self.simple_error(
                    "", _("The colors box must be empty or " "contain the same number of items as the value box")
                )
            for tc in c:
                if tc not in QColor.colorNames():
                    return self.simple_error("", _("The color {0} is unknown").format(tc))

            display_dict = {"enum_values": l, "enum_colors": c}
        elif col_type == "text" and is_multiple:
            display_dict = {"is_names": self.is_names.isChecked()}
        elif col_type in ["int", "float"]:
            if unicode(self.number_format_box.text()).strip():
                display_dict = {"number_format": unicode(self.number_format_box.text()).strip()}
            else:
                display_dict = {"number_format": None}

        if col_type in ["text", "composite", "enumeration"] and not is_multiple:
            display_dict["use_decorations"] = self.use_decorations.checkState()

        if not self.editing_col:
            self.parent.custcols[key] = {
                "label": col,
                "name": col_heading,
                "datatype": col_type,
                "display": display_dict,
                "normalized": None,
                "colnum": None,
                "is_multiple": is_multiple,
            }
            item = QListWidgetItem(col_heading, self.parent.opt_columns)
            item.setData(Qt.UserRole, QVariant(key))
            item.setData(Qt.DecorationRole, QVariant(QIcon(I("column.png"))))
            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsSelectable)
            item.setCheckState(Qt.Checked)
        else:
            idx = self.parent.opt_columns.currentRow()
            item = self.parent.opt_columns.item(idx)
            item.setText(col_heading)
            self.parent.custcols[self.orig_column_name]["label"] = col
            self.parent.custcols[self.orig_column_name]["name"] = col_heading
            self.parent.custcols[self.orig_column_name]["display"].update(display_dict)
            self.parent.custcols[self.orig_column_name]["*edited"] = True
            self.parent.custcols[self.orig_column_name]["*must_restart"] = True
        QDialog.accept(self)
Example #12
0
    def __init__(self, fm, pref_name, parent=None):
        QDialog.__init__(self, parent)
        self.fm = fm

        if pref_name == 'column_color_rules':
            self.rule_kind = 'color'
            rule_text = _('coloring')
        else:
            self.rule_kind = 'icon'
            rule_text = _('icon')

        self.setWindowIcon(QIcon(I('format-fill-color.png')))
        self.setWindowTitle(_('Create/edit a column {0} rule').format(rule_text))

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        self.l1 = l1 = QLabel(_('Create a column {0} rule by'
            ' filling in the boxes below'.format(rule_text)))
        l.addWidget(l1, 0, 0, 1, 8)

        self.f1 = QFrame(self)
        self.f1.setFrameShape(QFrame.HLine)
        l.addWidget(self.f1, 1, 0, 1, 8)

        self.l2 = l2 = QLabel(_('Set the'))
        l.addWidget(l2, 2, 0)

        if self.rule_kind == 'color':
            l.addWidget(QLabel(_('color')))
        else:
            self.kind_box = QComboBox(self)
            for tt, t in icon_rule_kinds:
                self.kind_box.addItem(tt, t)
            l.addWidget(self.kind_box, 2, 1)

        self.l3 = l3 = QLabel(_('of the column:'))
        l.addWidget(l3, 2, 2)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 2, 3)

        self.l4 = l4 = QLabel(_('to'))
        l.addWidget(l4, 2, 4)

        if self.rule_kind == 'color':
            self.color_box = QComboBox(self)
            self.color_label = QLabel('Sample text Sample text')
            self.color_label.setTextFormat(Qt.RichText)
            l.addWidget(self.color_box, 2, 5)
            l.addWidget(self.color_label, 2, 6)
            l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 7)
        else:
            self.filename_box = QComboBox()
            self.filename_box.setInsertPolicy(self.filename_box.InsertAlphabetically)
            d = os.path.join(config_dir, 'cc_icons')
            self.icon_file_names = []
            if os.path.exists(d):
                for icon_file in os.listdir(d):
                    icon_file = 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()

            l.addWidget(self.filename_box, 2, 5)
            self.filename_button = QPushButton(QIcon(I('document_open.png')),
                                               _('&Add icon'))
            l.addWidget(self.filename_button, 2, 6)
            l.addWidget(QLabel(_('Icons should be square or landscape')), 2, 7)
            l.setColumnStretch(7, 10)

        self.l5 = l5 = QLabel(
            _('Only if the following conditions are all satisfied:'))
        l.addWidget(l5, 3, 0, 1, 7)

        self.scroll_area = sa = QScrollArea(self)
        sa.setMinimumHeight(300)
        sa.setMinimumWidth(950)
        sa.setWidgetResizable(True)
        l.addWidget(sa, 4, 0, 1, 8)

        self.add_button = b = QPushButton(QIcon(I('plus.png')),
                _('Add another condition'))
        l.addWidget(b, 5, 0, 1, 8)
        b.clicked.connect(self.add_blank_condition)

        self.l6 = l6 = QLabel(_('You can disable a condition by'
            ' blanking all of its boxes'))
        l.addWidget(l6, 6, 0, 1, 8)

        self.bb = bb = QDialogButtonBox(
                QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        l.addWidget(bb, 7, 0, 1, 8)

        self.conditions_widget = QWidget(self)
        sa.setWidget(self.conditions_widget)
        self.conditions_widget.setLayout(QVBoxLayout())
        self.conditions_widget.layout().setAlignment(Qt.AlignTop)
        self.conditions = []

        if self.rule_kind == 'color':
            for b in (self.column_box, self.color_box):
                b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
                b.setMinimumContentsLength(15)

        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 self.rule_kind != 'color':
                continue
            name = all_columns_string if key == color_row_key else fm[key]['name']
            if name:
                self.column_box.addItem(name, key)
        self.column_box.setCurrentIndex(0)

        if self.rule_kind == 'color':
            self.color_box.addItems(QColor.colorNames())
            self.color_box.setCurrentIndex(0)
            self.update_color_label()
            self.color_box.currentIndexChanged.connect(self.update_color_label)
        else:
            self.filename_button.clicked.connect(self.filename_button_clicked)

        self.resize(self.sizeHint())
    def __init__(self, parent, text, mi=None, fm=None, color_field=None):
        QDialog.__init__(self, parent)
        Ui_TemplateDialog.__init__(self)
        self.setupUi(self)

        self.coloring = color_field is not None
        if self.coloring:
            cols = sorted([k for k in displayable_columns(fm)])
            self.colored_field.addItems(cols)
            self.colored_field.setCurrentIndex(
                self.colored_field.findText(color_field))
            colors = QColor.colorNames()
            colors.sort()
            self.color_name.addItems(colors)
        else:
            self.colored_field.setVisible(False)
            self.colored_field_label.setVisible(False)
            self.color_chooser_label.setVisible(False)
            self.color_name.setVisible(False)
            self.color_copy_button.setVisible(False)
        if mi:
            self.mi = mi
        else:
            self.mi = Metadata(None, None)

        # 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:
            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)

        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="http://manual.calibre-ebook.com/template_lang.html">'
            '%s</a>' % tt)
        tt = _('Template function reference')
        self.template_func_reference.setText(
            '<a href="http://manual.calibre-ebook.com/template_ref.html">'
            '%s</a>' % tt)
Example #14
0
    def __init__(self,
                 parent,
                 text,
                 mi=None,
                 fm=None,
                 color_field=None,
                 icon_field_key=None,
                 icon_rule_kind=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

        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))
            colors = QColor.colorNames()
            colors.sort()
            self.color_name.addItems(colors)
        elif self.iconing:
            self.icon_layout.setVisible(True)
            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()
            self.icon_with_text.setChecked(True)
            if icon_rule_kind == 'icon_only':
                self.icon_without_text.setChecked(True)
            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 = _('Series')
            self.mi.series_index = 3
            self.mi.rating = 4.0
            self.mi.tags = [_('Tag 1'), _('Tag 2')]
            self.mi.languages = ['eng']

        # 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:
            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="http://manual.calibre-ebook.com/template_lang.html">'
            '%s</a>' % tt)
        tt = _('Template function reference')
        self.template_func_reference.setText(
            '<a href="http://manual.calibre-ebook.com/template_ref.html">'
            '%s</a>' % tt)
Example #15
0
    def __init__(self, fm, parent=None):
        QDialog.__init__(self, parent)
        self.fm = fm

        self.setWindowIcon(QIcon(I('format-fill-color.png')))
        self.setWindowTitle(_('Create/edit a column coloring rule'))

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        self.l1 = l1 = QLabel(_('Create a coloring rule by'
            ' filling in the boxes below'))
        l.addWidget(l1, 0, 0, 1, 5)

        self.f1 = QFrame(self)
        self.f1.setFrameShape(QFrame.HLine)
        l.addWidget(self.f1, 1, 0, 1, 5)

        self.l2 = l2 = QLabel(_('Set the color of the column:'))
        l.addWidget(l2, 2, 0)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 2, 1)

        self.l3 = l3 = QLabel(_('to'))
        l.addWidget(l3, 2, 2)

        self.color_box = QComboBox(self)
        self.color_label = QLabel('Sample text Sample text')
        self.color_label.setTextFormat(Qt.RichText)
        l.addWidget(self.color_box, 2, 3)
        l.addWidget(self.color_label, 2, 4)
        l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 5)

        self.l4 = l4 = QLabel(
            _('Only if the following conditions are all satisfied:'))
        l.addWidget(l4, 3, 0, 1, 6)

        self.scroll_area = sa = QScrollArea(self)
        sa.setMinimumHeight(300)
        sa.setMinimumWidth(950)
        sa.setWidgetResizable(True)
        l.addWidget(sa, 4, 0, 1, 6)

        self.add_button = b = QPushButton(QIcon(I('plus.png')),
                _('Add another condition'))
        l.addWidget(b, 5, 0, 1, 6)
        b.clicked.connect(self.add_blank_condition)

        self.l5 = l5 = QLabel(_('You can disable a condition by'
            ' blanking all of its boxes'))
        l.addWidget(l5, 6, 0, 1, 6)

        self.bb = bb = QDialogButtonBox(
                QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        l.addWidget(bb, 7, 0, 1, 6)

        self.conditions_widget = QWidget(self)
        sa.setWidget(self.conditions_widget)
        self.conditions_widget.setLayout(QVBoxLayout())
        self.conditions_widget.layout().setAlignment(Qt.AlignTop)
        self.conditions = []

        for b in (self.column_box, self.color_box):
            b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
            b.setMinimumContentsLength(15)

        for key in sorted(
                displayable_columns(fm),
                key=sort_key):
            name = fm[key]['name']
            if name:
                self.column_box.addItem(key, key)
        self.column_box.setCurrentIndex(0)

        self.color_box.addItems(QColor.colorNames())
        self.color_box.setCurrentIndex(0)

        self.update_color_label()
        self.color_box.currentIndexChanged.connect(self.update_color_label)
        self.resize(self.sizeHint())