Adding support for direct array declaration in structure element declaration
authorLaurent Bessard
Sun, 21 Oct 2012 16:53:46 +0200
changeset 864 bf4f7f0801b9
parent 863 b1ead41fbd3b
child 865 c377a1d7767a
Adding support for direct array declaration in structure element declaration
PLCControler.py
PLCGenerator.py
editors/DataTypeEditor.py
--- a/PLCControler.py	Fri Oct 19 18:10:31 2012 +0200
+++ b/PLCControler.py	Sun Oct 21 16:53:46 2012 +0200
@@ -1210,8 +1210,8 @@
             for dimension in vartype_content["value"].getdimension():
                 dimensions.append((dimension.getlower(), dimension.getupper()))
             base_type = vartype_content["value"].baseType.getcontent()
-            if base_type["value"] is None:
-                base_type_name = base_type["name"]
+            if base_type["value"] is None or base_type["name"] in ["string", "wstring"]:
+                base_type_name = base_type["name"].upper()
             else:
                 base_type_name = base_type["value"].getname()
             tempvar["Type"] = ("array", base_type_name, dimensions)
@@ -1763,6 +1763,16 @@
                         element_type = element.type.getcontent()
                         if element_type["value"] is None or element_type["name"] in ["string", "wstring"]:
                             element_infos["Type"] = element_type["name"].upper()
+                        elif element_type["name"] == "array":
+                            dimensions = []
+                            for dimension in element_type["value"].getdimension():
+                                dimensions.append((dimension.getlower(), dimension.getupper()))
+                            base_type = element_type["value"].baseType.getcontent()
+                            if base_type["value"] is None or base_type["name"] in ["string", "wstring"]:
+                                base_type_name = base_type["name"].upper()
+                            else:
+                                base_type_name = base_type["value"].getname()
+                            element_infos["Type"] = ("array", base_type_name, dimensions)
                         else:
                             element_infos["Type"] = element_type["value"].getname()
                         if element.initialValue is not None:
@@ -1846,7 +1856,31 @@
                 for i, element_infos in enumerate(infos["elements"]):
                     element = plcopen.varListPlain_variable()
                     element.setname(element_infos["Name"])
-                    if element_infos["Type"] in self.GetBaseTypes():
+                    if isinstance(element_infos["Type"], TupleType):
+                        if element_infos["Type"][0] == "array":
+                            array_type, base_type_name, dimensions = element_infos["Type"]
+                            array = plcopen.derivedTypes_array()
+                            for j, dimension in enumerate(dimensions):
+                                dimension_range = plcopen.rangeSigned()
+                                dimension_range.setlower(dimension[0])
+                                dimension_range.setupper(dimension[1])
+                                if j == 0:
+                                    array.setdimension([dimension_range])
+                                else:
+                                    array.appenddimension(dimension_range)
+                            if base_type_name in self.GetBaseTypes():
+                                if base_type_name == "STRING":
+                                    array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
+                                elif base_type_name == "WSTRING":
+                                    array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
+                                else:
+                                    array.baseType.setcontent({"name" : base_type_name, "value" : None})
+                            else:
+                                derived_datatype = plcopen.derivedTypes_derived()
+                                derived_datatype.setname(base_type_name)
+                                array.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
+                            element.type.setcontent({"name" : "array", "value" : array})
+                    elif element_infos["Type"] in self.GetBaseTypes():
                         if element_infos["Type"] == "STRING":
                             element.type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
                         elif element_infos["Type"] == "WSTRING":
--- a/PLCGenerator.py	Fri Oct 19 18:10:31 2012 +0200
+++ b/PLCGenerator.py	Sun Oct 21 16:53:46 2012 +0200
@@ -192,6 +192,21 @@
                     if element_type["name"] == "derived":
                         elementtype_name = element_type["value"].getname()
                         self.GenerateDataType(elementtype_name)
