PLCOpenEditor.py
changeset 390 020420ad8914
parent 384 ed27a676d5c9
child 391 07447ee3538e
equal deleted inserted replaced
389:6a72016d721a 390:020420ad8914
    62  ID_PLCOPENEDITORTOOLBAR, ID_PLCOPENEDITORDEFAULTTOOLBAR, 
    62  ID_PLCOPENEDITORTOOLBAR, ID_PLCOPENEDITORDEFAULTTOOLBAR, 
    63  ID_PLCOPENEDITORSFCTOOLBAR, ID_PLCOPENEDITORFBDTOOLBAR, 
    63  ID_PLCOPENEDITORSFCTOOLBAR, ID_PLCOPENEDITORFBDTOOLBAR, 
    64  ID_PLCOPENEDITORLDTOOLBAR,
    64  ID_PLCOPENEDITORLDTOOLBAR,
    65 ] = [wx.NewId() for _init_ctrls in range(17)]
    65 ] = [wx.NewId() for _init_ctrls in range(17)]
    66 
    66 
       
    67 # Define PLCOpenEditor FileMenu extra items id
    67 [ID_PLCOPENEDITORFILEMENUGENERATE, 
    68 [ID_PLCOPENEDITORFILEMENUGENERATE, 
    68 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)]
    69 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)]
    69 
    70 
       
    71 # Define PLCOpenEditor EditMenu extra items id
    70 [ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE, 
    72 [ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, ID_PLCOPENEDITOREDITMENUADDDATATYPE, 
    71  ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, 
    73  ID_PLCOPENEDITOREDITMENUADDFUNCTION, ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, 
    72  ID_PLCOPENEDITOREDITMENUADDPROGRAM, ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, 
    74  ID_PLCOPENEDITOREDITMENUADDPROGRAM, ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, 
    73 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(6)]
    75 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(6)]
    74 
    76 
    75 
    77 
    76 #-------------------------------------------------------------------------------
    78 #-------------------------------------------------------------------------------
    77 #                            ToolBars definitions
    79 #                            ToolBars definitions
    78 #-------------------------------------------------------------------------------
    80 #-------------------------------------------------------------------------------
    79 
    81 
    80 
    82 # Define PLCOpenEditor Toolbar items id
    81 [ID_PLCOPENEDITORTOOLBARSELECTION, ID_PLCOPENEDITORTOOLBARCOMMENT,
    83 [ID_PLCOPENEDITORTOOLBARSELECTION, ID_PLCOPENEDITORTOOLBARCOMMENT,
    82  ID_PLCOPENEDITORTOOLBARVARIABLE, ID_PLCOPENEDITORTOOLBARBLOCK,
    84  ID_PLCOPENEDITORTOOLBARVARIABLE, ID_PLCOPENEDITORTOOLBARBLOCK,
    83  ID_PLCOPENEDITORTOOLBARCONNECTION, ID_PLCOPENEDITORTOOLBARWIRE,
    85  ID_PLCOPENEDITORTOOLBARCONNECTION, ID_PLCOPENEDITORTOOLBARWIRE,
    84  ID_PLCOPENEDITORTOOLBARPOWERRAIL, ID_PLCOPENEDITORTOOLBARRUNG,
    86  ID_PLCOPENEDITORTOOLBARPOWERRAIL, ID_PLCOPENEDITORTOOLBARRUNG,
    85  ID_PLCOPENEDITORTOOLBARCOIL, ID_PLCOPENEDITORTOOLBARCONTACT,
    87  ID_PLCOPENEDITORTOOLBARCOIL, ID_PLCOPENEDITORTOOLBARCONTACT,
    87  ID_PLCOPENEDITORTOOLBARSTEP, ID_PLCOPENEDITORTOOLBARTRANSITION,
    89  ID_PLCOPENEDITORTOOLBARSTEP, ID_PLCOPENEDITORTOOLBARTRANSITION,
    88  ID_PLCOPENEDITORTOOLBARACTIONBLOCK, ID_PLCOPENEDITORTOOLBARDIVERGENCE,
    90  ID_PLCOPENEDITORTOOLBARACTIONBLOCK, ID_PLCOPENEDITORTOOLBARDIVERGENCE,
    89  ID_PLCOPENEDITORTOOLBARJUMP,
    91  ID_PLCOPENEDITORTOOLBARJUMP,
    90 ] = [wx.NewId() for _init_coll_DefaultToolBar_Items in range(17)]
    92 ] = [wx.NewId() for _init_coll_DefaultToolBar_Items in range(17)]
    91 
    93 
       
    94 # Define behaviour of each Toolbar item according to current POU body type 
       
    95 # Informations meaning are in this order:
       
    96 #  - Item is toggled
       
    97 #  - PLCOpenEditor mode where item is displayed (could be more then one)
       
    98 #  - Item id
       
    99 #  - Item callback function name
       
   100 #  - Item icon filename
       
   101 #  - Item tooltip text
    92 ToolBarItems = {
   102 ToolBarItems = {
    93     "FBD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
   103     "FBD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
    94               ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool",
   104               ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool",
    95               "add_comment.png", "Create a new comment"),
   105               "add_comment.png", "Create a new comment"),
    96              (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
   106              (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE,
   167               "add_contact.png", "Create a new contact")],
   177               "add_contact.png", "Create a new contact")],
   168     "ST"  : [],
   178     "ST"  : [],
   169     "IL"  : []
   179     "IL"  : []
   170 }
   180 }
   171 
   181 
       
   182 #-------------------------------------------------------------------------------
       
   183 #                               Helper Functions
       
   184 #-------------------------------------------------------------------------------
       
   185 
       
   186 # Compatibility function for wx versions < 2.6
   172 def AppendMenu(parent, help, id, kind, text):
   187 def AppendMenu(parent, help, id, kind, text):
   173     if wx.VERSION >= (2, 6, 0):
   188     if wx.VERSION >= (2, 6, 0):
   174         parent.Append(help=help, id=id, kind=kind, text=text)
   189         parent.Append(help=help, id=id, kind=kind, text=text)
   175     else:
   190     else:
   176         parent.Append(helpString=help, id=id, kind=kind, item=text)
   191         parent.Append(helpString=help, id=id, kind=kind, item=text)
       
   192 
       
   193 [TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, TYPESTREE, 
       
   194  INSTANCESTREE, LIBRARYTREE, SCALING
       
   195 ] = [wx.NewId() for _refresh_elements in range(9)]
       
   196 
       
   197 def GetShortcutKeyCallbackFunction(viewer_function):
       
   198     def ShortcutKeyFunction(self, event):
       
   199         control = self.FindFocus()
       
   200         if isinstance(control, (Viewer, TextViewer)):
       
   201             getattr(control, viewer_function)()
       
   202         elif isinstance(control, wx.TextCtrl):
       
   203             control.ProcessEvent(event)
       
   204         event.Skip()
       
   205     return ShortcutKeyFunction
       
   206 
       
   207 def GetParentName(tree, item, parent_type):
       
   208     parent_item = tree.GetItemParent(item)
       
   209     parent_item_type = tree.GetPyData(parent_item)
       
   210     while parent_item_type != parent_type:
       
   211         parent_item = tree.GetItemParent(parent_item)
       
   212         parent_item_type = tree.GetPyData(parent_item)
       
   213     return tree.GetItemText(parent_item)
       
   214 
       
   215 def GetDeleteElementFunction(remove_function, parent_type=None, check_function=None):
       
   216     def DeleteElementFunction(self, selected):
       
   217         name = self.TypesTree.GetItemText(selected)
       
   218         if check_function is None or not check_function(self.Controler, name, self.Debug):
       
   219             if parent_type is not None:
       
   220                 parent_name = GetParentName(self.TypesTree, selected, parent_type)
       
   221                 remove_function(self.Controler, parent_name, name)
       
   222             else:
       
   223                 remove_function(self.Controler, name)
       
   224         else:
       
   225             self.ShowErrorMessage("\"%s\" is used by one or more POUs. It can't be removed!"%name)
       
   226     return DeleteElementFunction
       
   227 
       
   228 #-------------------------------------------------------------------------------
       
   229 #                            PLCOpenEditor Main Class
       
   230 #-------------------------------------------------------------------------------
   177 
   231 
   178 class PLCOpenEditor(wx.Frame):
   232 class PLCOpenEditor(wx.Frame):
   179     
   233     
   180     # Compatibility function for wx versions < 2.6
   234     # Compatibility function for wx versions < 2.6
   181     if wx.VERSION < (2, 6, 0):
   235     if wx.VERSION < (2, 6, 0):
   428         
   482         
   429         self.InstancesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORINSTANCESTREE,
   483         self.InstancesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORINSTANCESTREE,
   430                   name='InstancesTree', parent=self.TreeNoteBook, 
   484                   name='InstancesTree', parent=self.TreeNoteBook, 
   431                   pos=wx.Point(0, 0), size=wx.Size(0, 0),
   485                   pos=wx.Point(0, 0), size=wx.Size(0, 0),
   432                   style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
   486                   style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
       
   487         
       
   488         self.TabsImageList = wx.ImageList(16, 31)
       
   489         self.TabsImageListIndexes = {}
       
   490         
   433         if self.Debug:
   491         if self.Debug:
   434             if wx.VERSION >= (2, 6, 0):
   492             if wx.VERSION >= (2, 6, 0):
   435                 self.InstancesTree.Bind(wx.EVT_RIGHT_UP, self.OnInstancesTreeRightUp)
   493                 self.InstancesTree.Bind(wx.EVT_RIGHT_UP, self.OnInstancesTreeRightUp)
   436             else:
   494             else:
   437                 wx.EVT_RIGHT_UP(self.InstancesTree, self.OnInstancesTreeRightUp)
   495                 wx.EVT_RIGHT_UP(self.InstancesTree, self.OnInstancesTreeRightUp)
   538                 self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.VariablePanelIndexer, -200)
   596                 self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.VariablePanelIndexer, -200)
   539                 
   597                 
   540                 self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED,
   598                 self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED,
   541                       name='TabsOpened', parent=self.ThirdSplitter, pos=wx.Point(0,
   599                       name='TabsOpened', parent=self.ThirdSplitter, pos=wx.Point(0,
   542                       0), size=wx.Size(0, 0), style=0)
   600                       0), size=wx.Size(0, 0), style=0)
   543                 self.TabsImageList = wx.ImageList(16, 31)
       
   544                 self.TabsOpened.SetImageList(self.TabsImageList)
   601                 self.TabsOpened.SetImageList(self.TabsImageList)
   545                 self.TabsImageListIndexes = {}
       
   546                 if wx.VERSION >= (2, 6, 0):
   602                 if wx.VERSION >= (2, 6, 0):
   547                     self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
   603                     self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
   548                         self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED)
   604                         self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED)
   549                 else:
   605                 else:
   550                     wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED,
   606                     wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED,
   577             self._init_sizers()
   633             self._init_sizers()
   578         
   634         
   579         if USE_AUI:
   635         if USE_AUI:
   580             self.AUIManager.Update()
   636             self.AUIManager.Update()
   581     
   637     
       
   638     ## Constructor of the PLCOpenEditor class.
       
   639     #  @param parent The parent window.
       
   640     #  @param controler The controler been used by PLCOpenEditor (default: None).
       
   641     #  @param fileOpen The filepath to open if no controler defined (default: None).
       
   642     #  @param debug The filepath to open if no controler defined (default: False).
   582     def __init__(self, parent, controler = None, fileOpen = None, debug = False):
   643     def __init__(self, parent, controler = None, fileOpen = None, debug = False):
       
   644         # Variable indicating that PLCOpenEditor was opened with a defined controler
   583         self.ModeSolo = controler == None
   645         self.ModeSolo = controler == None
   584         self.Debug = debug
   646         self.Debug = debug
   585         if self.ModeSolo:
   647         if self.ModeSolo:
       
   648             # If no controler defined, create a new one
   586             self.Controler = PLCControler()
   649             self.Controler = PLCControler()
       
   650             # Open the filepath if defined
   587             if fileOpen is not None:
   651             if fileOpen is not None:
   588                 self.Controler.OpenXMLFile(fileOpen)
   652                 self.Controler.OpenXMLFile(fileOpen)
   589         else:
   653         else:
   590             self.Controler = controler
   654             self.Controler = controler
   591         
   655         
   592         self._init_ctrls(parent)
   656         self._init_ctrls(parent)
   593         
   657         
   594         self.SetIcon(wx.Icon(os.path.join(CWD,"Images","poe.ico"),wx.BITMAP_TYPE_ICO))
   658         # Define PLCOpenEditor icon
   595         
   659         self.SetIcon(wx.Icon(os.path.join(CWD,"Images", "poe.ico"),wx.BITMAP_TYPE_ICO))
   596         self.TypesTreeImageList = wx.ImageList(16, 16)
   660         
   597         self.InstancesTreeImageList = wx.ImageList(16, 16)
   661         # Define Tree item icon list
   598         self.TypesTreeImageDict = {}
   662         self.TreeImageList = wx.ImageList(16, 16)
   599         self.InstancesTreeImageDict = {}
   663         self.TreeImageDict = {}
       
   664         
       
   665         # Icons for languages
   600         for language in LANGUAGES:
   666         for language in LANGUAGES:
   601             self.TypesTreeImageDict[language]=self.TypesTreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%language)))
   667             self.TreeImageDict[language]=self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%language)))
   602             self.InstancesTreeImageDict[language]=self.InstancesTreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%language)))
   668             
   603         
   669         # Icons for other items
   604         for imgname, itemtype in [
   670         for imgname, itemtype in [
   605             #editables
   671             #editables
   606             ("PROJECT",        ITEM_PROJECT),
   672             ("PROJECT",        ITEM_PROJECT),
   607             #("POU",            ITEM_POU),
   673             #("POU",            ITEM_POU),
   608             #("VARIABLE",       ITEM_VARIABLE),
   674             #("VARIABLE",       ITEM_VARIABLE),
   626             ("TRANSITIONS",    ITEM_TRANSITIONS),
   692             ("TRANSITIONS",    ITEM_TRANSITIONS),
   627             ("ACTIONS",        ITEM_ACTIONS),
   693             ("ACTIONS",        ITEM_ACTIONS),
   628             ("CONFIGURATIONS", ITEM_CONFIGURATIONS),
   694             ("CONFIGURATIONS", ITEM_CONFIGURATIONS),
   629             ("RESOURCES",      ITEM_RESOURCES),
   695             ("RESOURCES",      ITEM_RESOURCES),
   630             ("PROPERTIES",     ITEM_PROPERTIES)]:
   696             ("PROPERTIES",     ITEM_PROPERTIES)]:
   631             self.TypesTreeImageDict[itemtype]=self.TypesTreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%imgname)))
   697             self.TreeImageDict[itemtype]=self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%imgname)))
   632             self.InstancesTreeImageDict[itemtype]=self.InstancesTreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%imgname)))
   698         
   633         self.TypesTree.AssignImageList(self.TypesTreeImageList)
   699         # Assign icon list to TreeCtrls
   634         self.InstancesTree.AssignImageList(self.InstancesTreeImageList)
   700         self.TypesTree.SetImageList(self.TreeImageList)
       
   701         self.InstancesTree.SetImageList(self.TreeImageList)
   635         
   702         
   636         self.CurrentToolBar = []
   703         self.CurrentToolBar = []
   637         self.CurrentLanguage = ""
   704         self.CurrentLanguage = ""
   638         self.SelectedItem = None
   705         self.SelectedItem = None
   639         self.Errors = []
   706         self.Errors = []
   640         self.DrawingMode = FREEDRAWING_MODE
   707         self.DrawingMode = FREEDRAWING_MODE
   641         #self.DrawingMode = DRIVENDRAWING_MODE
   708         #self.DrawingMode = DRIVENDRAWING_MODE
   642         if USE_AUI:
   709         if USE_AUI:
   643             self.AuiTabCtrl = []
   710             self.AuiTabCtrl = []
   644         
   711         
       
   712         # Initialize Printing configuring elements
   645         self.PrintData = wx.PrintData()
   713         self.PrintData = wx.PrintData()
   646         self.PrintData.SetPaperId(wx.PAPER_A4)
   714         self.PrintData.SetPaperId(wx.PAPER_A4)
   647         self.PrintData.SetPrintMode(wx.PRINT_MODE_PRINTER)
   715         self.PrintData.SetPrintMode(wx.PRINT_MODE_PRINTER)
   648         self.PageSetupData = wx.PageSetupDialogData(self.PrintData)
   716         self.PageSetupData = wx.PageSetupDialogData(self.PrintData)
   649         self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15))
   717         self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15))
   650         self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20))
   718         self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20))
   651         
   719         
       
   720         # Refresh elements that need to
   652         if not self.ModeSolo or fileOpen is not None:
   721         if not self.ModeSolo or fileOpen is not None:
   653             self.RefreshTypesTree()
   722             self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
   654             self.RefreshInstancesTree()
   723         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
   655             self.RefreshLibraryTree()
   724 
   656         
   725 
   657         self.RefreshFileMenu()
   726 #-------------------------------------------------------------------------------
   658         self.RefreshEditMenu()
   727 #                               General Functions
   659         self.RefreshDisplayMenu()
   728 #-------------------------------------------------------------------------------
   660         self.RefreshTitle()
   729 
   661         self.RefreshToolBar()
   730     ## Call PLCOpenEditor refresh functions.
   662 
   731     #  @param elements List of elements to refresh.
   663     def ResetSelectedItem(self):
   732     def _Refresh(self, *elements):
   664         self.SelectedItem = None
   733         for element in elements:
   665 
   734             self.RefreshFunctions[element](self)
       
   735 
       
   736     ## Callback function when AUINotebook Page closed with CloseButton
       
   737     #  @param event AUINotebook Event.
   666     def OnPageClose(self, event):
   738     def OnPageClose(self, event):
       
   739         # Get Selected Tab
   667         selected = event.GetSelection()
   740         selected = event.GetSelection()
   668         if selected >= 0:
   741         if selected >= 0:
       
   742             # Remove corresponding VariablePanel
   669             if not self.Debug:
   743             if not self.Debug:
   670                 tagname = self.TabsOpened.GetPage(selected).GetTagName()
   744                 tagname = self.TabsOpened.GetPage(selected).GetTagName()
   671                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
   745                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
   746             # Refresh Tab selection
   672             if self.TabsOpened.GetPageCount() > 0:
   747             if self.TabsOpened.GetPageCount() > 0:
   673                 new_index = min(selected, self.TabsOpened.GetPageCount() - 1)
   748                 new_index = min(selected, self.TabsOpened.GetPageCount() - 1)
   674                 self.TabsOpened.SetSelection(new_index)
   749                 self.TabsOpened.SetSelection(new_index)
   675                 if not self.Debug:
   750                 if not self.Debug:
   676                     tagname = self.TabsOpened.GetPage(new_index).GetTagName()
   751                     tagname = self.TabsOpened.GetPage(new_index).GetTagName()
   677                     self.VariablePanelIndexer.ChangeVariablePanel(tagname)
   752                     self.VariablePanelIndexer.ChangeVariablePanel(tagname)
   678             self.RefreshTitle()
   753             # Refresh all window elements that have changed
   679             self.RefreshFileMenu()
   754             self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU)
   680             self.RefreshEditMenu()
       
   681             self.RefreshDisplayMenu()
       
   682             self.RefreshToolBar()
       
   683         wx.CallAfter(self.RefreshTabCtrlEvent)
       
   684         event.Skip()
       
   685 
       
   686     def OnPageDragged(self, event):
       
   687         wx.CallAfter(self.RefreshTabCtrlEvent)
   755         wx.CallAfter(self.RefreshTabCtrlEvent)
   688         event.Skip()
   756         event.Skip()
   689 
   757 
   690     def GetCopyBuffer(self):
   758     def GetCopyBuffer(self):
   691         data = None
   759         data = None
   729         if dialog.ShowModal() == wx.ID_OK:
   797         if dialog.ShowModal() == wx.ID_OK:
   730             new_values = dialog.GetValues()
   798             new_values = dialog.GetValues()
   731             new_values["creationDateTime"] = old_values["creationDateTime"]
   799             new_values["creationDateTime"] = old_values["creationDateTime"]
   732             if new_values != old_values:
   800             if new_values != old_values:
   733                 self.Controler.SetProjectProperties(None, new_values)
   801                 self.Controler.SetProjectProperties(None, new_values)
   734                 self.RefreshTitle()
   802                 self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, 
   735                 self.RefreshFileMenu()
   803                               TYPESTREE, INSTANCESTREE, SCALING)
   736                 self.RefreshEditMenu()
       
   737                 self.RefreshDisplayMenu()
       
   738                 self.RefreshTypesTree()
       
   739                 self.RefreshScaling()
       
   740         dialog.Destroy()
   804         dialog.Destroy()
   741 
   805 
   742     def OnCloseFrame(self, event):
   806     def OnCloseFrame(self, event):
   743         if not self.ModeSolo and getattr(self, "_onclose", None) is not None:
   807         if not self.ModeSolo and getattr(self, "_onclose", None) is not None:
   744             self.AUIManager.UnInit()
   808             self.AUIManager.UnInit()
   745             self._onclose()
   809             self._onclose()
   746             event.Skip()
   810             event.Skip()
   747         elif not self.Controler.ProjectIsSaved():
   811         elif self.CheckSaveBeforeClosing():
   748             dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
   812             event.Skip()
   749             answer = dialog.ShowModal()
   813         else:
   750             dialog.Destroy()
   814             event.Veto()
   751             if answer == wx.ID_YES:
   815 
   752                 self.SaveProject()
   816 #-------------------------------------------------------------------------------
   753                 event.Skip()
   817 #                            Notebook Unified Functions
   754             elif answer == wx.ID_NO:
   818 #-------------------------------------------------------------------------------
   755                 self.Controler.Reset()
   819 
   756                 self.AUIManager.UnInit()
   820     ## Function that generate bitmap for
   757                 event.Skip()
   821     # for wx.aui.AUINotebook.
       
   822     #  @param window Panel to display in tab.
       
   823     #  @param text title for the tab ctrl.
       
   824     def GenerateBitmap(self, icon1_name, icon2_name = None):
       
   825         # Find index of bitmap if already created
       
   826         index = self.TabsImageListIndexes.get((icon1_name, icon2_name), None)
       
   827         # Return index or bitmap if found
       
   828         if index is not None:
       
   829             if USE_AUI:
       
   830                 return self.TabsImageList.GetBitmap(index)
   758             else:
   831             else:
   759                 event.Veto()
       
   760         else:
       
   761             event.Skip()
       
   762 
       
   763 #-------------------------------------------------------------------------------
       
   764 #                            Notebook Unified Functions
       
   765 #-------------------------------------------------------------------------------
       
   766 
       
   767     def GenerateBitmap(self, icon1_name, icon2_name = None):
       
   768         if not USE_AUI:
       
   769             index = self.TabsImageListIndexes.get((icon1_name, icon2_name), None)
       
   770             if index is not None:
       
   771                 return index
   832                 return index
   772         if icon2_name is None:
   833         if icon2_name is None:
       
   834             # Bitmap with only one icon
   773             tmp_bitmap = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name))
   835             tmp_bitmap = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name))
   774         else:
   836         else:
       
   837             # Bitmap with two icon
   775             icon1 = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name))
   838             icon1 = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon1_name))
   776             icon2 = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon2_name))
   839             icon2 = wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%icon2_name))
       
   840             # Calculate bitmap size
   777             width = icon1.GetWidth() + icon2.GetWidth() - 1
   841             width = icon1.GetWidth() + icon2.GetWidth() - 1
   778             height = max(icon1.GetHeight(), icon2.GetHeight())
   842             height = max(icon1.GetHeight(), icon2.GetHeight())
       
   843             # Create bitmap with both icons
   779             tmp_bitmap = wx.EmptyBitmap(width, height)
   844             tmp_bitmap = wx.EmptyBitmap(width, height)
   780             dc = wx.MemoryDC()
   845             dc = wx.MemoryDC()
   781             dc.SelectObject(tmp_bitmap)
   846             dc.SelectObject(tmp_bitmap)
   782             dc.Clear()
   847             dc.Clear()
   783             dc.DrawBitmap(icon1, 0, 0)
   848             dc.DrawBitmap(icon1, 0, 0)
   784             dc.DrawBitmap(icon2, icon1.GetWidth() - 1, 0)
   849             dc.DrawBitmap(icon2, icon1.GetWidth() - 1, 0)
       
   850         # Store bitmap in ImageList
       
   851         index = self.TabsImageList.Add(tmp_bitmap)
       
   852         # Save bitmap index in ImageList in dictionary
       
   853         self.TabsImageListIndexes[(icon1_name, icon2_name)] = index
   785         if USE_AUI:
   854         if USE_AUI:
   786             return tmp_bitmap
   855             return tmp_bitmap
   787         else:
   856         else:
   788             index = self.TabsImageList.Add(tmp_bitmap)
       
   789             self.TabsImageListIndexes[(icon1_name, icon2_name)] = index
       
   790             return index
   857             return index
   791     
   858     
       
   859     ## Function that add a tab in Notebook, calling refresh for tab DClick event
       
   860     # for wx.aui.AUINotebook.
       
   861     #  @param window Panel to display in tab.
       
   862     #  @param text title for the tab ctrl.
   792     def AddPage(self, window, text):
   863     def AddPage(self, window, text):
   793         self.TabsOpened.AddPage(window, text)
   864         self.TabsOpened.AddPage(window, text)
   794         self.RefreshTabCtrlEvent()
   865         self.RefreshTabCtrlEvent()
   795     
   866     
   796     def RefreshTabCtrlEvent(self):
   867     ## Function that fix difference in deleting all tabs between 
   797         if USE_AUI:
   868     # wx.Notebook and wx.aui.AUINotebook.
   798             auitabctrl = []
       
   799             for child in self.TabsOpened.GetChildren():
       
   800                 if isinstance(child, wx.aui.AuiTabCtrl):
       
   801                     auitabctrl.append(child)
       
   802                     if child not in self.AuiTabCtrl:
       
   803                         child.Bind(wx.EVT_LEFT_DCLICK, self.GetTabsOpenedDClickFunction(child))
       
   804             self.AuiTabCtrl = auitabctrl
       
   805             if self.TabsOpened.GetPageCount() == 0:
       
   806                 pane = self.AUIManager.GetPane(self.TabsOpened)
       
   807                 if pane.IsMaximized():
       
   808                     self.AUIManager.RestorePane(pane)
       
   809                 self.AUIManager.Update()
       
   810     
       
   811     def DeleteAllPages(self):
   869     def DeleteAllPages(self):
   812         if USE_AUI:
   870         if USE_AUI:
   813             for idx in xrange(self.TabsOpened.GetPageCount()):
   871             for idx in xrange(self.TabsOpened.GetPageCount()):
   814                 self.TabsOpened.DeletePage(0)
   872                 self.TabsOpened.DeletePage(0)
   815         else:
   873         else:
   816             self.TabsOpened.DeleteAllPages()
   874             self.TabsOpened.DeleteAllPages()
   817 
   875         self.RefreshTabCtrlEvent()
       
   876 
       
   877     ## Function that fix difference in setting picture on tab between 
       
   878     # wx.Notebook and wx.aui.AUINotebook.
       
   879     #  @param idx Tab index.
       
   880     #  @param bitmap wx.Bitmap to define on tab.
       
   881     #  @return True if operation succeeded
   818     def SetPageBitmap(self, idx, bitmap):
   882     def SetPageBitmap(self, idx, bitmap):
   819         if USE_AUI:
   883         if USE_AUI:
   820             return self.TabsOpened.SetPageBitmap(idx, bitmap)
   884             return self.TabsOpened.SetPageBitmap(idx, bitmap)
   821         else:
   885         else:
   822             return self.TabsOpened.SetPageImage(idx, bitmap)
   886             return self.TabsOpened.SetPageImage(idx, bitmap)
   823 
   887 
       
   888 #-------------------------------------------------------------------------------
       
   889 #                         Dialog Message Functions
       
   890 #-------------------------------------------------------------------------------
       
   891 
       
   892     ## Function displaying an Error dialog in PLCOpenEditor.
       
   893     #  @param message The message to display.
       
   894     def ShowErrorMessage(self, message):
       
   895         dialog = wx.MessageDialog(self, message, "Error", wx.OK|wx.ICON_ERROR)
       
   896         dialog.ShowModal()
       
   897         dialog.Destroy()
       
   898 
       
   899     ## Function displaying an Error dialog in PLCOpenEditor.
       
   900     #  @return False if closing cancelled.
       
   901     def CheckSaveBeforeClosing(self):
       
   902         if not self.Controler.ProjectIsSaved():
       
   903             dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
       
   904             answer = dialog.ShowModal()
       
   905             dialog.Destroy()
       
   906             if answer == wx.ID_YES:
       
   907                 self.SaveProject()
       
   908             elif answer == wx.ID_CANCEL:
       
   909                 return False
       
   910         return True
   824 
   911 
   825 #-------------------------------------------------------------------------------
   912 #-------------------------------------------------------------------------------
   826 #                            File Menu Functions
   913 #                            File Menu Functions
   827 #-------------------------------------------------------------------------------
   914 #-------------------------------------------------------------------------------
   828 
   915 
   869     def OnNewProjectMenu(self, event):
   956     def OnNewProjectMenu(self, event):
   870         dialog = ProjectDialog(self)
   957         dialog = ProjectDialog(self)
   871         if dialog.ShowModal() == wx.ID_OK:
   958         if dialog.ShowModal() == wx.ID_OK:
   872             properties = dialog.GetValues()
   959             properties = dialog.GetValues()
   873             self.Controler.CreateNewProject(properties)
   960             self.Controler.CreateNewProject(properties)
   874             self.RefreshTitle()
   961             self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, 
   875             self.RefreshFileMenu()
   962                           LIBRARYTREE)
   876             self.RefreshEditMenu()
       
   877             self.RefreshTypesTree()
       
   878             self.RefreshInstancesTree()
       
   879             self.RefreshLibraryTree()
       
   880         event.Skip()
   963         event.Skip()
   881 
   964 
   882     def OnOpenProjectMenu(self, event):
   965     def OnOpenProjectMenu(self, event):
   883         if not self.Controler.ProjectIsSaved():
   966         if not self.CheckSaveBeforeClosing():
   884             dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
   967             return
   885             answer = dialog.ShowModal()
       
   886             dialog.Destroy()
       
   887             if answer == wx.ID_YES:
       
   888                 self.SaveProject()
       
   889             elif answer == wx.ID_CANCEL:
       
   890                 return
       
   891         filepath = self.Controler.GetFilePath()
   968         filepath = self.Controler.GetFilePath()
   892         if filepath != "":
   969         if filepath != "":
   893             directory = os.path.dirname(filepath)
   970             directory = os.path.dirname(filepath)
   894         else:
   971         else:
   895             directory = os.getcwd()
   972             directory = os.getcwd()
   898             filepath = dialog.GetPath()
   975             filepath = dialog.GetPath()
   899             if os.path.isfile(filepath):
   976             if os.path.isfile(filepath):
   900                 self.DeleteAllPages()
   977                 self.DeleteAllPages()
   901                 self.VariablePanelIndexer.RemoveAllPanels()
   978                 self.VariablePanelIndexer.RemoveAllPanels()
   902                 self.Controler.OpenXMLFile(filepath)
   979                 self.Controler.OpenXMLFile(filepath)
   903                 self.RefreshTypesTree()
   980                 self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE)
   904                 self.RefreshInstancesTree()
   981             self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU)
   905                 self.RefreshLibraryTree()
       
   906             self.RefreshTitle()
       
   907             self.RefreshFileMenu()
       
   908             self.RefreshEditMenu()
       
   909             self.RefreshToolBar()
       
   910         dialog.Destroy()
   982         dialog.Destroy()
   911         event.Skip()
   983         event.Skip()
   912 
   984 
   913     def OnCloseTabMenu(self, event):
   985     def OnCloseTabMenu(self, event):
   914         selected = self.TabsOpened.GetSelection()
   986         selected = self.TabsOpened.GetSelection()
   921                 new_index = min(selected, self.TabsOpened.GetPageCount() - 1)
   993                 new_index = min(selected, self.TabsOpened.GetPageCount() - 1)
   922                 self.TabsOpened.SetSelection(new_index)
   994                 self.TabsOpened.SetSelection(new_index)
   923                 if not self.Debug:
   995                 if not self.Debug:
   924                     tagname = self.TabsOpened.GetPage(new_index).GetTagName()
   996                     tagname = self.TabsOpened.GetPage(new_index).GetTagName()
   925                     self.VariablePanelIndexer.ChangeVariablePanel(tagname)
   997                     self.VariablePanelIndexer.ChangeVariablePanel(tagname)
   926             self.RefreshFileMenu()
   998             self._Refresh(TOOLBAR, FILEMENU, EDITMENU)
   927             self.RefreshEditMenu()
       
   928             self.RefreshToolBar()
       
   929         event.Skip()
   999         event.Skip()
   930     
  1000     
   931     def OnCloseProjectMenu(self, event):
  1001     def OnCloseProjectMenu(self, event):
   932         if not self.Controler.ProjectIsSaved():
  1002         if not self.CheckSaveBeforeClosing():
   933             dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
  1003             return
   934             answer = dialog.ShowModal()
       
   935             dialog.Destroy()
       
   936             if answer == wx.ID_YES:
       
   937                 self.SaveProject()
       
   938             elif answer == wx.ID_CANCEL:
       
   939                 return
       
   940         self.DeleteAllPages()
  1004         self.DeleteAllPages()
   941         self.VariablePanelIndexer.RemoveAllPanels()
  1005         self.VariablePanelIndexer.RemoveAllPanels()
   942         self.TypesTree.DeleteAllItems()
  1006         self.TypesTree.DeleteAllItems()
   943         self.InstancesTree.DeleteAllItems()
  1007         self.InstancesTree.DeleteAllItems()
   944         self.Controler.Reset()
  1008         self.Controler.Reset()
   945         self.RefreshTitle()
  1009         self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU)
   946         self.RefreshFileMenu()
       
   947         self.RefreshEditMenu()
       
   948         self.RefreshToolBar()
       
   949         event.Skip()
  1010         event.Skip()
   950 
  1011 
   951     def OnSaveProjectMenu(self, event):
  1012     def OnSaveProjectMenu(self, event):
   952         if not self.ModeSolo and getattr(self, "_onsave", None) != None:
  1013         if not self.ModeSolo and getattr(self, "_onsave", None) != None:
   953             self._onsave()
  1014             self._onsave()
  1000         if dialog.ShowModal() == wx.ID_OK:
  1061         if dialog.ShowModal() == wx.ID_OK:
  1001             filepath = dialog.GetPath()
  1062             filepath = dialog.GetPath()
  1002             if os.path.isdir(os.path.dirname(filepath)):
  1063             if os.path.isdir(os.path.dirname(filepath)):
  1003                 result = self.Controler.SaveXMLFile(filepath)
  1064                 result = self.Controler.SaveXMLFile(filepath)
  1004                 if not result:
  1065                 if not result:
  1005                     message = wx.MessageDialog(self, "Can't save project to file %s!"%filepath, "Error", wx.OK|wx.ICON_ERROR)
  1066                     self.ShowErrorMessage("Can't save project to file %s!"%filepath)
  1006                     message.ShowModal()
       
  1007                     message.Destroy()
       
  1008             else:
  1067             else:
  1009                 message = wx.MessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR)
  1068                 self.ShowErrorMessage("\"%s\" is not a valid folder!"%os.path.dirname(filepath))
  1010                 message.ShowModal()
       
  1011                 message.Destroy()
       
  1012             self.RefreshTitle()
  1069             self.RefreshTitle()
  1013         dialog.Destroy()
  1070         dialog.Destroy()
  1014 
  1071 
  1015     def OnPageSetupMenu(self, event):
  1072     def OnPageSetupMenu(self, event):
  1016         dialog = wx.PageSetupDialog(self, self.PageSetupData)
  1073         dialog = wx.PageSetupDialog(self, self.PageSetupData)
  1049             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
  1106             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
  1050             printer = wx.Printer(dialog_data)
  1107             printer = wx.Printer(dialog_data)
  1051             printout = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins)
  1108             printout = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins)
  1052             
  1109             
  1053             if not printer.Print(self, printout, True):
  1110             if not printer.Print(self, printout, True):
  1054                 wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK)
  1111                 self.ShowErrorMessage("There was a problem printing.\nPerhaps your current printer is not set correctly?")
  1055             printout.Destroy()
  1112             printout.Destroy()
  1056         event.Skip()
  1113         event.Skip()
  1057 
  1114 
  1058     def OnPropertiesMenu(self, event):
  1115     def OnPropertiesMenu(self, event):
  1059         self.ShowProperties()
  1116         self.ShowProperties()
  1099                 self.EditMenu.Enable(wx.ID_PASTE, False)
  1156                 self.EditMenu.Enable(wx.ID_PASTE, False)
  1100                 self.EditMenu.Enable(wx.ID_SELECTALL, False)
  1157                 self.EditMenu.Enable(wx.ID_SELECTALL, False)
  1101                 self.EditMenu.Enable(wx.ID_ADD, False)
  1158                 self.EditMenu.Enable(wx.ID_ADD, False)
  1102                 self.EditMenu.Enable(wx.ID_DELETE, False)
  1159                 self.EditMenu.Enable(wx.ID_DELETE, False)
  1103     
  1160     
  1104     def OnUndoMenu(self, event):
  1161     def CloseTabsWithoutModel(self):
  1105         self.Controler.LoadPrevious()
       
  1106         idxs = range(self.TabsOpened.GetPageCount())
  1162         idxs = range(self.TabsOpened.GetPageCount())
  1107         idxs.reverse()
  1163         idxs.reverse()
  1108         for idx in idxs:
  1164         for idx in idxs:
  1109             tagname = self.TabsOpened.GetPage(idx).GetTagName()
  1165             tagname = self.TabsOpened.GetPage(idx).GetTagName()
  1110             if self.Controler.GetEditedElement(tagname, self.Debug) is None:
  1166             if self.Controler.GetEditedElement(tagname, self.Debug) is None:
  1111                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
  1167                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
  1112                 self.TabsOpened.DeletePage(idx)
  1168                 self.TabsOpened.DeletePage(idx)
  1113         selected = self.TabsOpened.GetSelection()
  1169         
  1114         if selected != -1:
  1170     def OnUndoMenu(self, event):
  1115             window = self.TabsOpened.GetPage(selected)
  1171         self.Controler.LoadPrevious()
  1116             window.RefreshView()
  1172         self.CloseTabsWithoutModel()
  1117             self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName())
  1173         self.RefreshEditor()
  1118         self.RefreshTitle()
  1174         self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, 
  1119         self.RefreshEditMenu()
  1175                       SCALING)
  1120         self.RefreshTypesTree()
       
  1121         self.RefreshInstancesTree()
       
  1122         self.RefreshLibraryTree()
       
  1123         self.RefreshScaling()
       
  1124         event.Skip()
  1176         event.Skip()
  1125     
  1177     
  1126     def OnRedoMenu(self, event):
  1178     def OnRedoMenu(self, event):
  1127         self.Controler.LoadNext()
  1179         self.Controler.LoadNext()
  1128         idxs = range(self.TabsOpened.GetPageCount())
  1180         self.CloseTabsWithoutModel()
  1129         idxs.reverse()
  1181         self.RefreshEditor()
  1130         for idx in idxs:
  1182         self._Refresh(TITLE, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, 
  1131             tagname = self.TabsOpened.GetPage(idx).GetTagName()
  1183                       SCALING)
  1132             if self.Controler.GetEditedElement(tagname, self.Debug) is None:
  1184         event.Skip()
  1133                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
  1185     
  1134                 self.TabsOpened.DeletePage(idx)
       
  1135         selected = self.TabsOpened.GetSelection()
       
  1136         if selected != -1:
       
  1137             window = self.TabsOpened.GetPage(selected)
       
  1138             window.RefreshView()
       
  1139             self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName())
       
  1140         self.RefreshTitle()
       
  1141         self.RefreshEditMenu()
       
  1142         self.RefreshTypesTree()
       
  1143         self.RefreshInstancesTree()
       
  1144         self.RefreshLibraryTree()
       
  1145         self.RefreshScaling()
       
  1146         event.Skip()
       
  1147 
       
  1148     def OnEnableUndoRedoMenu(self, event):
  1186     def OnEnableUndoRedoMenu(self, event):
  1149         self.Controler.EnableProjectBuffer(event.IsChecked())
  1187         self.Controler.EnableProjectBuffer(event.IsChecked())
  1150         self.RefreshEditMenu()
  1188         self.RefreshEditMenu()
  1151         event.Skip()
  1189         event.Skip()
  1152 
  1190 
  1153     def OnCutMenu(self, event):
  1191     OnCutMenu = GetShortcutKeyCallbackFunction("Cut")
  1154         control = self.FindFocus()
  1192     OnCopyMenu = GetShortcutKeyCallbackFunction("Copy")
  1155         if isinstance(control, (Viewer, TextViewer)):
  1193     OnPasteMenu = GetShortcutKeyCallbackFunction("Paste")
  1156             control.Cut()
  1194 
  1157         elif isinstance(control, wx.TextCtrl):
       
  1158             control.ProcessEvent(event)
       
  1159         event.Skip()
       
  1160     
       
  1161     def OnCopyMenu(self, event):
       
  1162         control = self.FindFocus()
       
  1163         if isinstance(control, (Viewer, TextViewer)):
       
  1164             control.Copy()
       
  1165         elif isinstance(control, wx.TextCtrl):
       
  1166             control.ProcessEvent(event)
       
  1167         event.Skip()
       
  1168     
       
  1169     def OnPasteMenu(self, event):
       
  1170         control = self.FindFocus()
       
  1171         if isinstance(control, (Viewer, TextViewer)):
       
  1172             control.Paste()
       
  1173         elif isinstance(control, wx.TextCtrl):
       
  1174             control.ProcessEvent(event)
       
  1175         event.Skip()
       
  1176     
       
  1177     def OnSelectAllMenu(self, event):
  1195     def OnSelectAllMenu(self, event):
  1178         control = self.FindFocus()
  1196         control = self.FindFocus()
  1179         if isinstance(control, (Viewer, TextViewer)):
  1197         if isinstance(control, (Viewer, TextViewer)):
  1180             control.SelectAll()
  1198             control.SelectAll()
  1181         elif isinstance(control, wx.TextCtrl):
  1199         elif isinstance(control, wx.TextCtrl):
  1182             control.SetSelection(0, control.GetLastPosition())
  1200             control.SetSelection(0, control.GetLastPosition())
  1183         elif isinstance(control, wx.ComboBox):
  1201         elif isinstance(control, wx.ComboBox):
  1184             control.SetMark(0, control.GetLastPosition() + 1)
  1202             control.SetMark(0, control.GetLastPosition() + 1)
  1185         event.Skip()
  1203         event.Skip()
  1186     
  1204     
       
  1205     DeleteFunctions = {
       
  1206         ITEM_DATATYPE: GetDeleteElementFunction(PLCControler.ProjectRemoveDataType, check_function=PLCControler.DataTypeIsUsed),
       
  1207         ITEM_POU: GetDeleteElementFunction(PLCControler.ProjectRemovePou, check_function=PLCControler.PouIsUsed),
       
  1208         ITEM_TRANSITION: GetDeleteElementFunction(PLCControler.ProjectRemovePouTransition, ITEM_POU),
       
  1209         ITEM_ACTION: GetDeleteElementFunction(PLCControler.ProjectRemovePouAction, ITEM_POU),
       
  1210         ITEM_CONFIGURATION: GetDeleteElementFunction(PLCControler.ProjectRemoveConfiguration),
       
  1211         ITEM_RESOURCE: GetDeleteElementFunction(PLCControler.ProjectRemoveConfigurationResource, ITEM_CONFIGURATION)
       
  1212     }
       
  1213     
  1187     def OnDeleteMenu(self, event):
  1214     def OnDeleteMenu(self, event):
  1188         window = self.FindFocus()
  1215         window = self.FindFocus()
  1189         if window == self.TypesTree:
  1216         if window == self.TypesTree or window is None:
  1190             selected = self.TypesTree.GetSelection()
  1217             selected = self.TypesTree.GetSelection()
  1191             if selected.IsOk():
  1218             if selected.IsOk():
  1192                 type = self.TypesTree.GetPyData(selected)
  1219                 type = self.TypesTree.GetPyData(selected)
  1193                 tagname = ""
  1220                 function = self.DeleteFunctions.get(type, None)
  1194                 if type == ITEM_DATATYPE:
  1221                 if function is not None:
  1195                     name = self.TypesTree.GetItemText(selected)
  1222                     function(self, selected)
  1196                     if not self.Controler.DataTypeIsUsed(name, self.Debug):
  1223                     self.CloseTabsWithoutModel()
  1197                         self.Controler.ProjectRemoveDataType(name)
  1224                     self._Refresh(TITLE, TOOLBAR, EDITMENU, TYPESTREE, 
  1198                         tagname = self.Controler.ComputeDataTypeName(name)
  1225                                   INSTANCESTREE, LIBRARYTREE)
  1199                     else:
       
  1200                         message = wx.MessageDialog(self, "\"%s\" is used by one or more POUs. It can't be removed!"%name, "Error", wx.OK|wx.ICON_ERROR)
       
  1201                         message.ShowModal()
       
  1202                         message.Destroy()
       
  1203                 elif type == ITEM_POU:
       
  1204                     name = self.TypesTree.GetItemText(selected)
       
  1205                     if not self.Controler.PouIsUsed(name, self.Debug):
       
  1206                         self.Controler.ProjectRemovePou(name)
       
  1207                         tagname = self.Controler.ComputePouName(name)
       
  1208                     else:
       
  1209                         message = wx.MessageDialog(self, "\"%s\" is used by one or more POUs. It can't be removed!"%name, "Error", wx.OK|wx.ICON_ERROR)
       
  1210                         message.ShowModal()
       
  1211                         message.Destroy()
       
  1212                 elif type in [ITEM_TRANSITION, ITEM_ACTION]:
       
  1213                     item = self.TypesTree.GetItemParent(selected)
       
  1214                     item_type = self.TypesTree.GetPyData(item)
       
  1215                     while item_type != ITEM_POU:
       
  1216                         item = self.TypesTree.GetItemParent(item)
       
  1217                         item_type = self.TypesTree.GetPyData(item)
       
  1218                     pou_name = self.TypesTree.GetItemText(item)
       
  1219                     if type == ITEM_TRANSITION:
       
  1220                         transition = self.TypesTree.GetItemText(selected)
       
  1221                         self.Controler.ProjectRemovePouTransition(pou_name, transition)
       
  1222                         tagname = self.Controler.ComputePouTransitionName(pou_name, transition)
       
  1223                     elif type == ITEM_ACTION:
       
  1224                         action = self.TypesTree.GetItemText(selected)
       
  1225                         self.Controler.ProjectRemovePouAction(pou_name, action)
       
  1226                         tagname = self.Controler.ComputePouActionName(pou_name, action)
       
  1227                 elif type == ITEM_CONFIGURATION:
       
  1228                     name = self.TypesTree.GetItemText(selected)
       
  1229                     self.Controler.ProjectRemoveConfiguration(name)
       
  1230                     tagname = self.Controler.ComputeConfigurationName(name)
       
  1231                 elif type == ITEM_RESOURCE:
       
  1232                     resource = self.TypesTree.GetItemText(selected)
       
  1233                     item = self.TypesTree.GetItemParent(selected)
       
  1234                     item_type = self.TypesTree.GetPyData(item)
       
  1235                     while item_type != ITEM_CONFIGURATION:
       
  1236                         item = self.TypesTree.GetItemParent(item)
       
  1237                         item_type = self.TypesTree.GetPyData(item)
       
  1238                     config_name = self.TypesTree.GetItemText(item)
       
  1239                     self.Controler.ProjectRemoveConfigurationResource(config_name, resource)
       
  1240                     tagname = self.Controler.ComputeConfigurationResourceName(config_name, selected)
       
  1241                 idx = self.IsOpened(tagname)
       
  1242                 if idx is not None:
       
  1243                     self.VariablePanelIndexer.RemoveVariablePanel(tagname)
       
  1244                     self.TabsOpened.DeletePage(idx)
       
  1245                 self.RefreshTitle()
       
  1246                 self.RefreshEditMenu()
       
  1247                 self.RefreshTypesTree()
       
  1248                 self.RefreshInstancesTree()
       
  1249                 self.RefreshLibraryTree()
       
  1250                 self.RefreshToolBar()
       
  1251         elif isinstance(window, (Viewer, TextViewer)):
  1226         elif isinstance(window, (Viewer, TextViewer)):
  1252             event = wx.KeyEvent(wx.EVT_CHAR._getEvtType())
  1227             event = wx.KeyEvent(wx.EVT_CHAR._getEvtType())
  1253             event.m_keyCode = wx.WXK_DELETE
  1228             event.m_keyCode = wx.WXK_DELETE
  1254             window.ProcessEvent(event)
  1229             window.ProcessEvent(event)
  1255         event.Skip()
  1230         event.Skip()
  1285             if not self.Debug and not self.ModeSolo:
  1260             if not self.Debug and not self.ModeSolo:
  1286                 self.DisplayMenu.Enable(wx.ID_CLEAR, False)
  1261                 self.DisplayMenu.Enable(wx.ID_CLEAR, False)
  1287             self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
  1262             self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False)
  1288         
  1263         
  1289     def OnRefreshMenu(self, event):
  1264     def OnRefreshMenu(self, event):
  1290         selected = self.TabsOpened.GetSelection()
  1265         self.RefreshEditor(not self.Debug)
  1291         if selected != -1:
       
  1292             window = self.TabsOpened.GetPage(selected)
       
  1293             window.RefreshView()
       
  1294             if not self.Debug:
       
  1295                 self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName())
       
  1296         event.Skip()
  1266         event.Skip()
  1297 
  1267 
  1298     def OnClearErrorsMenu(self, event):
  1268     def OnClearErrorsMenu(self, event):
  1299         self.ClearErrors()
  1269         self.ClearErrors()
  1300         event.Skip()
  1270         event.Skip()
  1312 
  1282 
  1313 
  1283 
  1314 #-------------------------------------------------------------------------------
  1284 #-------------------------------------------------------------------------------
  1315 #                      Project Editor Panels Management Functions
  1285 #                      Project Editor Panels Management Functions
  1316 #-------------------------------------------------------------------------------
  1286 #-------------------------------------------------------------------------------
       
  1287     
       
  1288     def OnPageDragged(self, event):
       
  1289         wx.CallAfter(self.RefreshTabCtrlEvent)
       
  1290         event.Skip()
       
  1291     
       
  1292     def RefreshTabCtrlEvent(self):
       
  1293         if USE_AUI:
       
  1294             auitabctrl = []
       
  1295             for child in self.TabsOpened.GetChildren():
       
  1296                 if isinstance(child, wx.aui.AuiTabCtrl):
       
  1297                     auitabctrl.append(child)
       
  1298                     if child not in self.AuiTabCtrl:
       
  1299                         child.Bind(wx.EVT_LEFT_DCLICK, self.GetTabsOpenedDClickFunction(child))
       
  1300             self.AuiTabCtrl = auitabctrl
       
  1301             if self.TabsOpened.GetPageCount() == 0:
       
  1302                 pane = self.AUIManager.GetPane(self.TabsOpened)
       
  1303                 if pane.IsMaximized():
       
  1304                     self.AUIManager.RestorePane(pane)
       
  1305                 self.AUIManager.Update()
  1317     
  1306     
  1318     def OnPouSelectedChanged(self, event):
  1307     def OnPouSelectedChanged(self, event):
  1319         old_selected = self.TabsOpened.GetSelection()
  1308         old_selected = self.TabsOpened.GetSelection()
  1320         if old_selected >= 0:
  1309         if old_selected >= 0:
  1321             if self.Debug:
  1310             if self.Debug:
  1330             else:
  1319             else:
  1331                 self.SelectInstancesTreeItem(self.InstancesTree.GetRootItem(), window.GetInstancePath())
  1320                 self.SelectInstancesTreeItem(self.InstancesTree.GetRootItem(), window.GetInstancePath())
  1332             window.RefreshView()
  1321             window.RefreshView()
  1333             if not self.Debug:
  1322             if not self.Debug:
  1334                 self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName())
  1323                 self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName())
  1335             self.RefreshFileMenu()
  1324             self._Refresh(FILEMENU, EDITMENU, DISPLAYMENU, TOOLBAR)
  1336             self.RefreshEditMenu()
       
  1337             self.RefreshDisplayMenu()
       
  1338             self.RefreshToolBar()
       
  1339         event.Skip()
  1325         event.Skip()
  1340 
  1326 
  1341     def RefreshEditor(self, variablepanel = True):
  1327     def RefreshEditor(self, variablepanel = True):
  1342         selected = self.TabsOpened.GetSelection()
  1328         selected = self.TabsOpened.GetSelection()
  1343         if selected != -1:
  1329         if selected != -1:
  1410         if not root.IsOk():
  1396         if not root.IsOk():
  1411             root = self.TypesTree.AddRoot(infos["name"])
  1397             root = self.TypesTree.AddRoot(infos["name"])
  1412         self.GenerateTypesTreeBranch(root, infos)
  1398         self.GenerateTypesTreeBranch(root, infos)
  1413         self.TypesTree.Expand(root)
  1399         self.TypesTree.Expand(root)
  1414 
  1400 
       
  1401     def ResetSelectedItem(self):
       
  1402         self.SelectedItem = None
       
  1403 
  1415     def GenerateTypesTreeBranch(self, root, infos, topology=False):
  1404     def GenerateTypesTreeBranch(self, root, infos, topology=False):
  1416         to_delete = []
  1405         to_delete = []
  1417         self.TypesTree.SetItemText(root, infos["name"])
  1406         self.TypesTree.SetItemText(root, infos["name"])
  1418         self.TypesTree.SetPyData(root, infos["type"])
  1407         self.TypesTree.SetPyData(root, infos["type"])
  1419         if infos.get("tagname", None) in self.Errors:
  1408         if infos.get("tagname", None) in self.Errors:
  1421             self.TypesTree.SetItemTextColour(root, wx.RED)
  1410             self.TypesTree.SetItemTextColour(root, wx.RED)
  1422         else:
  1411         else:
  1423             self.TypesTree.SetItemBackgroundColour(root, wx.WHITE)
  1412             self.TypesTree.SetItemBackgroundColour(root, wx.WHITE)
  1424             self.TypesTree.SetItemTextColour(root, wx.BLACK)
  1413             self.TypesTree.SetItemTextColour(root, wx.BLACK)
  1425         if infos["type"] == ITEM_POU:
  1414         if infos["type"] == ITEM_POU:
  1426             self.TypesTree.SetItemImage(root, self.TypesTreeImageDict[self.Controler.GetPouBodyType(infos["name"], self.Debug)])
  1415             self.TypesTree.SetItemImage(root, self.TreeImageDict[self.Controler.GetPouBodyType(infos["name"], self.Debug)])
  1427         else:
  1416         else:
  1428             self.TypesTree.SetItemImage(root, self.TypesTreeImageDict[infos["type"]])      
  1417             self.TypesTree.SetItemImage(root, self.TreeImageDict[infos["type"]])      
  1429             
  1418             
  1430         if wx.VERSION >= (2, 6, 0):
  1419         if wx.VERSION >= (2, 6, 0):
  1431             item, root_cookie = self.TypesTree.GetFirstChild(root)
  1420             item, root_cookie = self.TypesTree.GetFirstChild(root)
  1432         else:
  1421         else:
  1433             item, root_cookie = self.TypesTree.GetFirstChild(root, 0)
  1422             item, root_cookie = self.TypesTree.GetFirstChild(root, 0)
  1541                         self.RefreshEditorNames(self.Controler.ComputePouName(old_name), 
  1530                         self.RefreshEditorNames(self.Controler.ComputePouName(old_name), 
  1542                                                 self.Controler.ComputePouName(new_name))
  1531                                                 self.Controler.ComputePouName(new_name))
  1543                         self.RefreshLibraryTree()
  1532                         self.RefreshLibraryTree()
  1544                         self.RefreshPageTitles()
  1533                         self.RefreshPageTitles()
  1545                 elif itemtype == ITEM_TRANSITION:
  1534                 elif itemtype == ITEM_TRANSITION:
  1546                     parent = self.TypesTree.GetItemParent(item)
  1535                     pou_name = GetParentName(self.TypesTree, item, ITEM_POU)
  1547                     parent_type = self.TypesTree.GetPyData(parent)
       
  1548                     while parent_type != ITEM_POU:
       
  1549                         parent = self.TypesTree.GetItemParent(parent)
       
  1550                         parent_type = self.TypesTree.GetPyData(parent)
       
  1551                     pou_name = self.TypesTree.GetItemText(parent)
       
  1552                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
  1536                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
  1553                         message = "A pou with \"%s\" as name exists!"%new_name
  1537                         message = "A pou with \"%s\" as name exists!"%new_name
  1554                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]:
  1538                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]:
  1555                         message = "A variable with \"%s\" as name already exists in this pou!"%new_name
  1539                         message = "A variable with \"%s\" as name already exists in this pou!"%new_name
  1556                     else:
  1540                     else:
  1557                         self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
  1541                         self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
  1558                         self.RefreshEditorNames(self.Controler.ComputePouTransitionName(pou_name, old_name), 
  1542                         self.RefreshEditorNames(self.Controler.ComputePouTransitionName(pou_name, old_name), 
  1559                                                 self.Controler.ComputePouTransitionName(pou_name, new_name))
  1543                                                 self.Controler.ComputePouTransitionName(pou_name, new_name))
  1560                         self.RefreshPageTitles()
  1544                         self.RefreshPageTitles()
  1561                 elif itemtype == ITEM_ACTION:
  1545                 elif itemtype == ITEM_ACTION:
  1562                     parent = self.TypesTree.GetItemParent(item)
  1546                     pou_name = GetParentName(self.TypesTree, item, ITEM_POU)
  1563                     parent_type = self.TypesTree.GetPyData(parent)
       
  1564                     while parent_type != ITEM_POU:
       
  1565                         parent = self.TypesTree.GetItemParent(parent)
       
  1566                         parent_type = self.TypesTree.GetPyData(parent)
       
  1567                     pou_name = self.TypesTree.GetItemText(parent)
       
  1568                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
  1547                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
  1569                         message = "A pou with \"%s\" as name exists!"%new_name
  1548                         message = "A pou with \"%s\" as name exists!"%new_name
  1570                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]:
  1549                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]:
  1571                         message = "A variable with \"%s\" as name already exists in this pou!"%new_name
  1550                         message = "A variable with \"%s\" as name already exists in this pou!"%new_name
  1572                     else:
  1551                     else:
  1592                         self.Controler.ChangeConfigurationName(old_name, new_name)
  1571                         self.Controler.ChangeConfigurationName(old_name, new_name)
  1593                         self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), 
  1572                         self.RefreshEditorNames(self.Controler.ComputeConfigurationName(old_name), 
  1594                                                 self.Controler.ComputeConfigurationName(new_name))
  1573                                                 self.Controler.ComputeConfigurationName(new_name))
  1595                         self.RefreshPageTitles()
  1574                         self.RefreshPageTitles()
  1596                 elif itemtype == ITEM_RESOURCE:
  1575                 elif itemtype == ITEM_RESOURCE:
  1597                     parent = self.TypesTree.GetItemParent(item)
  1576                     config_name = GetParentName(self.TypesTree, item, ITEM_CONFIGURATION)
  1598                     parent_type = self.TypesTree.GetPyData(parent)
       
  1599                     while parent_type != ITEM_CONFIGURATION:
       
  1600                         parent = self.TypesTree.GetItemParent(parent)
       
  1601                         parent_type = self.TypesTree.GetPyData(parent)
       
  1602                     config_name = self.TypesTree.GetItemText(parent)
       
  1603                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug)]:
  1577                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug)]:
  1604                         message = "\"%s\" config already exists!"%new_name
  1578                         message = "\"%s\" config already exists!"%new_name
  1605                         abort = True
  1579                         abort = True
  1606                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
  1580                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
  1607                         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)
  1581                         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)
  1618                         self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(config_name, old_name), 
  1592                         self.RefreshEditorNames(self.Controler.ComputeConfigurationResourceName(config_name, old_name), 
  1619                                                 self.Controler.ComputeConfigurationResourceName(config_name, new_name))
  1593                                                 self.Controler.ComputeConfigurationResourceName(config_name, new_name))
  1620                         self.RefreshPageTitles()
  1594                         self.RefreshPageTitles()
  1621             if message or abort:
  1595             if message or abort:
  1622                 if message:
  1596                 if message:
  1623                     messageDialog = wx.MessageDialog(self, message, "Error", wx.OK|wx.ICON_ERROR)
  1597                     self.ShowErrorMessage(message)
  1624                     messageDialog.ShowModal()
       
  1625                     messageDialog.Destroy()
       
  1626                 item = event.GetItem()
  1598                 item = event.GetItem()
  1627                 wx.CallAfter(self.TypesTree.EditLabel, item)
  1599                 wx.CallAfter(self.TypesTree.EditLabel, item)
  1628                 event.Veto()
  1600                 event.Veto()
  1629             else:
  1601             else:
  1630                 wx.CallAfter(self.RefreshTypesTree)
  1602                 wx.CallAfter(self.RefreshTypesTree)
  1631                 self.RefreshEditor()
  1603                 self.RefreshEditor()
  1632                 self.RefreshFileMenu()
  1604                 self._Refresh(TITLE, FILEMENU, EDITMENU)
  1633                 self.RefreshEditMenu()
       
  1634                 self.RefreshTitle()
       
  1635                 event.Skip()
  1605                 event.Skip()
  1636     
  1606     
  1637     def OnTypesTreeItemActivated(self, event):
  1607     def OnTypesTreeItemActivated(self, event):
  1638         selected = event.GetItem()
  1608         selected = event.GetItem()
  1639         name = self.TypesTree.GetItemText(selected)
  1609         name = self.TypesTree.GetItemText(selected)
  1645         elif data == ITEM_POU:
  1615         elif data == ITEM_POU:
  1646             self.EditProjectElement(data, self.Controler.ComputePouName(name))
  1616             self.EditProjectElement(data, self.Controler.ComputePouName(name))
  1647         elif data == ITEM_CONFIGURATION:
  1617         elif data == ITEM_CONFIGURATION:
  1648             self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name))
  1618             self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name))
  1649         elif data == ITEM_RESOURCE:
  1619         elif data == ITEM_RESOURCE:
  1650             item = self.TypesTree.GetItemParent(selected)
  1620             config_name = GetParentName(self.TypesTree, selected, ITEM_CONFIGURATION)
  1651             item_type = self.TypesTree.GetPyData(item)
       
  1652             while item_type != ITEM_CONFIGURATION:
       
  1653                 item = self.TypesTree.GetItemParent(item)
       
  1654                 item_type = self.TypesTree.GetPyData(item)
       
  1655             config_name = self.TypesTree.GetItemText(item)
       
  1656             self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name))
  1621             self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name))
  1657         elif data in [ITEM_TRANSITION, ITEM_ACTION]:
  1622         elif data in [ITEM_TRANSITION, ITEM_ACTION]:
  1658             item = self.TypesTree.GetItemParent(selected)
  1623             pou_name = GetParentName(self.TypesTree, selected, ITEM_POU)
  1659             item_type = self.TypesTree.GetPyData(item)
       
  1660             while item_type != ITEM_POU:
       
  1661                 item = self.TypesTree.GetItemParent(item)
       
  1662                 item_type = self.TypesTree.GetPyData(item)
       
  1663             pou_name = self.TypesTree.GetItemText(item)
       
  1664             if data == ITEM_TRANSITION:
  1624             if data == ITEM_TRANSITION:
  1665                 tagname = self.Controler.ComputePouTransitionName(pou_name, name)
  1625                 tagname = self.Controler.ComputePouTransitionName(pou_name, name)
  1666             elif data == ITEM_ACTION:
  1626             elif data == ITEM_ACTION:
  1667                 tagname = self.Controler.ComputePouActionName(pou_name, name)
  1627                 tagname = self.Controler.ComputePouActionName(pou_name, name)
  1668             self.EditProjectElement(data, tagname)
  1628             self.EditProjectElement(data, tagname)
  1676         elif data == ITEM_POU:
  1636         elif data == ITEM_POU:
  1677             self.EditProjectElement(data, self.Controler.ComputePouName(name), True)
  1637             self.EditProjectElement(data, self.Controler.ComputePouName(name), True)
  1678         elif data == ITEM_CONFIGURATION:
  1638         elif data == ITEM_CONFIGURATION:
  1679             self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name), True)
  1639             self.EditProjectElement(data, self.Controler.ComputeConfigurationName(name), True)
  1680         elif data == ITEM_RESOURCE:
  1640         elif data == ITEM_RESOURCE:
  1681             item = self.TypesTree.GetItemParent(select_item)
  1641             config_name = GetParentName(self.TypesTree, select_item, ITEM_CONFIGURATION)
  1682             item_type = self.TypesTree.GetPyData(item)
       
  1683             while item_type != ITEM_CONFIGURATION:
       
  1684                 item = self.TypesTree.GetItemParent(item)
       
  1685                 item_type = self.TypesTree.GetPyData(item)
       
  1686             config_name = self.TypesTree.GetItemText(item)
       
  1687             self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name), True)
  1642             self.EditProjectElement(data, self.Controler.ComputeConfigurationResourceName(config_name, name), True)
  1688         elif data in [ITEM_TRANSITION, ITEM_ACTION]:
  1643         elif data in [ITEM_TRANSITION, ITEM_ACTION]:
  1689             item = self.TypesTree.GetItemParent(select_item)
  1644             pou_name = GetParentName(self.TypesTree, select_item, ITEM_POU)
  1690             item_type = self.TypesTree.GetPyData(item)
       
  1691             while item_type != ITEM_POU:
       
  1692                 item = self.TypesTree.GetItemParent(item)
       
  1693                 item_type = self.TypesTree.GetPyData(item)
       
  1694             pou_name = self.TypesTree.GetItemText(item)
       
  1695             if data == ITEM_TRANSITION:
  1645             if data == ITEM_TRANSITION:
  1696                 tagname = self.Controler.ComputePouTransitionName(pou_name, name)
  1646                 tagname = self.Controler.ComputePouTransitionName(pou_name, name)
  1697             elif data == ITEM_ACTION:
  1647             elif data == ITEM_ACTION:
  1698                 tagname = self.Controler.ComputePouActionName(pou_name, name)
  1648                 tagname = self.Controler.ComputePouActionName(pou_name, name)
  1699             self.EditProjectElement(data, tagname, True)
  1649             self.EditProjectElement(data, tagname, True)
  1722             old_selected = self.TabsOpened.GetSelection()
  1672             old_selected = self.TabsOpened.GetSelection()
  1723             if old_selected != openedidx:
  1673             if old_selected != openedidx:
  1724                 if old_selected >= 0:
  1674                 if old_selected >= 0:
  1725                     self.TabsOpened.GetPage(old_selected).ResetBuffer()
  1675                     self.TabsOpened.GetPage(old_selected).ResetBuffer()
  1726                 self.TabsOpened.SetSelection(openedidx)
  1676                 self.TabsOpened.SetSelection(openedidx)
  1727             self.TabsOpened.GetPage(openedidx).RefreshView()
       
  1728             self.VariablePanelIndexer.ChangeVariablePanel(tagname)
  1677             self.VariablePanelIndexer.ChangeVariablePanel(tagname)
  1729             self.RefreshPageTitles()
  1678             self.RefreshPageTitles()
  1730             self.RefreshFileMenu()
  1679             self._Refresh(FILEMENU, EDITMENU, TOOLBAR)
  1731             self.RefreshEditMenu()
       
  1732             self.RefreshToolBar()
       
  1733         elif not onlyopened:
  1680         elif not onlyopened:
  1734             if elementtype == ITEM_CONFIGURATION:
  1681             if elementtype == ITEM_CONFIGURATION:
  1735                 new_window = ConfigurationEditor(self.TabsOpened, tagname, self, self.Controler)
  1682                 new_window = ConfigurationEditor(self.TabsOpened, tagname, self, self.Controler)
  1736                 self.AddPage(new_window, "")
  1683                 self.AddPage(new_window, "")
  1737                 self.VariablePanelIndexer.AddVariablePanel(tagname, "config")
  1684                 self.VariablePanelIndexer.AddVariablePanel(tagname, "config")
  1773                 window = self.TabsOpened.GetPage(i)
  1720                 window = self.TabsOpened.GetPage(i)
  1774                 if window.GetTagName() == tagname:
  1721                 if window.GetTagName() == tagname:
  1775                     self.TabsOpened.SetSelection(i)
  1722                     self.TabsOpened.SetSelection(i)
  1776                     window.SetFocus()
  1723                     window.SetFocus()
  1777                     self.RefreshPageTitles()
  1724                     self.RefreshPageTitles()
  1778                     self.RefreshFileMenu()
  1725                     self._Refresh(FILEMENU, EDITMENU, TOOLBAR)
  1779                     self.RefreshEditMenu()
       
  1780                     self.RefreshToolBar()
       
  1781     
  1726     
  1782     def OnTypesTreeRightUp(self, event):
  1727     def OnTypesTreeRightUp(self, event):
  1783         if wx.Platform == '__WXMSW__':
  1728         if wx.Platform == '__WXMSW__':
  1784             item = event.GetItem()
  1729             item = event.GetItem()
  1785         else:
  1730         else:
  1813             new_id = wx.NewId()
  1758             new_id = wx.NewId()
  1814             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Rename")
  1759             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Rename")
  1815             self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id)
  1760             self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id)
  1816             new_id = wx.NewId()
  1761             new_id = wx.NewId()
  1817             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete")
  1762             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete")
  1818             self.Bind(wx.EVT_MENU, self.OnRemovePouMenu, id=new_id)
  1763             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
  1819             self.PopupMenu(menu)
  1764             self.PopupMenu(menu)
  1820         elif type == ITEM_CONFIGURATION:
  1765         elif type == ITEM_CONFIGURATION:
  1821             menu = wx.Menu(title='')
  1766             menu = wx.Menu(title='')
  1822             new_id = wx.NewId()
  1767             new_id = wx.NewId()
  1823             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Resource")
  1768             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Resource")
  1824             self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id)
  1769             self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id)
  1825             new_id = wx.NewId()
  1770             new_id = wx.NewId()
  1826             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete")
  1771             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete")
  1827             self.Bind(wx.EVT_MENU, self.OnRemoveConfigurationMenu, id=new_id)
  1772             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
  1828             self.PopupMenu(menu)
  1773             self.PopupMenu(menu)
  1829         elif type in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]:
  1774         elif type in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]:
  1830             menu = wx.Menu(title='')
  1775             menu = wx.Menu(title='')
  1831             new_id = wx.NewId()
  1776             new_id = wx.NewId()
  1832             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete")
  1777             AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete")
  1833             if type == ITEM_DATATYPE:
  1778             self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id)
  1834                 self.Bind(wx.EVT_MENU, self.OnRemoveDataTypeMenu, id=new_id)
       
  1835             elif type == ITEM_TRANSITION:
       
  1836                 self.Bind(wx.EVT_MENU, self.OnRemoveTransitionMenu, id=new_id)
       
  1837             elif type == ITEM_ACTION:
       
  1838                 self.Bind(wx.EVT_MENU, self.OnRemoveActionMenu, id=new_id)
       
  1839             elif type == ITEM_RESOURCE:
       
  1840                 self.Bind(wx.EVT_MENU, self.OnRemoveResourceMenu, id=new_id)
       
  1841             self.PopupMenu(menu)
  1779             self.PopupMenu(menu)
  1842         elif type in ITEMS_UNEDITABLE:
  1780         elif type in ITEMS_UNEDITABLE:
  1843             if name == "Data Types":
  1781             if name == "Data Types":
  1844                 menu = wx.Menu(title='')
  1782                 menu = wx.Menu(title='')
  1845                 new_id = wx.NewId()
  1783                 new_id = wx.NewId()
  1911         if infos.get("elmt_type", None) is not None:
  1849         if infos.get("elmt_type", None) is not None:
  1912             self.InstancesTree.SetItemText(root, "%s (%s)"%(infos["name"], infos["elmt_type"]))
  1850             self.InstancesTree.SetItemText(root, "%s (%s)"%(infos["name"], infos["elmt_type"]))
  1913         else:
  1851         else:
  1914             self.InstancesTree.SetItemText(root, infos["name"])
  1852             self.InstancesTree.SetItemText(root, infos["name"])
  1915         self.InstancesTree.SetPyData(root, (infos["type"], infos.get("tagname", None)))
  1853         self.InstancesTree.SetPyData(root, (infos["type"], infos.get("tagname", None)))
  1916         self.InstancesTree.SetItemImage(root, self.InstancesTreeImageDict[infos["type"]])      
  1854         self.InstancesTree.SetItemImage(root, self.TreeImageDict[infos["type"]])
  1917             
  1855             
  1918         if wx.VERSION >= (2, 6, 0):
  1856         if wx.VERSION >= (2, 6, 0):
  1919             item, root_cookie = self.InstancesTree.GetFirstChild(root)
  1857             item, root_cookie = self.InstancesTree.GetFirstChild(root)
  1920         else:
  1858         else:
  1921             item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
  1859             item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
  2640         self.RefreshTypesTree()
  2578         self.RefreshTypesTree()
  2641         self.VariablePanelIndexer.ClearErrors()
  2579         self.VariablePanelIndexer.ClearErrors()
  2642         for i in xrange(self.TabsOpened.GetPageCount()):
  2580         for i in xrange(self.TabsOpened.GetPageCount()):
  2643             viewer = self.TabsOpened.GetPage(i)
  2581             viewer = self.TabsOpened.GetPage(i)
  2644             viewer.ClearErrors()
  2582             viewer.ClearErrors()
  2645         
  2583 
       
  2584     RefreshFunctions = {
       
  2585         TITLE : RefreshTitle,
       
  2586         TOOLBAR : RefreshToolBar,
       
  2587         FILEMENU : RefreshFileMenu,
       
  2588         EDITMENU : RefreshEditMenu,
       
  2589         DISPLAYMENU : RefreshDisplayMenu,
       
  2590         TYPESTREE : RefreshTypesTree,
       
  2591         INSTANCESTREE : RefreshInstancesTree, 
       
  2592         LIBRARYTREE : RefreshLibraryTree,
       
  2593         SCALING : RefreshScaling}
       
  2594 
  2646 current_num = 0
  2595 current_num = 0
  2647 def GetNewNum():
  2596 def GetNewNum():
  2648     global current_num
  2597     global current_num
  2649     current_num += 1
  2598     current_num += 1
  2650     return current_num
  2599     return current_num
  4541     def ClearErrors(self):
  4490     def ClearErrors(self):
  4542         self.Table.ClearErrors()
  4491         self.Table.ClearErrors()
  4543         self.Table.ResetView(self.VariablesGrid)
  4492         self.Table.ResetView(self.VariablesGrid)
  4544 
  4493 
  4545 #-------------------------------------------------------------------------------
  4494 #-------------------------------------------------------------------------------
  4546 #                            Variables Editor Panel
  4495 #                            Debug Variables Panel
  4547 #-------------------------------------------------------------------------------
  4496 #-------------------------------------------------------------------------------
  4548 
  4497 
  4549 class VariableTableItem(DebugDataConsumer):
  4498 class VariableTableItem(DebugDataConsumer):
  4550     
  4499     
  4551     def __init__(self, parent, variable, value):
  4500     def __init__(self, parent, variable, value):