From d2a1c210e82362b9aa9bd325d20cbcf4642304c1 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sun, 19 Jun 2016 12:13:54 -0500 Subject: [PATCH 1/4] Editor: Create only one instance of IntrospectionManager for the application - Before we were creating one instance per EditorStack, which was causing freezes when adding more EditorStacks (e.g. when a new Editor window was created or when the Editor was splitted). --- spyderlib/plugins/editor.py | 18 ++++++++++++++---- spyderlib/utils/introspection/manager.py | 7 +++++-- spyderlib/widgets/editor.py | 16 ++++++++-------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/spyderlib/plugins/editor.py b/spyderlib/plugins/editor.py index 4ef71f12458..ce28958bbbf 100644 --- a/spyderlib/plugins/editor.py +++ b/spyderlib/plugins/editor.py @@ -37,6 +37,7 @@ from spyderlib.py3compat import getcwd, PY2, qbytearray_to_str, to_text_string from spyderlib.utils import codeanalysis, encoding, programs, sourcecode from spyderlib.utils import icon_manager as ima +from spyderlib.utils.introspection.manager import IntrospectionManager from spyderlib.utils.qthelpers import (add_actions, add_shortcut_to_tooltip, create_action, get_filetype_icon) from spyderlib.widgets.findreplace import FindReplace @@ -387,7 +388,7 @@ def __init__(self, parent, ignore_last_opened_files=False): self.editorstacks = None self.editorwindows = None self.editorwindows_to_be_created = None - + self.file_dependent_actions = [] self.pythonfile_dependent_actions = [] self.dock_toolbar_actions = None @@ -424,7 +425,9 @@ def __init__(self, parent, ignore_last_opened_files=False): self.editorwindows_to_be_created = [] self.toolbar_list = None self.menu_list = None - + + self.introspector = IntrospectionManager() + # Setup new windows: self.main.all_actions_defined.connect(self.setup_other_windows) @@ -1093,8 +1096,12 @@ def save_focus_editorstack(self): for win in [self]+self.editorwindows: if win.isAncestorOf(editorstack): self.set_last_focus_editorstack(win, editorstack) - - + + def set_editorstack_for_introspection(self): + editorstack = self.__get_focus_editorstack() + if editorstack is not None: + self.introspector.set_editor_widget(editorstack) + #------ Handling editorstacks def register_editorstack(self, editorstack): self.editorstacks.append(editorstack) @@ -1122,6 +1129,8 @@ def register_editorstack(self, editorstack): editorstack.set_io_actions(self.new_action, self.open_action, self.save_action, self.revert_action) editorstack.set_tempfile_path(self.TEMPFILE_PATH) + editorstack.set_introspector(self.introspector) + settings = ( ('set_pyflakes_enabled', 'code_analysis/pyflakes'), ('set_pep8_enabled', 'code_analysis/pep8'), @@ -1174,6 +1183,7 @@ def register_editorstack(self, editorstack): editorstack.update_plugin_title.connect( lambda: self.update_plugin_title.emit()) editorstack.editor_focus_changed.connect(self.save_focus_editorstack) + editorstack.editor_focus_changed.connect(self.set_editorstack_for_introspection) editorstack.editor_focus_changed.connect(self.main.plugin_focus_changed) editorstack.zoom_in.connect(lambda: self.zoom(1)) editorstack.zoom_out.connect(lambda: self.zoom(-1)) diff --git a/spyderlib/utils/introspection/manager.py b/spyderlib/utils/introspection/manager.py index 9719275f6ab..9c687283593 100644 --- a/spyderlib/utils/introspection/manager.py +++ b/spyderlib/utils/introspection/manager.py @@ -160,9 +160,9 @@ class IntrospectionManager(QObject): send_to_help = Signal(str, str, str, str, bool) edit_goto = Signal(str, int, str) - def __init__(self, editor_widget, executable=None): + def __init__(self, executable=None): super(IntrospectionManager, self).__init__() - self.editor_widget = editor_widget + self.editor_widget = None self.pending = None self.plugin_manager = PluginManager(executable) self.plugin_manager.introspection_complete.connect( @@ -174,6 +174,9 @@ def change_executable(self, executable): self.plugin_manager.introspection_complete.connect( self._introspection_complete) + def set_editor_widget(self, editor_widget): + self.editor_widget = editor_widget + def _get_code_info(self, name, position=None, **kwargs): editor = self.editor_widget.get_current_editor() diff --git a/spyderlib/widgets/editor.py b/spyderlib/widgets/editor.py index b7f3598a3a7..9af5d6fda6e 100644 --- a/spyderlib/widgets/editor.py +++ b/spyderlib/widgets/editor.py @@ -35,7 +35,6 @@ from spyderlib.utils import icon_manager as ima from spyderlib.utils import (codeanalysis, encoding, sourcecode, syntaxhighlighters) -from spyderlib.utils.introspection.manager import IntrospectionManager from spyderlib.utils.qthelpers import (add_actions, create_action, create_toolbutton, get_filetype_icon, mimedata2url) @@ -402,13 +401,7 @@ def __init__(self, parent, actions): if ccs not in syntaxhighlighters.COLOR_SCHEME_NAMES: ccs = syntaxhighlighters.COLOR_SCHEME_NAMES[0] self.color_scheme = ccs - self.introspector = IntrospectionManager(self) - - self.introspector.send_to_help.connect(self.send_to_help) - self.introspector.edit_goto.connect( - lambda fname, lineno, name: - self.edit_goto.emit(fname, lineno, name)) - + self.introspector = None self.__file_status_flag = False # Real-time code analysis @@ -862,6 +855,13 @@ def set_always_remove_trailing_spaces(self, state): def set_focus_to_editor(self, state): self.focus_to_editor = state + def set_introspector(self, introspector): + self.introspector = introspector + self.introspector.send_to_help.connect(self.send_to_help) + self.introspector.edit_goto.connect( + lambda fname, lineno, name: + self.edit_goto.emit(fname, lineno, name)) + #------ Stacked widget management def get_stack_index(self): return self.tabs.currentIndex() From 843b8ce9f67a12e865ad0a16a7360057d4e3f08c Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sun, 19 Jun 2016 12:31:54 -0500 Subject: [PATCH 2/4] Editor: Add missing doctring to set_editorstack_for_introspection - Also move it to a better place --- spyderlib/plugins/editor.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/spyderlib/plugins/editor.py b/spyderlib/plugins/editor.py index ce28958bbbf..1e2f83b3051 100644 --- a/spyderlib/plugins/editor.py +++ b/spyderlib/plugins/editor.py @@ -1097,11 +1097,6 @@ def save_focus_editorstack(self): if win.isAncestorOf(editorstack): self.set_last_focus_editorstack(win, editorstack) - def set_editorstack_for_introspection(self): - editorstack = self.__get_focus_editorstack() - if editorstack is not None: - self.introspector.set_editor_widget(editorstack) - #------ Handling editorstacks def register_editorstack(self, editorstack): self.editorstacks.append(editorstack) @@ -1253,8 +1248,16 @@ def file_renamed_in_data_in_editorstack(self, editorstack_id_str, if str(id(editorstack)) != editorstack_id_str: editorstack.rename_in_data(index, filename) + def set_editorstack_for_introspection(self): + """ + Set the current editorstack to be used by the IntrospectionManager + instance + """ + editorstack = self.__get_focus_editorstack() + if editorstack is not None: + self.introspector.set_editor_widget(editorstack) - #------ Handling editor windows + #------ Handling editor windows def setup_other_windows(self): """Setup toolbars and menus for 'New window' instances""" self.toolbar_list = ( From b887852d56265dd302fd830913f878d22bafdc18 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sun, 19 Jun 2016 13:03:05 -0500 Subject: [PATCH 3/4] Editor: Disconnect and reconnect introspector signals when EditorStack changes focus --- spyderlib/plugins/editor.py | 13 +++++++++++++ spyderlib/widgets/editor.py | 4 ---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/spyderlib/plugins/editor.py b/spyderlib/plugins/editor.py index 1e2f83b3051..32f9ae18834 100644 --- a/spyderlib/plugins/editor.py +++ b/spyderlib/plugins/editor.py @@ -1257,6 +1257,19 @@ def set_editorstack_for_introspection(self): if editorstack is not None: self.introspector.set_editor_widget(editorstack) + # Disconnect active signals + try: + self.introspector.send_to_help.disconnect() + self.introspector.edit_goto.disconnect() + except TypeError: + pass + + # Reconnect signals again + self.introspector.send_to_help.connect(editorstack.send_to_help) + self.introspector.edit_goto.connect( + lambda fname, lineno, name: + editorstack.edit_goto.emit(fname, lineno, name)) + #------ Handling editor windows def setup_other_windows(self): """Setup toolbars and menus for 'New window' instances""" diff --git a/spyderlib/widgets/editor.py b/spyderlib/widgets/editor.py index 9af5d6fda6e..9854a4b863e 100644 --- a/spyderlib/widgets/editor.py +++ b/spyderlib/widgets/editor.py @@ -857,10 +857,6 @@ def set_focus_to_editor(self, state): def set_introspector(self, introspector): self.introspector = introspector - self.introspector.send_to_help.connect(self.send_to_help) - self.introspector.edit_goto.connect( - lambda fname, lineno, name: - self.edit_goto.emit(fname, lineno, name)) #------ Stacked widget management def get_stack_index(self): From 52be612e71b277ec19f05dacff521a1cfffa8529 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sun, 19 Jun 2016 13:44:23 -0500 Subject: [PATCH 4/4] Editor: Fix tests for editor widget --- spyderlib/widgets/editor.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spyderlib/widgets/editor.py b/spyderlib/widgets/editor.py index 9854a4b863e..c96e2ec177b 100644 --- a/spyderlib/widgets/editor.py +++ b/spyderlib/widgets/editor.py @@ -2188,13 +2188,14 @@ def __init__(self): self.outlineexplorer = OutlineExplorerWidget(self, show_fullpath=False, show_all_files=False) self.outlineexplorer.edit_goto.connect(self.go_to_file) + self.editor_splitter = EditorSplitter(self, self, menu_actions, + first=True) editor_widgets = QWidget(self) editor_layout = QVBoxLayout() editor_layout.setContentsMargins(0, 0, 0, 0) editor_widgets.setLayout(editor_layout) - editor_layout.addWidget(EditorSplitter(self, self, menu_actions, - first=True)) + editor_layout.addWidget(self.editor_splitter) editor_layout.addWidget(self.find_widget) self.setContentsMargins(0, 0, 0, 0) @@ -2327,13 +2328,20 @@ def register_widget_shortcuts(self, context, widget): def test(): from spyderlib.utils.qthelpers import qapplication from spyderlib.config.base import get_module_path + from spyderlib.utils.introspection.manager import IntrospectionManager cur_dir = osp.join(get_module_path('spyderlib'), 'widgets') app = qapplication(test_time=8) + introspector = IntrospectionManager() + test = EditorPluginExample() test.resize(900, 700) test.show() + editorstack = test.editor_splitter.editorstack + editorstack.set_introspector(introspector) + introspector.set_editor_widget(editorstack) + import time t0 = time.time() test.load(osp.join(cur_dir, "editor.py"))