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/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 0f55c1e3de..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)
@@ -1051,24 +1051,23 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
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..0d91d317ff 100644
--- a/src/calibre/gui2/tools.py
+++ b/src/calibre/gui2/tools.py
@@ -71,109 +71,60 @@ 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):
+ return [], False, []
+ 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 = SingleConfig(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]))
+ out_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, out_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 c8d8ed79bd..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):