diff -r 0ea836add01f -r 0f10f5091245 PLCOpenEditor.py --- a/PLCOpenEditor.py Wed May 02 00:32:15 2012 +0200 +++ b/PLCOpenEditor.py Thu May 03 19:02:17 2012 +0200 @@ -114,7 +114,7 @@ from DataTypeEditor import * from PLCControler import * from SearchResultPanel import SearchResultPanel -from controls import CustomGrid, CustomTable +from controls import CustomGrid, CustomTable, LibraryPanel # Define PLCOpenEditor controls id [ID_PLCOPENEDITOR, ID_PLCOPENEDITORLEFTNOTEBOOK, @@ -122,10 +122,11 @@ ID_PLCOPENEDITORTYPESTREE, ID_PLCOPENEDITORINSTANCESTREE, ID_PLCOPENEDITORMAINSPLITTER, ID_PLCOPENEDITORSECONDSPLITTER, ID_PLCOPENEDITORTHIRDSPLITTER, ID_PLCOPENEDITORLIBRARYPANEL, - ID_PLCOPENEDITORLIBRARYTREE, ID_PLCOPENEDITORLIBRARYCOMMENT, - ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITORTABSOPENED, - ID_PLCOPENEDITOREDITORMENUTOOLBAR, ID_PLCOPENEDITOREDITORTOOLBAR, -] = [wx.NewId() for _init_ctrls in range(16)] + ID_PLCOPENEDITORLIBRARYSEARCHCTRL, ID_PLCOPENEDITORLIBRARYTREE, + ID_PLCOPENEDITORLIBRARYCOMMENT, ID_PLCOPENEDITORTABSOPENED, + ID_PLCOPENEDITORTABSOPENED, ID_PLCOPENEDITOREDITORMENUTOOLBAR, + ID_PLCOPENEDITOREDITORTOOLBAR, +] = [wx.NewId() for _init_ctrls in range(17)] # Define PLCOpenEditor FileMenu extra items id [ID_PLCOPENEDITORFILEMENUGENERATE, @@ -305,7 +306,42 @@ self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!")%name) return DeleteElementFunction +def SimplifyTabOrganization(tabs, rect): + for tab in tabs: + if tab["pos"][0] == rect.x: + others = [t for t in tabs if t != tab] + others.sort(lambda x,y: cmp(x["pos"][0], y["pos"][0])) + for other in others: + if (other["pos"][1] == tab["pos"][1] and + other["size"][1] == tab["size"][1] and + other["pos"][0] == tab["pos"][0] + tab["size"][0] + 7): + + tab["size"] = (tab["size"][0] + other["size"][0] + 7, tab["size"][1]) + tab["pages"].extend(other["pages"]) + tabs.remove(other) + + if tab["size"][0] == rect.width: + return True + + elif tab["pos"][1] == rect.y: + others = [t for t in tabs if t != tab] + others.sort(lambda x,y: cmp(x["pos"][1], y["pos"][1])) + for other in others: + if (other["pos"][0] == tab["pos"][0] and + other["size"][0] == tab["size"][0] and + other["pos"][1] == tab["pos"][1] + tab["size"][1] + 7): + + tab["size"] = (tab["size"][0], tab["size"][1] + other["size"][1] + 7) + tab["pages"].extend(other["pages"]) + tabs.remove(other) + + if tab["size"][1] == rect.height: + return True + return False + def ComputeTabsOrganization(tabs, rect): + if len(tabs) == 0: + return tabs if len(tabs) == 1: return tabs[0] split = None @@ -335,6 +371,9 @@ return {"split": split, "tab": split_tab, "others": ComputeTabsOrganization(tabs, split_rect)} + else: + if SimplifyTabOrganization(tabs, rect): + return ComputeTabsOrganization(tabs, rect) return tabs #------------------------------------------------------------------------------- @@ -469,22 +508,6 @@ self._init_coll_DisplayMenu_Items(self.DisplayMenu) self._init_coll_HelpMenu_Items(self.HelpMenu) - def _init_coll_MainLibrarySizer_Items(self, parent): - parent.AddWindow(self.LibraryTree, 0, border=0, flag=wx.GROW) - parent.AddSizer(self.LibraryComment, 0, border=0, flag=wx.GROW) - - def _init_coll_MainLibrarySizer_Growables(self, parent): - parent.AddGrowableCol(0) - parent.AddGrowableRow(0) - - def _init_sizers(self): - self.MainLibrarySizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) - - self._init_coll_MainLibrarySizer_Growables(self.MainLibrarySizer) - self._init_coll_MainLibrarySizer_Items(self.MainLibrarySizer) - - self.LibraryPanel.SetSizer(self.MainLibrarySizer) - def _init_ctrls(self, prnt): wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name='IDEFrame', parent=prnt, pos=wx.DefaultPosition, size=wx.Size(1000, 600), @@ -537,10 +560,10 @@ self.TabsOpened = wx.aui.AuiNotebook(self, ID_PLCOPENEDITORTABSOPENED, style=wx.aui.AUI_NB_DEFAULT_STYLE|wx.aui.AUI_NB_WINDOWLIST_BUTTON) - self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGING, - self.OnPouSelectedChanging) - self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, - self.OnPouSelectedChanged) + #self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGING, + # self.OnPouSelectedChanging) + #self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, + # self.OnPouSelectedChanged) self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnPageClose) self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_END_DRAG, @@ -705,31 +728,13 @@ # Creating Library Panel #----------------------------------------------------------------------- - self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL, - name='LibraryPanel', parent=self.RightNoteBook, pos=wx.Point(0, - 0), size=wx.Size(0, 0), style=0) + self.LibraryPanel = LibraryPanel(self, True) self.MainTabs["LibraryPanel"] = (self.LibraryPanel, _("Library")) self.RightNoteBook.AddPage(*self.MainTabs["LibraryPanel"]) - - self.LibraryTree = wx.TreeCtrl(id=ID_PLCOPENEDITORLIBRARYTREE, - name='LibraryTree', parent=self.LibraryPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 0), - style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_HIDE_ROOT|wx.TR_LINES_AT_ROOT) - self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnLibraryTreeItemSelected, - id=ID_PLCOPENEDITORLIBRARYTREE) - self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnLibraryTreeBeginDrag, - id=ID_PLCOPENEDITORLIBRARYTREE) - - self.LibraryComment = wx.TextCtrl(id=ID_PLCOPENEDITORLIBRARYCOMMENT, - name='LibraryComment', parent=self.LibraryPanel, - pos=wx.Point(0, 0), size=wx.Size(0, 160), - style=wx.TE_READONLY|wx.TE_MULTILINE) - + self._init_utils() self.SetMenuBar(self.MenuBar) - - self._init_sizers() - + if self.EnableDebug: self.DebugVariablePanel = DebugVariablePanel(self.RightNoteBook, self.Controler) self.MainTabs["DebugVariablePanel"] = (self.DebugVariablePanel, _("Debugger")) @@ -834,12 +839,14 @@ event.Skip() def GetProjectConfiguration(self): - if self.Config.HasEntry("projects"): - projects = cPickle.loads(str(self.Config.Read("projects"))) - else: - projects = {} - - return projects.setdefault(os.path.realpath(self.Controler.GetFilePath()), {}) + projects = {} + try: + if self.Config.HasEntry("projects"): + projects = cPickle.loads(str(self.Config.Read("projects"))) + except: + pass + + return projects.get(os.path.realpath(self.Controler.GetFilePath()), {}) def SavePageState(self, page): state = page.GetState() @@ -942,7 +949,21 @@ selected = page_idx if selected is not None: wx.CallAfter(notebook.SetSelection, selected) - + + def ResetPerspective(self): + if USE_AUI and self.DefaultPerspective is not None: + self.AUIManager.LoadPerspective(self.DefaultPerspective["perspective"]) + + for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]: + for idx in xrange(notebook.GetPageCount()): + notebook.RemovePage(0) + + notebooks = self.DefaultPerspective["notebooks"] + for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), + (self.BottomNoteBook, "bottomnotebook"), + (self.RightNoteBook, "rightnotebook")]: + self.LoadTabOrganization(notebook, notebooks.get(entry_name)) + def RestoreLastState(self): frame_size = None if self.Config.HasEntry("framesize"): @@ -966,21 +987,24 @@ "notebooks": notebooks, } - if self.Config.HasEntry("perspective"): - self.AUIManager.LoadPerspective(str(self.Config.Read("perspective"))) - - if self.Config.HasEntry("notebooks"): - notebooks = cPickle.loads(str(self.Config.Read("notebooks"))) - - for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]: - for idx in xrange(notebook.GetPageCount()): - notebook.RemovePage(0) - - for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), - (self.BottomNoteBook, "bottomnotebook"), - (self.RightNoteBook, "rightnotebook")]: - self.LoadTabOrganization(notebook, notebooks.get(entry_name)) - + try: + if self.Config.HasEntry("perspective"): + self.AUIManager.LoadPerspective(str(self.Config.Read("perspective"))) + + if self.Config.HasEntry("notebooks"): + notebooks = cPickle.loads(str(self.Config.Read("notebooks"))) + + for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]: + for idx in xrange(notebook.GetPageCount()): + notebook.RemovePage(0) + + for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), + (self.BottomNoteBook, "bottomnotebook"), + (self.RightNoteBook, "rightnotebook")]: + self.LoadTabOrganization(notebook, notebooks.get(entry_name)) + except: + self.ResetPerspective() + self.LoadProjectOrganization() def SaveLastState(self): @@ -1010,30 +1034,37 @@ if USE_AUI and self.Controler is not None: tabs = [] - if self.Config.HasEntry("projects"): - projects = cPickle.loads(str(self.Config.Read("projects"))) - else: - projects = {} + projects = {} + try: + if self.Config.HasEntry("projects"): + projects = cPickle.loads(str(self.Config.Read("projects"))) + except: + pass project_infos = projects.setdefault(os.path.realpath(self.Controler.GetFilePath()), {}) project_infos["tabs"] = self.SaveTabOrganization(self.TabsOpened) if self.EnableDebug: project_infos["debug_vars"] = self.DebugVariablePanel.GetDebugVariables() - + self.Config.Write("projects", cPickle.dumps(projects)) self.Config.Flush() def LoadProjectOrganization(self): - if USE_AUI and self.Controler is not None and self.Config.HasEntry("projects"): - projects = cPickle.loads(str(self.Config.Read("projects"))) - - project = projects.get(os.path.realpath(self.Controler.GetFilePath())) - if project is not None: - self.LoadTabOrganization(self.TabsOpened, project["tabs"]) - - if self.EnableDebug: - for variable in project["debug_vars"]: + if USE_AUI and self.Controler is not None: + project = self.GetProjectConfiguration() + + try: + if project.has_key("tabs"): + self.LoadTabOrganization(self.TabsOpened, project["tabs"]) + except: + self.DeleteAllPages() + + if self.EnableDebug: + try: + for variable in project.get("debug_vars", []): self.DebugVariablePanel.InsertValue(variable, force=True) + except: + self.DebugVariablePanel.ResetGrid() #------------------------------------------------------------------------------- # General Functions @@ -1048,7 +1079,7 @@ DISPLAYMENU : self.RefreshDisplayMenu, TYPESTREE : self.RefreshTypesTree, INSTANCESTREE : self.RefreshInstancesTree, - LIBRARYTREE : self.RefreshLibraryTree, + LIBRARYTREE : self.RefreshLibraryPanel, SCALING : self.RefreshScaling, PAGETITLES: self.RefreshPageTitles} @@ -1232,7 +1263,8 @@ self.DeleteAllPages() self.TypesTree.DeleteAllItems() self.InstancesTree.DeleteAllItems() - self.LibraryTree.DeleteAllItems() + self.LibraryPanel.ResetTree() + self.LibraryPanel.SetControler(None) self.Controler = None def OnCloseTabMenu(self, event): @@ -1493,18 +1525,7 @@ return ZoomFunction def OnResetPerspective(self, event): - if USE_AUI and self.DefaultPerspective is not None: - self.AUIManager.LoadPerspective(self.DefaultPerspective["perspective"]) - - for notebook in [self.LeftNoteBook, self.BottomNoteBook, self.RightNoteBook]: - for idx in xrange(notebook.GetPageCount()): - notebook.RemovePage(0) - - notebooks = self.DefaultPerspective["notebooks"] - for notebook, entry_name in [(self.LeftNoteBook, "leftnotebook"), - (self.BottomNoteBook, "bottomnotebook"), - (self.RightNoteBook, "rightnotebook")]: - self.LoadTabOrganization(notebook, notebooks.get(entry_name)) + self.ResetPerspective() #------------------------------------------------------------------------------- # Project Editor Panels Management Functions @@ -1749,7 +1770,7 @@ self.Controler.ChangePouName(old_name, new_name) self.RefreshEditorNames(self.Controler.ComputePouName(old_name), self.Controler.ComputePouName(new_name)) - self.RefreshLibraryTree() + self.RefreshLibraryPanel() self.RefreshPageTitles() elif itemtype == ITEM_TRANSITION: pou_name = GetParentName(self.TypesTree, item, ITEM_POU) @@ -2324,86 +2345,12 @@ self.DebugVariablePanel.InsertValue(iec_path) #------------------------------------------------------------------------------- -# Library Tree Management Functions -#------------------------------------------------------------------------------- - - def RefreshLibraryTree(self): - if self.Controler is not None: - to_delete = [] - selected_name = None - selected = self.LibraryTree.GetSelection() - if selected.IsOk(): - selected_pydata = self.LibraryTree.GetPyData(selected) - if selected_pydata is not None and selected_pydata["type"] != CATEGORY: - selected_name = self.LibraryTree.GetItemText(selected) - blocktypes = self.Controler.GetBlockTypes() - root = self.LibraryTree.GetRootItem() - if not root.IsOk(): - root = self.LibraryTree.AddRoot("") - if wx.VERSION >= (2, 6, 0): - category_item, root_cookie = self.LibraryTree.GetFirstChild(root) - else: - category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0) - for category in blocktypes: - category_name = category["name"] - if not category_item.IsOk(): - category_item = self.LibraryTree.AppendItem(root, _(category_name)) - if wx.Platform != '__WXMSW__': - category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) - else: - self.LibraryTree.SetItemText(category_item, _(category_name)) - self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY}) - if wx.VERSION >= (2, 6, 0): - blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item) - else: - blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item, 0) - for blocktype in category["list"]: - if not blocktype_item.IsOk(): - blocktype_item = self.LibraryTree.AppendItem(category_item, blocktype["name"]) - if wx.Platform != '__WXMSW__': - blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) - else: - self.LibraryTree.SetItemText(blocktype_item, blocktype["name"]) - self.LibraryTree.SetPyData(blocktype_item, {"type" : BLOCK, "block_type" : blocktype["type"], "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])}) - if selected_name == blocktype["name"]: - self.LibraryTree.SelectItem(blocktype_item) - comment = blocktype["comment"] - self.LibraryComment.SetValue(_(comment) + blocktype.get("usage", "")) - blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) - while blocktype_item.IsOk(): - to_delete.append(blocktype_item) - blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie) - category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) - while category_item.IsOk(): - to_delete.append(category_item) - category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) - for item in to_delete: - self.LibraryTree.Delete(item) - - def OnLibraryTreeItemSelected(self, event): - selected = event.GetItem() - pydata = self.LibraryTree.GetPyData(selected) - if pydata is not None and pydata["type"] != CATEGORY: - blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"]) - if blocktype: - comment = blocktype["comment"] - self.LibraryComment.SetValue(_(comment) + blocktype.get("usage", "")) - else: - self.LibraryComment.SetValue("") - else: - self.LibraryComment.SetValue("") - event.Skip() - - def OnLibraryTreeBeginDrag(self, event): - selected = event.GetItem() - pydata = self.LibraryTree.GetPyData(selected) - if pydata is not None and pydata["type"] == BLOCK: - data = wx.TextDataObject(str((self.LibraryTree.GetItemText(selected), - pydata["block_type"], "", pydata["inputs"]))) - dragSource = wx.DropSource(self.LibraryTree) - dragSource.SetData(data) - dragSource.DoDragDrop() - +# Library Panel Management Function +#------------------------------------------------------------------------------- + + def RefreshLibraryPanel(self): + self.LibraryPanel.RefreshTree() + #------------------------------------------------------------------------------- # ToolBars Management Functions #------------------------------------------------------------------------------- @@ -2984,6 +2931,7 @@ self.Controler = PLCControler() result = self.Controler.OpenXMLFile(fileOpen) if result is None: + self.LibraryPanel.SetControler(self.Controler) self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE) # Define PLCOpenEditor icon @@ -3073,6 +3021,7 @@ self.ResetView() self.Controler = PLCControler() self.Controler.CreateNewProject(properties) + self.LibraryPanel.SetControler(self.Controler) self._Refresh(TITLE, FILEMENU, EDITMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE) @@ -3097,6 +3046,7 @@ self.Controler = PLCControler() result = self.Controler.OpenXMLFile(filepath) if result is None: + self.LibraryPanel.SetControler(self.Controler) self.LoadProjectOrganization() self._Refresh(TYPESTREE, INSTANCESTREE, LIBRARYTREE) self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU)