From e9dc977a52e76003c0088e8767303c95fef97229 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Wed, 27 Jun 2018 07:59:10 +0100 Subject: [PATCH 1/6] Only show buttons for exporting data and defining arithmetic attributes when at least one dataset is present --- glue/app/qt/application.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/glue/app/qt/application.py b/glue/app/qt/application.py index 1dad20737..869dc435a 100644 --- a/glue/app/qt/application.py +++ b/glue/app/qt/application.py @@ -363,7 +363,6 @@ def _setup_ui(self): self._button_link_data.setIcon(get_icon('glue_link')) self._button_link_data.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self._button_link_data.clicked.connect(self._set_up_links) - self._on_data_collection_change() self._data_toolbar.addWidget(self._button_link_data) @@ -409,6 +408,8 @@ def _setup_ui(self): self.addToolBar(self._data_toolbar) + self._on_data_collection_change() + # Selection mode toolbar tbar = EditSubsetModeToolBar(parent=self) @@ -452,7 +453,9 @@ def _setup_ui(self): self._hub.subscribe(self, DataCollectionMessage, handler=self._on_data_collection_change) def _on_data_collection_change(self, *event): + self._button_save_data.setEnabled(len(self.data_collection) > 0) self._button_link_data.setEnabled(len(self.data_collection) > 1) + self._button_edit_components.setEnabled(len(self.data_collection) > 0) def keyPressEvent(self, event): if self.current_tab.activeSubWindow() and self.current_tab.activeSubWindow().widget(): From 2b12a20b5fb293e517748c04ffe1da33edae6794 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Wed, 27 Jun 2018 07:59:33 +0100 Subject: [PATCH 2/6] Use .ui in autoconnect call to try and avoid ciruclar references --- glue/app/qt/save_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue/app/qt/save_data.py b/glue/app/qt/save_data.py index 2992a13cc..4eb2b72bd 100644 --- a/glue/app/qt/save_data.py +++ b/glue/app/qt/save_data.py @@ -80,7 +80,7 @@ def __init__(self, data_collection=None, parent=None): self.ui = load_ui('save_data.ui', parent=self, directory=os.path.dirname(__file__)) - autoconnect_callbacks_to_qt(self.state, self) + autoconnect_callbacks_to_qt(self.state, self.ui) self.ui.button_cancel.clicked.connect(self.reject) self.ui.button_ok.clicked.connect(self.accept) From 3f0fe580c9059f7ae42f1bcf24c0ab5ff7473922 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Wed, 27 Jun 2018 08:29:52 +0100 Subject: [PATCH 3/6] Don't use lambda functions in DataComboHelper to avoid residual circular references --- glue/core/data_combo_helper.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/glue/core/data_combo_helper.py b/glue/core/data_combo_helper.py index 653f2aae1..c41bdbc35 100644 --- a/glue/core/data_combo_helper.py +++ b/glue/core/data_combo_helper.py @@ -374,18 +374,18 @@ def refresh(self, *args): self.choices = choices def _filter_msg(self, msg): - return msg.data in self._data or msg.sender in self._data_collection + return msg.sender in self._data def register_to_hub(self, hub): hub.subscribe(self, DataRenameComponentMessage, handler=self._on_rename, - filter=lambda msg: msg.sender in self._data) + filter=self._filter_msg) hub.subscribe(self, DataReorderComponentMessage, handler=self.refresh, - filter=lambda msg: msg.sender in self._data) + filter=self._filter_msg) hub.subscribe(self, ComponentsChangedMessage, handler=self.refresh, - filter=lambda msg: msg.sender in self._data) + filter=self._filter_msg) if self._data_collection is not None: hub.subscribe(self, DataCollectionDeleteMessage, handler=self._remove_data) @@ -535,16 +535,22 @@ def remove_data(self, data): self._datasets.remove(data) self.refresh() + def _remove_data_msg(self, msg): + self.remove_data(msg.data) + + def _filter_msg(self, msg): + return msg.sender in self._datasets + def register_to_hub(self, hub): super(ManualDataComboHelper, self).register_to_hub(hub) hub.subscribe(self, DataUpdateMessage, handler=self._on_data_update, - filter=lambda msg: msg.sender in self._datasets) + filter=self._filter_msg) hub.subscribe(self, DataCollectionDeleteMessage, - handler=lambda msg: self.remove_data(msg.data), - filter=lambda msg: msg.sender is self._data_collection) + handler=self._remove_data_msg, + filter=self._filter_msg) class DataCollectionComboHelper(BaseDataComboHelper): @@ -571,14 +577,17 @@ def __init__(self, state, selection_property, data_collection): self.refresh() + def _filter_msg(self, msg): + return msg.sender in self._datasets + def register_to_hub(self, hub): super(DataCollectionComboHelper, self).register_to_hub(hub) hub.subscribe(self, DataUpdateMessage, handler=self._on_data_update, - filter=lambda msg: msg.sender in self._datasets) + filter=self._filter_msg) hub.subscribe(self, DataCollectionAddMessage, handler=self.refresh, - filter=lambda msg: msg.sender is self._datasets) + filter=self._filter_msg) hub.subscribe(self, DataCollectionDeleteMessage, handler=self.refresh, - filter=lambda msg: msg.sender is self._datasets) + filter=self._filter_msg) From 00f4a8e6d1add7229ed6875ce1caea9f1e9e2f5c Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Wed, 27 Jun 2018 08:31:26 +0100 Subject: [PATCH 4/6] Added methods to remove callbacks from state classes and callback properties --- glue/external/echo/core.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/glue/external/echo/core.py b/glue/external/echo/core.py index a99d86551..bd0e1978a 100644 --- a/glue/external/echo/core.py +++ b/glue/external/echo/core.py @@ -188,6 +188,16 @@ def remove_callback(self, instance, func): else: raise ValueError("Callback function not found: %s" % func) + def clear_callbacks(self, instance): + """ + Remove all callbacks on this property. + """ + for cb in [self._callbacks, self._2arg_callbacks]: + if instance in cb: + cb[instance].clear() + if instance in self._disabled: + self._disabled.pop(instance) + class HasCallbackProperties(object): """ @@ -346,6 +356,14 @@ def iter_callback_properties(self): def callback_properties(self): return [name for name in dir(self) if self.is_callback_property(name)] + def clear_callbacks(self): + """ + Remove all global and property-specific callbacks. + """ + self._global_callbacks.clear() + for name, prop in self.iter_callback_properties(): + prop.clear_callbacks(self) + def add_callback(instance, prop, callback, echo_old=False, priority=0): """ From 7d564a733a253c5908c9cda1a6e81ba63d1bb416 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Wed, 27 Jun 2018 08:39:26 +0100 Subject: [PATCH 5/6] Fix filter_msg methods --- glue/core/data_combo_helper.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/glue/core/data_combo_helper.py b/glue/core/data_combo_helper.py index c41bdbc35..adb4f9f7d 100644 --- a/glue/core/data_combo_helper.py +++ b/glue/core/data_combo_helper.py @@ -541,6 +541,9 @@ def _remove_data_msg(self, msg): def _filter_msg(self, msg): return msg.sender in self._datasets + def _filter_msg_dc(self, msg): + return msg.sender is self._data_collection + def register_to_hub(self, hub): super(ManualDataComboHelper, self).register_to_hub(hub) @@ -550,7 +553,7 @@ def register_to_hub(self, hub): filter=self._filter_msg) hub.subscribe(self, DataCollectionDeleteMessage, handler=self._remove_data_msg, - filter=self._filter_msg) + filter=self._filter_msg_dc) class DataCollectionComboHelper(BaseDataComboHelper): @@ -577,17 +580,20 @@ def __init__(self, state, selection_property, data_collection): self.refresh() - def _filter_msg(self, msg): + def _filter_msg_in(self, msg): return msg.sender in self._datasets + def _filter_msg_is(self, msg): + return msg.sender is self._datasets + def register_to_hub(self, hub): super(DataCollectionComboHelper, self).register_to_hub(hub) hub.subscribe(self, DataUpdateMessage, handler=self._on_data_update, - filter=self._filter_msg) + filter=self._filter_msg_in) hub.subscribe(self, DataCollectionAddMessage, handler=self.refresh, - filter=self._filter_msg) + filter=self._filter_msg_is) hub.subscribe(self, DataCollectionDeleteMessage, handler=self.refresh, - filter=self._filter_msg) + filter=self._filter_msg_is) From 6cf98f17f64a7713a50e355a33b439818b1eb3a9 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Wed, 27 Jun 2018 08:41:30 +0100 Subject: [PATCH 6/6] Added changelog entry --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 75a152f92..1904953ac 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -56,6 +56,11 @@ v0.13.4 (unreleased) * Improve performance when updating links and changing attributes on subsets. [#1716] +* Fix errors that happened when clicking on the 'Export Data' and + 'Define arithmetic attributes' buttons when no data was present, + and fixed Qt errors that happened if the data collection changed + after the 'Export Data' dialog was opened. [#1795] + * Fixed parsing of AVM meta-data from images. [#1732] v0.13.3 (unreleased)