Added enable/disable of plugin method buttons. Fixed alpha graying problem with disabled buttons. Updated debug dialog message with bug report path
authoretisserant
Fri, 22 Feb 2008 19:04:01 +0100
changeset 109 f27ca37b6e7a
parent 108 280b458e42e5
child 110 a05e8b30c024
Added enable/disable of plugin method buttons. Fixed alpha graying problem with disabled buttons. Updated debug dialog message with bug report path
Beremiz.py
plugger.py
--- a/Beremiz.py	Fri Feb 22 15:40:18 2008 +0100
+++ b/Beremiz.py	Fri Feb 22 19:04:01 2008 +0100
@@ -59,8 +59,9 @@
 
 CWD = os.path.split(os.path.realpath(__file__))[0]
 
+# Some helpers to tweak GenBitmapTextButtons
+# TODO: declare customized classes instead.
 gen_mini_GetBackgroundBrush = lambda obj:lambda dc: wx.Brush(obj.GetParent().GetBackgroundColour(), wx.SOLID)
-gen_mini_GetLabelSize = lambda obj:lambda:(wx.lib.buttons.GenBitmapTextButton._GetLabelSize(obj)[:-1] + (False,))
 gen_textbutton_GetLabelSize = lambda obj:lambda:(wx.lib.buttons.GenButton._GetLabelSize(obj)[:-1] + (False,))
 
 def make_genbitmaptogglebutton_flat(button):
@@ -69,16 +70,45 @@
     button.SetBezelWidth(0)
     button.SetUseFocusIndicator(False)
 
-def GenerateEmptyBitmap(width, height, color):
-#    bitmap = wx.EmptyBitmap(width, height)
-#    dc = wx.MemoryDC(bitmap)
-#    dc.SetPen(wx.Pen(color))
-#    dc.SetBrush(wx.Brush(color))
-#    dc.DrawRectangle(0, 0, width, height)
-#    return bitmap
-    return wx.Bitmap(os.path.join(CWD, "images", "empty.png"))
+# Patch wx.lib.imageutils so that gray is supported on alpha images
+import wx.lib.imageutils
+def grayOut(anImage):
+    """
+    Convert the given image (in place) to a grayed-out
+    version, appropriate for a 'disabled' appearance.
+    """
+    factor = 0.7        # 0 < f < 1.  Higher is grayer.
+    if anImage.HasMask():
+        maskColor = (anImage.GetMaskRed(), anImage.GetMaskGreen(), anImage.GetMaskBlue())
+    else:
+        maskColor = None
+
+    if anImage.HasAlpha():
+        AlphaData = anImage.GetAlphaData()
+    else :
+        AlphaData = None
+
+    data = map(ord, list(anImage.GetData()))
+         
+    for i in range(0, len(data), 3):
+        pixel = (data[i], data[i+1], data[i+2])
+        pixel = wx.lib.imageutils.makeGray(pixel, factor, maskColor)
+        for x in range(3):
+            data[i+x] = pixel[x]
+    anImage.SetData(''.join(map(chr, data)))
+
+    if AlphaData is not None:
+        anImage.SetAlphaData(AlphaData)
+
+wx.lib.imageutils.grayOut = grayOut
+
+class GenBitmapTextButton(wx.lib.buttons.GenBitmapTextButton):
+    def _GetLabelSize(self):
+        return wx.lib.buttons.GenBitmapTextButton._GetLabelSize(self)[:-1] + (False,)
 
 class GenStaticBitmap(wx.lib.statbmp.GenStaticBitmap):
+    """ Customized GenStaticBitmap, fix transparency redraw bug on wx2.8/win32, 
+    and accept image name as __init__ parameter, fail silently if file do not exist"""
     def __init__(self, parent, ID, bitmapname,
                  pos = wx.DefaultPosition, size = wx.DefaultSize,
                  style = 0,
@@ -407,6 +437,7 @@
                 maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, xstart, ystart)
 
     def RefreshPLCParams(self):
+        self.Freeze()
         self.ClearSizer(self.PLCParamsSizer)
         
         if self.PluginRoot.HasProjectOpened():
