PLCOpenEditor.py
changeset 107 255eada20688
parent 102 85875dcb7754
child 108 9aa1fdfb7cb2
--- a/PLCOpenEditor.py	Fri Oct 05 18:11:27 2007 +0200
+++ b/PLCOpenEditor.py	Fri Oct 05 18:11:51 2007 +0200
@@ -34,6 +34,7 @@
 from RessourceEditor import *
 from PLCControler import *
 from plcopen import OpenPDFDoc
+from plcopen.structures import LOCATIONDATATYPES
 
 import os, re, platform, sys, time, traceback, getopt
 
@@ -298,7 +299,6 @@
             self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=ID_PLCOPENEDITORFILEMENUITEMS5)
             accel = wx.AcceleratorTable([wx.AcceleratorEntry(wx.ACCEL_CTRL, 83, ID_PLCOPENEDITORFILEMENUITEMS5)])
             self.SetAcceleratorTable(accel)
-            self.Bind(wx.EVT_ACTIVATE, self.OnFrameActivated)
         
         self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER,
               name='MainSplitter', parent=self, point=wx.Point(0, 0),
@@ -356,6 +356,7 @@
                 self.RefreshProjectTree()
         else:
             self.Controler = controler
+            self.RefreshProjectTree()
         
         self.CurrentToolBar = []
         self.CurrentLanguage = ""
@@ -443,16 +444,9 @@
             self.RefreshProjectTree()
         dialog.Destroy()
 
-    def OnFrameActivated(self, event):
-        if not self.ModeSolo and event.GetActive():
-            self.Controler.RefreshPluginsBlockLists()
-            selected = self.TabsOpened.GetSelection()
-            if selected >= 0:
-                self.TabsOpened.GetPage(selected).RefreshView()
-        event.Skip()
-
     def OnCloseFrame(self, event):
-        if not self.ModeSolo and getattr(self, "_onclose", None) != None:
+        if not self.ModeSolo and getattr(self, "_onclose", None) is not None:
+            self.Controler.CloseAllElements()
             self._onclose()
             event.Skip()
         elif not self.Controler.ProjectIsSaved():
@@ -776,6 +770,11 @@
                 dragSource.SetData(data)
                 dragSource.DoDragDrop()
 
+    def RefreshEditorNames(self, item_type, old_name, new_name):
+        for i in xrange(self.TabsOpened.GetPageCount()):
+            editor = self.TabsOpened.GetPage(i)
+            editor.RefreshName(item_type, old_name, new_name)
+
     def OnProjectTreeItemEndEdit(self, event):
         message = None
         abort = False
@@ -802,11 +801,15 @@
                     if not abort:
                         old_name = self.ProjectTree.GetItemText(item)
                         self.Controler.ChangePouName(old_name, new_name)
+                        self.RefreshEditorNames(itemtype, old_name, new_name)
                         self.RefreshTabsOpenedTitles()
                 elif itemtype == ITEM_TRANSITION:
-                    category = self.ProjectTree.GetItemParent(item)
-                    pou = self.ProjectTree.GetItemParent(category)
-                    pou_name = self.ProjectTree.GetItemText(pou)
+                    parent = self.ProjectTree.GetItemParent(selected)
+                    parent_type = self.ProjectTree.GetPyData(parent)
+                    while parent_type != ITEM_POU:
+                        parent = self.ProjectTree.GetItemParent(parent)
+                        parent_type = self.ProjectTree.GetPyData(parent)
+                    pou_name = self.ProjectTree.GetItemText(parent)
                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
                         message = "A pou with \"%s\" as name exists!"%new_name
                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]:
@@ -814,11 +817,15 @@
                     else:
                         old_name = self.ProjectTree.GetItemText(item)
                         self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
+                        self.RefreshEditorNames(itemtype, old_name, new_name)
                         self.RefreshTabsOpenedTitles()
                 elif itemtype == ITEM_ACTION:
-                    category = self.ProjectTree.GetItemParent(item)
-                    pou = self.ProjectTree.GetItemParent(category)
-                    pou_name = self.ProjectTree.GetItemText(pou)
+                    parent = self.ProjectTree.GetItemParent(selected)
+                    parent_type = self.ProjectTree.GetPyData(parent)
+                    while parent_type != ITEM_POU:
+                        parent = self.ProjectTree.GetItemParent(parent)
+                        parent_type = self.ProjectTree.GetPyData(parent)
+                    pou_name = self.ProjectTree.GetItemText(parent)
                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
                         message = "A pou with \"%s\" as name exists!"%new_name
                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]:
