Пример #1
0
 def __init__(self, *args):
     QWidget.__init__(self, *args)
     lo = QHBoxLayout(self)
     lo.setContentsMargins(0, 0, 0, 0)
     lo.setSpacing(5)
     # type selector
     self.wtypesel = QComboBox(self)
     for i, tp in enumerate(self.ValueTypes):
         self.wtypesel.addItem(tp.__name__)
     QObject.connect(self.wtypesel, SIGNAL("activated(int)"), self._selectTypeNum)
     typesel_lab = QLabel("&Type:", self)
     typesel_lab.setBuddy(self.wtypesel)
     lo.addWidget(typesel_lab, 0)
     lo.addWidget(self.wtypesel, 0)
     self.wvalue = QLineEdit(self)
     self.wvalue_lab = QLabel("&Value:", self)
     self.wvalue_lab.setBuddy(self.wvalue)
     self.wbool = QComboBox(self)
     self.wbool.addItems(["false", "true"])
     self.wbool.setCurrentIndex(1)
     lo.addWidget(self.wvalue_lab, 0)
     lo.addWidget(self.wvalue, 1)
     lo.addWidget(self.wbool, 1)
     self.wvalue.hide()
     # make input validators
     self._validators = {int: QIntValidator(self), float: QDoubleValidator(self)}
     # select bool type initially
     self._selectTypeNum(0)
Пример #2
0
 def create_widgets(self, opt):
     val = self.plugin.prefs[opt.name]
     if opt.type == 'number':
         c = QSpinBox if isinstance(opt.default, int) else QDoubleSpinBox
         widget = c(self)
         widget.setValue(val)
     elif opt.type == 'string':
         widget = QLineEdit(self)
         widget.setText(val if val else '')
     elif opt.type == 'bool':
         widget = QCheckBox(opt.label, self)
         widget.setChecked(bool(val))
     elif opt.type == 'choices':
         widget = QComboBox(self)
         for key, label in opt.choices.iteritems():
             widget.addItem(label, QVariant(key))
         idx = widget.findData(QVariant(val))
         widget.setCurrentIndex(idx)
     widget.opt = opt
     widget.setToolTip(textwrap.fill(opt.desc))
     self.widgets.append(widget)
     r = self.l.rowCount()
     if opt.type == 'bool':
         self.l.addWidget(widget, r, 0, 1, self.l.columnCount())
     else:
         l = QLabel(opt.label)
         l.setToolTip(widget.toolTip())
         self.memory.append(l)
         l.setBuddy(widget)
         self.l.addWidget(l, r, 0, 1, 1)
         self.l.addWidget(widget, r, 1, 1, 1)
Пример #3
0
class ConfigWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.l = QHBoxLayout()
        self.setLayout(self.l)

        self.oldest_articlel = QLabel('Oldest article:')
        self.l.addWidget(self.oldest_articlel)

        self.oldest_article_msg = QLineEdit(self)
        self.oldest_article_msg.setText(prefs['oldest_article'])
        self.l.addWidget(self.oldest_article_msg)
        self.oldest_articlel.setBuddy(self.oldest_article_msg)

        self.max_articlesl = QLabel('Max articles:')
        self.l.addWidget(self.max_articlesl)

        self.max_articles_msg = QLineEdit(self)
        self.max_articles_msg.setText(prefs['max_articles'])
        self.l.addWidget(self.max_articles_msg)
        self.max_articlesl.setBuddy(self.max_articles_msg)

    def save_settings(self):
        prefs['oldest_article'] = unicode(self.oldest_article_msg.text())
        prefs['max_articles'] = unicode(self.max_articles_msg.text())
Пример #4
0
class ConfigWidget(QWidget):
  'Configuration widget'
  def __init__(self):
    QWidget.__init__(self)
    self.layout = QHBoxLayout()
    self.setLayout(self.layout)

    self.key_label = QLabel('&api key:')
    self.layout.addWidget(self.key_label)

    self.key_msg = QLineEdit(self)
    self.key_msg.setText(PREFS['api_key'])
    self.layout.addWidget(self.key_msg)
    self.key_label.setBuddy(self.key_msg)

    self.threads_label = QLabel('&worker_threads:')
    self.layout.addWidget(self.threads_label)

    self.threads_msg = QLineEdit(self)
    self.threads_msg.setText(str(PREFS['worker_threads']))
    self.layout.addWidget(self.threads_msg)
    self.key_label.setBuddy(self.key_msg)

  def save_settings(self):
    'Apply new settings value'
    PREFS['api_key'] = unicode(self.key_msg.text())
    PREFS['worker_threads'] = int(self.threads_msg.text())
    pycomicvine.api_key = PREFS['api_key']
Пример #5
0
    def setup_ui(self):
        self.l = l = QGridLayout()
        self.setLayout(l)

        self.la = la = QLabel(_(
            'Arrange the files in this book into sub-folders based on their types.'
            ' If you leave a folder blank, the files will be placed in the root.'))
        la.setWordWrap(True)
        l.addWidget(la, 0, 0, 1, -1)

        folders = tprefs['folders_for_types']
        for i, (typ, text) in enumerate(self.TYPE_MAP):
            la = QLabel('&' + text)
            setattr(self, '%s_label' % typ, la)
            le = QLineEdit(self)
            setattr(self, '%s_folder' % typ, le)
            val = folders.get(typ, '')
            if val and not val.endswith('/'):
                val += '/'
            le.setText(val)
            la.setBuddy(le)
            l.addWidget(la, i + 1, 0)
            l.addWidget(le, i + 1, 1)
        self.la2 = la = QLabel(_(
            'Note that this will only arrange files inside the book,'
            ' it will not affect how they are displayed in the Files Browser'))
        la.setWordWrap(True)
        l.addWidget(la, i + 2, 0, 1, -1)
        l.addWidget(self.bb, i + 3, 0, 1, -1)
Пример #6
0
class AddBookDialog(SizePersistedDialog):

    def __init__(self, parent=None, mm=None, mi = None):
        SizePersistedDialog.__init__(self, parent, 'casanova plugin:add book dialog')
        self.setWindowTitle('Add text to Casanova:')
        self.gui = parent
        self.mm = mm
        self.mi = mi
        self.one_line_description = ''

        layout = QVBoxLayout(self)
        self.setLayout(layout)

        self.one_liner_label = QLabel('Enter a short description (255 chars max) before pressing OK')
        layout.addWidget(self.one_liner_label)
        self.one_liner_str = QLineEdit(self)
        self.one_liner_str.setText('')
        layout.addWidget(self.one_liner_str)
        self.one_liner_label.setBuddy(self.one_liner_str)

        self.values_label = QLabel('Below are potential matches of texts that already exist - please make sure you are adding something new')
        layout.addWidget(self.values_label)
        self.values_list = QListWidget(self)
        self.values_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        layout.addWidget(self.values_list)
        
        self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.button_box.accepted.connect(self._accept_clicked)
        self.button_box.rejected.connect(self.reject)
        layout.addWidget(self.button_box)

        self._display_choices()

        # Cause our dialog size to be restored from prefs or created on first usage
        self.resize_dialog()

    def _display_choices(self):
        self.values_list.clear()
        choices = self.mm.search(self.mi.title)
        if choices is None or len(choices)==0:
            item = QListWidgetItem(get_icon('images/books.png'), _('there seem to be no matches'), self.values_list)
            self.values_list.addItem(item)
        for id, name in choices.items():
            item = QListWidgetItem(get_icon('images/books.png'), name, self.values_list)
            item.setData(1, (id,))
            self.values_list.addItem(item)

    def _accept_clicked(self):
        #self._save_preferences()
        one_liner = unicode(self.one_liner_str.text())
        if one_liner=='':
            self.values_list.clear()
            item = QListWidgetItem(get_icon('images/books.png'), _('you need to enter a short description'), self.values_list)
            self.values_list.addItem(item)
        else:
            self.one_line_description = one_liner
        self.accept()  
Пример #7
0
class SearchDialog(SizePersistedDialog):

    def __init__(self, parent=None, func=None, title="Search"):
        SizePersistedDialog.__init__(self, parent, 'arg plugin:search dialog')
        self.setWindowTitle(title)
        self.gui = parent
        self.func = func
        
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        self.search_label = QLabel(title)
        layout.addWidget(self.search_label)
        self.search_str = QLineEdit(self)
        self.search_str.setText('')
        layout.addWidget(self.search_str)
        self.search_label.setBuddy(self.search_str)

        self.find_button = QPushButton("&Find")
        self.search_button_box = QDialogButtonBox(Qt.Horizontal)
        self.search_button_box.addButton(self.find_button, QDialogButtonBox.ActionRole)
        self.search_button_box.clicked.connect(self._find_clicked)
        layout.addWidget(self.search_button_box)        

        self.values_list = QListWidget(self)
        # for multiple selection
        #self.values_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        layout.addWidget(self.values_list)
        
        self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.button_box.accepted.connect(self._accept_clicked)
        self.button_box.rejected.connect(self.reject)
        layout.addWidget(self.button_box)

        # Cause our dialog size to be restored from prefs or created on first usage
        self.resize_dialog()

    def _display_choices(self, choices):
        self.values_list.clear()
        for id, name in choices.items():
            item = QListWidgetItem(get_icon('images/books.png'), name, self.values_list)
            item.setData(1, (id,))
            self.values_list.addItem(item)

    def _find_clicked(self):
        query = unicode(self.search_str.text())
        self._display_choices(self.func(query))

    def _accept_clicked(self):
        #self._save_preferences()
        self.selected_result = None
        if self.values_list.currentItem():
            i = self.values_list.currentItem()
            self.selected_result = (i.data(1)[0], i.text())
        self.accept() 
Пример #8
0
class DaysOfMonth(Base):

    HELP = _('''\
                Download this periodical every month, on the specified days.
                The download will happen as soon after the specified time as
                possible on the specified days of each month. For example,
                if you choose the 1st and the 15th after 9:00 AM, the
                periodical will be downloaded on the 1st and 15th of every
                month, as soon after 9:00 AM as possible.
            ''')

    def __init__(self, parent=None):
        Base.__init__(self, parent)

        self.l1 = QLabel(_('&Days of the month:'))
        self.days = QLineEdit(self)
        self.days.setToolTip(
            _('Comma separated list of days of the month.'
              ' For example: 1, 15'))
        self.l1.setBuddy(self.days)

        self.l2 = QLabel(_('Download &after:'))
        self.time = QTimeEdit(self)
        self.time.setDisplayFormat('hh:mm AP')
        self.l2.setBuddy(self.time)

        self.l.addWidget(self.l1, 0, 0, 1, 1)
        self.l.addWidget(self.days, 0, 1, 1, 1)
        self.l.addWidget(self.l2, 1, 0, 1, 1)
        self.l.addWidget(self.time, 1, 1, 1, 1)

    def initialize(self, typ=None, val=None):
        if val is None:
            val = ((1, ), 6, 0)
        days_of_month, hour, minute = val
        self.days.setText(', '.join(map(str, map(int, days_of_month))))
        self.time.setTime(QTime(hour, minute))

    @property
    def schedule(self):
        parts = [
            x.strip() for x in unicode(self.days.text()).split(',')
            if x.strip()
        ]
        try:
            days_of_month = tuple(map(int, parts))
        except:
            days_of_month = (1, )
        if not days_of_month:
            days_of_month = (1, )
        t = self.time.time()
        hour, minute = t.hour(), t.minute()
        return 'days_of_month', (days_of_month, int(hour), int(minute))
Пример #9
0
class DaysOfWeek(Base):

    HELP = _('''\
                Download this periodical every week on the specified days after
                the specified time. For example, if you choose: Monday after
                9:00 AM, then the periodical will be download every Monday as
                soon after 9:00 AM as possible.
            ''')

    def __init__(self, parent=None):
        Base.__init__(self, parent)
        self.days = [
            QCheckBox(force_unicode(calendar.day_abbr[d]), self)
            for d in xrange(7)
        ]
        for i, cb in enumerate(self.days):
            row = i % 2
            col = i // 2
            self.l.addWidget(cb, row, col, 1, 1)

        self.time = QTimeEdit(self)
        self.time.setDisplayFormat('hh:mm AP')
        if canonicalize_lang(get_lang()) in {'deu', 'nds'}:
            self.time.setDisplayFormat('HH:mm')
        self.hl = QHBoxLayout()
        self.l1 = QLabel(_('&Download after:'))
        self.l1.setBuddy(self.time)
        self.hl.addWidget(self.l1)
        self.hl.addWidget(self.time)
        self.l.addLayout(self.hl, 1, 3, 1, 1)
        self.initialize()

    def initialize(self, typ=None, val=None):
        if typ is None:
            typ = 'day/time'
            val = (-1, 6, 0)
        if typ == 'day/time':
            val = convert_day_time_schedule(val)

        days_of_week, hour, minute = val
        for i, d in enumerate(self.days):
            d.setChecked(i in days_of_week)

        self.time.setTime(QTime(hour, minute))

    @property
    def schedule(self):
        days_of_week = tuple(
            [i for i, d in enumerate(self.days) if d.isChecked()])
        t = self.time.time()
        hour, minute = t.hour(), t.minute()
        return 'days_of_week', (days_of_week, int(hour), int(minute))
Пример #10
0
class DaysOfMonth(Base):

    HELP = _('''\
                Download this periodical every month, on the specified days.
                The download will happen as soon after the specified time as
                possible on the specified days of each month. For example,
                if you choose the 1st and the 15th after 9:00 AM, the
                periodical will be downloaded on the 1st and 15th of every
                month, as soon after 9:00 AM as possible.
            ''')

    def __init__(self, parent=None):
        Base.__init__(self, parent)

        self.l1 = QLabel(_('&Days of the month:'))
        self.days = QLineEdit(self)
        self.days.setToolTip(_('Comma separated list of days of the month.'
            ' For example: 1, 15'))
        self.l1.setBuddy(self.days)

        self.l2 = QLabel(_('Download &after:'))
        self.time = QTimeEdit(self)
        self.time.setDisplayFormat('hh:mm AP')
        self.l2.setBuddy(self.time)

        self.l.addWidget(self.l1, 0, 0, 1, 1)
        self.l.addWidget(self.days, 0, 1, 1, 1)
        self.l.addWidget(self.l2, 1, 0, 1, 1)
        self.l.addWidget(self.time, 1, 1, 1, 1)

    def initialize(self, typ=None, val=None):
        if val is None:
            val = ((1,), 6, 0)
        days_of_month, hour, minute = val
        self.days.setText(', '.join(map(str, map(int, days_of_month))))
        self.time.setTime(QTime(hour, minute))

    @property
    def schedule(self):
        parts = [x.strip() for x in unicode(self.days.text()).split(',') if
                x.strip()]
        try:
            days_of_month = tuple(map(int, parts))
        except:
            days_of_month = (1,)
        if not days_of_month:
            days_of_month = (1,)
        t = self.time.time()
        hour, minute = t.hour(), t.minute()
        return 'days_of_month', (days_of_month, int(hour), int(minute))
Пример #11
0
class DaysOfWeek(Base):

    HELP = _('''\
                Download this periodical every week on the specified days after
                the specified time. For example, if you choose: Monday after
                9:00 AM, then the periodical will be download every Monday as
                soon after 9:00 AM as possible.
            ''')

    def __init__(self, parent=None):
        Base.__init__(self, parent)
        self.days = [QCheckBox(force_unicode(calendar.day_abbr[d]),
            self) for d in xrange(7)]
        for i, cb in enumerate(self.days):
            row = i % 2
            col = i // 2
            self.l.addWidget(cb, row, col, 1, 1)

        self.time = QTimeEdit(self)
        self.time.setDisplayFormat('hh:mm AP')
        if canonicalize_lang(get_lang()) in {'deu', 'nds'}:
            self.time.setDisplayFormat('HH:mm')
        self.hl = QHBoxLayout()
        self.l1 = QLabel(_('&Download after:'))
        self.l1.setBuddy(self.time)
        self.hl.addWidget(self.l1)
        self.hl.addWidget(self.time)
        self.l.addLayout(self.hl, 1, 3, 1, 1)
        self.initialize()

    def initialize(self, typ=None, val=None):
        if typ is None:
            typ = 'day/time'
            val = (-1, 6, 0)
        if typ == 'day/time':
            val = convert_day_time_schedule(val)

        days_of_week, hour, minute = val
        for i, d in enumerate(self.days):
            d.setChecked(i in days_of_week)

        self.time.setTime(QTime(hour, minute))

    @property
    def schedule(self):
        days_of_week = tuple([i for i, d in enumerate(self.days) if
            d.isChecked()])
        t = self.time.time()
        hour, minute = t.hour(), t.minute()
        return 'days_of_week', (days_of_week, int(hour), int(minute))
