296 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) |
297 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) |
297 if not self.ModeSolo: |
298 if not self.ModeSolo: |
298 self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=ID_PLCOPENEDITORFILEMENUITEMS5) |
299 self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=ID_PLCOPENEDITORFILEMENUITEMS5) |
299 accel = wx.AcceleratorTable([wx.AcceleratorEntry(wx.ACCEL_CTRL, 83, ID_PLCOPENEDITORFILEMENUITEMS5)]) |
300 accel = wx.AcceleratorTable([wx.AcceleratorEntry(wx.ACCEL_CTRL, 83, ID_PLCOPENEDITORFILEMENUITEMS5)]) |
300 self.SetAcceleratorTable(accel) |
301 self.SetAcceleratorTable(accel) |
301 self.Bind(wx.EVT_ACTIVATE, self.OnFrameActivated) |
|
302 |
302 |
303 self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER, |
303 self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER, |
304 name='MainSplitter', parent=self, point=wx.Point(0, 0), |
304 name='MainSplitter', parent=self, point=wx.Point(0, 0), |
305 size=wx.Size(0, 0), style=wx.SP_3D) |
305 size=wx.Size(0, 0), style=wx.SP_3D) |
306 self.MainSplitter.SetNeedUpdating(True) |
306 self.MainSplitter.SetNeedUpdating(True) |
441 new_values["creationDateTime"] = old_values["creationDateTime"] |
442 new_values["creationDateTime"] = old_values["creationDateTime"] |
442 self.Controler.SetProjectProperties(projectname, new_values) |
443 self.Controler.SetProjectProperties(projectname, new_values) |
443 self.RefreshProjectTree() |
444 self.RefreshProjectTree() |
444 dialog.Destroy() |
445 dialog.Destroy() |
445 |
446 |
446 def OnFrameActivated(self, event): |
|
447 if not self.ModeSolo and event.GetActive(): |
|
448 self.Controler.RefreshPluginsBlockLists() |
|
449 selected = self.TabsOpened.GetSelection() |
|
450 if selected >= 0: |
|
451 self.TabsOpened.GetPage(selected).RefreshView() |
|
452 event.Skip() |
|
453 |
|
454 def OnCloseFrame(self, event): |
447 def OnCloseFrame(self, event): |
455 if not self.ModeSolo and getattr(self, "_onclose", None) != None: |
448 if not self.ModeSolo and getattr(self, "_onclose", None) is not None: |
|
449 self.Controler.CloseAllElements() |
456 self._onclose() |
450 self._onclose() |
457 event.Skip() |
451 event.Skip() |
458 elif not self.Controler.ProjectIsSaved(): |
452 elif not self.Controler.ProjectIsSaved(): |
459 dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) |
453 dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) |
460 answer = dialog.ShowModal() |
454 answer = dialog.ShowModal() |
800 abort = True |
799 abort = True |
801 messageDialog.Destroy() |
800 messageDialog.Destroy() |
802 if not abort: |
801 if not abort: |
803 old_name = self.ProjectTree.GetItemText(item) |
802 old_name = self.ProjectTree.GetItemText(item) |
804 self.Controler.ChangePouName(old_name, new_name) |
803 self.Controler.ChangePouName(old_name, new_name) |
|
804 self.RefreshEditorNames(itemtype, old_name, new_name) |
805 self.RefreshTabsOpenedTitles() |
805 self.RefreshTabsOpenedTitles() |
806 elif itemtype == ITEM_TRANSITION: |
806 elif itemtype == ITEM_TRANSITION: |
807 category = self.ProjectTree.GetItemParent(item) |
807 parent = self.ProjectTree.GetItemParent(selected) |
808 pou = self.ProjectTree.GetItemParent(category) |
808 parent_type = self.ProjectTree.GetPyData(parent) |
809 pou_name = self.ProjectTree.GetItemText(pou) |
809 while parent_type != ITEM_POU: |
|
810 parent = self.ProjectTree.GetItemParent(parent) |
|
811 parent_type = self.ProjectTree.GetPyData(parent) |
|
812 pou_name = self.ProjectTree.GetItemText(parent) |
810 if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: |
813 if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: |
811 message = "A pou with \"%s\" as name exists!"%new_name |
814 message = "A pou with \"%s\" as name exists!"%new_name |
812 elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]: |
815 elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]: |
813 message = "A variable with \"%s\" as name already exists in this pou!"%new_name |
816 message = "A variable with \"%s\" as name already exists in this pou!"%new_name |
814 else: |
817 else: |
815 old_name = self.ProjectTree.GetItemText(item) |
818 old_name = self.ProjectTree.GetItemText(item) |
816 self.Controler.ChangePouTransitionName(pou_name, old_name, new_name) |
819 self.Controler.ChangePouTransitionName(pou_name, old_name, new_name) |
|
820 self.RefreshEditorNames(itemtype, old_name, new_name) |
817 self.RefreshTabsOpenedTitles() |
821 self.RefreshTabsOpenedTitles() |
818 elif itemtype == ITEM_ACTION: |
822 elif itemtype == ITEM_ACTION: |
819 category = self.ProjectTree.GetItemParent(item) |
823 parent = self.ProjectTree.GetItemParent(selected) |
820 pou = self.ProjectTree.GetItemParent(category) |
824 parent_type = self.ProjectTree.GetPyData(parent) |
821 pou_name = self.ProjectTree.GetItemText(pou) |
825 while parent_type != ITEM_POU: |
|
826 parent = self.ProjectTree.GetItemParent(parent) |
|
827 parent_type = self.ProjectTree.GetPyData(parent) |
|
828 pou_name = self.ProjectTree.GetItemText(parent) |
822 if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: |
829 if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: |
823 message = "A pou with \"%s\" as name exists!"%new_name |
830 message = "A pou with \"%s\" as name exists!"%new_name |
824 elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]: |
831 elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]: |
825 message = "A variable with \"%s\" as name already exists in this pou!"%new_name |
832 message = "A variable with \"%s\" as name already exists in this pou!"%new_name |
826 else: |
833 else: |
827 old_name = self.ProjectTree.GetItemText(item) |
834 old_name = self.ProjectTree.GetItemText(item) |
828 self.Controler.ChangePouActionName(pou_name, old_name, new_name) |
835 self.Controler.ChangePouActionName(pou_name, old_name, new_name) |
|
836 self.RefreshEditorNames(itemtype, old_name, new_name) |
|
837 self.RefreshTabsOpenedTitles() |
|
838 elif itemtype == ITEM_CONFIGURATION: |
|
839 if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]: |
|
840 message = "\"%s\" config already exists!"%new_name |
|
841 abort = True |
|
842 elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: |
|
843 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) |
|
844 if messageDialog.ShowModal() == wx.ID_NO: |
|
845 abort = True |
|
846 messageDialog.Destroy() |
|
847 elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]: |
|
848 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) |
|
849 if messageDialog.ShowModal() == wx.ID_NO: |
|
850 abort = True |
|
851 messageDialog.Destroy() |
|
852 if not abort: |
|
853 old_name = self.ProjectTree.GetItemText(item) |
|
854 self.Controler.ChangeConfigurationName(old_name, new_name) |
|
855 self.RefreshEditorNames(itemtype, old_name, new_name) |
|
856 self.RefreshTabsOpenedTitles() |
|
857 elif itemtype == ITEM_RESOURCE: |
|
858 parent = self.ProjectTree.GetItemParent(selected) |
|
859 parent_type = self.ProjectTree.GetPyData(parent) |
|
860 while parent_type != ITEM_CONFIGURATION: |
|
861 parent = self.ProjectTree.GetItemParent(parent) |
|
862 parent_type = self.ProjectTree.GetPyData(parent) |
|
863 config_name = self.ProjectTree.GetItemText(parent) |
|
864 if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]: |
|
865 message = "\"%s\" config already exists!"%new_name |
|
866 abort = True |
|
867 elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: |
|
868 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) |
|
869 if messageDialog.ShowModal() == wx.ID_NO: |
|
870 abort = True |
|
871 messageDialog.Destroy() |
|
872 elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]: |
|
873 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) |
|
874 if messageDialog.ShowModal() == wx.ID_NO: |
|
875 abort = True |
|
876 messageDialog.Destroy() |
|
877 if not abort: |
|
878 old_name = self.ProjectTree.GetItemText(item) |
|
879 self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name) |
|
880 self.RefreshEditorNames(itemtype, old_name, new_name) |
829 self.RefreshTabsOpenedTitles() |
881 self.RefreshTabsOpenedTitles() |
830 if message or abort: |
882 if message or abort: |
831 if message: |
883 if message: |
832 messageDialog = wx.MessageDialog(self, message, "Error", wx.OK|wx.ICON_ERROR) |
884 messageDialog = wx.MessageDialog(self, message, "Error", wx.OK|wx.ICON_ERROR) |
833 messageDialog.ShowModal() |
885 messageDialog.ShowModal() |
2086 if self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]: |
2132 if self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]: |
2087 grid.SetReadOnly(row, col, True) |
2133 grid.SetReadOnly(row, col, True) |
2088 else: |
2134 else: |
2089 editor = wx.grid.GridCellTextEditor() |
2135 editor = wx.grid.GridCellTextEditor() |
2090 renderer = wx.grid.GridCellStringRenderer() |
2136 renderer = wx.grid.GridCellStringRenderer() |
2091 elif colname in ["Initial Value","Location"]: |
2137 elif colname == "Initial Value": |
2092 editor = wx.grid.GridCellTextEditor() |
2138 editor = wx.grid.GridCellTextEditor() |
2093 renderer = wx.grid.GridCellStringRenderer() |
2139 renderer = wx.grid.GridCellStringRenderer() |
|
2140 elif colname == "Location": |
|
2141 if self.GetValueByName(row, "Class") in ["Local", "Global"]: |
|
2142 editor = wx.grid.GridCellTextEditor() |
|
2143 renderer = wx.grid.GridCellStringRenderer() |
|
2144 else: |
|
2145 grid.SetReadOnly(row, col, True) |
2094 elif colname == "Class": |
2146 elif colname == "Class": |
2095 if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]: |
2147 if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]: |
2096 grid.SetReadOnly(row, col, True) |
2148 grid.SetReadOnly(row, col, True) |
2097 else: |
2149 else: |
2098 editor = wx.grid.GridCellChoiceEditor() |
2150 editor = wx.grid.GridCellChoiceEditor() |
2148 col = self.ParentWindow.VariablesGrid.XToCol(x) |
2200 col = self.ParentWindow.VariablesGrid.XToCol(x) |
2149 row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize()) |
2201 row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize()) |
2150 if col != wx.NOT_FOUND and row != wx.NOT_FOUND: |
2202 if col != wx.NOT_FOUND and row != wx.NOT_FOUND: |
2151 if self.ParentWindow.Table.GetColLabelValue(col) != "Location": |
2203 if self.ParentWindow.Table.GetColLabelValue(col) != "Location": |
2152 return |
2204 return |
2153 try: |
2205 message = None |
2154 values = eval(data) |
2206 if not self.ParentWindow.Table.GetValueByName(row, "Edit"): |
2155 except: |
2207 message = "Can't affect a location to a function block instance" |
2156 values = None |
2208 elif self.ParentWindow.Table.GetValueByName(row, "Class") not in ["Local", "Global"]: |
2157 if values and values[1] == "location": |
2209 message = "Can affect a location only to local or global variables" |
2158 dialog = wx.SingleChoiceDialog(self.ParentWindow, "Select a variable class:", "Variable class", ["Input", "Output", "Memory"], wx.OK|wx.CANCEL) |
2210 else: |
2159 if dialog.ShowModal() == wx.ID_OK: |
2211 try: |
2160 selected = dialog.GetSelection() |
2212 values = eval(data) |
2161 if selected == 0: |
2213 except: |
2162 location = "%I" + values[0] |
2214 values = None |
2163 elif selected == 1: |
2215 if values and values[1] == "location": |
2164 location = "%Q" + values[0] |
2216 location = values[0] |
|
2217 variable_type = self.ParentWindow.Table.GetValueByName(row, "Type") |
|
2218 message = None |
|
2219 if location[0].isdigit() and variable_type != "BOOL": |
|
2220 message = "Incompatible size of data between \"%s\" and \"BOOL\""%location |
|
2221 elif location[0] not in LOCATIONDATATYPES: |
|
2222 message = "Unrecognized data size \"%s\""%location[0] |
|
2223 elif variable_type not in LOCATIONDATATYPES[location[0]]: |
|
2224 message = "Incompatible size of data between \"%s\" and \"%s\""%(location, variable_type) |
2165 else: |
2225 else: |
2166 location = "%M" + values[0] |
2226 dialog = wx.SingleChoiceDialog(self.ParentWindow, "Select a variable class:", "Variable class", ["Input", "Output", "Memory"], wx.OK|wx.CANCEL) |
2167 self.ParentWindow.Table.SetValue(row, col, location) |
2227 if dialog.ShowModal() == wx.ID_OK: |
2168 self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) |
2228 selected = dialog.GetSelection() |
2169 self.ParentWindow.SaveValues() |
2229 if selected == 0: |
2170 dialog.Destroy() |
2230 location = "%I" + location |
|
2231 elif selected == 1: |
|
2232 location = "%Q" + location |
|
2233 else: |
|
2234 location = "%M" + location |
|
2235 self.ParentWindow.Table.SetValue(row, col, location) |
|
2236 self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) |
|
2237 self.ParentWindow.SaveValues() |
|
2238 dialog.Destroy() |
|
2239 if message is not None: |
|
2240 message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR) |
|
2241 message.ShowModal() |
|
2242 message.Destroy() |
2171 |
2243 |
2172 [ID_POUEDITORPANEL, ID_POUEDITORPANELVIEWER, |
2244 [ID_POUEDITORPANEL, ID_POUEDITORPANELVIEWER, |
2173 ID_POUEDITORPANELVARIABLESGRID, ID_POUEDITORPANELRETURNTYPE, |
2245 ID_POUEDITORPANELVARIABLESGRID, ID_POUEDITORPANELRETURNTYPE, |
2174 ID_POUEDITORPANELCLASSFILTER, ID_POUEDITORPANELADDBUTTON, |
2246 ID_POUEDITORPANELCLASSFILTER, ID_POUEDITORPANELADDBUTTON, |
2175 ID_POUEDITORPANELDELETEBUTTON, ID_POUEDITORPANELUPBUTTON, |
2247 ID_POUEDITORPANELDELETEBUTTON, ID_POUEDITORPANELUPBUTTON, |
2287 size=wx.Size(0, 150), style=wx.VSCROLL) |
2359 size=wx.Size(0, 150), style=wx.VSCROLL) |
2288 self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, |
2360 self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, |
2289 'Sans')) |
2361 'Sans')) |
2290 self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, |
2362 self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, |
2291 False, 'Sans')) |
2363 False, 'Sans')) |
|
2364 self.VariablesGrid.SetSelectionBackground(wx.WHITE) |
|
2365 self.VariablesGrid.SetSelectionForeground(wx.BLACK) |
2292 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange) |
2366 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange) |
2293 self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell) |
2367 self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell) |
2294 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick) |
2368 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick) |
2295 self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnVariablesGridEditorShown) |
2369 self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnVariablesGridEditorShown) |
2296 self.VariablesGrid.SetDropTarget(VariableDropTarget(self)) |
2370 self.VariablesGrid.SetDropTarget(VariableDropTarget(self)) |
2391 self.staticText1.Hide() |
2465 self.staticText1.Hide() |
2392 self.ReturnType.Hide() |
2466 self.ReturnType.Hide() |
2393 |
2467 |
2394 self.VariablesGrid.SetTable(self.Table) |
2468 self.VariablesGrid.SetTable(self.Table) |
2395 self.VariablesGrid.SetRowLabelSize(0) |
2469 self.VariablesGrid.SetRowLabelSize(0) |
|
2470 for col in range(self.Table.GetNumberCols()): |
|
2471 attr = wx.grid.GridCellAttr() |
|
2472 attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) |
|
2473 self.VariablesGrid.SetColAttr(col, attr) |
|
2474 self.VariablesGrid.SetColSize(col, self.ColSizes[col]) |
|
2475 |
|
2476 def RefreshName(self, name_type, old_name, new_name): |
|
2477 if name_type == ITEM_POU and self.PouName == old_name: |
|
2478 self.PouName = new_name |
|
2479 elif name_type == ITEM_TRANSITION and self.TransitionName == old_name: |
|
2480 self.TransitionName = new_name |
|
2481 elif name_type == ITEM_ACTION and self.ActionName == old_name: |
|
2482 self.ActionName = new_name |
|
2483 elif name_type == ITEM_CONFIGURATION and self.ConfigName == old_name: |
|
2484 self.ConfigName = new_name |
|
2485 elif name_type == ITEM_RESOURCE and self.ResourceName == old_name: |
|
2486 self.ResourceName = new_name |
2396 |
2487 |
2397 def SetMode(self, mode): |
2488 def SetMode(self, mode): |
2398 if self.ElementType not in ["resource", "config"]: |
2489 if self.ElementType not in ["resource", "config"]: |
2399 if self.ElementType == "transition": |
2490 if self.ElementType == "transition": |
2400 language = self.Controler.GetTransitionBodyType(self.PouName, self.TransitionName) |
2491 language = self.Controler.GetTransitionBodyType(self.PouName, self.TransitionName) |