From 36768f69626e82564c98e6d79cc2e72e7e7405da Mon Sep 17 00:00:00 2001 From: John Schember Date: Fri, 28 Jan 2011 06:07:17 -0500 Subject: [PATCH 01/17] GUI: Autocomplete author and tags fix bug were first letter was repeated when completion text ended with a space. --- src/calibre/gui2/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index 41b18aebba..672ea7a3b7 100644 --- a/src/calibre/gui2/widgets.py +++ b/src/calibre/gui2/widgets.py @@ -503,7 +503,7 @@ class CompleteLineEdit(EnLineEdit): cursor_pos = self.cursorPosition() before_text = unicode(self.text())[:cursor_pos] after_text = unicode(self.text())[cursor_pos:] - prefix_len = len(before_text.split(self.separator)[-1].strip()) + prefix_len = len(before_text.split(self.separator)[-1].lstrip()) if self.space_before_sep: complete_text_pat = '%s%s %s %s' len_extra = 3 From 232ad55ff0ef08f035c546195c8078daeaf2a5af Mon Sep 17 00:00:00 2001 From: John Schember Date: Fri, 28 Jan 2011 07:45:08 -0500 Subject: [PATCH 02/17] Implement bug #3101: GUI, Stop Job Confirmation dialog. --- src/calibre/gui2/dialogs/confirm_delete.py | 2 +- src/calibre/gui2/dialogs/jobs.ui | 10 +++++----- src/calibre/gui2/jobs.py | 20 +++++++++++--------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/calibre/gui2/dialogs/confirm_delete.py b/src/calibre/gui2/dialogs/confirm_delete.py index ff7f0a285a..9cdd46712f 100644 --- a/src/calibre/gui2/dialogs/confirm_delete.py +++ b/src/calibre/gui2/dialogs/confirm_delete.py @@ -21,10 +21,10 @@ class Dialog(QDialog, Ui_Dialog): self.again.stateChanged.connect(self.toggle) self.buttonBox.setFocus(Qt.OtherFocusReason) - def toggle(self, *args): dynamic[_config_name(self.name)] = self.again.isChecked() + def confirm(msg, name, parent=None, pixmap='dialog_warning.png'): if not dynamic.get(_config_name(name), True): return True diff --git a/src/calibre/gui2/dialogs/jobs.ui b/src/calibre/gui2/dialogs/jobs.ui index 5b311bf056..51fb03c40b 100644 --- a/src/calibre/gui2/dialogs/jobs.ui +++ b/src/calibre/gui2/dialogs/jobs.ui @@ -14,7 +14,7 @@ Active Jobs - + :/images/jobs.png:/images/jobs.png @@ -44,16 +44,16 @@ - + - &Stop selected job + Show job &details - + - Show job &details + &Stop selected job diff --git a/src/calibre/gui2/jobs.py b/src/calibre/gui2/jobs.py index a2bd8e4492..9e09a6ca53 100644 --- a/src/calibre/gui2/jobs.py +++ b/src/calibre/gui2/jobs.py @@ -19,7 +19,7 @@ from PyQt4.Qt import QAbstractTableModel, QVariant, QModelIndex, Qt, \ from calibre.utils.ipc.server import Server from calibre.utils.ipc.job import ParallelJob -from calibre.gui2 import Dispatcher, error_dialog, NONE, config, gprefs +from calibre.gui2 import Dispatcher, error_dialog, question_dialog, NONE, config, gprefs from calibre.gui2.device import DeviceJob from calibre.gui2.dialogs.jobs_ui import Ui_JobsDialog from calibre import __appname__ @@ -380,8 +380,8 @@ class JobsDialog(QDialog, Ui_JobsDialog): self.model = model self.setWindowModality(Qt.NonModal) self.setWindowTitle(__appname__ + _(' - Jobs')) - self.kill_button.clicked.connect(self.kill_job) self.details_button.clicked.connect(self.show_details) + self.kill_button.clicked.connect(self.kill_job) self.stop_all_jobs_button.clicked.connect(self.kill_all_jobs) self.pb_delegate = ProgressBarDelegate(self) self.jobs_view.setItemDelegateForColumn(2, self.pb_delegate) @@ -415,19 +415,21 @@ class JobsDialog(QDialog, Ui_JobsDialog): d.exec_() d.timer.stop() - def kill_job(self, *args): - for index in self.jobs_view.selectedIndexes(): - row = index.row() - self.model.kill_job(row, self) - return - def show_details(self, *args): for index in self.jobs_view.selectedIndexes(): self.show_job_details(index) return + def kill_job(self, *args): + if question_dialog(self, _('Are you sure?'), _('Do you really want to stop the selected job?')): + for index in self.jobs_view.selectedIndexes(): + row = index.row() + self.model.kill_job(row, self) + return + def kill_all_jobs(self, *args): - self.model.kill_all_jobs() + if question_dialog(self, _('Are you sure?'), _('Do you really want to stop all non-device jobs?')): + self.model.kill_all_jobs() def closeEvent(self, e): self.save_state() From 44e4d5a891e3f650f8f518b6903c0ce34260ee19 Mon Sep 17 00:00:00 2001 From: GRiker Date: Fri, 28 Jan 2011 06:43:47 -0700 Subject: [PATCH 03/17] GwR clarification of --fields switch for CLI --- src/calibre/library/catalog.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/calibre/library/catalog.py b/src/calibre/library/catalog.py index e20eebc517..bc6ff7f64f 100644 --- a/src/calibre/library/catalog.py +++ b/src/calibre/library/catalog.py @@ -53,6 +53,7 @@ class CSV_XML(CatalogPlugin): # {{{ 'database. Should be a comma-separated list of fields.\n' 'Available fields: %s,\n' 'plus user-created custom fields.\n' + 'Example: --fields=title,authors,tags\n' "Default: '%%default'\n" "Applies to: CSV, XML output formats")%', '.join(FIELDS)), @@ -230,6 +231,7 @@ class BIBTEX(CatalogPlugin): # {{{ help = _('The fields to output when cataloging books in the ' 'database. Should be a comma-separated list of fields.\n' 'Available fields: %s.\n' + 'Example: --fields=title,authors,tags\n' "Default: '%%default'\n" "Applies to: BIBTEX output format")%', '.join(FIELDS)), @@ -523,7 +525,7 @@ class BIBTEX(CatalogPlugin): # {{{ citation_bibtex= True else : citation_bibtex= opts.impcit - + #Check add file entry and go to default in case of bad CLI if isinstance(opts.addfiles, (StringType, UnicodeType)) : if opts.addfiles == 'False' : From e6215419dbb643784a54e9c754ccec3086a8af93 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 Jan 2011 08:30:19 -0700 Subject: [PATCH 04/17] ... --- resources/recipes/onionavclub.recipe | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/recipes/onionavclub.recipe b/resources/recipes/onionavclub.recipe index 038111cbe9..f32fd084b1 100644 --- a/resources/recipes/onionavclub.recipe +++ b/resources/recipes/onionavclub.recipe @@ -26,7 +26,7 @@ class BBC(BasicNewsRecipe): extra_css = '.headline {font-size: x-large;} \n .fact { padding-top: 10pt }' feeds = [ - ('Interviews', 'http://www.avclub.com/feed/interview/'), + ('TV', 'http://www.avclub.com/feed/tv/'), ('AV Club Daily', 'http://www.avclub.com/feed/daily'), ('Film', 'http://www.avclub.com/feed/film/'), ('Music', 'http://www.avclub.com/feed/music/'), From b37460bfb0ff3cd4adfdbc4fa9d10e86f87a9c45 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 Jan 2011 08:37:37 -0700 Subject: [PATCH 05/17] Fix #8627 (android no longer detected after update) --- src/calibre/devices/android/driver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calibre/devices/android/driver.py b/src/calibre/devices/android/driver.py index 16022fc752..5912e40a69 100644 --- a/src/calibre/devices/android/driver.py +++ b/src/calibre/devices/android/driver.py @@ -19,7 +19,8 @@ class ANDROID(USBMS): VENDOR_ID = { # HTC - 0x0bb4 : { 0x0c02 : [0x100, 0x0227, 0x0226], 0x0c01 : [0x100, 0x0227], 0x0ff9 + 0x0bb4 : { 0x0c02 : [0x100, 0x0227, 0x0226], 0x0c01 : [0x100, + 0x0227, 0x0226], 0x0ff9 : [0x0100, 0x0227, 0x0226], 0x0c87: [0x0100, 0x0227, 0x0226], 0xc92 : [0x100], 0xc97: [0x226], 0xc99 : [0x0100]}, From c87ae50433ed86f7db68b5ea79d7e3dc604db96c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 Jan 2011 09:03:51 -0700 Subject: [PATCH 06/17] ... --- src/calibre/gui2/dialogs/metadata_single.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index ca2ccfa6d5..9156ef7101 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -209,7 +209,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): title = unicode(self.title.text()).strip() author = unicode(self.authors.text()).strip() if author.endswith('&'): - author = author[:-1] + author = author[:-1].strip() if not title or not author: return error_dialog(self, _('Specify title and author'), _('You must specify a title and author before generating ' From d06947281b63c86ac5215d433aeddb7430736c6a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 Jan 2011 10:05:16 -0700 Subject: [PATCH 07/17] EPUB Output: When using preserve cover aspect ratio, use the actual image sizes in the SVG template as otherwise ADE doesn't render the images correctly --- src/calibre/ebooks/oeb/transforms/cover.py | 4 ++-- src/calibre/ebooks/pdf/output.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/ebooks/oeb/transforms/cover.py b/src/calibre/ebooks/oeb/transforms/cover.py index 0d82e9ad73..013d17c321 100644 --- a/src/calibre/ebooks/oeb/transforms/cover.py +++ b/src/calibre/ebooks/oeb/transforms/cover.py @@ -141,8 +141,8 @@ class CoverManager(object): if width is None or height is None: self.log.warning('Failed to read cover dimensions') width, height = 600, 800 - if self.preserve_aspect_ratio: - width, height = 600, 800 + #if self.preserve_aspect_ratio: + # width, height = 600, 800 self.svg_template = self.svg_template.replace('__viewbox__', '0 0 %d %d'%(width, height)) self.svg_template = self.svg_template.replace('__width__', diff --git a/src/calibre/ebooks/pdf/output.py b/src/calibre/ebooks/pdf/output.py index 7fa7a0cf4c..24050abf6a 100644 --- a/src/calibre/ebooks/pdf/output.py +++ b/src/calibre/ebooks/pdf/output.py @@ -47,7 +47,7 @@ class PDFOutput(OutputFormatPlugin): OptionRecommendation(name='preserve_cover_aspect_ratio', recommended_value=False, help=_('Preserve the aspect ratio of the cover, instead' - ' of stretching it to fill the ull first page of the' + ' of stretching it to fill the full first page of the' ' generated pdf.') ), ]) From c8c9ca7af98f3dba9bbe0ae7908727b439760924 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 Jan 2011 11:15:35 -0700 Subject: [PATCH 08/17] Fix #8621 (Do not allow "Customize plugin" immediately after installation) --- src/calibre/gui2/preferences/plugins.py | 6 +++++ src/calibre/gui2/ui.py | 30 +++++++++++++++++-------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/calibre/gui2/preferences/plugins.py b/src/calibre/gui2/preferences/plugins.py index b00a485566..9e3b1b9d4a 100644 --- a/src/calibre/gui2/preferences/plugins.py +++ b/src/calibre/gui2/preferences/plugins.py @@ -220,6 +220,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): _('Plugin: %s does not need customization')%plugin.name).exec_() return self.changed_signal.emit() + from calibre.customize import InterfaceActionBase + if isinstance(plugin, InterfaceActionBase) and not getattr(plugin, + 'actual_iaction_plugin_loaded', False): + return error_dialog(self, _('Must restart'), + _('You must restart calibre before you can' + ' configure this plugin'), show=True) if plugin.do_user_config(): self._plugin_model.refresh_plugin(plugin) elif op == 'remove': diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 5fe630691c..d6d6b7fd01 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -101,28 +101,40 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ self.opts = opts self.device_connected = None self.gui_debug = gui_debug - acmap = OrderedDict() + self.iactions = OrderedDict() for action in interface_actions(): if opts.ignore_plugins and action.plugin_path is not None: continue try: - ac = action.load_actual_plugin(self) + ac = self.init_iaction(action) except: # Ignore errors in loading user supplied plugins import traceback traceback.print_exc() - if ac.plugin_path is None: + if action.plugin_path is None: raise + continue ac.plugin_path = action.plugin_path ac.interface_action_base_plugin = action - if ac.name in acmap: - if ac.priority >= acmap[ac.name].priority: - acmap[ac.name] = ac - else: - acmap[ac.name] = ac - self.iactions = acmap + self.add_iaction(ac) + + def init_iaction(self, action): + ac = action.load_actual_plugin(self) + ac.plugin_path = action.plugin_path + ac.interface_action_base_plugin = action + action.actual_iaction_plugin_loaded = True + return ac + + def add_iaction(self, ac): + acmap = self.iactions + if ac.name in acmap: + if ac.priority >= acmap[ac.name].priority: + acmap[ac.name] = ac + else: + acmap[ac.name] = ac + def initialize(self, library_path, db, listener, actions, show_gui=True): opts = self.opts From d44429dd5e5dbc95da7c322d1f7d4cc75cd82f18 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 Jan 2011 11:21:12 -0700 Subject: [PATCH 09/17] ... --- src/calibre/gui2/preferences/plugins.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/preferences/plugins.py b/src/calibre/gui2/preferences/plugins.py index 9e3b1b9d4a..ba5b921d44 100644 --- a/src/calibre/gui2/preferences/plugins.py +++ b/src/calibre/gui2/preferences/plugins.py @@ -188,6 +188,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.plugin_view.PositionAtCenter) self.plugin_view.scrollTo(idx, self.plugin_view.PositionAtCenter) + self.plugin_view.selectionModel().select(idx, + self.plugin_view.selectionModel().ClearAndSelect) + self.plugin_view.setCurrentIndex(idx) else: error_dialog(self, _('No valid plugin path'), _('%s is not a valid plugin path')%path).exec_() @@ -225,11 +228,11 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): 'actual_iaction_plugin_loaded', False): return error_dialog(self, _('Must restart'), _('You must restart calibre before you can' - ' configure this plugin'), show=True) + ' configure the %s plugin')%plugin.name, show=True) if plugin.do_user_config(): self._plugin_model.refresh_plugin(plugin) elif op == 'remove': - msg = _('Plugin {0} successfully removed').format(plugin.name) + msg = _('Plugin {0} successfully removed').format(plugin.name) if remove_plugin(plugin): self._plugin_model.populate() self._plugin_model.reset() From 3aa9db936c75b0fe2cf9b9dae8805a2215f03c79 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 Jan 2011 12:03:02 -0700 Subject: [PATCH 10/17] version 0.7.43 --- Changelog.yaml | 129 ++++++++++++++++++++++++++++++++++++++- src/calibre/constants.py | 2 +- 2 files changed, 128 insertions(+), 3 deletions(-) diff --git a/Changelog.yaml b/Changelog.yaml index 1fcb3f0e0b..e96c990cfc 100644 --- a/Changelog.yaml +++ b/Changelog.yaml @@ -4,12 +4,137 @@ # for important features/bug fixes. # Also, each release can have new and improved recipes. +#- version: ?.?.? +# date: 2011-??-?? +# +# new features: +# - title: +# +# bug fixes: +# - title: +# +# improved recipes: +# - +# +# new recipes: +# - title: + + +- version: 0.7.43 + date: 2011-01-28 + + new features: + - title: "Ask for confirmation when stopping running jobs" + tickets: [3101] + + - title: "Combine the database integrity check and library check into a single menu item. Also nicer implementation of the db integrity check." + + - title: "BiBTeX Catalog: Add option to include file paths in the catalog." + tickets: [8589] + + - title: "Create 'generic' output profiles and generic devices in the welcome wizard" + + - title: "Bulk metadata edit: Custom column widgets all have an apply checkbox next to them." + + - title: "Only use LibraryThing to download metadata if the user provides a library thing username and password. Since LT doesn't like web scraping" + + - title: "Allow renaming of user categories in the manage categories dialog. Also allow searching for books in a category from the Tag Browser by right clicking ona a category" + + - title: "Folder device plugin: Add option to disable the use of sub folders" + + - title: "Allow saving/loading of search and replace expressions in the bulk metadata edit dialog." + + - title: "Remeber previously used regular expression in the add books preferences dialog" + + - title: "Search and replace wizard: Cache the previously used input document." + + - title: "Pressing Esc clears the current search in the main book list" + + - title: "Preselct right formats when using send specific format to device" + tickets: [7834] + + - title: "Regex wizard gets find next and previous match buttons" + tickets: [4486] + + bug fixes: + - title: "Do not allow customization of user interface plugins until calibre is restarted" + tickets: [8621] + + - title: "EPUB Output: When using preserve cover aspect ratio, use the actual image sizes in the SVG template as otherwise ADE doesn't fully preserve the aspect ratio" + + - title: "Fix completion on a word with a trailing space causing the first letter to be duplicated in the edit metadata dialog" + + - title: "PML Input: PML x and Xn tags don't indent properly in TOC. Also handle invalid T markup and retain soft scene breaks" + tickets: [6194, 8565] + + - title: "TXT Input: Retain whitespace at the beginning of lines. Don't preserve spaces in heuristic processing. Detect and retain soft scene breaks." + + - title: "Fix Adding empty book - cover browser doesn't update" + tickets: [8557] + + - title: "When generating author sort string ignore trailing Inc." + tickets: [8539] + + - title: "When converting HTML/ZIP files do not leave temporary files that are only deleted on application shutdown." + tickets: [8597] + + - title: "Don't crash if the prefs stored in the db are corrupted" + + - title: "Catalog generation: Do not use inline-block CSS as apparently Adobe Digital Editions cannot handle it." + tickets: [8566] + + - title: "Fix extra spaces being inserted into TOC title when reading TOC from OPF guide element." + tickets: [8569] + + - title: "Remember window size for bulk metadata edit and catalog generation dialogs" + tickets: [8525] + + - title: "Heuristics, italicize common cases: Enhance pattern matching to match punctuation after pattern." + + - title: "Fix regression in converting HTML files that have ASCII-encoded non unicode characters inside their