@@ -483,6 +514,7 @@
         
         self.PLCConfigMainSizer.Layout()
         self.RefreshScrollBars()
+        self.Thaw()
 
 #    def GenerateAddButtonSizer(self, plugin, parent, horizontal = True):
 #        if horizontal:
@@ -512,18 +544,19 @@
         for plugin_method in plugin.PluginMethods:
             if "method" in plugin_method:
                 id = wx.NewId()
-                button = wx.lib.buttons.GenBitmapTextButton(id=id, parent=parent,
+                button = GenBitmapTextButton(id=id, parent=parent,
                     bitmap=wx.Bitmap(os.path.join(CWD, "%s24x24.png"%plugin_method.get("bitmap", os.path.join("images", "Unknown")))), label=plugin_method["name"], 
                     name=plugin_method["name"], pos=wx.DefaultPosition, style=wx.NO_BORDER)
                 button.SetToolTipString(plugin_method["tooltip"])
                 button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(plugin, plugin_method["method"]), id=id)
                 #hack to force size to mini
-                button._GetLabelSize = gen_mini_GetLabelSize(button)
-                #button._GetLabelSize = lambda :(-1,-1,False)
+                if not plugin_method.get("enabled",True):
+                    button.Disable()
                 msizer.AddWindow(button, 0, border=0, flag=0)
         return msizer
 
     def RefreshPluginTree(self):
+        self.Freeze()
         self.ClearSizer(self.PluginTreeSizer)
         if self.PluginRoot.HasProjectOpened():
             index = [0]
@@ -533,6 +566,7 @@
                     self.CollapsePlugin(child)
         self.PLCConfigMainSizer.Layout()
         self.RefreshScrollBars()
+        self.Thaw()
 
     def ExpandPlugin(self, plugin, force = False):
         for child in self.PluginInfos[plugin]["children"]:
@@ -583,10 +617,6 @@
         rolesizer = wx.BoxSizer(wx.HORIZONTAL)
         leftsizer.AddSizer(rolesizer, 0, border=0, flag=wx.GROW|wx.RIGHT)
 
-        roletext = wx.StaticText(leftwindow, -1)
-        roletext.SetLabel(plugin.PlugHelp)
-        rolesizer.AddWindow(roletext, 0, border=5, flag=wx.RIGHT|wx.ALIGN_LEFT)
-
         enablebutton_id = wx.NewId()
         enablebutton = wx.lib.buttons.GenBitmapToggleButton(id=enablebutton_id, bitmap=wx.Bitmap(os.path.join(CWD, 'images', 'Disabled.png')),
               name='EnableButton', parent=leftwindow, size=wx.Size(16, 16), pos=wx.Point(0, 0), style=0)#wx.NO_BORDER)