@@ -826,6 +833,51 @@
                     else:
                         old_name = self.ProjectTree.GetItemText(item)
                         self.Controler.ChangePouActionName(pou_name, old_name, new_name)
+                        self.RefreshEditorNames(itemtype, old_name, new_name)
+                        self.RefreshTabsOpenedTitles()
+                elif itemtype == ITEM_CONFIGURATION:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
+                        message = "\"%s\" config already exists!"%new_name
+                        abort = True
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+                        messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
+                        if messageDialog.ShowModal() == wx.ID_NO:
+                            abort = True
+                        messageDialog.Destroy()
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+                        messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
+                        if messageDialog.ShowModal() == wx.ID_NO:
+                            abort = True
+                        messageDialog.Destroy()
+                    if not abort:
+                        old_name = self.ProjectTree.GetItemText(item)
+                        self.Controler.ChangeConfigurationName(old_name, new_name)
+                        self.RefreshEditorNames(itemtype, old_name, new_name)
+                        self.RefreshTabsOpenedTitles()
+                elif itemtype == ITEM_RESOURCE:
+                    parent = self.ProjectTree.GetItemParent(selected)
+                    parent_type = self.ProjectTree.GetPyData(parent)
+                    while parent_type != ITEM_CONFIGURATION:
+                        parent = self.ProjectTree.GetItemParent(parent)
+                        parent_type = self.ProjectTree.GetPyData(parent)
+                    config_name = self.ProjectTree.GetItemText(parent)
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
+                        message = "\"%s\" config already exists!"%new_name
+                        abort = True
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+                        messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
+                        if messageDialog.ShowModal() == wx.ID_NO:
+                            abort = True
+                        messageDialog.Destroy()
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+                        messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
+                        if messageDialog.ShowModal() == wx.ID_NO:
+                            abort = True
+                        messageDialog.Destroy()
+                    if not abort:
+                        old_name = self.ProjectTree.GetItemText(item)
+                        self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name)
+                        self.RefreshEditorNames(itemtype, old_name, new_name)
                         self.RefreshTabsOpenedTitles()
             if message or abort:
                 if message:
@@ -1102,8 +1154,8 @@
                 for i in xrange(self.TabsOpened.GetPageCount()):
                     if self.TabsOpened.GetPageText(i) == selected:
                         deleted = i
-                if deleted != None:
-                    self.TabsOpened.DeletePage(i)
+                if deleted is not None:
+                    self.TabsOpened.DeletePage(deleted)
                 self.RefreshTitle()
                 self.RefreshEditMenu()
                 self.RefreshProjectTree()
