diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py
index a8e2239105..9b56509351 100644
--- a/src/calibre/devices/usbms/device.py
+++ b/src/calibre/devices/usbms/device.py
@@ -83,8 +83,6 @@ class Device(DeviceConfig, DevicePlugin):
'''
FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2}
FDI_BCD_TEMPLATE = ''
- FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2}
-
def reset(self, key='-1', log_packets=False, report_progress=None) :
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
diff --git a/src/calibre/ebooks/conversion/cli.py b/src/calibre/ebooks/conversion/cli.py
index 4529f060ad..73e1a1e523 100644
--- a/src/calibre/ebooks/conversion/cli.py
+++ b/src/calibre/ebooks/conversion/cli.py
@@ -211,7 +211,6 @@ def main(args=sys.argv):
OptionRecommendation.HIGH) \
for n in parser.options_iter()
if n.dest]
- print recommendations
plumber.merge_ui_recommendations(recommendations)
plumber.run()
diff --git a/src/calibre/ebooks/pdb/output.py b/src/calibre/ebooks/pdb/output.py
index 2095b64ab2..edf047442a 100644
--- a/src/calibre/ebooks/pdb/output.py
+++ b/src/calibre/ebooks/pdb/output.py
@@ -6,8 +6,9 @@ __docformat__ = 'restructuredtext en'
import os
-from calibre.customize.conversion import OutputFormatPlugin
-from calibre.ebooks.pdb import PDBError, get_writer
+from calibre.customize.conversion import OutputFormatPlugin, \
+ OptionRecommendation
+from calibre.ebooks.pdb import PDBError, get_writer, FORMAT_WRITERS
class PDBOutput(OutputFormatPlugin):
@@ -15,20 +16,25 @@ class PDBOutput(OutputFormatPlugin):
author = 'John Schember'
file_type = 'pdb'
+ options = set([
+ OptionRecommendation(name='format', recommended_value='doc',
+ level=OptionRecommendation.LOW,
+ short_switch='f', choices=FORMAT_WRITERS.keys(),
+ help=_('Format to use inside the pdb container. Choices are: '
+ '%s' % FORMAT_WRITERS.keys())),
+ ])
+
def convert(self, oeb_book, output_path, input_plugin, opts, log):
close = False
if not hasattr(output_path, 'write'):
- # Determine the format to write based upon the sub extension
- format = os.path.splitext(os.path.splitext(output_path)[0])[1][1:]
close = True
if not os.path.exists(os.path.dirname(output_path)) and os.path.dirname(output_path) != '':
os.makedirs(os.path.dirname(output_path))
out_stream = open(output_path, 'wb')
else:
- format = os.path.splitext(os.path.splitext(output_path.name)[0])[1][1:]
out_stream = output_path
- Writer = get_writer(format)
+ Writer = get_writer(opts.format)
if Writer is None:
raise PDBError('No writer avaliable for format %s.' % format)
diff --git a/src/calibre/gui2/add.py b/src/calibre/gui2/add.py
index 948cf4f3af..bd99864dbd 100644
--- a/src/calibre/gui2/add.py
+++ b/src/calibre/gui2/add.py
@@ -7,7 +7,7 @@ from PyQt4.Qt import QThread, SIGNAL, QMutex, QWaitCondition, Qt
from calibre.gui2.dialogs.progress import ProgressDialog
from calibre.constants import preferred_encoding
-from calibre.gui2.widgets import WarningDialog
+from calibre.gui2 import warning_dialog
class Add(QThread):
@@ -113,13 +113,13 @@ class AddFiles(Add):
def process_duplicates(self):
if self.duplicates:
- files = _('Books with the same title as the following already '
- 'exist in the database. Add them anyway?
')
+ files = ''
for mi in self.duplicates[2]:
- files += '- '+mi.title+'
\n'
- d = WarningDialog (_('Duplicates found!'),
- _('Duplicates found!'),
- files+'
', parent=self._parent)
+ files += mi.title+'\n'
+ d = warning_dialog(_('Duplicates found!'),
+ _('Books with the same title as the following already '
+ 'exist in the database. Add them anyway?'),
+ files, parent=self._parent)
if d.exec_() == d.Accepted:
num = self.db.add_books(*self.duplicates,
**dict(add_duplicates=True))[1]
@@ -221,19 +221,19 @@ class AddRecursive(Add):
def process_duplicates(self):
if self.duplicates:
- files = _('Books with the same title as the following already '
- 'exist in the database. Add them anyway?
')
+ files = ''
for mi in self.duplicates:
title = mi[0].title
if not isinstance(title, unicode):
title = title.decode(preferred_encoding, 'replace')
- files += '- '+title+'
\n'
- d = WarningDialog (_('Duplicates found!'),
- _('Duplicates found!'),
- files+'
', parent=self._parent)
+ files += title+'\n'
+ d = warning_dialog(_('Duplicates found!'),
+ _('Books with the same title as the following already '
+ 'exist in the database. Add them anyway?'),
+ files, parent=self._parent)
if d.exec_() == d.Accepted:
for mi, formats in self.duplicates:
self.db.import_book(mi, formats, notify=False)
self.number_of_books_added += 1
-
\ No newline at end of file
+
diff --git a/src/calibre/gui2/convert/bulk.py b/src/calibre/gui2/convert/bulk.py
new file mode 100644
index 0000000000..d6d03c9aec
--- /dev/null
+++ b/src/calibre/gui2/convert/bulk.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+
+__license__ = 'GPL 3'
+__copyright__ = '2009, John Schember '
+__docformat__ = 'restructuredtext en'
+
+import sys
+
+from PyQt4.Qt import QString, SIGNAL
+
+from calibre.gui2.convert.single import Config, sort_formats_by_preference, \
+ GroupModel
+from calibre.customize.ui import available_output_formats
+from calibre.gui2 import ResizableDialog
+from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
+from calibre.gui2.convert.page_setup import PageSetupWidget
+from calibre.gui2.convert import GuiRecommendations
+from calibre.ebooks.conversion.plumber import Plumber, OUTPUT_FORMAT_PREFERENCES
+from calibre.utils.logging import Log
+
+class BulkConfig(Config):
+
+ def __init__(self, parent, db, preferred_output_format=None):
+ ResizableDialog.__init__(self, parent)
+
+ self.setup_output_formats(db, preferred_output_format)
+ self.db = db
+
+ self.setup_pipeline()
+
+ self.input_formats.hide()
+
+ self.connect(self.output_formats, SIGNAL('currentIndexChanged(QString)'),
+ self.setup_pipeline)
+ self.connect(self.groups, SIGNAL('activated(QModelIndex)'),
+ self.show_pane)
+ self.connect(self.groups, SIGNAL('clicked(QModelIndex)'),
+ self.show_pane)
+ self.connect(self.groups, SIGNAL('entered(QModelIndex)'),
+ self.show_group_help)
+ self.groups.setMouseTracking(True)
+
+
+ def setup_pipeline(self, *args):
+ oidx = self.groups.currentIndex().row()
+ output_format = self.output_format
+
+ input_path = 'dummy.epub'
+ output_path = 'dummy.'+output_format
+ log = Log()
+ log.outputs = []
+ self.plumber = Plumber(input_path, output_path, log)
+
+ def widget_factory(cls):
+ return cls(self.stack, self.plumber.get_option_by_name,
+ self.plumber.get_option_help, self.db)
+
+ self.setWindowTitle(_('Bulk Convert'))
+ lf = widget_factory(LookAndFeelWidget)
+ ps = widget_factory(PageSetupWidget)
+
+ output_widget = None
+ name = 'calibre.gui2.convert.%s' % self.plumber.output_plugin.name.lower().replace(' ', '_')
+ try:
+ __import__(name)
+ output_widget = sys.modules[name]
+ pw = output_widget.PluginWidget
+ pw.ICON = ':/images/back.svg'
+ pw.HELP = _('Options specific to the output format.')
+ output_widget = widget_factory(pw)
+ except ImportError:
+ pass
+
+ while True:
+ c = self.stack.currentWidget()
+ if not c: break
+ self.stack.removeWidget(c)
+
+ widgets = [lf, ps]
+ if output_widget is not None:
+ widgets.append(output_widget)
+ for w in widgets:
+ self.stack.addWidget(w)
+ self.connect(w, SIGNAL('set_help(PyQt_PyObject)'),
+ self.help.setPlainText)
+
+ self._groups_model = GroupModel(widgets)
+ self.groups.setModel(self._groups_model)
+
+ idx = oidx if -1 < oidx < self._groups_model.rowCount() else 0
+ self.groups.setCurrentIndex(self._groups_model.index(idx))
+
+
+ def setup_output_formats(self, db, preferred_output_format):
+ available_formats = ''
+ available_formats = set([x.lower() for x in
+ available_formats.split(',')])
+ output_formats = sorted(available_output_formats())
+ output_formats.remove('oeb')
+ preferred_output_format = preferred_output_format if \
+ preferred_output_format in output_formats else \
+ sort_formats_by_preference(output_formats,
+ OUTPUT_FORMAT_PREFERENCES)[0]
+ self.output_formats.addItems(list(map(QString, [x.upper() for x in
+ output_formats])))
+ self.output_formats.setCurrentIndex(output_formats.index(preferred_output_format))
+
+ def accept(self):
+ recs = GuiRecommendations()
+ for w in self._groups_model.widgets:
+ x = w.commit(save_defaults=False)
+ recs.update(x)
+ self._recommendations = recs
+ ResizableDialog.accept(self)
+
+
diff --git a/src/calibre/gui2/convert/gui_conversion.py b/src/calibre/gui2/convert/gui_conversion.py
index 1d41b4ec29..8f25acb7be 100644
--- a/src/calibre/gui2/convert/gui_conversion.py
+++ b/src/calibre/gui2/convert/gui_conversion.py
@@ -4,8 +4,6 @@ __license__ = 'GPL 3'
__copyright__ = '2009, John Schember '
__docformat__ = 'restructuredtext en'
-import logging
-
from calibre.ebooks.conversion.plumber import Plumber
from calibre.utils.logging import Log
diff --git a/src/calibre/gui2/convert/pdb_output.py b/src/calibre/gui2/convert/pdb_output.py
new file mode 100644
index 0000000000..db52db8f46
--- /dev/null
+++ b/src/calibre/gui2/convert/pdb_output.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+
+__license__ = 'GPL 3'
+__copyright__ = '2009, John Schember '
+__docformat__ = 'restructuredtext en'
+
+from calibre.gui2.convert.pdb_output_ui import Ui_Form
+from calibre.gui2.convert import Widget
+from calibre.ebooks.pdb import FORMAT_WRITERS
+from calibre.gui2.widgets import BasicComboModel
+
+format_model = None
+
+class PluginWidget(Widget, Ui_Form):
+
+ TITLE = _('PDB Output')
+
+ def __init__(self, parent, get_option, get_help, db=None, book_id=None):
+ Widget.__init__(self, parent, 'pdb_output', ['format'])
+ self.db, self.book_id = db, book_id
+ self.initialize_options(get_option, get_help, db, book_id)
+
+ global format_model
+ if format_model is None:
+ format_model = BasicComboModel(FORMAT_WRITERS.keys())
+ self.format_model = format_model
+ self.opt_format.setModel(self.format_model)
+
diff --git a/src/calibre/gui2/convert/pdb_output.ui b/src/calibre/gui2/convert/pdb_output.ui
new file mode 100644
index 0000000000..5f21031233
--- /dev/null
+++ b/src/calibre/gui2/convert/pdb_output.ui
@@ -0,0 +1,44 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Form
+
+
+ -
+
+
+ Format:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 148
+ 246
+
+
+
+
+
+
+
+
+
diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py
index 1c990f7e8b..cf04e18ae6 100644
--- a/src/calibre/gui2/device.py
+++ b/src/calibre/gui2/device.py
@@ -21,18 +21,12 @@ from calibre.gui2 import config, error_dialog, Dispatcher, dynamic, \
pixmap_to_data, warning_dialog, \
info_dialog
from calibre.ebooks.metadata import authors_to_string
-from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
from calibre import sanitize_file_name, preferred_encoding
from calibre.utils.filenames import ascii_filename
from calibre.devices.errors import FreeSpaceError
from calibre.utils.smtp import compose_mail, sendmail, extract_email_address, \
config as email_config
-def warning(title, msg, details, parent):
- from calibre.gui2.widgets import WarningDialog
- WarningDialog(title, msg, details, parent).exec_()
-
-
class DeviceJob(Job):
def __init__(self, func, *args, **kwargs):
@@ -530,13 +524,13 @@ class DeviceGUI(object):
good.append(title)
if errors:
errors = '\n'.join([
- '%s
%s
%s
' %
- (title, e, tb.replace('\n', '
')) for \
+ '%s\n\n%s\n%s\n' %
+ (title, e, tb) for \
title, e, tb in errors
])
- ConversionErrorDialog(self, _('Failed to email books'),
- ''+_('Failed to email the following books:')+\
- '
'%errors,
+ error_dialog(self, _('Failed to email books'),
+ _('Failed to email the following books:'),
+ '%s'%errors,
show=True)
else:
self.status_bar.showMessage(_('Sent by email:') + ', '.join(good),
diff --git a/src/calibre/gui2/dialogs/warning.ui b/src/calibre/gui2/dialogs/warning.ui
deleted file mode 100644
index 11c2e95cad..0000000000
--- a/src/calibre/gui2/dialogs/warning.ui
+++ /dev/null
@@ -1,113 +0,0 @@
-
- Dialog
-
-
-
- 0
- 0
- 727
- 432
-
-
-
- Dialog
-
-
-
- :/images/dialog_warning.svg:/images/dialog_warning.svg
-
-
- -
-
-
- TextLabel
-
-
- true
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
- :/images/dialog_warning.svg
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
-
- -
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
-
-
-
-
-
-
-
-
-
- buttonBox
- accepted()
- Dialog
- accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
-
-
- buttonBox
- rejected()
- Dialog
- reject()
-
-
- 316
- 260
-
-
- 286
- 274
-
-
-
-
-
diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py
index 97e4c24d53..6bea660294 100644
--- a/src/calibre/gui2/main.py
+++ b/src/calibre/gui2/main.py
@@ -24,7 +24,7 @@ from calibre.gui2 import APP_UID, warning_dialog, choose_files, error_dialog, \
max_available_height, config, info_dialog, \
available_width, GetMetadata
from calibre.gui2.cover_flow import CoverFlow, DatabaseImages, pictureflowerror
-from calibre.gui2.widgets import ProgressIndicator, WarningDialog
+from calibre.gui2.widgets import ProgressIndicator
from calibre.gui2.dialogs.scheduler import Scheduler
from calibre.gui2.update import CheckForUpdates
from calibre.gui2.dialogs.progress import ProgressDialog
@@ -36,8 +36,8 @@ from calibre.gui2.jobs2 import JobManager
from calibre.gui2.dialogs.metadata_single import MetadataSingleDialog
from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog
from calibre.gui2.dialogs.jobs import JobsDialog
-from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
-from calibre.gui2.tools import convert_single_ebook, fetch_scheduled_recipe
+from calibre.gui2.tools import convert_single_ebook, convert_bulk_ebook, \
+ fetch_scheduled_recipe
from calibre.gui2.dialogs.config import ConfigDialog
from calibre.gui2.dialogs.search import SearchDialog
from calibre.gui2.dialogs.choose_format import ChooseFormatDialog
@@ -89,7 +89,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.persistent_files = []
self.metadata_dialogs = []
self.default_thumbnail = None
- self.device_error_dialog = ConversionErrorDialog(self,
+ self.device_error_dialog = error_dialog(self, _('Error'),
_('Error communicating with device'), ' ')
self.device_error_dialog.setModal(Qt.NonModal)
self.tb_wrapper = textwrap.TextWrapper(width=40)
@@ -865,16 +865,16 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
db = self.library_view.model().refresh_ids(
x.updated, cr)
if x.failures:
- details = ['%s: %s'%(title, reason) for title,
+ details = ['%s: %s'%(title, reason) for title,
reason in x.failures.values()]
- details = ''%(''.join(details))
- WarningDialog(_('Failed to download some metadata'),
+ details = '%s\n'%('\n'.join(details))
+ warning_dialog(_('Failed to download some metadata'),
_('Failed to download metadata for the following:'),
details, self).exec_()
else:
err = _('Failed to download metadata:')+\
'
'+x.tb+'
'
- ConversionErrorDialog(self, _('Error'), err,
+ error_dialog(self, _('Error'), err,
show=True)
@@ -1047,28 +1047,27 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
d = error_dialog(self, _('Cannot convert'),
_('No books selected'))
d.exec_()
- return [], []
+ return None
return [self.library_view.model().db.id(r) for r in rows]
def convert_bulk(self, checked):
- r = self.get_books_for_conversion()
- if r is None:
- return
- comics, others = r
-
- res = convert_bulk_ebooks(self,
- self.library_view.model().db, comics, others)
- if res is None:
- return
- jobs, changed = res
+ row_ids = self.get_books_for_conversion()
+ if row_ids is None: return
+ previous = self.library_view.currentIndex()
+ rows = [x.row() for x in \
+ self.library_view.selectionModel().selectedRows()]
+ jobs, changed, bad = convert_bulk_ebook(self,
+ self.library_view.model().db, row_ids)
for func, args, desc, fmt, id, temp_files in jobs:
- job = self.job_manager.run_job(Dispatcher(self.book_converted),
+ if id not in bad:
+ job = self.job_manager.run_job(Dispatcher(self.book_converted),
func, args=args, description=desc)
- self.conversion_jobs[job] = (temp_files, fmt, id)
+ self.conversion_jobs[job] = (temp_files, fmt, id)
if changed:
- self.library_view.model().resort(reset=False)
- self.library_view.model().research()
+ self.library_view.model().refresh_rows(rows)
+ current = self.library_view.currentIndex()
+ self.library_view.model().current_changed(current, previous)
def convert_single(self, checked):
row_ids = self.get_books_for_conversion()
@@ -1431,7 +1430,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
return
if isinstance(job.exception, JobKilled):
return
- ConversionErrorDialog(self, _('Conversion Error'), job.gui_text(),
+ error_dialog(self, _('Conversion Error'), job.gui_text(),
show=True)
diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py
index a8407df767..ceeee60ab5 100644
--- a/src/calibre/gui2/tools.py
+++ b/src/calibre/gui2/tools.py
@@ -16,6 +16,7 @@ from calibre.gui2 import warning_dialog
from calibre.gui2.convert import load_specifics
from calibre.gui2.convert.single import NoSupportedInputFormats
from calibre.gui2.convert.single import Config as SingleConfig
+from calibre.gui2.convert.bulk import BulkConfig
def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format=None):
changed = False
@@ -71,109 +72,59 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format
return jobs, changed, bad
-def convert_bulk_ebooks(*args):
- pass
- #(fmt, parent, db, comics, others):
- if others:
- d = get_dialog(fmt)(parent, db)
- if d.exec_() != QDialog.Accepted:
- others, user_mi = [], None
- else:
- opts = d.opts
- opts.verbose = 2
- user_mi = d.user_mi
- if comics:
- comic_opts = ComicConf.get_bulk_conversion_options(parent)
- if not comic_opts:
- comics = []
- bad_rows = []
+def convert_bulk_ebook(parent, db, book_ids):
+ changed = False
jobs = []
- total = sum(map(len, (others, comics)))
+ bad = []
+
+ total = len(book_ids)
if total == 0:
- return
- parent.status_bar.showMessage(_('Starting Bulk conversion of %d books')%total, 2000)
+ return None, None, None
+ parent.status_bar.showMessage(_('Starting conversion of %d books') % total, 2000)
- for i, row in enumerate(others+comics):
- row_id = db.id(row)
- if row in others:
- data = None
- for _fmt in EPUB_PREFERRED_SOURCE_FORMATS:
- try:
- data = db.format(row, _fmt.upper())
- if data is not None:
- break
- except:
- continue
- if data is None:
- bad_rows.append(row)
- continue
- options = opts.copy()
- mi = db.get_metadata(row)
- if user_mi is not None:
- if user_mi.series_index == 1:
- user_mi.series_index = None
- mi.smart_update(user_mi)
- db.set_metadata(db.id(row), mi)
- opf = OPFCreator(os.getcwdu(), mi)
- opf_file = PersistentTemporaryFile('.opf')
- opf.render(opf_file)
- opf_file.close()
- pt = PersistentTemporaryFile('.'+_fmt.lower())
- pt.write(data)
- pt.close()
- of = PersistentTemporaryFile('.'+fmt)
- of.close()
- cover = db.cover(row)
- cf = None
- if cover:
- cf = PersistentTemporaryFile('.jpeg')
- cf.write(cover)
- cf.close()
- options.cover = cf.name
- options.output = of.name
- options.from_opf = opf_file.name
- args = [options, pt.name]
- desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title))
- temp_files = [cf] if cf is not None else []
- temp_files.extend([opf_file, pt, of])
- jobs.append(('any2'+fmt, args, desc, fmt.upper(), row_id, temp_files))
- else:
- options = comic_opts.copy()
- mi = db.get_metadata(row)
- if mi.title:
- options.title = mi.title
- if mi.authors:
- options.author = ','.join(mi.authors)
- data = None
- for _fmt in ['cbz', 'cbr']:
- try:
- data = db.format(row, _fmt.upper())
- if data is not None:
- break
- except:
- continue
+ d = BulkConfig(parent, db)
+ if d.exec_() != QDialog.Accepted:
+ return jobs, changed, bad
- pt = PersistentTemporaryFile('.'+_fmt.lower())
- pt.write(data)
- pt.close()
- of = PersistentTemporaryFile('.'+fmt)
- of.close()
- setattr(options, 'output', of.name)
- options.verbose = 1
- args = [pt.name, options]
- desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title))
- jobs.append(('comic2'+fmt, args, desc, fmt.upper(), row_id, [pt, of]))
+ output_format = d.output_format
+ recs = cPickle.loads(d.recommendations)
- if bad_rows:
+ for i, book_id in enumerate(book_ids):
+ temp_files = []
+
+ try:
+ d = SingleConfig(parent, db, book_id, None, output_format)
+ d.accept()
+
+ mi = db.get_metadata(book_id, True)
+ in_file = db.format_abspath(book_id, d.input_format, True)
+
+ out_file = PersistentTemporaryFile('.' + output_format)
+ out_file.write(output_format)
+ out_file.close()
+
+ desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title))
+
+ args = [in_file, out_file.name, recs]
+ temp_files = [out_file]
+ jobs.append(('gui_convert', args, desc, d.output_format.upper(), book_id, temp_files))
+
+ changed = True
+ except NoSupportedInputFormats:
+ bad.append(book_id)
+
+ if bad != []:
res = []
- for row in bad_rows:
- title = db.title(row)
- res.append('%s'%title)
+ for id in bad:
+ title = db.title(id, True)
+ res.append('%s'%title)
- msg = _('Could not convert %d of %d books, because no suitable source format was found.
')%(len(res), total, '\n'.join(res))
- warning_dialog(parent, _('Could not convert some books'), msg).exec_()
+ msg = '%s' % '\n'.join(res)
+ warning_dialog(parent, _('Could not convert some books'),
+ _('Could not convert %d of %d books, because no suitable source format was found.' % (len(res), total)),
+ msg).exec_()
- return jobs, False
+ return jobs, changed, bad
def _fetch_news(data, fmt):
pt = PersistentTemporaryFile(suffix='_feeds2%s.%s'%(fmt.lower(), fmt.lower()))
diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py
index 7f3487f035..db36daa784 100644
--- a/src/calibre/gui2/widgets.py
+++ b/src/calibre/gui2/widgets.py
@@ -19,7 +19,6 @@ from calibre import fit_image
from calibre.utils.fontconfig import find_font_families
from calibre.ebooks.metadata.meta import metadata_from_filename
from calibre.utils.config import prefs
-from calibre.gui2.dialogs.warning_ui import Ui_Dialog as Ui_WarningDialog
class ProgressIndicator(QWidget):
@@ -56,16 +55,6 @@ class ProgressIndicator(QWidget):
self.movie.setPaused(True)
self.setVisible(False)
-
-class WarningDialog(QDialog, Ui_WarningDialog):
-
- def __init__(self, title, msg, details, parent=None):
- QDialog.__init__(self, parent)
- self.setupUi(self)
- self.setWindowTitle(title)
- self.msg.setText(msg)
- self.details.setText(details)
-
class FilenamePattern(QWidget, Ui_Form):
def __init__(self, parent):
@@ -305,6 +294,31 @@ class FontFamilyModel(QAbstractListModel):
def index_of(self, family):
return self.families.index(family.strip())
+class BasicComboModel(QAbstractListModel):
+
+ def __init__(self, items, *args):
+ QAbstractListModel.__init__(self, *args)
+ self.items = [i for i in items]
+ self.items.sort()
+
+ def rowCount(self, *args):
+ return len(self.items)
+
+ def data(self, index, role):
+ try:
+ item = self.items[index.row()]
+ except:
+ traceback.print_exc()
+ return NONE
+ if role == Qt.DisplayRole:
+ return QVariant(item)
+ if role == Qt.FontRole:
+ return QVariant(QFont(item))
+ return NONE
+
+ def index_of(self, item):
+ return self.items.index(item.strip())
+
class BasicListItem(QListWidgetItem):