diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py index 94cecd65b6..61393f9988 100644 --- a/src/calibre/devices/interface.py +++ b/src/calibre/devices/interface.py @@ -210,7 +210,31 @@ class DevicePlugin(Plugin): Read the file at C{path} on the device and write it to outfile. @param outfile: file object like C{sys.stdout} or the result of an C{open} call ''' - raise NotImplementedError() + raise NotImplementedError() + + @classmethod + def config_widget(cls): + ''' + Should return a QWidget. The QWidget contains the settings for the device interface + ''' + raise NotImplementedError() + + @classmethod + def save_settings(cls, settings_widget): + ''' + Should save settings to disk. Takes the widget created in config_widget + and saves all settings to disk. + ''' + raise NotImplementedError() + + @classmethod + def settings(cls): + ''' + Should return an opts object. The opts object should have one attribute + `formats` whihc is an ordered list of formats for the device. + ''' + raise NotImplementedError() + diff --git a/src/calibre/devices/prs500/cli/main.py b/src/calibre/devices/prs500/cli/main.py index 4a94bf41af..2484ff2902 100755 --- a/src/calibre/devices/prs500/cli/main.py +++ b/src/calibre/devices/prs500/cli/main.py @@ -13,7 +13,7 @@ from calibre import __version__, iswindows, __appname__ from calibre.devices.errors import PathError from calibre.utils.terminfo import TerminalController from calibre.devices.errors import ArgumentError, DeviceError, DeviceLocked -from calibre.devices import devices +from calibre.customize.ui import device_plugins from calibre.devices.scanner import DeviceScanner MINIMUM_COL_WIDTH = 12 #: Minimum width of columns in ls output @@ -203,7 +203,7 @@ def main(): _wmi = wmi.WMI() scanner = DeviceScanner(_wmi) scanner.scan() - for d in devices(): + for d in device_plugins(): if scanner.is_device_connected(d): dev = d(log_packets=options.log_packets) @@ -334,4 +334,4 @@ def main(): return 0 if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index c4bbe7839f..ca8b07cf0b 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -10,9 +10,10 @@ import os, subprocess, time, re from calibre.devices.interface import DevicePlugin as Device from calibre.devices.errors import DeviceError +from calibre.devices.usbms.deviceconfig import DeviceConfig from calibre import iswindows, islinux, isosx, __appname__ -class Device(Device): +class Device(DeviceConfig, Device): ''' This class provides logic common to all drivers for devices that export themselves as USB Mass Storage devices. If you are writing such a driver, inherit from this @@ -94,7 +95,7 @@ class Device(Device): for pid in cls.PRODUCT_ID: fdi_base_values = dict( app=__appname__, - deviceclass=cls.__name__, + deviceclass=cls.__class__.__name__, vendor_id=hex(vid), product_id=hex(pid), main_memory=cls.MAIN_MEMORY_VOLUME_LABEL, diff --git a/src/calibre/devices/usbms/deviceconfig.py b/src/calibre/devices/usbms/deviceconfig.py new file mode 100644 index 0000000000..999f2ea1b7 --- /dev/null +++ b/src/calibre/devices/usbms/deviceconfig.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +__license__ = 'GPL 3' +__copyright__ = '2009, John Schember ' +__docformat__ = 'restructuredtext en' + +from calibre.utils.config import Config, ConfigProxy + +class DeviceConfig(object): + + HELP_MESSAGE = _('Ordered list of formats the device will accept') + + @classmethod + def _config(cls): + c = Config('device_drivers_%s' % cls.__class__.__name__, _('settings for device drivers')) + c.add_opt('format_map', default=cls.FORMATS, help=cls.HELP_MESSAGE) + return c + + def _configProxy(cls): + return ConfigProxy(cls._config()) + + @classmethod + def config_widget(cls): + from calibre.gui2.device_drivers.configwidget import ConfigWidget + cw = ConfigWidget(cls.configProxy(cls._config()), cls.FORMATS) + return cw + + @classmethod + def save_settings(cls, config_widget): + cls.configProxy(cls._config())['format_map'] = config_widget.format_map() + + @classmethod + def settings(cls): + return cls._config().parse() + + def customization_help(cls, gui=False): + return cls.HELP_MESSAGE + diff --git a/src/calibre/ebooks/lrf/html/convert_from.py b/src/calibre/ebooks/lrf/html/convert_from.py index 9ec4857126..ebfdecc6f4 100644 --- a/src/calibre/ebooks/lrf/html/convert_from.py +++ b/src/calibre/ebooks/lrf/html/convert_from.py @@ -33,7 +33,7 @@ from calibre.ebooks.lrf.html.table import Table from calibre import filename_to_utf8, setup_cli_handlers, __appname__, \ fit_image, preferred_encoding from calibre.ptempfile import PersistentTemporaryFile -from calibre.devices.interface import Device +from calibre.devices.interface import DevicePlugin as Device from calibre.ebooks.lrf.html.color_map import lrs_color from calibre.ebooks.chardet import xml_to_unicode diff --git a/src/calibre/gui2/device_drivers/configwidget.py b/src/calibre/gui2/device_drivers/configwidget.py new file mode 100644 index 0000000000..6c144d16c4 --- /dev/null +++ b/src/calibre/gui2/device_drivers/configwidget.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +__license__ = 'GPL 3' +__copyright__ = '2009, John Schember ' +__docformat__ = 'restructuredtext en' + +from PyQt4.Qt import QWidget, QListWidgetItem, Qt, QVariant, SIGNAL + +from calibre.gui2.device_drivers.configwidget_ui import Ui_ConfigWidget + +class ConfigWidget(QWidget, Ui_ConfigWidget): + + def __init__(self, config, all_formats): + QWidget.__init__(self) + Ui_ConfigWidget.__init__(self) + self.setupUi(self) + + self.config = config + + format_map = config['format_map'] + disabled_formats = list(set(all_formats).difference(format_map)) + for format in format_map + 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.connect(self.column_up, SIGNAL('clicked()'), self.up_column) + self.connect(self.column_down, SIGNAL('clicked()'), self.down_column) + + def up_column(self): + idx = self.columns.currentRow() + if idx > 0: + self.columns.insertItem(idx-1, self.columns.takeItem(idx)) + self.columns.setCurrentRow(idx-1) + + def down_column(self): + idx = self.columns.currentRow() + if idx < self.columns.count()-1: + self.columns.insertItem(idx+1, self.columns.takeItem(idx)) + self.columns.setCurrentRow(idx+1) + + def format_map(self): + formats = [unicode(self.columns.item(i).data(Qt.UserRole).toString()) for i in range(self.columns.count()) if self.columns.item(i).checkState()==Qt.Checked] + return formats + diff --git a/src/calibre/gui2/device_drivers/configwidget.ui b/src/calibre/gui2/device_drivers/configwidget.ui new file mode 100644 index 0000000000..2f0359189e --- /dev/null +++ b/src/calibre/gui2/device_drivers/configwidget.ui @@ -0,0 +1,85 @@ + + + ConfigWidget + + + + 0 + 0 + 442 + 332 + + + + Form + + + + + + Select avaliable formats and their order for this device + + + + + + + + true + + + QAbstractItemView::SelectRows + + + + + + + + + ... + + + + :/images/arrow-up.svg:/images/arrow-up.svg + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + ... + + + + :/images/arrow-down.svg:/images/arrow-down.svg + + + + + + + + + + + + + + + + + diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 1d641de51c..da98f4de42 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -5,9 +5,9 @@ import sys, os, shutil from subprocess import check_call, call from calibre import __version__, __appname__ -from calibre.devices import devices +from calibre.customize.ui import device_plugins -DEVICES = devices() +DEVICES = device_plugins() DESTDIR = '' if os.environ.has_key('DESTDIR'): @@ -293,7 +293,7 @@ def setup_udev_rules(group_file, reload, fatal_errors): -'''%dict(cls=cls.__name__, vendor_id=cls.VENDOR_ID, product_id=cls.PRODUCT_ID, +'''%dict(cls=cls.__class__.__name__, vendor_id=cls.VENDOR_ID, product_id=cls.PRODUCT_ID, prog=__appname__, bcd=cls.BCD)) fdi.write('\n'+cls.get_fdi()) fdi.write('\n\n')