Viewer.py
changeset 27 dae55dd9ee14
parent 13 69075340d6a9
child 28 fc23e1f415d8
equal deleted inserted replaced
26:36d378bd852e 27:dae55dd9ee14
    21 #You should have received a copy of the GNU General Public
    21 #You should have received a copy of the GNU General Public
    22 #License along with this library; if not, write to the Free Software
    22 #License along with this library; if not, write to the Free Software
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 from wxPython.wx import *
    25 from wxPython.wx import *
    26 from wxPython.stc import * 
       
    27 from wxPython.grid import *
       
    28 import wx
    26 import wx
    29 
    27 
    30 from plcopen.structures import *
    28 from plcopen.structures import *
    31 from graphics.GraphicCommons import *
    29 from graphics.GraphicCommons import *
    32 from graphics.SFC_Objects import *
       
    33 from graphics.FBD_Objects import *
    30 from graphics.FBD_Objects import *
    34 from graphics.LD_Objects import *
    31 from graphics.LD_Objects import *
    35 
    32 from graphics.SFC_Objects import *
    36 import re
    33 
       
    34 from Dialogs import *
       
    35 
       
    36 SCROLLBAR_UNIT = 10
       
    37 WINDOW_BORDER = 10
       
    38 SCROLL_ZONE = 10
    37 
    39 
    38 #-------------------------------------------------------------------------------
    40 #-------------------------------------------------------------------------------
    39 #                       Graphic elements Viewer base class
    41 #                       Graphic elements Viewer base class
    40 #-------------------------------------------------------------------------------
    42 #-------------------------------------------------------------------------------
    41 
    43 
   105         
   107         
   106         self._init_coll_ContextualMenu_Items(self.ContextualMenu)
   108         self._init_coll_ContextualMenu_Items(self.ContextualMenu)
   107     
   109     
   108     # Create a new Viewer
   110     # Create a new Viewer
   109     def __init__(self, parent, window, controler):
   111     def __init__(self, parent, window, controler):
   110         wx.ScrolledWindow.__init__(self, parent, style=wx.SUNKEN_BORDER)
   112         wx.ScrolledWindow.__init__(self, parent, style=wx.SUNKEN_BORDER | wx.HSCROLL | wx.VSCROLL)
   111         self._init_menus()
   113         self._init_menus()
   112         # Adding a rubberband to Viewer
   114         # Adding a rubberband to Viewer
   113         self.rubberBand = RubberBand(drawingSurface=self)
   115         self.rubberBand = RubberBand(drawingSurface=self)
   114         self.SetBackgroundColour(wxColour(255,255,255))
   116         self.SetBackgroundColour(wxColour(255,255,255))
   115         self.ResetView()
   117         self.ResetView()
   131         EVT_LEFT_UP(self, self.OnViewerLeftUp)
   133         EVT_LEFT_UP(self, self.OnViewerLeftUp)
   132         EVT_LEFT_DCLICK(self, self.OnViewerLeftDClick)
   134         EVT_LEFT_DCLICK(self, self.OnViewerLeftDClick)
   133         EVT_RIGHT_UP(self, self.OnViewerRightUp)
   135         EVT_RIGHT_UP(self, self.OnViewerRightUp)
   134         EVT_MOTION(self, self.OnViewerMotion)
   136         EVT_MOTION(self, self.OnViewerMotion)
   135         EVT_CHAR(self, self.OnChar)
   137         EVT_CHAR(self, self.OnChar)
       
   138         EVT_SCROLLWIN(self, self.OnMoveWindow)
       
   139         EVT_SIZE(self, self.OnMoveWindow)
   136     
   140     
   137     # Returns a new id
   141     # Returns a new id
   138     def GetNewId(self):
   142     def GetNewId(self):
   139         self.current_id += 1
   143         self.current_id += 1
   140         return self.current_id
   144         return self.current_id
   141     
   145     
   142     # Destructor
   146     # Destructor
   143     def __del__(self):
   147     def __del__(self):
   144         self.ResetView()
   148         self.ResetView()
       
   149 
       
   150     def GetLogicalDC(self):
       
   151         dc = wxClientDC(self)
       
   152         self.DoPrepareDC(dc)
       
   153         return dc
   145 
   154 
   146 #-------------------------------------------------------------------------------
   155 #-------------------------------------------------------------------------------
   147 #                              Reset functions
   156 #                              Reset functions
   148 #-------------------------------------------------------------------------------
   157 #-------------------------------------------------------------------------------
   149 
   158 
   164         # Reset selection
   173         # Reset selection
   165         if self.Mode != MODE_SELECTION and self.SelectedElement:
   174         if self.Mode != MODE_SELECTION and self.SelectedElement:
   166             self.SelectedElement.SetSelected(False)
   175             self.SelectedElement.SetSelected(False)
   167             self.SelectedElement = None
   176             self.SelectedElement = None
   168             self.Refresh()
   177             self.Refresh()
       
   178 
       
   179     # Return current drawing mode
       
   180     def GetDrawingMode(self):
       
   181         return self.Parent.GetDrawingMode()
   169 
   182 
   170 #-------------------------------------------------------------------------------
   183 #-------------------------------------------------------------------------------
   171 #                          Refresh functions
   184 #                          Refresh functions
   172 #-------------------------------------------------------------------------------
   185 #-------------------------------------------------------------------------------
   173 
   186 
   182         # Load Blocks until they are all loaded
   195         # Load Blocks until they are all loaded
   183         while instance:
   196         while instance:
   184             instance = self.Controler.GetCurrentElementEditingInstanceInfos(exclude=ids)
   197             instance = self.Controler.GetCurrentElementEditingInstanceInfos(exclude=ids)
   185             if instance:
   198             if instance:
   186                 self.loadInstance(instance, ids)
   199                 self.loadInstance(instance, ids)
       
   200         self.RefreshScrollBar()
   187         self.Refresh()
   201         self.Refresh()
       
   202     
       
   203     def RefreshScrollBar(self):
       
   204         xstart, ystart = self.GetViewStart()
       
   205         window_size = self.GetClientSize()
       
   206         maxx = maxy = 0
       
   207         for element in self.Elements:
       
   208             posx, posy = element.GetPosition()
       
   209             width, height = element.GetSize()
       
   210             maxx = max(maxx, posx + width)
       
   211             maxy = max(maxy, posy + height)
       
   212         maxx = max(maxx + WINDOW_BORDER, xstart * SCROLLBAR_UNIT + window_size[0])
       
   213         maxy = max(maxy + WINDOW_BORDER, ystart * SCROLLBAR_UNIT + window_size[1])
       
   214         if self.rubberBand.IsShown():
       
   215             extent = self.rubberBand.GetCurrentExtent()
       
   216             maxx = max(maxx, extent.x + extent.width)
       
   217             maxy = max(maxy, extent.y + extent.height)
       
   218         self.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
       
   219             maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, xstart, ystart)
   188     
   220     
   189     # Load instance from given informations
   221     # Load instance from given informations
   190     def loadInstance(self, instance, ids):
   222     def loadInstance(self, instance, ids):
   191         ids.append(instance["id"])
   223         ids.append(instance["id"])
   192         self.current_id = max(self.current_id, instance["id"]) 
   224         self.current_id = max(self.current_id, instance["id"]) 
   430                     if new_instance:
   462                     if new_instance:
   431                         self.loadInstance(new_instance, ids)
   463                         self.loadInstance(new_instance, ids)
   432                 connected = self.FindElementById(refLocalId)
   464                 connected = self.FindElementById(refLocalId)
   433                 if connected:
   465                 if connected:
   434                     points = link["points"]
   466                     points = link["points"]
   435                     end_connector = connected.GetConnector(wxPoint(points[-1][0], points[-1][1]))
   467                     end_connector = connected.GetConnector(wxPoint(points[-1][0], points[-1][1]), link["formalParameter"])
   436                     if end_connector:
   468                     if end_connector:
   437                         wire = Wire(self)
   469                         wire = Wire(self)
   438                         wire.SetPoints(points)
   470                         wire.SetPoints(points)
   439                         start_connector.Connect((wire, 0), False)
   471                         start_connector.Connect((wire, 0), False)
   440                         end_connector.Connect((wire, -1), False)
   472                         end_connector.Connect((wire, -1), False)
   627 #-------------------------------------------------------------------------------
   659 #-------------------------------------------------------------------------------
   628 #                          Mouse event functions
   660 #                          Mouse event functions
   629 #-------------------------------------------------------------------------------
   661 #-------------------------------------------------------------------------------
   630 
   662 
   631     def OnViewerLeftDown(self, event):
   663     def OnViewerLeftDown(self, event):
       
   664         if self.Mode == MODE_SELECTION:
       
   665             dc = self.GetLogicalDC()
       
   666             pos = event.GetLogicalPosition(dc)
       
   667             if event.ControlDown() and self.SelectedElement:
       
   668                 element = self.FindElement(pos, True)
       
   669                 if element:
       
   670                     if isinstance(self.SelectedElement, Graphic_Group):
       
   671                         self.SelectedElement.SetSelected(False)
       
   672                         self.SelectedElement.SelectElement(element)
       
   673                     elif self.SelectedElement:
       
   674                         group = Graphic_Group(self)
       
   675                         group.SelectElement(self.SelectedElement)
       
   676                         group.SelectElement(element)
       
   677                         self.SelectedElement = group
       
   678                     elements = self.SelectedElement.GetElements()
       
   679                     if len(elements) == 0:
       
   680                         self.SelectedElement = element
       
   681                     elif len(elements) == 1:
       
   682                         self.SelectedElement = elements[0]
       
   683                     self.SelectedElement.SetSelected(True)
       
   684             else:
       
   685                 element = self.FindElement(pos)
       
   686                 if self.SelectedElement and self.SelectedElement != element:
       
   687                     self.SelectedElement.SetSelected(False)
       
   688                     self.SelectedElement = None
       
   689                     self.Refresh()
       
   690                 if element:
       
   691                     self.SelectedElement = element
       
   692                     self.SelectedElement.OnLeftDown(event, dc, self.Scaling)
       
   693                     self.Refresh()
       
   694                 else:
       
   695                     self.rubberBand.Reset()
       
   696                     self.rubberBand.OnLeftDown(event, dc, self.Scaling)
       
   697         elif self.Mode in [MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, 
       
   698                            MODE_CONTACT, MODE_COIL, MODE_POWERRAIL, MODE_INITIALSTEP, 
       
   699                            MODE_STEP, MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION]:
       
   700             self.rubberBand.Reset()
       
   701             self.rubberBand.OnLeftDown(event, self.GetLogicalDC(), self.Scaling)
       
   702         elif self.Mode == MODE_WIRE:
       
   703             pos = GetScaledEventPosition(event, self.GetLogicalDC(), self.Scaling)
       
   704             connector = self.FindBlockConnector(pos)
       
   705             if connector:
       
   706                 if (connector.GetDirection() == EAST):
       
   707                     wire = Wire(self, [wxPoint(pos.x, pos.y), EAST], [wxPoint(pos.x, pos.y), WEST])
       
   708                 else:
       
   709                     wire = Wire(self, [wxPoint(pos.x, pos.y), WEST], [wxPoint(pos.x, pos.y), EAST])
       
   710                 wire.oldPos = pos
       
   711                 wire.Handle = (HANDLE_POINT, 0)
       
   712                 wire.ProcessDragging(0, 0)
       
   713                 wire.Handle = (HANDLE_POINT, 1)
       
   714                 self.Wires.append(wire)
       
   715                 self.Elements.append(wire)
       
   716                 if self.SelectedElement:
       
   717                     self.SelectedElement.SetSelected(False)
       
   718                 self.SelectedElement = wire
       
   719             elif self.SelectedElement:
       
   720                 self.SelectedElement.SetSelected(False)
       
   721                 self.SelectedElement = None
       
   722             self.Refresh()
   632         event.Skip()
   723         event.Skip()
   633 
   724 
   634     def OnViewerLeftUp(self, event):
   725     def OnViewerLeftUp(self, event):
       
   726         if self.rubberBand.IsShown():
       
   727             if self.Mode == MODE_SELECTION:
       
   728                 elements = self.SearchElements(self.rubberBand.GetCurrentExtent())
       
   729                 self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)
       
   730                 if len(elements) > 0:
       
   731                     self.SelectedElement = Graphic_Group(self)
       
   732                     self.SelectedElement.SetElements(elements)
       
   733                     self.SelectedElement.SetSelected(True)
       
   734                     self.Refresh()
       
   735             else:
       
   736                 bbox = self.rubberBand.GetCurrentExtent()
       
   737                 self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)                
       
   738                 if self.Mode == MODE_BLOCK:
       
   739                     wxCallAfter(self.AddNewBlock, bbox)
       
   740                 elif self.Mode == MODE_VARIABLE:
       
   741                     wxCallAfter(self.AddNewVariable, bbox)
       
   742                 elif self.Mode == MODE_CONNECTION:
       
   743                     wxCallAfter(self.AddNewConnection, bbox)
       
   744                 elif self.Mode == MODE_COMMENT:
       
   745                     wxCallAfter(self.AddNewComment, bbox)
       
   746                 elif self.Mode == MODE_CONTACT:
       
   747                     wxCallAfter(self.AddNewContact, bbox)
       
   748                 elif self.Mode == MODE_COIL:
       
   749                     wxCallAfter(self.AddNewContact, bbox)
       
   750                 elif self.Mode == MODE_POWERRAIL:
       
   751                     wxCallAfter(self.AddNewPowerRail, bbox)
       
   752                 elif self.Mode == MODE_INITIALSTEP:
       
   753                     wxCallAfter(self.AddNewInitialStep, bbox)
       
   754                 elif self.Mode == MODE_STEP:
       
   755                     wxCallAfter(self.AddNewStep, bbox)
       
   756                 elif self.Mode == MODE_TRANSITION:
       
   757                     wxCallAfter(self.AddNewTransition, bbox)
       
   758                 elif self.Mode == MODE_DIVERGENCE:
       
   759                     wxCallAfter(self.AddNewDivergence, bbox)
       
   760                 elif self.Mode == MODE_JUMP:
       
   761                     wxCallAfter(self.AddNewJump, bbox)
       
   762                 elif self.Mode == MODE_ACTION:
       
   763                     wxCallAfter(self.AddNewActionBlock, bbox)
       
   764         elif self.Mode == MODE_SELECTION and self.SelectedElement:
       
   765             self.SelectedElement.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)
       
   766             wxCallAfter(self.SetCursor, wxNullCursor)
       
   767             self.ReleaseMouse()
       
   768             self.Refresh()
       
   769         elif self.Mode == MODE_WIRE and self.SelectedElement:
       
   770             dc = self.GetLogicalDC()
       
   771             pos = GetScaledEventPosition(event, dc, self.Scaling)
       
   772             connector = self.FindBlockConnector(pos, False)
       
   773             if connector and connector != self.SelectedElement.StartConnected:
       
   774                 self.SelectedElement.ResetPoints()
       
   775                 self.SelectedElement.OnMotion(event, dc, self.Scaling)
       
   776                 self.SelectedElement.GeneratePoints()
       
   777                 self.SelectedElement.RefreshModel()
       
   778                 self.SelectedElement.SetSelected(True)
       
   779             else:
       
   780                 self.SelectedElement.Delete()
       
   781                 self.SelectedElement = None
       
   782             self.Refresh()
       
   783         if not self.SavedMode:
       
   784             wxCallAfter(self.Parent.ResetCurrentMode)
   635         event.Skip()
   785         event.Skip()
   636     
   786     
   637     def OnViewerRightUp(self, event):
   787     def OnViewerRightUp(self, event):
       
   788         pos = event.GetPosition()
       
   789         element = self.FindElement(pos)
       
   790         if element:
       
   791             if self.SelectedElement and self.SelectedElement != element:
       
   792                 self.SelectedElement.SetSelected(False)
       
   793             self.SelectedElement = element
       
   794             self.SelectedElement.SetSelected(True)
       
   795             self.SelectedElement.OnRightUp(event, self.GetLogicalDC(), self.Scaling)
       
   796             wxCallAfter(self.SetCursor, wxNullCursor)
       
   797             self.ReleaseMouse()
       
   798             self.Refresh()
   638         event.Skip()
   799         event.Skip()
   639     
   800     
   640     def OnViewerLeftDClick(self, event):
   801     def OnViewerLeftDClick(self, event):
       
   802         if self.Mode == MODE_SELECTION and self.SelectedElement:
       
   803             self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
       
   804             self.Refresh()
   641         event.Skip()
   805         event.Skip()
   642     
   806     
   643     def OnViewerMotion(self, event):
   807     def OnViewerMotion(self, event):
       
   808         if self.rubberBand.IsShown():
       
   809             self.rubberBand.OnMotion(event, self.GetLogicalDC(), self.Scaling)
       
   810         elif self.Mode == MODE_SELECTION and self.SelectedElement:
       
   811             self.SelectedElement.OnMotion(event, self.GetLogicalDC(), self.Scaling)
       
   812             self.Refresh()
       
   813         elif self.Mode == MODE_WIRE and self.SelectedElement:
       
   814             dc = self.GetLogicalDC()
       
   815             pos = GetScaledEventPosition(event, dc, self.Scaling)
       
   816             connector = self.FindBlockConnector(pos, False)
       
   817             if not connector or self.SelectedElement.EndConnected == None:
       
   818                 self.SelectedElement.ResetPoints()
       
   819                 self.SelectedElement.OnMotion(event, dc, self.Scaling)
       
   820                 self.SelectedElement.GeneratePoints()
       
   821                 self.Refresh()
       
   822         if (event.Dragging() and self.SelectedElement) or self.rubberBand.IsShown():
       
   823             position = event.GetPosition()
       
   824             move_window = wxPoint()
       
   825             window_size = self.GetClientSize()
       
   826             xstart, ystart = self.GetViewStart()
       
   827             if position.x < SCROLL_ZONE and xstart > 0:
       
   828                 move_window.x = -1
       
   829             elif position.x > window_size[0] - SCROLL_ZONE:
       
   830                 move_window.x = 1
       
   831             if position.y < SCROLL_ZONE and ystart > 0:
       
   832                 move_window.y = -1
       
   833             elif position.y > window_size[1] - SCROLL_ZONE:
       
   834                 move_window.y = 1
       
   835             if move_window.x != 0 or move_window.y != 0:
       
   836                 self.Scroll(xstart + move_window.x, ystart + move_window.y)
       
   837             self.RefreshScrollBar()
   644         event.Skip()
   838         event.Skip()
   645 
   839 
   646 #-------------------------------------------------------------------------------
   840 #-------------------------------------------------------------------------------
   647 #                          Keyboard event functions
   841 #                          Keyboard event functions
   648 #-------------------------------------------------------------------------------
   842 #-------------------------------------------------------------------------------
   649 
   843 
   650     def OnChar(self, event):
   844     def OnChar(self, event):
   651         event.Skip()
   845         keycode = event.GetKeyCode()
       
   846         if self.Scaling:
       
   847             scaling = self.Scaling
       
   848         else:
       
   849             scaling = (8, 8)
       
   850         if keycode == WXK_DELETE and self.SelectedElement:
       
   851             self.SelectedElement.Clean()
       
   852             self.SelectedElement.Delete()
       
   853             self.SelectedElement = None
       
   854         elif keycode == WXK_LEFT and self.SelectedElement:
       
   855             self.SelectedElement.Move(-scaling[0], 0)
       
   856         elif keycode == WXK_RIGHT and self.SelectedElement:
       
   857             self.SelectedElement.Move(scaling[0], 0)
       
   858         elif keycode == WXK_UP and self.SelectedElement:
       
   859             self.SelectedElement.Move(0, -scaling[1])
       
   860         elif keycode == WXK_DOWN and self.SelectedElement:
       
   861             self.SelectedElement.Move(0, scaling[1])
       
   862         self.Refresh()
       
   863         event.Skip()
       
   864 
       
   865 #-------------------------------------------------------------------------------
       
   866 #                          Model adding functions
       
   867 #-------------------------------------------------------------------------------
       
   868 
       
   869     def AddNewBlock(self, bbox):
       
   870         dialog = BlockPropertiesDialog(self.Parent)
       
   871         dialog.SetBlockList(self.Controler.GetBlockTypes())
       
   872         dialog.SetMinBlockSize((bbox.width, bbox.height))
       
   873         if dialog.ShowModal() == wxID_OK:
       
   874             id = self.GetNewId()
       
   875             values = dialog.GetValues()
       
   876             if "name" in values:
       
   877                 block = FBD_Block(self, values["type"], values["name"], id, values["extension"])
       
   878             else:
       
   879                 block = FBD_Block(self, values["type"], "", id, values["extension"])
       
   880             block.SetPosition(bbox.x, bbox.y)
       
   881             block.SetSize(values["width"], values["height"])
       
   882             self.Blocks.append(block)
       
   883             self.Elements.append(block)
       
   884             self.Controler.AddCurrentElementEditingBlock(id)
       
   885             self.RefreshBlockModel(block)
       
   886             self.Refresh()
       
   887         dialog.Destroy()
       
   888     
       
   889     def AddNewVariable(self, bbox):
       
   890         dialog = VariablePropertiesDialog(self.Parent)
       
   891         dialog.SetMinVariableSize((bbox.width, bbox.height))
       
   892         varlist = []
       
   893         vars = self.Controler.GetCurrentElementEditingInterfaceVars()
       
   894         if vars:
       
   895             for var in vars:
       
   896                 varlist.append((var["Name"], var["Class"], var["Type"]))
       
   897         returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
       
   898         if returntype:
       
   899             varlist.append((self.Controler.GetCurrentElementEditingName(), "Output", returntype))
       
   900         dialog.SetVariables(varlist)
       
   901         if dialog.ShowModal() == wxID_OK:
       
   902             id = self.GetNewId()
       
   903             values = dialog.GetValues()
       
   904             variable = FBD_Variable(self, values["type"], values["name"], values["value_type"], id)
       
   905             variable.SetPosition(bbox.x, bbox.y)
       
   906             variable.SetSize(values["width"], values["height"])
       
   907             self.Blocks.append(variable)
       
   908             self.Elements.append(variable)
       
   909             self.Controler.AddCurrentElementEditingVariable(id, values["type"])
       
   910             self.RefreshVariableModel(variable)
       
   911             self.Refresh()
       
   912         dialog.Destroy()
       
   913 
       
   914     def AddNewConnection(self, bbox):
       
   915         dialog = ConnectionPropertiesDialog(self.Parent)
       
   916         dialog.SetMinConnectionSize((bbox.width, bbox.height))
       
   917         if dialog.ShowModal() == wxID_OK:
       
   918             id = self.GetNewId()
       
   919             values = dialog.GetValues()
       
   920             connection = FBD_Connector(self, values["type"], values["name"], id)
       
   921             connection.SetPosition(bbox.x, bbox.y)
       
   922             connection.SetSize(values["width"], values["height"])
       
   923             self.Blocks.append(connection)
       
   924             self.Elements.append(connection)
       
   925             self.Controler.AddCurrentElementEditingConnection(id, values["type"])
       
   926             self.RefreshConnectionModel(connection)
       
   927             self.Refresh()
       
   928         dialog.Destroy()
       
   929 
       
   930     def AddNewComment(self, bbox):
       
   931         dialog = wxTextEntryDialog(self.Parent, "Add a new comment", "Please enter comment text", "", wxOK|wxCANCEL|wxTE_MULTILINE)
       
   932         if dialog.ShowModal() == wxID_OK:
       
   933             value = dialog.GetValue()
       
   934             id = self.GetNewId()
       
   935             comment = Comment(self, value, id)
       
   936             comment.SetPosition(bbox.x, bbox.y)
       
   937             min_width, min_height = comment.GetMinSize()
       
   938             comment.SetSize(max(min_width,bbox.width),max(min_height,bbox.height))
       
   939             self.Elements.append(comment)
       
   940             self.Controler.AddCurrentElementEditingComment(id)
       
   941             self.RefreshCommentModel(comment)
       
   942             self.Refresh()
       
   943         dialog.Destroy()
       
   944 
       
   945     def AddNewContact(self, bbox):
       
   946         dialog = LDElementDialog(self.Parent, "contact")
       
   947         varlist = []
       
   948         vars = self.Controler.GetCurrentElementEditingInterfaceVars()
       
   949         if vars:
       
   950             for var in vars:
       
   951                 if var["Class"] != "Output" and var["Type"] == "BOOL":
       
   952                     varlist.append(var["Name"])
       
   953         dialog.SetVariables(varlist)
       
   954         dialog.SetValues({"name":"","type":CONTACT_NORMAL})
       
   955         dialog.SetElementSize(bbox.width, bbox.height)
       
   956         if dialog.ShowModal() == wxID_OK:
       
   957             id = self.GetNewId()
       
   958             values = dialog.GetValues()
       
   959             contact = LD_Contact(self, values["type"], values["name"], id)
       
   960             contact.SetPosition(bbox.x, bbox.y)
       
   961             contact.SetSize(values["width"], values["height"])
       
   962             self.Blocks.append(contact)
       
   963             self.Elements.append(contact)
       
   964             self.Controler.AddCurrentElementEditingContact(id)
       
   965             self.RefreshContactModel(contact)
       
   966             self.Refresh()
       
   967         dialog.Destroy()
       
   968 
       
   969     def AddNewCoil(self, bbox):
       
   970         dialog = LDElementDialog(self.Parent, "coil")
       
   971         varlist = []
       
   972         vars = self.Controler.GetCurrentElementEditingInterfaceVars()
       
   973         if vars:
       
   974             for var in vars:
       
   975                 if var["Class"] != "Input" and var["Type"] == "BOOL":
       
   976                     varlist.append(var["Name"])
       
   977         returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
       
   978         if returntype == "BOOL":
       
   979             varlist.append(self.Controler.GetCurrentElementEditingName())
       
   980         dialog.SetVariables(varlist)
       
   981         dialog.SetValues({"name":"","type":COIL_NORMAL})
       
   982         dialog.SetElementSize(bbox.width, bbox.height)
       
   983         if dialog.ShowModal() == wxID_OK:
       
   984             id = self.GetNewId()
       
   985             values = dialog.GetValues()
       
   986             coil = LD_Coil(self, values["type"], values["name"], id)
       
   987             coil.SetPosition(bbox.x, bbox.y)
       
   988             coil.SetSize(values["width"], values["height"])
       
   989             self.Blocks.append(coil)
       
   990             self.Elements.append(coil)
       
   991             self.Controler.AddCurrentElementEditingCoil(id)
       
   992             self.RefreshCoilModel(contact)
       
   993             self.Refresh()
       
   994         dialog.Destroy()
       
   995 
       
   996     def AddNewPowerRail(self, bbox):
       
   997         dialog = LDPowerRailDialog(self.Parent)
       
   998         dialog.SetMinSize((bbox.width, bbox.height))
       
   999         if dialog.ShowModal() == wxID_OK:
       
  1000             id = self.GetNewId()
       
  1001             values = dialog.GetValues()
       
  1002             powerrail = LD_PowerRail(self, values["type"], id, [True for i in xrange(values["number"])])
       
  1003             powerrail.SetPosition(bbox.x, bbox.y)
       
  1004             powerrail.SetSize(values["width"], values["height"])
       
  1005             self.Blocks.append(powerrail)
       
  1006             self.Elements.append(powerrail)
       
  1007             self.Controler.AddCurrentElementEditingPowerRail(id, values["type"])
       
  1008             self.RefreshPowerRailModel(powerrail)
       
  1009             self.Refresh()
       
  1010         dialog.Destroy()
       
  1011 
       
  1012     def AddNewTransition(self, bbox):
       
  1013         dialog = TransitionContentDialog(self.Parent)
       
  1014         dialog.SetTransitions(self.Controler.GetCurrentElementEditingTransitions())
       
  1015         if dialog.ShowModal() == wxID_OK:
       
  1016             id = self.GetNewId()
       
  1017             values = dialog.GetValues()
       
  1018             transition = SFC_Transition(self, values["type"], values["value"], id)
       
  1019             transition.SetPosition(bbox.x, bbox.y)
       
  1020             min_width, min_height = transition.GetMinSize()
       
  1021             transition.SetSize(max(bbox.width, min_width), max(bbox.height, min_height))
       
  1022             self.Blocks.append(transition)
       
  1023             self.Elements.append(transition)
       
  1024             self.Controler.AddCurrentElementEditingTransition(id)
       
  1025             self.RefreshTransitionModel(transition)
       
  1026             self.Refresh()
       
  1027         dialog.Destroy()
       
  1028 
       
  1029     def AddNewDivergence(self, bbox):
       
  1030         dialog = DivergenceCreateDialog(self.Parent)
       
  1031         dialog.SetMinSize((bbox.width, bbox.height))
       
  1032         if dialog.ShowModal() == wxID_OK:
       
  1033             id = self.GetNewId()
       
  1034             values = dialog.GetValues()
       
  1035             divergence = SFC_Divergence(self, values["type"], values["number"], id)
       
  1036             divergence.SetPosition(bbox.x, bbox.y)
       
  1037             min_width, min_height = divergence.GetMinSize()
       
  1038             divergence.SetSize(max(bbox.width, min_width), max(bbox.height, min_height))
       
  1039             self.Blocks.append(divergence)
       
  1040             self.Elements.append(divergence)
       
  1041             self.Controler.AddCurrentElementEditingDivergence(id, values["type"])
       
  1042             self.RefreshDivergenceModel(divergence)
       
  1043             self.Refresh()
       
  1044         dialog.Destroy()
   652 
  1045 
   653 #-------------------------------------------------------------------------------
  1046 #-------------------------------------------------------------------------------
   654 #                          Model update functions
  1047 #                          Model update functions
   655 #-------------------------------------------------------------------------------
  1048 #-------------------------------------------------------------------------------
   656 
  1049 
   762         infos["x"], infos["y"] = actionblock.GetPosition()
  1155         infos["x"], infos["y"] = actionblock.GetPosition()
   763         infos["width"], infos["height"] = actionblock.GetSize()
  1156         infos["width"], infos["height"] = actionblock.GetSize()
   764         infos["connector"] = actionblock.GetConnector()
  1157         infos["connector"] = actionblock.GetConnector()
   765         self.Controler.SetCurrentElementEditingActionBlockInfos(actionblockid, infos)
  1158         self.Controler.SetCurrentElementEditingActionBlockInfos(actionblockid, infos)
   766 
  1159 
       
  1160 
       
  1161 #-------------------------------------------------------------------------------
       
  1162 #                          Model delete functions
       
  1163 #-------------------------------------------------------------------------------
       
  1164 
       
  1165 
       
  1166     def DeleteBlock(self, block):
       
  1167         elements = []
       
  1168         for output in block.GetConnectors()["outputs"]:
       
  1169             for element in output.GetConnectedBlocks():
       
  1170                 if element not in elements:
       
  1171                     elements.append(element)
       
  1172         block.Clean()
       
  1173         self.Blocks.remove(block)
       
  1174         self.Elements.remove(block)
       
  1175         self.Controler.RemoveCurrentElementEditingInstance(block.GetId())
       
  1176         for element in elements:
       
  1177             element.RefreshModel()
       
  1178 
       
  1179     def DeleteVariable(self, variable):
       
  1180         connectors = variable.GetConnectors()
       
  1181         if connectors["output"]:
       
  1182             elements = connectors["output"].GetConnectedBlocks()
       
  1183         else:
       
  1184             elements = []
       
  1185         variable.Clean()
       
  1186         self.Blocks.remove(variable)
       
  1187         self.Elements.remove(variable)
       
  1188         self.Controler.RemoveCurrentElementEditingInstance(variable.GetId())
       
  1189         for element in elements:
       
  1190             element.RefreshModel()
       
  1191 
       
  1192     def DeleteConnection(self, connection):
       
  1193         if connection.GetType() == CONTINUATION:
       
  1194             elements = connection.GetConnector().GetConnectedBlocks()
       
  1195         else:
       
  1196             elements = []
       
  1197         connection.Clean()
       
  1198         self.Blocks.remove(connection)
       
  1199         self.Elements.remove(connection)
       
  1200         self.Controler.RemoveCurrentElementEditingInstance(connection.GetId())
       
  1201         for element in elements:
       
  1202             element.RefreshModel()
       
  1203 
       
  1204     def DeleteComment(self, comment):
       
  1205         self.Elements.remove(comment)
       
  1206         self.Controler.RemoveCurrentElementEditingInstance(comment.GetId())
       
  1207 
       
  1208     def DeleteWire(self, wire):
       
  1209         connected = wire.GetConnected()
       
  1210         wire.Clean()
       
  1211         self.Wires.remove(wire)
       
  1212         self.Elements.remove(wire)
       
  1213         for connector in connected:
       
  1214             connector.RefreshParentBlock()
       
  1215 
       
  1216     def DeleteContact(self, contact):
       
  1217         connectors = contact.GetConnectors()
       
  1218         elements = connectors["output"].GetConnectedBlocks()
       
  1219         contact.Clean()
       
  1220         self.Blocks.remove(contact)
       
  1221         self.Elements.remove(contact)
       
  1222         self.Controler.RemoveCurrentElementEditingInstance(contact.GetId())
       
  1223         for element in elements:
       
  1224             element.RefreshModel()
       
  1225 
       
  1226     def DeleteCoil(self, coil):
       
  1227         connectors = coil.GetConnectors()
       
  1228         elements = connectors["output"].GetConnectedBlocks()
       
  1229         coil.Clean()
       
  1230         self.Blocks.remove(coil)
       
  1231         self.Elements.remove(coil)
       
  1232         self.Controler.RemoveCurrentElementEditingInstance(coil.GetId())
       
  1233         for element in elements:
       
  1234             element.RefreshModel()
       
  1235 
       
  1236     def DeletePowerRail(self, powerrail):
       
  1237         elements = []
       
  1238         if powerrail.GetType() == LEFTRAIL:
       
  1239             for connector in powerrail.GetConnectors():
       
  1240                 for element in connector.GetConnectedBlocks():
       
  1241                     if element not in elements:
       
  1242                         elements.append(element)
       
  1243         powerrrail.Clean()
       
  1244         self.Blocks.remove(powerrrail)
       
  1245         self.Elements.remove(powerrrail)
       
  1246         self.Controler.RemoveCurrentElementEditingInstance(powerrrail.GetId())
       
  1247         for element in elements:
       
  1248             element.RefreshModel()
       
  1249 
       
  1250 #-------------------------------------------------------------------------------
       
  1251 #                          Edit element content functions
       
  1252 #-------------------------------------------------------------------------------
       
  1253 
       
  1254     def EditBlockContent(self, block):
       
  1255         dialog = BlockPropertiesDialog(self.Parent)
       
  1256         dialog.SetBlockList(self.Controler.GetBlockTypes())
       
  1257         dialog.SetMinBlockSize(block.GetSize())
       
  1258         values = {"name" : block.GetName(), "type" : block.GetType()}
       
  1259         values["extension"] = block.GetExtension()
       
  1260         dialog.SetValues(values)
       
  1261         if dialog.ShowModal() == wxID_OK:
       
  1262             values = dialog.GetValues()
       
  1263             if "name" in values:
       
  1264                 block.SetName(values["name"])
       
  1265             block.SetSize(values["width"], values["height"])
       
  1266             block.SetType(values["type"], values["extension"])
       
  1267             self.RefreshBlockModel(block)
       
  1268             self.Refresh()
       
  1269         dialog.Destroy()
       
  1270 
       
  1271     def EditVariableContent(self, variable):
       
  1272         dialog = VariablePropertiesDialog(self.Parent)
       
  1273         dialog.SetMinVariableSize(variable.GetSize())
       
  1274         varlist = []
       
  1275         vars = self.Controler.GetCurrentElementEditingInterfaceVars()
       
  1276         if vars:
       
  1277             for var in vars:
       
  1278                 varlist.append((var["Name"], var["Class"], var["Type"]))
       
  1279         returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
       
  1280         if returntype:
       
  1281             varlist.append((self.Controler.GetCurrentElementEditingName(), "Output", returntype))
       
  1282         dialog.SetVariables(varlist)
       
  1283         values = {"name" : variable.GetName(), "type" : variable.GetType()}
       
  1284         dialog.SetValues(values)
       
  1285         if dialog.ShowModal() == wxID_OK:
       
  1286             old_type = variable.GetType()
       
  1287             values = dialog.GetValues()
       
  1288             variable.SetName(values["name"])
       
  1289             variable.SetType(values["type"], values["value_type"])
       
  1290             variable.SetSize(values["width"], values["height"])
       
  1291             if old_type != values["type"]:
       
  1292                 id = variable.GetId()
       
  1293                 self.Controler.RemoveCurrentElementEditingInstance(id)
       
  1294                 self.Controler.AddCurrentElementEditingVariable(id, values["type"])
       
  1295             self.RefreshVariableModel(variable)
       
  1296             self.Refresh()
       
  1297         dialog.Destroy()
       
  1298 
       
  1299 
   767 #-------------------------------------------------------------------------------
  1300 #-------------------------------------------------------------------------------
   768 #                            Editing functions
  1301 #                            Editing functions
   769 #-------------------------------------------------------------------------------
  1302 #-------------------------------------------------------------------------------
   770     
  1303     
   771     def Cut(self):
  1304     def Cut(self):
   779 
  1312 
   780 #-------------------------------------------------------------------------------
  1313 #-------------------------------------------------------------------------------
   781 #                            Drawing functions
  1314 #                            Drawing functions
   782 #-------------------------------------------------------------------------------
  1315 #-------------------------------------------------------------------------------
   783 
  1316 
       
  1317     def OnMoveWindow(self, event):
       
  1318         self.RefreshScrollBar()
       
  1319         event.Skip()
       
  1320 
   784     def OnPaint(self, event):
  1321     def OnPaint(self, event):
   785         dc = wxClientDC(self)
  1322         dc = self.GetLogicalDC()
   786         dc.Clear()
  1323         dc.Clear()
   787         dc.SetPen(wxPen(wxColour(230, 230, 230)))
  1324         dc.SetPen(wxPen(wxColour(230, 230, 230)))
   788         if self.Scaling and self.DrawGrid:
  1325         if self.Scaling and self.DrawGrid:
   789             width, height = dc.GetSize()
  1326             width, height = dc.GetSize()
   790             for i in xrange(1, width / self.Scaling[0] + 1):
  1327             for i in xrange(1, width / self.Scaling[0] + 1):
   797         for element in self.Elements:
  1334         for element in self.Elements:
   798             if element not in self.Wires and element != self.SelectedElement:
  1335             if element not in self.Wires and element != self.SelectedElement:
   799                 element.Draw(dc)
  1336                 element.Draw(dc)
   800         if self.SelectedElement:
  1337         if self.SelectedElement:
   801             self.SelectedElement.Draw(dc)
  1338             self.SelectedElement.Draw(dc)
   802         event.Skip()
  1339         if self.rubberBand.IsShown():
   803 
  1340             self.rubberBand.Draw()
   804 
  1341         event.Skip()
   805 #-------------------------------------------------------------------------------
  1342 
   806 #                         Textual programs Viewer class
  1343 
   807 #-------------------------------------------------------------------------------
       
   808 
       
   809 
       
   810 NEWLINE = "\n"
       
   811 NUMBERS = [str(i) for i in xrange(10)]
       
   812 LETTERS = ['_']
       
   813 for i in xrange(26):
       
   814     LETTERS.append(chr(ord('a') + i))
       
   815     LETTERS.append(chr(ord('A') + i))
       
   816 
       
   817 [wxSTC_PLC_WORD, wxSTC_PLC_COMMENT, wxSTC_PLC_NUMBER, wxSTC_PLC_VARIABLE, 
       
   818  wxSTC_PLC_FUNCTION, wxSTC_PLC_JUMP] = range(6)
       
   819 [SPACE, WORD, NUMBER, COMMENT] = range(4)
       
   820 
       
   821 [wxID_TEXTVIEWER,
       
   822 ] = [wx.NewId() for _init_ctrls in range(1)]
       
   823 
       
   824 if wx.Platform == '__WXMSW__':
       
   825     faces = { 'times': 'Times New Roman',
       
   826               'mono' : 'Courier New',
       
   827               'helv' : 'Arial',
       
   828               'other': 'Comic Sans MS',
       
   829               'size' : 10,
       
   830              }
       
   831 else:
       
   832     faces = { 'times': 'Times',
       
   833               'mono' : 'Courier',
       
   834               'helv' : 'Helvetica',
       
   835               'other': 'new century schoolbook',
       
   836               'size' : 12,
       
   837              }
       
   838 re_texts = {}
       
   839 re_texts["letter"] = "[A-Za-z]"
       
   840 re_texts["digit"] = "[0-9]"
       
   841 re_texts["identifier"] = "((?:%(letter)s|(?:_(?:%(letter)s|%(digit)s)))(?:_?(?:%(letter)s|%(digit)s))*)"%re_texts
       
   842 IDENTIFIER_MODEL = re.compile(re_texts["identifier"])
       
   843 LABEL_MODEL = re.compile("[ \t\n]%(identifier)s:[ \t\n]"%re_texts)
       
   844 
       
   845 class TextViewer(wxStyledTextCtrl):
       
   846     
       
   847     def __init__(self, parent, window, controler):
       
   848         wxStyledTextCtrl.__init__(self, parent, wxID_TEXTVIEWER, style=0)
       
   849         
       
   850         self.CmdKeyAssign(ord('+'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMIN)
       
   851         self.CmdKeyAssign(ord('-'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMOUT)
       
   852         
       
   853         self.SetViewWhiteSpace(False)
       
   854         
       
   855         self.SetLexer(wxSTC_LEX_CONTAINER)
       
   856         
       
   857         # Global default styles for all languages
       
   858         self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
       
   859         self.StyleClearAll()  # Reset all to be like the default
       
   860         
       
   861         self.StyleSetSpec(wxSTC_STYLE_LINENUMBER,  "back:#C0C0C0,size:%(size)d" % faces)
       
   862         self.SetSelBackground(1, "#E0E0E0")
       
   863         
       
   864         # Highlighting styles
       
   865         self.StyleSetSpec(wxSTC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
       
   866         self.StyleSetSpec(wxSTC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces)
       
   867         self.StyleSetSpec(wxSTC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces)
       
   868         self.StyleSetSpec(wxSTC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces)
       
   869         self.StyleSetSpec(wxSTC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
       
   870         self.StyleSetSpec(wxSTC_PLC_JUMP, "fore:#007F00,size:%(size)d" % faces)
       
   871         
       
   872         # Indicators styles
       
   873         self.IndicatorSetStyle(0, wxSTC_INDIC_SQUIGGLE)
       
   874         self.IndicatorSetForeground(0, wxRED)
       
   875         
       
   876         # Line numbers in the margin
       
   877         self.SetMarginType(1, wxSTC_MARGIN_NUMBER)
       
   878         self.SetMarginWidth(1, 50)
       
   879         
       
   880         # Indentation size
       
   881         self.SetTabWidth(2)
       
   882         self.SetUseTabs(0)
       
   883         
       
   884         self.Keywords = []
       
   885         self.Variables = []
       
   886         self.Functions = []
       
   887         self.Jumps = []
       
   888         self.TextChanged = False
       
   889         self.TextSyntax = "ST"
       
   890         
       
   891         self.Controler = controler
       
   892 
       
   893         EVT_KEY_DOWN(self, self.OnKeyDown)
       
   894         EVT_STC_STYLENEEDED(self, wxID_TEXTVIEWER, self.OnStyleNeeded)
       
   895         EVT_KILL_FOCUS(self, self.OnKillFocus)
       
   896     
       
   897     def SetTextSyntax(self, syntax):
       
   898         self.TextSyntax = syntax
       
   899     
       
   900     def SetKeywords(self, keywords):
       
   901         self.Keywords = [keyword.upper() for keyword in keywords]
       
   902         self.Colourise(0, -1)
       
   903     
       
   904     def SetVariables(self, variables):
       
   905         self.Variables = [variable.upper() for variable in variables]
       
   906         self.Colourise(0, -1)
       
   907     
       
   908     def SetFunctions(self, blocktypes):
       
   909         self.Functions = []
       
   910         for category in blocktypes:
       
   911             for blocktype in category["list"]:
       
   912                 if blocktype["name"] not in self.Keywords and blocktype["name"] not in self.Variables:
       
   913                     self.Functions.append(blocktype["name"].upper())
       
   914         self.Colourise(0, -1)
       
   915     
       
   916     def RefreshJumpList(self):
       
   917         self.Jumps = [jump.upper() for jump in LABEL_MODEL.findall(self.GetText())]
       
   918         self.Colourise(0, -1)
       
   919     
       
   920     def RefreshView(self):
       
   921         self.SetText(self.Controler.GetCurrentElementEditingText())
       
   922         self.RefreshJumpList()
       
   923     
       
   924     def OnStyleNeeded(self, event):
       
   925         self.TextChanged = True
       
   926         line = self.LineFromPosition(self.GetEndStyled())
       
   927         if line == 0:
       
   928             start_pos = 0
       
   929         else:
       
   930             start_pos = self.GetLineEndPosition(line - 1) + 1
       
   931         end_pos = event.GetPosition()
       
   932         self.StartStyling(start_pos, 0xff)
       
   933         
       
   934         i = start_pos
       
   935         state = SPACE
       
   936         line = ""
       
   937         word = ""
       
   938         while i < end_pos:
       
   939             char = chr(self.GetCharAt(i)).upper()
       
   940             line += char
       
   941             if char == NEWLINE:
       
   942                 if state == COMMENT:
       
   943                     self.SetStyling(i - start_pos + 1, wxSTC_PLC_COMMENT)
       
   944                 elif state == NUMBER:
       
   945                     self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER)
       
   946                 elif state == WORD:
       
   947                     if word in self.Keywords:
       
   948                         self.SetStyling(i - start_pos, wxSTC_PLC_WORD)
       
   949                     elif word in self.Variables:
       
   950                         self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE)
       
   951                     elif word in self.Functions:
       
   952                         self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION)
       
   953                     elif word in self.Jumps:
       
   954                         self.SetStyling(i - start_pos, wxSTC_PLC_JUMP)
       
   955                     else:
       
   956                         self.SetStyling(i - start_pos, 31)
       
   957                         if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i:
       
   958                             self.StartStyling(start_pos, wxSTC_INDICS_MASK)
       
   959                             self.SetStyling(i - start_pos, wxSTC_INDIC0_MASK)
       
   960                             self.StartStyling(i, 0xff)    
       
   961                 else:
       
   962                     self.SetStyling(i - start_pos, 31)
       
   963                 start_pos = i
       
   964                 state = SPACE
       
   965                 line = ""
       
   966             elif line.endswith("(*") and state != COMMENT:
       
   967                 self.SetStyling(i - start_pos - 1, 31)
       
   968                 start_pos = i
       
   969                 state = COMMENT
       
   970             elif state == COMMENT:
       
   971                 if line.endswith("*)"):
       
   972                     self.SetStyling(i - start_pos + 2, wxSTC_PLC_COMMENT)
       
   973                     start_pos = i + 1
       
   974                     state = SPACE
       
   975             elif char in LETTERS:
       
   976                 if state == NUMBER:
       
   977                     word = "#"
       
   978                     state = WORD
       
   979                 elif state == SPACE:
       
   980                     self.SetStyling(i - start_pos, 31)
       
   981                     word = char
       
   982                     start_pos = i
       
   983                     state = WORD
       
   984                 else:
       
   985                     word += char
       
   986             elif char in NUMBERS or char == '.' and state != WORD:
       
   987                 if state == SPACE:
       
   988                     self.SetStyling(i - start_pos, 31)
       
   989                     start_pos = i
       
   990                     state = NUMBER
       
   991                 if state == WORD and char != '.':
       
   992                     word += char
       
   993             else:
       
   994                 if state == WORD:
       
   995                     if word in self.Keywords:
       
   996                         self.SetStyling(i - start_pos, wxSTC_PLC_WORD)
       
   997                     elif word in self.Variables:
       
   998                         self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE)
       
   999                     elif word in self.Functions:
       
  1000                         self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION)
       
  1001                     elif word in self.Jumps:
       
  1002                         self.SetStyling(i - start_pos, wxSTC_PLC_JUMP)
       
  1003                     else:
       
  1004                         self.SetStyling(i - start_pos, 31)
       
  1005                         if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i:
       
  1006                             self.StartStyling(start_pos, wxSTC_INDICS_MASK)
       
  1007                             self.SetStyling(i - start_pos, wxSTC_INDIC0_MASK)
       
  1008                             self.StartStyling(i, 0xff)
       
  1009                     word = ""
       
  1010                     start_pos = i
       
  1011                     state = SPACE
       
  1012                 elif state == NUMBER:
       
  1013                     self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER)
       
  1014                     start_pos = i
       
  1015                     state = SPACE
       
  1016             i += 1
       
  1017         if state == COMMENT:
       
  1018             self.SetStyling(i - start_pos + 2, wxSTC_PLC_COMMENT)
       
  1019         elif state == NUMBER:
       
  1020             self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER)
       
  1021         elif state == WORD:
       
  1022             if word in self.Keywords:
       
  1023                 self.SetStyling(i - start_pos, wxSTC_PLC_WORD)
       
  1024             elif word in self.Variables:
       
  1025                 self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE)
       
  1026             elif word in self.Functions:
       
  1027                 self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION)
       
  1028             elif word in self.Jumps:
       
  1029                 self.SetStyling(i - start_pos, wxSTC_PLC_JUMP)
       
  1030             else:
       
  1031                 self.SetStyling(i - start_pos, 31)
       
  1032         else:
       
  1033             self.SetStyling(i - start_pos, 31)
       
  1034         event.Skip()
       
  1035     
       
  1036     def Cut(self):
       
  1037         self.CmdKeyExecute(wxSTC_CMD_CUT)
       
  1038         
       
  1039     def Copy(self):
       
  1040         self.CmdKeyExecute(wxSTC_CMD_COPY)
       
  1041     
       
  1042     def Paste(self):
       
  1043         self.CmdKeyExecute(wxSTC_CMD_PASTE)
       
  1044     
       
  1045     def RefreshModel(self):
       
  1046         if self.TextChanged:
       
  1047             self.RefreshJumpList()
       
  1048             self.Controler.SetCurrentElementEditingText(self.GetText())
       
  1049     
       
  1050     def OnKeyDown(self, event):
       
  1051         if self.CallTipActive():
       
  1052             self.CallTipCancel()
       
  1053         key = event.KeyCode()
       
  1054 
       
  1055         # Code completion
       
  1056         if key == WXK_SPACE and event.ControlDown():
       
  1057             
       
  1058             line = self.GetCurrentLine()
       
  1059             if line == 0:
       
  1060                 start_pos = 0
       
  1061             else:
       
  1062                 start_pos = self.GetLineEndPosition(line - 1) + 1
       
  1063             end_pos = self.GetCurrentPos()
       
  1064 
       
  1065             lineText = self.GetTextRange(start_pos, end_pos).replace("\t", " ")
       
  1066             words = lineText.split(" ")
       
  1067             words = [word for i, word in enumerate(words) if word != '' or i == len(words) - 1]
       
  1068                         
       
  1069             kw = []
       
  1070             
       
  1071             if self.TextSyntax == "IL":
       
  1072                 if len(words) == 1:
       
  1073                     kw = self.Keywords
       
  1074                 elif len(words) == 2:
       
  1075                     if words[0].upper() in ["CAL", "CALC", "CALNC"]:
       
  1076                         kw = self.Functions
       
  1077                     elif words[0].upper() in ["JMP", "JMPC", "JMPNC"]:
       
  1078                         kw = self.Jumps
       
  1079                     else:
       
  1080                         kw = self.Variables
       
  1081             else:
       
  1082                 kw = self.Keywords + self.Variables + self.Functions
       
  1083             if len(kw) > 0:
       
  1084                 kw.sort()
       
  1085                 self.AutoCompSetIgnoreCase(True)
       
  1086                 self.AutoCompShow(len(words[-1]), " ".join(kw))
       
  1087         else:
       
  1088             self.TextChanged = False
       
  1089             wxCallAfter(self.RefreshModel)
       
  1090             event.Skip()
       
  1091 
       
  1092     def OnKillFocus(self, event):
       
  1093         self.AutoCompCancel()
       
  1094         event.Skip()
       
  1095 
       
  1096 
       
  1097 #-------------------------------------------------------------------------------
       
  1098 #                            Resource Editor class
       
  1099 #-------------------------------------------------------------------------------
       
  1100 
       
  1101 class ResourceTable(wxPyGridTableBase):
       
  1102     
       
  1103     """
       
  1104     A custom wxGrid Table using user supplied data
       
  1105     """
       
  1106     def __init__(self, parent, data, colnames):
       
  1107         # The base class must be initialized *first*
       
  1108         wxPyGridTableBase.__init__(self)
       
  1109         self.data = data
       
  1110         self.colnames = colnames
       
  1111         self.Parent = parent
       
  1112         
       
  1113         self.ColAlignements = []
       
  1114         self.ColSizes = []
       
  1115         # XXX
       
  1116         # we need to store the row length and collength to
       
  1117         # see if the table has changed size
       
  1118         self._rows = self.GetNumberRows()
       
  1119         self._cols = self.GetNumberCols()
       
  1120     
       
  1121     def GetColAlignements(self):
       
  1122         return self.ColAlignements
       
  1123     
       
  1124     def SetColAlignements(self, list):
       
  1125         self.ColAlignements = list
       
  1126 
       
  1127     def GetColSizes(self):
       
  1128         return self.ColSizes
       
  1129     
       
  1130     def SetColSizes(self, list):
       
  1131         self.ColSizes = list
       
  1132 
       
  1133     def GetNumberCols(self):
       
  1134         return len(self.colnames)
       
  1135         
       
  1136     def GetNumberRows(self):
       
  1137         return len(self.data)
       
  1138 
       
  1139     def GetColLabelValue(self, col):
       
  1140         if col < len(self.colnames):
       
  1141             return self.colnames[col]
       
  1142 
       
  1143     def GetRowLabelValues(self, row):
       
  1144         return row
       
  1145 
       
  1146     def GetValue(self, row, col):
       
  1147         if row < self.GetNumberRows():
       
  1148             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
       
  1149             return name
       
  1150     
       
  1151     def GetValueByName(self, row, colname):
       
  1152         return self.data[row].get(colname)
       
  1153 
       
  1154     def SetValue(self, row, col, value):
       
  1155         if col < len(self.colnames):
       
  1156             self.data[row][self.GetColLabelValue(col)] = value
       
  1157     
       
  1158     def SetValueByName(self, row, colname, value):
       
  1159         if colname in self.colnames:
       
  1160             self.data[row][colname] = value
       
  1161     
       
  1162     def ResetView(self, grid):
       
  1163         """
       
  1164         (wxGrid) -> Reset the grid view.   Call this to
       
  1165         update the grid if rows and columns have been added or deleted
       
  1166         """
       
  1167         grid.BeginBatch()
       
  1168         for current, new, delmsg, addmsg in [
       
  1169             (self._rows, self.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED),
       
  1170             (self._cols, self.GetNumberCols(), wxGRIDTABLE_NOTIFY_COLS_DELETED, wxGRIDTABLE_NOTIFY_COLS_APPENDED),
       
  1171         ]:
       
  1172             if new < current:
       
  1173                 msg = wxGridTableMessage(self,delmsg,new,current-new)
       
  1174                 grid.ProcessTableMessage(msg)
       
  1175             elif new > current:
       
  1176                 msg = wxGridTableMessage(self,addmsg,new-current)
       
  1177                 grid.ProcessTableMessage(msg)
       
  1178                 self.UpdateValues(grid)
       
  1179         grid.EndBatch()
       
  1180 
       
  1181         self._rows = self.GetNumberRows()
       
  1182         self._cols = self.GetNumberCols()
       
  1183         # update the column rendering scheme
       
  1184         self._updateColAttrs(grid)
       
  1185 
       
  1186         # update the scrollbars and the displayed part of the grid
       
  1187         grid.AdjustScrollbars()
       
  1188         grid.ForceRefresh()
       
  1189 
       
  1190     def UpdateValues(self, grid):
       
  1191         """Update all displayed values"""
       
  1192         # This sends an event to the grid table to update all of the values
       
  1193         msg = wxGridTableMessage(self, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES)
       
  1194         grid.ProcessTableMessage(msg)
       
  1195 
       
  1196     def _updateColAttrs(self, grid):
       
  1197         """
       
  1198         wxGrid -> update the column attributes to add the
       
  1199         appropriate renderer given the column name.
       
  1200 
       
  1201         Otherwise default to the default renderer.
       
  1202         """
       
  1203         
       
  1204         for col in range(self.GetNumberCols()):
       
  1205             attr = wxGridCellAttr()
       
  1206             attr.SetAlignment(self.ColAlignements[col], wxALIGN_CENTRE)
       
  1207             grid.SetColAttr(col, attr)
       
  1208             grid.SetColSize(col, self.ColSizes[col])
       
  1209         
       
  1210         for row in range(self.GetNumberRows()):
       
  1211             for col in range(self.GetNumberCols()):
       
  1212                 editor = None
       
  1213                 renderer = None
       
  1214                 colname = self.GetColLabelValue(col)
       
  1215                 grid.SetReadOnly(row, col, False)
       
  1216                 if colname in ["Name","Interval"]:
       
  1217                     editor = wxGridCellTextEditor()
       
  1218                     renderer = wxGridCellStringRenderer()
       
  1219                     if colname == "Interval" and self.GetValueByName(row, "Single") != "":
       
  1220                         grid.SetReadOnly(row, col, True)
       
  1221                 elif colname == "Single":
       
  1222                     editor = wxGridCellChoiceEditor()
       
  1223                     editor.SetParameters(self.Parent.VariableList)
       
  1224                     if self.GetValueByName(row, "Interval") != "":
       
  1225                         grid.SetReadOnly(row, col, True)
       
  1226                 elif colname == "Type":
       
  1227                     editor = wxGridCellChoiceEditor()
       
  1228                     editor.SetParameters(self.Parent.TypeList)
       
  1229                 elif colname == "Priority":
       
  1230                     editor = wxGridCellNumberEditor()
       
  1231                     editor.SetParameters("0,65535")
       
  1232                 elif colname == "Task":
       
  1233                     editor = wxGridCellChoiceEditor()
       
  1234                     editor.SetParameters(self.Parent.TaskList)
       
  1235                     
       
  1236                 grid.SetCellEditor(row, col, editor)
       
  1237                 grid.SetCellRenderer(row, col, renderer)
       
  1238                 
       
  1239                 grid.SetCellBackgroundColour(row, col, wxWHITE)
       
  1240     
       
  1241     def SetData(self, data):
       
  1242         self.data = data
       
  1243     
       
  1244     def GetData(self):
       
  1245         return self.data
       
  1246     
       
  1247     def GetCurrentIndex(self):
       
  1248         return self.CurrentIndex
       
  1249     
       
  1250     def SetCurrentIndex(self, index):
       
  1251         self.CurrentIndex = index
       
  1252     
       
  1253     def AppendRow(self, row_content):
       
  1254         self.data.append(row_content)
       
  1255 
       
  1256     def RemoveRow(self, row_index):
       
  1257         self.data.pop(row_index)
       
  1258         
       
  1259     def MoveRow(self, row_index, move, grid):
       
  1260         new_index = max(0, min(row_index + move, len(self.data) - 1))
       
  1261         if new_index != row_index:
       
  1262             self.data.insert(new_index, self.data.pop(row_index))
       
  1263             grid.SetGridCursor(new_index, grid.GetGridCursorCol())
       
  1264 
       
  1265     def Empty(self):
       
  1266         self.data = []
       
  1267         self.editors = []
       
  1268 
       
  1269 [wxID_RESOURCEEDITOR, wxID_RESOURCEEDITORSTATICTEXT1,
       
  1270  wxID_RESOURCEEDITORSTATICTEXT2, wxID_RESOURCEEDITORINSTANCESGRID,
       
  1271  wxID_RESOURCEEDITORTASKSGRID, wxID_RESOURCEEDITORADDINSTANCEBUTTON,
       
  1272  wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, wxID_RESOURCEEDITORUPINSTANCEBUTTON,
       
  1273  wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, wxID_RESOURCEEDITORADDTASKBUTTON,
       
  1274  wxID_RESOURCEEDITORDELETETASKBUTTON, wxID_RESOURCEEDITORUPTASKBUTTON,
       
  1275  wxID_RESOURCEEDITORDOWNTASKBUTTON,
       
  1276 ] = [wx.NewId() for _init_ctrls in range(13)]
       
  1277 
       
  1278 class ResourceEditor(wx.Panel):
       
  1279     
       
  1280     def _init_coll_InstancesSizer_Growables(self, parent):
       
  1281         # generated method, don't edit
       
  1282 
       
  1283         parent.AddGrowableCol(0)
       
  1284         parent.AddGrowableRow(1)
       
  1285 
       
  1286     def _init_coll_InstancesSizer_Items(self, parent):
       
  1287         # generated method, don't edit
       
  1288 
       
  1289         parent.AddSizer(self.InstancesButtonsSizer, 0, border=0, flag=wxGROW)
       
  1290         parent.AddWindow(self.InstancesGrid, 0, border=0, flag=wxGROW)
       
  1291 
       
  1292     def _init_coll_InstancesButtonsSizer_Growables(self, parent):
       
  1293         # generated method, don't edit
       
  1294 
       
  1295         parent.AddGrowableCol(0)
       
  1296         parent.AddGrowableRow(0)
       
  1297 
       
  1298     def _init_coll_InstancesButtonsSizer_Items(self, parent):
       
  1299         # generated method, don't edit
       
  1300 
       
  1301         parent.AddWindow(self.staticText2, 0, border=0, flag=wxALIGN_BOTTOM)
       
  1302         parent.AddWindow(self.AddInstanceButton, 0, border=0, flag=0)
       
  1303         parent.AddWindow(self.DeleteInstanceButton, 0, border=0, flag=0)
       
  1304         parent.AddWindow(self.UpInstanceButton, 0, border=0, flag=0)
       
  1305         parent.AddWindow(self.DownInstanceButton, 0, border=0, flag=0)
       
  1306 
       
  1307     def _init_coll_TasksSizer_Growables(self, parent):
       
  1308         # generated method, don't edit
       
  1309 
       
  1310         parent.AddGrowableCol(0)
       
  1311         parent.AddGrowableRow(1)
       
  1312 
       
  1313     def _init_coll_TasksSizer_Items(self, parent):
       
  1314         # generated method, don't edit
       
  1315 
       
  1316         parent.AddSizer(self.TasksButtonsSizer, 0, border=0, flag=wxGROW)
       
  1317         parent.AddWindow(self.TasksGrid, 0, border=0, flag=wxGROW)
       
  1318 
       
  1319     def _init_coll_TasksButtonsSizer_Growables(self, parent):
       
  1320         # generated method, don't edit
       
  1321 
       
  1322         parent.AddGrowableCol(0)
       
  1323         parent.AddGrowableRow(0)
       
  1324 
       
  1325     def _init_coll_TasksButtonsSizer_Items(self, parent):
       
  1326         # generated method, don't edit
       
  1327 
       
  1328         parent.AddWindow(self.staticText1, 0, border=0, flag=wxALIGN_BOTTOM)
       
  1329         parent.AddWindow(self.AddTaskButton, 0, border=0, flag=0)
       
  1330         parent.AddWindow(self.DeleteTaskButton, 0, border=0, flag=0)
       
  1331         parent.AddWindow(self.UpTaskButton, 0, border=0, flag=0)
       
  1332         parent.AddWindow(self.DownTaskButton, 0, border=0, flag=0)
       
  1333 
       
  1334     def _init_coll_MainGridSizer_Items(self, parent):
       
  1335         # generated method, don't edit
       
  1336 
       
  1337         parent.AddSizer(self.TasksSizer, 0, border=0, flag=wxGROW)
       
  1338         parent.AddSizer(self.InstancesSizer, 0, border=0, flag=wxGROW)
       
  1339 
       
  1340     def _init_coll_MainGridSizer_Growables(self, parent):
       
  1341         # generated method, don't edit
       
  1342 
       
  1343         parent.AddGrowableCol(0)
       
  1344         parent.AddGrowableRow(0)
       
  1345         parent.AddGrowableRow(1)
       
  1346 
       
  1347     def _init_sizers(self):
       
  1348         # generated method, don't edit
       
  1349         self.MainGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  1350 
       
  1351         self.InstancesSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  1352 
       
  1353         self.InstancesButtonsSizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
       
  1354 
       
  1355         self.TasksSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
       
  1356 
       
  1357         self.TasksButtonsSizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
       
  1358 
       
  1359         self._init_coll_MainGridSizer_Growables(self.MainGridSizer)
       
  1360         self._init_coll_MainGridSizer_Items(self.MainGridSizer)
       
  1361         self._init_coll_InstancesSizer_Growables(self.InstancesSizer)
       
  1362         self._init_coll_InstancesSizer_Items(self.InstancesSizer)
       
  1363         self._init_coll_InstancesButtonsSizer_Growables(self.InstancesButtonsSizer)
       
  1364         self._init_coll_InstancesButtonsSizer_Items(self.InstancesButtonsSizer)
       
  1365         self._init_coll_TasksSizer_Growables(self.TasksSizer)
       
  1366         self._init_coll_TasksSizer_Items(self.TasksSizer)
       
  1367         self._init_coll_TasksButtonsSizer_Growables(self.TasksButtonsSizer)
       
  1368         self._init_coll_TasksButtonsSizer_Items(self.TasksButtonsSizer)
       
  1369 
       
  1370         self.SetSizer(self.MainGridSizer)
       
  1371 
       
  1372     def _init_ctrls(self, prnt):
       
  1373         # generated method, don't edit
       
  1374         wx.Panel.__init__(self, id=wxID_RESOURCEEDITOR, name='', parent=prnt,
       
  1375               pos=wx.Point(0, 0), size=wx.Size(-1, -1),
       
  1376               style=wx.SUNKEN_BORDER)
       
  1377         
       
  1378         self.staticText1 = wx.StaticText(id=wxID_RESOURCEEDITORSTATICTEXT1,
       
  1379               label=u'Tasks:', name='staticText2', parent=self, pos=wx.Point(0,
       
  1380               0), size=wx.Size(60, 17), style=wxALIGN_CENTER)
       
  1381 
       
  1382         self.TasksGrid = wx.grid.Grid(id=wxID_RESOURCEEDITORTASKSGRID,
       
  1383               name='TasksGrid', parent=self, pos=wx.Point(0, 0), 
       
  1384               size=wx.Size(-1, -1), style=wxVSCROLL)
       
  1385         self.TasksGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
  1386               'Sans'))
       
  1387         self.TasksGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
  1388               False, 'Sans'))
       
  1389         EVT_GRID_CELL_CHANGE(self.TasksGrid, self.OnTasksGridCellChange)
       
  1390 
       
  1391         self.AddTaskButton = wx.Button(id=wxID_RESOURCEEDITORADDTASKBUTTON, label='Add Task',
       
  1392               name='AddTaskButton', parent=self, pos=wx.Point(0, 0),
       
  1393               size=wx.Size(102, 32), style=0)
       
  1394         EVT_BUTTON(self, wxID_RESOURCEEDITORADDTASKBUTTON, self.OnAddTaskButton)
       
  1395 
       
  1396         self.DeleteTaskButton = wx.Button(id=wxID_RESOURCEEDITORDELETETASKBUTTON, label='Delete Task',
       
  1397               name='DeleteTaskButton', parent=self, pos=wx.Point(0, 0),
       
  1398               size=wx.Size(102, 32), style=0)
       
  1399         EVT_BUTTON(self, wxID_RESOURCEEDITORDELETETASKBUTTON, self.OnDeleteTaskButton)
       
  1400 
       
  1401         self.UpTaskButton = wx.Button(id=wxID_RESOURCEEDITORUPTASKBUTTON, label='^',
       
  1402               name='UpTaskButton', parent=self, pos=wx.Point(0, 0),
       
  1403               size=wx.Size(32, 32), style=0)
       
  1404         EVT_BUTTON(self, wxID_RESOURCEEDITORUPTASKBUTTON, self.OnUpTaskButton)
       
  1405 
       
  1406         self.DownTaskButton = wx.Button(id=wxID_RESOURCEEDITORDOWNTASKBUTTON, label='v',
       
  1407               name='DownTaskButton', parent=self, pos=wx.Point(0, 0),
       
  1408               size=wx.Size(32, 32), style=0)
       
  1409         EVT_BUTTON(self, wxID_RESOURCEEDITORDOWNTASKBUTTON, self.OnDownTaskButton)
       
  1410 
       
  1411         self.staticText2 = wx.StaticText(id=wxID_RESOURCEEDITORSTATICTEXT2,
       
  1412               label=u'Instances:', name='staticText1', parent=self,
       
  1413               pos=wx.Point(0, 0), size=wx.Size(85, 17), style=wxALIGN_CENTER)
       
  1414 
       
  1415         self.InstancesGrid = wx.grid.Grid(id=wxID_RESOURCEEDITORINSTANCESGRID,
       
  1416               name='InstancesGrid', parent=self, pos=wx.Point(0, 0), 
       
  1417               size=wx.Size(-1, -1), style=wxVSCROLL)
       
  1418         self.InstancesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
       
  1419               'Sans'))
       
  1420         self.InstancesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
       
  1421               False, 'Sans'))
       
  1422         EVT_GRID_CELL_CHANGE(self.InstancesGrid, self.OnInstancesGridCellChange)
       
  1423 
       
  1424         self.AddInstanceButton = wx.Button(id=wxID_RESOURCEEDITORADDINSTANCEBUTTON, label='Add Instance',
       
  1425               name='AddInstanceButton', parent=self, pos=wx.Point(0, 0),
       
  1426               size=wx.Size(122, 32), style=0)
       
  1427         EVT_BUTTON(self, wxID_RESOURCEEDITORADDINSTANCEBUTTON, self.OnAddInstanceButton)
       
  1428 
       
  1429         self.DeleteInstanceButton = wx.Button(id=wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, label='Delete Instance',
       
  1430               name='DeleteInstanceButton', parent=self, pos=wx.Point(0, 0),
       
  1431               size=wx.Size(122, 32), style=0)
       
  1432         EVT_BUTTON(self, wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, self.OnDeleteInstanceButton)
       
  1433 
       
  1434         self.UpInstanceButton = wx.Button(id=wxID_RESOURCEEDITORUPINSTANCEBUTTON, label='^',
       
  1435               name='UpInstanceButton', parent=self, pos=wx.Point(0, 0),
       
  1436               size=wx.Size(32, 32), style=0)
       
  1437         EVT_BUTTON(self, wxID_RESOURCEEDITORUPINSTANCEBUTTON, self.OnUpInstanceButton)
       
  1438 
       
  1439         self.DownInstanceButton = wx.Button(id=wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, label='v',
       
  1440               name='DownInstanceButton', parent=self, pos=wx.Point(0, 0),
       
  1441               size=wx.Size(32, 32), style=0)
       
  1442         EVT_BUTTON(self, wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, self.OnDownInstanceButton)
       
  1443 
       
  1444         self._init_sizers()
       
  1445 
       
  1446     def __init__(self, parent, window, controler):
       
  1447         self._init_ctrls(parent)
       
  1448         
       
  1449         self.Parent = window
       
  1450         self.Controler = controler
       
  1451         
       
  1452         self.TasksDefaultValue = {"Name" : "", "Single" : "", "Interval" : "", "Priority" : 0}
       
  1453         self.TasksTable = ResourceTable(self, [], ["Name", "Single", "Interval", "Priority"])
       
  1454         self.TasksTable.SetColAlignements([wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_RIGHT, wxALIGN_RIGHT])
       
  1455         self.TasksTable.SetColSizes([200, 100, 100, 100])
       
  1456         self.TasksGrid.SetTable(self.TasksTable)
       
  1457         self.TasksGrid.SetRowLabelSize(0)
       
  1458         self.TasksTable.ResetView(self.TasksGrid)
       
  1459 
       
  1460         self.InstancesDefaultValue = {"Name" : "", "Type" : "", "Task" : ""}
       
  1461         self.InstancesTable = ResourceTable(self, [], ["Name", "Type", "Task"])
       
  1462         self.InstancesTable.SetColAlignements([wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT])
       
  1463         self.InstancesTable.SetColSizes([200, 150, 150])
       
  1464         self.InstancesGrid.SetTable(self.InstancesTable)
       
  1465         self.InstancesGrid.SetRowLabelSize(0)
       
  1466         self.InstancesTable.ResetView(self.InstancesGrid)
       
  1467 
       
  1468     def SetMode(self, mode):
       
  1469         pass
       
  1470 
       
  1471     def RefreshTypeList(self):
       
  1472         self.TypeList = ""
       
  1473         blocktypes = self.Controler.GetBlockResource()
       
  1474         for blocktype in blocktypes:
       
  1475             self.TypeList += ",%s"%blocktype
       
  1476 
       
  1477     def RefreshTaskList(self):
       
  1478         self.TaskList = ""
       
  1479         for row in xrange(self.TasksTable.GetNumberRows()):
       
  1480             self.TaskList += ",%s"%self.TasksTable.GetValueByName(row, "Name")
       
  1481 
       
  1482     def RefreshVariableList(self):
       
  1483         self.VariableList = ""
       
  1484         for variable in self.Controler.GetCurrentResourceEditingVariables():
       
  1485             self.VariableList += ",%s"%variable
       
  1486         
       
  1487     def RefreshModel(self):
       
  1488         self.Controler.SetCurrentResourceEditingInfos(self.TasksTable.GetData(), self.InstancesTable.GetData())
       
  1489 
       
  1490     def RefreshView(self):
       
  1491         tasks, instances = self.Controler.GetCurrentResourceEditingInfos()
       
  1492         self.TasksTable.SetData(tasks)
       
  1493         self.InstancesTable.SetData(instances)
       
  1494         self.RefreshTypeList()
       
  1495         self.RefreshTaskList()
       
  1496         self.RefreshVariableList()
       
  1497         self.InstancesTable.ResetView(self.InstancesGrid)
       
  1498         self.TasksTable.ResetView(self.TasksGrid)
       
  1499 
       
  1500     def OnAddTaskButton(self, event):
       
  1501         self.TasksTable.AppendRow(self.TasksDefaultValue.copy())
       
  1502         self.RefreshModel()
       
  1503         self.RefreshView()
       
  1504         event.Skip()
       
  1505 
       
  1506     def OnDeleteTaskButton(self, event):
       
  1507         row = self.TasksGrid.GetGridCursorRow()
       
  1508         self.TasksTable.RemoveRow(row)
       
  1509         self.RefreshModel()
       
  1510         self.RefreshView()
       
  1511         event.Skip()
       
  1512 
       
  1513     def OnUpTaskButton(self, event):
       
  1514         row = self.TasksGrid.GetGridCursorRow()
       
  1515         self.TasksTable.MoveRow(row, -1, self.TasksGrid)
       
  1516         self.RefreshModel()
       
  1517         self.RefreshView()
       
  1518         event.Skip()
       
  1519 
       
  1520     def OnDownTaskButton(self, event):
       
  1521         row = self.TasksGrid.GetGridCursorRow()
       
  1522         self.TasksTable.MoveRow(row, 1, self.TasksGrid)
       
  1523         self.RefreshModel()
       
  1524         self.RefreshView()
       
  1525         event.Skip()
       
  1526 
       
  1527     def OnAddInstanceButton(self, event):
       
  1528         self.InstancesTable.AppendRow(self.InstancesDefaultValue.copy())
       
  1529         self.RefreshModel()
       
  1530         self.RefreshView()
       
  1531         event.Skip()
       
  1532 
       
  1533     def OnDeleteInstanceButton(self, event):
       
  1534         row = self.InstancesGrid.GetGridCursorRow()
       
  1535         self.InstancesTable.RemoveRow(row)
       
  1536         self.RefreshModel()
       
  1537         self.RefreshView()
       
  1538         event.Skip()
       
  1539 
       
  1540     def OnUpInstanceButton(self, event):
       
  1541         row = self.InstancesGrid.GetGridCursorRow()
       
  1542         self.InstancesTable.MoveRow(row, -1, self.InstancesGrid)
       
  1543         self.RefreshModel()
       
  1544         self.RefreshView()
       
  1545         event.Skip()
       
  1546 
       
  1547     def OnDownInstanceButton(self, event):
       
  1548         row = self.InstancesGrid.GetGridCursorRow()
       
  1549         self.InstancesTable.MoveRow(row, 1, self.InstancesGrid)
       
  1550         self.RefreshModel()
       
  1551         self.RefreshView()
       
  1552         event.Skip()
       
  1553 
       
  1554     def OnTasksGridCellChange(self, event):
       
  1555         row, col = event.GetRow(), event.GetCol()
       
  1556         if self.TasksTable.GetColLabelValue(event.GetCol()) == "Name":
       
  1557             tasklist = self.TaskList.split(",")
       
  1558             for i in xrange(self.TasksTable.GetNumberRows()):
       
  1559                 task = self.TasksTable.GetValueByName(i, "Name")
       
  1560                 if task in tasklist:
       
  1561                     tasklist.remove(task)
       
  1562             tasklist.remove("")
       
  1563             if len(tasklist) > 0:
       
  1564                 old_name = tasklist[0]
       
  1565                 new_name = self.TasksTable.GetValue(row, col)
       
  1566                 for i in xrange(self.InstancesTable.GetNumberRows()):
       
  1567                     if self.InstancesTable.GetValueByName(i, "Task") == old_name:
       
  1568                         self.InstancesTable.SetValueByName(i, "Task", new_name)
       
  1569         self.RefreshModel()
       
  1570         self.RefreshView()
       
  1571         event.Skip()
       
  1572 
       
  1573     def OnInstancesGridCellChange(self, event):
       
  1574         self.RefreshModel()
       
  1575         self.RefreshView()
       
  1576         event.Skip()