From a9a080639596a9e9fb38fddb3fdf2d693cc30109 Mon Sep 17 00:00:00 2001
From: Daniel Brown <ddb@star.sr.bham.ac.uk>
Date: Tue, 4 Mar 2014 13:47:15 +0000
Subject: [PATCH] sorting out dangling put commands when object removed

---
 pykat/components.py   |  5 +++++
 pykat/gui/graphics.py |  6 +-----
 pykat/gui/gui.py      |  9 ++++++---
 pykat/param.py        | 32 ++++++++++++++++++++++++++++++--
 4 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/pykat/components.py b/pykat/components.py
index d5e1f17..fa29d7b 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -159,6 +159,11 @@ class Component(object):
     def remove(self):
         self._kat.remove(self)
         
+        # inform all parameters that we have removed its owner
+        # so that it can then warn about any puts/vars/xaxis
+        for p in self._params:
+            p._onOwnerRemoved()
+        
         del self._params[:]
 
         self.__removed = True
diff --git a/pykat/gui/graphics.py b/pykat/gui/graphics.py
index 8172e38..58bcf39 100644
--- a/pykat/gui/graphics.py
+++ b/pykat/gui/graphics.py
@@ -143,15 +143,11 @@ class SpaceQGraphicsItem(QGraphicsLineItem):
         
     
 class ComponentQGraphicsItem(QtSvg.QGraphicsSvgItem):
-    
-    def __on_component_deleted(self, arg):
-        import gc
-        print gc.get_referrers(self)
         
     def __init__(self, svgfile, component, nodes):
         QGraphicsSvgItem.__init__(self,svgfile)
         self.__nodeGraphics = []
-        self.__component = weakref.ref(component, self.__on_component_deleted)
+        self.__component = weakref.ref(component)
         
         # this signals the itemChange() method when this item is moved
         # used for refreshing the spaces between components
diff --git a/pykat/gui/gui.py b/pykat/gui/gui.py
index 4d71109..a6cdb94 100644
--- a/pykat/gui/gui.py
+++ b/pykat/gui/gui.py
@@ -87,7 +87,6 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow):
             
             for n in nodes:
                 for cc in self._kat.nodes.getNodeComponents(n):
-                    print "refresh", cc 
                     if cc != None:
                         ccitm = cc.getQGraphicsItem()
                         if ccitm != None:
@@ -145,7 +144,10 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow):
 
         self.kat.add(l)
         self.addComponentToScene(l,x,y)   
-     
+    
+    def deleteComponent(self, comp):
+        comp.component.remove()
+    
     def disconnect(self, node):
         comps = self.kat.nodes.getNodeComponents(node)
         
@@ -231,7 +233,8 @@ class pyKatGraphicsView(QGraphicsView):
             if isinstance(item, ComponentQGraphicsItem):           
                 menu.addSeparator()
                 menu.addAction("Edit")
-                menu.addAction("Delete")
+                action = menu.addAction("Delete")
+                action.triggered.connect(functools.partial(gui.deleteComponent, item))
             if isinstance(item,NodeQGraphicItem):
                 menu.addSeparator()
                 comps = self._kat.nodes.getNodeComponents(item.node)
diff --git a/pykat/param.py b/pykat/param.py
index 2376114..cd732b1 100644
--- a/pykat/param.py
+++ b/pykat/param.py
@@ -27,9 +27,13 @@ class putable(object):
         
         if self._putter != None:
             self._putter.put_count -= 1
+            self._putter.putees.remove(self)
         
         self._putter = var
-        self._putter.put_count += 1
+        
+        if var != None:
+            self._putter.put_count += 1
+            self._putter.putees.append(self)
         
     def _getPutFinesseText(self):
         rtn = []
@@ -49,6 +53,7 @@ class putter(object):
         self._put_name = put_name
         self.put_count = 0
         self._isPutter = isPutter
+        self.putees = [] # list of params that this puts to
     
     @property
     def isPutter(self): return self._isPutter
@@ -87,6 +92,9 @@ class Param(putable, putter):
     @property
     def canFsig(self): return self._canFsig
     
+    @property
+    def owner(self): return self._owner()
+    
     @property
     def fsig_name(self): return self.__fsig_name
     
@@ -136,7 +144,27 @@ class Param(putable, putter):
             rtn.append("set {put_name} {comp} {param}".format(put_name=self.put_name(), comp=self._owner().name, param=self.name))
         
         return rtn
-        
+    
+    def _onOwnerRemoved(self):
+        #if this param can be put somewhere we need to check if it is
+        if self.isPutable:
+            for a in self.putees:
+                print "Removing put from {0} {1} to {2} {3}".format(self.owner.name, self.name, a.owner.name, a.name)
+                a._putter = None
+                self.put_count -= 1
+                
+            # delete any references left over
+            del self.putees[:]
+        
+        # check if we have anything being put to us
+        if self.isPutter:
+            if self._putter != None:
+                print "Removing put from {0} {1} to {2} {3}".format(self._putter.owner.name, self._putter.name, self.owner.name, self.name)
+                self._putter.put_count -= 1
+                self._putter.putees.remove(self)
+                self._putter = None
+       
+       
     def __mul__(self, a):
         return self.value * a
     
-- 
GitLab