From d1d5ee7a3e022331f775ddf812d6fb72bef49cd0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 27 Jun 2011 12:13:30 -0600 Subject: [PATCH 1/5] ... --- src/calibre/gui2/preferences/main.py | 1 - src/calibre/gui2/preferences/search.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/calibre/gui2/preferences/main.py b/src/calibre/gui2/preferences/main.py index 85a5fc018c..774b7f8958 100644 --- a/src/calibre/gui2/preferences/main.py +++ b/src/calibre/gui2/preferences/main.py @@ -357,7 +357,6 @@ class Preferences(QMainWindow): bytearray(self.saveGeometry())) if self.committed: self.gui.must_restart_before_config = self.must_restart - self.gui.tags_view.set_new_model() # in case columns changed self.gui.tags_view.recount() self.gui.create_device_menu() self.gui.set_device_menu_items_state(bool(self.gui.device_connected)) diff --git a/src/calibre/gui2/preferences/search.py b/src/calibre/gui2/preferences/search.py index 7bdb12ec55..c86de7f2a3 100644 --- a/src/calibre/gui2/preferences/search.py +++ b/src/calibre/gui2/preferences/search.py @@ -173,7 +173,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): def refresh_gui(self, gui): gui.set_highlight_only_button_icon() if self.muc_changed: - gui.tags_view.set_new_model() + gui.tags_view.recount() gui.search.search_as_you_type(config['search_as_you_type']) gui.search.do_search() From ef13b74d1a6fb459688fe3de3f9f679889983b9a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 27 Jun 2011 12:48:01 -0600 Subject: [PATCH 2/5] Tag Browser: Do not allow methods to be called in a non GUI thread --- src/calibre/gui2/tag_browser/view.py | 30 +++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index c833f7fa43..ed1a597827 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -16,9 +16,10 @@ from PyQt4.Qt import (QItemDelegate, Qt, QTreeView, pyqtSignal, QSize, QIcon, from calibre.gui2.tag_browser.model import (TagTreeItem, TAG_SEARCH_STATES, TagsModel) -from calibre.gui2 import config, gprefs +from calibre.gui2 import config, gprefs, is_gui_thread from calibre.utils.search_query_parser import saved_searches from calibre.utils.icu import sort_key +from calibre.constants import DEBUG class TagDelegate(QItemDelegate): # {{{ @@ -125,6 +126,8 @@ class TagsView(QTreeView): # {{{ self.recount() def get_state(self): + if not is_gui_thread(): + return self.debug_threading() state_map = {} expanded_categories = [] for row, category in enumerate(self._model.category_nodes): @@ -136,9 +139,13 @@ class TagsView(QTreeView): # {{{ return expanded_categories, state_map def reread_collapse_parameters(self): + if not is_gui_thread(): + return self.debug_threading() self._model.reread_collapse_parameters(self.get_state()[1]) def set_database(self, db, tag_match, sort_by): + if not is_gui_thread(): + return self.debug_threading() self._model.set_database(db) self.pane_is_visible = True # because TagsModel.set_database did a recount @@ -165,6 +172,8 @@ class TagsView(QTreeView): # {{{ self.expanded.connect(self.item_expanded) def database_changed(self, event, ids): + if not is_gui_thread(): + return self.debug_threading() if self.refresh_signal_processed: self.refresh_signal_processed = False self.refresh_required.emit() @@ -191,6 +200,8 @@ class TagsView(QTreeView): # {{{ pass def set_search_restriction(self, s): + if not is_gui_thread(): + return self.debug_threading() s = s if s else None self._model.set_search_restriction(s) @@ -217,6 +228,8 @@ class TagsView(QTreeView): # {{{ set_to: if None, advance the state. Otherwise must be one of the values in TAG_SEARCH_STATES ''' + if not is_gui_thread(): + return self.debug_threading() modifiers = int(QApplication.keyboardModifiers()) exclusive = modifiers not in (Qt.CTRL, Qt.SHIFT) if self._model.toggle(index, exclusive, set_to=set_to): @@ -529,11 +542,21 @@ class TagsView(QTreeView): # {{{ fm_src['display'].get('make_category', False)))): self.setDropIndicatorShown(True) + def debug_threading(self): + if DEBUG: + import traceback + print ('Attempt to use Tab Browser in non GUI thread') + traceback.print_stack() + def clear(self): + if not is_gui_thread(): + return self.debug_threading() if self.model(): self.model().clear_state() def is_visible(self, idx): + if not is_gui_thread(): + return self.debug_threading() item = idx.data(Qt.UserRole).toPyObject() if getattr(item, 'type', None) == TagTreeItem.TAG: idx = idx.parent() @@ -544,6 +567,9 @@ class TagsView(QTreeView): # {{{ Rebuild the category tree, expand any categories that were expanded, reset the search states, and reselect the current node. ''' + if not is_gui_thread(): + return self.debug_threading() + if self.disable_recounting or not self.pane_is_visible: return self.refresh_signal_processed = True @@ -570,6 +596,8 @@ class TagsView(QTreeView): # {{{ def show_item_at_index(self, idx, box=False, position=QTreeView.PositionAtCenter): + if not is_gui_thread(): + return self.debug_threading() if idx.isValid() and idx.data(Qt.UserRole).toPyObject() is not self._model.root_item: self.setCurrentIndex(idx) self.scrollTo(idx, position) From cc0aee27f5e23e29c7ba43afed026fb7373abb77 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 27 Jun 2011 12:53:40 -0600 Subject: [PATCH 3/5] Revert thread check from Tag Browser since it doesn't prevent the crash --- src/calibre/gui2/tag_browser/view.py | 30 +--------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index ed1a597827..c833f7fa43 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -16,10 +16,9 @@ from PyQt4.Qt import (QItemDelegate, Qt, QTreeView, pyqtSignal, QSize, QIcon, from calibre.gui2.tag_browser.model import (TagTreeItem, TAG_SEARCH_STATES, TagsModel) -from calibre.gui2 import config, gprefs, is_gui_thread +from calibre.gui2 import config, gprefs from calibre.utils.search_query_parser import saved_searches from calibre.utils.icu import sort_key -from calibre.constants import DEBUG class TagDelegate(QItemDelegate): # {{{ @@ -126,8 +125,6 @@ class TagsView(QTreeView): # {{{ self.recount() def get_state(self): - if not is_gui_thread(): - return self.debug_threading() state_map = {} expanded_categories = [] for row, category in enumerate(self._model.category_nodes): @@ -139,13 +136,9 @@ class TagsView(QTreeView): # {{{ return expanded_categories, state_map def reread_collapse_parameters(self): - if not is_gui_thread(): - return self.debug_threading() self._model.reread_collapse_parameters(self.get_state()[1]) def set_database(self, db, tag_match, sort_by): - if not is_gui_thread(): - return self.debug_threading() self._model.set_database(db) self.pane_is_visible = True # because TagsModel.set_database did a recount @@ -172,8 +165,6 @@ class TagsView(QTreeView): # {{{ self.expanded.connect(self.item_expanded) def database_changed(self, event, ids): - if not is_gui_thread(): - return self.debug_threading() if self.refresh_signal_processed: self.refresh_signal_processed = False self.refresh_required.emit() @@ -200,8 +191,6 @@ class TagsView(QTreeView): # {{{ pass def set_search_restriction(self, s): - if not is_gui_thread(): - return self.debug_threading() s = s if s else None self._model.set_search_restriction(s) @@ -228,8 +217,6 @@ class TagsView(QTreeView): # {{{ set_to: if None, advance the state. Otherwise must be one of the values in TAG_SEARCH_STATES ''' - if not is_gui_thread(): - return self.debug_threading() modifiers = int(QApplication.keyboardModifiers()) exclusive = modifiers not in (Qt.CTRL, Qt.SHIFT) if self._model.toggle(index, exclusive, set_to=set_to): @@ -542,21 +529,11 @@ class TagsView(QTreeView): # {{{ fm_src['display'].get('make_category', False)))): self.setDropIndicatorShown(True) - def debug_threading(self): - if DEBUG: - import traceback - print ('Attempt to use Tab Browser in non GUI thread') - traceback.print_stack() - def clear(self): - if not is_gui_thread(): - return self.debug_threading() if self.model(): self.model().clear_state() def is_visible(self, idx): - if not is_gui_thread(): - return self.debug_threading() item = idx.data(Qt.UserRole).toPyObject() if getattr(item, 'type', None) == TagTreeItem.TAG: idx = idx.parent() @@ -567,9 +544,6 @@ class TagsView(QTreeView): # {{{ Rebuild the category tree, expand any categories that were expanded, reset the search states, and reselect the current node. ''' - if not is_gui_thread(): - return self.debug_threading() - if self.disable_recounting or not self.pane_is_visible: return self.refresh_signal_processed = True @@ -596,8 +570,6 @@ class TagsView(QTreeView): # {{{ def show_item_at_index(self, idx, box=False, position=QTreeView.PositionAtCenter): - if not is_gui_thread(): - return self.debug_threading() if idx.isValid() and idx.data(Qt.UserRole).toPyObject() is not self._model.root_item: self.setCurrentIndex(idx) self.scrollTo(idx, position) From 2395ef81120f19c3c82303d733d57c4829050a49 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 27 Jun 2011 13:28:40 -0600 Subject: [PATCH 4/5] Fix another crash in the Tag Browser --- src/calibre/gui2/tag_browser/view.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index c833f7fa43..2660d8f969 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -571,6 +571,9 @@ class TagsView(QTreeView): # {{{ def show_item_at_index(self, idx, box=False, position=QTreeView.PositionAtCenter): if idx.isValid() and idx.data(Qt.UserRole).toPyObject() is not self._model.root_item: + self.setExpanded(idx, True) # Needed otherwise Qt segfaults if the + # node is buried in a collapsed, off + # screen hierarchy self.setCurrentIndex(idx) self.scrollTo(idx, position) self.setCurrentIndex(idx) From ccfff7f456b3d347725977f73c34f9ba8bd71618 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 27 Jun 2011 13:33:22 -0600 Subject: [PATCH 5/5] ... --- src/calibre/gui2/tag_browser/view.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index 2660d8f969..853fc296b5 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -574,9 +574,7 @@ class TagsView(QTreeView): # {{{ self.setExpanded(idx, True) # Needed otherwise Qt segfaults if the # node is buried in a collapsed, off # screen hierarchy - self.setCurrentIndex(idx) self.scrollTo(idx, position) - self.setCurrentIndex(idx) if box: self._model.set_boxed(idx)