diff sat_frontends/quick_frontend/quick_widgets.py @ 2853:6901a425d882

quick frontend (widgets): improved deletion of widget: QuickWidget deletion has been improved a bit. A new "all_instances" kwarg can be used to completely delete all instances of a widget.
author Goffi <goffi@goffi.org>
date Sun, 10 Mar 2019 18:03:41 +0100
parents e2595c81eb6d
children ef65dbce313b
line wrap: on
line diff
--- a/sat_frontends/quick_frontend/quick_widgets.py	Sun Mar 10 18:03:14 2019 +0100
+++ b/sat_frontends/quick_frontend/quick_widgets.py	Sun Mar 10 18:03:41 2019 +0100
@@ -266,31 +266,61 @@
         return widget
 
     def deleteWidget(self, widget_to_delete, *args, **kwargs):
-        """Delete a widget
+        """Delete a widget instance
 
         this method must be called by frontends when a widget is deleted
-        widget's onDelete method will be called before deletion
+        widget's onDelete method will be called before deletion, and deletion will be
+        stopped if it returns False.
         @param widget_to_delete(QuickWidget): widget which need to deleted
         @param *args: extra arguments to pass to onDelete
         @param *kwargs: extra keywords arguments to pass to onDelete
             the extra arguments are not use by QuickFrontend, it's is up to
             the frontend to use them or not
+            "all_instances" can be used as kwarg, if it evaluate to True, all
+            instances of the widget will be deleted (if onDelete is not returning False
+            for any of the instance). This arguments is not sent to onDelete methods.
         """
-        if widget_to_delete.onDelete(*args, **kwargs) == False:
-            return
+        # TODO: all_instances must be independante kwargs, this is not possible with Python 2
+        #       but will be with Python 3
+        all_instances = kwargs.get('all_instances', False)
+
+        if all_instances:
+            for w in self.getWidgetInstances(widget_to_delete):
+                if w.onDelete(*args, **kwargs) == False:
+                    return
+        else:
+            if widget_to_delete.onDelete(*args, **kwargs) == False:
+                return
 
         if self.host.selected_widget == widget_to_delete:
             self.host.selected_widget = None
 
-        for widget_map in self._widgets.itervalues():
-            to_delete = set()
-            for hash_, widget_instances in widget_map.iteritems():
-                if widget_to_delete in widget_instances:
-                    widget_instances.remove(widget_to_delete)
-                    if not widget_instances:
-                        to_delete.add(hash_)
-            for hash_ in to_delete:
-                del widget_map[hash_]
+        class_ = self.getRealClass(widget_to_delete.__class__)
+        try:
+            widgets_map = self._widgets[class_.__name__]
+        except KeyError:
+            log.error(u"no widgets_map found for class {cls}".format(cls=class_))
+            return
+        widget_hash = unicode(class_.getWidgetHash(widget_to_delete.target,
+                                                   widget_to_delete.profiles))
+        widget_instances = widgets_map[widget_hash]
+        if all_instances:
+            widget_instances.clear()
+        else:
+            try:
+                widget_instances.remove(widget_to_delete)
+            except ValueError:
+                log.error(u"widget_to_delete not found in widget instances")
+                return
+
+            log.debug(u"widget {} deleted".format(widget_to_delete))
+
+        if not widget_instances:
+            # all instances with this hash have been deleted
+            # we remove the hash itself
+            del widgets_map[widget_hash]
+            log.debug(u"All instances of {cls} with hash {widget_hash} have been deleted"
+                .format(cls=class_, widget_hash=widget_hash))
 
 
 class QuickWidget(object):
@@ -402,5 +432,4 @@
         @return (boot, None): False to cancel deletion
             all other value continue deletion
         """
-        log.debug(u"widget {} deleted".format(self))
         return True