@@ -230,6 +230,9 @@ def void_formatter(array, *args, **kwargs):
230
230
arrays = [k for k , v in self .data .items () if self ._display_in_grid (k , v )]
231
231
self .add_list_items (arrays )
232
232
233
+ # tracking data changes
234
+ self .arraywidget .model_data .dataChanged .connect (self .data_changed )
235
+
233
236
return True
234
237
235
238
def _reset (self ):
@@ -277,6 +280,22 @@ def setup_menu_bar(self):
277
280
help_menu .addAction (create_action (self , _ ('Online Objects and Functions (API) &Reference' ),
278
281
triggered = self .open_api_documentation ))
279
282
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
+
280
299
def add_list_item (self , name ):
281
300
listitem = QListWidgetItem (self ._listwidget )
282
301
listitem .setText (name )
@@ -339,7 +358,7 @@ def update_mapping(self, value):
339
358
340
359
# 3) mark session as dirty if needed
341
360
if len (changed_displayable_keys ) > 0 or deleted_displayable_keys :
342
- self ._unsaved_modifications = True
361
+ self .unsaved_modifications = True
343
362
344
363
# 4) change displayed array in the array widget
345
364
# only display first result if there are more than one
@@ -465,6 +484,10 @@ def update_title(self):
465
484
title = [name ]
466
485
# extra info
467
486
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
468
491
self .setWindowTitle (' - ' .join (title ))
469
492
470
493
def set_current_array (self , array , name ):
@@ -512,7 +535,7 @@ def new(self):
512
535
self ._reset ()
513
536
self .arraywidget .set_data (np .empty (0 ))
514
537
self .set_current_file (None )
515
- self ._unsaved_modifications = False
538
+ self .unsaved_modifications = False
516
539
self .statusBar ().showMessage ("Viewer has been reset" , 4000 )
517
540
518
541
def _open_file (self , filepath ):
@@ -532,7 +555,7 @@ def _open_file(self, filepath):
532
555
self .statusBar ().showMessage ("File {} loaded" .format (os .path .basename (filepath )), 4000 )
533
556
self ._add_arrays (session )
534
557
self ._listwidget .setCurrentRow (0 )
535
- self ._unsaved_modifications = False
558
+ self .unsaved_modifications = False
536
559
537
560
def open (self ):
538
561
if self ._ask_to_save_if_unsaved_modifications ():
@@ -563,7 +586,7 @@ def _save_data(self, filepath):
563
586
session = Session ({k : v for k , v in self .data .items () if self ._display_in_grid (k , v )})
564
587
session .save (filepath )
565
588
self .set_current_file (filepath )
566
- self ._unsaved_modifications = False
589
+ self .unsaved_modifications = False
567
590
self .statusBar ().showMessage ("Arrays saved in file {}" .format (filepath ), 4000 )
568
591
569
592
def save (self ):
@@ -642,13 +665,14 @@ def closeEvent(self, event):
642
665
event .ignore ()
643
666
644
667
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
646
669
if self .arraywidget .dirty :
647
- self ._unsaved_modifications = True
670
+ self .unsaved_modifications = True
648
671
self .arraywidget .accept_changes ()
649
672
650
673
def discard_changes (self ):
651
674
self .arraywidget .reject_changes ()
675
+ self .update_title ()
652
676
653
677
def get_value (self ):
654
678
"""Return modified array -- this is *not* a copy"""
0 commit comments