etisserant@0: #!/usr/bin/env python etisserant@0: # -*- coding: utf-8 -*- etisserant@0: etisserant@0: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor etisserant@0: #based on the plcopen standard. etisserant@0: # etisserant@0: #Copyright (C): Edouard TISSERANT and Laurent BESSARD etisserant@0: # etisserant@0: #See COPYING file for copyrights details. etisserant@0: # etisserant@0: #This library is free software; you can redistribute it and/or etisserant@0: #modify it under the terms of the GNU Lesser General Public etisserant@0: #License as published by the Free Software Foundation; either etisserant@0: #version 2.1 of the License, or (at your option) any later version. etisserant@0: # etisserant@0: #This library is distributed in the hope that it will be useful, etisserant@0: #but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@0: #Lesser General Public License for more details. etisserant@0: # etisserant@0: #You should have received a copy of the GNU Lesser General Public etisserant@0: #License along with this library; if not, write to the Free Software etisserant@0: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: etisserant@0: from wxPython.wx import * etisserant@0: from wxPython.stc import * etisserant@0: from wxPython.grid import * etisserant@0: import wx etisserant@0: etisserant@0: from plcopen.structures import * etisserant@0: from graphics.GraphicCommons import * etisserant@0: from graphics.SFC_Objects import * etisserant@0: from graphics.FBD_Objects import * etisserant@0: from graphics.LD_Objects import * etisserant@0: etisserant@0: import re etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Graphic elements Viewer base class etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: # ID Constants for menu items etisserant@0: [wxID_FBDVIEWERCONTEXTUALMENUITEMS0, wxID_FBDVIEWERCONTEXTUALMENUITEMS1, etisserant@0: wxID_FBDVIEWERCONTEXTUALMENUITEMS2, wxID_FBDVIEWERCONTEXTUALMENUITEMS3, etisserant@0: wxID_FBDVIEWERCONTEXTUALMENUITEMS5, wxID_FBDVIEWERCONTEXTUALMENUITEMS6, etisserant@0: wxID_FBDVIEWERCONTEXTUALMENUITEMS8, wxID_FBDVIEWERCONTEXTUALMENUITEMS9, etisserant@0: wxID_FBDVIEWERCONTEXTUALMENUITEMS11, etisserant@0: ] = [wx.NewId() for _init_coll_ContextualMenu_Items in range(9)] etisserant@0: etisserant@0: etisserant@0: """ etisserant@0: Class that implements a Viewer based on a wxScrolledWindow for drawing and etisserant@0: manipulating graphic elements etisserant@0: """ etisserant@0: etisserant@0: class Viewer(wx.ScrolledWindow): etisserant@0: etisserant@0: # Create Contextual Menu items etisserant@0: def _init_coll_ContextualMenu_Items(self, parent): etisserant@0: # Create menu items etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS0, etisserant@0: kind=wx.ITEM_RADIO, text=u'No Modifier') etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS1, etisserant@0: kind=wx.ITEM_RADIO, text=u'Negated') etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS2, etisserant@0: kind=wx.ITEM_RADIO, text=u'Rising Edge') etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS3, etisserant@0: kind=wx.ITEM_RADIO, text=u'Falling Edge') etisserant@0: parent.AppendSeparator() etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS5, etisserant@0: kind=wx.ITEM_NORMAL, text=u'Add Wire Segment') etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS6, etisserant@0: kind=wx.ITEM_NORMAL, text=u'Delete Wire Segment') etisserant@0: parent.AppendSeparator() etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS8, etisserant@0: kind=wx.ITEM_NORMAL, text=u'Add Divergence Branch') etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS9, etisserant@0: kind=wx.ITEM_NORMAL, text=u'Delete Divergence Branch') etisserant@0: parent.AppendSeparator() etisserant@0: parent.Append(help='', id=wxID_FBDVIEWERCONTEXTUALMENUITEMS11, etisserant@0: kind=wx.ITEM_NORMAL, text=u'Delete') etisserant@0: # Link menu event to corresponding called functions etisserant@0: self.Bind(wx.EVT_MENU, self.OnNoModifierMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS0) etisserant@0: self.Bind(wx.EVT_MENU, self.OnNegatedMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS1) etisserant@0: self.Bind(wx.EVT_MENU, self.OnRisingEdgeMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS2) etisserant@0: self.Bind(wx.EVT_MENU, self.OnFallingEdgeMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS3) etisserant@0: self.Bind(wx.EVT_MENU, self.OnAddSegmentMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS5) etisserant@0: self.Bind(wx.EVT_MENU, self.OnDeleteSegmentMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS6) etisserant@0: self.Bind(wx.EVT_MENU, self.OnAddBranchMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS8) etisserant@0: self.Bind(wx.EVT_MENU, self.OnDeleteBranchMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS9) etisserant@0: self.Bind(wx.EVT_MENU, self.OnDeleteMenu, etisserant@0: id=wxID_FBDVIEWERCONTEXTUALMENUITEMS11) etisserant@0: etisserant@0: # Create and initialize Contextual Menu etisserant@0: def _init_menus(self): etisserant@0: self.ContextualMenu = wx.Menu(title='') etisserant@0: etisserant@0: self._init_coll_ContextualMenu_Items(self.ContextualMenu) etisserant@0: etisserant@0: # Create a new Viewer etisserant@0: def __init__(self, parent, window, controler): etisserant@0: wx.ScrolledWindow.__init__(self, parent, style=wx.SUNKEN_BORDER) etisserant@0: self._init_menus() etisserant@0: # Adding a rubberband to Viewer etisserant@0: self.rubberBand = RubberBand(drawingSurface=self) etisserant@0: self.SetBackgroundColour(wxColour(255,255,255)) etisserant@0: self.ResetView() etisserant@0: self.Scaling = None etisserant@0: #self.Scaling = (8, 8) etisserant@0: self.DrawGrid = True etisserant@0: self.current_id = 0 etisserant@0: etisserant@0: # Initialize Viewer mode to Selection mode etisserant@0: self.Mode = MODE_SELECTION etisserant@0: etisserant@0: self.Parent = window etisserant@0: self.Controler = controler etisserant@0: etisserant@0: # Link Viewer event to corresponding methods etisserant@0: EVT_PAINT(self, self.OnPaint) etisserant@0: EVT_LEFT_DOWN(self, self.OnViewerLeftDown) etisserant@0: EVT_LEFT_UP(self, self.OnViewerLeftUp) etisserant@0: EVT_LEFT_DCLICK(self, self.OnViewerLeftDClick) etisserant@0: EVT_RIGHT_UP(self, self.OnViewerRightUp) etisserant@0: EVT_MOTION(self, self.OnViewerMotion) etisserant@0: EVT_CHAR(self, self.OnChar) etisserant@0: etisserant@0: # Returns a new id etisserant@0: def GetNewId(self): etisserant@0: self.current_id += 1 etisserant@0: return self.current_id etisserant@0: etisserant@0: # Destructor etisserant@0: def __del__(self): etisserant@0: self.ResetView() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Reset functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: # Resets Viewer lists etisserant@0: def ResetView(self): etisserant@0: self.Blocks = [] etisserant@0: self.Wires = [] etisserant@0: self.Elements = [] etisserant@0: self.SelectedElement = None etisserant@0: etisserant@0: # Changes Viewer mode etisserant@0: def SetMode(self, mode): etisserant@0: self.Mode = mode etisserant@0: # Reset selection etisserant@0: if self.SelectedElement: etisserant@0: self.SelectedElement.SetSelected(False) etisserant@0: self.SelectedElement = None etisserant@0: self.Refresh() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Refresh functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: # Refresh Viewer elements etisserant@0: def RefreshView(self): etisserant@0: self.current_id = 0 etisserant@0: # Start by reseting Viewer etisserant@0: self.ResetView() etisserant@0: instance = True etisserant@0: # List of ids of already loaded blocks etisserant@0: ids = [] etisserant@0: # Load Blocks until they are all loaded etisserant@0: while instance: etisserant@0: instance = self.Controler.GetCurrentElementEditingInstanceInfos(exclude=ids) etisserant@0: if instance: etisserant@0: self.loadInstance(instance, ids) etisserant@0: self.Refresh() etisserant@0: etisserant@0: # Load instance from given informations etisserant@0: def loadInstance(self, instance, ids): etisserant@0: ids.append(instance["id"]) etisserant@0: self.current_id = max(self.current_id, instance["id"]) etisserant@0: if instance["type"] == "input": etisserant@0: variable = FBD_Variable(self, INPUT, instance["name"], instance["value_type"], instance["id"]) etisserant@0: variable.SetPosition(instance["x"], instance["y"]) etisserant@0: variable.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(variable) etisserant@0: self.Elements.append(variable) etisserant@0: connectors = variable.GetConnectors() etisserant@0: connectors["output"].SetPosition(wxPoint(*instance["connector"]["position"])) etisserant@0: if instance["connector"]["negated"]: etisserant@0: connectors["output"].SetNegated(True) etisserant@0: if instance["connector"]["edge"]: etisserant@0: connectors["output"].SetEdge(instance["connector"]["edge"]) etisserant@0: elif instance["type"] == "output": etisserant@0: variable = FBD_Variable(self, OUTPUT, instance["name"], instance["value_type"], instance["id"]) etisserant@0: variable.SetPosition(instance["x"], instance["y"]) etisserant@0: variable.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(variable) etisserant@0: self.Elements.append(variable) etisserant@0: connectors = variable.GetConnectors() etisserant@0: connectors["input"].SetPosition(wxPoint(*instance["connector"]["position"])) etisserant@0: if instance["connector"]["negated"]: etisserant@0: connectors["input"].SetNegated(True) etisserant@0: if instance["connector"]["edge"]: etisserant@0: connectors["input"].SetEdge(instance["connector"]["edge"]) etisserant@0: self.CreateWires(connectors["input"], instance["connector"]["links"], ids) etisserant@0: elif instance["type"] == "inout": etisserant@0: variable = FBD_Variable(self, INOUT, instance["name"], instance["value_type"], instance["id"]) etisserant@0: variable.SetPosition(instance["x"], instance["y"]) etisserant@0: variable.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(variable) etisserant@0: self.Elements.append(variable) etisserant@0: connectors = variable.GetConnectors() etisserant@0: connectors["output"].SetPosition(wxPoint(*instance["connectors"]["output"]["position"])) etisserant@0: connectors["input"].SetPosition(wxPoint(*instance["connectors"]["input"]["position"])) etisserant@0: if instance["connectors"]["output"]["negated"]: etisserant@0: connectors["output"].SetNegated(True) etisserant@0: if instance["connectors"]["output"]["edge"]: etisserant@0: connectors["output"].SetEdge(instance["connectors"]["output"]["edge"]) etisserant@0: if instance["connectors"]["input"]["negated"]: etisserant@0: connectors["input"].SetNegated(True) etisserant@0: if instance["connectors"]["input"]["edge"]: etisserant@0: connectors["input"].SetEdge(instance["connectors"]["input"]["edge"]) etisserant@0: self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids) etisserant@0: elif instance["type"] == "continuation": etisserant@0: connection = FBD_Connector(self, CONTINUATION, instance["name"], instance["id"]) etisserant@0: connection.SetPosition(instance["x"], instance["y"]) etisserant@0: connection.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(connection) etisserant@0: self.Elements.append(connection) etisserant@0: connector = connection.GetConnector() etisserant@0: connector.SetPosition(wxPoint(*instance["connector"]["position"])) etisserant@0: elif instance["type"] == "connection": etisserant@0: connection = FBD_Connection(self, CONNECTOR, instance["name"], instance["id"]) etisserant@0: connection.SetPosition(instance["x"], instance["y"]) etisserant@0: connection.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(connection) etisserant@0: self.Elements.append(connection) etisserant@0: connector = connection.GetConnector() etisserant@0: connector.SetPosition(wxPoint(*instance["connector"]["position"])) etisserant@0: self.CreateWires(connector, instance["connector"]["links"], ids) etisserant@0: elif instance["type"] == "comment": etisserant@0: comment = Comment(self, instance["content"], instance["id"]) etisserant@0: comment.SetPosition(instance["x"], instance["y"]) etisserant@0: comment.SetSize(instance["width"], instance["height"]) etisserant@0: self.Elements.append(comment) etisserant@0: elif instance["type"] == "leftPowerRail": etisserant@0: leftpowerrail = LD_PowerRail(self, LEFTRAIL, instance["id"], [True for i in range(len(instance["connectors"]))]) etisserant@0: leftpowerrail.SetPosition(instance["x"], instance["y"]) etisserant@0: self.Blocks.append(leftpowerrail) etisserant@0: self.Elements.append(leftpowerrail) etisserant@0: connectors = leftpowerrail.GetConnectors() etisserant@0: for i, connector in enumerate(instance["connectors"]): etisserant@0: connectors[i].SetPosition(wxPoint(*connector["position"])) etisserant@0: elif instance["type"] == "rightPowerRail": etisserant@0: rightpowerrail = LD_PowerRail(self, RIGHTRAIL, instance["id"], [True for i in range(len(instance["connectors"]))]) etisserant@0: rightpowerrail.SetPosition(instance["x"], instance["y"]) etisserant@0: self.Blocks.append(rightpowerrail) etisserant@0: self.Elements.append(rightpowerrail) etisserant@0: connectors = rightpowerrail.GetConnectors() etisserant@0: for i, connector in enumerate(instance["connectors"]): etisserant@0: connectors[i].SetPosition(wxPoint(*connector["position"])) etisserant@0: self.CreateWires(connectors[i], connector["links"], ids) etisserant@0: elif instance["type"] == "contact": etisserant@0: if instance["negated"]: etisserant@0: negated = instance["negated"] etisserant@0: else: etisserant@0: negated = False etisserant@0: if instance["edge"]: etisserant@0: edge = instance["edge"] etisserant@0: else: etisserant@0: edge = "none" etisserant@0: if negated and edge == "none": etisserant@0: contact_type = CONTACT_REVERSE etisserant@0: elif not negated and edge == "rising": etisserant@0: contact_type = CONTACT_RISING etisserant@0: elif not negated and edge == "falling": etisserant@0: contact_type = CONTACT_FALLING etisserant@0: else: etisserant@0: contact_type = CONTACT_NORMAL etisserant@0: contact = LD_Contact(self, contact_type, instance["name"], instance["id"]) etisserant@0: contact.SetPosition(instance["x"], instance["y"]) etisserant@0: self.Blocks.append(contact) etisserant@0: self.Elements.append(contact) etisserant@0: connectors = contact.GetConnectors() etisserant@0: connectors["input"].SetPosition(wxPoint(*instance["connectors"]["input"]["position"])) etisserant@0: self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids) etisserant@0: connectors["output"].SetPosition(wxPoint(*instance["connectors"]["output"]["position"])) etisserant@0: elif instance["type"] == "coil": etisserant@0: if instance["negated"]: etisserant@0: negated = instance["negated"] etisserant@0: else: etisserant@0: negated = False etisserant@0: if instance["storage"]: etisserant@0: storage = instance["storage"] etisserant@0: else: etisserant@0: storage = "none" etisserant@0: if negated and storage == "none": etisserant@0: coil_type = COIL_REVERSE etisserant@0: elif not negated and storage == "set": etisserant@0: coil_type = COIL_SET etisserant@0: elif not negated and storage == "reset": etisserant@0: coil_type = COIL_RESET etisserant@0: else: etisserant@0: coil_type = COIL_NORMAL etisserant@0: coil = LD_Coil(self, coil_type, instance["name"], instance["id"]) etisserant@0: coil.SetPosition(instance["x"], instance["y"]) etisserant@0: self.Blocks.append(coil) etisserant@0: self.Elements.append(coil) etisserant@0: connectors = coil.GetConnectors() etisserant@0: connectors["input"].SetPosition(wxPoint(*instance["connectors"]["input"]["position"])) etisserant@0: self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids) etisserant@0: connectors["output"].SetPosition(wxPoint(*instance["connectors"]["output"]["position"])) etisserant@0: elif instance["type"] == "step": etisserant@0: if instance["initial"]: etisserant@0: initial = instance["initial"] etisserant@0: else: etisserant@0: initial = False etisserant@0: step = SFC_Step(self, instance["name"], initial, instance["id"]) etisserant@0: step.SetPosition(instance["x"], instance["y"]) etisserant@0: step.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(step) etisserant@0: self.Elements.append(step) etisserant@0: if "output" in instance["connectors"]: etisserant@0: step.AddOutput() etisserant@0: if "action" in instance["connectors"]: etisserant@0: step.AddAction() etisserant@0: connectors = step.GetConnectors() etisserant@0: if connectors["input"]: etisserant@0: connectors["input"].SetPosition(wxPoint(*instance["connectors"]["input"]["position"])) etisserant@0: self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids) etisserant@0: if connectors["output"]: etisserant@0: connectors["output"].SetPosition(wxPoint(*instance["connectors"]["output"]["position"])) etisserant@0: if connectors["action"]: etisserant@0: connectors["action"].SetPosition(wxPoint(*instance["connectors"]["action"]["position"])) etisserant@0: elif instance["type"] == "transition": etisserant@0: transition = SFC_Transition(self, instance["condition_type"], instance["condition"], instance["id"]) etisserant@0: transition.SetPosition(instance["x"], instance["y"]) etisserant@0: self.Blocks.append(transition) etisserant@0: self.Elements.append(transition) etisserant@0: connectors = transition.GetConnectors() etisserant@0: connectors["input"].SetPosition(wxPoint(*instance["connectors"]["input"]["position"])) etisserant@0: self.CreateWires(connectors["input"], instance["connectors"]["input"]["links"], ids) etisserant@0: connectors["output"].SetPosition(wxPoint(*instance["connectors"]["output"]["position"])) etisserant@0: elif instance["type"] in ["selectionDivergence", "selectionConvergence", "simultaneousDivergence", "simultaneousConvergence"]: etisserant@0: if instance["type"] == "selectionDivergence": etisserant@0: divergence = SFC_Divergence(self, SELECTION_DIVERGENCE, etisserant@0: len(instance["connectors"]["outputs"]), instance["id"]) etisserant@0: elif instance["type"] == "selectionConvergence": etisserant@0: divergence = SFC_Divergence(self, SELECTION_CONVERGENCE, etisserant@0: len(instance["connectors"]["inputs"]), instance["id"]) etisserant@0: elif instance["type"] == "simultaneousDivergence": etisserant@0: divergence = SFC_Divergence(self, SIMULTANEOUS_DIVERGENCE, etisserant@0: len(instance["connectors"]["outputs"]), instance["id"]) etisserant@0: else: etisserant@0: divergence = SFC_Divergence(self, SIMULTANEOUS_CONVERGENCE, etisserant@0: len(instance["connectors"]["inputs"]), instance["id"]) etisserant@0: divergence.SetPosition(instance["x"], instance["y"]) etisserant@0: divergence.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(divergence) etisserant@0: self.Elements.append(divergence) etisserant@0: connectors = divergence.GetConnectors() etisserant@0: for i, input_connector in enumerate(instance["connectors"]["inputs"]): etisserant@0: connector = connectors["inputs"][i] etisserant@0: connector.SetPosition(wxPoint(*input_connector["position"])) etisserant@0: self.CreateWires(connector, input_connector["links"], ids) etisserant@0: for i, output_connector in enumerate(instance["connectors"]["outputs"]): etisserant@0: connector = connectors["outputs"][i] etisserant@0: connector.SetPosition(wxPoint(*output_connector["position"])) etisserant@0: elif instance["type"] == "jump": etisserant@0: jump = SFC_Jump(self, instance["target"], instance["id"]) etisserant@0: jump.SetPosition(instance["x"], instance["y"]) etisserant@0: self.Blocks.append(jump) etisserant@0: self.Elements.append(jump) etisserant@0: connector = jump.GetConnector() etisserant@0: connector.SetPosition(wxPoint(*instance["connector"]["position"])) etisserant@0: self.CreateWires(connector, instance["connector"]["links"], ids) etisserant@0: elif instance["type"] == "actionBlock": etisserant@0: actionBlock = SFC_ActionBlock(self, instance["actions"], instance["id"]) etisserant@0: actionBlock.SetPosition(instance["x"], instance["y"]) etisserant@0: actionBlock.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(actionBlock) etisserant@0: self.Elements.append(actionBlock) etisserant@0: connector = actionBlock.GetConnector() etisserant@0: connector.SetPosition(wxPoint(*instance["connector"]["position"])) etisserant@0: self.CreateWires(connector, instance["connector"]["links"], ids) etisserant@0: else: etisserant@0: if instance["name"] != None: etisserant@0: block = FBD_Block(self, instance["type"], instance["name"], instance["id"], len(instance["connectors"]["inputs"])) etisserant@0: else: etisserant@0: block = FBD_Block(self, instance["type"], "", instance["id"], len(instance["connectors"]["inputs"])) etisserant@0: block.SetPosition(instance["x"], instance["y"]) etisserant@0: block.SetSize(instance["width"], instance["height"]) etisserant@0: self.Blocks.append(block) etisserant@0: self.Elements.append(block) etisserant@0: connectors = block.GetConnectors() etisserant@0: for i, input_connector in enumerate(instance["connectors"]["inputs"]): etisserant@0: connector = connectors["inputs"][i] etisserant@0: connector.SetPosition(wxPoint(*input_connector["position"])) etisserant@0: if input_connector["negated"]: etisserant@0: connector.SetNegated(True) etisserant@0: if input_connector["edge"]: etisserant@0: connector.SetEdge(input_connector["edge"]) etisserant@0: self.CreateWires(connector, input_connector["links"], ids) etisserant@0: for i, output_connector in enumerate(instance["connectors"]["outputs"]): etisserant@0: connector = connectors["outputs"][i] etisserant@0: if output_connector["negated"]: etisserant@0: connector.SetNegated(True) etisserant@0: if output_connector["edge"]: etisserant@0: connector.SetEdge(output_connector["edge"]) etisserant@0: connector.SetPosition(wxPoint(*output_connector["position"])) etisserant@0: etisserant@0: def CreateWires(self, start_connector, links, ids): etisserant@0: for link in links: etisserant@0: refLocalId = link["refLocalId"] etisserant@0: if refLocalId != None: etisserant@0: if refLocalId not in ids: etisserant@0: new_instance = self.Controler.GetCurrentElementEditingInstanceInfos(refLocalId) etisserant@0: if new_instance: etisserant@0: self.loadInstance(new_instance, ids) etisserant@0: connected = self.FindElementById(refLocalId) etisserant@0: if connected: etisserant@0: points = link["points"] etisserant@0: end_connector = connected.GetConnector(wxPoint(points[-1][0], points[-1][1])) etisserant@0: if end_connector: etisserant@0: wire = Wire(self) etisserant@0: wire.SetPoints(points) etisserant@0: start_connector.Connect((wire, 0), False) etisserant@0: end_connector.Connect((wire, -1), False) etisserant@0: wire.ConnectStartPoint(None, start_connector) etisserant@0: wire.ConnectEndPoint(None, end_connector) etisserant@0: self.Wires.append(wire) etisserant@0: self.Elements.append(wire) etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Search Element functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def FindBlock(self, pos): etisserant@0: for block in self.Blocks: etisserant@0: if block.HitTest(pos) or block.TestHandle(pos) != (0, 0): etisserant@0: return block etisserant@0: return None etisserant@0: etisserant@0: def FindWire(self, pos): etisserant@0: for wire in self.Wires: etisserant@0: if wire.HitTest(pos) or wire.TestHandle(pos) != (0, 0): etisserant@0: return wire etisserant@0: return None etisserant@0: etisserant@0: def FindElement(self, pos, exclude_group = False): etisserant@0: if self.SelectedElement and not (exclude_group and isinstance(self.SelectedElement, Graphic_Group)): etisserant@0: if self.SelectedElement.HitTest(pos) or self.SelectedElement.TestHandle(pos) != (0, 0): etisserant@0: return self.SelectedElement etisserant@0: for element in self.Elements: etisserant@0: if element.HitTest(pos) or element.TestHandle(pos) != (0, 0): etisserant@0: return element etisserant@0: return None etisserant@0: etisserant@0: def FindBlockConnector(self, pos): etisserant@0: for block in self.Blocks: etisserant@0: result = block.TestConnector(pos) etisserant@0: if result: etisserant@0: return result etisserant@0: return None etisserant@0: etisserant@0: def FindElementById(self, id): etisserant@0: for element in self.Elements: etisserant@0: if element.GetId() == id: etisserant@0: return element etisserant@0: return None etisserant@0: etisserant@0: def SearchElements(self, bbox): etisserant@0: elements = [] etisserant@0: for element in self.Elements: etisserant@0: element_bbox = element.GetBoundingBox() etisserant@0: if element_bbox.x >= bbox.x and element_bbox.y >= bbox.y and element_bbox.x + element_bbox.width <= bbox.x + bbox.width and element_bbox.y + element_bbox.height <= bbox.y + bbox.height: etisserant@0: elements.append(element) etisserant@0: return elements etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Popup menu functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def PopupBlockMenu(self, connector = None): etisserant@0: self.ContextualMenu.FindItemByPosition(0).Enable(connector != None) etisserant@0: self.ContextualMenu.FindItemByPosition(1).Enable(connector != None) etisserant@0: self.ContextualMenu.FindItemByPosition(2).Enable(connector != None) etisserant@0: self.ContextualMenu.FindItemByPosition(3).Enable(connector != None) etisserant@0: self.ContextualMenu.FindItemByPosition(5).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(6).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(8).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(9).Enable(False) etisserant@0: if connector: etisserant@0: if connector.IsNegated(): etisserant@0: self.ContextualMenu.FindItemByPosition(1).Check(True) etisserant@0: elif connector.GetEdge() == "rising": etisserant@0: self.ContextualMenu.FindItemByPosition(2).Check(True) etisserant@0: elif connector.GetEdge() == "falling": etisserant@0: self.ContextualMenu.FindItemByPosition(3).Check(True) etisserant@0: else: etisserant@0: self.ContextualMenu.FindItemByPosition(0).Check(True) etisserant@0: self.PopupMenu(self.ContextualMenu) etisserant@0: etisserant@0: def PopupVariableMenu(self, connector = None): etisserant@0: self.ContextualMenu.FindItemByPosition(0).Enable(connector != None) etisserant@0: self.ContextualMenu.FindItemByPosition(1).Enable(connector != None) etisserant@0: self.ContextualMenu.FindItemByPosition(2).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(3).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(5).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(6).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(8).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(9).Enable(False) etisserant@0: if connector: etisserant@0: if connector.IsNegated(): etisserant@0: self.ContextualMenu.FindItemByPosition(1).Check(True) etisserant@0: else: etisserant@0: self.ContextualMenu.FindItemByPosition(0).Check(True) etisserant@0: self.PopupMenu(self.ContextualMenu) etisserant@0: etisserant@0: def PopupWireMenu(self): etisserant@0: self.ContextualMenu.FindItemByPosition(0).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(1).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(2).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(3).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(5).Enable(True) etisserant@0: self.ContextualMenu.FindItemByPosition(6).Enable(True) etisserant@0: self.ContextualMenu.FindItemByPosition(8).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(9).Enable(False) etisserant@0: self.PopupMenu(self.ContextualMenu) etisserant@0: etisserant@0: def PopupDivergenceMenu(self, connector): etisserant@0: self.ContextualMenu.FindItemByPosition(0).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(1).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(2).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(3).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(5).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(6).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(8).Enable(True) etisserant@0: self.ContextualMenu.FindItemByPosition(9).Enable(connector) etisserant@0: self.PopupMenu(self.ContextualMenu) etisserant@0: etisserant@0: def PopupDefaultMenu(self): etisserant@0: self.ContextualMenu.FindItemByPosition(0).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(1).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(2).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(3).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(5).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(6).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(8).Enable(False) etisserant@0: self.ContextualMenu.FindItemByPosition(9).Enable(False) etisserant@0: self.PopupMenu(self.ContextualMenu) etisserant@0: etisserant@0: def EditCommentContent(self, comment): etisserant@0: dialog = wxTextEntryDialog(self.Parent, "Edit comment", "Please enter comment text", comment.GetContent(), wxOK|wxCANCEL|wxTE_MULTILINE) etisserant@0: if dialog.ShowModal() == wxID_OK: etisserant@0: value = dialog.GetValue() etisserant@0: comment.SetContent(value) etisserant@0: infos = {"content" : value} etisserant@0: infos["width"], infos["height"] = comment.GetSize() etisserant@0: self.Controler.SetCurrentElementEditingCommentInfos(comment.GetId(), infos) etisserant@0: self.Refresh() etisserant@0: dialog.Destroy() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Menu items functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def OnNoModifierMenu(self, event): etisserant@0: if self.SelectedElement and self.SelectedElement in self.Blocks: etisserant@0: self.SelectedElement.SetConnectorNegated(False) etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnNegatedMenu(self, event): etisserant@0: if self.SelectedElement and self.SelectedElement in self.Blocks: etisserant@0: self.SelectedElement.SetConnectorNegated(True) etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnRisingEdgeMenu(self, event): etisserant@0: if self.SelectedElement and self.SelectedElement in self.Blocks: etisserant@0: self.SelectedElement.SetConnectorEdge("rising") etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnFallingEdgeMenu(self, event): etisserant@0: if self.SelectedElement and self.SelectedElement in self.Blocks: etisserant@0: self.SelectedElement.SetConnectorEdge("falling") etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnAddSegmentMenu(self, event): etisserant@0: if self.SelectedElement and self.SelectedElement in self.Wires: etisserant@0: self.SelectedElement.AddSegment() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDeleteSegmentMenu(self, event): etisserant@0: if self.SelectedElement and self.SelectedElement in self.Wires: etisserant@0: self.SelectedElement.DeleteSegment() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnAddBranchMenu(self, event): etisserant@0: if self.SelectedElement and self.SelectedElement in self.Blocks: etisserant@0: self.AddDivergenceBranch(self.SelectedElement) etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDeleteBranchMenu(self, event): etisserant@0: if self.SelectedElement and self.SelectedElement in self.Blocks: etisserant@0: self.RemoveDivergenceBranch(self.SelectedElement) etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDeleteMenu(self, event): etisserant@0: if self.SelectedElement: etisserant@0: self.SelectedElement.Delete() etisserant@0: self.SelectedElement = None etisserant@0: event.Skip() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Mouse event functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def OnViewerLeftDown(self, event): etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnViewerLeftUp(self, event): etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnViewerRightUp(self, event): etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnViewerLeftDClick(self, event): etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnViewerMotion(self, event): etisserant@0: event.Skip() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Keyboard event functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def OnChar(self, event): etisserant@0: event.Skip() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Model update functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def RefreshBlockModel(self, block): etisserant@0: blockid = block.GetId() etisserant@0: infos = {} etisserant@0: infos["type"] = block.GetType() etisserant@0: infos["name"] = block.GetName() etisserant@0: infos["x"], infos["y"] = block.GetPosition() etisserant@0: infos["width"], infos["height"] = block.GetSize() etisserant@0: infos["connectors"] = block.GetConnectors() etisserant@0: self.Controler.SetCurrentElementEditingBlockInfos(blockid, infos) etisserant@0: etisserant@0: def RefreshVariableModel(self, variable): etisserant@0: variableid = variable.GetId() etisserant@0: infos = {} etisserant@0: infos["name"] = variable.GetName() etisserant@0: infos["x"], infos["y"] = variable.GetPosition() etisserant@0: infos["width"], infos["height"] = variable.GetSize() etisserant@0: infos["connectors"] = variable.GetConnectors() etisserant@0: self.Controler.SetCurrentElementEditingVariableInfos(variableid, infos) etisserant@0: etisserant@0: def RefreshConnectionModel(self, connection): etisserant@0: connectionid = connection.GetId() etisserant@0: infos = {} etisserant@0: infos["name"] = connection.GetName() etisserant@0: infos["x"], infos["y"] = connection.GetPosition() etisserant@0: infos["width"], infos["height"] = connection.GetSize() etisserant@0: infos["connector"] = connection.GetConnector() etisserant@0: self.Controler.SetCurrentElementEditingConnectionInfos(connectionid, infos) etisserant@0: etisserant@0: def RefreshCommentModel(self, comment): etisserant@0: commentid = comment.GetId() etisserant@0: infos = {} etisserant@0: infos["content"] = comment.GetContent() etisserant@0: infos["x"], infos["y"] = comment.GetPosition() etisserant@0: infos["width"], infos["height"] = comment.GetSize() etisserant@0: self.Controler.SetCurrentElementEditingCommentInfos(commentid, infos) etisserant@0: etisserant@0: def RefreshPowerRailModel(self, powerrail): etisserant@0: powerrailid = powerrail.GetId() etisserant@0: infos = {} etisserant@0: infos["x"], infos["y"] = powerrail.GetPosition() etisserant@0: infos["width"], infos["height"] = powerrail.GetSize() etisserant@0: infos["connectors"] = powerrail.GetConnectors() etisserant@0: self.Controler.SetCurrentElementEditingPowerRailInfos(powerrailid, infos) etisserant@0: etisserant@0: def RefreshContactModel(self, contact): etisserant@0: contactid = contact.GetId() etisserant@0: infos = {} etisserant@0: infos["name"] = contact.GetName() etisserant@0: infos["type"] = contact.GetType() etisserant@0: infos["x"], infos["y"] = contact.GetPosition() etisserant@0: infos["width"], infos["height"] = contact.GetSize() etisserant@0: infos["connectors"] = contact.GetConnectors() etisserant@0: self.Controler.SetCurrentElementEditingContactInfos(contactid, infos) etisserant@0: etisserant@0: def RefreshCoilModel(self, coil): etisserant@0: coilid = coil.GetId() etisserant@0: infos = {} etisserant@0: infos["name"] = coil.GetName() etisserant@0: infos["type"] = coil.GetType() etisserant@0: infos["x"], infos["y"] = coil.GetPosition() etisserant@0: infos["width"], infos["height"] = coil.GetSize() etisserant@0: infos["connectors"] = coil.GetConnectors() etisserant@0: self.Controler.SetCurrentElementEditingCoilInfos(coilid, infos) etisserant@0: etisserant@0: def RefreshStepModel(self, step): etisserant@0: stepid = step.GetId() etisserant@0: infos = {} etisserant@0: infos["name"] = step.GetName() etisserant@0: infos["initial"] = step.GetInitial() etisserant@0: infos["x"], infos["y"] = step.GetPosition() etisserant@0: infos["width"], infos["height"] = step.GetSize() etisserant@0: infos["connectors"] = step.GetConnectors() etisserant@0: self.Controler.SetCurrentElementEditingStepInfos(stepid, infos) etisserant@0: etisserant@0: def RefreshTransitionModel(self, transition): etisserant@0: transitionid = transition.GetId() etisserant@0: infos = {} etisserant@0: infos["type"] = transition.GetType() etisserant@0: infos["condition"] = transition.GetCondition() etisserant@0: infos["x"], infos["y"] = transition.GetPosition() etisserant@0: infos["width"], infos["height"] = transition.GetSize() etisserant@0: infos["connectors"] = transition.GetConnectors() etisserant@0: self.Controler.SetCurrentElementEditingTransitionInfos(transitionid, infos) etisserant@0: etisserant@0: def RefreshDivergenceModel(self, divergence): etisserant@0: divergenceid = divergence.GetId() etisserant@0: infos = {} etisserant@0: infos["x"], infos["y"] = divergence.GetPosition() etisserant@0: infos["width"], infos["height"] = divergence.GetSize() etisserant@0: infos["connectors"] = divergence.GetConnectors() etisserant@0: self.Controler.SetCurrentElementEditingDivergenceInfos(divergenceid, infos) etisserant@0: etisserant@0: def RefreshJumpModel(self, jump): etisserant@0: jumpid = jump.GetId() etisserant@0: infos = {} etisserant@0: infos["target"] = jump.GetTarget() etisserant@0: infos["x"], infos["y"] = jump.GetPosition() etisserant@0: infos["width"], infos["height"] = jump.GetSize() etisserant@0: infos["connector"] = jump.GetConnector() etisserant@0: self.Controler.SetCurrentElementEditingJumpInfos(jumpid, infos) etisserant@0: etisserant@0: def RefreshActionBlockModel(self, actionblock): etisserant@0: actionblockid = actionblock.GetId() etisserant@0: infos = {} etisserant@0: infos["actions"] = actionblock.GetActions() etisserant@0: infos["x"], infos["y"] = actionblock.GetPosition() etisserant@0: infos["width"], infos["height"] = actionblock.GetSize() etisserant@0: infos["connector"] = actionblock.GetConnector() etisserant@0: self.Controler.SetCurrentElementEditingActionBlockInfos(actionblockid, infos) etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Editing functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def Cut(self): etisserant@0: pass etisserant@0: etisserant@0: def Copy(self): etisserant@0: pass etisserant@0: etisserant@0: def Paste(self): etisserant@0: pass etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Drawing functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def OnPaint(self, event): etisserant@0: dc = wxClientDC(self) etisserant@0: dc.Clear() etisserant@0: dc.SetPen(wxPen(wxColour(230, 230, 230))) etisserant@0: if self.Scaling and self.DrawGrid: etisserant@0: width, height = dc.GetSize() etisserant@0: for i in xrange(1, width / self.Scaling[0] + 1): etisserant@0: dc.DrawLine(i * self.Scaling[0], 0, i * self.Scaling[0], height) etisserant@0: for i in xrange(1, height / self.Scaling[1] + 1): etisserant@0: dc.DrawLine(0, i * self.Scaling[1], width, i * self.Scaling[1]) etisserant@0: for wire in self.Wires: etisserant@0: if wire != self.SelectedElement: etisserant@0: wire.Draw(dc) etisserant@0: for element in self.Elements: etisserant@0: if element not in self.Wires and element != self.SelectedElement: etisserant@0: element.Draw(dc) etisserant@0: if self.SelectedElement: etisserant@0: self.SelectedElement.Draw(dc) etisserant@0: event.Skip() etisserant@0: etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Textual programs Viewer class etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: etisserant@0: NEWLINE = "\n" etisserant@0: NUMBERS = [str(i) for i in xrange(10)] etisserant@0: LETTERS = ['_'] etisserant@0: for i in xrange(26): etisserant@0: LETTERS.append(chr(ord('a') + i)) etisserant@0: LETTERS.append(chr(ord('A') + i)) etisserant@0: etisserant@0: [wxSTC_PLC_WORD, wxSTC_PLC_COMMENT, wxSTC_PLC_NUMBER, wxSTC_PLC_VARIABLE, etisserant@0: wxSTC_PLC_FUNCTION, wxSTC_PLC_JUMP] = range(6) etisserant@0: [SPACE, WORD, NUMBER, COMMENT] = range(4) etisserant@0: etisserant@0: [wxID_TEXTVIEWER, etisserant@0: ] = [wx.NewId() for _init_ctrls in range(1)] etisserant@0: etisserant@0: if wx.Platform == '__WXMSW__': etisserant@0: faces = { 'times': 'Times New Roman', etisserant@0: 'mono' : 'Courier New', etisserant@0: 'helv' : 'Arial', etisserant@0: 'other': 'Comic Sans MS', etisserant@0: 'size' : 10, etisserant@0: } etisserant@0: else: etisserant@0: faces = { 'times': 'Times', etisserant@0: 'mono' : 'Courier', etisserant@0: 'helv' : 'Helvetica', etisserant@0: 'other': 'new century schoolbook', etisserant@0: 'size' : 12, etisserant@0: } etisserant@0: re_texts = {} etisserant@0: re_texts["letter"] = "[A-Za-z]" etisserant@0: re_texts["digit"] = "[0-9]" etisserant@0: re_texts["identifier"] = "((?:%(letter)s|(?:_(?:%(letter)s|%(digit)s)))(?:_?(?:%(letter)s|%(digit)s))*)"%re_texts etisserant@0: IDENTIFIER_MODEL = re.compile(re_texts["identifier"]) etisserant@0: LABEL_MODEL = re.compile("[ \t\n]%(identifier)s:[ \t\n]"%re_texts) etisserant@0: etisserant@0: class TextViewer(wxStyledTextCtrl): etisserant@0: etisserant@0: def __init__(self, parent, window, controler): etisserant@0: wxStyledTextCtrl.__init__(self, parent, wxID_TEXTVIEWER, style=0) etisserant@0: etisserant@0: self.CmdKeyAssign(ord('+'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMIN) etisserant@0: self.CmdKeyAssign(ord('-'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMOUT) etisserant@0: etisserant@0: self.SetViewWhiteSpace(False) etisserant@0: etisserant@0: self.SetLexer(wxSTC_LEX_CONTAINER) etisserant@0: etisserant@0: # Global default styles for all languages etisserant@0: self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) etisserant@0: self.StyleClearAll() # Reset all to be like the default etisserant@0: etisserant@0: self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,size:%(size)d" % faces) etisserant@0: self.SetSelBackground(1, "#E0E0E0") etisserant@0: etisserant@0: # Highlighting styles etisserant@0: self.StyleSetSpec(wxSTC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces) etisserant@0: self.StyleSetSpec(wxSTC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces) etisserant@0: self.StyleSetSpec(wxSTC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces) etisserant@0: self.StyleSetSpec(wxSTC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces) etisserant@0: self.StyleSetSpec(wxSTC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces) etisserant@0: self.StyleSetSpec(wxSTC_PLC_JUMP, "fore:#007F00,size:%(size)d" % faces) etisserant@0: etisserant@0: # Indicators styles etisserant@0: self.IndicatorSetStyle(0, wxSTC_INDIC_SQUIGGLE) etisserant@0: self.IndicatorSetForeground(0, wxRED) etisserant@0: etisserant@0: # Line numbers in the margin etisserant@0: self.SetMarginType(1, wxSTC_MARGIN_NUMBER) etisserant@0: self.SetMarginWidth(1, 50) etisserant@0: etisserant@0: # Indentation size etisserant@0: self.SetTabWidth(2) etisserant@0: etisserant@0: self.Keywords = [] etisserant@0: self.Variables = [] etisserant@0: self.Functions = [] etisserant@0: self.Jumps = [] etisserant@0: self.TextChanged = False etisserant@0: etisserant@0: self.Controler = controler etisserant@0: etisserant@0: EVT_KEY_DOWN(self, self.OnKeyDown) etisserant@0: EVT_STC_STYLENEEDED(self, wxID_TEXTVIEWER, self.OnStyleNeeded) etisserant@0: etisserant@0: def SetKeywords(self, keywords): etisserant@0: self.Keywords = [keyword.upper() for keyword in keywords] etisserant@0: self.Colourise(0, -1) etisserant@0: etisserant@0: def SetVariables(self, variables): etisserant@0: self.Variables = [variable.upper() for variable in variables] etisserant@0: self.Colourise(0, -1) etisserant@0: etisserant@0: def SetFunctions(self, blocktypes): etisserant@0: self.Functions = [] etisserant@0: for category in blocktypes: etisserant@0: for blocktype in category["list"]: etisserant@0: if blocktype["name"] not in self.Keywords and blocktype["name"] not in self.Variables: etisserant@0: self.Functions.append(blocktype["name"].upper()) etisserant@0: self.Colourise(0, -1) etisserant@0: etisserant@0: def RefreshJumpList(self): etisserant@0: self.Jumps = [jump.upper() for jump in LABEL_MODEL.findall(self.GetText())] etisserant@0: self.Colourise(0, -1) etisserant@0: etisserant@0: def RefreshView(self): etisserant@0: self.SetText(self.Controler.GetCurrentElementEditingText()) etisserant@0: self.RefreshJumpList() etisserant@0: etisserant@0: def OnStyleNeeded(self, event): etisserant@0: self.TextChanged = True etisserant@0: line = self.LineFromPosition(self.GetEndStyled()) etisserant@0: if line == 0: etisserant@0: start_pos = 0 etisserant@0: else: etisserant@0: start_pos = self.GetLineEndPosition(line - 1) + 1 etisserant@0: end_pos = event.GetPosition() etisserant@0: self.StartStyling(start_pos, 0xff) etisserant@0: etisserant@0: i = start_pos etisserant@0: state = SPACE etisserant@0: line = "" etisserant@0: word = "" etisserant@0: while i < end_pos: etisserant@0: char = chr(self.GetCharAt(i)).upper() etisserant@0: line += char etisserant@0: if char == NEWLINE: etisserant@0: if state == COMMENT: etisserant@0: self.SetStyling(i - start_pos + 1, wxSTC_PLC_COMMENT) etisserant@0: elif state == NUMBER: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER) etisserant@0: elif state == WORD: etisserant@0: if word in self.Keywords: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_WORD) etisserant@0: elif word in self.Variables: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE) etisserant@0: elif word in self.Functions: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION) etisserant@0: elif word in self.Jumps: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_JUMP) etisserant@0: else: etisserant@0: self.SetStyling(i - start_pos, 31) etisserant@0: if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i: etisserant@0: self.StartStyling(start_pos, wxSTC_INDICS_MASK) etisserant@0: self.SetStyling(i - start_pos, wxSTC_INDIC0_MASK) etisserant@0: self.StartStyling(i, 0xff) etisserant@0: else: etisserant@0: self.SetStyling(i - start_pos, 31) etisserant@0: start_pos = i etisserant@0: state = SPACE etisserant@0: line = "" etisserant@0: elif line.endswith("(*") and state != COMMENT: etisserant@0: self.SetStyling(i - start_pos - 1, 31) etisserant@0: start_pos = i etisserant@0: state = COMMENT etisserant@0: elif state == COMMENT: etisserant@0: if line.endswith("*)"): etisserant@0: self.SetStyling(i - start_pos + 2, wxSTC_PLC_COMMENT) etisserant@0: start_pos = i + 1 etisserant@0: state = SPACE etisserant@0: elif char in LETTERS: etisserant@0: if state == NUMBER: etisserant@0: word = "#" etisserant@0: state = WORD etisserant@0: elif state == SPACE: etisserant@0: self.SetStyling(i - start_pos, 31) etisserant@0: word = char etisserant@0: start_pos = i etisserant@0: state = WORD etisserant@0: else: etisserant@0: word += char etisserant@0: elif char in NUMBERS or char == '.' and state != WORD: etisserant@0: if state == SPACE: etisserant@0: self.SetStyling(i - start_pos, 31) etisserant@0: start_pos = i etisserant@0: state = NUMBER etisserant@0: if state == WORD and char != '.': etisserant@0: word += char etisserant@0: else: etisserant@0: if state == WORD: etisserant@0: if word in self.Keywords: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_WORD) etisserant@0: elif word in self.Variables: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE) etisserant@0: elif word in self.Functions: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION) etisserant@0: elif word in self.Jumps: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_JUMP) etisserant@0: else: etisserant@0: self.SetStyling(i - start_pos, 31) etisserant@0: if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i: etisserant@0: self.StartStyling(start_pos, wxSTC_INDICS_MASK) etisserant@0: self.SetStyling(i - start_pos, wxSTC_INDIC0_MASK) etisserant@0: self.StartStyling(i, 0xff) etisserant@0: word = "" etisserant@0: start_pos = i etisserant@0: state = SPACE etisserant@0: elif state == NUMBER: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER) etisserant@0: start_pos = i etisserant@0: state = SPACE etisserant@0: i += 1 etisserant@0: if state == COMMENT: etisserant@0: self.SetStyling(i - start_pos + 2, wxSTC_PLC_COMMENT) etisserant@0: elif state == NUMBER: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER) etisserant@0: elif state == WORD: etisserant@0: if word in self.Keywords: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_WORD) etisserant@0: elif word in self.Variables: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE) etisserant@0: elif word in self.Functions: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION) etisserant@0: elif word in self.Jumps: etisserant@0: self.SetStyling(i - start_pos, wxSTC_PLC_JUMP) etisserant@0: else: etisserant@0: self.SetStyling(i - start_pos, 31) etisserant@0: else: etisserant@0: self.SetStyling(i - start_pos, 31) etisserant@0: event.Skip() etisserant@0: etisserant@0: def Cut(self): etisserant@0: self.CmdKeyExecute(wxSTC_CMD_CUT) etisserant@0: etisserant@0: def Copy(self): etisserant@0: self.CmdKeyExecute(wxSTC_CMD_COPY) etisserant@0: etisserant@0: def Paste(self): etisserant@0: self.CmdKeyExecute(wxSTC_CMD_PASTE) etisserant@0: etisserant@0: def RefreshModel(self): etisserant@0: if self.TextChanged: etisserant@0: self.RefreshJumpList() etisserant@0: self.Controler.SetCurrentElementEditingText(self.GetText()) etisserant@0: etisserant@0: def OnKeyDown(self, event): etisserant@0: if self.CallTipActive(): etisserant@0: self.CallTipCancel() etisserant@0: key = event.KeyCode() etisserant@0: etisserant@0: if key == WXK_SPACE and event.ControlDown(): etisserant@0: pos = self.GetCurrentPos() etisserant@0: etisserant@0: # Tips etisserant@0: if event.ShiftDown(): etisserant@0: self.CallTipSetBackground("yellow") etisserant@0: self.CallTipShow(pos, 'Here will be some help.') etisserant@0: etisserant@0: # Code completion etisserant@0: else: etisserant@0: kw = [key for key in self.Keywords] etisserant@0: etisserant@0: kw.sort() # Python sorts are case sensitive etisserant@0: self.AutoCompSetIgnoreCase(False) # so this needs to match etisserant@0: etisserant@0: self.AutoCompShow(0, " ".join(kw)) etisserant@0: else: etisserant@0: self.TextChanged = False etisserant@0: wxCallAfter(self.RefreshModel) etisserant@0: event.Skip() etisserant@0: etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Resource Editor class etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: class ResourceTable(wxPyGridTableBase): etisserant@0: etisserant@0: """ etisserant@0: A custom wxGrid Table using user supplied data etisserant@0: """ etisserant@0: def __init__(self, parent, data, colnames): etisserant@0: # The base class must be initialized *first* etisserant@0: wxPyGridTableBase.__init__(self) etisserant@0: self.data = data etisserant@0: self.colnames = colnames etisserant@0: self.Parent = parent etisserant@0: etisserant@0: self.ColAlignements = [] etisserant@0: self.ColSizes = [] etisserant@0: # XXX etisserant@0: # we need to store the row length and collength to etisserant@0: # see if the table has changed size etisserant@0: self._rows = self.GetNumberRows() etisserant@0: self._cols = self.GetNumberCols() etisserant@0: etisserant@0: def GetColAlignements(self): etisserant@0: return self.ColAlignements etisserant@0: etisserant@0: def SetColAlignements(self, list): etisserant@0: self.ColAlignements = list etisserant@0: etisserant@0: def GetColSizes(self): etisserant@0: return self.ColSizes etisserant@0: etisserant@0: def SetColSizes(self, list): etisserant@0: self.ColSizes = list etisserant@0: etisserant@0: def GetNumberCols(self): etisserant@0: return len(self.colnames) etisserant@0: etisserant@0: def GetNumberRows(self): etisserant@0: return len(self.data) etisserant@0: etisserant@0: def GetColLabelValue(self, col): etisserant@0: if col < len(self.colnames): etisserant@0: return self.colnames[col] etisserant@0: etisserant@0: def GetRowLabelValues(self, row): etisserant@0: return row etisserant@0: etisserant@0: def GetValue(self, row, col): etisserant@0: if row < self.GetNumberRows(): etisserant@0: name = str(self.data[row].get(self.GetColLabelValue(col), "")) etisserant@0: return name etisserant@0: etisserant@0: def GetValueByName(self, row, colname): etisserant@0: return self.data[row].get(colname) etisserant@0: etisserant@0: def SetValue(self, row, col, value): etisserant@0: if col < len(self.colnames): etisserant@0: self.data[row][self.GetColLabelValue(col)] = value etisserant@0: etisserant@0: def SetValueByName(self, row, colname, value): etisserant@0: if colname in self.colnames: etisserant@0: self.data[row][colname] = value etisserant@0: etisserant@0: def ResetView(self, grid): etisserant@0: """ etisserant@0: (wxGrid) -> Reset the grid view. Call this to etisserant@0: update the grid if rows and columns have been added or deleted etisserant@0: """ etisserant@0: grid.BeginBatch() etisserant@0: for current, new, delmsg, addmsg in [ etisserant@0: (self._rows, self.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED), etisserant@0: (self._cols, self.GetNumberCols(), wxGRIDTABLE_NOTIFY_COLS_DELETED, wxGRIDTABLE_NOTIFY_COLS_APPENDED), etisserant@0: ]: etisserant@0: if new < current: etisserant@0: msg = wxGridTableMessage(self,delmsg,new,current-new) etisserant@0: grid.ProcessTableMessage(msg) etisserant@0: elif new > current: etisserant@0: msg = wxGridTableMessage(self,addmsg,new-current) etisserant@0: grid.ProcessTableMessage(msg) etisserant@0: self.UpdateValues(grid) etisserant@0: grid.EndBatch() etisserant@0: etisserant@0: self._rows = self.GetNumberRows() etisserant@0: self._cols = self.GetNumberCols() etisserant@0: # update the column rendering scheme etisserant@0: self._updateColAttrs(grid) etisserant@0: etisserant@0: # update the scrollbars and the displayed part of the grid etisserant@0: grid.AdjustScrollbars() etisserant@0: grid.ForceRefresh() etisserant@0: etisserant@0: def UpdateValues(self, grid): etisserant@0: """Update all displayed values""" etisserant@0: # This sends an event to the grid table to update all of the values etisserant@0: msg = wxGridTableMessage(self, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES) etisserant@0: grid.ProcessTableMessage(msg) etisserant@0: etisserant@0: def _updateColAttrs(self, grid): etisserant@0: """ etisserant@0: wxGrid -> update the column attributes to add the etisserant@0: appropriate renderer given the column name. etisserant@0: etisserant@0: Otherwise default to the default renderer. etisserant@0: """ etisserant@0: etisserant@0: for col in range(self.GetNumberCols()): etisserant@0: attr = wxGridCellAttr() etisserant@0: attr.SetAlignment(self.ColAlignements[col], wxALIGN_CENTRE) etisserant@0: grid.SetColAttr(col, attr) etisserant@0: grid.SetColSize(col, self.ColSizes[col]) etisserant@0: etisserant@0: for row in range(self.GetNumberRows()): etisserant@0: for col in range(self.GetNumberCols()): etisserant@0: editor = None etisserant@0: renderer = None etisserant@0: colname = self.GetColLabelValue(col) etisserant@0: grid.SetReadOnly(row, col, False) etisserant@0: if colname in ["Name","Interval"]: etisserant@0: editor = wxGridCellTextEditor() etisserant@0: renderer = wxGridCellStringRenderer() etisserant@0: if colname == "Interval" and self.GetValueByName(row, "Single") != "": etisserant@0: grid.SetReadOnly(row, col, True) etisserant@0: elif colname == "Single": etisserant@0: editor = wxGridCellChoiceEditor() etisserant@0: editor.SetParameters(self.Parent.VariableList) etisserant@0: if self.GetValueByName(row, "Interval") != "": etisserant@0: grid.SetReadOnly(row, col, True) etisserant@0: elif colname == "Type": etisserant@0: editor = wxGridCellChoiceEditor() etisserant@0: editor.SetParameters(self.Parent.TypeList) etisserant@0: elif colname == "Priority": etisserant@0: editor = wxGridCellNumberEditor() etisserant@0: editor.SetParameters("0,65535") etisserant@0: elif colname == "Task": etisserant@0: editor = wxGridCellChoiceEditor() etisserant@0: editor.SetParameters(self.Parent.TaskList) etisserant@0: etisserant@0: grid.SetCellEditor(row, col, editor) etisserant@0: grid.SetCellRenderer(row, col, renderer) etisserant@0: etisserant@0: grid.SetCellBackgroundColour(row, col, wxWHITE) etisserant@0: etisserant@0: def SetData(self, data): etisserant@0: self.data = data etisserant@0: etisserant@0: def GetData(self): etisserant@0: return self.data etisserant@0: etisserant@0: def GetCurrentIndex(self): etisserant@0: return self.CurrentIndex etisserant@0: etisserant@0: def SetCurrentIndex(self, index): etisserant@0: self.CurrentIndex = index etisserant@0: etisserant@0: def AppendRow(self, row_content): etisserant@0: self.data.append(row_content) etisserant@0: etisserant@0: def RemoveRow(self, row_index): etisserant@0: self.data.pop(row_index) etisserant@0: etisserant@0: def MoveRow(self, row_index, move, grid): etisserant@0: new_index = max(0, min(row_index + move, len(self.data) - 1)) etisserant@0: if new_index != row_index: etisserant@0: self.data.insert(new_index, self.data.pop(row_index)) etisserant@0: grid.SetGridCursor(new_index, grid.GetGridCursorCol()) etisserant@0: etisserant@0: def Empty(self): etisserant@0: self.data = [] etisserant@0: self.editors = [] etisserant@0: etisserant@0: [wxID_RESOURCEEDITOR, wxID_RESOURCEEDITORSTATICTEXT1, etisserant@0: wxID_RESOURCEEDITORSTATICTEXT2, wxID_RESOURCEEDITORINSTANCESGRID, etisserant@0: wxID_RESOURCEEDITORTASKSGRID, wxID_RESOURCEEDITORADDINSTANCEBUTTON, etisserant@0: wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, wxID_RESOURCEEDITORUPINSTANCEBUTTON, etisserant@0: wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, wxID_RESOURCEEDITORADDTASKBUTTON, etisserant@0: wxID_RESOURCEEDITORDELETETASKBUTTON, wxID_RESOURCEEDITORUPTASKBUTTON, etisserant@0: wxID_RESOURCEEDITORDOWNTASKBUTTON, etisserant@0: ] = [wx.NewId() for _init_ctrls in range(13)] etisserant@0: etisserant@0: class ResourceEditor(wx.Panel): etisserant@0: etisserant@0: def _init_coll_InstancesSizer_Growables(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddGrowableCol(0) etisserant@0: parent.AddGrowableRow(1) etisserant@0: etisserant@0: def _init_coll_InstancesSizer_Items(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddSizer(self.InstancesButtonsSizer, 0, border=0, flag=wxGROW) etisserant@0: parent.AddWindow(self.InstancesGrid, 0, border=0, flag=wxGROW) etisserant@0: etisserant@0: def _init_coll_InstancesButtonsSizer_Growables(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddGrowableCol(0) etisserant@0: parent.AddGrowableRow(0) etisserant@0: etisserant@0: def _init_coll_InstancesButtonsSizer_Items(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddWindow(self.staticText2, 0, border=0, flag=wxALIGN_BOTTOM) etisserant@0: parent.AddWindow(self.AddInstanceButton, 0, border=0, flag=0) etisserant@0: parent.AddWindow(self.DeleteInstanceButton, 0, border=0, flag=0) etisserant@0: parent.AddWindow(self.UpInstanceButton, 0, border=0, flag=0) etisserant@0: parent.AddWindow(self.DownInstanceButton, 0, border=0, flag=0) etisserant@0: etisserant@0: def _init_coll_TasksSizer_Growables(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddGrowableCol(0) etisserant@0: parent.AddGrowableRow(1) etisserant@0: etisserant@0: def _init_coll_TasksSizer_Items(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddSizer(self.TasksButtonsSizer, 0, border=0, flag=wxGROW) etisserant@0: parent.AddWindow(self.TasksGrid, 0, border=0, flag=wxGROW) etisserant@0: etisserant@0: def _init_coll_TasksButtonsSizer_Growables(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddGrowableCol(0) etisserant@0: parent.AddGrowableRow(0) etisserant@0: etisserant@0: def _init_coll_TasksButtonsSizer_Items(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddWindow(self.staticText1, 0, border=0, flag=wxALIGN_BOTTOM) etisserant@0: parent.AddWindow(self.AddTaskButton, 0, border=0, flag=0) etisserant@0: parent.AddWindow(self.DeleteTaskButton, 0, border=0, flag=0) etisserant@0: parent.AddWindow(self.UpTaskButton, 0, border=0, flag=0) etisserant@0: parent.AddWindow(self.DownTaskButton, 0, border=0, flag=0) etisserant@0: etisserant@0: def _init_coll_MainGridSizer_Items(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddSizer(self.TasksSizer, 0, border=0, flag=wxGROW) etisserant@0: parent.AddSizer(self.InstancesSizer, 0, border=0, flag=wxGROW) etisserant@0: etisserant@0: def _init_coll_MainGridSizer_Growables(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddGrowableCol(0) etisserant@0: parent.AddGrowableRow(0) etisserant@0: parent.AddGrowableRow(1) etisserant@0: etisserant@0: def _init_sizers(self): etisserant@0: # generated method, don't edit etisserant@0: self.MainGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) etisserant@0: etisserant@0: self.InstancesSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) etisserant@0: etisserant@0: self.InstancesButtonsSizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0) etisserant@0: etisserant@0: self.TasksSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) etisserant@0: etisserant@0: self.TasksButtonsSizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0) etisserant@0: etisserant@0: self._init_coll_MainGridSizer_Growables(self.MainGridSizer) etisserant@0: self._init_coll_MainGridSizer_Items(self.MainGridSizer) etisserant@0: self._init_coll_InstancesSizer_Growables(self.InstancesSizer) etisserant@0: self._init_coll_InstancesSizer_Items(self.InstancesSizer) etisserant@0: self._init_coll_InstancesButtonsSizer_Growables(self.InstancesButtonsSizer) etisserant@0: self._init_coll_InstancesButtonsSizer_Items(self.InstancesButtonsSizer) etisserant@0: self._init_coll_TasksSizer_Growables(self.TasksSizer) etisserant@0: self._init_coll_TasksSizer_Items(self.TasksSizer) etisserant@0: self._init_coll_TasksButtonsSizer_Growables(self.TasksButtonsSizer) etisserant@0: self._init_coll_TasksButtonsSizer_Items(self.TasksButtonsSizer) etisserant@0: etisserant@0: self.SetSizer(self.MainGridSizer) etisserant@0: etisserant@0: def _init_ctrls(self, prnt): etisserant@0: # generated method, don't edit etisserant@0: wx.Panel.__init__(self, id=wxID_RESOURCEEDITOR, name='', parent=prnt, etisserant@0: pos=wx.Point(0, 0), size=wx.Size(-1, -1), etisserant@0: style=wx.SUNKEN_BORDER) etisserant@0: etisserant@0: self.staticText1 = wx.StaticText(id=wxID_RESOURCEEDITORSTATICTEXT1, etisserant@0: label=u'Tasks:', name='staticText2', parent=self, pos=wx.Point(0, etisserant@0: 0), size=wx.Size(60, 17), style=wxALIGN_CENTER) etisserant@0: etisserant@0: self.TasksGrid = wx.grid.Grid(id=wxID_RESOURCEEDITORTASKSGRID, etisserant@0: name='TasksGrid', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(-1, -1), style=wxVSCROLL) etisserant@0: self.TasksGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, etisserant@0: 'Sans')) etisserant@0: self.TasksGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, etisserant@0: False, 'Sans')) etisserant@0: EVT_GRID_CELL_CHANGE(self.TasksGrid, self.OnTasksGridCellChange) etisserant@0: etisserant@0: self.AddTaskButton = wx.Button(id=wxID_RESOURCEEDITORADDTASKBUTTON, label='Add Task', etisserant@0: name='AddTaskButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(102, 32), style=0) etisserant@0: EVT_BUTTON(self, wxID_RESOURCEEDITORADDTASKBUTTON, self.OnAddTaskButton) etisserant@0: etisserant@0: self.DeleteTaskButton = wx.Button(id=wxID_RESOURCEEDITORDELETETASKBUTTON, label='Delete Task', etisserant@0: name='DeleteTaskButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(102, 32), style=0) etisserant@0: EVT_BUTTON(self, wxID_RESOURCEEDITORDELETETASKBUTTON, self.OnDeleteTaskButton) etisserant@0: etisserant@0: self.UpTaskButton = wx.Button(id=wxID_RESOURCEEDITORUPTASKBUTTON, label='^', etisserant@0: name='UpTaskButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(32, 32), style=0) etisserant@0: EVT_BUTTON(self, wxID_RESOURCEEDITORUPTASKBUTTON, self.OnUpTaskButton) etisserant@0: etisserant@0: self.DownTaskButton = wx.Button(id=wxID_RESOURCEEDITORDOWNTASKBUTTON, label='v', etisserant@0: name='DownTaskButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(32, 32), style=0) etisserant@0: EVT_BUTTON(self, wxID_RESOURCEEDITORDOWNTASKBUTTON, self.OnDownTaskButton) etisserant@0: etisserant@0: self.staticText2 = wx.StaticText(id=wxID_RESOURCEEDITORSTATICTEXT2, etisserant@0: label=u'Instances:', name='staticText1', parent=self, etisserant@0: pos=wx.Point(0, 0), size=wx.Size(85, 17), style=wxALIGN_CENTER) etisserant@0: etisserant@0: self.InstancesGrid = wx.grid.Grid(id=wxID_RESOURCEEDITORINSTANCESGRID, etisserant@0: name='InstancesGrid', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(-1, -1), style=wxVSCROLL) etisserant@0: self.InstancesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, etisserant@0: 'Sans')) etisserant@0: self.InstancesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, etisserant@0: False, 'Sans')) etisserant@0: EVT_GRID_CELL_CHANGE(self.InstancesGrid, self.OnInstancesGridCellChange) etisserant@0: etisserant@0: self.AddInstanceButton = wx.Button(id=wxID_RESOURCEEDITORADDINSTANCEBUTTON, label='Add Instance', etisserant@0: name='AddInstanceButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(122, 32), style=0) etisserant@0: EVT_BUTTON(self, wxID_RESOURCEEDITORADDINSTANCEBUTTON, self.OnAddInstanceButton) etisserant@0: etisserant@0: self.DeleteInstanceButton = wx.Button(id=wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, label='Delete Instance', etisserant@0: name='DeleteInstanceButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(122, 32), style=0) etisserant@0: EVT_BUTTON(self, wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, self.OnDeleteInstanceButton) etisserant@0: etisserant@0: self.UpInstanceButton = wx.Button(id=wxID_RESOURCEEDITORUPINSTANCEBUTTON, label='^', etisserant@0: name='UpInstanceButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(32, 32), style=0) etisserant@0: EVT_BUTTON(self, wxID_RESOURCEEDITORUPINSTANCEBUTTON, self.OnUpInstanceButton) etisserant@0: etisserant@0: self.DownInstanceButton = wx.Button(id=wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, label='v', etisserant@0: name='DownInstanceButton', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(32, 32), style=0) etisserant@0: EVT_BUTTON(self, wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, self.OnDownInstanceButton) etisserant@0: etisserant@0: self._init_sizers() etisserant@0: etisserant@0: def __init__(self, parent, window, controler): etisserant@0: self._init_ctrls(parent) etisserant@0: etisserant@0: self.Parent = window etisserant@0: self.Controler = controler etisserant@0: etisserant@0: self.TasksDefaultValue = {"Name" : "", "Single" : "", "Interval" : "", "Priority" : 0} etisserant@0: self.TasksTable = ResourceTable(self, [], ["Name", "Single", "Interval", "Priority"]) etisserant@0: self.TasksTable.SetColAlignements([wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_RIGHT, wxALIGN_RIGHT]) etisserant@0: self.TasksTable.SetColSizes([200, 100, 100, 100]) etisserant@0: self.TasksGrid.SetTable(self.TasksTable) etisserant@0: self.TasksGrid.SetRowLabelSize(0) etisserant@0: self.TasksTable.ResetView(self.TasksGrid) etisserant@0: etisserant@0: self.InstancesDefaultValue = {"Name" : "", "Type" : "", "Task" : ""} etisserant@0: self.InstancesTable = ResourceTable(self, [], ["Name", "Type", "Task"]) etisserant@0: self.InstancesTable.SetColAlignements([wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT]) etisserant@0: self.InstancesTable.SetColSizes([200, 150, 150]) etisserant@0: self.InstancesGrid.SetTable(self.InstancesTable) etisserant@0: self.InstancesGrid.SetRowLabelSize(0) etisserant@0: self.InstancesTable.ResetView(self.InstancesGrid) etisserant@0: etisserant@0: def RefreshTypeList(self): etisserant@0: self.TypeList = "" etisserant@0: blocktypes = self.Controler.GetBlockResource() etisserant@0: for blocktype in blocktypes: etisserant@0: self.TypeList += ",%s"%blocktype etisserant@0: etisserant@0: def RefreshTaskList(self): etisserant@0: self.TaskList = "" etisserant@0: for row in xrange(self.TasksTable.GetNumberRows()): etisserant@0: self.TaskList += ",%s"%self.TasksTable.GetValueByName(row, "Name") etisserant@0: etisserant@0: def RefreshVariableList(self): etisserant@0: self.VariableList = "" etisserant@0: for variable in self.Controler.GetCurrentResourceEditingVariables(): etisserant@0: self.VariableList += ",%s"%variable etisserant@0: etisserant@0: def RefreshModel(self): etisserant@0: self.Controler.SetCurrentResourceEditingInfos(self.TasksTable.GetData(), self.InstancesTable.GetData()) etisserant@0: etisserant@0: def RefreshView(self): etisserant@0: tasks, instances = self.Controler.GetCurrentResourceEditingInfos() etisserant@0: self.TasksTable.SetData(tasks) etisserant@0: self.InstancesTable.SetData(instances) etisserant@0: self.RefreshTypeList() etisserant@0: self.RefreshTaskList() etisserant@0: self.RefreshVariableList() etisserant@0: self.InstancesTable.ResetView(self.InstancesGrid) etisserant@0: self.TasksTable.ResetView(self.TasksGrid) etisserant@0: etisserant@0: def OnAddTaskButton(self, event): etisserant@0: self.TasksTable.AppendRow(self.TasksDefaultValue.copy()) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDeleteTaskButton(self, event): etisserant@0: row = self.TasksGrid.GetGridCursorRow() etisserant@0: self.TasksTable.RemoveRow(row) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnUpTaskButton(self, event): etisserant@0: row = self.TasksGrid.GetGridCursorRow() etisserant@0: self.TasksTable.MoveRow(row, -1, self.TasksGrid) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDownTaskButton(self, event): etisserant@0: row = self.TasksGrid.GetGridCursorRow() etisserant@0: self.TasksTable.MoveRow(row, 1, self.TasksGrid) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnAddInstanceButton(self, event): etisserant@0: self.InstancesTable.AppendRow(self.InstancesDefaultValue.copy()) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDeleteInstanceButton(self, event): etisserant@0: row = self.InstancesGrid.GetGridCursorRow() etisserant@0: self.InstancesTable.RemoveRow(row) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnUpInstanceButton(self, event): etisserant@0: row = self.InstancesGrid.GetGridCursorRow() etisserant@0: self.InstancesTable.MoveRow(row, -1, self.InstancesGrid) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnDownInstanceButton(self, event): etisserant@0: row = self.InstancesGrid.GetGridCursorRow() etisserant@0: self.InstancesTable.MoveRow(row, 1, self.InstancesGrid) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnTasksGridCellChange(self, event): etisserant@0: row, col = event.GetRow(), event.GetCol() etisserant@0: if self.TasksTable.GetColLabelValue(event.GetCol()) == "Name": etisserant@0: tasklist = self.TaskList.split(",") etisserant@0: for i in xrange(self.TasksTable.GetNumberRows()): etisserant@0: task = self.TasksTable.GetValueByName(i, "Name") etisserant@0: if task in tasklist: etisserant@0: tasklist.remove(task) etisserant@0: tasklist.remove("") etisserant@0: if len(tasklist) > 0: etisserant@0: old_name = tasklist[0] etisserant@0: new_name = self.TasksTable.GetValue(row, col) etisserant@0: for i in xrange(self.InstancesTable.GetNumberRows()): etisserant@0: if self.InstancesTable.GetValueByName(i, "Task") == old_name: etisserant@0: self.InstancesTable.SetValueByName(i, "Task", new_name) etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnInstancesGridCellChange(self, event): etisserant@0: self.RefreshModel() etisserant@0: self.RefreshView() etisserant@0: event.Skip()