Пример #12
0
    def __init__(self, service, parent):
        QDialog.__init__(self, parent)

        self.l = l = QGridLayout()
        self.setLayout(l)
        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok
                                        | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.tl = QLabel(('<p>' + _(
            'Setup sending email using'
        ) + ' <b>{name}</b><p>' + _(
            'If you don\'t have an account, you can sign up for a free {name} email '
            'account at <a href="http://{url}">http://{url}</a>. {extra}')
                          ).format(**service))
        l.addWidget(self.tl, 0, 0, 3, 0)
        self.tl.setWordWrap(True)
        self.tl.setOpenExternalLinks(True)
        for name, label in (
            ['from_', _('Your %s &email address:')],
            ['username', _('Your %s &username:'******'password', _('Your %s &password:'******'name'])
            le = QLineEdit(self)
            setattr(self, name, le)
            setattr(self, name + '_label', la)
            r = l.rowCount()
            l.addWidget(la, r, 0)
            l.addWidget(le, r, 1)
            la.setBuddy(le)
            if name == 'password':
                self.ptoggle = QCheckBox(_('&Show password'), self)
                l.addWidget(self.ptoggle, r, 2)
                self.ptoggle.stateChanged.connect(
                    lambda s: self.password.setEchoMode(
                        self.password.Normal
                        if s == Qt.Checked else self.password.Password))
        self.username.setText(service['username'])
        self.password.setEchoMode(self.password.Password)
        self.bl = QLabel('<p>' + _(
            'If you plan to use email to send books to your Kindle, remember to'
            ' add the your %s email address to the allowed email addresses in your '
            'Amazon.com Kindle management page.') % service['name'])
        self.bl.setWordWrap(True)
        l.addWidget(self.bl, l.rowCount(), 0, 3, 0)
        l.addWidget(bb, l.rowCount(), 0, 3, 0)
        self.setWindowTitle(_('Setup') + ' ' + service['name'])
        self.resize(self.sizeHint())
        self.service = service
Пример #13
0
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.l5 = QHBoxLayout()
        self.server_prefix_label = QLabel('Server prefix:')
        self.l5.addWidget(self.server_prefix_label)

        self.server_prefix = QLineEdit(self)
        self.server_prefix.setText(prefs['server_prefix'])
        self.l5.addWidget(self.server_prefix)
        self.server_prefix_label.setBuddy(self.server_prefix)
        self.l.addLayout(self.l5)

        self.ll = QHBoxLayout()
        self.server_label = QLabel('Server:')
        self.ll.addWidget(self.server_label)

        self.lsb_server = QLineEdit(self)
        self.lsb_server.setText(prefs['lsb_server'])
        self.ll.addWidget(self.lsb_server)
        self.server_label.setBuddy(self.lsb_server)
        self.l.addLayout(self.ll)

        self.lll = QHBoxLayout()
        self.librarian_label = QLabel('Librarian:')
        self.lll.addWidget(self.librarian_label)

        self.librarian = QLineEdit(self)
        self.librarian.setText(prefs['librarian']['name'])
        self.lll.addWidget(self.librarian)
        self.librarian_label.setBuddy(self.librarian)
        self.l.addLayout(self.lll)

        self.llll = QHBoxLayout()
        self.library_uuid_label = QLabel('Library ID:')
        self.llll.addWidget(self.library_uuid_label)
        self.library_uuid_button = QPushButton("New unique Library ID")
        self.library_uuid_button.clicked.connect(self.new_library_uuid)

        self.library_uuid = QLabel(self)
        self.library_uuid.setText(prefs['library_uuid'])
        self.llll.addWidget(self.library_uuid)
        self.llll.addWidget(self.library_uuid_button)
        self.library_uuid_label.setBuddy(self.library_uuid)
        self.l.addLayout(self.llll)

    def new_library_uuid(self):
        self.library_uuid.setText(str(uuid.uuid4()))

    def save_settings(self):
        prefs['lsb_server'] = unicode(self.lsb_server.text())
        prefs['server_prefix'] = unicode(self.server_prefix.text())
        prefs['librarian'] = {'name': unicode(self.librarian.text()),
                              'saved': True}
        prefs['library_uuid'] = self.library_uuid.text()
Пример #14
0
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.l = QHBoxLayout()
        self.setLayout(self.l)

        self.label = QLabel("Server:")
        self.l.addWidget(self.label)

        self.msg = QLineEdit(self)
        self.msg.setText(prefs["lsb_server"])
        self.l.addWidget(self.msg)
        self.label.setBuddy(self.msg)

    def save_settings(self):
        prefs["lsb_server"] = unicode(self.msg.text())
Пример #15
0
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.l = QHBoxLayout()
        self.setLayout(self.l)

        self.label = QLabel('Hello world &message:')
        self.l.addWidget(self.label)

        self.msg = QLineEdit(self)
        self.msg.setText(prefs['hello_world_msg'])
        self.l.addWidget(self.msg)
        self.label.setBuddy(self.msg)

    def save_settings(self):
        prefs['hello_world_msg'] = unicode(self.msg.text())
Пример #16
0
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.l = QHBoxLayout()
        self.setLayout(self.l)

        self.label = QLabel("Hello world &message:")
        self.l.addWidget(self.label)

        self.msg = QLineEdit(self)
        self.msg.setText(prefs["hello_world_msg"])
        self.l.addWidget(self.msg)
        self.label.setBuddy(self.msg)

    def save_settings(self):
        None
Пример #17
0
    def __init__(self, service, parent):
        QDialog.__init__(self, parent)

        self.l = l = QGridLayout()
        self.setLayout(l)
        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.tl = QLabel(('<p>'+_('Setup sending email using') +
                ' <b>{name}</b><p>' +
            _('If you don\'t have an account, you can sign up for a free {name} email '
            'account at <a href="http://{url}">http://{url}</a>. {extra}')).format(
                **service))
        l.addWidget(self.tl, 0, 0, 3, 0)
        self.tl.setWordWrap(True)
        self.tl.setOpenExternalLinks(True)
        for name, label in (
                ['from_', _('Your %s &email address:')],
                ['username', _('Your %s &username:'******'password', _('Your %s &password:'******'name'])
            le = QLineEdit(self)
            setattr(self, name, le)
            setattr(self, name+'_label', la)
            r = l.rowCount()
            l.addWidget(la, r, 0)
            l.addWidget(le, r, 1)
            la.setBuddy(le)
            if name == 'password':
                self.ptoggle = QCheckBox(_('&Show password'), self)
                l.addWidget(self.ptoggle, r, 2)
                self.ptoggle.stateChanged.connect(
                        lambda s: self.password.setEchoMode(self.password.Normal if s
                            == Qt.Checked else self.password.Password))
        self.username.setText(service['username'])
        self.password.setEchoMode(self.password.Password)
        self.bl = QLabel('<p>' + _(
            'If you plan to use email to send books to your Kindle, remember to'
            ' add the your %s email address to the allowed email addresses in your '
            'Amazon.com Kindle management page.')%service['name'])
        self.bl.setWordWrap(True)
        l.addWidget(self.bl, l.rowCount(), 0, 3, 0)
        l.addWidget(bb, l.rowCount(), 0, 3, 0)
        self.setWindowTitle(_('Setup') + ' ' + service['name'])
        self.resize(self.sizeHint())
        self.service = service
Пример #18
0
class ConfigWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.l = QHBoxLayout()
        self.setLayout(self.l)

        self.label = QLabel('Message header:')
        self.l.addWidget(self.label)

        self.msg = QLineEdit(self)
        self.msg.setText(prefs['my_msg_header'])
        self.l.addWidget(self.msg)
        self.label.setBuddy(self.msg)

    def save_settings(self):
        prefs['my_msg_header'] = unicode(self.msg.text())
Пример #19
0
    def __init__(self, parent=None):
        QFrame.__init__(self, parent)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setAutoFillBackground(True)
        self.capture = 0

        self.setFrameShape(self.StyledPanel)
        self.setFrameShadow(self.Raised)
        self._layout = l = QGridLayout(self)
        self.setLayout(l)

        self.header = QLabel('')
        l.addWidget(self.header, 0, 0, 1, 2)

        self.use_default = QRadioButton('')
        self.use_custom = QRadioButton(_('Custom'))
        l.addWidget(self.use_default, 1, 0, 1, 3)
        l.addWidget(self.use_custom, 2, 0, 1, 3)
        self.use_custom.toggled.connect(self.custom_toggled)

        off = 2
        for which in (1, 2):
            text = _('&Shortcut:') if which == 1 else _('&Alternate shortcut:')
            la = QLabel(text)
            la.setStyleSheet('QLabel { margin-left: 1.5em }')
            l.addWidget(la, off + which, 0, 1, 3)
            setattr(self, 'label%d' % which, la)
            button = QPushButton(_('None'), self)
            button.clicked.connect(partial(self.capture_clicked, which=which))
            button.keyPressEvent = partial(self.key_press_event, which=which)
            setattr(self, 'button%d' % which, button)
            clear = QToolButton(self)
            clear.setIcon(QIcon(I('clear_left.png')))
            clear.clicked.connect(partial(self.clear_clicked, which=which))
            setattr(self, 'clear%d' % which, clear)
            l.addWidget(button, off + which, 1, 1, 1)
            l.addWidget(clear, off + which, 2, 1, 1)
            la.setBuddy(button)

        self.done_button = doneb = QPushButton(_('Done'), self)
        l.addWidget(doneb, 0, 2, 1, 1)
        doneb.clicked.connect(lambda: self.editing_done.emit(self))
        l.setColumnStretch(0, 100)

        self.custom_toggled(False)
Пример #20
0
    def __init__(self, parent=None):
        QFrame.__init__(self, parent)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setAutoFillBackground(True)
        self.capture = 0

        self.setFrameShape(self.StyledPanel)
        self.setFrameShadow(self.Raised)
        self._layout = l = QGridLayout(self)
        self.setLayout(l)

        self.header = QLabel('')
        l.addWidget(self.header, 0, 0, 1, 2)

        self.use_default = QRadioButton('')
        self.use_custom = QRadioButton(_('Custom'))
        l.addWidget(self.use_default, 1, 0, 1, 3)
        l.addWidget(self.use_custom, 2, 0, 1, 3)
        self.use_custom.toggled.connect(self.custom_toggled)

        off = 2
        for which in (1, 2):
            text = _('&Shortcut:') if which == 1 else _('&Alternate shortcut:')
            la = QLabel(text)
            la.setStyleSheet('QLabel { margin-left: 1.5em }')
            l.addWidget(la, off+which, 0, 1, 3)
            setattr(self, 'label%d'%which, la)
            button = QPushButton(_('None'), self)
            button.clicked.connect(partial(self.capture_clicked, which=which))
            button.keyPressEvent = partial(self.key_press_event, which=which)
            setattr(self, 'button%d'%which, button)
            clear = QToolButton(self)
            clear.setIcon(QIcon(I('clear_left.png')))
            clear.clicked.connect(partial(self.clear_clicked, which=which))
            setattr(self, 'clear%d'%which, clear)
            l.addWidget(button, off+which, 1, 1, 1)
            l.addWidget(clear, off+which, 2, 1, 1)
            la.setBuddy(button)

        self.done_button = doneb = QPushButton(_('Done'), self)
        l.addWidget(doneb, 0, 2, 1, 1)
        doneb.clicked.connect(lambda : self.editing_done.emit(self))
        l.setColumnStretch(0, 100)

        self.custom_toggled(False)
Пример #21
0
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.ll = QHBoxLayout()
        self.server_label = QLabel('Gphoto2 server address:')
        self.ll.addWidget(self.server_label)

        self.gphoto2_server = QLineEdit(self)
        self.gphoto2_server.setText(prefs['gphoto2_server'])
        self.ll.addWidget(self.gphoto2_server)
        self.server_label.setBuddy(self.gphoto2_server)
        self.l.addLayout(self.ll)

    def save_settings(self):
        prefs['gphoto2_server'] = self.gphoto2_server.text()
Пример #22
0
class ConfigWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.ll = QHBoxLayout()
        self.server_label = QLabel('Gphoto2 server address:')
        self.ll.addWidget(self.server_label)

        self.gphoto2_server = QLineEdit(self)
        self.gphoto2_server.setText(prefs['gphoto2_server'])
        self.ll.addWidget(self.gphoto2_server)
        self.server_label.setBuddy(self.gphoto2_server)
        self.l.addLayout(self.ll)
        
    def save_settings(self):
        prefs['gphoto2_server'] = self.gphoto2_server.text()
    def __init__(self, plugin):
        super(ConfigWidget, self).__init__()
        
        self.vlayout = QVBoxLayout()
        self.setLayout(self.vlayout)

        self.dcinput = {}

        for key in prefs.defaults:
            hlayout = QHBoxLayout()
            txtlabel = QLabel(key.replace("_", " "))
            txtinput = QLineEdit()
            txtinput.setText(str(prefs[key]))
            txtlabel.setBuddy(txtinput)
            self.dcinput[key] = txtinput
            
            hlayout.addWidget(txtlabel)
            hlayout.addWidget(txtinput)
            self.vlayout.addLayout(hlayout)
Пример #24
0
 def __init__(self, parent, modal=True, flags=Qt.WindowFlags()):
     QDialog.__init__(self, parent, flags)
     self.setModal(modal)
     self.setWindowTitle("Add Tag")
     lo = QVBoxLayout(self)
     lo.setMargin(10)
     lo.setSpacing(5)
     # tag selector
     lo1 = QHBoxLayout()
     lo.addLayout(lo1)
     lo1.setSpacing(5)
     self.wtagsel = QComboBox(self)
     self.wtagsel.setEditable(True)
     wtagsel_lbl = QLabel("&Tag:", self)
     wtagsel_lbl.setBuddy(self.wtagsel)
     lo1.addWidget(wtagsel_lbl, 0)
     lo1.addWidget(self.wtagsel, 1)
     QObject.connect(self.wtagsel, SIGNAL("activated(int)"),
                     self._check_tag)
     QObject.connect(self.wtagsel,
                     SIGNAL("editTextChanged(const QString &)"),
                     self._check_tag_text)
     # value editor
     self.valedit = ValueTypeEditor(self)
     lo.addWidget(self.valedit)
     # buttons
     lo.addSpacing(10)
     lo2 = QHBoxLayout()
     lo.addLayout(lo2)
     lo2.setContentsMargins(0, 0, 0, 0)
     lo2.setMargin(5)
     self.wokbtn = QPushButton("OK", self)
     self.wokbtn.setMinimumWidth(128)
     QObject.connect(self.wokbtn, SIGNAL("clicked()"), self.accept)
     self.wokbtn.setEnabled(False)
     cancelbtn = QPushButton("Cancel", self)
     cancelbtn.setMinimumWidth(128)
     QObject.connect(cancelbtn, SIGNAL("clicked()"), self.reject)
     lo2.addWidget(self.wokbtn)
     lo2.addStretch(1)
     lo2.addWidget(cancelbtn)
     self.setMinimumWidth(384)
Пример #25
0
class ConfigWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.l5 = QHBoxLayout()
        self.server_prefix_label = QLabel('Server prefix:')
        self.l5.addWidget(self.server_prefix_label)

        self.server_prefix = QLineEdit(self)
        self.server_prefix.setText(prefs['server_prefix'])
        self.l5.addWidget(self.server_prefix)
        self.server_prefix_label.setBuddy(self.server_prefix)
        self.l.addLayout(self.l5)

        self.ll = QHBoxLayout()
        self.server_label = QLabel('Server:')
        self.ll.addWidget(self.server_label)

        self.lsb_server = QLineEdit(self)
        self.lsb_server.setText(prefs['lsb_server'])
        self.ll.addWidget(self.lsb_server)
        self.server_label.setBuddy(self.lsb_server)
        self.l.addLayout(self.ll)

        self.lll = QHBoxLayout()
        self.librarian_label = QLabel('Librarian:')
        self.lll.addWidget(self.librarian_label)

        self.librarian = QLineEdit(self)
        self.librarian.setText(prefs['librarian'])
        self.lll.addWidget(self.librarian)
        self.librarian_label.setBuddy(self.librarian)
        self.l.addLayout(self.lll)

        self.llll = QHBoxLayout()
        self.library_uuid_label = QLabel('Library ID:')
        self.llll.addWidget(self.library_uuid_label)

        self.library_uuid = QLabel(self)
        self.library_uuid.setText(prefs['library_uuid'])
        self.llll.addWidget(self.library_uuid)
        self.library_uuid_label.setBuddy(self.library_uuid)
        self.l.addLayout(self.llll)

    def save_settings(self):
        prefs['lsb_server'] = unicode(self.lsb_server.text())
        prefs['server_prefix'] = unicode(self.server_prefix.text())
        prefs['librarian'] = unicode(self.librarian.text())
        prefs['library_uuid'] = prefs['library_uuid']
Пример #26
0
class ConfigWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.l5 = QHBoxLayout()
        self.server_prefix_label = QLabel('Server prefix:')
        self.l5.addWidget(self.server_prefix_label)

        self.server_prefix = QLineEdit(self)
        self.server_prefix.setText(prefs['server_prefix'])
        self.l5.addWidget(self.server_prefix)
        self.server_prefix_label.setBuddy(self.server_prefix)
        self.l.addLayout(self.l5)

        self.ll = QHBoxLayout()
        self.server_label = QLabel('Server:')
        self.ll.addWidget(self.server_label)

        self.lsb_server = QLineEdit(self)
        self.lsb_server.setText(prefs['lsb_server'])
        self.ll.addWidget(self.lsb_server)
        self.server_label.setBuddy(self.lsb_server)
        self.l.addLayout(self.ll)

        self.lll = QHBoxLayout()
        self.librarian_label = QLabel('Librarian:')
        self.lll.addWidget(self.librarian_label)

        self.librarian = QLabel(self)
        self.librarian.setText(prefs['librarian'])
        self.lll.addWidget(self.librarian)
        self.librarian_label.setBuddy(self.librarian)
        self.l.addLayout(self.lll)

        self.llll = QHBoxLayout()
        self.library_uuid_label = QLabel('Library ID:')
        self.llll.addWidget(self.library_uuid_label)

        self.library_uuid = QLabel(self)
        self.library_uuid.setText(prefs['library_uuid'])
        self.llll.addWidget(self.library_uuid)
        self.library_uuid_label.setBuddy(self.library_uuid)
        self.l.addLayout(self.llll)

    def save_settings(self):
        prefs['lsb_server'] = unicode(self.lsb_server.text())
        prefs['server_prefix'] = unicode(self.server_prefix.text())
        prefs['librarian'] = prefs['librarian']
        prefs['library_uuid'] = prefs['library_uuid']
Пример #27
0
 def __init__(self, parent, modal=True, flags=Qt.WindowFlags()):
     QDialog.__init__(self, parent, flags)
     self.setModal(modal)
     self.setWindowTitle("Add Tag")
     lo = QVBoxLayout(self)
     lo.setMargin(10)
     lo.setSpacing(5)
     # tag selector
     lo1 = QHBoxLayout()
     lo.addLayout(lo1)
     lo1.setSpacing(5)
     self.wtagsel = QComboBox(self)
     self.wtagsel.setEditable(True)
     wtagsel_lbl = QLabel("&Tag:", self)
     wtagsel_lbl.setBuddy(self.wtagsel)
     lo1.addWidget(wtagsel_lbl, 0)
     lo1.addWidget(self.wtagsel, 1)
     QObject.connect(self.wtagsel, SIGNAL("activated(int)"), self._check_tag)
     QObject.connect(self.wtagsel, SIGNAL("editTextChanged(const QString &)"), self._check_tag_text)
     # value editor
     self.valedit = ValueTypeEditor(self)
     lo.addWidget(self.valedit)
     # buttons
     lo.addSpacing(10)
     lo2 = QHBoxLayout()
     lo.addLayout(lo2)
     lo2.setContentsMargins(0, 0, 0, 0)
     lo2.setMargin(5)
     self.wokbtn = QPushButton("OK", self)
     self.wokbtn.setMinimumWidth(128)
     QObject.connect(self.wokbtn, SIGNAL("clicked()"), self.accept)
     self.wokbtn.setEnabled(False)
     cancelbtn = QPushButton("Cancel", self)
     cancelbtn.setMinimumWidth(128)
     QObject.connect(cancelbtn, SIGNAL("clicked()"), self.reject)
     lo2.addWidget(self.wokbtn)
     lo2.addStretch(1)
     lo2.addWidget(cancelbtn)
     self.setMinimumWidth(384)
Пример #28
0
class EveryXDays(Base):

    HELP = _('''\
                Download this periodical every x days. For example, if you
                choose 30 days, the periodical will be downloaded every 30
                days. Note that you can set periods of less than a day, like
                0.1 days to download a periodical more than once a day.
            ''')

    def __init__(self, parent=None):
        Base.__init__(self, parent)
        self.l1 = QLabel(_('&Download every:'))
        self.interval = QDoubleSpinBox(self)
        self.interval.setMinimum(0.04)
        self.interval.setSpecialValueText(_('every hour'))
        self.interval.setMaximum(1000.0)
        self.interval.setValue(31.0)
        self.interval.setSuffix(' ' + _('days'))
        self.interval.setSingleStep(1.0)
        self.interval.setDecimals(2)
        self.l1.setBuddy(self.interval)
        self.l2 = QLabel(
            _('Note: You can set intervals of less than a day,'
              ' by typing the value manually.'))
        self.l2.setWordWrap(True)

        self.l.addWidget(self.l1, 0, 0, 1, 1)
        self.l.addWidget(self.interval, 0, 1, 1, 1)
        self.l.addWidget(self.l2, 1, 0, 1, -1)

    def initialize(self, typ=None, val=None):
        if val is None:
            val = 31.0
        self.interval.setValue(val)

    @property
    def schedule(self):
        schedule = self.interval.value()
        return 'interval', schedule
Пример #29
0
class EveryXDays(Base):

    HELP = _('''\
                Download this periodical every x days. For example, if you
                choose 30 days, the periodical will be downloaded every 30
                days. Note that you can set periods of less than a day, like
                0.1 days to download a periodical more than once a day.
            ''')

    def __init__(self, parent=None):
        Base.__init__(self, parent)
        self.l1 = QLabel(_('&Download every:'))
        self.interval = QDoubleSpinBox(self)
        self.interval.setMinimum(0.04)
        self.interval.setSpecialValueText(_('every hour'))
        self.interval.setMaximum(1000.0)
        self.interval.setValue(31.0)
        self.interval.setSuffix(' ' + _('days'))
        self.interval.setSingleStep(1.0)
        self.interval.setDecimals(2)
        self.l1.setBuddy(self.interval)
        self.l2 = QLabel(_('Note: You can set intervals of less than a day,'
            ' by typing the value manually.'))
        self.l2.setWordWrap(True)

        self.l.addWidget(self.l1, 0, 0, 1, 1)
        self.l.addWidget(self.interval, 0, 1, 1, 1)
        self.l.addWidget(self.l2, 1, 0, 1, -1)

    def initialize(self, typ=None, val=None):
        if val is None:
            val = 31.0
        self.interval.setValue(val)

    @property
    def schedule(self):
        schedule = self.interval.value()
        return 'interval', schedule
Пример #30
0
    def __init__(self, parent=None):
        super(IPETLogFileView, self).__init__(parent)
        vlayout = QVBoxLayout(self)
        self.textbrowser = QTextEdit(self)
        self.textbrowser.setReadOnly(True)
        self.testrunselection = OptionsComboBox(self)
        self.problemselection = OptionsComboBox(self)
        vlayout.addWidget(self.textbrowser)
        self.setStyleSheet(self.StyleSheet)
        hlayout = QHBoxLayout()
        testrunselectionlabel = QLabel("Select a test run", self)
        problemselectionlabel = QLabel("Select an instance", self)
        testrunselectionlabel.setBuddy(self.testrunselection)
        problemselectionlabel.setBuddy(self.problemselection)
        for l, s in [(testrunselectionlabel, self.testrunselection),
                     (problemselectionlabel, self.problemselection)]:
            v = QVBoxLayout(self)
            v.addWidget(l)
            v.addWidget(s)
            hlayout.addLayout(v)
        vlayout.addLayout(hlayout)
        self.setLayout(vlayout)

        self.initConnections()
Пример #31
0
class ConfigWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.serialLabel = QLabel('eInk Kindle Serial numbers (First character B, 16 characters, use commas if more than one)')
        self.l.addWidget(self.serialLabel)

        self.serials = QLineEdit(self)
        self.serials.setText(prefs['serials'])
        self.l.addWidget(self.serials)
        self.serialLabel.setBuddy(self.serials)

        self.pidLabel = QLabel('Mobipocket PIDs (8 or 10 characters, use commas if more than one)')
        self.l.addWidget(self.pidLabel)

        self.pids = QLineEdit(self)
        self.pids.setText(prefs['pids'])
        self.l.addWidget(self.pids)
        self.pidLabel.setBuddy(self.serials)

        self.wpLabel = QLabel('For Linux only: WINEPREFIX (enter absolute path)')
        self.l.addWidget(self.wpLabel)

        self.wineprefix = QLineEdit(self)
        wineprefix = prefs['WINEPREFIX']
        if wineprefix is not None:
            self.wineprefix.setText(wineprefix)
        else:
            self.wineprefix.setText('')

        self.l.addWidget(self.wineprefix)
        self.wpLabel.setBuddy(self.wineprefix)

    def save_settings(self):
    	prefs['pids'] = str(self.pids.text()).replace(" ","")
        prefs['serials'] = str(self.serials.text()).replace(" ","")
        winepref=str(self.wineprefix.text())
        if winepref.strip() != '':
            prefs['WINEPREFIX'] = winepref
        else:
            prefs['WINEPREFIX'] = None
Пример #32
0
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.ll = QHBoxLayout()
        self.server_label = QLabel("Server:")
        self.ll.addWidget(self.server_label)

        self.lsb_server = QLineEdit(self)
        self.lsb_server.setText(prefs["lsb_server"])
        self.ll.addWidget(self.lsb_server)
        self.server_label.setBuddy(self.lsb_server)
        self.l.addLayout(self.ll)

        self.lll = QHBoxLayout()
        self.librarian_label = QLabel("Librarian:")
        self.lll.addWidget(self.librarian_label)

        self.librarian = QLineEdit(self)
        self.librarian.setText(prefs["librarian"])
        self.lll.addWidget(self.librarian)
        self.librarian_label.setBuddy(self.librarian)
        self.l.addLayout(self.lll)

        self.llll = QHBoxLayout()
        self.library_uuid_label = QLabel("Library ID:")
        self.llll.addWidget(self.library_uuid_label)

        self.library_uuid = QLabel(self)
        self.library_uuid.setText(prefs["library_uuid"])
        self.llll.addWidget(self.library_uuid)
        self.library_uuid_label.setBuddy(self.library_uuid)
        self.l.addLayout(self.llll)

    def save_settings(self):
        prefs["lsb_server"] = unicode(self.lsb_server.text())
        prefs["librarian"] = unicode(self.librarian.text())
        prefs["library_uuid"] = prefs["library_uuid"]
Пример #33
0
class ConfigWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.url_label = QLabel('Casanova server:')
        self.l.addWidget(self.url_label)

        self.url_msg = QLineEdit(self)
        self.url_msg.setText(prefs['base_url'])
        self.l.addWidget(self.url_msg)

        self.url_label.setBuddy(self.url_msg)

        self.username_label = QLabel('Username:'******'username'])
        self.l.addWidget(self.username_msg)

        self.username_label.setBuddy(self.username_msg)        

        self.password_label = QLabel('password:'******'password'])
        self.l.addWidget(self.password_msg)

        self.password_label.setBuddy(self.password_msg)                

    def save_settings(self):
        prefs['base_url'] = unicode(self.url_msg.text())
        prefs['username'] = unicode(self.username_msg.text())
        prefs['password'] = unicode(self.password_msg.text())
Пример #34
0
    def __init__(self, plugin_action):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        c = plugin_prefs[STORE_NAME]
        avail_columns = self.get_custom_columns()
        library_config = get_library_config(self.plugin_action.gui.current_db)
        pages_algorithm = library_config.get(KEY_PAGES_ALGORITHM, DEFAULT_LIBRARY_VALUES[KEY_PAGES_ALGORITHM])
        button_default = c.get(KEY_BUTTON_DEFAULT, DEFAULT_STORE_VALUES[KEY_BUTTON_DEFAULT])
        # Fudge the button default to cater for the options no longer supported by plugin as of 1.5
        if button_default in ['Estimate', 'EstimatePage', 'EstimateWord']:
            button_default = 'Estimate'
        else:
            button_default = 'Goodreads'
        overwrite_existing = c.get(KEY_OVERWRITE_EXISTING, DEFAULT_STORE_VALUES[KEY_OVERWRITE_EXISTING])

        # --- Pages ---
        page_group_box = QGroupBox('Page count options:', self)
        layout.addWidget(page_group_box)
        page_group_box_layout = QGridLayout()
        page_group_box.setLayout(page_group_box_layout)

        page_column_label = QLabel('&Custom column:', self)
        page_column_label.setToolTip('Leave this blank if you do not want to count pages')
        page_col = library_config.get(KEY_PAGES_CUSTOM_COLUMN, '')
        self.page_column_combo = CustomColumnComboBox(self, avail_columns, page_col)
        page_column_label.setBuddy(self.page_column_combo)
        page_group_box_layout.addWidget(page_column_label, 0, 0, 1, 1)
        page_group_box_layout.addWidget(self.page_column_combo, 0, 1, 1, 2)

        page_algorithm_label = QLabel('&Algorithm:', self)
        page_algorithm_label.setToolTip('Choose which algorithm to use if you have specified a page count column')
        self.page_algorithm_combo = AlgorithmComboBox(self, PAGE_ALGORITHMS, pages_algorithm)
        page_algorithm_label.setBuddy(self.page_algorithm_combo)
        page_group_box_layout.addWidget(page_algorithm_label, 1, 0, 1, 1)
        page_group_box_layout.addWidget(self.page_algorithm_combo, 1, 1, 1, 2)

        # --- Words ---
        layout.addSpacing(5)
        word_group_box = QGroupBox('Word count options:', self)
        layout.addWidget(word_group_box)
        word_group_box_layout = QGridLayout()
        word_group_box.setLayout(word_group_box_layout)

        word_column_label = QLabel('C&ustom column:', self)
        word_column_label.setToolTip('Leave this blank if you do not want to count words')
        word_col = library_config.get(KEY_WORDS_CUSTOM_COLUMN, '')
        self.word_column_combo = CustomColumnComboBox(self, avail_columns, word_col)
        word_column_label.setBuddy(self.word_column_combo)
        word_group_box_layout.addWidget(word_column_label, 0, 0, 1, 1)
        word_group_box_layout.addWidget(self.word_column_combo, 0, 1, 1, 2)

        # --- Readability ---
        layout.addSpacing(5)
        readability_group_box = QGroupBox('Readability options:', self)
        layout.addWidget(readability_group_box)
        readability_layout = QGridLayout()
        readability_group_box.setLayout(readability_layout)

        readability_label = QLabel('Readability statistics available are <a href="http://en.wikipedia.org/wiki/Flesch–Kincaid_readability_test">Flesch-Kincaid</a> '
                                   'or <a href="http://en.wikipedia.org/wiki/Gunning_fog_index">Gunning Fog Index</a>.', self)
        readability_layout.addWidget(readability_label, 0, 0, 1, 3)
        readability_label.linkActivated.connect(self._link_activated)

        flesch_reading_column_label = QLabel('&Flesch Reading Ease:', self)
        flesch_reading_column_label.setToolTip('Specify the custom column to store a computed Flesch Reading Ease score.\n'
                                     'Leave this blank if you do not want to calculate it')
        flesch_reading_col = library_config.get(KEY_FLESCH_READING_CUSTOM_COLUMN, '')
        self.flesch_reading_column_combo = CustomColumnComboBox(self, avail_columns, flesch_reading_col)
        flesch_reading_column_label.setBuddy(self.flesch_reading_column_combo)
        readability_layout.addWidget(flesch_reading_column_label, 1, 0, 1, 1)
        readability_layout.addWidget(self.flesch_reading_column_combo, 1, 1, 1, 2)

        flesch_grade_column_label = QLabel('Flesch-&Kincaid Grade:', self)
        flesch_grade_column_label.setToolTip('Specify the custom column to store a computed Flesch-Kincaid Grade Level score.\n'
                                     'Leave this blank if you do not want to calculate it')
        flesch_grade_col = library_config.get(KEY_FLESCH_GRADE_CUSTOM_COLUMN, '')
        self.flesch_grade_column_combo = CustomColumnComboBox(self, avail_columns, flesch_grade_col)
        flesch_grade_column_label.setBuddy(self.flesch_grade_column_combo)
        readability_layout.addWidget(flesch_grade_column_label, 2, 0, 1, 1)
        readability_layout.addWidget(self.flesch_grade_column_combo, 2, 1, 1, 2)

        gunning_fog_column_label = QLabel('&Gunning Fox Index:', self)
        gunning_fog_column_label.setToolTip('Specify the custom column to store a computed Gunning Fog Index score.\n'
                                     'Leave this blank if you do not want to calculate it')
        gunning_fog_col = library_config.get(KEY_GUNNING_FOG_CUSTOM_COLUMN, '')
        self.gunning_fog_column_combo = CustomColumnComboBox(self, avail_columns, gunning_fog_col)
        gunning_fog_column_label.setBuddy(self.gunning_fog_column_combo)
        readability_layout.addWidget(gunning_fog_column_label, 3, 0, 1, 1)
        readability_layout.addWidget(self.gunning_fog_column_combo, 3, 1, 1, 2)

        # --- Other options ---
        layout.addSpacing(5)
        other_group_box = QGroupBox('Other options:', self)
        layout.addWidget(other_group_box)
        other_group_box_layout = QGridLayout()
        other_group_box.setLayout(other_group_box_layout)

        button_default_label = QLabel('&Button default:', self)
        button_default_label.setToolTip('If plugin is placed as a toolbar button, choose a default action when clicked on')
        self.button_default_combo = KeyValueComboBox(self, BUTTON_DEFAULTS, button_default)
        button_default_label.setBuddy(self.button_default_combo)
        other_group_box_layout.addWidget(button_default_label, 0, 0, 1, 1)
        other_group_box_layout.addWidget(self.button_default_combo, 0, 1, 1, 2)

        self.overwrite_checkbox = QCheckBox('Always overwrite an existing word/page count', self)
        self.overwrite_checkbox.setToolTip('Uncheck this option if you have manually populated values in\n'
                                           'either of your page/word custom columns, and never want the\n'
                                           'plugin to overwrite it. Acts as a convenience option for users\n'
                                           'who have the toolbar button configured to populate both page\n'
                                           'and word count, but for some books have already assigned values\n'
                                           'into a column and just want the zero/blank column populated.')
        self.overwrite_checkbox.setChecked(overwrite_existing)
        other_group_box_layout.addWidget(self.overwrite_checkbox, 1, 0, 1, 3)

        keyboard_shortcuts_button = QPushButton('Keyboard shortcuts...', self)
        keyboard_shortcuts_button.setToolTip(_(
                    'Edit the keyboard shortcuts associated with this plugin'))
        keyboard_shortcuts_button.clicked.connect(self.edit_shortcuts)
        view_prefs_button = QPushButton('&View library preferences...', self)
        view_prefs_button.setToolTip(_(
                    'View data stored in the library database for this plugin'))
        view_prefs_button.clicked.connect(self.view_prefs)
        layout.addWidget(keyboard_shortcuts_button)
        layout.addWidget(view_prefs_button)
        layout.addStretch(1)
Пример #35
0
    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.db = db

        self.setWindowTitle(_('Check Library -- Problems Found'))
        self.setWindowIcon(QIcon(I('debug.png')))

        self._tl = QHBoxLayout()
        self.setLayout(self._tl)
        self.splitter = QSplitter(self)
        self.left = QWidget(self)
        self.splitter.addWidget(self.left)
        self.helpw = QTextEdit(self)
        self.splitter.addWidget(self.helpw)
        self._tl.addWidget(self.splitter)
        self._layout = QVBoxLayout()
        self.left.setLayout(self._layout)
        self.helpw.setReadOnly(True)
        self.helpw.setText(_('''\
        <h1>Help</h1>

        <p>calibre stores the list of your books and their metadata in a
        database. The actual book files and covers are stored as normal
        files in the calibre library folder. The database contains a list of the files
        and covers belonging to each book entry. This tool checks that the
        actual files in the library folder on your computer match the
        information in the database.</p>

        <p>The result of each type of check is shown to the left. The various
        checks are:
        </p>
        <ul>
        <li><b>Invalid titles</b>: These are files and folders appearing
        in the library where books titles should, but that do not have the
        correct form to be a book title.</li>
        <li><b>Extra titles</b>: These are extra files in your calibre
        library that appear to be correctly-formed titles, but have no corresponding
        entries in the database</li>
        <li><b>Invalid authors</b>: These are files appearing
        in the library where only author folders should be.</li>
        <li><b>Extra authors</b>: These are folders in the
        calibre library that appear to be authors but that do not have entries
        in the database</li>
        <li><b>Missing book formats</b>: These are book formats that are in
        the database but have no corresponding format file in the book's folder.
        <li><b>Extra book formats</b>: These are book format files found in
        the book's folder but not in the database.
        <li><b>Unknown files in books</b>: These are extra files in the
        folder of each book that do not correspond to a known format or cover
        file.</li>
        <li><b>Missing cover files</b>: These represent books that are marked
        in the database as having covers but the actual cover files are
        missing.</li>
        <li><b>Cover files not in database</b>: These are books that have
        cover files but are marked as not having covers in the database.</li>
        <li><b>Folder raising exception</b>: These represent folders in the
        calibre library that could not be processed/understood by this
        tool.</li>
        </ul>

        <p>There are two kinds of automatic fixes possible: <i>Delete
        marked</i> and <i>Fix marked</i>.</p>
        <p><i>Delete marked</i> is used to remove extra files/folders/covers that
        have no entries in the database. Check the box next to the item you want
        to delete. Use with caution.</p>

        <p><i>Fix marked</i> is applicable only to covers and missing formats
        (the three lines marked 'fixable'). In the case of missing cover files,
        checking the fixable box and pushing this button will tell calibre that
        there is no cover for all of the books listed. Use this option if you
        are not going to restore the covers from a backup. In the case of extra
        cover files, checking the fixable box and pushing this button will tell
        calibre that the cover files it found are correct for all the books
        listed. Use this when you are not going to delete the file(s). In the
        case of missing formats, checking the fixable box and pushing this
        button will tell calibre that the formats are really gone. Use this if
        you are not going to restore the formats from a backup.</p>

        '''))

        self.log = QTreeWidget(self)
        self.log.itemChanged.connect(self.item_changed)
        self.log.itemExpanded.connect(self.item_expanded_or_collapsed)
        self.log.itemCollapsed.connect(self.item_expanded_or_collapsed)
        self._layout.addWidget(self.log)

        self.check_button = QPushButton(_('&Run the check again'))
        self.check_button.setDefault(False)
        self.check_button.clicked.connect(self.run_the_check)
        self.copy_button = QPushButton(_('Copy &to clipboard'))
        self.copy_button.setDefault(False)
        self.copy_button.clicked.connect(self.copy_to_clipboard)
        self.ok_button = QPushButton(_('&Done'))
        self.ok_button.setDefault(True)
        self.ok_button.clicked.connect(self.accept)
        self.delete_button = QPushButton(_('Delete &marked'))
        self.delete_button.setToolTip(_('Delete marked files (checked subitems)'))
        self.delete_button.setDefault(False)
        self.delete_button.clicked.connect(self.delete_marked)
        self.fix_button = QPushButton(_('&Fix marked'))
        self.fix_button.setDefault(False)
        self.fix_button.setEnabled(False)
        self.fix_button.setToolTip(_('Fix marked sections (checked fixable items)'))
        self.fix_button.clicked.connect(self.fix_items)
        self.bbox = QDialogButtonBox(self)
        self.bbox.addButton(self.check_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.delete_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.fix_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.copy_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.ok_button, QDialogButtonBox.AcceptRole)

        h = QHBoxLayout()
        ln = QLabel(_('Names to ignore:'))
        h.addWidget(ln)
        self.name_ignores = QLineEdit()
        self.name_ignores.setText(db.prefs.get('check_library_ignore_names', ''))
        self.name_ignores.setToolTip(
            _('Enter comma-separated standard file name wildcards, such as synctoy*.dat'))
        ln.setBuddy(self.name_ignores)
        h.addWidget(self.name_ignores)
        le = QLabel(_('Extensions to ignore'))
        h.addWidget(le)
        self.ext_ignores = QLineEdit()
        self.ext_ignores.setText(db.prefs.get('check_library_ignore_extensions', ''))
        self.ext_ignores.setToolTip(
            _('Enter comma-separated extensions without a leading dot. Used only in book folders'))
        le.setBuddy(self.ext_ignores)
        h.addWidget(self.ext_ignores)
        self._layout.addLayout(h)

        self._layout.addWidget(self.bbox)
        self.resize(950, 500)
        self.bbox.setEnabled(True)
Пример #36
0
class AddBookDialog(SizePersistedDialog):
    def __init__(self, parent=None, mm=None, mi=None):
        SizePersistedDialog.__init__(self, parent,
                                     'casanova plugin:add book dialog')
        self.setWindowTitle('Add text to Casanova:')
        self.gui = parent
        self.mm = mm
        self.mi = mi
        self.one_line_description = ''

        layout = QVBoxLayout(self)
        self.setLayout(layout)

        self.one_liner_label = QLabel(
            'Enter a short description (255 chars max) before pressing OK')
        layout.addWidget(self.one_liner_label)
        self.one_liner_str = QLineEdit(self)
        self.one_liner_str.setText('')
        layout.addWidget(self.one_liner_str)
        self.one_liner_label.setBuddy(self.one_liner_str)

        self.values_label = QLabel(
            'Below are potential matches of texts that already exist - please make sure you are adding something new'
        )
        layout.addWidget(self.values_label)
        self.values_list = QListWidget(self)
        self.values_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        layout.addWidget(self.values_list)

        self.button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                           | QDialogButtonBox.Cancel)
        self.button_box.accepted.connect(self._accept_clicked)
        self.button_box.rejected.connect(self.reject)
        layout.addWidget(self.button_box)

        self._display_choices()

        # Cause our dialog size to be restored from prefs or created on first usage
        self.resize_dialog()

    def _display_choices(self):
        self.values_list.clear()
        choices = self.mm.search(self.mi.title)
        if choices is None or len(choices) == 0:
            item = QListWidgetItem(get_icon('images/books.png'),
                                   _('there seem to be no matches'),
                                   self.values_list)
            self.values_list.addItem(item)
        for id, name in choices.items():
            item = QListWidgetItem(get_icon('images/books.png'), name,
                                   self.values_list)
            item.setData(1, (id, ))
            self.values_list.addItem(item)

    def _accept_clicked(self):
        #self._save_preferences()
        one_liner = unicode(self.one_liner_str.text())
        if one_liner == '':
            self.values_list.clear()
            item = QListWidgetItem(get_icon('images/books.png'),
                                   _('you need to enter a short description'),
                                   self.values_list)
            self.values_list.addItem(item)
        else:
            self.one_line_description = one_liner
        self.accept()
Пример #37
0
    def __init__(self,
                 field_metadata,
                 parent=None,
                 revert_tooltip=None,
                 datetime_fmt='MMMM yyyy',
                 blank_as_equal=True,
                 fields=('title', 'authors', 'series', 'tags', 'rating',
                         'publisher', 'pubdate', 'identifiers', 'languages',
                         'comments', 'cover')):
        QWidget.__init__(self, parent)
        self.l = l = QGridLayout()
        l.setContentsMargins(0, 0, 0, 0)
        self.setLayout(l)
        revert_tooltip = revert_tooltip or _('Revert %s')
        self.current_mi = None
        self.changed_font = QFont(QApplication.font())
        self.changed_font.setBold(True)
        self.changed_font.setItalic(True)
        self.blank_as_equal = blank_as_equal

        self.widgets = OrderedDict()
        row = 0

        for field in fields:
            m = field_metadata[field]
            dt = m['datatype']
            extra = None
            if 'series' in {field, dt}:
                cls = SeriesEdit
            elif field == 'identifiers':
                cls = IdentifiersEdit
            elif field == 'languages':
                cls = LanguagesEdit
            elif 'comments' in {field, dt}:
                cls = CommentsEdit
            elif 'rating' in {field, dt}:
                cls = RatingsEdit
            elif dt == 'datetime':
                extra = datetime_fmt
                cls = DateEdit
            elif field == 'cover':
                cls = CoverView
            elif dt in {'text', 'enum'}:
                cls = LineEdit
            else:
                continue
            neww = cls(field, True, self, m, extra)
            neww.changed.connect(partial(self.changed, field))
            oldw = cls(field, False, self, m, extra)
            newl = QLabel('&%s:' % m['name'])
            newl.setBuddy(neww)
            button = QToolButton(self)
            button.setIcon(QIcon(I('back.png')))
            button.clicked.connect(partial(self.revert, field))
            button.setToolTip(revert_tooltip % m['name'])
            self.widgets[field] = Widgets(neww, oldw, newl, button)
            for i, w in enumerate((newl, neww, button, oldw)):
                c = i if i < 2 else i + 1
                if w is oldw:
                    c += 1
                l.addWidget(w, row, c)
            row += 1

        self.sep = f = QFrame(self)
        f.setFrameShape(f.VLine)
        l.addWidget(f, 0, 2, row, 1)
        self.sep2 = f = QFrame(self)
        f.setFrameShape(f.VLine)
        l.addWidget(f, 0, 4, row, 1)
Пример #38
0
class ManageKeysDialog(QDialog):
    def __init__(self,
                 parent,
                 key_type_name,
                 plugin_keys,
                 create_key,
                 keyfile_ext=u"",
                 wineprefix=None):
        QDialog.__init__(self, parent)
        self.parent = parent
        self.key_type_name = key_type_name
        self.plugin_keys = plugin_keys
        self.create_key = create_key
        self.keyfile_ext = keyfile_ext
        self.import_key = (keyfile_ext != u"")
        self.binary_file = (keyfile_ext == u"der")
        self.json_file = (keyfile_ext == u"k4i")
        self.wineprefix = wineprefix

        self.setWindowTitle("{0} {1}: Manage {2}s".format(
            PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))

        # Start Qt Gui dialog layout
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        help_layout = QHBoxLayout()
        layout.addLayout(help_layout)
        # Add hyperlink to a help file at the right. We will replace the correct name when it is clicked.
        help_label = QLabel('<a href="http://www.foo.com/">Help</a>', self)
        help_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse
                                           | Qt.LinksAccessibleByKeyboard)
        help_label.setAlignment(Qt.AlignRight)
        help_label.linkActivated.connect(self.help_link_activated)
        help_layout.addWidget(help_label)

        keys_group_box = QGroupBox(_(u"{0}s".format(self.key_type_name)), self)
        layout.addWidget(keys_group_box)
        keys_group_box_layout = QHBoxLayout()
        keys_group_box.setLayout(keys_group_box_layout)

        self.listy = QListWidget(self)
        self.listy.setToolTip(
            u"{0}s that will be used to decrypt ebooks".format(
                self.key_type_name))
        self.listy.setSelectionMode(QAbstractItemView.SingleSelection)
        self.populate_list()
        keys_group_box_layout.addWidget(self.listy)

        button_layout = QVBoxLayout()
        keys_group_box_layout.addLayout(button_layout)
        self._add_key_button = QtGui.QToolButton(self)
        self._add_key_button.setToolTip(u"Create new {0}".format(
            self.key_type_name))
        self._add_key_button.setIcon(QIcon(I('plus.png')))
        self._add_key_button.clicked.connect(self.add_key)
        button_layout.addWidget(self._add_key_button)

        self._delete_key_button = QtGui.QToolButton(self)
        self._delete_key_button.setToolTip(_(u"Delete highlighted key"))
        self._delete_key_button.setIcon(QIcon(I('list_remove.png')))
        self._delete_key_button.clicked.connect(self.delete_key)
        button_layout.addWidget(self._delete_key_button)

        if type(self.plugin_keys) == dict and self.import_key:
            self._rename_key_button = QtGui.QToolButton(self)
            self._rename_key_button.setToolTip(_(u"Rename highlighted key"))
            self._rename_key_button.setIcon(QIcon(I('edit-select-all.png')))
            self._rename_key_button.clicked.connect(self.rename_key)
            button_layout.addWidget(self._rename_key_button)

            self.export_key_button = QtGui.QToolButton(self)
            self.export_key_button.setToolTip(
                u"Save highlighted key to a .{0} file".format(
                    self.keyfile_ext))
            self.export_key_button.setIcon(QIcon(I('save.png')))
            self.export_key_button.clicked.connect(self.export_key)
            button_layout.addWidget(self.export_key_button)
        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
                                       QtGui.QSizePolicy.Expanding)
        button_layout.addItem(spacerItem)

        if self.wineprefix is not None:
            layout.addSpacing(5)
            wineprefix_layout = QHBoxLayout()
            layout.addLayout(wineprefix_layout)
            wineprefix_layout.setAlignment(Qt.AlignCenter)
            self.wp_label = QLabel(u"WINEPREFIX:")
            wineprefix_layout.addWidget(self.wp_label)
            self.wp_lineedit = QLineEdit(self)
            wineprefix_layout.addWidget(self.wp_lineedit)
            self.wp_label.setBuddy(self.wp_lineedit)
            self.wp_lineedit.setText(self.wineprefix)

        layout.addSpacing(5)
        migrate_layout = QHBoxLayout()
        layout.addLayout(migrate_layout)
        if self.import_key:
            migrate_layout.setAlignment(Qt.AlignJustify)
            self.migrate_btn = QPushButton(u"Import Existing Keyfiles", self)
            self.migrate_btn.setToolTip(
                u"Import *.{0} files (created using other tools).".format(
                    self.keyfile_ext))
            self.migrate_btn.clicked.connect(self.migrate_wrapper)
            migrate_layout.addWidget(self.migrate_btn)
        migrate_layout.addStretch()
        self.button_box = QDialogButtonBox(QDialogButtonBox.Close)
        self.button_box.rejected.connect(self.close)
        migrate_layout.addWidget(self.button_box)

        self.resize(self.sizeHint())

    def getwineprefix(self):
        if self.wineprefix is not None:
            return unicode(self.wp_lineedit.text().toUtf8(), 'utf8').strip()
        return u""

    def populate_list(self):
        if type(self.plugin_keys) == dict:
            for key in self.plugin_keys.keys():
                self.listy.addItem(QListWidgetItem(key))
        else:
            for key in self.plugin_keys:
                self.listy.addItem(QListWidgetItem(key))

    def add_key(self):
        d = self.create_key(self)
        d.exec_()

        if d.result() != d.Accepted:
            # New key generation cancelled.
            return
        new_key_value = d.key_value
        if type(self.plugin_keys) == dict:
            if new_key_value in self.plugin_keys.values():
                old_key_name = [
                    name for name, value in self.plugin_keys.iteritems()
                    if value == new_key_value
                ][0]
                info_dialog(
                    None,
                    "{0} {1}: Duplicate {2}".format(PLUGIN_NAME,
                                                    PLUGIN_VERSION,
                                                    self.key_type_name),
                    u"The new {1} is the same as the existing {1} named <strong>{0}</strong> and has not been added."
                    .format(old_key_name, self.key_type_name),
                    show=True)
                return
            self.plugin_keys[d.key_name] = new_key_value
        else:
            if new_key_value in self.plugin_keys:
                info_dialog(
                    None,
                    "{0} {1}: Duplicate {2}".format(PLUGIN_NAME,
                                                    PLUGIN_VERSION,
                                                    self.key_type_name),
                    u"This {0} is already in the list of {0}s has not been added."
                    .format(self.key_type_name),
                    show=True)
                return

            self.plugin_keys.append(d.key_value)
        self.listy.clear()
        self.populate_list()

    def rename_key(self):
        if not self.listy.currentItem():
            errmsg = u"No {0} selected to rename. Highlight a keyfile first.".format(
                self.key_type_name)
            r = error_dialog(None,
                             "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
                             _(errmsg),
                             show=True,
                             show_copy_button=False)
            return

        d = RenameKeyDialog(self)
        d.exec_()

        if d.result() != d.Accepted:
            # rename cancelled or moot.
            return
        keyname = unicode(self.listy.currentItem().text().toUtf8(), 'utf8')
        if not question_dialog(
                self,
                "{0} {1}: Confirm Rename".format(PLUGIN_NAME, PLUGIN_VERSION),
                u"Do you really want to rename the {2} named <strong>{0}</strong> to <strong>{1}</strong>?"
                .format(keyname, d.key_name, self.key_type_name),
                show_copy_button=False,
                default_yes=False):
            return
        self.plugin_keys[d.key_name] = self.plugin_keys[keyname]
        del self.plugin_keys[keyname]

        self.listy.clear()
        self.populate_list()

    def delete_key(self):
        if not self.listy.currentItem():
            return
        keyname = unicode(self.listy.currentItem().text().toUtf8(), 'utf8')
        if not question_dialog(
                self,
                "{0} {1}: Confirm Delete".format(PLUGIN_NAME, PLUGIN_VERSION),
                u"Do you really want to delete the {1} <strong>{0}</strong>?".
                format(keyname, self.key_type_name),
                show_copy_button=False,
                default_yes=False):
            return
        if type(self.plugin_keys) == dict:
            del self.plugin_keys[keyname]
        else:
            self.plugin_keys.remove(keyname)

        self.listy.clear()
        self.populate_list()

    def help_link_activated(self, url):
        def get_help_file_resource():
            # Copy the HTML helpfile to the plugin directory each time the
            # link is clicked in case the helpfile is updated in newer plugins.
            help_file_name = u"{0}_{1}_Help.htm".format(
                PLUGIN_NAME, self.key_type_name)
            file_path = os.path.join(config_dir, u"plugins", u"DeDRM", u"help",
                                     help_file_name)
            with open(file_path, 'w') as f:
                f.write(self.parent.load_resource(help_file_name))
            return file_path

        url = 'file:///' + get_help_file_resource()
        open_url(QUrl(url))

    def migrate_files(self):
        dynamic[PLUGIN_NAME + u"config_dir"] = config_dir
        files = choose_files(
            self, PLUGIN_NAME + u"config_dir",
            u"Select {0} files to import".format(self.key_type_name),
            [(u"{0} files".format(self.key_type_name), [self.keyfile_ext])],
            False)
        counter = 0
        skipped = 0
        if files:
            for filename in files:
                fpath = os.path.join(config_dir, filename)
                filename = os.path.basename(filename)
                new_key_name = os.path.splitext(os.path.basename(filename))[0]
                with open(fpath, 'rb') as keyfile:
                    new_key_value = keyfile.read()
                if self.binary_file:
                    new_key_value = new_key_value.encode('hex')
                elif self.json_file:
                    new_key_value = json.loads(new_key_value)
                match = False
                for key in self.plugin_keys.keys():
                    if uStrCmp(new_key_name, key, True):
                        skipped += 1
                        msg = u"A key with the name <strong>{0}</strong> already exists!\nSkipping key file  <strong>{1}</strong>.\nRename the existing key and import again".format(
                            new_key_name, filename)
                        inf = info_dialog(None,
                                          "{0} {1}".format(
                                              PLUGIN_NAME, PLUGIN_VERSION),
                                          _(msg),
                                          show_copy_button=False,
                                          show=True)
                        match = True
                        break
                if not match:
                    if new_key_value in self.plugin_keys.values():
                        old_key_name = [
                            name
                            for name, value in self.plugin_keys.iteritems()
                            if value == new_key_value
                        ][0]
                        skipped += 1
                        info_dialog(
                            None,
                            "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
                            u"The key in file {0} is the same as the existing key <strong>{1}</strong> and has been skipped."
                            .format(filename, old_key_name),
                            show_copy_button=False,
                            show=True)
                    else:
                        counter += 1
                        self.plugin_keys[new_key_name] = new_key_value

            msg = u""
            if counter + skipped > 1:
                if counter > 0:
                    msg += u"Imported <strong>{0:d}</strong> key {1}. ".format(
                        counter, u"file" if counter == 1 else u"files")
                if skipped > 0:
                    msg += u"Skipped <strong>{0:d}</strong> key {1}.".format(
                        skipped, u"file" if counter == 1 else u"files")
                inf = info_dialog(None,
                                  "{0} {1}".format(PLUGIN_NAME,
                                                   PLUGIN_VERSION),
                                  _(msg),
                                  show_copy_button=False,
                                  show=True)
        return counter > 0

    def migrate_wrapper(self):
        if self.migrate_files():
            self.listy.clear()
            self.populate_list()

    def export_key(self):
        if not self.listy.currentItem():
            errmsg = u"No keyfile selected to export. Highlight a keyfile first."
            r = error_dialog(None,
                             "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
                             _(errmsg),
                             show=True,
                             show_copy_button=False)
            return
        filter = QString(u"{0} Files (*.{1})".format(self.key_type_name,
                                                     self.keyfile_ext))
        keyname = unicode(self.listy.currentItem().text().toUtf8(), 'utf8')
        if dynamic.get(PLUGIN_NAME + 'save_dir'):
            defaultname = os.path.join(
                dynamic.get(PLUGIN_NAME + 'save_dir'),
                u"{0}.{1}".format(keyname, self.keyfile_ext))
        else:
            defaultname = os.path.join(
                os.path.expanduser('~'),
                u"{0}.{1}".format(keyname, self.keyfile_ext))
        filename = unicode(
            QtGui.QFileDialog.getSaveFileName(
                self, u"Save {0} File as...".format(self.key_type_name),
                defaultname,
                u"{0} Files (*.{1})".format(self.key_type_name,
                                            self.keyfile_ext), filter))
        if filename:
            dynamic[PLUGIN_NAME + 'save_dir'] = os.path.split(filename)[0]
            with file(filename, 'w') as fname:
                if self.binary_file:
                    fname.write(self.plugin_keys[keyname].decode('hex'))
                elif self.json_file:
                    fname.write(json.dumps(self.plugin_keys[keyname]))
                else:
                    fname.write(self.plugin_keys[keyname])
