chiark / gitweb /
Add more documentation...
authordaid <daid303@gmail.com>
Tue, 4 Feb 2014 08:36:51 +0000 (09:36 +0100)
committerdaid <daid303@gmail.com>
Tue, 4 Feb 2014 08:36:51 +0000 (09:36 +0100)
Cura/avr_isp/chipDB.py
Cura/avr_isp/intelHex.py
Cura/doctest.py [new file with mode: 0644]
Cura/gui/tools/batchRun.py [deleted file]
Cura/gui/tools/minecraftImport.py
Cura/gui/util/toolbarUtil.py [deleted file]

index 6ce1ddcf0e2c62b7c3763c77612a2ce7471b0c24..b28906aea6e267f63c1a8aa3447a05ee7a042c09 100644 (file)
@@ -1,3 +1,7 @@
+"""
+Database of AVR chips for avr_isp programming. Contains signatures and flash sizes from the AVR datasheets.
+To support more chips add the relevant data to the avrChipDB list.
+"""
 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
 
 avrChipDB = {
index aa64e186b32e6704783f33e8f63bda388544614c..91422ad582a6a2a6d2db0d9e06f69c4bd8d03988 100644 (file)
@@ -1,3 +1,8 @@
+"""
+Module to read intel hex files into binary data blobs.
+IntelHex files are commonly used to distribute firmware
+See: http://en.wikipedia.org/wiki/Intel_HEX
+"""
 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
 import io
 
diff --git a/Cura/doctest.py b/Cura/doctest.py
new file mode 100644 (file)
index 0000000..18139c0
--- /dev/null
@@ -0,0 +1,83 @@
+"""
+A helper file to check which parts of the code have documentation and which are lacking documentation.
+This because much of the Cura code is currently undocumented which needs to be improved.'
+"""
+import os
+import traceback
+import glob
+import sys
+import inspect
+import types
+import random
+
+def treeWalk(moduleList, dirname, fnames):
+       dirname = dirname.replace("\\", ".").replace("/", ".")
+       if dirname == 'Cura.util.pymclevel':
+               return
+       if dirname == 'Cura.util.Power':
+               return
+       if dirname == 'Cura.plugins':
+               return
+       if dirname == 'Cura.resouces':
+               return
+       for moduleName in filter(lambda f: f.endswith('.py'), fnames):
+               moduleName = moduleName[:-3]
+               if moduleName == '__init__':
+                       continue
+               fullName = '%s.%s' % (dirname, moduleName)
+               try:
+                       module = __import__(fullName, fromlist=['Cura'], level=1)
+                       moduleList.append(module)
+               except:
+                       #traceback.print_exc()
+                       print "Failed to load: %s" % (fullName)
+
+def main():
+       moduleList = []
+       os.path.walk("Cura", treeWalk, moduleList)
+       moduleDocCount = 0
+       functionCount = 0
+       functionDocCount = 0
+       typeCount = 0
+       typeDocCount = 0
+       undocList = []
+       for module in moduleList:
+               if inspect.getdoc(module):
+                       moduleDocCount += 1
+               else:
+                       undocList.append(module.__name__)
+               for name in dir(module):
+                       a = getattr(module, name)
+                       if type(a) is types.FunctionType:
+                               functionCount += 1
+                               if inspect.getdoc(a):
+                                       functionDocCount += 1
+                               # else:
+                               #       undocList.append('%s.%s' % (module.__name__, name))
+                       elif type(a) is types.TypeType:
+                               typeCount += 1
+                               if inspect.getdoc(a):
+                                       typeDocCount += 1
+                               # else:
+                               #       undocList.append('%s.%s' % (module.__name__, name))
+                               for name2 in dir(a):
+                                       a2 = getattr(a, name2)
+                                       if type(a2) is types.MethodType:
+                                               if hasattr(a.__bases__[0], name2):
+                                                       continue
+                                               functionCount += 1
+                                               if inspect.getdoc(a2):
+                                                       functionDocCount += 1
+                                               # else:
+                                               #       undocList.append('%s.%s.%s' % (module.__name__, name, name2))
+
+       print '%d/%d modules have documentation.' % (moduleDocCount, len(moduleList))
+       print '%d/%d functions have documentation.' % (functionDocCount, functionCount)
+       print '%d/%d types have documentation.' % (typeDocCount, typeCount)
+       print ''
+       print 'You might want to document:'
+       for n in xrange(0, 10):
+               print random.Random().choice(undocList)
+
+if __name__ == '__main__':
+       main()
diff --git a/Cura/gui/tools/batchRun.py b/Cura/gui/tools/batchRun.py
deleted file mode 100644 (file)
index 5a3078d..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
-
-import wx, os, multiprocessing, threading, time, shutil
-
-from Cura.util import profile
-from Cura.util import sliceRun
-from Cura.util import meshLoader
-from Cura.util import gcodeInterpreter
-from Cura.gui.util import dropTarget
-
-class batchRunWindow(wx.Frame):
-       def __init__(self, parent):
-               super(batchRunWindow, self).__init__(parent, title=_("Cura - Batch run"))
-               
-               self.list = []
-               
-               self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.loadSupportedExtensions() + ['.g', '.gcode']))
-               
-               wx.EVT_CLOSE(self, self.OnClose)
-               self.panel = wx.Panel(self, -1)
-               self.SetSizer(wx.BoxSizer(wx.VERTICAL))
-               self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND)
-
-               self.sizer = wx.GridBagSizer(2,2)
-               self.panel.SetSizer(self.sizer)
-
-               self.listbox = wx.ListBox(self.panel, -1, choices=[])
-               self.addButton = wx.Button(self.panel, -1, _("Add"))
-               self.remButton = wx.Button(self.panel, -1, _("Remove"))
-               self.sliceButton = wx.Button(self.panel, -1, _("Prepare all"))
-
-               self.addButton.Bind(wx.EVT_BUTTON, self.OnAddModel)
-               self.remButton.Bind(wx.EVT_BUTTON, self.OnRemModel)
-               self.sliceButton.Bind(wx.EVT_BUTTON, self.OnSlice)
-               self.listbox.Bind(wx.EVT_LISTBOX, self.OnListSelect)
-
-               self.sizer.Add(self.listbox, (0,0), span=(1,3), flag=wx.EXPAND)
-               self.sizer.Add(self.addButton, (1,0), span=(1,1))
-               self.sizer.Add(self.remButton, (1,1), span=(1,1))
-               self.sizer.Add(self.sliceButton, (1,2), span=(1,1))
-
-               self.sizer.AddGrowableCol(2)
-               self.sizer.AddGrowableRow(0)
-
-       def OnAddModel(self, e):
-               dlg=wx.FileDialog(self, _("Open file to batch prepare"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST|wx.FD_MULTIPLE)
-               dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
-               if dlg.ShowModal() == wx.ID_OK:
-                       for filename in dlg.GetPaths():
-                               profile.putPreference('lastFile', filename)
-                               self.list.append(filename)
-                               self.selection = filename
-                               self._updateListbox()
-               dlg.Destroy()
-       
-       def OnDropFiles(self, filenames):
-               for filename in filenames:
-                       profile.putPreference('lastFile', filename)
-                       self.list.append(filename)
-                       self.selection = filename
-                       self._updateListbox()
-
-       def OnRemModel(self, e):
-               if self.selection is None:
-                       return
-               self.list.remove(self.selection)
-               self._updateListbox()
-
-       def OnListSelect(self, e):
-               if self.listbox.GetSelection() == -1:
-                       return
-               self.selection = self.list[self.listbox.GetSelection()]
-
-       def _updateListbox(self):
-               self.listbox.Clear()
-               for item in self.list:
-                       self.listbox.AppendAndEnsureVisible(os.path.split(item)[1])
-               if self.selection in self.list:
-                       self.listbox.SetSelection(self.list.index(self.selection))
-               elif len(self.list) > 0:
-                       self.selection = self.list[0]
-                       self.listbox.SetSelection(0)
-               else:
-                       self.selection = None
-                       self.listbox.SetSelection(-1)
-
-       def OnClose(self, e):
-               self.Destroy()
-
-       def OnSlice(self, e):
-               sliceCmdList = []
-               outputFilenameList = []
-               center = profile.getMachineCenterCoords() + profile.getObjectMatrix()
-               for filename in self.list:
-                       outputFilename = sliceRun.getExportFilename(filename)
-                       outputFilenameList.append(outputFilename)
-                       sliceCmdList.append(sliceRun.getSliceCommand(outputFilename, [filename], [center]))
-               bspw = BatchSliceProgressWindow(self.list[:], outputFilenameList, sliceCmdList)
-               bspw.Centre()
-               bspw.Show(True)
-       
-class BatchSliceProgressWindow(wx.Frame):
-       def __init__(self, filenameList, outputFilenameList, sliceCmdList):
-               super(BatchSliceProgressWindow, self).__init__(None, title='Cura')
-               self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
-               
-               self.filenameList = filenameList
-               self.outputFilenameList = outputFilenameList
-               self.sliceCmdList = sliceCmdList
-               self.abort = False
-               self.sliceStartTime = time.time()
-
-               try:
-                       self.threadCount = multiprocessing.cpu_count() - 1
-               except:
-                       self.threadCount = 1
-               if self.threadCount < 1:
-                       self.threadCount = 1
-               if self.threadCount > len(self.sliceCmdList):
-                       self.threadCount = len(self.sliceCmdList)
-               self.cmdIndex = 0
-               
-               self.prevStep = []
-               self.totalDoneFactor = []
-               for i in xrange(0, self.threadCount):
-                       self.prevStep.append('start')
-                       self.totalDoneFactor.append(0.0)
-
-               self.sizer = wx.GridBagSizer(2, 2) 
-               self.progressGauge = []
-               self.statusText = []
-               for i in xrange(0, self.threadCount):
-                       self.statusText.append(wx.StaticText(self, -1, _("Building: %d                           ") % (len(self.sliceCmdList))))
-                       self.progressGauge.append(wx.Gauge(self, -1))
-                       self.progressGauge[i].SetRange(10000)
-               self.progressTextTotal = wx.StaticText(self, -1, _("Done: 0/%d                           ") % (len(self.sliceCmdList)))
-               self.progressGaugeTotal = wx.Gauge(self, -1)
-               self.progressGaugeTotal.SetRange(len(self.sliceCmdList))
-               self.abortButton = wx.Button(self, -1, _("Abort"))
-               for i in xrange(0, self.threadCount):
-                       self.sizer.Add(self.statusText[i], (i*2,0), span=(1,4))
-                       self.sizer.Add(self.progressGauge[i], (1+i*2, 0), span=(1,4), flag=wx.EXPAND)
-               self.sizer.Add(self.progressTextTotal, (self.threadCount*2,0), span=(1,4))
-               self.sizer.Add(self.progressGaugeTotal, (1+self.threadCount*2, 0), span=(1,4), flag=wx.EXPAND)
-
-               self.sizer.Add(self.abortButton, (2+self.threadCount*2,0), span=(1,4), flag=wx.ALIGN_CENTER)
-               self.sizer.AddGrowableCol(0)
-               self.sizer.AddGrowableRow(0)
-
-               self.Bind(wx.EVT_BUTTON, self.OnAbort, self.abortButton)
-               self.SetSizer(self.sizer)
-               self.Layout()
-               self.Fit()
-               
-               threading.Thread(target=self.OnRunManager).start()
-
-       def OnAbort(self, e):
-               if self.abort:
-                       self.Close()
-               else:
-                       self.abort = True
-                       self.abortButton.SetLabel(_("Close"))
-
-       def SetProgress(self, index, stepName, layer, maxLayer):
-               if self.prevStep[index] != stepName:
-                       self.totalDoneFactor[index] += sliceRun.sliceStepTimeFactor[self.prevStep[index]]
-                       newTime = time.time()
-                       self.prevStep[index] = stepName
-               
-               progresValue = ((self.totalDoneFactor[index] + sliceRun.sliceStepTimeFactor[stepName] * layer / maxLayer) / sliceRun.totalRunTimeFactor) * 10000
-               self.progressGauge[index].SetValue(int(progresValue))
-               self.statusText[index].SetLabel(stepName + " [" + str(layer) + "/" + str(maxLayer) + "]")
-       
-       def OnRunManager(self):
-               threads = []
-               for i in xrange(0, self.threadCount):
-                       threads.append(threading.Thread(target=self.OnRun, args=(i,)))
-
-               for t in threads:
-                       t.start()
-               for t in threads:
-                       t.join()
-
-               self.abort = True
-               sliceTime = time.time() - self.sliceStartTime
-               status = _("Build: %d models") % (len(self.sliceCmdList))
-               status += _("\nSlicing took: %(hours)02d:%(minutes)02d") % (sliceTime / 60, sliceTime % 60)
-
-               wx.CallAfter(self.statusText[0].SetLabel, status)
-               wx.CallAfter(self.OnSliceDone)
-       
-       def OnRun(self, index):
-               while self.cmdIndex < len(self.sliceCmdList):
-                       cmdIndex = self.cmdIndex;
-                       self.cmdIndex += 1                      
-                       action = self.sliceCmdList[cmdIndex]
-                       wx.CallAfter(self.SetTitle, _("Building: [%(index)d/%(size)d]")  % (self.sliceCmdList.index(action) + 1, len(self.sliceCmdList)))
-
-                       p = sliceRun.startSliceCommandProcess(action)
-                       line = p.stdout.readline()
-                       maxValue = 1
-                       while(len(line) > 0):
-                               line = line.rstrip()
-                               if line[0:9] == "Progress[" and line[-1:] == "]":
-                                       progress = line[9:-1].split(":")
-                                       if len(progress) > 2:
-                                               maxValue = int(progress[2])
-                                       wx.CallAfter(self.SetProgress, index, progress[0], int(progress[1]), maxValue)
-                               else:
-                                       wx.CallAfter(self.statusText[index].SetLabel, line)
-                               if self.abort:
-                                       p.terminate()
-                                       wx.CallAfter(self.statusText[index].SetLabel, _("Aborted by user."))
-                                       return
-                               line = p.stdout.readline()
-                       self.returnCode = p.wait()
-
-                       # Update output gocde file...
-                       # Warning: the user could have changed the profile between the slcer run and this code.  We might be using old information.
-                       gcodeFilename = self.outputFilenameList[index]
-                       gcode = gcodeInterpreter.gcode()
-                       gcode.load(gcodeFilename)
-                       profile.replaceGCodeTags(gcodeFilename, gcode)
-                       
-                       wx.CallAfter(self.progressGauge[index].SetValue, 10000)
-                       self.totalDoneFactor[index] = 0.0
-                       wx.CallAfter(self.progressTextTotal.SetLabel, _("Done %(index)d/%(size)d") % (self.cmdIndex, len(self.sliceCmdList)))
-                       wx.CallAfter(self.progressGaugeTotal.SetValue, self.cmdIndex)
-       
-       def OnSliceDone(self):
-               self.abortButton.Destroy()
-               self.closeButton = wx.Button(self, -1, _("Close"))
-               self.sizer.Add(self.closeButton, (2+self.threadCount*2,0), span=(1,1))
-               if profile.getPreference('sdpath') != '':
-                       self.copyToSDButton = wx.Button(self, -1, _("To SDCard"))
-                       self.Bind(wx.EVT_BUTTON, self.OnCopyToSD, self.copyToSDButton)
-                       self.sizer.Add(self.copyToSDButton, (2+self.threadCount*2,1), span=(1,1))
-               self.Bind(wx.EVT_BUTTON, self.OnAbort, self.closeButton)
-               self.Layout()
-               self.Fit()
-
-       def OnCopyToSD(self, e):
-               for f in self.filenameList:
-                       exportFilename = sliceRun.getExportFilename(f)
-                       filename = os.path.basename(exportFilename)
-                       if profile.getPreference('sdshortnames') == 'True':
-                               filename = sliceRun.getShortFilename(filename)
-                       shutil.copy(exportFilename, os.path.join(profile.getPreference('sdpath'), filename))
index d63e977ba3ee08258cf97f4a7ad132def6c9e994..16b86aa45d2b05406e3f47d40484f1fc1296c30a 100644 (file)
@@ -1,3 +1,7 @@
+"""
+Tool to import sections of minecraft levels into Cura.
+This makes use of the pymclevel module from David Rio Vierra
+"""
 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
 
 import wx
diff --git a/Cura/gui/util/toolbarUtil.py b/Cura/gui/util/toolbarUtil.py
deleted file mode 100644 (file)
index 44a33f1..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
-from __future__ import division
-
-import wx
-from wx.lib import buttons
-
-from Cura.util import profile
-from Cura.util.resources import getPathForImage
-
-
-#######################################################
-# toolbarUtil contains help classes and functions for
-# toolbar buttons.
-#######################################################
-
-class Toolbar(wx.ToolBar):
-       def __init__(self, parent):
-               super(Toolbar, self).__init__(parent, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER)
-               self.SetToolBitmapSize(( 21, 21 ))
-
-               if not hasattr(parent, 'popup'):
-                       # Create popup window
-                       parent.popup = wx.PopupWindow(parent, flags=wx.BORDER_SIMPLE)
-                       parent.popup.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
-                       parent.popup.text = wx.StaticText(parent.popup, -1, '')
-                       parent.popup.sizer = wx.BoxSizer()
-                       parent.popup.sizer.Add(parent.popup.text, flag=wx.EXPAND | wx.ALL, border=1)
-                       parent.popup.SetSizer(parent.popup.sizer)
-                       parent.popup.owner = None
-
-       def OnPopupDisplay(self, e):
-               self.UpdatePopup(e.GetEventObject())
-               self.GetParent().popup.Show(True)
-
-       def OnPopupHide(self, e):
-               if self.GetParent().popup.owner == e.GetEventObject():
-                       self.GetParent().popup.Show(False)
-
-       def UpdatePopup(self, control):
-               popup = self.GetParent().popup
-               popup.owner = control
-               popup.text.SetLabel(control.helpText)
-               popup.text.Wrap(350)
-               popup.Fit();
-               x, y = control.ClientToScreenXY(0, 0)
-               sx, sy = control.GetSizeTuple()
-               popup.SetPosition((x, y + sy))
-
-
-class ToggleButton(buttons.GenBitmapToggleButton):
-       def __init__(self, parent, profileSetting, bitmapFilenameOn, bitmapFilenameOff,
-                    helpText='', id=-1, callback=None, size=(20, 20)):
-               self.bitmapOn = wx.Bitmap(getPathForImage(bitmapFilenameOn))
-               self.bitmapOff = wx.Bitmap(getPathForImage(bitmapFilenameOff))
-
-               super(ToggleButton, self).__init__(parent, id, self.bitmapOff, size=size)
-
-               self.callback = callback
-               self.profileSetting = profileSetting
-               self.helpText = helpText
-
-               self.SetBezelWidth(1)
-               self.SetUseFocusIndicator(False)
-
-               if self.profileSetting != '':
-                       self.SetValue(profile.getProfileSetting(self.profileSetting) == 'True')
-                       self.Bind(wx.EVT_BUTTON, self.OnButtonProfile)
-               else:
-                       self.Bind(wx.EVT_BUTTON, self.OnButton)
-
-               self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
-               self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeave)
-
-               parent.AddControl(self)
-
-       def SetBitmap(self, boolValue):
-               if boolValue:
-                       self.SetBitmapLabel(self.bitmapOn, False)
-               else:
-                       self.SetBitmapLabel(self.bitmapOff, False)
-
-       def SetValue(self, boolValue):
-               self.SetBitmap(boolValue)
-               super(ToggleButton, self).SetValue(boolValue)
-
-       def OnButton(self, event):
-               self.SetBitmap(self.GetValue())
-               if self.callback != None:
-                       self.callback()
-               event.Skip()
-
-       def OnButtonProfile(self, event):
-               if buttons.GenBitmapToggleButton.GetValue(self):
-                       self.SetBitmap(True)
-                       profile.putProfileSetting(self.profileSetting, 'True')
-               else:
-                       self.SetBitmap(False)
-                       profile.putProfileSetting(self.profileSetting, 'False')
-               if self.callback != None:
-                       self.callback()
-               event.Skip()
-
-       def OnMouseEnter(self, event):
-               self.GetParent().OnPopupDisplay(event)
-               self.SetBitmap(True)
-               self.Refresh()
-               event.Skip()
-
-       def OnMouseLeave(self, event):
-               self.GetParent().OnPopupHide(event)
-               self.SetBitmap(self.GetValue())
-               self.Refresh()
-               event.Skip()
-
-
-class RadioButton(buttons.GenBitmapButton):
-       def __init__(self, parent, group, bitmapFilenameOn, bitmapFilenameOff,
-                    helpText='', id=-1, callback=None):
-               self.bitmapOn = wx.Bitmap(getPathForImage(bitmapFilenameOn))
-               self.bitmapOff = wx.Bitmap(getPathForImage(bitmapFilenameOff))
-
-               super(RadioButton, self).__init__(parent, id, self.bitmapOff, size=self.bitmapOn.GetSize() + (4, 4))
-
-               self.group = group
-               group.append(self)
-               self.callback = callback
-               self.helpText = helpText
-               self._value = False
-
-               self.SetBezelWidth(1)
-               self.SetUseFocusIndicator(False)
-
-               self.Bind(wx.EVT_BUTTON, self.OnButton)
-
-               self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
-               self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeave)
-
-               if len(group) == 1:
-                       self.SetValue(True)
-
-               parent.AddControl(self)
-
-       def SetBitmap(self, boolValue):
-               if boolValue:
-                       self.SetBitmapLabel(self.bitmapOn, False)
-               else:
-                       self.SetBitmapLabel(self.bitmapOff, False)
-               self.Refresh()
-
-       def SetValue(self, boolValue):
-               self._value = boolValue
-               self.SetBitmap(self.GetValue())
-               if boolValue:
-                       for other in self.group:
-                               if other != self:
-                                       other.SetValue(False)
-
-       def GetValue(self):
-               return self._value
-
-       def OnButton(self, event):
-               self.SetValue(True)
-               self.callback()
-               event.Skip()
-
-       def OnMouseEnter(self, event):
-               self.GetParent().OnPopupDisplay(event)
-               self.SetBitmap(True)
-               self.Refresh()
-               event.Skip()
-
-       def OnMouseLeave(self, event):
-               self.GetParent().OnPopupHide(event)
-               self.SetBitmap(self.GetValue())
-               self.Refresh()
-               event.Skip()
-
-
-class NormalButton(buttons.GenBitmapButton):
-       def __init__(self, parent, callback, bitmapFilename,
-                    helpText='', id=-1, size=(20, 20)):
-               self.bitmap = wx.Bitmap(getPathForImage(bitmapFilename))
-               super(NormalButton, self).__init__(parent, id, self.bitmap, size=size)
-
-               self.helpText = helpText
-               self.callback = callback
-
-               self.SetBezelWidth(1)
-               self.SetUseFocusIndicator(False)
-
-               self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
-               self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeave)
-
-               self.Bind(wx.EVT_BUTTON, self.OnButton)
-
-               parent.AddControl(self)
-
-       def OnButton(self, event):
-               self.GetParent().OnPopupHide(event)
-               self.callback(event)
-
-       def OnMouseEnter(self, event):
-               self.GetParent().OnPopupDisplay(event)
-               event.Skip()
-
-       def OnMouseLeave(self, event):
-               self.GetParent().OnPopupHide(event)
-               event.Skip()
-