Allow the user to graphically select folders when configuring the MTP device

This commit is contained in:
Kovid Goyal 2012-09-12 21:18:16 +05:30
parent e35622a98b
commit 903af8f4e5
2 changed files with 75 additions and 14 deletions

View File

@ -18,6 +18,7 @@ from calibre.ebooks import BOOK_EXTENSIONS
from calibre.gui2 import error_dialog from calibre.gui2 import error_dialog
from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.gui2.dialogs.template_dialog import TemplateDialog
from calibre.utils.date import parse_date from calibre.utils.date import parse_date
from calibre.gui2.device_drivers.mtp_folder_browser import Browser
class FormatsConfig(QWidget): # {{{ class FormatsConfig(QWidget): # {{{
@ -117,19 +118,36 @@ class TemplateConfig(QWidget): # {{{
class SendToConfig(QWidget): # {{{ class SendToConfig(QWidget): # {{{
def __init__(self, val): def __init__(self, val, device):
QWidget.__init__(self) QWidget.__init__(self)
self.t = t = QLineEdit(self) self.t = t = QLineEdit(self)
t.setText(', '.join(val or [])) t.setText(', '.join(val or []))
t.setCursorPosition(0) t.setCursorPosition(0)
self.l = l = QVBoxLayout(self) self.l = l = QGridLayout(self)
self.setLayout(l) self.setLayout(l)
self.m = m = QLabel('<p>'+_('''A <b>list of &folders</b> on the device to self.m = m = QLabel('<p>'+_('''A <b>list of &folders</b> on the device to
which to send ebooks. The first one that exists will be used:''')) which to send ebooks. The first one that exists will be used:'''))
m.setWordWrap(True) m.setWordWrap(True)
m.setBuddy(t) m.setBuddy(t)
l.addWidget(m) l.addWidget(m, 0, 0, 1, 2)
l.addWidget(t) l.addWidget(t, 1, 0)
self.b = b = QToolButton()
l.addWidget(b, 1, 1)
b.setIcon(QIcon(I('document_open.png')))
b.clicked.connect(self.browse)
b.setToolTip(_('Browse for a folder on the device'))
self._device = weakref.ref(device)
@property
def device(self):
return self._device()
def browse(self):
b = Browser(self.device.filesystem_cache, show_files=False,
parent=self)
if b.exec_() == b.Accepted:
sid, path = b.current_item
self.t.setText('/'.join(path[1:]))
@property @property
def value(self): def value(self):
@ -183,8 +201,9 @@ class Rule(QWidget):
remove = pyqtSignal(object) remove = pyqtSignal(object)
def __init__(self, rule=None): def __init__(self, device, rule=None):
QWidget.__init__(self) QWidget.__init__(self)
self._device = weakref.ref(device)
self.l = l = QHBoxLayout() self.l = l = QHBoxLayout()
self.setLayout(l) self.setLayout(l)
@ -198,6 +217,11 @@ class Rule(QWidget):
self.folder = f = QLineEdit(self) self.folder = f = QLineEdit(self)
f.setPlaceholderText(_('Folder on the device')) f.setPlaceholderText(_('Folder on the device'))
l.addWidget(f) l.addWidget(f)
self.b = b = QToolButton()
l.addWidget(b)
b.setIcon(QIcon(I('document_open.png')))
b.clicked.connect(self.browse)
b.setToolTip(_('Browse for a folder on the device'))
self.rb = rb = QPushButton(QIcon(I('list_remove.png')), self.rb = rb = QPushButton(QIcon(I('list_remove.png')),
_('&Remove rule'), self) _('&Remove rule'), self)
l.addWidget(rb) l.addWidget(rb)
@ -217,6 +241,17 @@ class Rule(QWidget):
self.ignore = False self.ignore = False
@property
def device(self):
return self._device()
def browse(self):
b = Browser(self.device.filesystem_cache, show_files=False,
parent=self)
if b.exec_() == b.Accepted:
sid, path = b.current_item
self.folder.setText('/'.join(path[1:]))
def removed(self): def removed(self):
self.remove.emit(self) self.remove.emit(self)
@ -232,8 +267,9 @@ class Rule(QWidget):
class FormatRules(QGroupBox): class FormatRules(QGroupBox):
def __init__(self, rules): def __init__(self, device, rules):
QGroupBox.__init__(self, _('Format specific sending')) QGroupBox.__init__(self, _('Format specific sending'))
self._device = weakref.ref(device)
self.l = l = QVBoxLayout() self.l = l = QVBoxLayout()
self.setLayout(l) self.setLayout(l)
self.la = la = QLabel('<p>'+_( self.la = la = QLabel('<p>'+_(
@ -251,7 +287,7 @@ class FormatRules(QGroupBox):
l.addWidget(sa) l.addWidget(sa)
self.widgets = [] self.widgets = []
for rule in rules: for rule in rules:
r = Rule(rule) r = Rule(device, rule)
self.widgets.append(r) self.widgets.append(r)
w.l.addWidget(r) w.l.addWidget(r)
r.remove.connect(self.remove_rule) r.remove.connect(self.remove_rule)
@ -264,8 +300,12 @@ class FormatRules(QGroupBox):
b.clicked.connect(self.add_rule) b.clicked.connect(self.add_rule)
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
@property
def device(self):
return self._device()
def add_rule(self): def add_rule(self):
r = Rule() r = Rule(self.device)
self.widgets.append(r) self.widgets.append(r)
self.w.l.addWidget(r) self.w.l.addWidget(r)
r.remove.connect(self.remove_rule) r.remove.connect(self.remove_rule)
@ -319,10 +359,10 @@ 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.rules = r = FormatRules(self.device, 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'), self.device)
self.template = TemplateConfig(self.get_pref('send_template')) self.template = TemplateConfig(self.get_pref('send_template'))
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)

View File

@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
from operator import attrgetter from operator import attrgetter
from PyQt4.Qt import (QTabWidget, QTreeWidget, QTreeWidgetItem, Qt, QDialog, from PyQt4.Qt import (QTabWidget, QTreeWidget, QTreeWidgetItem, Qt, QDialog,
QDialogButtonBox, QVBoxLayout, QSize) QDialogButtonBox, QVBoxLayout, QSize, pyqtSignal)
from calibre.gui2 import file_icon_provider from calibre.gui2 import file_icon_provider
@ -47,17 +47,33 @@ class Storage(QTreeWidget):
for child in sorted(f.files, key=attrgetter('name')): for child in sorted(f.files, key=attrgetter('name')):
i = item(child, parent) i = item(child, parent)
@property
def current_item(self):
item = self.currentItem()
if item is not None:
return (self.object_id, item.data(0, Qt.UserRole).toPyObject())
return None
class Folders(QTabWidget): class Folders(QTabWidget):
selected = pyqtSignal()
def __init__(self, filesystem_cache, show_files=True): def __init__(self, filesystem_cache, show_files=True):
QTabWidget.__init__(self) QTabWidget.__init__(self)
self.fs = filesystem_cache self.fs = filesystem_cache
for storage in self.fs.entries: for storage in self.fs.entries:
w = Storage(storage, show_files) w = Storage(storage, show_files)
self.addTab(w, w.name) self.addTab(w, w.name)
w.doubleClicked.connect(self.selected)
self.setCurrentIndex(0) self.setCurrentIndex(0)
@property
def current_item(self):
w = self.currentWidget()
if w is not None:
return w.current_item
class Browser(QDialog): class Browser(QDialog):
def __init__(self, filesystem_cache, show_files=True, parent=None): def __init__(self, filesystem_cache, show_files=True, parent=None):
@ -71,6 +87,11 @@ class Browser(QDialog):
bb.accepted.connect(self.accept) bb.accepted.connect(self.accept)
bb.rejected.connect(self.reject) bb.rejected.connect(self.reject)
self.setMinimumSize(QSize(500, 500)) self.setMinimumSize(QSize(500, 500))
self.folders.selected.connect(self.accept)
@property
def current_item(self):
return self.folders.current_item
def browse(): def browse():
from calibre.gui2 import Application from calibre.gui2 import Application
@ -87,10 +108,10 @@ def browse():
raise ValueError('No MTP device found') raise ValueError('No MTP device found')
dev.open(cd, 'test') dev.open(cd, 'test')
d = Browser(dev.filesystem_cache) d = Browser(dev.filesystem_cache)
if d.exec_() == d.Accepted: d.exec_()
pass
dev.shutdown() dev.shutdown()
return d.current_item
if __name__ == '__main__': if __name__ == '__main__':
browse() print (browse())