Пример #39
0
    def __init__(
            self, field_metadata, parent=None, revert_tooltip=None,
            datetime_fmt='MMMM yyyy', blank_as_equal=True,
            fields=('title', 'authors', 'series', 'tags', 'rating', 'publisher', 'pubdate', 'identifiers', 'languages', 'comments', 'cover')):
        QWidget.__init__(self, parent)
        self.l = l = QGridLayout()
        l.setContentsMargins(0, 0, 0, 0)
        self.setLayout(l)
        revert_tooltip = revert_tooltip or _('Revert %s')
        self.current_mi = None
        self.changed_font = QFont(QApplication.font())
        self.changed_font.setBold(True)
        self.changed_font.setItalic(True)
        self.blank_as_equal = blank_as_equal

        self.widgets = OrderedDict()
        row = 0

        for field in fields:
            m = field_metadata[field]
            dt = m['datatype']
            extra = None
            if 'series' in {field, dt}:
                cls = SeriesEdit
            elif field == 'identifiers':
                cls = IdentifiersEdit
            elif field == 'languages':
                cls = LanguagesEdit
            elif 'comments' in {field, dt}:
                cls = CommentsEdit
            elif 'rating' in {field, dt}:
                cls = RatingsEdit
            elif dt == 'datetime':
                extra = datetime_fmt
                cls = DateEdit
            elif field == 'cover':
                cls = CoverView
            elif dt in {'text', 'enum'}:
                cls = LineEdit
            else:
                continue
            neww = cls(field, True, self, m, extra)
            neww.changed.connect(partial(self.changed, field))
            oldw = cls(field, False, self, m, extra)
            newl = QLabel('&%s:' % m['name'])
            newl.setBuddy(neww)
            button = QToolButton(self)
            button.setIcon(QIcon(I('back.png')))
            button.clicked.connect(partial(self.revert, field))
            button.setToolTip(revert_tooltip % m['name'])
            self.widgets[field] = Widgets(neww, oldw, newl, button)
            for i, w in enumerate((newl, neww, button, oldw)):
                c = i if i < 2 else i + 1
                if w is oldw:
                    c += 1
                l.addWidget(w, row, c)
            row += 1

        self.sep = f = QFrame(self)
        f.setFrameShape(f.VLine)
        l.addWidget(f, 0, 2, row, 1)
        self.sep2 = f = QFrame(self)
        f.setFrameShape(f.VLine)
        l.addWidget(f, 0, 4, row, 1)
        if 'comments' in self.widgets and not gprefs.get('diff_widget_show_comments_controls', True):
            self.widgets['comments'].new.hide_toolbars()
class ConfigWidget(QWidget):

    def __init__(self, plugin_action, prefs):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        self.prefs = prefs

        self.layout = QGridLayout()
        self.setLayout(self.layout)

        accounts = self.prefs[self.prefs.ACCOUNTS]
        # Copy any data necessary into the prefs object

        # The primary account, as configured in the GUI above
        account = accounts.get('0', {})

        self.labelUrlBase = QLabel(_('URL'))
        self.layout.addWidget(self.labelUrlBase, 0, 0)

        self.urlbase = QLabel()
        if prefs[prefs.URLBASE] is not None:
            self.urlbase.setText(prefs[prefs.URLBASE])
        self.layout.addWidget(self.urlbase, 0, 1)
        self.labelUrlBase.setBuddy(self.urlbase)

        self.labelUserName = QLabel(_('Username'))
        self.layout.addWidget(self.labelUserName, 1, 0)

        self.username = QLineEdit(self)
        if account.get(prefs.USERNAME) is not None:
            self.username.setText(account[prefs.USERNAME])
        self.layout.addWidget(self.username, 1, 1)
        self.labelUserName.setBuddy(self.username)

        self.labelPassword = QLabel(_('Password'))
        self.layout.addWidget(self.labelPassword, 2, 0)

        self.password = QLineEdit(self)
        if account.get(prefs.OBFUSCATED_PASSWORD) is not None:
            decrypted = prefs.decrypt_password(account[prefs.OBFUSCATED_PASSWORD])
            self.password.setText(decrypted)

        self.layout.addWidget(self.password, 2, 1)
        self.labelPassword.setBuddy(self.password)


    def save_settings(self):

        # TODO proper obfuscating somewhere, maybe even in 'migrate'

        accounts = self.prefs[self.prefs.ACCOUNTS]
        # Copy any data necessary into the prefs object

        # The primary account, as configured in the GUI above
        account_id = '0'
        account = accounts.get(account_id, {})
        account[self.prefs.ACCOUNT_ID] = account_id
        account[self.prefs.USERNAME] = '%s' % self.username.text()
        decrypted = '%s' % self.password.text()
        # account['Lala'] = decrypted
        account[self.prefs.OBFUSCATED_PASSWORD] = '%s' % self.prefs.encrypt_password(decrypted) 
        account[self.prefs.ENABLED] = True
        accounts[account_id] = account

        # Now the secondary account :-)
        account_id = '1'
        account = accounts.get(account_id, {})
        account[self.prefs.ACCOUNT_ID] = account_id
        if account.get(self.prefs.USERNAME) is None:
            account[self.prefs.USERNAME] = ''
            decrypted = ''
            # account['Lala'] = decrypted
            account[self.prefs.OBFUSCATED_PASSWORD] = '%s' % self.prefs.encrypt_password(decrypted) 
            account[self.prefs.ENABLED] = False
        accounts[account_id] = account

        # Now, put the hash back to the main prefs
        self.prefs[self.prefs.ACCOUNTS] = accounts

        # And save it...
        self.prefs.save()
