diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 180433532d..0004d80b6e 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -2,7 +2,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __appname__ = 'calibre' -__version__ = '0.4.128' +__version__ = '0.4.129' __author__ = "Kovid Goyal " ''' Various run time constants. diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index fa8f6845cc..bbda8f95d2 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -146,36 +146,7 @@ class PRS505(Device): self._card_prefix = re.search(card_pat, mount).group(2) + os.sep - def open_windows_nowmi(self): - from calibre import plugins - winutil = plugins['winutil'][0] - volumes = winutil.get_mounted_volumes_for_usb_device(self.VENDOR_ID, self.PRODUCT_ID) - main = None - for device_id in volumes.keys(): - if 'PRS-505/UC&' in device_id: - main = volumes[device_id]+':\\' - if not main: - raise DeviceError(_('Unable to detect the %s disk drive. Try rebooting.')%self.__class__.__name__) - self._main_prefix = main - card = self._card_prefix = None - win32api = __import__('win32api') - for device_id in volumes.keys(): - if 'PRS-505/UC:' in device_id: - card = volumes[device_id]+':\\' - try: - win32api.GetVolumeInformation(card) - self._card_prefix = card - break - except: - continue - - def open_windows(self): - try: - self.open_windows_nowmi() - return - except: - pass drives = [] wmi = __import__('wmi', globals(), locals(), [], -1) c = wmi.WMI() diff --git a/src/calibre/ebooks/epub/from_feeds.py b/src/calibre/ebooks/epub/from_feeds.py index bbadbc54de..fd1759712d 100644 --- a/src/calibre/ebooks/epub/from_feeds.py +++ b/src/calibre/ebooks/epub/from_feeds.py @@ -40,6 +40,7 @@ def convert(opts, recipe_arg, notification=None): c.smart_update(recipe_opts, opts) opts = recipe_opts opts.chapter_mark = 'none' + opts.dont_split_on_page_breaks = True opf = glob.glob(os.path.join(tdir, '*.opf')) if not opf: raise Exception('Downloading of recipe: %s failed'%recipe_arg) diff --git a/src/calibre/ebooks/epub/from_html.py b/src/calibre/ebooks/epub/from_html.py index 413bea4801..179c0af22b 100644 --- a/src/calibre/ebooks/epub/from_html.py +++ b/src/calibre/ebooks/epub/from_html.py @@ -128,6 +128,8 @@ class HTMLProcessor(Processor, Rationalizer): if hasattr(self.body, 'xpath'): for script in list(self.body.xpath('descendant::script')): script.getparent().remove(script) + + self.fix_markup() def convert_image(self, img): rpath = img.get('src', '') @@ -145,6 +147,17 @@ class HTMLProcessor(Processor, Rationalizer): if val == rpath: self.resource_map[key] = rpath+'_calibre_converted.jpg' img.set('src', rpath+'_calibre_converted.jpg') + + def fix_markup(self): + ''' + Perform various markup transforms to get the output to render correctly + in the quirky ADE. + ''' + # Replace
that are children of with

 

+ if hasattr(self.body, 'xpath'): + for br in self.body.xpath('./br'): + br.tag = 'p' + br.text = u'\u00a0' def save(self): for meta in list(self.root.xpath('//meta')): diff --git a/src/calibre/ebooks/lrf/comic/convert_from.py b/src/calibre/ebooks/lrf/comic/convert_from.py index 0569bf3733..c22f1745ae 100755 --- a/src/calibre/ebooks/lrf/comic/convert_from.py +++ b/src/calibre/ebooks/lrf/comic/convert_from.py @@ -10,11 +10,6 @@ Based on ideas from comiclrf created by FangornUK. import os, sys, shutil, traceback, textwrap from uuid import uuid4 -try: - from reportlab.pdfgen import canvas - _reportlab = True -except: - _reportlab = False @@ -396,10 +391,9 @@ def create_lrf(pages, profile, opts, thumbnail=None): def create_pdf(pages, profile, opts, thumbnail=None): width, height = PROFILES[profile] - - if not _reportlab: - raise RuntimeError('Failed to load reportlab') - + + from reportlab.pdfgen import canvas + pdf = canvas.Canvas(filename=opts.output, pagesize=(width,height+15)) pdf.setAuthor(opts.author) pdf.setTitle(opts.title) diff --git a/src/calibre/gui2/dialogs/progress.py b/src/calibre/gui2/dialogs/progress.py new file mode 100644 index 0000000000..2543cefb4d --- /dev/null +++ b/src/calibre/gui2/dialogs/progress.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2009, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +'''''' + +from PyQt4.Qt import QDialog, SIGNAL, Qt + +from calibre.gui2.dialogs.progress_ui import Ui_Dialog + +class ProgressDialog(QDialog, Ui_Dialog): + + def __init__(self, title, msg='', min=0, max=99, parent=None): + QDialog.__init__(self, parent) + self.setupUi(self) + self.setWindowTitle(title) + self.title.setText(title) + self.message.setText(msg) + self.setWindowModality(Qt.ApplicationModal) + self.set_min(min) + self.set_max(max) + self.canceled = False + + self.connect(self.button_box, SIGNAL('rejected()'), self._canceled) + + def set_msg(self, msg=''): + self.message.setText(msg) + + def set_value(self, val): + self.bar.setValue(val) + + def set_min(self, min): + self.bar.setMinimum(min) + + def set_max(self, max): + self.bar.setMaximum(max) + + def _canceled(self, *args): + self.canceled = True + self.button_box.setDisabled(True) + self.title.setText(_('Aborting...')) + + def keyPressEvent(self, ev): + if ev.key() == Qt.Key_Escape: + self._canceled() + else: + QDialog.keyPressEvent(self, ev) \ No newline at end of file diff --git a/src/calibre/gui2/dialogs/progress.ui b/src/calibre/gui2/dialogs/progress.ui new file mode 100644 index 0000000000..60488be62d --- /dev/null +++ b/src/calibre/gui2/dialogs/progress.ui @@ -0,0 +1,72 @@ + + Dialog + + + + 0 + 0 + 712 + 308 + + + + Dialog + + + + :/images/jobs.svg:/images/jobs.svg + + + + + + + 75 + true + + + + TextLabel + + + Qt::AlignCenter + + + true + + + + + + + 0 + + + + + + + TextLabel + + + Qt::AlignCenter + + + true + + + + + + + QDialogButtonBox::Abort + + + + + + + + + + diff --git a/src/calibre/gui2/images/news/ambito.png b/src/calibre/gui2/images/news/ambito.png new file mode 100644 index 0000000000..e0a6f409cf Binary files /dev/null and b/src/calibre/gui2/images/news/ambito.png differ diff --git a/src/calibre/gui2/images/news/elargentino.png b/src/calibre/gui2/images/news/elargentino.png new file mode 100644 index 0000000000..1e3e64d8a5 Binary files /dev/null and b/src/calibre/gui2/images/news/elargentino.png differ diff --git a/src/calibre/gui2/images/news/ftd.png b/src/calibre/gui2/images/news/ftd.png new file mode 100644 index 0000000000..a37c7a22f4 Binary files /dev/null and b/src/calibre/gui2/images/news/ftd.png differ diff --git a/src/calibre/gui2/images/news/heise.png b/src/calibre/gui2/images/news/heise.png new file mode 100644 index 0000000000..1f83f6cc65 Binary files /dev/null and b/src/calibre/gui2/images/news/heise.png differ diff --git a/src/calibre/gui2/images/news/security_watch.png b/src/calibre/gui2/images/news/security_watch.png new file mode 100644 index 0000000000..1c048d6577 Binary files /dev/null and b/src/calibre/gui2/images/news/security_watch.png differ diff --git a/src/calibre/gui2/images/news/sueddeutsche.png b/src/calibre/gui2/images/news/sueddeutsche.png new file mode 100644 index 0000000000..b7a5de767b Binary files /dev/null and b/src/calibre/gui2/images/news/sueddeutsche.png differ diff --git a/src/calibre/gui2/images/news/zdnet.png b/src/calibre/gui2/images/news/zdnet.png new file mode 100644 index 0000000000..9e2605dc52 Binary files /dev/null and b/src/calibre/gui2/images/news/zdnet.png differ diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py index 792d011883..8a737fd608 100644 --- a/src/calibre/gui2/library.py +++ b/src/calibre/gui2/library.py @@ -198,13 +198,18 @@ class BooksModel(QAbstractTableModel): ''' Return list indices of all cells in index.row()''' return [ self.index(index.row(), c) for c in range(self.columnCount(None))] - def save_to_disk(self, rows, path, single_dir=False, single_format=None): + def save_to_disk(self, rows, path, single_dir=False, single_format=None, + callback=None): rows = [row.row() for row in rows] if single_format is None: - return self.db.export_to_dir(path, rows, self.sorted_on[0] == 'authors', - single_dir=single_dir) + return self.db.export_to_dir(path, rows, + self.sorted_on[0] == 'authors', + single_dir=single_dir, + callback=callback) else: - return self.db.export_single_format_to_dir(path, rows, single_format) + return self.db.export_single_format_to_dir(path, rows, + single_format, + callback=callback) def delete_books(self, indices): diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 6ff5df412d..5753a7c974 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -28,6 +28,7 @@ from calibre.gui2.cover_flow import CoverFlow, DatabaseImages, pictureflowerror from calibre.library.database import LibraryDatabase from calibre.gui2.dialogs.scheduler import Scheduler from calibre.gui2.update import CheckForUpdates +from calibre.gui2.dialogs.progress import ProgressDialog from calibre.gui2.main_window import MainWindow, option_parser as _option_parser from calibre.gui2.main_ui import Ui_MainWindow from calibre.gui2.device import DeviceManager @@ -308,18 +309,7 @@ class Main(MainWindow, Ui_MainWindow): self.library_path = dir db = LibraryDatabase2(self.library_path) self.library_view.set_database(db) - if self.olddb is not None: - pd = QProgressDialog('', '', 0, 100, self) - pd.setWindowModality(Qt.ApplicationModal) - pd.setCancelButton(None) - pd.setWindowTitle(_('Migrating database')) - pd.show() - number_of_books = db.migrate_old(self.olddb, pd) - self.olddb.close() - if number_of_books == 0: - os.remove(self.olddb.dbpath) - self.olddb = None - prefs['library_path'] = self.library_path + prefs['library_path'] = self.library_path self.library_view.sortByColumn(*dynamic.get('sort_column', ('timestamp', Qt.DescendingOrder))) if not self.library_view.restore_column_widths(): self.library_view.resizeColumnsToContents() @@ -339,6 +329,8 @@ class Main(MainWindow, Ui_MainWindow): self.connect(self.search, SIGNAL('search(PyQt_PyObject, PyQt_PyObject)'), self.tags_view.model().reinit) self.connect(self.library_view.model(), SIGNAL('count_changed(int)'), self.location_view.count_changed) + self.connect(self.library_view.model(), SIGNAL('count_changed(int)'), + self.tags_view.recount) self.library_view.model().count_changed() ########################### Cover Flow ################################ self.cover_flow = None @@ -598,29 +590,26 @@ class Main(MainWindow, Ui_MainWindow): root = choose_dir(self, 'recursive book import root dir dialog', 'Select root folder') if not root: return - progress = QProgressDialog('', '&'+_('Stop'), - 0, 0, self) - progress.setWindowModality(Qt.ApplicationModal) - progress.setWindowTitle(_('Adding books recursively...')) + progress = ProgressDialog(_('Adding books recursively...'), + min=0, max=0, parent=self) progress.show() def callback(msg): if msg != '.': - progress.setLabelText((_('Added ')+msg) if msg else _('Searching...')) - stop = progress.wasCanceled() + progress.set_msg((_('Added ')+msg) if msg else _('Searching...')) QApplication.processEvents() QApplication.sendPostedEvents() QApplication.flush() - return stop + return progress.canceled try: duplicates = self.library_view.model().db.recursive_import(root, single, callback=callback) finally: - progress.hide() - progress.close() + progress.hide() if duplicates: files = _('

Books with the same title as the following already exist in the database. Add them anyway?

', self) + d = WarningDialog(_('Duplicates found!'), _('Duplicates found!'), + files+'

', self) if d.exec_() == QDialog.Accepted: for mi, formats in duplicates: self.library_view.model().db.import_book(mi, formats ) @@ -686,15 +675,13 @@ class Main(MainWindow, Ui_MainWindow): return # Get format and metadata information formats, metadata, names, infos = [], [], [], [] - progress = QProgressDialog(_('Reading metadata...'), _('Stop'), 0, len(paths), self) - progress.setWindowTitle(_('Adding books...')) - progress.setWindowModality(Qt.ApplicationModal) - progress.setLabelText(_('Reading metadata...')) + progress = ProgressDialog(_('Adding books...'), _('Reading metadata...'), + min=0, max=len(paths), parent=self) progress.show() try: for c, book in enumerate(paths): - progress.setValue(c) - if progress.wasCanceled(): + progress.set_value(c) + if progress.canceled: return format = os.path.splitext(book)[1] format = format[1:] if format else None @@ -713,15 +700,14 @@ class Main(MainWindow, Ui_MainWindow): infos.append({'title':mi.title, 'authors':', '.join(mi.authors), 'cover':self.default_thumbnail, 'tags':[]}) title = mi.title if isinstance(mi.title, unicode) else mi.title.decode(preferred_encoding, 'replace') - progress.setLabelText(_('Read metadata from ')+title) + progress.set_msg(_('Read metadata from ')+title) if not to_device: - progress.setLabelText(_('Adding books to database...')) + progress.set_msg(_('Adding books to database...')) model = self.library_view.model() paths = list(paths) duplicates, number_added = model.add_books(paths, formats, metadata) - progress.cancel() if duplicates: files = _('

Books with the same title as the following already exist in the database. Add them anyway?