Skip to content

Commit 8b7ea10

Browse files
committed
fix #21 : add marker * to the title when unsaved changes are detected.
changed behavior of var unsaved_modifications (MappingEditor class): set to True as soon as data has been changed (before users click on Apply button)
1 parent 5a07ac1 commit 8b7ea10

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

larray_editor/arrayadapter.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,7 @@ def _map_global_to_filtered(self, k):
176176
tuple
177177
Positional index (row, column) of the modified data cell.
178178
"""
179-
if not isinstance(k, tuple):
180-
raise ValueError("Expected tuple argument. Passed argument is of type {}".format(type(k).__name__))
181-
if len(k) != self.la_data.ndim:
182-
raise ValueError("Length of passed tuple k ({}) must be equal to the number of dimensions "
183-
"of current array ({}).\nPassed argument is: {}".format(len(k), self.la_data.ndim, k))
179+
assert isinstance(k, tuple) and len(k) == self.la_data.ndim
184180
dkey = {axis_id: axis_key for axis_key, axis_id in zip(k, self.la_data.axes.ids)}
185181
# transform global dictionary key to "local" (filtered) key by removing
186182
# the parts of the key which are redundant with the filter

larray_editor/editor.py

+30-6
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ def void_formatter(array, *args, **kwargs):
230230
arrays = [k for k, v in self.data.items() if self._display_in_grid(k, v)]
231231
self.add_list_items(arrays)
232232

233+
# tracking data changes
234+
self.arraywidget.model_data.dataChanged.connect(self.data_changed)
235+
233236
return True
234237

235238
def _reset(self):
@@ -277,6 +280,22 @@ def setup_menu_bar(self):
277280
help_menu.addAction(create_action(self, _('Online Objects and Functions (API) &Reference'),
278281
triggered=self.open_api_documentation))
279282

283+
def data_changed(self):
284+
# We do not set self._unsaved_modifications to True because if users click on `Discard` button
285+
# (which calls reject_changes) or choose to display another array, all temporary changes are lost.
286+
# `update_title` relies on _is_unsaved_modifications() which checks both self._unsaved_modifications
287+
# and self.arraywidget.dirty
288+
self.update_title()
289+
290+
@property
291+
def unsaved_modifications(self):
292+
return self._unsaved_modifications
293+
294+
@unsaved_modifications.setter
295+
def unsaved_modifications(self, unsaved_modifications):
296+
self._unsaved_modifications = unsaved_modifications
297+
self.update_title()
298+
280299
def add_list_item(self, name):
281300
listitem = QListWidgetItem(self._listwidget)
282301
listitem.setText(name)
@@ -339,7 +358,7 @@ def update_mapping(self, value):
339358

340359
# 3) mark session as dirty if needed
341360
if len(changed_displayable_keys) > 0 or deleted_displayable_keys:
342-
self._unsaved_modifications = True
361+
self.unsaved_modifications = True
343362

344363
# 4) change displayed array in the array widget
345364
# only display first result if there are more than one
@@ -465,6 +484,10 @@ def update_title(self):
465484
title = [name]
466485
# extra info
467486
title += [self.title]
487+
# add '*' at the end of the title if unsaved modifications.
488+
if self._is_unsaved_modifications():
489+
title += ['*']
490+
# set title
468491
self.setWindowTitle(' - '.join(title))
469492

470493
def set_current_array(self, array, name):
@@ -512,7 +535,7 @@ def new(self):
512535
self._reset()
513536
self.arraywidget.set_data(np.empty(0))
514537
self.set_current_file(None)
515-
self._unsaved_modifications = False
538+
self.unsaved_modifications = False
516539
self.statusBar().showMessage("Viewer has been reset", 4000)
517540

518541
def _open_file(self, filepath):
@@ -532,7 +555,7 @@ def _open_file(self, filepath):
532555
self.statusBar().showMessage("File {} loaded".format(os.path.basename(filepath)), 4000)
533556
self._add_arrays(session)
534557
self._listwidget.setCurrentRow(0)
535-
self._unsaved_modifications = False
558+
self.unsaved_modifications = False
536559

537560
def open(self):
538561
if self._ask_to_save_if_unsaved_modifications():
@@ -563,7 +586,7 @@ def _save_data(self, filepath):
563586
session = Session({k: v for k, v in self.data.items() if self._display_in_grid(k, v)})
564587
session.save(filepath)
565588
self.set_current_file(filepath)
566-
self._unsaved_modifications = False
589+
self.unsaved_modifications = False
567590
self.statusBar().showMessage("Arrays saved in file {}".format(filepath), 4000)
568591

569592
def save(self):
@@ -642,13 +665,14 @@ def closeEvent(self, event):
642665
event.ignore()
643666

644667
def apply_changes(self):
645-
# update _unsaved_modifications only if 1 or more changes have been applied
668+
# update unsaved_modifications (and thus title) only if at least 1 change has been applied
646669
if self.arraywidget.dirty:
647-
self._unsaved_modifications = True
670+
self.unsaved_modifications = True
648671
self.arraywidget.accept_changes()
649672

650673
def discard_changes(self):
651674
self.arraywidget.reject_changes()
675+
self.update_title()
652676

653677
def get_value(self):
654678
"""Return modified array -- this is *not* a copy"""

0 commit comments

Comments
 (0)