@@ -602,6 +632,9 @@
         enablebutton.Bind(wx.EVT_BUTTON, toggleenablebutton, id=enablebutton_id)
         rolesizer.AddWindow(enablebutton, 0, border=0, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
 
+        roletext = wx.StaticText(leftwindow, -1)
+        roletext.SetLabel(plugin.PlugHelp)
+        rolesizer.AddWindow(roletext, 0, border=5, flag=wx.RIGHT|wx.ALIGN_LEFT)
         
         plugin_IECChannel = plugin.BaseParams.getIEC_Channel()
         
@@ -805,7 +838,11 @@
                 infos["variable_list"].Append(location["NAME"].replace("__", "%").replace("_", "."))
         self.PLCConfigMainSizer.Layout()
         self.RefreshScrollBars()
-
+        
+    def RefreshAll(self):
+        self.RefreshPLCParams()
+        self.RefreshPluginTree()
+        
     def GetItemChannelChangedFunction(self, plugin, value):
         def OnPluginTreeItemChannelChanged(event):
             res, StructChanged = plugin.SetParamsAttribute("BaseParams.IEC_Channel", value, self.Log)
@@ -834,7 +871,8 @@
     def GetButtonCallBackFunction(self, plugin, method):
         def OnButtonClick(event):
             getattr(plugin,method)(self.Log)
-            self.RefreshVariableLists()
+            #self.RefreshVariableLists()
+            wx.CallAfter(self.RefreshAll)
             event.Skip()
         return OnButtonClick
     
@@ -1166,7 +1204,7 @@
 
 Max_Traceback_List_Size = 20
 
-def Display_Exception_Dialog(e_type,e_value,e_tb):
+def Display_Exception_Dialog(e_type, e_value, e_tb, bug_report_path):
     trcbck_lst = []
     for i,line in enumerate(traceback.extract_tb(e_tb)):
         trcbck = " " + str(i+1) + ". "
@@ -1184,17 +1222,16 @@
 
     dlg = wx.SingleChoiceDialog(None, 
         """
-An error happens.
-
-Click on OK for saving an error report.
-
-Please contact LOLITech at:
-+33 (0)3 29 52 95 67
-bugs_Beremiz@lolitech.fr
-
-
-Error:
-""" +
+An unhandled exception (bug) occured. Bug report saved at :
+(%s)
+
+Please be kind enough to send this file to:
+bugs_beremiz@lolitech.fr
+
+You should now restart Beremiz.
+
+Traceback:
+""" % bug_report_path +
         str(e_type) + " : " + str(e_value), 
         "Error",
         trcbck_lst)
@@ -1231,7 +1268,9 @@
         if str(e_value).startswith("!!!"):
             Display_Error_Dialog(e_value)
         elif ex not in ignored_exceptions:
-            result = Display_Exception_Dialog(e_type,e_value,e_traceback)
+            date = time.ctime()
+            bug_report_path = path+os.sep+"bug_report_"+date.replace(':','-').replace(' ','_')+".txt"
+            result = Display_Exception_Dialog(e_type,e_value,e_traceback,bug_report_path)
             if result:
                 ignored_exceptions.append(ex)
                 info = {
@@ -1243,7 +1282,7 @@
                     'platform' : platform.platform(),
                     'e-type' : e_type,
                     'e-value' : e_value,
-                    'date' : time.ctime(),
+                    'date' : date,
                     'cwd' : os.getcwd(),
                     }
                 if e_traceback:
@@ -1254,7 +1293,7 @@
                     if 'self' in exception_locals:
                         info['self'] = format_namespace(exception_locals['self'].__dict__)
                 
-                output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
+                output = open(bug_report_path,'w')
                 lst = info.keys()
                 lst.sort()
                 for a in lst:
--- a/plugger.py	Fri Feb 22 15:40:18 2008 +0100
+++ b/plugger.py	Fri Feb 22 19:04:01 2008 +0100
@@ -532,6 +532,13 @@
                 #except Exception, e:
                 #    logger.write_error("Could not add child \"%s\", type %s :\n%s\n"%(pname, ptype, str(e)))
 
+    def EnableMethod(self, method, value):
+        for d in self.PluginMethods:
+            if d["method"]==method:
+                d["enabled"]=value
+                return True
+        return False
+
 def _GetClassFunction(name):
     def GetRootClass():
         return getattr(__import__("plugins." + name), name).RootClass
@@ -968,9 +975,10 @@
         status, result, err_result = logger.LogCommand("\"%s\" \"%s\" -o \"%s\" %s"%(linker, '" "'.join(objs), exe_path, ' '.join(LDFLAGS+[_LDFLAGS])))
         if status != 0:
             logger.write_error("Build failed\n")
+            self.EnableMethod("_Run", False)
             return False
         
-        
+        self.EnableMethod("_Run", True)
         return True
         
 
@@ -1060,10 +1068,12 @@
          "method" : "_Clean"},
         {"bitmap" : os.path.join("images", "Run"),
          "name" : "Run",
+         "enabled" : False,
          "tooltip" : "Run PLC from build folder",
          "method" : "_Run"},
         {"bitmap" : os.path.join("images", "Stop"),
          "name" : "Stop",
+         "enabled" : False,
          "tooltip" : "Stop Running PLC",
          "method" : "_Stop"},
         {"bitmap" : os.path.join("images", "ShowIECcode"),