class ConfigWidget(QWidget):
    def __init__(self, plugin_action, prefs):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        self.prefs = prefs

        self.layout = QGridLayout()
        self.setLayout(self.layout)

        accounts = self.prefs[self.prefs.ACCOUNTS]
        # Copy any data necessary into the prefs object

        # The primary account, as configured in the GUI above
        account = accounts.get('0', {})

        self.labelUrlBase = QLabel(_('URL'))
        self.layout.addWidget(self.labelUrlBase, 0, 0)

        self.urlbase = QLabel()
        if prefs[prefs.URLBASE] is not None:
            self.urlbase.setText(prefs[prefs.URLBASE])
        self.layout.addWidget(self.urlbase, 0, 1)
        self.labelUrlBase.setBuddy(self.urlbase)

        self.labelUserName = QLabel(_('Username'))
        self.layout.addWidget(self.labelUserName, 1, 0)

        self.username = QLineEdit(self)
        if account.get(prefs.USERNAME) is not None:
            self.username.setText(account[prefs.USERNAME])
        self.layout.addWidget(self.username, 1, 1)
        self.labelUserName.setBuddy(self.username)

        self.labelPassword = QLabel(_('Password'))
        self.layout.addWidget(self.labelPassword, 2, 0)

        self.password = QLineEdit(self)
        if account.get(prefs.OBFUSCATED_PASSWORD) is not None:
            decrypted = prefs.decrypt_password(
                account[prefs.OBFUSCATED_PASSWORD])
            self.password.setText(decrypted)

        self.layout.addWidget(self.password, 2, 1)
        self.labelPassword.setBuddy(self.password)

    def save_settings(self):

        # TODO proper obfuscating somewhere, maybe even in 'migrate'

        accounts = self.prefs[self.prefs.ACCOUNTS]
        # Copy any data necessary into the prefs object

        # The primary account, as configured in the GUI above
        account_id = '0'
        account = accounts.get(account_id, {})
        account[self.prefs.ACCOUNT_ID] = account_id
        account[self.prefs.USERNAME] = '%s' % self.username.text()
        decrypted = '%s' % self.password.text()
        # account['Lala'] = decrypted
        account[self.prefs.
                OBFUSCATED_PASSWORD] = '%s' % self.prefs.encrypt_password(
                    decrypted)
        account[self.prefs.ENABLED] = True
        accounts[account_id] = account

        # Now the secondary account :-)
        account_id = '1'
        account = accounts.get(account_id, {})
        account[self.prefs.ACCOUNT_ID] = account_id
        if account.get(self.prefs.USERNAME) is None:
            account[self.prefs.USERNAME] = ''
            decrypted = ''
            # account['Lala'] = decrypted
            account[self.prefs.
                    OBFUSCATED_PASSWORD] = '%s' % self.prefs.encrypt_password(
                        decrypted)
            account[self.prefs.ENABLED] = False
        accounts[account_id] = account

        # Now, put the hash back to the main prefs
        self.prefs[self.prefs.ACCOUNTS] = accounts

        # And save it...
        self.prefs.save()