+                    elif element_type["name"] == "array":
+                        base_type = element_type["value"].baseType.getcontent()
+                        # Array derived directly from a user defined type 
+                        if base_type["name"] == "derived":
+                            basetype_name = base_type["value"].getname()
+                            self.GenerateDataType(basetype_name)
+                        # Array derived directly from a string type 
+                        elif base_type["name"] in ["string", "wstring"]:
+                            basetype_name = base_type["name"].upper()
+                        # Array derived directly from an elementary type 
+                        else:
+                            basetype_name = base_type["name"]
+                        dimensions = ["%s..%s" % (dimension.getlower(), dimension.getupper())
+                                      for dimension in element_type["value"].getdimension()]
+                        elementtype_name = "ARRAY [%s] OF %s" % (",".join(dimensions), basetype_name)
                     # Structure element derived directly from a string type 
                     elif element_type["name"] in ["string", "wstring"]:
                         elementtype_name = element_type["name"].upper()
--- a/editors/DataTypeEditor.py	Fri Oct 19 18:10:31 2012 +0200
+++ b/editors/DataTypeEditor.py	Sun Oct 21 16:53:46 2012 +0200
@@ -23,6 +23,7 @@
 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 import re
+from types import TupleType
 
 import wx
 import wx.grid
@@ -31,6 +32,7 @@
 from plcopen.structures import IEC_KEYWORDS, TestIdentifier
 from graphics.GraphicCommons import REFRESH_HIGHLIGHT_PERIOD
 from controls import CustomEditableListBox, CustomGrid, CustomTable
+from dialogs import ArrayTypeDialog
 from EditorPanel import EditorPanel
 from util.BitmapLibrary import GetBitmap
 
@@ -70,8 +72,12 @@
         if row < self.GetNumberRows():
             if col == 0:
                 return row + 1
-            name = str(self.data[row].get(self.GetColLabelValue(col, False), ""))
-            return name
+            colname = self.GetColLabelValue(col, False)
+            value = self.data[row].get(colname, "")
+            if colname == "Type" and isinstance(value, TupleType):
+                if value[0] == "array":
+                    return "ARRAY [%s] OF %s" % (",".join(map(lambda x : "..".join(x), value[2])), value[1])
+            return str(value)
     
     def SetValue(self, row, col, value):
         if col < len(self.colnames):
@@ -609,18 +615,25 @@
         row, col = event.GetRow(), event.GetCol() 
         if self.StructureElementsTable.GetColLabelValue(col) == "Type":
             type_menu = wx.Menu(title='')
+            
             base_menu = wx.Menu(title='')
             for base_type in self.Controler.GetBaseTypes():
                 new_id = wx.NewId()
                 AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type)
                 self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(base_type), id=new_id)
             type_menu.AppendMenu(wx.NewId(), _("Base Types"), base_menu)
+            
             datatype_menu = wx.Menu(title='')
             for datatype in self.Controler.GetDataTypes(self.TagName, False):
                 new_id = wx.NewId()
                 AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
                 self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(datatype), id=new_id)
             type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu)
+            
+            new_id = wx.NewId()
+            AppendMenu(type_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Array"))
+            self.Bind(wx.EVT_MENU, self.ElementArrayTypeFunction, id=new_id)
+            
 ##            functionblock_menu = wx.Menu(title='')
 ##            bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
 ##            pouname, poutype = self.Controler.GetEditedElementType(self.TagName)
@@ -630,6 +643,7 @@
 ##                    AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type)
 ##                    self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id)
 ##                type_menu.AppendMenu(wx.NewId(), _("Function Block Types"), functionblock_menu)
+
             rect = self.StructureElementsGrid.BlockToDeviceRect((row, col), (row, col))
             self.StructureElementsGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.StructureElementsGrid.GetColLabelSize())
             type_menu.Destroy()
@@ -645,6 +659,17 @@
             self.StructureElementsTable.ResetView(self.StructureElementsGrid)
         return ElementTypeFunction
 
+    def ElementArrayTypeFunction(self, event):
+        row = self.StructureElementsGrid.GetGridCursorRow()
+        dialog = ArrayTypeDialog(self, 
+                                 self.Controler.GetDataTypes(self.TagName), 
+                                 self.StructureElementsTable.GetValueByName(row, "Type"))
+        if dialog.ShowModal() == wx.ID_OK:
+            self.StructureElementsTable.SetValueByName(row, "Type", dialog.GetValue())
+            self.RefreshTypeInfos()
+            self.StructureElementsTable.ResetView(self.StructureElementsGrid)
+        dialog.Destroy()
+
     def RefreshDisplayedInfos(self):
         selected = DATATYPE_TYPES_DICT[self.DerivationType.GetStringSelection()]
         if selected != self.CurrentPanel: