UI for creating format routing rules for MTP devices

This commit is contained in:
Kovid Goyal 2012-09-12 14:15:54 +05:30
parent ac9ade0409
commit d26bf70d54

View File

@ -11,7 +11,8 @@ import weakref
from PyQt4.Qt import (QWidget, QListWidgetItem, Qt, QToolButton, QLabel, from PyQt4.Qt import (QWidget, QListWidgetItem, Qt, QToolButton, QLabel,
QTabWidget, QGridLayout, QListWidget, QIcon, QLineEdit, QVBoxLayout, QTabWidget, QGridLayout, QListWidget, QIcon, QLineEdit, QVBoxLayout,
QPushButton) QPushButton, QGroupBox, QScrollArea, QHBoxLayout, QComboBox,
pyqtSignal, QSizePolicy, QDialog, QDialogButtonBox)
from calibre.ebooks import BOOK_EXTENSIONS from calibre.ebooks import BOOK_EXTENSIONS
from calibre.gui2 import error_dialog from calibre.gui2 import error_dialog
@ -86,7 +87,7 @@ class TemplateConfig(QWidget): # {{{
m.setBuddy(t) m.setBuddy(t)
l.addWidget(m, 0, 0, 1, 2) l.addWidget(m, 0, 0, 1, 2)
l.addWidget(t, 1, 0, 1, 1) l.addWidget(t, 1, 0, 1, 1)
b = self.b = QPushButton(_('Template editor')) b = self.b = QPushButton(_('&Template editor'))
l.addWidget(b, 1, 1, 1, 1) l.addWidget(b, 1, 1, 1, 1)
b.clicked.connect(self.edit_template) b.clicked.connect(self.edit_template)
@ -176,6 +177,113 @@ class IgnoredDevices(QWidget): # {{{
# }}} # }}}
# Rules {{{
class Rule(QWidget):
remove = pyqtSignal(object)
def __init__(self, rule=None):
QWidget.__init__(self)
self.l = l = QHBoxLayout()
self.setLayout(l)
self.l1 = l1 = QLabel(_('Send the '))
l.addWidget(l1)
self.fmt = f = QComboBox(self)
l.addWidget(f)
self.l2 = l2 = QLabel(_(' format to the folder: '))
l.addWidget(l2)
self.folder = f = QLineEdit(self)
f.setPlaceholderText(_('Folder on the device'))
l.addWidget(f)
self.rb = rb = QPushButton(QIcon(I('list_remove.png')),
_('&Remove rule'), self)
l.addWidget(rb)
rb.clicked.connect(self.removed)
for fmt in sorted(BOOK_EXTENSIONS):
self.fmt.addItem(fmt.upper(), fmt.lower())
self.fmt.setCurrentIndex(0)
if rule is not None:
fmt, folder = rule
idx = self.fmt.findText(fmt.upper())
if idx > -1:
self.fmt.setCurrentIndex(idx)
self.folder.setText(folder)
self.ignore = False
def removed(self):
self.remove.emit(self)
@property
def rule(self):
folder = unicode(self.folder.text()).strip()
if folder:
return (
unicode(self.fmt.itemData(self.fmt.currentIndex()).toString()),
folder
)
return None
class FormatRules(QGroupBox):
def __init__(self, rules):
QGroupBox.__init__(self, _('Format specific sending'))
self.l = l = QVBoxLayout()
self.setLayout(l)
self.la = la = QLabel('<p>'+_(
'''You can create rules that control where ebooks of a specific
format are sent to on the device. These will take precedence over
the folders specified above.'''))
la.setWordWrap(True)
l.addWidget(la)
self.sa = sa = QScrollArea(self)
sa.setWidgetResizable(True)
self.w = w = QWidget(self)
w.l = QVBoxLayout()
w.setLayout(w.l)
sa.setWidget(w)
l.addWidget(sa)
self.widgets = []
for rule in rules:
r = Rule(rule)
self.widgets.append(r)
w.l.addWidget(r)
r.remove.connect(self.remove_rule)
if not self.widgets:
self.add_rule()
self.b = b = QPushButton(QIcon(I('plus.png')), _('Add a &new rule'))
l.addWidget(b)
b.clicked.connect(self.add_rule)
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
def add_rule(self):
r = Rule()
self.widgets.append(r)
self.w.l.addWidget(r)
r.remove.connect(self.remove_rule)
self.sa.verticalScrollBar().setValue(self.sa.verticalScrollBar().maximum())
def remove_rule(self, rule):
rule.setVisible(False)
rule.ignore = True
@property
def rules(self):
for w in self.widgets:
if not w.ignore:
r = w.rule
if r is not None:
yield r
# }}}
class MTPConfig(QTabWidget): class MTPConfig(QTabWidget):
def __init__(self, device, parent=None): def __init__(self, device, parent=None):
@ -185,8 +293,8 @@ class MTPConfig(QTabWidget):
cd = msg = None cd = msg = None
if device.current_friendly_name is not None: if device.current_friendly_name is not None:
if device.current_serial_num is None: if device.current_serial_num is None:
msg = '<p>' + _('The <b>%s</b> device has no serial number, ' msg = '<p>' + (_('The <b>%s</b> device has no serial number, '
'it cannot be configured'%device.current_friendly_name) 'it cannot be configured')%device.current_friendly_name)
else: else:
cd = 'device-'+device.current_serial_num cd = 'device-'+device.current_serial_num
else: else:
@ -211,6 +319,7 @@ class MTPConfig(QTabWidget):
l = self.base.l = QGridLayout(self.base) l = self.base.l = QGridLayout(self.base)
self.base.setLayout(l) self.base.setLayout(l)
self.rules = r = FormatRules(self.get_pref('rules'))
self.formats = FormatsConfig(set(BOOK_EXTENSIONS), self.formats = FormatsConfig(set(BOOK_EXTENSIONS),
self.get_pref('format_map')) self.get_pref('format_map'))
self.send_to = SendToConfig(self.get_pref('send_to')) self.send_to = SendToConfig(self.get_pref('send_to'))
@ -218,17 +327,20 @@ class MTPConfig(QTabWidget):
self.base.la = la = QLabel(_( self.base.la = la = QLabel(_(
'Choose the formats to send to the %s')%self.device.current_friendly_name) 'Choose the formats to send to the %s')%self.device.current_friendly_name)
la.setWordWrap(True) la.setWordWrap(True)
l.addWidget(la, 0, 0, 1, 1) self.base.b = b = QPushButton(QIcon(I('list_remove.png')),
l.addWidget(self.formats, 1, 0, 2, 1) _('&Ignore the %s in calibre')%device.current_friendly_name,
l.addWidget(self.send_to, 1, 1, 1, 1)
l.addWidget(self.template, 2, 1, 1, 1)
l.setRowStretch(2, 10)
self.base.b = b = QPushButton(QIcon(I('minus.png')),
_('Ignore the %s in calibre')%device.current_friendly_name,
self.base) self.base)
l.addWidget(b, 3, 0, 1, 2)
b.clicked.connect(self.ignore_device) b.clicked.connect(self.ignore_device)
l.addWidget(b, 0, 0, 1, 2)
l.addWidget(la, 1, 0, 1, 1)
l.addWidget(self.formats, 2, 0, 3, 1)
l.addWidget(self.send_to, 2, 1, 1, 1)
l.addWidget(self.template, 3, 1, 1, 1)
l.setRowStretch(4, 10)
l.addWidget(r, 5, 0, 1, 2)
l.setRowStretch(5, 100)
self.igntab = IgnoredDevices(self.device.prefs['history'], self.igntab = IgnoredDevices(self.device.prefs['history'],
self.device.prefs['blacklist']) self.device.prefs['blacklist'])
self.addTab(self.igntab, _('Ignored devices')) self.addTab(self.igntab, _('Ignored devices'))
@ -280,6 +392,11 @@ class MTPConfig(QTabWidget):
if s and s != self.device.prefs['send_to']: if s and s != self.device.prefs['send_to']:
p['send_to'] = s p['send_to'] = s
p.pop('rules', None)
r = list(self.rules.rules)
if r and r != self.device.prefs['rules']:
p['rules'] = r
self.device.prefs[self.current_device_key] = p self.device.prefs[self.current_device_key] = p
self.device.prefs['blacklist'] = self.igntab.blacklist self.device.prefs['blacklist'] = self.igntab.blacklist
@ -296,8 +413,16 @@ if __name__ == '__main__':
cd = dev.detect_managed_devices(s.devices) cd = dev.detect_managed_devices(s.devices)
dev.open(cd, 'test') dev.open(cd, 'test')
cw = dev.config_widget() cw = dev.config_widget()
cw.show() d = QDialog()
app.exec_() d.l = QVBoxLayout()
d.setLayout(d.l)
d.l.addWidget(cw)
bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
d.l.addWidget(bb)
bb.accepted.connect(d.accept)
bb.rejected.connect(d.reject)
if d.exec_() == d.Accepted:
cw.commit()
dev.shutdown() dev.shutdown()