Пример #42
0
class ValueTypeEditor(QWidget):
    ValueTypes = (bool, int, float, complex, str)

    def __init__(self, *args):
        QWidget.__init__(self, *args)
        lo = QHBoxLayout(self)
        lo.setContentsMargins(0, 0, 0, 0)
        lo.setSpacing(5)
        # type selector
        self.wtypesel = QComboBox(self)
        for i, tp in enumerate(self.ValueTypes):
            self.wtypesel.addItem(tp.__name__)
        QObject.connect(self.wtypesel, SIGNAL("activated(int)"), self._selectTypeNum)
        typesel_lab = QLabel("&Type:", self)
        typesel_lab.setBuddy(self.wtypesel)
        lo.addWidget(typesel_lab, 0)
        lo.addWidget(self.wtypesel, 0)
        self.wvalue = QLineEdit(self)
        self.wvalue_lab = QLabel("&Value:", self)
        self.wvalue_lab.setBuddy(self.wvalue)
        self.wbool = QComboBox(self)
        self.wbool.addItems(["false", "true"])
        self.wbool.setCurrentIndex(1)
        lo.addWidget(self.wvalue_lab, 0)
        lo.addWidget(self.wvalue, 1)
        lo.addWidget(self.wbool, 1)
        self.wvalue.hide()
        # make input validators
        self._validators = {int: QIntValidator(self), float: QDoubleValidator(self)}
        # select bool type initially
        self._selectTypeNum(0)

    def _selectTypeNum(self, index):
        tp = self.ValueTypes[index]
        self.wbool.setShown(tp is bool)
        self.wvalue.setShown(tp is not bool)
        self.wvalue_lab.setBuddy(self.wbool if tp is bool else self.wvalue)
        self.wvalue.setValidator(self._validators.get(tp, None))

    def setValue(self, value):
        """Sets current value"""
        for i, tp in enumerate(self.ValueTypes):
            if isinstance(value, tp):
                self.wtypesel.setCurrentIndex(i)
                self._selectTypeNum(i)
                if tp is bool:
                    self.wbool.setCurrentIndex(1 if value else 0)
                else:
                    self.wvalue.setText(str(value))
                return
        # unknown value: set bool
        self.setValue(True)

    def getValue(self):
        """Returns current value, or None if no legal value is set"""
        tp = self.ValueTypes[self.wtypesel.currentIndex()]
        if tp is bool:
            return bool(self.wbool.currentIndex())
        else:
            try:
                return tp(self.wvalue.text())
            except:
                print("Error converting input to type ", tp.__name__)
                traceback.print_exc()
                return None
Пример #43
0
    def __init__(self, settings, all_formats, supports_subdirs,
        must_read_metadata, supports_use_author_sort,
        extra_customization_message, device, extra_customization_choices=None):

        QWidget.__init__(self)
        Ui_ConfigWidget.__init__(self)
        self.setupUi(self)

        self.settings = settings

        all_formats = set(all_formats)
        self.calibre_known_formats = device.FORMATS
        try:
            self.device_name = device.get_gui_name()
        except TypeError:
            self.device_name = getattr(device, 'gui_name', None) or _('Device')
        if device.USER_CAN_ADD_NEW_FORMATS:
            all_formats = set(all_formats) | set(BOOK_EXTENSIONS)

        format_map = settings.format_map
        disabled_formats = list(set(all_formats).difference(format_map))
        for format in format_map + list(sorted(disabled_formats)):
            item = QListWidgetItem(format, self.columns)
            item.setData(Qt.UserRole, QVariant(format))
            item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable|Qt.ItemIsSelectable)
            item.setCheckState(Qt.Checked if format in format_map else Qt.Unchecked)

        self.column_up.clicked.connect(self.up_column)
        self.column_down.clicked.connect(self.down_column)

        if device.HIDE_FORMATS_CONFIG_BOX:
            self.groupBox.hide()

        if supports_subdirs:
            self.opt_use_subdirs.setChecked(self.settings.use_subdirs)
        else:
            self.opt_use_subdirs.hide()
        if not must_read_metadata:
            self.opt_read_metadata.setChecked(self.settings.read_metadata)
        else:
            self.opt_read_metadata.hide()
        if supports_use_author_sort:
            self.opt_use_author_sort.setChecked(self.settings.use_author_sort)
        else:
            self.opt_use_author_sort.hide()
        if extra_customization_message:
            extra_customization_choices = extra_customization_choices or {}
            def parse_msg(m):
                msg, _, tt = m.partition(':::') if m else ('', '', '')
                return msg.strip(), textwrap.fill(tt.strip(), 100)

            if isinstance(extra_customization_message, list):
                self.opt_extra_customization = []
                if len(extra_customization_message) > 6:
                    row_func = lambda x, y: ((x/2) * 2) + y
                    col_func = lambda x: x%2
                else:
                    row_func = lambda x, y: x*2 + y
                    col_func = lambda x: 0

                for i, m in enumerate(extra_customization_message):
                    label_text, tt = parse_msg(m)
                    if not label_text:
                        self.opt_extra_customization.append(None)
                        continue
                    if isinstance(settings.extra_customization[i], bool):
                        self.opt_extra_customization.append(QCheckBox(label_text))
                        self.opt_extra_customization[-1].setToolTip(tt)
                        self.opt_extra_customization[i].setChecked(bool(settings.extra_customization[i]))
                    elif i in extra_customization_choices:
                        cb = QComboBox(self)
                        self.opt_extra_customization.append(cb)
                        l = QLabel(label_text)
                        l.setToolTip(tt), cb.setToolTip(tt), l.setBuddy(cb), cb.setToolTip(tt)
                        for li in sorted(extra_customization_choices[i]):
                            self.opt_extra_customization[i].addItem(li)
                        cb.setCurrentIndex(max(0, cb.findText(settings.extra_customization[i])))
                    else:
                        self.opt_extra_customization.append(QLineEdit(self))
                        l = QLabel(label_text)
                        l.setToolTip(tt)
                        self.opt_extra_customization[i].setToolTip(tt)
                        l.setBuddy(self.opt_extra_customization[i])
                        l.setWordWrap(True)
                        self.opt_extra_customization[i].setText(settings.extra_customization[i])
                        self.opt_extra_customization[i].setCursorPosition(0)
                        self.extra_layout.addWidget(l, row_func(i, 0), col_func(i))
                    self.extra_layout.addWidget(self.opt_extra_customization[i],
                                                row_func(i, 1), col_func(i))
            else:
                self.opt_extra_customization = QLineEdit()
                label_text, tt = parse_msg(extra_customization_message)
                l = QLabel(label_text)
                l.setToolTip(tt)
                l.setBuddy(self.opt_extra_customization)
                l.setWordWrap(True)
                if settings.extra_customization:
                    self.opt_extra_customization.setText(settings.extra_customization)
                    self.opt_extra_customization.setCursorPosition(0)
                self.opt_extra_customization.setCursorPosition(0)
                self.extra_layout.addWidget(l, 0, 0)
                self.extra_layout.addWidget(self.opt_extra_customization, 1, 0)
        self.opt_save_template.setText(settings.save_template)
Пример #44
0
class ManageKeysDialog(QDialog):
    def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext = u"", wineprefix = None):
        QDialog.__init__(self,parent)
        self.parent = parent
        self.key_type_name = key_type_name
        self.plugin_keys = plugin_keys
        self.create_key = create_key
        self.keyfile_ext = keyfile_ext
        self.import_key = (keyfile_ext != u"")
        self.binary_file = (keyfile_ext == u"der")
        self.json_file = (keyfile_ext == u"k4i")
        self.wineprefix = wineprefix

        self.setWindowTitle("{0} {1}: Manage {2}s".format(PLUGIN_NAME, PLUGIN_VERSION, self.key_type_name))

        # Start Qt Gui dialog layout
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        help_layout = QHBoxLayout()
        layout.addLayout(help_layout)
        # Add hyperlink to a help file at the right. We will replace the correct name when it is clicked.
        help_label = QLabel('<a href="http://www.foo.com/">Help</a>', self)
        help_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard)
        help_label.setAlignment(Qt.AlignRight)
        help_label.linkActivated.connect(self.help_link_activated)
        help_layout.addWidget(help_label)

        keys_group_box = QGroupBox(_(u"{0}s".format(self.key_type_name)), self)
        layout.addWidget(keys_group_box)
        keys_group_box_layout = QHBoxLayout()
        keys_group_box.setLayout(keys_group_box_layout)

        self.listy = QListWidget(self)
        self.listy.setToolTip(u"{0}s that will be used to decrypt ebooks".format(self.key_type_name))
        self.listy.setSelectionMode(QAbstractItemView.SingleSelection)
        self.populate_list()
        keys_group_box_layout.addWidget(self.listy)

        button_layout = QVBoxLayout()
        keys_group_box_layout.addLayout(button_layout)
        self._add_key_button = QtGui.QToolButton(self)
        self._add_key_button.setToolTip(u"Create new {0}".format(self.key_type_name))
        self._add_key_button.setIcon(QIcon(I('plus.png')))
        self._add_key_button.clicked.connect(self.add_key)
        button_layout.addWidget(self._add_key_button)

        self._delete_key_button = QtGui.QToolButton(self)
        self._delete_key_button.setToolTip(_(u"Delete highlighted key"))
        self._delete_key_button.setIcon(QIcon(I('list_remove.png')))
        self._delete_key_button.clicked.connect(self.delete_key)
        button_layout.addWidget(self._delete_key_button)

        if type(self.plugin_keys) == dict and self.import_key:
            self._rename_key_button = QtGui.QToolButton(self)
            self._rename_key_button.setToolTip(_(u"Rename highlighted key"))
            self._rename_key_button.setIcon(QIcon(I('edit-select-all.png')))
            self._rename_key_button.clicked.connect(self.rename_key)
            button_layout.addWidget(self._rename_key_button)

            self.export_key_button = QtGui.QToolButton(self)
            self.export_key_button.setToolTip(u"Save highlighted key to a .{0} file".format(self.keyfile_ext))
            self.export_key_button.setIcon(QIcon(I('save.png')))
            self.export_key_button.clicked.connect(self.export_key)
            button_layout.addWidget(self.export_key_button)
        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        button_layout.addItem(spacerItem)

        if self.wineprefix is not None:
            layout.addSpacing(5)
            wineprefix_layout = QHBoxLayout()
            layout.addLayout(wineprefix_layout)
            wineprefix_layout.setAlignment(Qt.AlignCenter)
            self.wp_label = QLabel(u"WINEPREFIX:")
            wineprefix_layout.addWidget(self.wp_label)
            self.wp_lineedit = QLineEdit(self)
            wineprefix_layout.addWidget(self.wp_lineedit)
            self.wp_label.setBuddy(self.wp_lineedit)
            self.wp_lineedit.setText(self.wineprefix)

        layout.addSpacing(5)
        migrate_layout = QHBoxLayout()
        layout.addLayout(migrate_layout)
        if self.import_key:
            migrate_layout.setAlignment(Qt.AlignJustify)
            self.migrate_btn = QPushButton(u"Import Existing Keyfiles", self)
            self.migrate_btn.setToolTip(u"Import *.{0} files (created using other tools).".format(self.keyfile_ext))
            self.migrate_btn.clicked.connect(self.migrate_wrapper)
            migrate_layout.addWidget(self.migrate_btn)
        migrate_layout.addStretch()
        self.button_box = QDialogButtonBox(QDialogButtonBox.Close)
        self.button_box.rejected.connect(self.close)
        migrate_layout.addWidget(self.button_box)

        self.resize(self.sizeHint())

    def getwineprefix(self):
        if self.wineprefix is not None:
            return unicode(self.wp_lineedit.text().toUtf8(), 'utf8').strip()
        return u""

    def populate_list(self):
        if type(self.plugin_keys) == dict:
            for key in self.plugin_keys.keys():
                self.listy.addItem(QListWidgetItem(key))
        else:
            for key in self.plugin_keys:
                self.listy.addItem(QListWidgetItem(key))

    def add_key(self):
        d = self.create_key(self)
        d.exec_()

        if d.result() != d.Accepted:
            # New key generation cancelled.
            return
        new_key_value = d.key_value
        if type(self.plugin_keys) == dict:
            if new_key_value in self.plugin_keys.values():
                old_key_name = [name for name, value in self.plugin_keys.iteritems() if value == new_key_value][0]
                info_dialog(None, "{0} {1}: Duplicate {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name),
                                    u"The new {1} is the same as the existing {1} named <strong>{0}</strong> and has not been added.".format(old_key_name,self.key_type_name), show=True)
                return
            self.plugin_keys[d.key_name] = new_key_value
        else:
            if new_key_value in self.plugin_keys:
                info_dialog(None, "{0} {1}: Duplicate {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name),
                                    u"This {0} is already in the list of {0}s has not been added.".format(self.key_type_name), show=True)
                return

            self.plugin_keys.append(d.key_value)
        self.listy.clear()
        self.populate_list()

    def rename_key(self):
        if not self.listy.currentItem():
            errmsg = u"No {0} selected to rename. Highlight a keyfile first.".format(self.key_type_name)
            r = error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
                                    _(errmsg), show=True, show_copy_button=False)
            return

        d = RenameKeyDialog(self)
        d.exec_()

        if d.result() != d.Accepted:
            # rename cancelled or moot.
            return
        keyname = unicode(self.listy.currentItem().text().toUtf8(),'utf8')
        if not question_dialog(self, "{0} {1}: Confirm Rename".format(PLUGIN_NAME, PLUGIN_VERSION), u"Do you really want to rename the {2} named <strong>{0}</strong> to <strong>{1}</strong>?".format(keyname,d.key_name,self.key_type_name), show_copy_button=False, default_yes=False):
            return
        self.plugin_keys[d.key_name] = self.plugin_keys[keyname]
        del self.plugin_keys[keyname]

        self.listy.clear()
        self.populate_list()

    def delete_key(self):
        if not self.listy.currentItem():
            return
        keyname = unicode(self.listy.currentItem().text().toUtf8(), 'utf8')
        if not question_dialog(self, "{0} {1}: Confirm Delete".format(PLUGIN_NAME, PLUGIN_VERSION), u"Do you really want to delete the {1} <strong>{0}</strong>?".format(keyname, self.key_type_name), show_copy_button=False, default_yes=False):
            return
        if type(self.plugin_keys) == dict:
            del self.plugin_keys[keyname]
        else:
            self.plugin_keys.remove(keyname)

        self.listy.clear()
        self.populate_list()

    def help_link_activated(self, url):
        def get_help_file_resource():
            # Copy the HTML helpfile to the plugin directory each time the
            # link is clicked in case the helpfile is updated in newer plugins.
            help_file_name = u"{0}_{1}_Help.htm".format(PLUGIN_NAME, self.key_type_name)
            file_path = os.path.join(config_dir, u"plugins", u"DeDRM", u"help", help_file_name)
            with open(file_path,'w') as f:
                f.write(self.parent.load_resource(help_file_name))
            return file_path
        url = 'file:///' + get_help_file_resource()
        open_url(QUrl(url))

    def migrate_files(self):
        dynamic[PLUGIN_NAME + u"config_dir"] = config_dir
        files = choose_files(self, PLUGIN_NAME + u"config_dir",
                u"Select {0} files to import".format(self.key_type_name), [(u"{0} files".format(self.key_type_name), [self.keyfile_ext])], False)
        counter = 0
        skipped = 0
        if files:
            for filename in files:
                fpath = os.path.join(config_dir, filename)
                filename = os.path.basename(filename)
                new_key_name = os.path.splitext(os.path.basename(filename))[0]
                with open(fpath,'rb') as keyfile:
                    new_key_value = keyfile.read()
                if self.binary_file:
                    new_key_value = new_key_value.encode('hex')
                elif self.json_file:
                    new_key_value = json.loads(new_key_value)
                match = False
                for key in self.plugin_keys.keys():
                    if uStrCmp(new_key_name, key, True):
                        skipped += 1
                        msg = u"A key with the name <strong>{0}</strong> already exists!\nSkipping key file  <strong>{1}</strong>.\nRename the existing key and import again".format(new_key_name,filename)
                        inf = info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
                                _(msg), show_copy_button=False, show=True)
                        match = True
                        break
                if not match:
                    if new_key_value in self.plugin_keys.values():
                        old_key_name = [name for name, value in self.plugin_keys.iteritems() if value == new_key_value][0]
                        skipped += 1
                        info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
                                            u"The key in file {0} is the same as the existing key <strong>{1}</strong> and has been skipped.".format(filename,old_key_name), show_copy_button=False, show=True)
                    else:
                        counter += 1
                        self.plugin_keys[new_key_name] = new_key_value

            msg = u""
            if counter+skipped > 1:
                if counter > 0:
                    msg += u"Imported <strong>{0:d}</strong> key {1}. ".format(counter, u"file" if counter == 1 else u"files")
                if skipped > 0:
                    msg += u"Skipped <strong>{0:d}</strong> key {1}.".format(skipped, u"file" if counter == 1 else u"files")
                inf = info_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
                                    _(msg), show_copy_button=False, show=True)
        return counter > 0

    def migrate_wrapper(self):
        if self.migrate_files():
            self.listy.clear()
            self.populate_list()

    def export_key(self):
        if not self.listy.currentItem():
            errmsg = u"No keyfile selected to export. Highlight a keyfile first."
            r = error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION),
                                    _(errmsg), show=True, show_copy_button=False)
            return
        filter = QString(u"{0} Files (*.{1})".format(self.key_type_name, self.keyfile_ext))
        keyname = unicode(self.listy.currentItem().text().toUtf8(), 'utf8')
        if dynamic.get(PLUGIN_NAME + 'save_dir'):
            defaultname = os.path.join(dynamic.get(PLUGIN_NAME + 'save_dir'), u"{0}.{1}".format(keyname , self.keyfile_ext))
        else:
            defaultname = os.path.join(os.path.expanduser('~'), u"{0}.{1}".format(keyname , self.keyfile_ext))
        filename = unicode(QtGui.QFileDialog.getSaveFileName(self, u"Save {0} File as...".format(self.key_type_name), defaultname,
                                            u"{0} Files (*.{1})".format(self.key_type_name,self.keyfile_ext), filter))
        if filename:
            dynamic[PLUGIN_NAME + 'save_dir'] = os.path.split(filename)[0]
            with file(filename, 'w') as fname:
                if self.binary_file:
                    fname.write(self.plugin_keys[keyname].decode('hex'))
                elif self.json_file:
                    fname.write(json.dumps(self.plugin_keys[keyname]))
                else:
                    fname.write(self.plugin_keys[keyname])