@@ -2067,12 +2119,6 @@
         Otherwise default to the default renderer.
         """
         
-        for col in range(self.GetNumberCols()):
-            attr = wx.grid.GridCellAttr()
-            attr.SetAlignment(self.Parent.ColAlignements[col], wx.ALIGN_CENTRE)
-            grid.SetColAttr(col, attr)
-            grid.SetColSize(col, self.Parent.ColSizes[col])
-        
         typelist = None
         accesslist = None
         for row in range(self.GetNumberRows()):
@@ -2088,9 +2134,15 @@
                         else:
                             editor = wx.grid.GridCellTextEditor()
                             renderer = wx.grid.GridCellStringRenderer()
-                    elif colname in ["Initial Value","Location"]:
+                    elif colname == "Initial Value":
                         editor = wx.grid.GridCellTextEditor()
                         renderer = wx.grid.GridCellStringRenderer()
+                    elif colname == "Location":
+                        if self.GetValueByName(row, "Class") in ["Local", "Global"]:
+                            editor = wx.grid.GridCellTextEditor()
+                            renderer = wx.grid.GridCellStringRenderer()
+                        else:
+                            grid.SetReadOnly(row, col, True)
                     elif colname == "Class":
                         if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
                             grid.SetReadOnly(row, col, True)
@@ -2150,24 +2202,44 @@
         if col != wx.NOT_FOUND and row != wx.NOT_FOUND:
             if self.ParentWindow.Table.GetColLabelValue(col) != "Location":
                 return
-            try:
-                values = eval(data)    
-            except:
-                values = None
-            if values and values[1] == "location":
-                dialog = wx.SingleChoiceDialog(self.ParentWindow, "Select a variable class:", "Variable class", ["Input", "Output", "Memory"], wx.OK|wx.CANCEL)
-                if dialog.ShowModal() == wx.ID_OK:
-                    selected = dialog.GetSelection()
-                    if selected == 0:
-                        location = "%I" + values[0]
-                    elif selected == 1:
-                        location = "%Q" + values[0]
+            message = None
+            if not self.ParentWindow.Table.GetValueByName(row, "Edit"):
+                message = "Can't affect a location to a function block instance"
+            elif self.ParentWindow.Table.GetValueByName(row, "Class") not in ["Local", "Global"]:
+                message = "Can affect a location only to local or global variables"
+            else:
+                try:
+                    values = eval(data)    
+                except:
+                    values = None
+                if values and values[1] == "location":
+                    location = values[0]
+                    variable_type = self.ParentWindow.Table.GetValueByName(row, "Type")
+                    message = None
+                    if location[0].isdigit() and variable_type != "BOOL":
+                        message = "Incompatible size of data between \"%s\" and \"BOOL\""%location
+                    elif location[0] not in LOCATIONDATATYPES:
+                        message = "Unrecognized data size \"%s\""%location[0]
+                    elif variable_type not in LOCATIONDATATYPES[location[0]]:
+                        message = "Incompatible size of data between \"%s\" and \"%s\""%(location, variable_type)
                     else:
-                        location = "%M" + values[0]
-                    self.ParentWindow.Table.SetValue(row, col, location)
-                    self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
-                    self.ParentWindow.SaveValues()
-                dialog.Destroy()    
+                        dialog = wx.SingleChoiceDialog(self.ParentWindow, "Select a variable class:", "Variable class", ["Input", "Output", "Memory"], wx.OK|wx.CANCEL)
+                        if dialog.ShowModal() == wx.ID_OK:
+                            selected = dialog.GetSelection()
+                            if selected == 0:
+                                location = "%I" + location
+                            elif selected == 1:
+                                location = "%Q" + location
+                            else:
+                                location = "%M" + location
+                            self.ParentWindow.Table.SetValue(row, col, location)
+                            self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
+                            self.ParentWindow.SaveValues()
+                        dialog.Destroy()
+            if message is not None:
+                message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR)
+                message.ShowModal()
+                message.Destroy()
 
 [ID_POUEDITORPANEL, ID_POUEDITORPANELVIEWER, 
  ID_POUEDITORPANELVARIABLESGRID, ID_POUEDITORPANELRETURNTYPE, 
@@ -2289,6 +2361,8 @@
               'Sans'))
         self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
               False, 'Sans'))
+        self.VariablesGrid.SetSelectionBackground(wx.WHITE)
+        self.VariablesGrid.SetSelectionForeground(wx.BLACK)
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell)
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick)
@@ -2393,6 +2467,23 @@
         
         self.VariablesGrid.SetTable(self.Table)
         self.VariablesGrid.SetRowLabelSize(0)
+        for col in range(self.Table.GetNumberCols()):
+            attr = wx.grid.GridCellAttr()
+            attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE)
+            self.VariablesGrid.SetColAttr(col, attr)
+            self.VariablesGrid.SetColSize(col, self.ColSizes[col])
+    
+    def RefreshName(self, name_type, old_name, new_name):
+        if name_type == ITEM_POU and self.PouName == old_name:
+            self.PouName = new_name
+        elif name_type == ITEM_TRANSITION and self.TransitionName == old_name:
+            self.TransitionName = new_name
+        elif name_type == ITEM_ACTION and self.ActionName == old_name:
+            self.ActionName = new_name
+        elif name_type == ITEM_CONFIGURATION and self.ConfigName == old_name:
+            self.ConfigName = new_name
+        elif name_type == ITEM_RESOURCE and self.ResourceName == old_name:
+            self.ResourceName = new_name
     
     def SetMode(self, mode):
         if self.ElementType not in ["resource", "config"]:
@@ -2552,6 +2643,8 @@
                 event.Skip()
         else:
             self.SaveValues()
+            if colname == "Class":
+                self.Table.ResetView(self.VariablesGrid)
             event.Skip()
 
     def OnVariablesGridCellLeftClick(self, event):