From aeb5cb189ef2a9a7c044e70db202c7d3b3e5e58e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 25 Aug 2009 17:04:33 -0600 Subject: [PATCH] Fix #3280 (Frequent crashes) --- src/calibre/gui2/add.py | 58 ++++++++++++++++++++++++++++++-------- src/calibre/gui2/main.py | 8 ++++++ src/calibre/manual/faq.rst | 6 ++-- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/calibre/gui2/add.py b/src/calibre/gui2/add.py index 56ed9b661a..93bebf593f 100644 --- a/src/calibre/gui2/add.py +++ b/src/calibre/gui2/add.py @@ -5,7 +5,8 @@ import os, shutil, time from Queue import Queue, Empty from threading import Thread -from PyQt4.Qt import QThread, SIGNAL, QObject, QTimer, Qt +from PyQt4.Qt import QThread, SIGNAL, QObject, QTimer, Qt, \ + QProgressDialog from calibre.gui2.dialogs.progress import ProgressDialog from calibre.gui2 import question_dialog, error_dialog @@ -13,6 +14,25 @@ from calibre.ebooks.metadata.opf2 import OPF from calibre.ebooks.metadata import MetaInformation from calibre.constants import preferred_encoding +class DuplicatesAdder(QThread): + + def __init__(self, parent, db, duplicates, db_adder): + QThread.__init__(self, parent) + self.db, self.db_adder = db, db_adder + self.duplicates = duplicates + + def run(self): + count = 1 + for mi, cover, formats in self.duplicates: + id = self.db.create_book_entry(mi, cover=cover, + add_duplicates=True) + self.db_adder.add_formats(id, formats) + self.db_adder.number_of_books_added += 1 + self.emit(SIGNAL('added(PyQt_PyObject)'), count) + count += 1 + self.emit(SIGNAL('adding_done()')) + + class RecursiveFind(QThread): def __init__(self, parent, db, root, single): @@ -196,15 +216,19 @@ class Adder(QObject): self.callback(self.paths, self.names, self.infos) self.callback_called = True + def duplicates_processed(self): + self.db_adder.end = True + if not self.callback_called: + self.callback(self.paths, self.names, self.infos) + self.callback_called = True + if hasattr(self, '__p_d'): + self.__p_d.hide() + def update(self): if self.entry_count <= 0: self.timer.stop() - self.process_duplicates() self.pd.hide() - self.db_adder.end = True - if not self.callback_called: - self.callback(self.paths, self.names, self.infos) - self.callback_called = True + self.process_duplicates() return try: @@ -240,18 +264,28 @@ class Adder(QObject): def process_duplicates(self): duplicates = self.db_adder.duplicates if not duplicates: - return + return self.duplicates_processed() self.pd.hide() files = [x[0].title for x in duplicates] if question_dialog(self._parent, _('Duplicates found!'), _('Books with the same title as the following already ' 'exist in the database. Add them anyway?'), '\n'.join(files)): - for mi, cover, formats in duplicates: - id = self.db.create_book_entry(mi, cover=cover, - add_duplicates=True) - self.db_adder.add_formats(id, formats) - self.db_adder.number_of_books_added += 1 + pd = QProgressDialog(_('Adding duplicates...'), '', 0, len(duplicates), + self._parent) + pd.setCancelButton(None) + pd.setValue(0) + pd.show() + self.__p_d = pd + self.__d_a = DuplicatesAdder(self._parent, self.db, duplicates, + self.db_adder) + self.connect(self.__d_a, SIGNAL('added(PyQt_PyObject)'), + pd.setValue) + self.connect(self.__d_a, SIGNAL('adding_done()'), + self.duplicates_processed) + self.__d_a.start() + else: + return self.duplicates_processed() def cleanup(self): if hasattr(self, 'pd'): diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 154b6e859a..8d2abd77d7 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -1576,6 +1576,12 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.device_error_dialog.show() def job_exception(self, job): + if not hasattr(self, '_modeless_dialogs'): + self._modeless_dialogs = [] + if self.isVisible(): + for x in list(self._modeless_dialogs): + if not x.isVisible(): + self._modeless_dialogs.remove(x) try: if 'calibre.ebooks.DRMError' in job.details: d = error_dialog(self, _('Conversion Error'), @@ -1586,6 +1592,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): 'http://wiki.mobileread.com/wiki/DRM')) d.setModal(False) d.show() + self._modeless_dialogs.append(d) return except: pass @@ -1600,6 +1607,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): det_msg=job.details) d.setModal(False) d.show() + self._modeless_dialogs.append(d) def initialize_database(self): diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index 458247896e..36a262ab5c 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -54,11 +54,11 @@ In order to convert a collection of HTML files in a specific oder, you have to c Then just add this HTML file to the GUI and use the convert button to create your ebook. -How do I convert my file containing non-English characters? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +How do I convert my file containing non-English characters, or smart quotes? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are two aspects to this problem: 1. Knowing the encoding of the source file: |app| tries to guess what character encoding your source files use, but often, this is impossible, so you need to tell it what encoding to use. This can be done in the GUI via the :guilabel:`Input character encoding` field in the :guilabel:`Look & Feel` section. The command-line tools all have an :option:`--input-encoding` option. - 2. When adding HTML files to |app|, you may need to tell |app| what encoding the files are in. To do this go to Preferences->Plugins->File Type plugins and customize the HTML2Zip plugin, telling it what encoding your HTML files are in. |app| will then automatically convert the HTML files into the UTF-8 encoding when adding them. + 2. When adding HTML files to |app|, you may need to tell |app| what encoding the files are in. To do this go to Preferences->Plugins->File Type plugins and customize the HTML2Zip plugin, telling it what encoding your HTML files are in. Now when you add HTML files to |app| they will be correctly processed. HTML files from different sources often have different encodings, so you may have to change this setting repeatedly. A common encoding for many files from the web is ``cp1252`` and I would suggest you try that first. 3. Embedding fonts: If you are generating an LRF file to read on your SONY Reader, you are limited by the fact that the Reader only supports a few non-English characters in the fonts it comes pre-loaded with. You can work around this problem by embedding a unicode-aware font that supports the character set your file uses into the LRF file. You should embed atleast a serif and a sans-serif font. Be aware that embedding fonts significantly slows down page-turn speed on the reader.