Пример #45
0
    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.db = db

        self.setWindowTitle(_('Check Library -- Problems Found'))
        self.setWindowIcon(QIcon(I('debug.png')))

        self._tl = QHBoxLayout()
        self.setLayout(self._tl)
        self.splitter = QSplitter(self)
        self.left = QWidget(self)
        self.splitter.addWidget(self.left)
        self.helpw = QTextEdit(self)
        self.splitter.addWidget(self.helpw)
        self._tl.addWidget(self.splitter)
        self._layout = QVBoxLayout()
        self.left.setLayout(self._layout)
        self.helpw.setReadOnly(True)
        self.helpw.setText(
            _('''\
        <h1>Help</h1>

        <p>calibre stores the list of your books and their metadata in a
        database. The actual book files and covers are stored as normal
        files in the calibre library folder. The database contains a list of the files
        and covers belonging to each book entry. This tool checks that the
        actual files in the library folder on your computer match the
        information in the database.</p>

        <p>The result of each type of check is shown to the left. The various
        checks are:
        </p>
        <ul>
        <li><b>Invalid titles</b>: These are files and folders appearing
        in the library where books titles should, but that do not have the
        correct form to be a book title.</li>
        <li><b>Extra titles</b>: These are extra files in your calibre
        library that appear to be correctly-formed titles, but have no corresponding
        entries in the database</li>
        <li><b>Invalid authors</b>: These are files appearing
        in the library where only author folders should be.</li>
        <li><b>Extra authors</b>: These are folders in the
        calibre library that appear to be authors but that do not have entries
        in the database</li>
        <li><b>Missing book formats</b>: These are book formats that are in
        the database but have no corresponding format file in the book's folder.
        <li><b>Extra book formats</b>: These are book format files found in
        the book's folder but not in the database.
        <li><b>Unknown files in books</b>: These are extra files in the
        folder of each book that do not correspond to a known format or cover
        file.</li>
        <li><b>Missing cover files</b>: These represent books that are marked
        in the database as having covers but the actual cover files are
        missing.</li>
        <li><b>Cover files not in database</b>: These are books that have
        cover files but are marked as not having covers in the database.</li>
        <li><b>Folder raising exception</b>: These represent folders in the
        calibre library that could not be processed/understood by this
        tool.</li>
        </ul>

        <p>There are two kinds of automatic fixes possible: <i>Delete
        marked</i> and <i>Fix marked</i>.</p>
        <p><i>Delete marked</i> is used to remove extra files/folders/covers that
        have no entries in the database. Check the box next to the item you want
        to delete. Use with caution.</p>

        <p><i>Fix marked</i> is applicable only to covers and missing formats
        (the three lines marked 'fixable'). In the case of missing cover files,
        checking the fixable box and pushing this button will tell calibre that
        there is no cover for all of the books listed. Use this option if you
        are not going to restore the covers from a backup. In the case of extra
        cover files, checking the fixable box and pushing this button will tell
        calibre that the cover files it found are correct for all the books
        listed. Use this when you are not going to delete the file(s). In the
        case of missing formats, checking the fixable box and pushing this
        button will tell calibre that the formats are really gone. Use this if
        you are not going to restore the formats from a backup.</p>

        '''))

        self.log = QTreeWidget(self)
        self.log.itemChanged.connect(self.item_changed)
        self.log.itemExpanded.connect(self.item_expanded_or_collapsed)
        self.log.itemCollapsed.connect(self.item_expanded_or_collapsed)
        self._layout.addWidget(self.log)

        self.check_button = QPushButton(_('&Run the check again'))
        self.check_button.setDefault(False)
        self.check_button.clicked.connect(self.run_the_check)
        self.copy_button = QPushButton(_('Copy &to clipboard'))
        self.copy_button.setDefault(False)
        self.copy_button.clicked.connect(self.copy_to_clipboard)
        self.ok_button = QPushButton(_('&Done'))
        self.ok_button.setDefault(True)
        self.ok_button.clicked.connect(self.accept)
        self.delete_button = QPushButton(_('Delete &marked'))
        self.delete_button.setToolTip(
            _('Delete marked files (checked subitems)'))
        self.delete_button.setDefault(False)
        self.delete_button.clicked.connect(self.delete_marked)
        self.fix_button = QPushButton(_('&Fix marked'))
        self.fix_button.setDefault(False)
        self.fix_button.setEnabled(False)
        self.fix_button.setToolTip(
            _('Fix marked sections (checked fixable items)'))
        self.fix_button.clicked.connect(self.fix_items)
        self.bbox = QDialogButtonBox(self)
        self.bbox.addButton(self.check_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.delete_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.fix_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.copy_button, QDialogButtonBox.ActionRole)
        self.bbox.addButton(self.ok_button, QDialogButtonBox.AcceptRole)

        h = QHBoxLayout()
        ln = QLabel(_('Names to ignore:'))
        h.addWidget(ln)
        self.name_ignores = QLineEdit()
        self.name_ignores.setText(
            db.prefs.get('check_library_ignore_names', ''))
        self.name_ignores.setToolTip(
            _('Enter comma-separated standard file name wildcards, such as synctoy*.dat'
              ))
        ln.setBuddy(self.name_ignores)
        h.addWidget(self.name_ignores)
        le = QLabel(_('Extensions to ignore'))
        h.addWidget(le)
        self.ext_ignores = QLineEdit()
        self.ext_ignores.setText(
            db.prefs.get('check_library_ignore_extensions', ''))
        self.ext_ignores.setToolTip(
            _('Enter comma-separated extensions without a leading dot. Used only in book folders'
              ))
        le.setBuddy(self.ext_ignores)
        h.addWidget(self.ext_ignores)
        self._layout.addLayout(h)

        self._layout.addWidget(self.bbox)
        self.resize(950, 500)
        self.bbox.setEnabled(True)
Пример #46
0
class ValueTypeEditor(QWidget):
    ValueTypes = (bool, int, float, complex, str)

    def __init__(self, *args):
        QWidget.__init__(self, *args)
        lo = QHBoxLayout(self)
        lo.setContentsMargins(0, 0, 0, 0)
        lo.setSpacing(5)
        # type selector
        self.wtypesel = QComboBox(self)
        for i, tp in enumerate(self.ValueTypes):
            self.wtypesel.addItem(tp.__name__)
        QObject.connect(self.wtypesel, SIGNAL("activated(int)"),
                        self._selectTypeNum)
        typesel_lab = QLabel("&Type:", self)
        typesel_lab.setBuddy(self.wtypesel)
        lo.addWidget(typesel_lab, 0)
        lo.addWidget(self.wtypesel, 0)
        self.wvalue = QLineEdit(self)
        self.wvalue_lab = QLabel("&Value:", self)
        self.wvalue_lab.setBuddy(self.wvalue)
        self.wbool = QComboBox(self)
        self.wbool.addItems(["false", "true"])
        self.wbool.setCurrentIndex(1)
        lo.addWidget(self.wvalue_lab, 0)
        lo.addWidget(self.wvalue, 1)
        lo.addWidget(self.wbool, 1)
        self.wvalue.hide()
        # make input validators
        self._validators = {
            int: QIntValidator(self),
            float: QDoubleValidator(self)
        }
        # select bool type initially
        self._selectTypeNum(0)

    def _selectTypeNum(self, index):
        tp = self.ValueTypes[index]
        self.wbool.setShown(tp is bool)
        self.wvalue.setShown(tp is not bool)
        self.wvalue_lab.setBuddy(self.wbool if tp is bool else self.wvalue)
        self.wvalue.setValidator(self._validators.get(tp, None))

    def setValue(self, value):
        """Sets current value"""
        for i, tp in enumerate(self.ValueTypes):
            if isinstance(value, tp):
                self.wtypesel.setCurrentIndex(i)
                self._selectTypeNum(i)
                if tp is bool:
                    self.wbool.setCurrentIndex(1 if value else 0)
                else:
                    self.wvalue.setText(str(value))
                return
        # unknown value: set bool
        self.setValue(True)

    def getValue(self):
        """Returns current value, or None if no legal value is set"""
        tp = self.ValueTypes[self.wtypesel.currentIndex()]
        if tp is bool:
            return bool(self.wbool.currentIndex())
        else:
            try:
                return tp(self.wvalue.text())
            except:
                print("Error converting input to type ", tp.__name__)
                traceback.print_exc()
                return None