--- a/Beremiz.py Mon May 21 02:49:53 2012 +0200
+++ b/Beremiz.py Mon May 21 10:04:27 2012 +0200
@@ -156,14 +156,14 @@
import cPickle
from util.BrowseValuesLibraryDialog import BrowseValuesLibraryDialog
import types, time, re, platform, time, traceback, commands
-from ProjectController import ProjectController, MATIEC_ERROR_MODEL
+from ProjectController import ProjectController, MATIEC_ERROR_MODEL, ITEM_CONFNODE
from util.MiniTextControler import MiniTextControler
from util.ProcessLogger import ProcessLogger
from docutil import OpenHtmlFrame
from PLCOpenEditor import IDEFrame, AppendMenu, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES
from PLCOpenEditor import EditorPanel, Viewer, TextViewer, GraphicViewer, ResourceEditor, ConfigurationEditor, DataTypeEditor
-from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
+from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY, ITEM_PROJECT, ITEM_RESOURCE
SCROLLBAR_UNIT = 10
WINDOW_COLOUR = wx.Colour(240,240,240)
@@ -452,6 +452,17 @@
(wx.ID_SAVEAS, "saveas.png", _(u'Save As...'), None),
(wx.ID_PRINT, "print.png", _(u'Print'), None)])
+ def _init_coll_AddMenu_Items(self, parent):
+ IDEFrame._init_coll_AddMenu_Items(self, parent, False)
+ new_id = wx.NewId()
+ AppendMenu(parent, help='', id=new_id,
+ kind=wx.ITEM_NORMAL, text=_(u'&Resource'))
+ for name, XSDClass, help in ProjectController.CTNChildrenTypes:
+ new_id = wx.NewId()
+ AppendMenu(parent, help='', id=new_id,
+ kind=wx.ITEM_NORMAL, text=help)
+ self.Bind(wx.EVT_MENU, self._GetAddConfNodeFunction(name), id=new_id)
+
def _init_coll_HelpMenu_Items(self, parent):
parent.Append(help='', id=wx.ID_ABOUT,
kind=wx.ITEM_NORMAL, text=_(u'About'))
@@ -495,7 +506,7 @@
def OnMethod(evt):
if obj.CTR is not None:
obj.CTR.CallMethod('_'+meth)
- wx.CallAfter(self.RefreshAll)
+ wx.CallAfter(self.RefreshStatusToolBar)
return OnMethod
newid = wx.NewId()
self.Bind(wx.EVT_MENU, OnMethodGen(self,method), id=newid)
@@ -510,8 +521,8 @@
self.PLCConfig.Bind(wx.EVT_LEFT_DOWN, self.OnPanelLeftDown)
self.PLCConfig.Bind(wx.EVT_SIZE, self.OnMoveWindow)
self.PLCConfig.Bind(wx.EVT_MOUSEWHEEL, self.OnPLCConfigScroll)
- self.MainTabs["PLCConfig"] = (self.PLCConfig, _("Topology"))
- self.BottomNoteBook.InsertPage(0, self.PLCConfig, _("Topology"), True)
+ #self.MainTabs["PLCConfig"] = (self.PLCConfig, _("Topology"))
+ #self.BottomNoteBook.InsertPage(0, self.PLCConfig, _("Topology"), True)
self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
name='LogConsole', parent=self.BottomNoteBook, pos=wx.Point(0, 0),
@@ -520,9 +531,21 @@
self.MainTabs["LogConsole"] = (self.LogConsole, _("Log Console"))
self.BottomNoteBook.AddPage(*self.MainTabs["LogConsole"])
self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogConsole), wx.RIGHT)
+
+ StatusToolBar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
+ wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
+ StatusToolBar.SetToolBitmapSize(wx.Size(25, 25))
+ StatusToolBar.Realize()
+ self.Panes["StatusToolBar"] = StatusToolBar
+ self.AUIManager.AddPane(StatusToolBar, wx.aui.AuiPaneInfo().
+ Name("StatusToolBar").Caption(_("Status ToolBar")).
+ ToolbarPane().Top().Position(2).
+ LeftDockable(False).RightDockable(False))
self._init_beremiz_sizers()
+ self.AUIManager.Update()
+
def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True):
IDEFrame.__init__(self, parent, debug)
self.Log = LogPseudoFile(self.LogConsole,self.RiseLogConsole)
@@ -553,6 +576,11 @@
("VAR_LOCAL", LOCATION_VAR_MEMORY)]:
self.LocationImageDict[itemtype]=self.LocationImageList.Add(wx.Bitmap(os.path.join(base_folder, "plcopeneditor", 'Images', '%s.png'%imgname)))
+ # Icons for other items
+ for imgname, itemtype in [
+ ("Extension", ITEM_CONFNODE)]:
+ self.TreeImageDict[itemtype]=self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'images', '%s.png'%imgname)))
+
# Add beremiz's icon in top left corner of the frame
self.SetIcon(wx.Icon(Bpath( "images", "brz.ico"), wx.BITMAP_TYPE_ICO))
@@ -567,10 +595,11 @@
result = self.CTR.LoadProject(projectOpen, buildpath)
if not result:
self.LibraryPanel.SetControler(self.Controler)
+ self.ProjectTree.Enable(True)
self.PouInstanceVariablesPanel.SetController(self.Controler)
self.RefreshConfigRecentProjects(os.path.abspath(projectOpen))
self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
- self.RefreshAll()
+ self.RefreshStatusToolBar()
else:
self.ResetView()
self.ShowErrorMessage(result)
@@ -579,9 +608,10 @@
self.Controler = ctr
if ctr is not None:
self.LibraryPanel.SetControler(self.Controler)
+ self.ProjectTree.Enable(True)
self.PouInstanceVariablesPanel.SetController(self.Controler)
self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
- self.RefreshAll()
+ self.RefreshStatusToolBar()
if self.EnableDebug:
self.DebugVariablePanel.SetDataProducer(self.CTR)
@@ -589,6 +619,7 @@
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
self.RefreshConfNodeMenu()
+ self.RefreshStatusToolBar()
self.LogConsole.SetFocus()
def RiseLogConsole(self):
@@ -823,6 +854,26 @@
if callback is not None:
self.Bind(wx.EVT_MENU, callback, id=id)
+ def RefreshStatusToolBar(self):
+ StatusToolBar = self.Panes["StatusToolBar"]
+ StatusToolBar.ClearTools()
+
+ if self.CTR is not None:
+
+ for confnode_method in self.CTR.StatusMethods:
+ if "method" in confnode_method and confnode_method.get("shown",True):
+ id = wx.NewId()
+ StatusToolBar.AddSimpleTool(id,
+ wx.Bitmap(Bpath("images", "%s.png"%confnode_method.get("bitmap", "Unknown"))),
+ confnode_method["tooltip"])
+ self.Bind(wx.EVT_MENU, self.GetMenuCallBackFunction(confnode_method["method"]), id=id)
+
+ StatusToolBar.Realize()
+ self.AUIManager.GetPane("StatusToolBar").BestSize(StatusToolBar.GetBestSize()).Show()
+ else:
+ self.AUIManager.GetPane("StatusToolBar").Hide()
+ self.AUIManager.Update()
+
def RefreshConfNodeMenu(self):
if self.CTR is not None:
selected = self.TabsOpened.GetSelection()
@@ -1420,7 +1471,7 @@
event.Skip()
return OnConfNodeTreeItemChannelChanged
- def _GetAddConfNodeFunction(self, name, confnode):
+ def _GetAddConfNodeFunction(self, name, confnode=None):
def OnConfNodeMenu(event):
wx.CallAfter(self.AddConfNode, name, confnode)
return OnConfNodeMenu
@@ -1437,6 +1488,19 @@
main_menu.Destroy()
return AddConfNodeMenu
+ def GetMenuCallBackFunction(self, method):
+ """ Generate the callbackfunc for a given CTR method"""
+ def OnMenu(event):
+ # Disable button to prevent re-entrant call
+ event.GetEventObject().Disable()
+ # Call
+ getattr(self.CTR, method)()
+ # Re-enable button
+ event.GetEventObject().Enable()
+ # Trigger refresh on Idle
+ wx.CallAfter(self.RefreshStatusToolBar)
+ return OnMenu
+
def GetButtonCallBackFunction(self, confnode, method):
""" Generate the callbackfunc for a given confnode method"""
def OnButtonClick(event):
@@ -1656,6 +1720,9 @@
textctrl.Bind(wx.EVT_TEXT, self.GetTextCtrlCallBackFunction(textctrl, confnode, element_path))
first = False
+ def GetConfigEntry(self, entry_name, default):
+ return cPickle.loads(str(self.Config.Read(entry_name, cPickle.dumps(default))))
+
def ResetView(self):
IDEFrame.ResetView(self)
self.ConfNodeInfos = {}
@@ -1695,12 +1762,13 @@
self.CTR = ctr
self.Controler = self.CTR
self.LibraryPanel.SetControler(self.Controler)
+ self.ProjectTree.Enable(True)
self.PouInstanceVariablesPanel.SetController(self.Controler)
self.RefreshConfigRecentProjects(projectpath)
if self.EnableDebug:
self.DebugVariablePanel.SetDataProducer(self.CTR)
self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
- self.RefreshAll()
+ self.RefreshStatusToolBar()
else:
self.ResetView()
self.ShowErrorMessage(result)
@@ -1731,13 +1799,14 @@
result = self.CTR.LoadProject(projectpath)
if not result:
self.LibraryPanel.SetControler(self.Controler)
+ self.ProjectTree.Enable(True)
self.PouInstanceVariablesPanel.SetController(self.Controler)
self.RefreshConfigRecentProjects(projectpath)
if self.EnableDebug:
self.DebugVariablePanel.SetDataProducer(self.CTR)
self.LoadProjectOrganization()
self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE)
- self.RefreshAll()
+ self.RefreshStatusToolBar()
else:
self.ResetView()
self.ShowErrorMessage(result)
@@ -1752,18 +1821,16 @@
self.SaveProjectOrganization()
self.ResetView()
self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)
- self.RefreshAll()
+ self.RefreshStatusToolBar()
def OnSaveProjectMenu(self, event):
if self.CTR is not None:
self.CTR.SaveProject()
- self.RefreshAll()
self._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES)
def OnSaveProjectAsMenu(self, event):
if self.CTR is not None:
self.CTR.SaveProjectAs()
- self.RefreshAll()
self._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES)
event.Skip()
@@ -1784,6 +1851,71 @@
wx.CallAfter(self.RefreshConfNodeMenu)
IDEFrame.OnPageClose(self, event)
+ def OnProjectTreeItemBeginEdit(self, event):
+ selected = event.GetItem()
+ if self.ProjectTree.GetPyData(selected)["type"] in ITEM_CONFNODE:
+ event.Veto()
+ else:
+ IDEFrame.OnProjectTreeItemBeginEdit(self, event)
+
+ def OnProjectTreeRightUp(self, event):
+ if wx.Platform == '__WXMSW__':
+ item = event.GetItem()
+ else:
+ item, flags = self.ProjectTree.HitTest(wx.Point(event.GetX(), event.GetY()))
+ item_infos = self.ProjectTree.GetPyData(item)
+
+ if item_infos["type"] == ITEM_CONFNODE:
+ confnode_menu = wx.Menu(title='')
+
+ confnode = item_infos["confnode"]
+ if confnode is not None and len(confnode.CTNChildrenTypes) > 0:
+ for name, XSDClass, help in confnode.CTNChildrenTypes:
+ new_id = wx.NewId()
+ confnode_menu.Append(help=help, id=new_id, kind=wx.ITEM_NORMAL, text=name)
+ self.Bind(wx.EVT_MENU, self._GetAddConfNodeFunction(name, confnode), id=new_id)
+
+ new_id = wx.NewId()
+ AppendMenu(confnode_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete"))
+ self.Bind(wx.EVT_MENU, self.GetDeleteButtonFunction(confnode), id=new_id)
+
+ self.PopupMenu(confnode_menu)
+ confnode_menu.Destroy()
+
+ event.Skip()
+ else:
+ IDEFrame.OnProjectTreeRightUp(self, event)
+
+ def OnProjectTreeItemActivated(self, event):
+ selected = event.GetItem()
+ name = self.ProjectTree.GetItemText(selected)
+ item_infos = self.ProjectTree.GetPyData(selected)
+ if item_infos["type"] == ITEM_CONFNODE:
+ item_infos["confnode"]._OpenView()
+ event.Skip()
+ elif item_infos["type"] == ITEM_PROJECT:
+ self.CTR._OpenView()
+ else:
+ IDEFrame.OnProjectTreeItemActivated(self, event)
+
+ def SelectProjectTreeItem(self, tagname):
+ if self.ProjectTree is not None:
+ root = self.ProjectTree.GetRootItem()
+ if root.IsOk():
+ words = tagname.split("::")
+ if len(words) == 1:
+ if tagname == "Project":
+ self.SelectedItem = root
+ self.ProjectTree.SelectItem(root)
+ wx.CallAfter(self.ResetSelectedItem)
+ else:
+ return self.RecursiveProjectTreeItemSelection(root,
+ [(word, ITEM_CONFNODE) for word in tagname.split(".")])
+ elif words[0] == "R":
+ return self.RecursiveProjectTreeItemSelection(root, [(words[2], ITEM_RESOURCE)])
+ else:
+ IDEFrame.SelectProjectTreeItem(self, tagname)
+
def GetAddButtonFunction(self, confnode, window):
def AddButtonFunction(event):
if confnode and len(confnode.CTNChildrenTypes) > 0:
@@ -1803,14 +1935,17 @@
event.Skip()
return DeleteButtonFunction
- def AddConfNode(self, ConfNodeType, confnode):
+ def AddConfNode(self, ConfNodeType, confnode=None):
if self.CTR.CheckProjectPathPerm():
dialog = wx.TextEntryDialog(self, _("Please enter a name for confnode:"), _("Add ConfNode"), "", wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
ConfNodeName = dialog.GetValue()
- confnode.CTNAddChild(ConfNodeName, ConfNodeType)
+ if confnode is not None:
+ confnode.CTNAddChild(ConfNodeName, ConfNodeType)
+ else:
+ self.CTR.CTNAddChild(ConfNodeName, ConfNodeType)
self.CTR.RefreshConfNodesBlockLists()
- self._Refresh(TITLE, FILEMENU)
+ self._Refresh(TITLE, FILEMENU, PROJECTTREE)
self.RefreshConfNodeTree()
dialog.Destroy()
@@ -1822,7 +1957,7 @@
confnode.CTNRemove()
del confnode
self.CTR.RefreshConfNodesBlockLists()
- self._Refresh(TITLE, FILEMENU)
+ self._Refresh(TITLE, FILEMENU, PROJECTTREE)
self.RefreshConfNodeTree()
dialog.Destroy()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ConfTreeNodeEditor.py Mon May 21 10:04:27 2012 +0200
@@ -0,0 +1,536 @@
+
+import os
+import types
+
+import wx
+import wx.lib.buttons
+
+from controls import EditorPanel
+
+from PLCOpenEditor import TITLE, FILEMENU, PROJECTTREE, PAGETITLES
+
+from util import opjimg
+from util.TextCtrlAutoComplete import TextCtrlAutoComplete
+from util.BrowseValuesLibraryDialog import BrowseValuesLibraryDialog
+
+if wx.Platform == '__WXMSW__':
+ faces = { 'times': 'Times New Roman',
+ 'mono' : 'Courier New',
+ 'helv' : 'Arial',
+ 'other': 'Comic Sans MS',
+ 'size' : 16,
+ }
+else:
+ faces = { 'times': 'Times',
+ 'mono' : 'Courier',
+ 'helv' : 'Helvetica',
+ 'other': 'new century schoolbook',
+ 'size' : 18,
+ }
+
+SCROLLBAR_UNIT = 10
+WINDOW_COLOUR = wx.Colour(240,240,240)
+
+CWD = os.path.split(os.path.realpath(__file__))[0]
+
+def Bpath(*args):
+ return os.path.join(CWD,*args)
+
+# 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_textbutton_GetLabelSize = lambda obj:lambda:(wx.lib.buttons.GenButton._GetLabelSize(obj)[:-1] + (False,))
+
+def make_genbitmaptogglebutton_flat(button):
+ button.GetBackgroundBrush = gen_mini_GetBackgroundBrush(button)
+ button.labelDelta = 0
+ button.SetBezelWidth(0)
+ button.SetUseFocusIndicator(False)
+
+# Patch wx.lib.imageutils so that gray is supported on alpha images
+import wx.lib.imageutils
+from wx.lib.imageutils import grayOut as old_grayOut
+def grayOut(anImage):
+ if anImage.HasAlpha():
+ AlphaData = anImage.GetAlphaData()
+ else :
+ AlphaData = None
+
+ old_grayOut(anImage)
+
+ if AlphaData is not None:
+ anImage.SetAlphaData(AlphaData)
+
+wx.lib.imageutils.grayOut = grayOut
+
+class GenBitmapTextButton(wx.lib.buttons.GenBitmapTextButton):
+ def _GetLabelSize(self):
+ """ used internally """
+ w, h = self.GetTextExtent(self.GetLabel())
+ if not self.bmpLabel:
+ return w, h, False # if there isn't a bitmap use the size of the text
+
+ w_bmp = self.bmpLabel.GetWidth()+2
+ h_bmp = self.bmpLabel.GetHeight()+2
+ height = h + h_bmp
+ if w_bmp > w:
+ width = w_bmp
+ else:
+ width = w
+ return width, height, False
+
+ def DrawLabel(self, dc, width, height, dw=0, dy=0):
+ bmp = self.bmpLabel
+ if bmp != None: # if the bitmap is used
+ if self.bmpDisabled and not self.IsEnabled():
+ bmp = self.bmpDisabled
+ if self.bmpFocus and self.hasFocus:
+ bmp = self.bmpFocus
+ if self.bmpSelected and not self.up:
+ bmp = self.bmpSelected
+ bw,bh = bmp.GetWidth(), bmp.GetHeight()
+ if not self.up:
+ dw = dy = self.labelDelta
+ hasMask = bmp.GetMask() != None
+ else:
+ bw = bh = 0 # no bitmap -> size is zero
+
+ dc.SetFont(self.GetFont())
+ if self.IsEnabled():
+ dc.SetTextForeground(self.GetForegroundColour())
+ else:
+ dc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT))
+
+ label = self.GetLabel()
+ tw, th = dc.GetTextExtent(label) # size of text
+ if not self.up:
+ dw = dy = self.labelDelta
+
+ pos_x = (width-bw)/2+dw # adjust for bitmap and text to centre
+ pos_y = (height-bh-th)/2+dy
+ if bmp !=None:
+ dc.DrawBitmap(bmp, pos_x, pos_y, hasMask) # draw bitmap if available
+ pos_x = (width-tw)/2+dw # adjust for bitmap and text to centre
+ pos_y += bh + 2
+
+ dc.DrawText(label, pos_x, pos_y) # draw the text
+
+
+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,
+ name = "genstatbmp"):
+
+ bitmappath = Bpath( "images", bitmapname)
+ if os.path.isfile(bitmappath):
+ bitmap = wx.Bitmap(bitmappath)
+ else:
+ bitmap = None
+ wx.lib.statbmp.GenStaticBitmap.__init__(self, parent, ID, bitmap,
+ pos, size,
+ style,
+ name)
+
+ def OnPaint(self, event):
+ dc = wx.PaintDC(self)
+ colour = self.GetParent().GetBackgroundColour()
+ dc.SetPen(wx.Pen(colour))
+ dc.SetBrush(wx.Brush(colour ))
+ dc.DrawRectangle(0, 0, *dc.GetSizeTuple())
+ if self._bitmap:
+ dc.DrawBitmap(self._bitmap, 0, 0, True)
+
+class ConfTreeNodeEditor(EditorPanel):
+
+ HAS_BASE_PARAMS = True
+
+ def _init_ConfNodeEditor(self, prnt):
+ self.ConfNodeEditor = None
+
+ def _init_Editor(self, prnt):
+ self.Editor = wx.SplitterWindow(id=self.ID, name='EditorSplitter', parent=prnt,
+ size=wx.Size(0, 0), style=wx.SUNKEN_BORDER|wx.SP_3D)
+ self.SetNeedUpdating(True)
+ self.SetMinimumPaneSize(1)
+
+ self.ParamsEditor = wx.ScrolledWindow(self.Editor, -1, size=wx.Size(-1, -1),
+ style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER|wx.HSCROLL|wx.VSCROLL)
+ self.ParamsEditor.SetBackgroundColour(WINDOW_COLOUR)
+ self.ParamsEditor.Bind(wx.EVT_SIZE, self.OnWindowResize)
+ self.ParamsEditor.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
+
+ # Variable allowing disabling of ParamsEditor scroll when Popup shown
+ self.ScrollingEnabled = True
+
+ self.ParamsEditorSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
+ self.ParamsEditorSizer.AddGrowableCol(0)
+ self.ParamsEditorSizer.AddGrowableRow(1)
+
+ self.ParamsEditor.SetSizer(self.ParamsEditorSizer)
+
+ baseparamseditor_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ self.ParamsEditorSizer.AddSizer(baseparamseditor_sizer, 0, border=5,
+ flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.TOP)
+
+ self.FullIECChannel = wx.StaticText(self.ParamsEditor, -1)
+ self.FullIECChannel.SetFont(
+ wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL,
+ wx.BOLD, faceName = faces["helv"]))
+ baseparamseditor_sizer.AddWindow(self.FullIECChannel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL)
+
+ updownsizer = wx.BoxSizer(wx.VERTICAL)
+ baseparamseditor_sizer.AddSizer(updownsizer, 0, border=5,
+ flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL)
+
+ ieccdownbutton_id = wx.NewId()
+ self.IECCDownButton = wx.lib.buttons.GenBitmapButton(
+ id=ieccdownbutton_id, bitmap=wx.Bitmap(opjimg('IECCDown')),
+ name='IECDownButton', parent=self.ParamsEditor, pos=wx.Point(0, 0),
+ size=wx.Size(16, 16), style=wx.NO_BORDER)
+ self.IECCDownButton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(-1),
+ id=ieccdownbutton_id)
+ updownsizer.AddWindow(self.IECCDownButton, 0, border=0, flag=wx.ALIGN_LEFT)
+
+ ieccupbutton_id = wx.NewId()
+ self.IECCUpButton = wx.lib.buttons.GenBitmapTextButton(
+ id=ieccupbutton_id, bitmap=wx.Bitmap(opjimg('IECCUp')),
+ name='IECUpButton', parent=self.ParamsEditor, pos=wx.Point(0, 0),
+ size=wx.Size(16, 16), style=wx.NO_BORDER)
+ self.IECCUpButton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(1),
+ id=ieccupbutton_id)
+ updownsizer.AddWindow(self.IECCUpButton, 0, border=0, flag=wx.ALIGN_LEFT)
+
+ self.RefreshIECChannelControlsState()
+
+ confnodename_id = wx.NewId()
+ self.ConfNodeName = wx.TextCtrl(
+ self.ParamsEditor, confnodename_id,
+ size=wx.Size(150, 25), style=wx.NO_BORDER)
+ self.ConfNodeName.SetFont(
+ wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL,
+ wx.BOLD, faceName = faces["helv"]))
+ self.ConfNodeName.ChangeValue(self.Controler.MandatoryParams[1].getName())
+ self.ConfNodeName.Bind(wx.EVT_TEXT,
+ self.GetTextCtrlCallBackFunction(self.ConfNodeName, "BaseParams.Name"),
+ id=confnodename_id)
+ baseparamseditor_sizer.AddWindow(self.ConfNodeName, 0, border=5, flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
+
+ buttons_sizer = self.GenerateMethodButtonSizer()
+ baseparamseditor_sizer.AddSizer(buttons_sizer, 0, border=0, flag=wx.ALIGN_CENTER)
+
+ self.ConfNodeParamsSizer = wx.BoxSizer(wx.VERTICAL)
+ self.ParamsEditorSizer.AddSizer(self.ConfNodeParamsSizer, 0, border=5,
+ flag=wx.LEFT|wx.RIGHT|wx.BOTTOM)
+
+ self.RefreshConfNodeParamsSizer()
+
+ self._init_ConfNodeEditor(self.Editor)
+
+ if self.ConfNodeEditor is not None:
+ min_size = self.ParamsEditorSizer.GetMinSize()
+ self.Editor.SplitHorizontally(self.ParamsEditor,
+ self.ConfNodeEditor,
+ min(min_size.height, 200))
+ else:
+ self.Editor.Initialize(self.ParamsEditor)
+
+ def __init__(self, parent, tagname, controler, window):
+ EditorPanel.__init__(self, parent, tagname, window, controler)
+
+ self.SetIcon(wx.Bitmap(self.Controler.GetIconPath(), wx.BITMAP_TYPE_PNG))
+
+ def __del__(self):
+ self.Controler.OnCloseEditor(self)
+
+ def GetTagName(self):
+ return self.Controler.CTNFullName()
+
+ def GetTitle(self):
+ fullname = self.Controler.CTNFullName()
+ if self.Controler.CTNTestModified():
+ return "~%s~" % fullname
+ return fullname
+
+ def HasNoModel(self):
+ return False
+
+ def EnableScrolling(self, enable):
+ self.ScrollingEnabled = enable
+
+ def RefreshIECChannelControlsState(self):
+ self.FullIECChannel.SetLabel(self.Controler.GetFullIEC_Channel())
+ self.IECCDownButton.Enable(self.Controler.BaseParams.getIEC_Channel() > 0)
+
+ def RefreshConfNodeParamsSizer(self):
+ self.Freeze()
+ self.ConfNodeParamsSizer.Clear(True)
+
+ confnode_infos = self.Controler.GetParamsAttributes()
+ if len(confnode_infos) > 0:
+ self.GenerateSizerElements(self.ConfNodeParamsSizer, confnode_infos, None, False)
+
+ self.ParamsEditorSizer.Layout()
+ self.Thaw()
+
+ def GenerateMethodButtonSizer(self):
+ normal_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])
+ mouseover_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=True, faceName = faces["helv"])
+
+ msizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ for confnode_method in self.Controler.ConfNodeMethods:
+ if "method" in confnode_method and confnode_method.get("shown",True):
+ id = wx.NewId()
+ label = confnode_method["name"]
+ button = GenBitmapTextButton(id=id, parent=self.ParamsEditor,
+ bitmap=wx.Bitmap(Bpath("images", "%s.png"%confnode_method.get("bitmap", "Unknown"))), label=label,
+ name=label, pos=wx.DefaultPosition, style=wx.NO_BORDER)
+ button.SetFont(normal_bt_font)
+ button.SetToolTipString(confnode_method["tooltip"])
+ button.Bind(wx.EVT_BUTTON, self.GetButtonCallBackFunction(confnode_method["method"]), id=id)
+ # a fancy underline on mouseover
+ def setFontStyle(b, s):
+ def fn(event):
+ b.SetFont(s)
+ b.Refresh()
+ event.Skip()
+ return fn
+ button.Bind(wx.EVT_ENTER_WINDOW, setFontStyle(button, mouseover_bt_font))
+ button.Bind(wx.EVT_LEAVE_WINDOW, setFontStyle(button, normal_bt_font))
+ #hack to force size to mini
+ if not confnode_method.get("enabled",True):
+ button.Disable()
+ msizer.AddWindow(button, 0, border=0, flag=wx.ALIGN_CENTER)
+ return msizer
+
+ def GenerateSizerElements(self, sizer, elements, path, clean = True):
+ if clean:
+ sizer.Clear(True)
+ first = True
+ for element_infos in elements:
+ if path:
+ element_path = "%s.%s"%(path, element_infos["name"])
+ else:
+ element_path = element_infos["name"]
+ if element_infos["type"] == "element":
+ label = element_infos["name"]
+ staticbox = wx.StaticBox(id=-1, label=_(label),
+ name='%s_staticbox'%element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.Size(10, 0), style=0)
+ staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
+ if first:
+ sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW|wx.TOP)
+ else:
+ sizer.AddSizer(staticboxsizer, 0, border=0, flag=wx.GROW)
+ self.GenerateSizerElements(staticboxsizer, element_infos["children"], element_path)
+ else:
+ boxsizer = wx.FlexGridSizer(cols=3, rows=1)
+ boxsizer.AddGrowableCol(1)
+ if first:
+ sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.ALL)
+ else:
+ sizer.AddSizer(boxsizer, 0, border=5, flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
+ staticbitmap = GenStaticBitmap(ID=-1, bitmapname="%s.png"%element_infos["name"],
+ name="%s_bitmap"%element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
+ boxsizer.AddWindow(staticbitmap, 0, border=5, flag=wx.RIGHT)
+ label = element_infos["name"]
+ statictext = wx.StaticText(id=-1, label="%s:"%_(label),
+ name="%s_label"%element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
+ boxsizer.AddWindow(statictext, 0, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.RIGHT)
+ id = wx.NewId()
+ if isinstance(element_infos["type"], types.ListType):
+ if isinstance(element_infos["value"], types.TupleType):
+ browse_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
+ boxsizer.AddSizer(browse_boxsizer, 0, border=0, flag=0)
+
+ textctrl = wx.TextCtrl(id=id, name=element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.Size(275, 25), style=wx.TE_READONLY)
+ if element_infos["value"] is not None:
+ textctrl.SetValue(element_infos["value"][0])
+ value_infos = element_infos["value"][1]
+ else:
+ value_infos = None
+ browse_boxsizer.AddWindow(textctrl, 0, border=0, flag=0)
+ button_id = wx.NewId()
+ button = wx.Button(id=button_id, name="browse_%s" % element_infos["name"], parent=self.ParamsEditor,
+ label="...", pos=wx.Point(0, 0), size=wx.Size(25, 25))
+ browse_boxsizer.AddWindow(button, 0, border=0, flag=0)
+ button.Bind(wx.EVT_BUTTON,
+ self.GetBrowseCallBackFunction(element_infos["name"], textctrl, element_infos["type"],
+ value_infos, element_path),
+ id=button_id)
+ else:
+ combobox = wx.ComboBox(id=id, name=element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.Size(300, 28), style=wx.CB_READONLY)
+ boxsizer.AddWindow(combobox, 0, border=0, flag=0)
+ if element_infos["use"] == "optional":
+ combobox.Append("")
+ if len(element_infos["type"]) > 0 and isinstance(element_infos["type"][0], types.TupleType):
+ for choice, xsdclass in element_infos["type"]:
+ combobox.Append(choice)
+ name = element_infos["name"]
+ value = element_infos["value"]
+ staticbox = wx.StaticBox(id=-1, label="%s - %s"%(_(name), _(value)),
+ name='%s_staticbox'%element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.Size(10, 0), style=0)
+ staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
+ sizer.AddSizer(staticboxsizer, 0, border=5, flag=wx.GROW|wx.BOTTOM)
+ self.GenerateSizerElements(staticboxsizer, element_infos["children"], element_path)
+ callback = self.GetChoiceContentCallBackFunction(combobox, staticboxsizer, element_path)
+ else:
+ for choice in element_infos["type"]:
+ combobox.Append(choice)
+ callback = self.GetChoiceCallBackFunction(combobox, element_path)
+ if element_infos["value"] is None:
+ combobox.SetStringSelection("")
+ else:
+ combobox.SetStringSelection(element_infos["value"])
+ combobox.Bind(wx.EVT_COMBOBOX, callback, id=id)
+ elif isinstance(element_infos["type"], types.DictType):
+ scmin = -(2**31)
+ scmax = 2**31-1
+ if "min" in element_infos["type"]:
+ scmin = element_infos["type"]["min"]
+ if "max" in element_infos["type"]:
+ scmax = element_infos["type"]["max"]
+ spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.Size(300, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
+ spinctrl.SetRange(scmin,scmax)
+ boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
+ if element_infos["value"] is not None:
+ spinctrl.SetValue(element_infos["value"])
+ spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, element_path), id=id)
+ else:
+ if element_infos["type"] == "boolean":
+ checkbox = wx.CheckBox(id=id, name=element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.Size(17, 25), style=0)
+ boxsizer.AddWindow(checkbox, 0, border=0, flag=0)
+ if element_infos["value"] is not None:
+ checkbox.SetValue(element_infos["value"])
+ checkbox.Bind(wx.EVT_CHECKBOX, self.GetCheckBoxCallBackFunction(checkbox, element_path), id=id)
+ elif element_infos["type"] in ["unsignedLong", "long","integer"]:
+ if element_infos["type"].startswith("unsigned"):
+ scmin = 0
+ else:
+ scmin = -(2**31)
+ scmax = 2**31-1
+ spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=self.ParamsEditor,
+ pos=wx.Point(0, 0), size=wx.Size(300, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
+ spinctrl.SetRange(scmin, scmax)
+ boxsizer.AddWindow(spinctrl, 0, border=0, flag=0)
+ if element_infos["value"] is not None:
+ spinctrl.SetValue(element_infos["value"])
+ spinctrl.Bind(wx.EVT_SPINCTRL, self.GetTextCtrlCallBackFunction(spinctrl, element_path), id=id)
+ else:
+ choices = self.ParentWindow.GetConfigEntry(element_path, [""])
+ textctrl = TextCtrlAutoComplete(id=id,
+ name=element_infos["name"],
+ parent=self.ParamsEditor,
+ appframe=self,
+ choices=choices,
+ element_path=element_path,
+ pos=wx.Point(0, 0),
+ size=wx.Size(300, 25),
+ style=0)
+
+ boxsizer.AddWindow(textctrl, 0, border=0, flag=0)
+ if element_infos["value"] is not None:
+ textctrl.ChangeValue(str(element_infos["value"]))
+ textctrl.Bind(wx.EVT_TEXT, self.GetTextCtrlCallBackFunction(textctrl, element_path))
+ first = False
+
+
+ def GetItemChannelChangedFunction(self, dir):
+ def OnConfNodeTreeItemChannelChanged(event):
+ confnode_IECChannel = self.Controler.BaseParams.getIEC_Channel()
+ res = self.SetConfNodeParamsAttribute("BaseParams.IEC_Channel", confnode_IECChannel + dir)
+ wx.CallAfter(self.RefreshIECChannelControlsState)
+ wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU, PROJECTTREE)
+ wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, self.GetTagName())
+ event.Skip()
+ return OnConfNodeTreeItemChannelChanged
+
+ def SetConfNodeParamsAttribute(self, *args, **kwargs):
+ res, StructChanged = self.Controler.SetParamsAttribute(*args, **kwargs)
+ if StructChanged:
+ wx.CallAfter(self.RefreshConfNodeParamsSizer)
+ wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU)
+ return res
+
+ def GetButtonCallBackFunction(self, method):
+ """ Generate the callbackfunc for a given confnode method"""
+ def OnButtonClick(event):
+ # Disable button to prevent re-entrant call
+ event.GetEventObject().Disable()
+ # Call
+ getattr(self.Controler,method)()
+ # Re-enable button
+ event.GetEventObject().Enable()
+
+ event.Skip()
+ return OnButtonClick
+
+ def GetChoiceCallBackFunction(self, choicectrl, path):
+ def OnChoiceChanged(event):
+ res = self.SetConfNodeParamsAttribute(path, choicectrl.GetStringSelection())
+ choicectrl.SetStringSelection(res)
+ event.Skip()
+ return OnChoiceChanged
+
+ def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, path):
+ def OnChoiceContentChanged(event):
+ res = self.SetConfNodeParamsAttribute(path, choicectrl.GetStringSelection())
+ event.Skip()
+ return OnChoiceContentChanged
+
+ def GetTextCtrlCallBackFunction(self, textctrl, path):
+ def OnTextCtrlChanged(event):
+ res = self.SetConfNodeParamsAttribute(path, textctrl.GetValue())
+ if res != textctrl.GetValue():
+ textctrl.ChangeValue(res)
+ if textctrl == self.ConfNodeName:
+ wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU, PROJECTTREE, PAGETITLES)
+ wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, self.GetTagName())
+ event.Skip()
+ return OnTextCtrlChanged
+
+ def GetCheckBoxCallBackFunction(self, chkbx, path):
+ def OnCheckBoxChanged(event):
+ res = self.SetConfNodeParamsAttribute(path, chkbx.IsChecked())
+ chkbx.SetValue(res)
+ event.Skip()
+ return OnCheckBoxChanged
+
+ def GetBrowseCallBackFunction(self, name, textctrl, library, value_infos, path):
+ infos = [value_infos]
+ def OnBrowseButton(event):
+ dialog = BrowseValuesLibraryDialog(self, name, library, infos[0])
+ if dialog.ShowModal() == wx.ID_OK:
+ value, value_infos = self.SetConfNodeParamsAttribute(path, dialog.GetValueInfos())
+ textctrl.ChangeValue(value)
+ infos[0] = value_infos
+ dialog.Destroy()
+ event.Skip()
+ return OnBrowseButton
+
+ def OnWindowResize(self, event):
+ self.GetBestSize()
+ xstart, ystart = self.ParamsEditor.GetViewStart()
+ window_size = self.ParamsEditor.GetClientSize()
+ maxx, maxy = self.ParamsEditorSizer.GetMinSize()
+ posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
+ posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
+ self.ParamsEditor.Scroll(posx, posy)
+ self.ParamsEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
+ maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
+ event.Skip()
+
+ def OnMouseWheel(self, event):
+ if self.ScrollingEnabled:
+ event.Skip()
+
--- a/ConfigTreeNode.py Mon May 21 02:49:53 2012 +0200
+++ b/ConfigTreeNode.py Mon May 21 10:04:27 2012 +0200
@@ -12,7 +12,7 @@
from xml.dom import minidom
from xmlclass import GenerateClassesFromXSDstring
-from util import opjimg, GetClassImporter
+from util import GetClassImporter
from PLCControler import PLCControler, LOCATION_CONFNODE
@@ -40,7 +40,8 @@
ConfNodeMethods = []
LibraryControler = None
EditorType = None
-
+ IconPath = None
+
def _AddParamsMembers(self):
self.CTNParams = None
if self.XSD:
@@ -572,22 +573,3 @@
self.GetCTRoot().logger.write_error(_("Could not add child \"%s\", type %s :\n%s\n")%(pname, ptype, str(exc)))
self.GetCTRoot().logger.write_error(traceback.format_exc())
- def EnableMethod(self, method, value):
- for d in self.ConfNodeMethods:
- if d["method"]==method:
- d["enabled"]=value
- return True
- return False
-
- def ShowMethod(self, method, value):
- for d in self.ConfNodeMethods:
- if d["method"]==method:
- d["shown"]=value
- return True
- return False
-
- def CallMethod(self, method):
- for d in self.ConfNodeMethods:
- if d["method"]==method and d.get("enabled", True) and d.get("shown", True):
- getattr(self, method)()
-
--- a/ProjectController.py Mon May 21 02:49:53 2012 +0200
+++ b/ProjectController.py Mon May 21 10:04:27 2012 +0200
@@ -16,13 +16,14 @@
import connectors
from util import MiniTextControler, opjimg, CheckPathPerm, GetClassImporter
from util.ProcessLogger import ProcessLogger
-from PLCControler import PLCControler
-from PLCOpenEditor import ProjectDialog
+from PLCControler import PLCControler
+from PLCOpenEditor import CWD
from TextViewer import TextViewer
from plcopen.structures import IEC_KEYWORDS
from targets.typemapping import DebugTypesSize
from util.discovery import DiscoveryDialog
from ConfigTreeNode import ConfigTreeNode
+from ProjectNodeEditor import ProjectNodeEditor
base_folder = os.path.split(sys.path[0])[0]
@@ -31,6 +32,8 @@
DEBUG_RETRIES_WARN = 3
DEBUG_RETRIES_REREGISTER = 4
+ITEM_CONFNODE = 25
+
class ProjectController(ConfigTreeNode, PLCControler):
"""
This class define Root object of the confnode tree.
@@ -73,7 +76,8 @@
</xsd:element>
</xsd:schema>
"""
-
+ EditorType = ProjectNodeEditor
+
def __init__(self, frame, logger):
PLCControler.__init__(self)
@@ -99,6 +103,7 @@
# Keep track of the confnode type name
self.CTNType = "Beremiz"
self.Children = {}
+ self._View = None
# After __init__ root confnode is not valid
self.ProjectPath = None
self._setBuildPath(None)
@@ -121,7 +126,7 @@
if self.DebugTimer:
self.DebugTimer.cancel()
self.KillDebugThread()
-
+
def SetAppFrame(self, frame, logger):
self.AppFrame = frame
self.logger = logger
@@ -143,6 +148,9 @@
self.logger = logger
+ def CTNName(self):
+ return "Project"
+
def CTNTestModified(self):
return self.ChangesToSave or not self.ProjectIsSaved()
@@ -173,6 +181,9 @@
def GetProjectName(self):
return os.path.split(self.ProjectPath)[1]
+ def GetIconPath(self):
+ return os.path.join(CWD, "Images", "PROJECT.png")
+
def GetDefaultTargetName(self):
if wx.Platform == '__WXMSW__':
return "Win32"
@@ -212,9 +223,9 @@
dialog.Destroy()
if answer == wx.ID_YES:
if self.SaveProjectAs():
- self.AppFrame.RefreshAll()
self.AppFrame.RefreshTitle()
self.AppFrame.RefreshFileMenu()
+ self.AppFrame.RefreshPageTitles()
return True
return False
@@ -228,17 +239,16 @@
if not os.path.isdir(ProjectPath) or len(os.listdir(ProjectPath)) > 0:
return _("Chosen folder isn't empty. You can't use it for a new project!")
- dialog = ProjectDialog(self.AppFrame)
- if dialog.ShowModal() == wx.ID_OK:
- values = dialog.GetValues()
- values["creationDateTime"] = datetime(*localtime()[:6])
- dialog.Destroy()
- else:
- dialog.Destroy()
- return _("Project not created")
-
# Create PLCOpen program
- self.CreateNewProject(values)
+ self.CreateNewProject(
+ {"projectName": _("Unnamed"),
+ "productName": _("Unnamed"),
+ "productVersion": _("1"),
+ "companyName": _("Unknown"),
+ "creationDateTime": datetime(*localtime()[:6])})
+ self.ProjectAddConfiguration("config")
+ self.ProjectAddConfigurationResource("config", "resource1")
+
# Change XSD into class members
self._AddParamsMembers()
self.Children = {}
@@ -290,6 +300,32 @@
return None
+ def RecursiveConfNodeInfos(self, confnode):
+ values = []
+ for CTNChild in confnode.IECSortedChildren():
+ values.append(
+ {"name": "%s: %s" % (CTNChild.GetFullIEC_Channel(),
+ CTNChild.CTNName()),
+ "type": ITEM_CONFNODE,
+ "confnode": CTNChild,
+ "icon": CTNChild.GetIconPath(),
+ "values": self.RecursiveConfNodeInfos(CTNChild)})
+ return values
+
+ def GetProjectInfos(self):
+ infos = PLCControler.GetProjectInfos(self)
+ configurations = infos["values"].pop(-1)
+ resources = None
+ for config_infos in configurations["values"]:
+ if resources is None:
+ resources = config_infos["values"][0]
+ else:
+ resources["values"].extend(config_infos["values"][0]["values"])
+ if resources is not None:
+ infos["values"].append(resources)
+ infos["values"].extend(self.RecursiveConfNodeInfos(self))
+ return infos
+
def CloseProject(self):
self.ClearChildren()
self.ResetAppFrame(None)
@@ -906,7 +942,7 @@
return IEC_code_viewer
elif name == "IEC raw code":
- controler = MiniTextControler(self._getIECrawcodepath())
+ controler = MiniTextControler.MiniTextControler(self._getIECrawcodepath())
IEC_raw_code_viewer = TextViewer(self.AppFrame.TabsOpened, "", None, controler, instancepath=name)
#IEC_raw_code_viewer.Enable(False)
IEC_raw_code_viewer.SetTextSyntax("ALL")
@@ -918,7 +954,8 @@
return IEC_raw_code_viewer
- return None
+ else:
+ return ConfigTreeNode._OpenView(self, name)
def _Clean(self):
if os.path.isdir(os.path.join(self._getBuildPath())):
@@ -971,7 +1008,7 @@
{"Broken": self.logger.write_error,
None: lambda x: None}.get(
self.previous_plcstate, self.logger.write)(_("PLC is %s\n")%status)
- self.AppFrame.RefreshAll()
+ self.AppFrame.RefreshStatusToolBar()
def RegisterDebugVarToConnector(self):
self.DebugTimer=None
@@ -1339,7 +1376,7 @@
wx.CallAfter(self.UpdateMethodsFromPLCStatus)
- ConfNodeMethods = [
+ StatusMethods = [
{"bitmap" : "Build",
"name" : _("Build"),
"tooltip" : _("Build project into build folder"),
@@ -1378,8 +1415,31 @@
"shown" : False,
"tooltip" : _("Show IEC code generated by PLCGenerator"),
"method" : "_showIECcode"},
+ ]
+
+ ConfNodeMethods = [
{"bitmap" : "editIECrawcode",
"name" : _("Raw IEC code"),
"tooltip" : _("Edit raw IEC code added to code generated by PLCGenerator"),
"method" : "_editIECrawcode"},
]
+
+
+ def EnableMethod(self, method, value):
+ for d in self.StatusMethods:
+ if d["method"]==method:
+ d["enabled"]=value
+ return True
+ return False
+
+ def ShowMethod(self, method, value):
+ for d in self.StatusMethods:
+ if d["method"]==method:
+ d["shown"]=value
+ return True
+ return False
+
+ def CallMethod(self, method):
+ for d in self.StatusMethods:
+ if d["method"]==method and d.get("enabled", True) and d.get("shown", True):
+ getattr(self, method)()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ProjectNodeEditor.py Mon May 21 10:04:27 2012 +0200
@@ -0,0 +1,54 @@
+
+import wx
+
+from ConfTreeNodeEditor import ConfTreeNodeEditor, WINDOW_COLOUR
+
+class ProjectNodeEditor(ConfTreeNodeEditor):
+
+ VARIABLE_PANEL_TYPE = "config"
+
+ def _init_Editor(self, prnt):
+ self.Editor = wx.ScrolledWindow(prnt, -1, size=wx.Size(-1, -1),
+ style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER|wx.HSCROLL|wx.VSCROLL)
+ self.Editor.SetBackgroundColour(WINDOW_COLOUR)
+ self.ParamsEditor = self.Editor
+
+ # Variable allowing disabling of Editor scroll when Popup shown
+ self.ScrollingEnabled = True
+
+ self.ParamsEditorSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
+ self.ParamsEditorSizer.AddGrowableCol(0)
+ self.ParamsEditorSizer.AddGrowableRow(1)
+
+ self.Editor.SetSizer(self.ParamsEditorSizer)
+
+
+ buttons_sizer = self.GenerateMethodButtonSizer()
+ self.ParamsEditorSizer.AddSizer(buttons_sizer, 0, border=5,
+ flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.TOP)
+
+ self.ConfNodeParamsSizer = wx.BoxSizer(wx.VERTICAL)
+ self.ParamsEditorSizer.AddSizer(self.ConfNodeParamsSizer, 0, border=5,
+ flag=wx.LEFT|wx.RIGHT|wx.BOTTOM)
+
+ self.RefreshConfNodeParamsSizer()
+
+ def __init__(self, parent, controler, window):
+ configuration = controler.GetProjectMainConfigurationName()
+ if configuration is not None:
+ tagname = controler.ComputeConfigurationName(configuration)
+ else:
+ tagname = ""
+
+ ConfTreeNodeEditor.__init__(self, parent, tagname, controler, window)
+
+ def GetTagName(self):
+ return self.Controler.CTNName()
+
+ def GetTitle(self):
+ fullname = self.Controler.CTNName()
+ if self.Controler.CTNTestModified():
+ return "~%s~" % fullname
+ return fullname
+
+
\ No newline at end of file
--- a/c_ext/CFileEditor.py Mon May 21 02:49:53 2012 +0200
+++ b/c_ext/CFileEditor.py Mon May 21 10:04:27 2012 +0200
@@ -6,7 +6,8 @@
import wx.lib.buttons
from util import opjimg
-from controls import CustomGrid, CustomTable, EditorPanel
+from controls import CustomGrid, CustomTable
+from ConfTreeNodeEditor import ConfTreeNodeEditor
if wx.Platform == '__WXMSW__':
faces = { 'times': 'Times New Roman',
@@ -776,10 +777,10 @@
ID_CFILEEDITORCFILETREE, ID_CFILEEDITORPARTSOPENED,
] = [wx.NewId() for _init_ctrls in range(4)]
-class CFileEditor(EditorPanel):
-
- def _init_Editor(self, prnt):
- self.Editor = wx.Panel(id=ID_CFILEEDITOR, parent=prnt, pos=wx.Point(0, 0),
+class CFileEditor(ConfTreeNodeEditor):
+
+ def _init_ConfNodeEditor(self, prnt):
+ self.ConfNodeEditor = wx.Panel(id=ID_CFILEEDITOR, parent=prnt, pos=wx.Point(0, 0),
size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
self.Panels = {}
@@ -790,41 +791,31 @@
button_id = wx.NewId()
button = FoldPanelCaption(id=button_id, name='FoldPanelCaption_%s' % name,
label=name, bitmap=wx.Bitmap(opjimg("CollapsedIconData")),
- parent=self.Editor, pos=wx.Point(0, 0),
+ parent=self.ConfNodeEditor, pos=wx.Point(0, 0),
size=wx.Size(0, 20), style=wx.NO_BORDER|wx.ALIGN_LEFT)
button.SetBitmapSelected(wx.Bitmap(opjimg("ExpandedIconData")))
button.Bind(wx.EVT_BUTTON, self.GenPanelButtonCallback(name), id=button_id)
self.MainSizer.AddWindow(button, 0, border=0, flag=wx.TOP|wx.GROW)
if panel_class == VariablesEditor:
- panel = VariablesEditor(self.Editor, self.ParentWindow, self.Controler)
- else:
- panel = panel_class(self.Editor, name, self.ParentWindow, self.Controler)
+ panel = VariablesEditor(self.ConfNodeEditor, self.ParentWindow, self.Controler)
+ else:
+ panel = panel_class(self.ConfNodeEditor, name, self.ParentWindow, self.Controler)
self.MainSizer.AddWindow(panel, 0, border=0, flag=wx.BOTTOM|wx.GROW)
panel.Hide()
self.Panels[name] = {"button": button, "panel": panel, "expanded": False, "row": 2 * idx + 1}
- self.Spacer = wx.Panel(self.Editor, -1)
+ self.Spacer = wx.Panel(self.ConfNodeEditor, -1)
self.SpacerExpanded = True
self.MainSizer.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
self.MainSizer.AddGrowableRow(2 * len(CFILE_PARTS))
- self.Editor.SetSizer(self.MainSizer)
-
+ self.ConfNodeEditor.SetSizer(self.MainSizer)
+
def __init__(self, parent, controler, window):
- EditorPanel.__init__(self, parent, "", window, controler)
- self.SetIcon(wx.Bitmap(opjimg("Cfile")))
-
- def __del__(self):
- self.Controler.OnCloseEditor(self)
-
- def GetTitle(self):
- fullname = self.Controler.CTNFullName()
- if not self.Controler.CFileIsSaved():
- return "~%s~" % fullname
- return fullname
+ ConfTreeNodeEditor.__init__(self, parent, "", controler, window)
def GetBufferState(self):
return self.Controler.GetBufferState()
@@ -837,9 +828,6 @@
self.Controler.LoadNext()
self.RefreshView()
- def HasNoModel(self):
- return False
-
def RefreshView(self):
for infos in self.Panels.itervalues():
infos["panel"].RefreshView()
--- a/c_ext/c_ext.py Mon May 21 02:49:53 2012 +0200
+++ b/c_ext/c_ext.py Mon May 21 10:04:27 2012 +0200
@@ -4,6 +4,7 @@
from xmlclass import *
+from util import opjimg
from CFileEditor import CFileEditor
from PLCControler import UndoBuffer, LOCATION_CONFNODE, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT
@@ -43,6 +44,9 @@
self.CreateCFileBuffer(False)
self.OnCTNSave()
+ def GetIconPath(self):
+ return opjimg("Cfile")
+
def CFileName(self):
return os.path.join(self.CTNPath(), "cfile.xml")
@@ -138,13 +142,6 @@
return self.CFile.publishFunction.gettext()
return ""
- ConfNodeMethods = [
- {"bitmap" : "EditCfile",
- "name" : _("Edit C File"),
- "tooltip" : _("Edit C File"),
- "method" : "_OpenView"},
- ]
-
def CTNTestModified(self):
return self.ChangesToSave or not self.CFileIsSaved()
--- a/canfestival/NetworkEditor.py Mon May 21 02:49:53 2012 +0200
+++ b/canfestival/NetworkEditor.py Mon May 21 10:04:27 2012 +0200
@@ -1,6 +1,3 @@
-import os, sys
-base_folder = os.path.split(sys.path[0])[0]
-CanFestivalPath = os.path.join(base_folder, "CanFestival-3")
import wx
@@ -56,7 +53,7 @@
EditorPanel.__init__(self, parent, "", window, controler)
NetworkEditorTemplate.__init__(self, controler, window, False)
- img = wx.Bitmap(os.path.join(CanFestivalPath, "objdictgen", "networkedit.png"), wx.BITMAP_TYPE_PNG).ConvertToImage()
+ img = wx.Bitmap(controler.GetIconPath(), wx.BITMAP_TYPE_PNG).ConvertToImage()
self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16)))
self.RefreshNetworkNodes()
--- a/canfestival/SlaveEditor.py Mon May 21 02:49:53 2012 +0200
+++ b/canfestival/SlaveEditor.py Mon May 21 10:04:27 2012 +0200
@@ -1,6 +1,3 @@
-import os, sys
-base_folder = os.path.split(sys.path[0])[0]
-CanFestivalPath = os.path.join(base_folder, "CanFestival-3")
import wx
@@ -28,7 +25,7 @@
EditorPanel.__init__(self, parent, "", window, controler)
NodeEditorTemplate.__init__(self, controler, window, False)
- img = wx.Bitmap(os.path.join(CanFestivalPath, "objdictgen", "networkedit.png"), wx.BITMAP_TYPE_PNG).ConvertToImage()
+ img = wx.Bitmap(controler.GetIconPath(), wx.BITMAP_TYPE_PNG).ConvertToImage()
self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16)))
def __del__(self):
--- a/canfestival/canfestival.py Mon May 21 02:49:53 2012 +0200
+++ b/canfestival/canfestival.py Mon May 21 10:04:27 2012 +0200
@@ -64,6 +64,7 @@
""" % DEFAULT_SETTINGS
EditorType = SlaveEditor
+ IconPath = os.path.join(CanFestivalPath, "objdictgen", "networkedit.png")
def __init__(self):
# TODO change netname when name change
@@ -215,6 +216,7 @@
""" % DEFAULT_SETTINGS
EditorType = NetworkEditor
+ IconPath = os.path.join(CanFestivalPath, "objdictgen", "networkedit.png")
def __init__(self):
manager = NodeManager()
Binary file images/Extension.png has changed
Binary file images/Pyfile.png has changed
Binary file images/SVGUI.png has changed
--- a/images/icons.svg Mon May 21 02:49:53 2012 +0200
+++ b/images/icons.svg Mon May 21 10:04:27 2012 +0200
@@ -31,8 +31,8 @@
</rdf:RDF>
</metadata>
<sodipodi:namedview
- inkscape:window-height="1000"
- inkscape:window-width="1280"
+ inkscape:window-height="1056"
+ inkscape:window-width="1920"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
guidetolerance="10.0"
@@ -43,10 +43,10 @@
pagecolor="#ffffff"
id="base"
showgrid="false"
- inkscape:zoom="0.90509668"
- inkscape:cx="574.84342"
- inkscape:cy="238.35742"
- inkscape:window-x="1920"
+ inkscape:zoom="7.2407736"
+ inkscape:cx="412.79813"
+ inkscape:cy="698.07641"
+ inkscape:window-x="0"
inkscape:window-y="24"
inkscape:current-layer="svg2"
showguides="true"
@@ -84368,6 +84368,926 @@
id="linearGradient18427"
xlink:href="#linearGradient1884-0"
inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6"
+ id="linearGradient20956-0-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient34137-1-6">
+ <stop
+ id="stop34139-3-8"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop34141-3-5"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6"
+ id="linearGradient20950-0-9"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient17477">
+ <stop
+ id="stop17479"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17481"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1908-2-3"
+ id="linearGradient20952-0-3"
+ gradientUnits="userSpaceOnUse"
+ x1="-84.232422"
+ y1="10.337565"
+ x2="-71.603516"
+ y2="10.337565" />
+ <linearGradient
+ id="linearGradient1908-2-3">
+ <stop
+ id="stop1909-2-0"
+ style="stop-color:#884631;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3698-2-9"
+ style="stop-color:#df421e;stop-opacity:1"
+ offset="0.625" />
+ <stop
+ id="stop3699-4-7"
+ style="stop-color:#efa08e;stop-opacity:1"
+ offset="0.8125" />
+ <stop
+ id="stop1910-7-0"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6"
+ id="linearGradient20948-9-2"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient17490">
+ <stop
+ id="stop17492"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17494"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6"
+ id="linearGradient20954-8-1"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient17497">
+ <stop
+ id="stop17499"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17501"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3256-7-6"
+ id="linearGradient20958-4-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.044357,0.957527)"
+ x1="591.27606"
+ y1="330.16998"
+ x2="620.33301"
+ y2="382.54678" />
+ <linearGradient
+ id="linearGradient3256-7-6">
+ <stop
+ id="stop3258-8-5"
+ style="stop-color:#3d9cde;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3260-6-8"
+ style="stop-color:#3d9cde;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5083-0-2"
+ id="linearGradient20960-0-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1929605,-0.00426242,0.00585233,0.1786386,680.44209,227.41631)"
+ x1="566.74347"
+ y1="415.15009"
+ x2="588.13922"
+ y2="458.04449" />
+ <linearGradient
+ id="linearGradient5083-0-2">
+ <stop
+ id="stop5085-6-2"
+ style="stop-color:#df6e6e;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop5097-4-2"
+ style="stop-color:#df6e6e;stop-opacity:1"
+ offset="0.36000001" />
+ <stop
+ id="stop5087-3-7"
+ style="stop-color:#fbcaca;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2345-5-1"
+ id="linearGradient20962-7-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08313961,-0.03722276,-0.03243445,0.0934943,693.52705,270.28905)"
+ x1="100.76616"
+ y1="77.379333"
+ x2="125.25793"
+ y2="77.379333" />
+ <linearGradient
+ id="linearGradient2345-5-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2347-8-7" />
+ <stop
+ style="stop-color:#f0f0f0;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2349-1-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1930-9-3"
+ id="linearGradient20964-0-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.07819037,-0.03500718,-0.03448742,0.09941203,684.96091,272.7873)"
+ x1="10.145814"
+ y1="21.762129"
+ x2="19.678274"
+ y2="15.811033" />
+ <linearGradient
+ id="linearGradient1930-9-3">
+ <stop
+ id="stop1931-3-1"
+ style="stop-color:#ff9870;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop1932-0-0"
+ style="stop-color:#ffd8c9;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2355-6-7"
+ id="linearGradient20966-2-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.00952271,-0.00152943,-0.8372982,1.5053504,699.75234,263.84813)"
+ x1="1270.3132"
+ y1="4.8765283"
+ x2="1247.6848"
+ y2="0.72310239" />
+ <linearGradient
+ id="linearGradient2355-6-7">
+ <stop
+ id="stop2359-4-8"
+ style="stop-color:#b18e4b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2358-3-1"
+ style="stop-color:#f7dca0;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3970-6-0"
+ id="linearGradient20968-8-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2028254,-0.00448039,0.00556771,0.1699505,680.44209,227.41631)"
+ x1="-94.151642"
+ y1="379.97745"
+ x2="-100.4097"
+ y2="374.03232" />
+ <linearGradient
+ id="linearGradient3970-6-0">
+ <stop
+ id="stop3971-7-5"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3972-0-0"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2560-1-6"
+ id="linearGradient20970-8-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.1217387,-0.01955224,-0.06549549,0.1177522,699.8779,263.8683)"
+ spreadMethod="reflect"
+ x1="97.345161"
+ y1="112.84396"
+ x2="99.20697"
+ y2="115.81121" />
+ <linearGradient
+ id="linearGradient2560-1-6">
+ <stop
+ id="stop2562-9-9"
+ style="stop-color:#868686;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2561-8-2"
+ style="stop-color:#e2e2e2;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2560-1-6"
+ id="linearGradient20972-1-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1839072,-0.00406245,0.0061405,0.1874324,680.55604,227.23529)"
+ x1="-13.15085"
+ y1="250.48668"
+ x2="-5.590662"
+ y2="258.31036" />
+ <linearGradient
+ id="linearGradient17533">
+ <stop
+ id="stop17535"
+ style="stop-color:#868686;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17537"
+ style="stop-color:#e2e2e2;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1884-0-3"
+ id="linearGradient20974-5-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.0874385,-0.01404345,-0.09118816,0.1639442,699.8779,263.8683)"
+ x1="240.97612"
+ y1="200.61511"
+ x2="231.89941"
+ y2="205.45764" />
+ <linearGradient
+ id="linearGradient1884-0-3">
+ <stop
+ id="stop1886-1-5"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop1885-5-7"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1884-0-3"
+ id="linearGradient20977-9-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2064601,-0.00456044,0.00503988,0.1538412,680.41644,232.74127)"
+ x1="7.1050277"
+ y1="221.98289"
+ x2="46.488174"
+ y2="259.94464" />
+ <linearGradient
+ id="linearGradient17544">
+ <stop
+ id="stop17546"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17548-5"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ y2="259.94464"
+ x2="46.488174"
+ y1="221.98289"
+ x1="7.1050277"
+ gradientTransform="matrix(0.2064601,-0.00456044,0.00503988,0.1538412,682.71501,230.6378)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient18427-9"
+ xlink:href="#linearGradient1884-0-3"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient17551">
+ <stop
+ id="stop17553"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17555"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5175-3-7"
+ id="linearGradient18288-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-40,0)"
+ x1="0"
+ y1="1"
+ x2="15"
+ y2="16" />
+ <linearGradient
+ id="linearGradient5175-3-7">
+ <stop
+ style="stop-color:#bdcccd;stop-opacity:1;"
+ offset="0"
+ id="stop5177-6-9" />
+ <stop
+ style="stop-color:#7979ff;stop-opacity:1;"
+ offset="1"
+ id="stop5179-73-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5175-3-7-9"
+ id="linearGradient18288-5-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-40,0)"
+ x1="0"
+ y1="1"
+ x2="15"
+ y2="16" />
+ <linearGradient
+ id="linearGradient5175-3-7-9">
+ <stop
+ style="stop-color:#bdcccd;stop-opacity:1;"
+ offset="0"
+ id="stop5177-6-9-6" />
+ <stop
+ style="stop-color:#7979ff;stop-opacity:1;"
+ offset="1"
+ id="stop5179-73-8-3" />
+ </linearGradient>
+ <linearGradient
+ y2="16"
+ x2="15"
+ y1="1"
+ x1="0"
+ gradientTransform="translate(-40,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17616-2"
+ xlink:href="#linearGradient5175-3-7-9"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6-5"
+ id="linearGradient20956-0-4-4"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564"
+ gradientTransform="translate(-216,0)" />
+ <linearGradient
+ id="linearGradient34137-1-6-5">
+ <stop
+ id="stop34139-3-8-3"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop34141-3-5-8"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6-5"
+ id="linearGradient20950-0-9-7"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient18466">
+ <stop
+ id="stop18468"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop18470"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1908-2-3-6"
+ id="linearGradient20952-0-3-6"
+ gradientUnits="userSpaceOnUse"
+ x1="-84.232422"
+ y1="10.337565"
+ x2="-71.603516"
+ y2="10.337565" />
+ <linearGradient
+ id="linearGradient1908-2-3-6">
+ <stop
+ id="stop1909-2-0-2"
+ style="stop-color:#884631;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3698-2-9-0"
+ style="stop-color:#df421e;stop-opacity:1"
+ offset="0.625" />
+ <stop
+ id="stop3699-4-7-7"
+ style="stop-color:#efa08e;stop-opacity:1"
+ offset="0.8125" />
+ <stop
+ id="stop1910-7-0-7"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6-5"
+ id="linearGradient20948-9-2-1"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient18479">
+ <stop
+ id="stop18481"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop18483"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6-5"
+ id="linearGradient20954-8-1-1"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient18486">
+ <stop
+ id="stop18488"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop18490"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ y2="14.276564"
+ x2="-77.844841"
+ y1="5.1423945"
+ x1="-77.844841"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient18496-1"
+ xlink:href="#linearGradient34137-1-6-5"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6-3"
+ id="linearGradient20956-0-4-6"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient34137-1-6-3">
+ <stop
+ id="stop34139-3-8-1"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop34141-3-5-1"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6-3"
+ id="linearGradient20950-0-9-0"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient17627">
+ <stop
+ id="stop17629"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17631"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1908-2-3-0"
+ id="linearGradient20952-0-3-3"
+ gradientUnits="userSpaceOnUse"
+ x1="-84.232422"
+ y1="10.337565"
+ x2="-71.603516"
+ y2="10.337565" />
+ <linearGradient
+ id="linearGradient1908-2-3-0">
+ <stop
+ id="stop1909-2-0-21"
+ style="stop-color:#884631;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3698-2-9-1"
+ style="stop-color:#df421e;stop-opacity:1"
+ offset="0.625" />
+ <stop
+ id="stop3699-4-7-75"
+ style="stop-color:#efa08e;stop-opacity:1"
+ offset="0.8125" />
+ <stop
+ id="stop1910-7-0-9"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6-3"
+ id="linearGradient20948-9-2-8"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient17640">
+ <stop
+ id="stop17642"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17644"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient34137-1-6-3"
+ id="linearGradient20954-8-1-9"
+ gradientUnits="userSpaceOnUse"
+ x1="-77.844841"
+ y1="5.1423945"
+ x2="-77.844841"
+ y2="14.276564" />
+ <linearGradient
+ id="linearGradient17647">
+ <stop
+ id="stop17649"
+ style="stop-color:#80bd2b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17651"
+ style="stop-color:#b1d68e;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3256-7-6-8"
+ id="linearGradient20958-4-9-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.044357,0.957527)"
+ x1="591.27606"
+ y1="330.16998"
+ x2="620.33301"
+ y2="382.54678" />
+ <linearGradient
+ id="linearGradient3256-7-6-8">
+ <stop
+ id="stop3258-8-5-4"
+ style="stop-color:#3d9cde;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3260-6-8-6"
+ style="stop-color:#3d9cde;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5083-0-2-0"
+ id="linearGradient20960-0-8-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1929605,-0.00426242,0.00585233,0.1786386,680.44209,227.41631)"
+ x1="566.74347"
+ y1="415.15009"
+ x2="588.13922"
+ y2="458.04449" />
+ <linearGradient
+ id="linearGradient5083-0-2-0">
+ <stop
+ id="stop5085-6-2-6"
+ style="stop-color:#df6e6e;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop5097-4-2-1"
+ style="stop-color:#df6e6e;stop-opacity:1"
+ offset="0.36000001" />
+ <stop
+ id="stop5087-3-7-5"
+ style="stop-color:#fbcaca;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2345-5-1-2"
+ id="linearGradient20962-7-3-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.08313961,-0.03722276,-0.03243445,0.0934943,693.52705,270.28905)"
+ x1="100.76616"
+ y1="77.379333"
+ x2="125.25793"
+ y2="77.379333" />
+ <linearGradient
+ id="linearGradient2345-5-1-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2347-8-7-0" />
+ <stop
+ style="stop-color:#f0f0f0;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2349-1-9-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1930-9-3-0"
+ id="linearGradient20964-0-0-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.07819037,-0.03500718,-0.03448742,0.09941203,684.96091,272.7873)"
+ x1="10.145814"
+ y1="21.762129"
+ x2="19.678274"
+ y2="15.811033" />
+ <linearGradient
+ id="linearGradient1930-9-3-0">
+ <stop
+ id="stop1931-3-1-9"
+ style="stop-color:#ff9870;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop1932-0-0-8"
+ style="stop-color:#ffd8c9;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2355-6-7-2"
+ id="linearGradient20966-2-1-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.00952271,-0.00152943,-0.8372982,1.5053504,699.75234,263.84813)"
+ x1="1270.3132"
+ y1="4.8765283"
+ x2="1247.6848"
+ y2="0.72310239" />
+ <linearGradient
+ id="linearGradient2355-6-7-2">
+ <stop
+ id="stop2359-4-8-1"
+ style="stop-color:#b18e4b;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2358-3-1-4"
+ style="stop-color:#f7dca0;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3970-6-0-1"
+ id="linearGradient20968-8-5-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2028254,-0.00448039,0.00556771,0.1699505,680.44209,227.41631)"
+ x1="-94.151642"
+ y1="379.97745"
+ x2="-100.4097"
+ y2="374.03232" />
+ <linearGradient
+ id="linearGradient3970-6-0-1">
+ <stop
+ id="stop3971-7-5-7"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3972-0-0-6"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2560-1-6-6"
+ id="linearGradient20970-8-2-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.1217387,-0.01955224,-0.06549549,0.1177522,699.8779,263.8683)"
+ spreadMethod="reflect"
+ x1="97.345161"
+ y1="112.84396"
+ x2="99.20697"
+ y2="115.81121" />
+ <linearGradient
+ id="linearGradient2560-1-6-6">
+ <stop
+ id="stop2562-9-9-4"
+ style="stop-color:#868686;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2561-8-2-6"
+ style="stop-color:#e2e2e2;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2560-1-6-6"
+ id="linearGradient20972-1-9-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.1839072,-0.00406245,0.0061405,0.1874324,680.55604,227.23529)"
+ x1="-13.15085"
+ y1="250.48668"
+ x2="-5.590662"
+ y2="258.31036" />
+ <linearGradient
+ id="linearGradient17683">
+ <stop
+ id="stop17685"
+ style="stop-color:#868686;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17687"
+ style="stop-color:#e2e2e2;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1884-0-3-5"
+ id="linearGradient20974-5-0-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.0874385,-0.01404345,-0.09118816,0.1639442,699.8779,263.8683)"
+ x1="240.97612"
+ y1="200.61511"
+ x2="231.89941"
+ y2="205.45764" />
+ <linearGradient
+ id="linearGradient1884-0-3-5">
+ <stop
+ id="stop1886-1-5-5"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop1885-5-7-9"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1884-0-3-5"
+ id="linearGradient20977-9-3-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.2064601,-0.00456044,0.00503988,0.1538412,680.41644,232.74127)"
+ x1="7.1050277"
+ y1="221.98289"
+ x2="46.488174"
+ y2="259.94464" />
+ <linearGradient
+ id="linearGradient17694">
+ <stop
+ id="stop17696"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17698"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ y2="259.94464"
+ x2="46.488174"
+ y1="221.98289"
+ x1="7.1050277"
+ gradientTransform="matrix(0.2064601,-0.00456044,0.00503988,0.1538412,682.71501,230.6378)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient18427-9-5"
+ xlink:href="#linearGradient1884-0-3-5"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient17701">
+ <stop
+ id="stop17703"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop17705"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5175-3-7-0"
+ id="linearGradient18288-5-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-40,0)"
+ x1="0"
+ y1="1"
+ x2="15"
+ y2="16" />
+ <linearGradient
+ id="linearGradient5175-3-7-0">
+ <stop
+ style="stop-color:#bdcccd;stop-opacity:1;"
+ offset="0"
+ id="stop5177-6-9-66" />
+ <stop
+ style="stop-color:#7979ff;stop-opacity:1;"
+ offset="1"
+ id="stop5179-73-8-1" />
+ </linearGradient>
+ <linearGradient
+ y2="16"
+ x2="15"
+ y1="1"
+ x1="0"
+ gradientTransform="translate(-40,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17755"
+ xlink:href="#linearGradient5175-3-7-0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="16"
+ x2="15"
+ y1="1"
+ x1="0"
+ gradientTransform="translate(-40,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient17616-2-6"
+ xlink:href="#linearGradient5175-3-7-9-2"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient5175-3-7-9-2">
+ <stop
+ style="stop-color:#bdcccd;stop-opacity:1;"
+ offset="0"
+ id="stop5177-6-9-6-1" />
+ <stop
+ style="stop-color:#7979ff;stop-opacity:1;"
+ offset="1"
+ id="stop5179-73-8-3-1" />
+ </linearGradient>
+ <linearGradient
+ y2="16"
+ x2="15"
+ y1="1"
+ x1="0"
+ gradientTransform="translate(-40,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient18010"
+ xlink:href="#linearGradient5175-3-7-9-2"
+ inkscape:collect="always" />
</defs>
<g
id="g19063"
@@ -88150,7 +89070,7 @@
y="318.55981"
x="166.52481"
id="tspan16195-0"
- sodipodi:role="line">%% Cfile %%</tspan></text>
+ sodipodi:role="line">%% Extension Cfile Pyfile wxGlade SVGUI %%</tspan></text>
<use
style="display:inline"
inkscape:label="#use3839"
@@ -88162,7 +89082,7 @@
y="0"
x="0" />
<g
- transform="translate(240.59375,323.65905)"
+ transform="translate(306.59375,321.65905)"
style="display:inline"
id="Cfile"
inkscape:export-xdpi="90"
@@ -88176,7 +89096,7 @@
inkscape:label="#rect2160" />
</g>
<g
- transform="matrix(0.48337242,0,0,0.48337242,-116.19489,195.05406)"
+ transform="matrix(0.48337242,0,0,0.48337242,-50.19489,193.05406)"
id="g20864-0">
<flowRoot
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient20956-0);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Andale Mono"
@@ -88421,4 +89341,613 @@
d="m 683.74504,273.49232 c -1.22386,-1.06852 -1.69077,-0.0713 -2.46786,0.60552 -0.16596,-0.14351 -0.33193,-0.28702 -0.49789,-0.43052 0.58126,-0.69698 0.87377,-1.06034 1.79321,-1.49705 0.18016,0.10818 0.89961,1.12667 1.17254,1.32205 z"
style="fill:url(#linearGradient18427);fill-opacity:1;fill-rule:evenodd;stroke:none" />
</g>
+ <g
+ transform="translate(340.16573,321.66009)"
+ style="display:inline"
+ id="Pyfile"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient18288-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m -40,0 0,16 16,0 0,-16 -16,0 z m 1,1 14,0 0,14 -14,0 0,-14 z"
+ id="path3806-1"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:label="#rect2160" />
+ </g>
+ <g
+ transform="matrix(0.48337242,0,0,0.48337242,-16.622911,193.05511)"
+ id="g20864-0-1">
+ <flowRoot
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient20956-0-4);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Andale Mono"
+ xml:space="preserve"
+ id="flowRoot20866-6-1"
+ transform="matrix(1.6473499,0,0,1.6473499,800.92342,263.57576)"><flowRegion
+ style="fill:url(#linearGradient20950-0-9);fill-opacity:1;stroke:url(#linearGradient20952-0-3)"
+ id="flowRegion20868-2-3"><rect
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient20948-9-2);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Andale Mono"
+ id="rect20870-8-5"
+ y="2.3818817"
+ x="-85.494621"
+ height="232.12506"
+ width="382.57648" /></flowRegion><flowPara
+ style="fill:url(#linearGradient20954-8-1);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="flowPara20872-9-1">Py</flowPara></flowRoot> <g
+ style="fill:#7f755d;fill-opacity:1"
+ transform="matrix(0.181771,-0.00401536,0.00591171,0.1804431,680.18691,229.08403)"
+ id="g20874-5-1">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20876-0-6"
+ d="m 1.4170205,261.85309 7.769385,-6.57914 c 0.765446,-1.05831 2.1914695,-2.72284 1.5255835,-4.7977 -0.665889,-2.07485 -5.2273365,-8.82612 -7.5721615,-9.77925 -1.386275,-0.90836 -2.42141895,-0.14712 -3.53780895,0.97913 l -7.97284325,7.1397 9.7878452,13.03726 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path20878-2-8"
+ d="m 6.3306155,244.87972 c 0,0 -2.616026,-2.68246 -3.762417,-3.01369 -1.146391,-0.33124 -2.78605395,0.63625 -2.78605395,0.63625 l -8.95013235,8.40586 4.9440407,3.25217 10.5545626,-9.28059 z"
+ style="fill-rule:evenodd;stroke:url(#linearGradient20958-4-9);stroke-width:0.12755789pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20880-7-3"
+ d="m 1.1712645,261.24893 8.55879,-7.37552 c 0.7654475,-1.05831 0.7879145,-1.59597 0.122028,-3.67082 -0.665879,-2.07487 -2.311691,-3.96225 -3.176211,-5.03563 -0.864515,-1.07336 -0.934989,-0.88783 -0.934989,-0.88783 l -9.9615162,8.67619 5.3918982,8.29361 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccccc"
+ id="path20882-2-1"
+ d="m 175.51025,216.82807 21.95339,16.91491 6.658,-2.15935 -1.95757,-24.45985 -5.06032,-7.39057 -24.29269,11.33659 2.69919,5.75827 z"
+ style="fill-rule:evenodd;stroke:#7f755d;stroke-width:0.25pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path20884-8-0"
+ d="m -116.9537,358.31756 16.25336,-21.84817 9.630572,6.6259 -25.883932,15.22227 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccc"
+ id="path20886-1-5"
+ d="m 107.78757,107.46646 65.87052,107.21317 7.55772,-4.67859 -66.95019,-108.29284 -6.47805,5.75826 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20888-7-8"
+ d="m -14.598686,260.57822 -85.10568,77.2095 -3.842104,-2.09678 84.095096,-76.57048 4.852688,1.45776 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccc"
+ id="path20890-7-9"
+ d="m 125.60221,97.389495 66.03955,106.895065 6.84287,-2.66312 -64.60491,-105.491566 -8.27751,1.259621 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20892-9-0"
+ d="m -9.830588,265.49155 -84.110342,74.87974 -2.59509,-5.77891 83.496785,-74.38768 3.208647,5.28685 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccccccccc"
+ id="path20894-7-7"
+ d="m 110.00338,110.582 c 1.2724,0.25448 6.11816,-5.21843 13.67588,-7.73767 7.55773,-2.51925 11.81997,-3.655376 12.7197,-4.914997 0.89973,-1.259621 0.0403,-4.234248 -3.05908,-4.498647 -3.24717,-0.277006 1.97492,-5.3986 -1.61951,-5.578322 -3.59892,-0.179946 -0.35989,-5.398375 -3.59892,-5.038484 -3.59475,0.399416 -8.99729,1.079675 -14.93551,3.598917 -5.93821,2.519242 -13.675879,7.557727 -14.03577,8.27751 -0.359892,0.719784 -0.89973,3.778863 1.79946,4.858538 2.69919,1.079675 -0.17995,3.239025 3.23902,5.038485 3.41898,1.79946 0.23641,6.8944 5.81473,5.99467 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccccc"
+ id="path20896-9-9"
+ d="m 173.64877,214.66374 7.4398,-4.83107 c 0,0 1.68699,3.03659 1.95691,5.37588 0.23524,2.03879 1.03469,4.25122 -0.56233,5.08348 -1.39074,0.72474 -2.40677,0.3149 -3.50894,-0.53984 -1.10217,-0.85474 -3.41897,-2.69919 -3.84635,-3.21653 -0.42737,-0.51735 -1.47909,-1.87192 -1.47909,-1.87192 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20898-8-3"
+ d="m -93.801751,340.32522 c 0,0 -4.095912,3.39042 -5.194629,3.96327 -1.09871,0.57284 -3.92138,1.30285 -4.23982,0.55371 -0.32654,-0.76824 0.98731,-2.98324 1.63991,-4.0857 0.65681,-1.10957 2.826585,-3.81262 3.157733,-4.17955 0.331148,-0.36694 1.995326,-1.9592 1.995326,-1.9592 l 2.64148,5.70747 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20900-8-4"
+ d="m -96.344601,334.49624 c -0.825291,0.986 -4.161619,4.62437 -5.987149,5.25831 -0.86127,0.49333 -2.11326,1.24051 -2.81892,1.23501 -0.70566,-0.006 -1.47333,0.41108 -0.24286,-1.51529 1.23047,-1.92638 1.7546,-3.108 3.69543,-5.00838 1.57427,-1.79583 3.769887,-3.3333 3.769887,-3.3333 l 1.583612,3.36365 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="cccccc"
+ id="path20902-9-8"
+ d="m 197.2837,233.653 7.73767,5.84824 -0.89973,-8.36748 c 0,0 -1.84825,-3.50031 -2.24932,-2.15935 -0.80976,2.69919 -1.25709,3.04451 -3.59892,1.70948 -2.37727,-1.3552 -0.9897,2.96911 -0.9897,2.96911 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.25pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20904-8-7"
+ d="m -20.117505,259.67677 c 4.654072,3.69244 6.467237,3.63487 9.644037,12.66822 5.4456249,-6.37534 8.5048862,-7.63703 12.7005112,-11.28509 -2.7465784,-5.39697 -4.9249749,-9.08941 -10.5124624,-11.98639 -3.8303928,4.55715 -6.6380568,6.6143 -11.8320858,10.60326 z"
+ style="opacity:0.66134183;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="cccccc"
+ id="path20906-0-1"
+ d="m 197.2837,233.653 7.73767,5.84824 -0.89973,-8.36748 c 0,0 -1.84825,-3.50031 -2.24932,-2.15935 -0.80976,2.69919 -1.25709,3.04451 -3.59892,1.70948 -2.37727,-1.3552 -0.9897,2.96911 -0.9897,2.96911 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20908-5-7"
+ d="m -3.0784244,252.19014 -13.3404576,11.17254 -2.594287,-2.38508 13.0932716,-10.60509 2.841473,1.81763 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20910-2-2"
+ d="m 9.6173564,249.29743 c -6.3752923,-5.91819 -9.05434448,-0.58695 -13.3404576,2.97653 -0.8647623,-0.79503 -1.7295247,-1.59005 -2.594287,-2.38508 3.2394813,-3.69574 4.8719016,-5.62371 9.8791499,-7.87309 0.9471577,0.60588 4.6263188,6.19364 6.0555947,7.28164 z"
+ style="fill-rule:evenodd;stroke:none" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20912-0-8"
+ d="m 682.29306,275.84865 1.4079,-1.24901 c 0.13622,-0.19892 0.39186,-0.51269 0.25521,-0.89377 -0.13666,-0.38107 -1.02757,-1.61115 -1.47029,-1.77782 -0.26383,-0.16232 -0.45211,-0.0172 -0.65332,0.19569 l -1.44241,1.35353 1.90291,2.37138 z"
+ style="fill:#ff7556;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path20914-2-6"
+ d="m 683.10581,272.68865 c 0,0 -0.50374,-0.48544 -0.71937,-0.54199 -0.21563,-0.0566 -0.5153,0.12916 -0.5153,0.12916 l -1.61686,1.59178 0.941,0.58124 1.91053,-1.76019 z"
+ style="fill:url(#linearGradient20960-0-8);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient20962-7-3);stroke-width:0.02369117pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20916-4-1"
+ d="m 682.2436,275.7379 1.55018,-1.39957 c 0.13622,-0.19892 0.13715,-0.29847 4.9e-4,-0.67954 -0.13666,-0.38107 -0.45478,-0.72343 -0.62238,-0.91843 -0.16761,-0.19499 -0.17961,-0.16038 -0.17961,-0.16038 l -1.80369,1.64594 1.05501,1.51198 z"
+ style="fill:url(#linearGradient20964-0-0);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20918-3-9"
+ d="m 665.03485,291.8397 -3.55147,2.04823 -0.50089,-0.41474 2.13093,-3.44443 1.09463,-0.96833 1.55424,2.00466 -0.72744,0.77461 z"
+ style="fill:url(#linearGradient20966-2-1);fill-opacity:1;fill-rule:evenodd;stroke:#7f755d;stroke-width:0.0312406pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path20920-7-5"
+ d="m 660.82006,294.1801 2.8963,-4.10843 1.83475,1.18603 -4.73105,2.9224 z"
+ style="fill:url(#linearGradient20968-8-5);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20922-3-1"
+ d="m 680.51064,277.3948 -15.11913,14.16958 -0.39251,-0.78734 15.31338,-14.30553 0.19826,0.92329 z"
+ style="fill:#d98100;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20924-0-2"
+ d="m 679.30091,275.67874 -15.39097,14.6327 -0.72866,-0.37205 15.20653,-14.51033 0.9131,0.24968 z"
+ style="fill:#eb9a00;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20926-0-8"
+ d="m 679.51026,275.6741 -15.11104,14.12163 -0.47972,-0.48933 14.85539,-13.94541 0.73537,0.31311 z"
+ style="fill:#ffe07a;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20928-1-4"
+ d="m 680.21919,276.56799 -15.21961,14.19764 -0.51861,-1.05831 15.10827,-14.10409 0.62995,0.96476 z"
+ style="fill:#f5a600;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccc"
+ id="path20930-5-5"
+ d="m 680.04086,277.80167 c -0.14846,0.0156 -0.20463,-0.84074 -0.76783,-1.3212 -0.56319,-0.48046 -0.90331,-0.71097 -0.8945,-0.90456 0.009,-0.19359 0.33064,-0.60241 0.66417,-0.58977 0.34944,0.0132 0.22754,-0.79922 0.60431,-0.76653 0.37724,0.0327 0.46303,-0.76137 0.76129,-0.65775 0.33103,0.115 0.8222,0.2992 1.22204,0.75342 0.39984,0.45423 0.78205,1.29563 0.76146,1.40375 -0.0206,0.10813 -0.20796,0.55162 -0.56557,0.66133 -0.3576,0.10971 -0.23788,0.46323 -0.72499,0.66357 -0.48711,0.20035 -0.56883,0.97598 -1.06038,0.75774 z"
+ style="fill:url(#linearGradient20970-8-2);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20932-8-3"
+ d="m 665.3937,291.56227 -0.36856,-0.8071 c 0,0 -0.4102,0.40422 -0.62234,0.7323 -0.18488,0.28593 -0.44041,0.5874 -0.34511,0.73155 0.083,0.12553 0.21788,0.0837 0.39662,-0.0199 0.17873,-0.10362 0.55823,-0.32821 0.64223,-0.39481 0.084,-0.0666 0.29716,-0.24207 0.29716,-0.24207 z"
+ style="fill:#d98100;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20934-0-7"
+ d="m 665.02523,290.75654 c 0,0 -0.7427,0.64402 -0.94397,0.75451 -0.20126,0.11049 -0.72282,0.25715 -0.7867,0.11988 -0.0655,-0.14077 0.1659,-0.55591 0.28082,-0.76253 0.11567,-0.20796 0.50361,-0.7169 0.5631,-0.78614 0.0595,-0.0692 0.35994,-0.37063 0.35994,-0.37063 l 0.52681,1.04491 z"
+ style="fill:#f5a600;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20936-0-9"
+ d="m 664.51606,289.68875 c -0.14781,0.18578 -0.74746,0.87255 -1.0838,0.99733 -0.1575,0.0948 -0.38627,0.23817 -0.5178,0.24006 -0.13153,0.002 -0.27205,0.0821 -0.0544,-0.2793 0.21762,-0.36141 0.30812,-0.58215 0.65827,-0.94167 0.28247,-0.33868 0.68229,-0.63212 0.68229,-0.63212 l 0.31548,0.6157 z"
+ style="fill:#ffe07a;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path20938-0-0"
+ d="m 661.50864,293.87805 -1.24277,0.70578 0.75218,-1.17458 c 0,0 0.46311,-0.4675 0.39757,-0.27044 -0.13168,0.39672 -0.11386,0.45304 0.22789,0.30125 0.34692,-0.15408 -0.13487,0.43799 -0.13487,0.43799 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.0312406pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20940-4-7"
+ d="m 678.26705,275.53471 c 0.88963,0.66388 1.22716,0.64576 1.87388,2.3037 0.97612,-1.20174 1.53854,-1.44773 2.29826,-2.13982 -0.54451,-0.98704 -0.97282,-1.66111 -2.03157,-2.174 -0.68615,0.85876 -1.19687,1.25085 -2.14057,2.01012 z"
+ style="opacity:0.66134183;fill:url(#linearGradient20972-1-9);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path20942-7-2"
+ d="m 661.50864,293.87805 -1.24277,0.70578 0.75218,-1.17458 c 0,0 0.46311,-0.4675 0.39757,-0.27044 -0.13168,0.39672 -0.11386,0.45304 0.22789,0.30125 0.34692,-0.15408 -0.13487,0.43799 -0.13487,0.43799 z"
+ style="fill:url(#linearGradient20974-5-0);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20944-5-3"
+ d="m 681.35307,274.03857 -2.37447,2.16274 -0.49788,-0.43052 2.30861,-2.11935 0.56374,0.38713 z"
+ style="fill:url(#linearGradient20977-9-3);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20946-3-7"
+ d="m 683.74504,273.49232 c -1.22386,-1.06852 -1.69077,-0.0713 -2.46786,0.60552 -0.16596,-0.14351 -0.33193,-0.28702 -0.49789,-0.43052 0.58126,-0.69698 0.87377,-1.06034 1.79321,-1.49705 0.18016,0.10818 0.89961,1.12667 1.17254,1.32205 z"
+ style="fill:url(#linearGradient18427-9);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ </g>
+ <g
+ transform="translate(254.35096,322.61608)"
+ style="display:inline"
+ id="Extension"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient17616-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m -40,0 0,16 16,0 0,-16 -16,0 z m 1,1 14,0 0,14 -14,0 0,-14 z"
+ id="path3806-1-6"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:label="#rect2160" />
+ </g>
+ <path
+ style="color:#000000;fill:url(#linearGradient20956-0-4-4);fill-opacity:1;fill-rule:nonzero;stroke:#547c1b;stroke-width:0.0845204;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 221.83496,325.42773 c -0.6638,0 -1.20229,0.52766 -1.21875,1.1875 l -3.0625,0 0,3.09375 c 0.0105,-2.7e-4 0.0207,0 0.0312,0 0.67418,0 1.21875,0.54457 1.21875,1.21875 0,0.67418 -0.54457,1.21875 -1.21875,1.21875 -0.0104,0 -0.0209,2.6e-4 -0.0312,0 l 0,3.0625 3.0625,0 c -2.6e-4,-0.0103 0,-0.0209 0,-0.0312 0,-0.67418 0.54457,-1.21875 1.21875,-1.21875 0.67418,0 1.21875,0.54457 1.21875,1.21875 0,0.0104 2.6e-4,0.0209 0,0.0312 l 3.0625,0 0,-3.0625 c 0.67418,0 1.21875,-0.54457 1.21875,-1.21875 0,-0.67418 -0.54457,-1.21875 -1.21875,-1.21875 l 0,-3.09375 -3.0625,0 c -0.0165,-0.65984 -0.55495,-1.1875 -1.21875,-1.1875 z"
+ id="rect17637"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="translate(391.49198,321.23503)"
+ style="display:inline"
+ id="wxGlade"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient17755);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m -40,0 0,16 16,0 0,-16 -16,0 z m 1,1 14,0 0,14 -14,0 0,-14 z"
+ id="path3806-1-8"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:label="#rect2160" />
+ </g>
+ <g
+ transform="matrix(0.48337242,0,0,0.48337242,34.703335,192.63005)"
+ id="g20864-0-1-3">
+ <flowRoot
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient20956-0-4-6);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Andale Mono"
+ xml:space="preserve"
+ id="flowRoot20866-6-1-0"
+ transform="matrix(1.6473499,0,0,1.6473499,800.92342,263.57576)"><flowRegion
+ style="fill:url(#linearGradient20950-0-9-0);fill-opacity:1;stroke:url(#linearGradient20952-0-3-3)"
+ id="flowRegion20868-2-3-9"><rect
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient20948-9-2-8);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Andale Mono"
+ id="rect20870-8-5-2"
+ y="2.3818817"
+ x="-85.494621"
+ height="232.12506"
+ width="382.57648" /></flowRegion><flowPara
+ style="fill:url(#linearGradient20954-8-1-9);fill-opacity:1;stroke:#547c1b;stroke-width:0.1061436;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="flowPara20872-9-1-0">Wx</flowPara></flowRoot> <g
+ style="fill:#7f755d;fill-opacity:1"
+ transform="matrix(0.181771,-0.00401536,0.00591171,0.1804431,680.18691,229.08403)"
+ id="g20874-5-1-3">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20876-0-6-5"
+ d="m 1.4170205,261.85309 7.769385,-6.57914 c 0.765446,-1.05831 2.1914695,-2.72284 1.5255835,-4.7977 -0.665889,-2.07485 -5.2273365,-8.82612 -7.5721615,-9.77925 -1.386275,-0.90836 -2.42141895,-0.14712 -3.53780895,0.97913 l -7.97284325,7.1397 9.7878452,13.03726 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path20878-2-8-1"
+ d="m 6.3306155,244.87972 c 0,0 -2.616026,-2.68246 -3.762417,-3.01369 -1.146391,-0.33124 -2.78605395,0.63625 -2.78605395,0.63625 l -8.95013235,8.40586 4.9440407,3.25217 10.5545626,-9.28059 z"
+ style="fill-rule:evenodd;stroke:url(#linearGradient20958-4-9-9);stroke-width:0.12755789pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20880-7-3-7"
+ d="m 1.1712645,261.24893 8.55879,-7.37552 c 0.7654475,-1.05831 0.7879145,-1.59597 0.122028,-3.67082 -0.665879,-2.07487 -2.311691,-3.96225 -3.176211,-5.03563 -0.864515,-1.07336 -0.934989,-0.88783 -0.934989,-0.88783 l -9.9615162,8.67619 5.3918982,8.29361 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccccc"
+ id="path20882-2-1-0"
+ d="m 175.51025,216.82807 21.95339,16.91491 6.658,-2.15935 -1.95757,-24.45985 -5.06032,-7.39057 -24.29269,11.33659 2.69919,5.75827 z"
+ style="fill-rule:evenodd;stroke:#7f755d;stroke-width:0.25pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path20884-8-0-5"
+ d="m -116.9537,358.31756 16.25336,-21.84817 9.630572,6.6259 -25.883932,15.22227 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccc"
+ id="path20886-1-5-6"
+ d="m 107.78757,107.46646 65.87052,107.21317 7.55772,-4.67859 -66.95019,-108.29284 -6.47805,5.75826 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20888-7-8-9"
+ d="m -14.598686,260.57822 -85.10568,77.2095 -3.842104,-2.09678 84.095096,-76.57048 4.852688,1.45776 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccc"
+ id="path20890-7-9-9"
+ d="m 125.60221,97.389495 66.03955,106.895065 6.84287,-2.66312 -64.60491,-105.491566 -8.27751,1.259621 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20892-9-0-3"
+ d="m -9.830588,265.49155 -84.110342,74.87974 -2.59509,-5.77891 83.496785,-74.38768 3.208647,5.28685 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccccccccc"
+ id="path20894-7-7-3"
+ d="m 110.00338,110.582 c 1.2724,0.25448 6.11816,-5.21843 13.67588,-7.73767 7.55773,-2.51925 11.81997,-3.655376 12.7197,-4.914997 0.89973,-1.259621 0.0403,-4.234248 -3.05908,-4.498647 -3.24717,-0.277006 1.97492,-5.3986 -1.61951,-5.578322 -3.59892,-0.179946 -0.35989,-5.398375 -3.59892,-5.038484 -3.59475,0.399416 -8.99729,1.079675 -14.93551,3.598917 -5.93821,2.519242 -13.675879,7.557727 -14.03577,8.27751 -0.359892,0.719784 -0.89973,3.778863 1.79946,4.858538 2.69919,1.079675 -0.17995,3.239025 3.23902,5.038485 3.41898,1.79946 0.23641,6.8944 5.81473,5.99467 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="ccccccc"
+ id="path20896-9-9-7"
+ d="m 173.64877,214.66374 7.4398,-4.83107 c 0,0 1.68699,3.03659 1.95691,5.37588 0.23524,2.03879 1.03469,4.25122 -0.56233,5.08348 -1.39074,0.72474 -2.40677,0.3149 -3.50894,-0.53984 -1.10217,-0.85474 -3.41897,-2.69919 -3.84635,-3.21653 -0.42737,-0.51735 -1.47909,-1.87192 -1.47909,-1.87192 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20898-8-3-8"
+ d="m -93.801751,340.32522 c 0,0 -4.095912,3.39042 -5.194629,3.96327 -1.09871,0.57284 -3.92138,1.30285 -4.23982,0.55371 -0.32654,-0.76824 0.98731,-2.98324 1.63991,-4.0857 0.65681,-1.10957 2.826585,-3.81262 3.157733,-4.17955 0.331148,-0.36694 1.995326,-1.9592 1.995326,-1.9592 l 2.64148,5.70747 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20900-8-4-8"
+ d="m -96.344601,334.49624 c -0.825291,0.986 -4.161619,4.62437 -5.987149,5.25831 -0.86127,0.49333 -2.11326,1.24051 -2.81892,1.23501 -0.70566,-0.006 -1.47333,0.41108 -0.24286,-1.51529 1.23047,-1.92638 1.7546,-3.108 3.69543,-5.00838 1.57427,-1.79583 3.769887,-3.3333 3.769887,-3.3333 l 1.583612,3.36365 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="cccccc"
+ id="path20902-9-8-5"
+ d="m 197.2837,233.653 7.73767,5.84824 -0.89973,-8.36748 c 0,0 -1.84825,-3.50031 -2.24932,-2.15935 -0.80976,2.69919 -1.25709,3.04451 -3.59892,1.70948 -2.37727,-1.3552 -0.9897,2.96911 -0.9897,2.96911 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:0.25pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20904-8-7-3"
+ d="m -20.117505,259.67677 c 4.654072,3.69244 6.467237,3.63487 9.644037,12.66822 5.4456249,-6.37534 8.5048862,-7.63703 12.7005112,-11.28509 -2.7465784,-5.39697 -4.9249749,-9.08941 -10.5124624,-11.98639 -3.8303928,4.55715 -6.6380568,6.6143 -11.8320858,10.60326 z"
+ style="opacity:0.66134183;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ transform="matrix(-0.538066,-0.09955063,-0.448862,0.758281,97.82153,199.2334)"
+ sodipodi:nodetypes="cccccc"
+ id="path20906-0-1-7"
+ d="m 197.2837,233.653 7.73767,5.84824 -0.89973,-8.36748 c 0,0 -1.84825,-3.50031 -2.24932,-2.15935 -0.80976,2.69919 -1.25709,3.04451 -3.59892,1.70948 -2.37727,-1.3552 -0.9897,2.96911 -0.9897,2.96911 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20908-5-7-9"
+ d="m -3.0784244,252.19014 -13.3404576,11.17254 -2.594287,-2.38508 13.0932716,-10.60509 2.841473,1.81763 z"
+ style="fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20910-2-2-1"
+ d="m 9.6173564,249.29743 c -6.3752923,-5.91819 -9.05434448,-0.58695 -13.3404576,2.97653 -0.8647623,-0.79503 -1.7295247,-1.59005 -2.594287,-2.38508 3.2394813,-3.69574 4.8719016,-5.62371 9.8791499,-7.87309 0.9471577,0.60588 4.6263188,6.19364 6.0555947,7.28164 z"
+ style="fill-rule:evenodd;stroke:none" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20912-0-8-9"
+ d="m 682.29306,275.84865 1.4079,-1.24901 c 0.13622,-0.19892 0.39186,-0.51269 0.25521,-0.89377 -0.13666,-0.38107 -1.02757,-1.61115 -1.47029,-1.77782 -0.26383,-0.16232 -0.45211,-0.0172 -0.65332,0.19569 l -1.44241,1.35353 1.90291,2.37138 z"
+ style="fill:#ff7556;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path20914-2-6-9"
+ d="m 683.10581,272.68865 c 0,0 -0.50374,-0.48544 -0.71937,-0.54199 -0.21563,-0.0566 -0.5153,0.12916 -0.5153,0.12916 l -1.61686,1.59178 0.941,0.58124 1.91053,-1.76019 z"
+ style="fill:url(#linearGradient20960-0-8-0);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient20962-7-3-8);stroke-width:0.02369117pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20916-4-1-7"
+ d="m 682.2436,275.7379 1.55018,-1.39957 c 0.13622,-0.19892 0.13715,-0.29847 4.9e-4,-0.67954 -0.13666,-0.38107 -0.45478,-0.72343 -0.62238,-0.91843 -0.16761,-0.19499 -0.17961,-0.16038 -0.17961,-0.16038 l -1.80369,1.64594 1.05501,1.51198 z"
+ style="fill:url(#linearGradient20964-0-0-1);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20918-3-9-5"
+ d="m 665.03485,291.8397 -3.55147,2.04823 -0.50089,-0.41474 2.13093,-3.44443 1.09463,-0.96833 1.55424,2.00466 -0.72744,0.77461 z"
+ style="fill:url(#linearGradient20966-2-1-4);fill-opacity:1;fill-rule:evenodd;stroke:#7f755d;stroke-width:0.0312406pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path20920-7-5-0"
+ d="m 660.82006,294.1801 2.8963,-4.10843 1.83475,1.18603 -4.73105,2.9224 z"
+ style="fill:url(#linearGradient20968-8-5-5);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20922-3-1-8"
+ d="m 680.51064,277.3948 -15.11913,14.16958 -0.39251,-0.78734 15.31338,-14.30553 0.19826,0.92329 z"
+ style="fill:#d98100;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20924-0-2-6"
+ d="m 679.30091,275.67874 -15.39097,14.6327 -0.72866,-0.37205 15.20653,-14.51033 0.9131,0.24968 z"
+ style="fill:#eb9a00;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20926-0-8-4"
+ d="m 679.51026,275.6741 -15.11104,14.12163 -0.47972,-0.48933 14.85539,-13.94541 0.73537,0.31311 z"
+ style="fill:#ffe07a;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20928-1-4-0"
+ d="m 680.21919,276.56799 -15.21961,14.19764 -0.51861,-1.05831 15.10827,-14.10409 0.62995,0.96476 z"
+ style="fill:#f5a600;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccc"
+ id="path20930-5-5-5"
+ d="m 680.04086,277.80167 c -0.14846,0.0156 -0.20463,-0.84074 -0.76783,-1.3212 -0.56319,-0.48046 -0.90331,-0.71097 -0.8945,-0.90456 0.009,-0.19359 0.33064,-0.60241 0.66417,-0.58977 0.34944,0.0132 0.22754,-0.79922 0.60431,-0.76653 0.37724,0.0327 0.46303,-0.76137 0.76129,-0.65775 0.33103,0.115 0.8222,0.2992 1.22204,0.75342 0.39984,0.45423 0.78205,1.29563 0.76146,1.40375 -0.0206,0.10813 -0.20796,0.55162 -0.56557,0.66133 -0.3576,0.10971 -0.23788,0.46323 -0.72499,0.66357 -0.48711,0.20035 -0.56883,0.97598 -1.06038,0.75774 z"
+ style="fill:url(#linearGradient20970-8-2-4);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20932-8-3-8"
+ d="m 665.3937,291.56227 -0.36856,-0.8071 c 0,0 -0.4102,0.40422 -0.62234,0.7323 -0.18488,0.28593 -0.44041,0.5874 -0.34511,0.73155 0.083,0.12553 0.21788,0.0837 0.39662,-0.0199 0.17873,-0.10362 0.55823,-0.32821 0.64223,-0.39481 0.084,-0.0666 0.29716,-0.24207 0.29716,-0.24207 z"
+ style="fill:#d98100;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20934-0-7-0"
+ d="m 665.02523,290.75654 c 0,0 -0.7427,0.64402 -0.94397,0.75451 -0.20126,0.11049 -0.72282,0.25715 -0.7867,0.11988 -0.0655,-0.14077 0.1659,-0.55591 0.28082,-0.76253 0.11567,-0.20796 0.50361,-0.7169 0.5631,-0.78614 0.0595,-0.0692 0.35994,-0.37063 0.35994,-0.37063 l 0.52681,1.04491 z"
+ style="fill:#f5a600;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ id="path20936-0-9-0"
+ d="m 664.51606,289.68875 c -0.14781,0.18578 -0.74746,0.87255 -1.0838,0.99733 -0.1575,0.0948 -0.38627,0.23817 -0.5178,0.24006 -0.13153,0.002 -0.27205,0.0821 -0.0544,-0.2793 0.21762,-0.36141 0.30812,-0.58215 0.65827,-0.94167 0.28247,-0.33868 0.68229,-0.63212 0.68229,-0.63212 l 0.31548,0.6157 z"
+ style="fill:#ffe07a;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path20938-0-0-5"
+ d="m 661.50864,293.87805 -1.24277,0.70578 0.75218,-1.17458 c 0,0 0.46311,-0.4675 0.39757,-0.27044 -0.13168,0.39672 -0.11386,0.45304 0.22789,0.30125 0.34692,-0.15408 -0.13487,0.43799 -0.13487,0.43799 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.0312406pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20940-4-7-1"
+ d="m 678.26705,275.53471 c 0.88963,0.66388 1.22716,0.64576 1.87388,2.3037 0.97612,-1.20174 1.53854,-1.44773 2.29826,-2.13982 -0.54451,-0.98704 -0.97282,-1.66111 -2.03157,-2.174 -0.68615,0.85876 -1.19687,1.25085 -2.14057,2.01012 z"
+ style="opacity:0.66134183;fill:url(#linearGradient20972-1-9-5);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path20942-7-2-7"
+ d="m 661.50864,293.87805 -1.24277,0.70578 0.75218,-1.17458 c 0,0 0.46311,-0.4675 0.39757,-0.27044 -0.13168,0.39672 -0.11386,0.45304 0.22789,0.30125 0.34692,-0.15408 -0.13487,0.43799 -0.13487,0.43799 z"
+ style="fill:url(#linearGradient20974-5-0-5);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20944-5-3-8"
+ d="m 681.35307,274.03857 -2.37447,2.16274 -0.49788,-0.43052 2.30861,-2.11935 0.56374,0.38713 z"
+ style="fill:url(#linearGradient20977-9-3-4);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path20946-3-7-8"
+ d="m 683.74504,273.49232 c -1.22386,-1.06852 -1.69077,-0.0713 -2.46786,0.60552 -0.16596,-0.14351 -0.33193,-0.28702 -0.49789,-0.43052 0.58126,-0.69698 0.87377,-1.06034 1.79321,-1.49705 0.18016,0.10818 0.89961,1.12667 1.17254,1.32205 z"
+ style="fill:url(#linearGradient18427-9-5);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ </g>
+ <g
+ transform="translate(444.93931,321.78746)"
+ style="display:inline"
+ id="SVGUI"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient18010);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
+ d="m -40,0 0,16 16,0 0,-16 -16,0 z m 1,1 14,0 0,14 -14,0 0,-14 z"
+ id="path3806-1-6-1"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:label="#rect2160" />
+ </g>
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g17987"
+ id="use18031"
+ transform="matrix(0.53388959,0,0,0.53388959,278.35752,221.2112)"
+ width="744.09448"
+ height="1052.3622" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#HMIEditor"
+ id="use18033"
+ transform="matrix(0.53388959,0,0,0.53388959,278.35752,221.2112)"
+ width="744.09448"
+ height="1052.3622" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g17590"
+ id="use18035"
+ transform="matrix(0.53388959,0,0,0.53388959,278.35752,221.2112)"
+ width="744.09448"
+ height="1052.3622" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g17603"
+ id="use18037"
+ transform="matrix(0.53388959,0,0,0.53388959,278.35752,221.2112)"
+ width="744.09448"
+ height="1052.3622" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path17627"
+ id="use18039"
+ transform="matrix(0.53388959,0,0,0.53388959,278.35752,221.2112)"
+ width="744.09448"
+ height="1052.3622" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path17629"
+ id="use18041"
+ transform="matrix(0.53388959,0,0,0.53388959,278.35752,221.2112)"
+ width="744.09448"
+ height="1052.3622" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g17968"
+ id="use18043"
+ transform="matrix(0.53388959,0,0,0.53388959,278.35752,221.2112)"
+ width="744.09448"
+ height="1052.3622" />
</svg>
Binary file images/wxGlade.png has changed
--- a/py_ext/PythonEditor.py Mon May 21 02:49:53 2012 +0200
+++ b/py_ext/PythonEditor.py Mon May 21 10:04:27 2012 +0200
@@ -1,10 +1,9 @@
-import wx, wx.grid
-import wx.stc as stc
+import wx
+import wx.grid
+import wx.stc as stc
import keyword
-from util import opjimg
-
-from controls import EditorPanel
+from ConfTreeNodeEditor import ConfTreeNodeEditor
if wx.Platform == '__WXMSW__':
faces = { 'times': 'Times New Roman',
@@ -55,197 +54,186 @@
else:
return None
-class PythonEditor(EditorPanel):
+class PythonEditor(ConfTreeNodeEditor):
fold_symbols = 3
- def _init_Editor(self, prnt):
- self.Editor = stc.StyledTextCtrl(id=ID_PYTHONEDITOR, parent=prnt,
+ def _init_ConfNodeEditor(self, prnt):
+ self.ConfNodeEditor = stc.StyledTextCtrl(id=ID_PYTHONEDITOR, parent=prnt,
name="TextViewer", pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0)
- self.Editor.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
- self.Editor.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
-
- self.Editor.SetLexer(stc.STC_LEX_PYTHON)
- self.Editor.SetKeyWords(0, " ".join(keyword.kwlist))
-
- self.Editor.SetProperty("fold", "1")
- self.Editor.SetProperty("tab.timmy.whinge.level", "1")
- self.Editor.SetMargins(0,0)
-
- self.Editor.SetViewWhiteSpace(False)
-
- self.Editor.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
- self.Editor.SetEdgeColumn(78)
+ self.ConfNodeEditor.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
+ self.ConfNodeEditor.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
+
+ self.ConfNodeEditor.SetLexer(stc.STC_LEX_PYTHON)
+ self.ConfNodeEditor.SetKeyWords(0, " ".join(keyword.kwlist))
+
+ self.ConfNodeEditor.SetProperty("fold", "1")
+ self.ConfNodeEditor.SetProperty("tab.timmy.whinge.level", "1")
+ self.ConfNodeEditor.SetMargins(0,0)
+
+ self.ConfNodeEditor.SetViewWhiteSpace(False)
+
+ self.ConfNodeEditor.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
+ self.ConfNodeEditor.SetEdgeColumn(78)
# Set up the numbers in the margin for margin #1
- self.Editor.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
+ self.ConfNodeEditor.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
# Reasonable value for, say, 4-5 digits using a mono font (40 pix)
- self.Editor.SetMarginWidth(1, 40)
+ self.ConfNodeEditor.SetMarginWidth(1, 40)
# Setup a margin to hold fold markers
- self.Editor.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
- self.Editor.SetMarginMask(2, stc.STC_MASK_FOLDERS)
- self.Editor.SetMarginSensitive(2, True)
- self.Editor.SetMarginWidth(2, 12)
+ self.ConfNodeEditor.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
+ self.ConfNodeEditor.SetMarginMask(2, stc.STC_MASK_FOLDERS)
+ self.ConfNodeEditor.SetMarginSensitive(2, True)
+ self.ConfNodeEditor.SetMarginWidth(2, 12)
if self.fold_symbols == 0:
# Arrow pointing right for contracted folders, arrow pointing down for expanded
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_ARROWDOWN, "black", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_ARROW, "black", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "black", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "black", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_ARROWDOWN, "black", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_ARROW, "black", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "black", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "black", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
elif self.fold_symbols == 1:
# Plus for contracted folders, minus for expanded
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_MINUS, "white", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_PLUS, "white", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "white", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "white", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_MINUS, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_PLUS, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
elif self.fold_symbols == 2:
# Like a flattened tree control using circular headers and curved joins
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_CIRCLEMINUS, "white", "#404040")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_CIRCLEPLUS, "white", "#404040")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#404040")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNERCURVE, "white", "#404040")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE, "white", "#404040")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_CIRCLEMINUS, "white", "#404040")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_CIRCLEPLUS, "white", "#404040")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#404040")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNERCURVE, "white", "#404040")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE, "white", "#404040")
elif self.fold_symbols == 3:
# Like a flattened tree control using square headers
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "#808080")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "#808080")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#808080")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "#808080")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
- self.Editor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "#808080")
-
-
- self.Editor.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
- self.Editor.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
- self.Editor.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "#808080")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "#808080")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#808080")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "#808080")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
+ self.ConfNodeEditor.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "#808080")
+
+
+ self.ConfNodeEditor.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
+ self.ConfNodeEditor.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
+ self.ConfNodeEditor.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
# Global default style
if wx.Platform == '__WXMSW__':
- self.Editor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier New')
+ self.ConfNodeEditor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier New')
elif wx.Platform == '__WXMAC__':
# TODO: if this looks fine on Linux too, remove the Mac-specific case
# and use this whenever OS != MSW.
- self.Editor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Monaco')
+ self.ConfNodeEditor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Monaco')
else:
defsize = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT).GetPointSize()
- self.Editor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier,size:%d'%defsize)
+ self.ConfNodeEditor.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:#000000,back:#FFFFFF,face:Courier,size:%d'%defsize)
# Clear styles and revert to default.
- self.Editor.StyleClearAll()
+ self.ConfNodeEditor.StyleClearAll()
# Following style specs only indicate differences from default.
# The rest remains unchanged.
# Line numbers in margin
- self.Editor.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,'fore:#000000,back:#99A9C2')
# Highlighted brace
- self.Editor.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT,'fore:#00009D,back:#FFFF00')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT,'fore:#00009D,back:#FFFF00')
# Unmatched brace
- self.Editor.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD,'fore:#00009D,back:#FF0000')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD,'fore:#00009D,back:#FF0000')
# Indentation guide
- self.Editor.StyleSetSpec(wx.stc.STC_STYLE_INDENTGUIDE, "fore:#CDCDCD")
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_STYLE_INDENTGUIDE, "fore:#CDCDCD")
# Python styles
- self.Editor.StyleSetSpec(wx.stc.STC_P_DEFAULT, 'fore:#000000')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_DEFAULT, 'fore:#000000')
# Comments
- self.Editor.StyleSetSpec(wx.stc.STC_P_COMMENTLINE, 'fore:#008000,back:#F0FFF0')
- self.Editor.StyleSetSpec(wx.stc.STC_P_COMMENTBLOCK, 'fore:#008000,back:#F0FFF0')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_COMMENTLINE, 'fore:#008000,back:#F0FFF0')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_COMMENTBLOCK, 'fore:#008000,back:#F0FFF0')
# Numbers
- self.Editor.StyleSetSpec(wx.stc.STC_P_NUMBER, 'fore:#008080')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_NUMBER, 'fore:#008080')
# Strings and characters
- self.Editor.StyleSetSpec(wx.stc.STC_P_STRING, 'fore:#800080')
- self.Editor.StyleSetSpec(wx.stc.STC_P_CHARACTER, 'fore:#800080')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_STRING, 'fore:#800080')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_CHARACTER, 'fore:#800080')
# Keywords
- self.Editor.StyleSetSpec(wx.stc.STC_P_WORD, 'fore:#000080,bold')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_WORD, 'fore:#000080,bold')
# Triple quotes
- self.Editor.StyleSetSpec(wx.stc.STC_P_TRIPLE, 'fore:#800080,back:#FFFFEA')
- self.Editor.StyleSetSpec(wx.stc.STC_P_TRIPLEDOUBLE, 'fore:#800080,back:#FFFFEA')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_TRIPLE, 'fore:#800080,back:#FFFFEA')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_TRIPLEDOUBLE, 'fore:#800080,back:#FFFFEA')
# Class names
- self.Editor.StyleSetSpec(wx.stc.STC_P_CLASSNAME, 'fore:#0000FF,bold')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_CLASSNAME, 'fore:#0000FF,bold')
# Function names
- self.Editor.StyleSetSpec(wx.stc.STC_P_DEFNAME, 'fore:#008080,bold')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_DEFNAME, 'fore:#008080,bold')
# Operators
- self.Editor.StyleSetSpec(wx.stc.STC_P_OPERATOR, 'fore:#800000,bold')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_OPERATOR, 'fore:#800000,bold')
# Identifiers. I leave this as not bold because everything seems
# to be an identifier if it doesn't match the above criterae
- self.Editor.StyleSetSpec(wx.stc.STC_P_IDENTIFIER, 'fore:#000000')
+ self.ConfNodeEditor.StyleSetSpec(wx.stc.STC_P_IDENTIFIER, 'fore:#000000')
# Caret color
- self.Editor.SetCaretForeground("BLUE")
+ self.ConfNodeEditor.SetCaretForeground("BLUE")
# Selection background
- self.Editor.SetSelBackground(1, '#66CCFF')
-
- self.Editor.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
- self.Editor.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
+ self.ConfNodeEditor.SetSelBackground(1, '#66CCFF')
+
+ self.ConfNodeEditor.SetSelBackground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
+ self.ConfNodeEditor.SetSelForeground(True, wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
# register some images for use in the AutoComplete box.
#self.RegisterImage(1, images.getSmilesBitmap())
- self.Editor.RegisterImage(1,
+ self.ConfNodeEditor.RegisterImage(1,
wx.ArtProvider.GetBitmap(wx.ART_DELETE, size=(16,16)))
- self.Editor.RegisterImage(2,
+ self.ConfNodeEditor.RegisterImage(2,
wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16,16)))
- self.Editor.RegisterImage(3,
+ self.ConfNodeEditor.RegisterImage(3,
wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16,16)))
# Indentation and tab stuff
- self.Editor.SetIndent(4) # Proscribed indent size for wx
- self.Editor.SetIndentationGuides(True) # Show indent guides
- self.Editor.SetBackSpaceUnIndents(True)# Backspace unindents rather than delete 1 space
- self.Editor.SetTabIndents(True) # Tab key indents
- self.Editor.SetTabWidth(4) # Proscribed tab size for wx
- self.Editor.SetUseTabs(False) # Use spaces rather than tabs, or
+ self.ConfNodeEditor.SetIndent(4) # Proscribed indent size for wx
+ self.ConfNodeEditor.SetIndentationGuides(True) # Show indent guides
+ self.ConfNodeEditor.SetBackSpaceUnIndents(True)# Backspace unindents rather than delete 1 space
+ self.ConfNodeEditor.SetTabIndents(True) # Tab key indents
+ self.ConfNodeEditor.SetTabWidth(4) # Proscribed tab size for wx
+ self.ConfNodeEditor.SetUseTabs(False) # Use spaces rather than tabs, or
# TabTimmy will complain!
# White space
- self.Editor.SetViewWhiteSpace(False) # Don't view white space
+ self.ConfNodeEditor.SetViewWhiteSpace(False) # Don't view white space
# EOL: Since we are loading/saving ourselves, and the
# strings will always have \n's in them, set the STC to
# edit them that way.
- self.Editor.SetEOLMode(wx.stc.STC_EOL_LF)
- self.Editor.SetViewEOL(False)
+ self.ConfNodeEditor.SetEOLMode(wx.stc.STC_EOL_LF)
+ self.ConfNodeEditor.SetViewEOL(False)
# No right-edge mode indicator
- self.Editor.SetEdgeMode(stc.STC_EDGE_NONE)
-
- self.Editor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE)
-
- self.Editor.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_PYTHONEDITOR)
- self.Editor.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
- self.Editor.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_PYTHONEDITOR)
+ self.ConfNodeEditor.SetEdgeMode(stc.STC_EDGE_NONE)
+
+ self.ConfNodeEditor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE)
+
+ self.ConfNodeEditor.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_PYTHONEDITOR)
+ self.ConfNodeEditor.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
+ self.ConfNodeEditor.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_PYTHONEDITOR)
def __init__(self, parent, controler, window):
- EditorPanel.__init__(self, parent, "", window, controler)
+ ConfTreeNodeEditor.__init__(self, parent, "", controler, window)
self.DisableEvents = False
self.CurrentAction = None
-
- self.SetIcon(wx.Bitmap(opjimg("Cfile")))
-
- def __del__(self):
- self.Controler.OnCloseEditor(self)
-
- def GetTitle(self):
- fullname = self.Controler.CTNFullName()
- if not self.Controler.PythonIsSaved():
- return "~%s~" % fullname
- return fullname
def GetBufferState(self):
return self.Controler.GetBufferState()
@@ -258,9 +246,6 @@
self.Controler.LoadNext()
self.RefreshView()
- def HasNoModel(self):
- return False
-
def OnModification(self, event):
if not self.DisableEvents:
mod_type = event.GetModificationType()
@@ -313,50 +298,43 @@
def RefreshView(self):
self.ResetBuffer()
self.DisableEvents = True
- old_cursor_pos = self.Editor.GetCurrentPos()
- old_text = self.Editor.GetText()
+ old_cursor_pos = self.ConfNodeEditor.GetCurrentPos()
+ old_text = self.ConfNodeEditor.GetText()
new_text = self.Controler.GetPythonCode()
- self.Editor.SetText(new_text)
+ self.ConfNodeEditor.SetText(new_text)
new_cursor_pos = GetCursorPos(old_text, new_text)
if new_cursor_pos != None:
- self.Editor.GotoPos(new_cursor_pos)
- else:
- self.Editor.GotoPos(old_cursor_pos)
- self.Editor.ScrollToColumn(0)
- self.Editor.EmptyUndoBuffer()
+ self.ConfNodeEditor.GotoPos(new_cursor_pos)
+ else:
+ self.ConfNodeEditor.GotoPos(old_cursor_pos)
+ self.ConfNodeEditor.ScrollToColumn(0)
+ self.ConfNodeEditor.EmptyUndoBuffer()
self.DisableEvents = False
- self.Editor.Colourise(0, -1)
+ self.ConfNodeEditor.Colourise(0, -1)
def RefreshModel(self):
- self.Controler.SetPythonCode(self.Editor.GetText())
+ self.Controler.SetPythonCode(self.ConfNodeEditor.GetText())
def OnKeyPressed(self, event):
- if self.Editor.CallTipActive():
- self.Editor.CallTipCancel()
+ if self.ConfNodeEditor.CallTipActive():
+ self.ConfNodeEditor.CallTipCancel()
key = event.GetKeyCode()
if key == 32 and event.ControlDown():
- pos = self.Editor.GetCurrentPos()
-
- # Tips
- if event.ShiftDown():
- pass
-## self.CallTipSetBackground("yellow")
-## self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
-## 'show some suff, maybe parameters..\n\n'
-## 'fubar(param1, param2)')
+ pos = self.ConfNodeEditor.GetCurrentPos()
+
# Code completion
- else:
- self.Editor.AutoCompSetIgnoreCase(False) # so this needs to match
+ if not event.ShiftDown():
+ self.ConfNodeEditor.AutoCompSetIgnoreCase(False) # so this needs to match
# Images are specified with a appended "?type"
- self.Editor.AutoCompShow(0, " ".join([word + "?1" for word in keyword.kwlist]))
+ self.ConfNodeEditor.AutoCompShow(0, " ".join([word + "?1" for word in keyword.kwlist]))
else:
event.Skip()
def OnKillFocus(self, event):
- self.Editor.AutoCompCancel()
+ self.ConfNodeEditor.AutoCompCancel()
event.Skip()
def OnUpdateUI(self, evt):
@@ -364,11 +342,11 @@
braceAtCaret = -1
braceOpposite = -1
charBefore = None
- caretPos = self.Editor.GetCurrentPos()
+ caretPos = self.ConfNodeEditor.GetCurrentPos()
if caretPos > 0:
- charBefore = self.Editor.GetCharAt(caretPos - 1)
- styleBefore = self.Editor.GetStyleAt(caretPos - 1)
+ charBefore = self.ConfNodeEditor.GetCharAt(caretPos - 1)
+ styleBefore = self.ConfNodeEditor.GetStyleAt(caretPos - 1)
# check before
if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
@@ -376,24 +354,19 @@
# check after
if braceAtCaret < 0:
- charAfter = self.Editor.GetCharAt(caretPos)
- styleAfter = self.Editor.GetStyleAt(caretPos)
+ charAfter = self.ConfNodeEditor.GetCharAt(caretPos)
+ styleAfter = self.ConfNodeEditor.GetStyleAt(caretPos)
if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
braceAtCaret = caretPos
if braceAtCaret >= 0:
- braceOpposite = self.Editor.BraceMatch(braceAtCaret)
+ braceOpposite = self.ConfNodeEditor.BraceMatch(braceAtCaret)
if braceAtCaret != -1 and braceOpposite == -1:
- self.Editor.BraceBadLight(braceAtCaret)
- else:
- self.Editor.BraceHighlight(braceAtCaret, braceOpposite)
- #pt = self.Editor.PointFromPosition(braceOpposite)
- #self.Editor.Refresh(True, wxRect(pt.x, pt.y, 5,5))
- #print pt
- #self.Editor.Refresh(False)
-
+ self.ConfNodeEditor.BraceBadLight(braceAtCaret)
+ else:
+ self.ConfNodeEditor.BraceHighlight(braceAtCaret, braceOpposite)
def OnMarginClick(self, evt):
# fold and unfold as needed
@@ -401,83 +374,83 @@
if evt.GetShift() and evt.GetControl():
self.FoldAll()
else:
- lineClicked = self.Editor.LineFromPosition(evt.GetPosition())
-
- if self.Editor.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
+ lineClicked = self.ConfNodeEditor.LineFromPosition(evt.GetPosition())
+
+ if self.ConfNodeEditor.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
if evt.GetShift():
- self.Editor.SetFoldExpanded(lineClicked, True)
+ self.ConfNodeEditor.SetFoldExpanded(lineClicked, True)
self.Expand(lineClicked, True, True, 1)
elif evt.GetControl():
- if self.Editor.GetFoldExpanded(lineClicked):
- self.Editor.SetFoldExpanded(lineClicked, False)
+ if self.ConfNodeEditor.GetFoldExpanded(lineClicked):
+ self.ConfNodeEditor.SetFoldExpanded(lineClicked, False)
self.Expand(lineClicked, False, True, 0)
else:
- self.Editor.SetFoldExpanded(lineClicked, True)
+ self.ConfNodeEditor.SetFoldExpanded(lineClicked, True)
self.Expand(lineClicked, True, True, 100)
else:
- self.Editor.ToggleFold(lineClicked)
+ self.ConfNodeEditor.ToggleFold(lineClicked)
def FoldAll(self):
- lineCount = self.Editor.GetLineCount()
+ lineCount = self.ConfNodeEditor.GetLineCount()
expanding = True
# find out if we are folding or unfolding
for lineNum in range(lineCount):
- if self.Editor.GetFoldLevel(lineNum) & stc.STC_FOLDLEVELHEADERFLAG:
- expanding = not self.Editor.GetFoldExpanded(lineNum)
+ if self.ConfNodeEditor.GetFoldLevel(lineNum) & stc.STC_FOLDLEVELHEADERFLAG:
+ expanding = not self.ConfNodeEditor.GetFoldExpanded(lineNum)
break
lineNum = 0
while lineNum < lineCount:
- level = self.Editor.GetFoldLevel(lineNum)
+ level = self.ConfNodeEditor.GetFoldLevel(lineNum)
if level & stc.STC_FOLDLEVELHEADERFLAG and \
(level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
if expanding:
- self.Editor.SetFoldExpanded(lineNum, True)
+ self.ConfNodeEditor.SetFoldExpanded(lineNum, True)
lineNum = self.Expand(lineNum, True)
lineNum = lineNum - 1
else:
- lastChild = self.Editor.GetLastChild(lineNum, -1)
- self.Editor.SetFoldExpanded(lineNum, False)
+ lastChild = self.ConfNodeEditor.GetLastChild(lineNum, -1)
+ self.ConfNodeEditor.SetFoldExpanded(lineNum, False)
if lastChild > lineNum:
- self.Editor.HideLines(lineNum+1, lastChild)
+ self.ConfNodeEditor.HideLines(lineNum+1, lastChild)
lineNum = lineNum + 1
def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
- lastChild = self.Editor.GetLastChild(line, level)
+ lastChild = self.ConfNodeEditor.GetLastChild(line, level)
line = line + 1
while line <= lastChild:
if force:
if visLevels > 0:
- self.Editor.ShowLines(line, line)
+ self.ConfNodeEditor.ShowLines(line, line)
else:
- self.Editor.HideLines(line, line)
+ self.ConfNodeEditor.HideLines(line, line)
else:
if doExpand:
- self.Editor.ShowLines(line, line)
+ self.ConfNodeEditor.ShowLines(line, line)
if level == -1:
- level = self.Editor.GetFoldLevel(line)
+ level = self.ConfNodeEditor.GetFoldLevel(line)
if level & stc.STC_FOLDLEVELHEADERFLAG:
if force:
if visLevels > 1:
- self.Editor.SetFoldExpanded(line, True)
+ self.ConfNodeEditor.SetFoldExpanded(line, True)
else:
- self.Editor.SetFoldExpanded(line, False)
+ self.ConfNodeEditor.SetFoldExpanded(line, False)
line = self.Expand(line, doExpand, force, visLevels-1)
else:
- if doExpand and self.Editor.GetFoldExpanded(line):
+ if doExpand and self.ConfNodeEditor.GetFoldExpanded(line):
line = self.Expand(line, True, force, visLevels-1)
else:
line = self.Expand(line, False, force, visLevels-1)
@@ -489,18 +462,18 @@
def Cut(self):
self.ResetBuffer()
self.DisableEvents = True
- self.Editor.CmdKeyExecute(wx.stc.STC_CMD_CUT)
+ self.ConfNodeEditor.CmdKeyExecute(wx.stc.STC_CMD_CUT)
self.DisableEvents = False
self.RefreshModel()
self.RefreshBuffer()
def Copy(self):
- self.Editor.CmdKeyExecute(wx.stc.STC_CMD_COPY)
+ self.ConfNodeEditor.CmdKeyExecute(wx.stc.STC_CMD_COPY)
def Paste(self):
self.ResetBuffer()
self.DisableEvents = True
- self.Editor.CmdKeyExecute(wx.stc.STC_CMD_PASTE)
+ self.ConfNodeEditor.CmdKeyExecute(wx.stc.STC_CMD_PASTE)
self.DisableEvents = False
self.RefreshModel()
self.RefreshBuffer()
--- a/py_ext/PythonFileCTNMixin.py Mon May 21 02:49:53 2012 +0200
+++ b/py_ext/PythonFileCTNMixin.py Mon May 21 10:04:27 2012 +0200
@@ -14,13 +14,6 @@
def __init__(self):
- self.ConfNodeMethods.insert(0,
- {"bitmap" : "editPYTHONcode",
- "name" : _("Edit Python File"),
- "tooltip" : _("Edit Python File"),
- "method" : "_OpenView"},
- )
-
filepath = self.PythonFileName()
self.PythonCode = PythonClasses["Python"]()
--- a/py_ext/py_ext.py Mon May 21 02:49:53 2012 +0200
+++ b/py_ext/py_ext.py Mon May 21 10:04:27 2012 +0200
@@ -1,6 +1,7 @@
import os
from POULibrary import POULibrary
from PythonFileCTNMixin import PythonFileCTNMixin
+from util import opjimg
class PythonLibrary(POULibrary):
def GetLibraryPath(self):
@@ -29,6 +30,10 @@
return (["py_ext"], [(Gen_Pythonfile_path, IECCFLAGS)], True), ""
class PythonFile(PythonFileCTNMixin):
+
+ def GetIconPath(self):
+ return opjimg("Pyfile")
+
def CTNGenerate_C(self, buildpath, locations):
current_location = self.GetCurrentLocation()
# define a unique name for the generated C file