# HG changeset patch # User laurent # Date 1337587184 -7200 # Node ID 629680fb05824a0d7a5371562479c2781538d032 # Parent 3216bf5f711dd215610acb38b7225cc714c82a73 refactoring diff -r 3216bf5f711d -r 629680fb0582 GraphicViewer.py --- a/GraphicViewer.py Sat May 19 12:40:53 2012 +0200 +++ b/GraphicViewer.py Mon May 21 09:59:44 2012 +0200 @@ -507,14 +507,15 @@ ## Refresh the variable cursor. # @param dc The draw canvas def RefreshCursor(self, dc=None): - if dc is None: - dc = wx.BufferedDC(wx.ClientDC(self.Canvas.canvas), self.Canvas._Buffer) - - # Erase previous time cursor if drawn - if self.LastCursor is not None: - self.DrawCursor(dc, *self.LastCursor) - - # Draw new time cursor - if self.CursorIdx is not None: - self.LastCursor = self.Datas[self.CursorIdx] - self.DrawCursor(dc, *self.LastCursor) + if self: + if dc is None: + dc = wx.BufferedDC(wx.ClientDC(self.Canvas.canvas), self.Canvas._Buffer) + + # Erase previous time cursor if drawn + if self.LastCursor is not None: + self.DrawCursor(dc, *self.LastCursor) + + # Draw new time cursor + if self.CursorIdx is not None: + self.LastCursor = self.Datas[self.CursorIdx] + self.DrawCursor(dc, *self.LastCursor) diff -r 3216bf5f711d -r 629680fb0582 PLCControler.py --- a/PLCControler.py Sat May 19 12:40:53 2012 +0200 +++ b/PLCControler.py Mon May 21 09:59:44 2012 +0200 @@ -577,7 +577,7 @@ return ["%s.%s" % (words[1], words[2])] return [] - def RecursiveGetPouInstanceTagname(self, project, pou_type, parts): + def RecursiveGetPouInstanceTagName(self, project, pou_type, parts): pou = project.getpou(pou_type) if pou is not None: if len(parts) == 0: @@ -587,13 +587,13 @@ for variable in varlist.getvariable(): vartype_content = variable.gettype().getcontent() if vartype_content["name"] == "derived": - return self.RecursiveGetPouInstanceTagname( + return self.RecursiveGetPouInstanceTagName( project, vartype_content["value"].getname(), parts[1:]) return None - def GetPouInstanceTagname(self, instance_path, debug = False): + def GetPouInstanceTagName(self, instance_path, debug = False): parts = instance_path.split(".") if len(parts) == 1: return self.ComputeConfigurationName(parts[0]) @@ -614,149 +614,26 @@ return self.ComputePouName( pou_instance.gettypeName()) else: - return self.RecursiveGetPouInstanceTagname( + return self.RecursiveGetPouInstanceTagName( project, pou_instance.gettypeName(), parts[3:]) return None - def GetInstanceInfos(self, instance_path): + def GetInstanceInfos(self, instance_path, debug = False): tagname = self.GetPouInstanceTagName(instance_path) if tagname is not None: - return self.Controler.GetPouVariables(tagname, self.Debug) + return self.GetPouVariables(tagname, debug) else: - pou_path, var_name = tagname.rsplit(".", 1) - tagname = self.Controler.GetPouInstanceTagName(pou_path) + pou_path, var_name = instance_path.rsplit(".", 1) + tagname = self.GetPouInstanceTagName(pou_path) if tagname is not None: - pou_infos = self.Controler.GetPouVariables(tagname, self.Debug) + pou_infos = self.GetPouVariables(tagname, debug) for var_infos in pou_infos["variables"]: if var_infos["name"] == var_name: return var_infos return None - - # Return project topology informations - def GetProjectTopology(self, debug = False): - project = self.GetProject(debug) - if project is not None: - infos = {"name": project.getname(), "type": ITEM_PROJECT, "values" : []} - for config in project.getconfigurations(): - config_infos = {"name" : config.getname(), "type": ITEM_CONFIGURATION, "values" : []} - for resource in config.getresource(): - resource_infos = {"name" : resource.getname(), "type": ITEM_RESOURCE, "values": []} - for task in resource.gettask(): - for pou in task.getpouInstance(): - instance_infos = self.GetPouTopology(pou.getname(), pou.gettypeName(), debug=debug) - if instance_infos is not None: - resource_infos["values"].append(instance_infos) - for pou in resource.getpouInstance(): - instance_infos = self.GetPouTopology(pou.getname(), pou.gettypeName(), debug=debug) - if instance_infos is not None: - resource_infos["values"].append(instance_infos) - for varlist in resource.getglobalVars(): - for variable in varlist.getvariable(): - vartype_content = variable.gettype().getcontent() - if vartype_content["name"] == "derived": - var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True, debug) - if var_infos is not None: - resource_infos["values"].append(var_infos) - elif vartype_content["name"] in ["string", "wstring"]: - resource_infos["values"].append({"name" : variable.getname(), - "elmt_type" : vartype_content["name"].upper(), - "type" : ITEM_VAR_GLOBAL, "values" : []}) - else: - resource_infos["values"].append({"name" : variable.getname(), - "elmt_type" : vartype_content["name"], - "type" : ITEM_VAR_GLOBAL, "values" : []}) - config_infos["values"].append(resource_infos) - for varlist in config.getglobalVars(): - for variable in varlist.getvariable(): - vartype_content = variable.gettype().getcontent() - if vartype_content["name"] == "derived": - var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True, debug) - if var_infos is not None: - config_infos["values"].append(var_infos) - elif vartype_content["name"] in ["string", "wstring"]: - config_infos["values"].append({"name" : variable.getname(), - "elmt_type" : vartype_content["name"].upper(), - "type" : ITEM_VAR_GLOBAL, "values" : []}) - else: - config_infos["values"].append({"name" : variable.getname(), - "elmt_type" : vartype_content["name"], - "type" : ITEM_VAR_GLOBAL, "values" : []}) - infos["values"].append(config_infos) - return infos - return None - - # Return pou topology informations - def GetPouTopology(self, name, type, global_var = False, debug = False): - project = self.GetProject(debug) - if project is not None: - pou = project.getpou(type) - if pou is not None: - pou_type = pou.getpouType() - if pou_type == "function": - return None - elif pou_type == "program": - pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, - "tagname" : self.ComputePouName(pou.getname()), "values" : []} - else: - pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, - "tagname" : self.ComputePouName(pou.getname()), "values" : []} - if pou.getbodyType() == "SFC": - for transition in pou.gettransitionList(): - pou_infos["values"].append({"name" : transition.getname(), - "elmt_type" : "TRANSITION", "type" : ITEM_TRANSITION, - "tagname" : self.ComputePouActionName(pou.getname(), transition.getname()), - "values" : []}) - for action in pou.getactionList(): - pou_infos["values"].append({"name": action.getname(), - "elmt_type" : "ACTION", "type": ITEM_ACTION, - "tagname" : self.ComputePouActionName(pou.getname(), action.getname()), - "values" : []}) - if pou.interface: - # Extract variables from every varLists - for type, varlist in pou.getvars(): - infos = VAR_CLASS_INFOS.get(type, None) - if infos is not None: - current_var_class = infos[1] - else: - current_var_class = ITEM_VAR_LOCAL - for variable in varlist.getvariable(): - vartype_content = variable.gettype().getcontent() - if vartype_content["name"] == "derived": - var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname()) - if var_infos is not None: - pou_infos["values"].append(var_infos) - elif vartype_content["name"] in ["string", "wstring"]: - pou_infos["values"].append({"name" : variable.getname(), - "elmt_type" : vartype_content["name"].upper(), - "type" : current_var_class, "values" : []}) - else: - pou_infos["values"].append({"name" : variable.getname(), - "elmt_type" : vartype_content["name"], - "type" : current_var_class, "values" : []}) - return pou_infos - block_infos = self.GetBlockType(type, debug = debug) - if block_infos is not None: - if block_infos["type"] == "function": - return None - elif block_infos["type"] == "program": - pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, "values" : []} - else: - pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, "values" : []} - for varname, vartype, varmodifier in block_infos["inputs"]: - pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []}) - for varname, vartype, varmodifier in block_infos["outputs"]: - pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_OUTPUT, "values" : []}) - return pou_infos - - if type in self.GetDataTypes(debug = debug): - if global_var: - return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_GLOBAL, "values" : []} - else: - return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_LOCAL, "values" : []} - return None - + # Return if data type given by name is used by another data type or pou def DataTypeIsUsed(self, name, debug = False): project = self.GetProject(debug) @@ -919,6 +796,15 @@ self.Project.removepou(pou_name) self.BufferProject() + # Return the name of the configuration if only one exist + def GetProjectMainConfigurationName(self): + if self.Project is not None: + # Found the configuration corresponding to old name and change its name to new name + configurations = self.Project.getconfigurations() + if len(configurations) == 1: + return configurations[0].getname() + return None + # Add a configuration to Project def ProjectAddConfiguration(self, config_name): if self.Project is not None: diff -r 3216bf5f711d -r 629680fb0582 PLCOpenEditor.py --- a/PLCOpenEditor.py Sat May 19 12:40:53 2012 +0200 +++ b/PLCOpenEditor.py Mon May 21 09:59:44 2012 +0200 @@ -279,20 +279,13 @@ control.ProcessEvent(event) return ShortcutKeyFunction -def GetParentName(tree, item, parent_type): - parent_item = tree.GetItemParent(item) - parent_item_type = tree.GetPyData(parent_item) - while parent_item_type != parent_type: - parent_item = tree.GetItemParent(parent_item) - parent_item_type = tree.GetPyData(parent_item) - return tree.GetItemText(parent_item) - def GetDeleteElementFunction(remove_function, parent_type=None, check_function=None): def DeleteElementFunction(self, selected): name = self.ProjectTree.GetItemText(selected) if check_function is None or not check_function(self.Controler, name): if parent_type is not None: - parent_name = GetParentName(self.ProjectTree, selected, parent_type) + item_infos = self.ProjectTree.GetPyData(selected) + parent_name = item_infos["tagname"].split("::")[1] remove_function(self.Controler, parent_name, name) else: remove_function(self.Controler, name) @@ -406,7 +399,7 @@ def _init_coll_FileMenu_Items(self, parent): pass - def _init_coll_AddMenu_Items(self, parent): + def _init_coll_AddMenu_Items(self, parent, add_config=True): AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE, kind=wx.ITEM_NORMAL, text=_(u'&Data Type')) AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION, @@ -415,8 +408,9 @@ kind=wx.ITEM_NORMAL, text=_(u'Function &Block')) AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM, kind=wx.ITEM_NORMAL, text=_(u'&Program')) - AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, - kind=wx.ITEM_NORMAL, text=_(u'&Configuration')) + if add_config: + AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, + kind=wx.ITEM_NORMAL, text=_(u'&Configuration')) def _init_coll_EditMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_UNDO, @@ -854,11 +848,12 @@ elif page_infos[0] == "editor": tagname = page_infos[1] page_ref = self.EditProjectElement(self.Controler.GetElementType(tagname), tagname) - page_ref.RefreshView() - return notebook.GetPageIndex(page_ref) + if page_ref is not None: + page_ref.RefreshView() + return notebook.GetPageIndex(page_ref) elif page_infos[0] == "debug": instance_path = page_infos[1] - instance_infos = self.Controler.GetInstanceInfos(instance_path) + instance_infos = self.Controler.GetInstanceInfos(instance_path, self.EnableDebug) if instance_infos is not None: return notebook.GetPageIndex(self.OpenDebugViewer(instance_infos["class"], instance_path, instance_infos["type"])) return None @@ -1194,6 +1189,7 @@ def ResetView(self): self.DeleteAllPages() self.ProjectTree.DeleteAllItems() + self.ProjectTree.Enable(False) self.PouInstanceVariablesPanel.ResetView() self.LibraryPanel.ResetTree() self.LibraryPanel.SetControler(None) @@ -1387,8 +1383,7 @@ if window == self.ProjectTree or window is None: selected = self.ProjectTree.GetSelection() if selected.IsOk(): - type = self.ProjectTree.GetPyData(selected) - function = self.DeleteFunctions.get(type, None) + function = self.DeleteFunctions.get(self.ProjectTree.GetPyData(selected)["type"], None) if function is not None: function(self, selected) self.CloseTabsWithoutModel() @@ -1484,6 +1479,10 @@ self.AUIManager.RestorePane(pane) self.AUIManager.Update() + def EnsureTabVisible(self, tab): + notebook = tab.GetParent() + notebook.SetSelection(notebook.GetPageIndex(tab)) + def OnPouSelectedChanging(self, event): if not self.Starting: selected = self.TabsOpened.GetSelection() @@ -1503,8 +1502,13 @@ wx.CallAfter(self.SelectProjectTreeItem, tagname) wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname) window.RefreshView() + self.EnsureTabVisible(self.LibraryPanel) else: instance_path = window.GetInstancePath() + if tagname == "": + instance_path = instance_path.rsplit(".", 1)[0] + tagname = self.Controler.GetPouInstanceTagName(instance_path, self.EnableDebug) + self.EnsureTabVisible(self.DebugVariablePanel) wx.CallAfter(self.PouInstanceVariablesPanel.SetPouType, tagname, instance_path) wx.CallAfter(self._Refresh, FILEMENU, EDITMENU, DISPLAYMENU, EDITORTOOLBAR) event.Skip() @@ -1581,15 +1585,20 @@ return self.GenerateProjectTreeBranch(root, infos["values"][0]) item_name = _(item_name) self.ProjectTree.SetItemText(root, item_name) - self.ProjectTree.SetPyData(root, infos["type"]) + self.ProjectTree.SetPyData(root, infos) highlight_colours = self.Highlights.get(infos.get("tagname", None), (wx.WHITE, wx.BLACK)) self.ProjectTree.SetItemBackgroundColour(root, highlight_colours[0]) self.ProjectTree.SetItemTextColour(root, highlight_colours[1]) if infos["type"] == ITEM_POU: self.ProjectTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"])]) - else: + elif infos.has_key("icon") and infos["icon"] is not None: + icon_path = infos["icon"] + if not self.TreeImageDict.has_key(icon_path): + self.TreeImageDict[icon_path] = self.TreeImageList.Add(wx.Bitmap(icon_path)) + self.ProjectTree.SetItemImage(root, self.TreeImageDict[icon_path]) + elif self.TreeImageDict.has_key(infos["type"]): self.ProjectTree.SetItemImage(root, self.TreeImageDict[infos["type"]]) - + if wx.VERSION >= (2, 6, 0): item, root_cookie = self.ProjectTree.GetFirstChild(root) else: @@ -1634,7 +1643,8 @@ else: item, root_cookie = self.ProjectTree.GetFirstChild(root, 0) while item.IsOk() and not found: - if (self.ProjectTree.GetItemText(item), self.ProjectTree.GetPyData(item)) == items[0]: + item_infos = self.ProjectTree.GetPyData(item) + if (item_infos["name"].split(":")[-1].strip(), item_infos["type"]) == items[0]: if len(items) == 1: self.SelectedItem = item self.ProjectTree.SelectItem(item) @@ -1650,7 +1660,7 @@ def OnProjectTreeBeginDrag(self, event): if wx.Platform == '__WXMSW__': self.SelectedItem = event.GetItem() - if self.SelectedItem is not None and self.ProjectTree.GetPyData(self.SelectedItem) == ITEM_POU: + if self.SelectedItem is not None and self.ProjectTree.GetPyData(self.SelectedItem)["type"] == ITEM_POU: block_name = self.ProjectTree.GetItemText(self.SelectedItem) block_type = self.Controler.GetPouType(block_name) if block_type != "program": @@ -1662,7 +1672,7 @@ def OnProjectTreeItemBeginEdit(self, event): selected = event.GetItem() - if self.ProjectTree.GetPyData(selected) in ITEMS_UNEDITABLE: + if self.ProjectTree.GetPyData(selected)["type"] in ITEMS_UNEDITABLE: event.Veto() else: event.Skip() @@ -1679,10 +1689,10 @@ else: item = event.GetItem() old_name = self.ProjectTree.GetItemText(item) - itemtype = self.ProjectTree.GetPyData(item) - if itemtype == ITEM_PROJECT: + item_infos = self.ProjectTree.GetPyData(item) + if item_infos["type"] == ITEM_PROJECT: self.Controler.SetProjectProperties(name = new_name) - elif itemtype == ITEM_DATATYPE: + elif item_infos["type"] == ITEM_DATATYPE: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames() if name != old_name]: message = _("\"%s\" data type already exists!")%new_name abort = True @@ -1691,7 +1701,7 @@ self.RefreshEditorNames(self.Controler.ComputeDataTypeName(old_name), self.Controler.ComputeDataTypeName(new_name)) self.RefreshPageTitles() - elif itemtype == ITEM_POU: + elif item_infos["type"] == ITEM_POU: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]: message = _("\"%s\" pou already exists!")%new_name abort = True @@ -1706,29 +1716,29 @@ self.Controler.ComputePouName(new_name)) self.RefreshLibraryPanel() self.RefreshPageTitles() - elif itemtype == ITEM_TRANSITION: - pou_name = GetParentName(self.ProjectTree, item, ITEM_POU) + elif item_infos["type"] == ITEM_TRANSITION: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: message = _("A POU named \"%s\" already exists!")%new_name elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]: message = _("A variable with \"%s\" as name already exists in this pou!")%new_name else: - self.Controler.ChangePouTransitionName(pou_name, old_name, new_name) - self.RefreshEditorNames(self.Controler.ComputePouTransitionName(pou_name, old_name), - self.Controler.ComputePouTransitionName(pou_name, new_name)) + words = item_infos["tagname"].split("::") + self.Controler.ChangePouTransitionName(words[1], old_name, new_name) + self.RefreshEditorNames(self.Controler.ComputePouTransitionName(words[1], old_name), + self.Controler.ComputePouTransitionName(words[1], new_name)) self.RefreshPageTitles() - elif itemtype == ITEM_ACTION: - pou_name = GetParentName(self.ProjectTree, item, ITEM_POU) + elif item_infos["type"] == ITEM_ACTION: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: message = _("A POU named \"%s\" already exists!")%new_name elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]: message = _("A variable with \"%s\" as name already exists in this pou!")%new_name else: - self.Controler.ChangePouActionName(pou_name, old_name, new_name) - self.RefreshEditorNames(self.Controler.ComputePouActionName(pou_name, old_name), - self.Controler.ComputePouActionName(pou_name, new_name)) + words = item_infos["tagname"].split("::") + self.Controler.ChangePouActionName(words[1], old_name, new_name) + self.RefreshEditorNames(self.Controler.ComputePouActionName(words[1], old_name), + self.Controler.ComputePouActionName(words[1], new_name)) self.RefreshPageTitles() - elif itemtype == ITEM_CONFIGURATION: + elif item_infos["type"] == ITEM_CONFIGURATION: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]: message = _("\"%s\" config already exists!")%new_name abort = True @@ -1747,8 +1757,7 @@ self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), self.Controler.ComputeConfigurationName(new_name)) self.RefreshPageTitles() - elif itemtype == ITEM_RESOURCE: - config_name = GetParentName(self.ProjectTree, item, ITEM_CONFIGURATION) + elif item_infos["type"] == ITEM_RESOURCE: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]: message = _("\"%s\" config already exists!")%new_name abort = True @@ -1763,9 +1772,10 @@ abort = True messageDialog.Destroy() if not abort: - self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name) - self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(config_name, old_name), - self.Controler.ComputeConfigurationResourceName(config_name, new_name)) + words = item_infos["tagname"].split("::") + self.Controler.ChangeConfigurationResourceName(words[1], old_name, new_name) + self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(words[1], old_name), + self.Controler.ComputeConfigurationResourceName(words[1], new_name)) self.RefreshPageTitles() if message or abort: if message: @@ -1782,49 +1792,23 @@ def OnProjectTreeItemActivated(self, event): selected = event.GetItem() name = self.ProjectTree.GetItemText(selected) - data = self.ProjectTree.GetPyData(selected) - if data == ITEM_PROJECT: + item_infos = self.ProjectTree.GetPyData(selected) + if item_infos["type"] == ITEM_PROJECT: self.EditProjectSettings() - elif data == ITEM_DATATYPE: - self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name)) - elif data == ITEM_POU: - self.EditProjectElement(data, self.Controler.ComputePouName(name)) - elif data == ITEM_CONFIGURATION: - self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name)) - elif data == ITEM_RESOURCE: - config_name = GetParentName(self.ProjectTree, selected, ITEM_CONFIGURATION) - self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name)) - elif data in [ITEM_TRANSITION, ITEM_ACTION]: - pou_name = GetParentName(self.ProjectTree, selected, ITEM_POU) - if data == ITEM_TRANSITION: - tagname = self.Controler.ComputePouTransitionName(pou_name, name) - elif data == ITEM_ACTION: - tagname = self.Controler.ComputePouActionName(pou_name, name) - self.EditProjectElement(data, tagname) + elif item_infos["type"] in [ITEM_DATATYPE, ITEM_POU, + ITEM_CONFIGURATION, ITEM_RESOURCE, + ITEM_TRANSITION, ITEM_ACTION]: + self.EditProjectElement(item_infos["type"], item_infos["tagname"]) event.Skip() def ProjectTreeItemSelect(self, select_item): name = self.ProjectTree.GetItemText(select_item) - data = self.ProjectTree.GetPyData(select_item) - tagname = None - if data == ITEM_DATATYPE: - tagname = self.Controler.ComputeDataTypeName(name) - elif data == ITEM_POU: - tagname = self.Controler.ComputePouName(name) - elif data == ITEM_CONFIGURATION: - tagname = self.Controler.ComputeConfigurationName(name) - elif data == ITEM_RESOURCE: - config_name = GetParentName(self.ProjectTree, select_item, ITEM_CONFIGURATION) - tagname = self.Controler.ComputeConfigurationResourceName(config_name, name) - elif data in [ITEM_TRANSITION, ITEM_ACTION]: - pou_name = GetParentName(self.ProjectTree, select_item, ITEM_POU) - if data == ITEM_TRANSITION: - tagname = self.Controler.ComputePouTransitionName(pou_name, name) - elif data == ITEM_ACTION: - tagname = self.Controler.ComputePouActionName(pou_name, name) - if tagname is not None: - self.EditProjectElement(data, tagname, True) - self.PouInstanceVariablesPanel.SetPouType(tagname) + item_infos = self.ProjectTree.GetPyData(select_item) + if item_infos["type"] in [ITEM_DATATYPE, ITEM_POU, + ITEM_CONFIGURATION, ITEM_RESOURCE, + ITEM_TRANSITION, ITEM_ACTION]: + self.EditProjectElement(item_infos["type"], item_infos["tagname"], True) + self.PouInstanceVariablesPanel.SetPouType(item_infos["tagname"]) def OnProjectTreeLeftUp(self, event): if self.SelectedItem is not None: @@ -1838,7 +1822,7 @@ event.Skip() def OnProjectTreeItemChanging(self, event): - if self.ProjectTree.GetPyData(event.GetItem()) not in ITEMS_UNEDITABLE and self.SelectedItem is None: + if self.ProjectTree.GetPyData(event.GetItem())["type"] not in ITEMS_UNEDITABLE and self.SelectedItem is None: self.SelectedItem = event.GetItem() event.Veto() else: @@ -1925,10 +1909,10 @@ self.ProjectTree.SelectItem(item) self.ProjectTreeItemSelect(item) name = self.ProjectTree.GetItemText(item) - type = self.ProjectTree.GetPyData(item) + item_infos = self.ProjectTree.GetPyData(item) menu = None - if type in ITEMS_UNEDITABLE: + if item_infos["type"] in ITEMS_UNEDITABLE: name = UNEDITABLE_NAMES_DICT[name] if name == "Data Types": @@ -1960,11 +1944,11 @@ menu = wx.Menu(title='') new_id = wx.NewId() AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition")) - parent = self.ProjectTree.GetItemParent(item) + parent = self.ProjectTree.GetItemParent(item)["type"] parent_type = self.ProjectTree.GetPyData(parent) while parent_type != ITEM_POU: parent = self.ProjectTree.GetItemParent(parent) - parent_type = self.ProjectTree.GetPyData(parent) + parent_type = self.ProjectTree.GetPyData(parent)["type"] self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(self.ProjectTree.GetItemText(parent)), id=new_id) elif name == "Actions": @@ -1972,10 +1956,10 @@ new_id = wx.NewId() AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action")) parent = self.ProjectTree.GetItemParent(item) - parent_type = self.ProjectTree.GetPyData(parent) + parent_type = self.ProjectTree.GetPyData(parent)["type"] while parent_type != ITEM_POU: parent = self.ProjectTree.GetItemParent(parent) - parent_type = self.ProjectTree.GetPyData(parent) + parent_type = self.ProjectTree.GetPyData(parent)["type"] self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(self.ProjectTree.GetItemText(parent)), id=new_id) elif name == "Resources": @@ -1983,14 +1967,18 @@ new_id = wx.NewId() AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource")) parent = self.ProjectTree.GetItemParent(item) - parent_type = self.ProjectTree.GetPyData(parent) - while parent_type != ITEM_CONFIGURATION: + parent_type = self.ProjectTree.GetPyData(parent)["type"] + while parent_type not in [ITEM_CONFIGURATION, ITEM_PROJECT]: parent = self.ProjectTree.GetItemParent(parent) - parent_type = self.ProjectTree.GetPyData(parent) - self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(self.ProjectTree.GetItemText(parent)), id=new_id) + parent_type = self.ProjectTree.GetPyData(parent)["type"] + if parent_type == ITEM_PROJECT: + parent_name = None + else: + parent_name = self.ProjectTree.GetItemText(parent) + self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(parent_name), id=new_id) else: - if type == ITEM_POU: + if item_infos["type"] == ITEM_POU: menu = wx.Menu(title='') if self.Controler.GetPouBodyType(name) == "SFC": new_id = wx.NewId() @@ -2020,13 +2008,13 @@ AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename")) self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id) - elif type == ITEM_CONFIGURATION: + elif item_infos["type"] == ITEM_CONFIGURATION: menu = wx.Menu(title='') new_id = wx.NewId() AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource")) self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id) - elif type in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]: + elif item_infos["type"] in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]: menu = wx.Menu(title='') if menu is not None: @@ -2129,7 +2117,7 @@ for idx in idxs: editor = self.TabsOpened.GetPage(idx) if editor.IsDebugging(): - instance_infos = self.Controler.GetInstanceInfos(editor.GetInstancePath()) + instance_infos = self.Controler.GetInstanceInfos(editor.GetInstancePath(), self.EnableDebug) if instance_infos is None: self.TabsOpened.DeletePage(idx) elif isinstance(editor, GraphicViewer): @@ -2141,6 +2129,7 @@ def AddDebugVariable(self, iec_path, force=False): if self.EnableDebug: self.DebugVariablePanel.InsertValue(iec_path, force=force) + self.EnsureTabVisible(self.DebugVariablePanel) #------------------------------------------------------------------------------- # Library Panel Management Function @@ -2441,7 +2430,7 @@ def GenerateChangePouTypeFunction(self, name, new_type): def OnChangePouTypeMenu(event): selected = self.ProjectTree.GetSelection() - if self.ProjectTree.GetPyData(selected) == ITEM_POU: + if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: self.Controler.ProjectChangePouType(name, new_type) self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, PROJECTTREE, LIBRARYTREE) return OnChangePouTypeMenu @@ -2479,7 +2468,7 @@ def OnRemoveDataTypeMenu(self, event): selected = self.ProjectTree.GetSelection() - if self.ProjectTree.GetPyData(selected) == ITEM_DATATYPE: + if self.ProjectTree.GetPyData(selected)["type"] == ITEM_DATATYPE: name = self.ProjectTree.GetItemText(selected) if not self.Controler.DataTypeIsUsed(name): self.Controler.ProjectRemoveDataType(name) @@ -2493,12 +2482,12 @@ def OnRenamePouMenu(self, event): selected = self.ProjectTree.GetSelection() - if self.ProjectTree.GetPyData(selected) == ITEM_POU: + if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: wx.CallAfter(self.ProjectTree.EditLabel, selected) def OnRemovePouMenu(self, event): selected = self.ProjectTree.GetSelection() - if self.ProjectTree.GetPyData(selected) == ITEM_POU: + if self.ProjectTree.GetPyData(selected)["type"] == ITEM_POU: name = self.ProjectTree.GetItemText(selected) if not self.Controler.PouIsUsed(name): self.Controler.ProjectRemovePou(name) @@ -2512,14 +2501,10 @@ def OnRemoveTransitionMenu(self, event): selected = self.ProjectTree.GetSelection() - if self.ProjectTree.GetPyData(selected) == ITEM_TRANSITION: + item_infos = self.ProjectTree.GetPyData(selected) + if item_infos["type"] == ITEM_TRANSITION: transition = self.ProjectTree.GetItemText(selected) - item = self.ProjectTree.GetItemParent(selected) - item_type = self.ProjectTree.GetPyData(item) - while item_type != ITEM_POU: - item = self.ProjectTree.GetItemParent(item) - item_type = self.ProjectTree.GetPyData(item) - pou_name = self.ProjectTree.GetItemText(item) + pou_name = item_infos["tagname"].split("::")[1] self.Controler.ProjectRemovePouTransition(pou_name, transition) tagname = self.Controler.ComputePouTransitionName(pou_name, transition) idx = self.IsOpened(tagname) @@ -2529,14 +2514,10 @@ def OnRemoveActionMenu(self, event): selected = self.ProjectTree.GetSelection() - if self.ProjectTree.GetPyData(selected) == ITEM_ACTION: + item_infos = self.ProjectTree.GetPyData(selected) + if item_infos["type"] == ITEM_ACTION: action = self.ProjectTree.GetItemText(selected) - item = self.ProjectTree.GetItemParent(selected) - item_type = self.ProjectTree.GetPyData(item) - while item_type != ITEM_POU: - item = self.ProjectTree.GetItemParent(item) - item_type = self.ProjectTree.GetPyData(item) - pou_name = self.ProjectTree.GetItemText(item) + pou_name = item_infos["tagname"].split("::")[1] self.Controler.ProjectRemovePouAction(pou_name, action) tagname = self.Controler.ComputePouActionName(pou_name, action) idx = self.IsOpened(tagname) @@ -2546,7 +2527,7 @@ def OnRemoveConfigurationMenu(self, event): selected = self.ProjectTree.GetSelection() - if self.ProjectTree.GetPyData(selected) == ITEM_CONFIGURATION: + if self.ProjectTree.GetPyData(selected)["type"] == ITEM_CONFIGURATION: name = self.ProjectTree.GetItemText(selected) self.Controler.ProjectRemoveConfiguration(name) tagname = self.Controler.ComputeConfigurationName(name) @@ -2557,14 +2538,10 @@ def OnRemoveResourceMenu(self, event): selected = self.ProjectTree.GetSelection() - if self.ProjectTree.GetPyData(selected) == ITEM_RESOURCE: + item_infos = self.ProjectTree.GetPyData(selected) + if item_infos["type"] == ITEM_RESOURCE: resource = self.ProjectTree.GetItemText(selected) - item = self.ProjectTree.GetItemParent(selected) - item_type = self.ProjectTree.GetPyData(item) - while item_type != ITEM_CONFIGURATION: - item = self.ProjectTree.GetItemParent(item) - item_type = self.ProjectTree.GetPyData(item) - config_name = self.ProjectTree.GetItemText(item) + config_name = item_infos["tagname"].split("::")[1] self.Controler.ProjectRemoveConfigurationResource(config_name, resource) tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected) idx = self.IsOpened(tagname) @@ -2711,11 +2688,13 @@ # Open the filepath if defined if fileOpen is not None and os.path.isfile(fileOpen): # Create a new controller - self.Controler = PLCControler() - result = self.Controler.OpenXMLFile(fileOpen) + controler = PLCControler() + result = controler.OpenXMLFile(fileOpen) if result is None: - self.LibraryPanel.SetControler(self.Controler) - self.PouInstanceVariablesPanel.SetController(self.Controler) + self.Controler = controler + self.LibraryPanel.SetControler(controler) + self.ProjectTree.Enable(True) + self.PouInstanceVariablesPanel.SetController(controler) self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) # Define PLCOpenEditor icon @@ -2826,11 +2805,13 @@ filepath = dialog.GetPath() if os.path.isfile(filepath): self.ResetView() - self.Controler = PLCControler() - result = self.Controler.OpenXMLFile(filepath) + controler = PLCControler() + result = controler.OpenXMLFile(filepath) if result is None: - self.LibraryPanel.SetControler(self.Controler) - self.PouInstanceVariablesPanel.SetController(self.Controler) + self.Controler = controler + self.LibraryPanel.SetControler(controler) + self.ProjectTree.Enable(True) + self.PouInstanceVariablesPanel.SetController(controler) self.LoadProjectOrganization() self._Refresh(PROJECTTREE, LIBRARYTREE) self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU) @@ -4254,11 +4235,12 @@ items = [(idx, item) for idx, item in enumerate(self.Table.GetData())] items.reverse() for idx, item in items: - if self.GetDataType(item.GetVariable().upper()) is None: + iec_path = item.GetVariable().upper() + if self.GetDataType(iec_path) is None: self.RemoveDataConsumer(item) self.Table.RemoveItem(idx) else: - self.AddDataConsumer(iec_path.upper(), item) + self.AddDataConsumer(iec_path, item) self.Freeze() self.Table.ResetView(self.VariablesGrid) self.VariablesGrid.RefreshButtons() diff -r 3216bf5f711d -r 629680fb0582 TextViewer.py --- a/TextViewer.py Sat May 19 12:40:53 2012 +0200 +++ b/TextViewer.py Mon May 21 09:59:44 2012 +0200 @@ -247,7 +247,8 @@ return {"cursor_pos": self.Editor.GetCurrentPos()} def SetState(self, state): - self.Editor.GotoPos(state.get("cursor_pos", 0)) + if self: + self.Editor.GotoPos(state.get("cursor_pos", 0)) def OnModification(self, event): if not self.DisableEvents: diff -r 3216bf5f711d -r 629680fb0582 Viewer.py --- a/Viewer.py Sat May 19 12:40:53 2012 +0200 +++ b/Viewer.py Mon May 21 09:59:44 2012 +0200 @@ -691,9 +691,10 @@ "zoom": self.CurrentScale} def SetState(self, state): - self.SetScale(state["zoom"]) - self.Scroll(*state["position"]) - self.RefreshVisibleElements() + if self: + self.SetScale(state["zoom"]) + self.Scroll(*state["position"]) + self.RefreshVisibleElements() def GetLogicalDC(self, buffered=False): if buffered: diff -r 3216bf5f711d -r 629680fb0582 controls/CustomTree.py --- a/controls/CustomTree.py Sat May 19 12:40:53 2012 +0200 +++ b/controls/CustomTree.py Mon May 21 09:59:44 2012 +0200 @@ -27,12 +27,14 @@ self.BackgroundAlign = wx.ALIGN_LEFT|wx.ALIGN_TOP self.AddMenu = None + self.Enabled = False if wx.Platform == '__WXMSW__': self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) else: self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnResize) + self.Bind(wx.EVT_SCROLL, self.OnScroll) self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) def SetBackgroundBitmap(self, bitmap, align): @@ -42,6 +44,9 @@ def SetAddMenu(self, add_menu): self.AddMenu = add_menu + def Enable(self, enabled): + self.Enabled = enabled + def GetBitmapRect(self): client_size = self.GetClientSize() bitmap_size = self.BackgroundBitmap.GetSize() @@ -76,13 +81,19 @@ self.RefreshBackground(True) def OnLeftUp(self, event): - pos = event.GetPosition() - item, flags = self.HitTest(pos) - - bitmap_rect = self.GetBitmapRect() - if (bitmap_rect.InsideXY(pos.x, pos.y) or - flags & wx.TREE_HITTEST_NOWHERE) and self.AddMenu is not None: - self.PopupMenuXY(self.AddMenu, pos.x, pos.y) + if self.Enabled: + pos = event.GetPosition() + item, flags = self.HitTest(pos) + + bitmap_rect = self.GetBitmapRect() + if (bitmap_rect.InsideXY(pos.x, pos.y) or + flags & wx.TREE_HITTEST_NOWHERE) and self.AddMenu is not None: + self.PopupMenuXY(self.AddMenu, pos.x, pos.y) + event.Skip() + + def OnScroll(self, event): + print "scroll event" + self.RefreshBackground(True) event.Skip() def OnResize(self, event): diff -r 3216bf5f711d -r 629680fb0582 controls/EditorPanel.py --- a/controls/EditorPanel.py Sat May 19 12:40:53 2012 +0200 +++ b/controls/EditorPanel.py Mon May 21 09:59:44 2012 +0200 @@ -65,7 +65,7 @@ elif self.VariableEditor is not None: self.Initialize(self.VariableEditor) elif self.Editor is not None: - self.Initialize(self.Editor) + self.Initialize(self.Editor) def __init__(self, parent, tagname, window, controler, debug=False): self.ParentWindow = window diff -r 3216bf5f711d -r 629680fb0582 controls/PouInstanceVariablesPanel.py --- a/controls/PouInstanceVariablesPanel.py Sat May 19 12:40:53 2012 +0200 +++ b/controls/PouInstanceVariablesPanel.py Mon May 21 09:59:44 2012 +0200 @@ -48,6 +48,7 @@ size=wx.Size(0, 28), style=wx.CB_READONLY) self.Bind(wx.EVT_COMBOBOX, self.OnInstanceChoiceChanged, self.InstanceChoice) + self.InstanceChoice.Bind(wx.EVT_LEFT_DOWN, self.OnInstanceChoiceLeftDown) self.DebugButton = wx.lib.buttons.GenBitmapButton( name='DebugButton', parent=self, @@ -56,7 +57,7 @@ style=wx.NO_BORDER) self.Bind(wx.EVT_BUTTON, self.OnDebugButtonClick, self.DebugButton) - + self.VariablesList = CT.CustomTreeCtrl( name='VariablesList', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), @@ -66,12 +67,13 @@ CT.TR_HAS_VARIABLE_ROW_HEIGHT| CT.TR_HIDE_ROOT| CT.TR_NO_LINES| - CT.TR_ALIGN_WINDOWS_RIGHT) + getattr(CT, "TR_ALIGN_WINDOWS_RIGHT", CT.TR_ALIGN_WINDOWS)) self.VariablesList.SetIndent(0) self.VariablesList.SetSpacing(5) self.VariablesList.DoSelectItem = lambda *x,**y:True self.VariablesList.Bind(CT.EVT_TREE_ITEM_ACTIVATED, self.OnVariablesListItemActivated) + self.VariablesList.Bind(wx.EVT_LEFT_DOWN, self.OnVariablesListLeftDown) buttons_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0) buttons_sizer.AddWindow(self.ParentButton, 0, border=0, flag=0) @@ -106,7 +108,9 @@ def SetController(self, controller): self.Controller = controller - + + self.RefreshView() + def SetPouType(self, tagname, pou_instance=None): self.PouTagName = tagname if pou_instance is not None: @@ -115,6 +119,8 @@ self.RefreshView() def ResetView(self): + self.Controller = None + self.PouTagName = None self.PouInfos = None self.PouInstance = None @@ -124,6 +130,7 @@ def RefreshView(self): self.VariablesList.DeleteAllItems() self.InstanceChoice.Clear() + self.InstanceChoice.SetValue("") if self.PouTagName is not None: self.PouInfos = self.Controller.GetPouVariables(self.PouTagName, self.Debug) @@ -183,6 +190,8 @@ instances = self.Controller.SearchPouInstances(self.PouTagName, self.Debug) for instance in instances: self.InstanceChoice.Append(instance) + if len(instances) == 1: + self.PouInstance = instances[0] if self.PouInfos["class"] in [ITEM_CONFIGURATION, ITEM_RESOURCE]: self.PouInstance = None self.InstanceChoice.SetSelection(0) @@ -250,10 +259,21 @@ event.Skip() return GraphButtonCallback + def ShowInstanceChoicePopup(self): + self.InstanceChoice.SetFocusFromKbd() + size = self.InstanceChoice.GetSize() + event = wx.MouseEvent(wx.EVT_LEFT_DOWN._getEvtType()) + event.m_x = size.width / 2 + event.m_y = size.height / 2 + event.SetEventObject(self.InstanceChoice) + #event = wx.KeyEvent(wx.EVT_KEY_DOWN._getEvtType()) + #event.m_keyCode = wx.WXK_SPACE + self.InstanceChoice.GetEventHandler().ProcessEvent(event) + def OnParentButtonClick(self, event): if self.InstanceChoice.GetSelection() != -1: parent_path = self.InstanceChoice.GetStringSelection().rsplit(".", 1)[0] - tagname = self.Controller.GetPouInstanceTagname(parent_path, self.Debug) + tagname = self.Controller.GetPouInstanceTagName(parent_path, self.Debug) if tagname is not None: wx.CallAfter(self.SetPouType, tagname, parent_path) wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, tagname) @@ -277,7 +297,7 @@ selected_item = event.GetItem() if selected_item is not None and selected_item.IsOk(): item_infos = self.VariablesList.GetPyData(selected_item) - if item_infos["class"] not in ITEMS_VARIABLE: + if item_infos is not None and item_infos["class"] not in ITEMS_VARIABLE: if item_infos["class"] == ITEM_RESOURCE: tagname = self.Controller.ComputeConfigurationResourceName( instance_path, @@ -289,4 +309,10 @@ wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, tagname) event.Skip() - + def OnVariablesListLeftDown(self, event): + if self.InstanceChoice.GetSelection() == -1: + wx.CallAfter(self.ShowInstanceChoicePopup) + event.Skip() + + def OnInstanceChoiceLeftDown(self, event): + event.Skip() diff -r 3216bf5f711d -r 629680fb0582 graphics/FBD_Objects.py --- a/graphics/FBD_Objects.py Sat May 19 12:40:53 2012 +0200 +++ b/graphics/FBD_Objects.py Mon May 21 09:59:44 2012 +0200 @@ -263,6 +263,7 @@ self.Pen = MiterPen(self.Colour) # Extract the inputs properties and create or modify the corresponding connector + idx = 0 for idx, (input_name, input_type, input_modifier) in enumerate(inputs): if idx < len(self.Inputs): connector = self.Inputs[idx] @@ -280,6 +281,7 @@ self.Inputs = self.Inputs[:idx + 1] # Extract the outputs properties and create or modify the corresponding connector + idx = 0 for idx, (output_name, output_type, output_modifier) in enumerate(outputs): if idx < len(self.Outputs): connector = self.Outputs[idx] diff -r 3216bf5f711d -r 629680fb0582 plcopen/plcopen.py --- a/plcopen/plcopen.py Sat May 19 12:40:53 2012 +0200 +++ b/plcopen/plcopen.py Mon May 21 09:59:44 2012 +0200 @@ -234,8 +234,10 @@ self.contentHeader.setauthor(contentheader["authorName"]) if contentheader.has_key("language"): self.contentHeader.setlanguage(contentheader["language"]) - self.contentHeader.setpageSize(*contentheader["pageSize"]) - self.contentHeader.setscaling(contentheader["scaling"]) + if contentheader.has_key("pageSize"): + self.contentHeader.setpageSize(*contentheader["pageSize"]) + if contentheader.has_key("scaling"): + self.contentHeader.setscaling(contentheader["scaling"]) setattr(cls, "setcontentHeader", setcontentHeader) def getdataTypes(self):