# HG changeset patch # User laurent # Date 1341177619 -7200 # Node ID a1d970365e41d9b4e155c1cc7fa7419d9d4df231 # Parent f5cea1a6851e0474550bad50d0696f41a16bfaa3 Adding support for beremiz extensions to define custom file editors for project files diff -r f5cea1a6851e -r a1d970365e41 Beremiz.py --- a/Beremiz.py Thu Jun 28 16:42:07 2012 +0200 +++ b/Beremiz.py Sun Jul 01 23:20:19 2012 +0200 @@ -605,12 +605,14 @@ if self.CTR is not None: selected = self.TabsOpened.GetSelection() if selected >= 0: - graphic_viewer = isinstance(self.TabsOpened.GetPage(selected), Viewer) + window = self.TabsOpened.GetPage(selected) + viewer_is_modified = window.IsModified() + is_viewer = isinstance(window, Viewer) else: - graphic_viewer = False + viewer_is_modified = is_viewer = False if self.TabsOpened.GetPageCount() > 0: self.FileMenu.Enable(wx.ID_CLOSE, True) - if graphic_viewer: + if is_viewer: self.FileMenu.Enable(wx.ID_PREVIEW, True) self.FileMenu.Enable(wx.ID_PRINT, True) MenuToolBar.EnableTool(wx.ID_PRINT, True) @@ -624,7 +626,7 @@ self.FileMenu.Enable(wx.ID_PRINT, False) MenuToolBar.EnableTool(wx.ID_PRINT, False) self.FileMenu.Enable(wx.ID_PAGE_SETUP, True) - project_modified = self.CTR.ProjectTestModified() + project_modified = self.CTR.ProjectTestModified() or viewer_is_modified self.FileMenu.Enable(wx.ID_SAVE, project_modified) MenuToolBar.EnableTool(wx.ID_SAVE, project_modified) self.FileMenu.Enable(wx.ID_SAVEAS, True) @@ -876,12 +878,20 @@ self.RefreshAll() def OnSaveProjectMenu(self, event): + selected = self.TabsOpened.GetSelection() + if selected != -1: + window = self.TabsOpened.GetPage(selected) + window.Save() if self.CTR is not None: self.CTR.SaveProject() self.RefreshAll() self._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES) def OnSaveProjectAsMenu(self, event): + selected = self.TabsOpened.GetSelection() + if selected != -1: + window = self.TabsOpened.GetPage(selected) + window.SaveAs() if self.CTR is not None: self.CTR.SaveProjectAs() self.RefreshAll() diff -r f5cea1a6851e -r a1d970365e41 ConfigTreeNode.py --- a/ConfigTreeNode.py Thu Jun 28 16:42:07 2012 +0200 +++ b/ConfigTreeNode.py Sun Jul 01 23:20:19 2012 +0200 @@ -408,15 +408,13 @@ def _OpenView(self, name=None, onlyopened=False): if self.EditorType is not None: app_frame = self.GetCTRoot().AppFrame - if self._View is None: + if self._View is None and not onlyopened: self._View = self.EditorType(app_frame.TabsOpened, self, app_frame) - + + if self._View is not None: app_frame.EditProjectElement(self._View, self.CTNName()) - elif onlyopened: - app_frame.EditProjectElement(self._View, self.CTNName(), onlyopened) - return self._View return None diff -r f5cea1a6851e -r a1d970365e41 ProjectController.py --- a/ProjectController.py Thu Jun 28 16:42:07 2012 +0200 +++ b/ProjectController.py Sun Jul 01 23:20:19 2012 +0200 @@ -939,6 +939,10 @@ def _OpenProjectFiles(self): self._OpenView("Project files") + _FileEditors = {} + def _OpenFileEditor(self, filepath): + self._OpenView(filepath) + def _OpenView(self, name=None, onlyopened=False): if name == "IEC code": if self._IECCodeView is None: @@ -955,11 +959,9 @@ self._IECCodeView.SetText(text = text) self._IECCodeView.SetIcon(GetBitmap("ST")) + if self._IECCodeView is not None: self.AppFrame.EditProjectElement(self._IECCodeView, name) - elif onlyopened: - self.AppFrame.EditProjectElement(self._IECCodeView, name, onlyopened) - return self._IECCodeView elif name == "IEC raw code": @@ -972,25 +974,56 @@ self._IECRawCodeView.SetKeywords(IEC_KEYWORDS) self._IECRawCodeView.RefreshView() self._IECRawCodeView.SetIcon(GetBitmap("ST")) - + + if self._IECRawCodeView is not None: self.AppFrame.EditProjectElement(self._IECRawCodeView, name) - elif onlyopened: - self.AppFrame.EditProjectElement(self._IECRawCodeView, name, onlyopened) - return self._IECRawCodeView elif name == "Project files": if self._ProjectFilesView is None: self._ProjectFilesView = FileManagementPanel(self.AppFrame.TabsOpened, self, name, self._getProjectFilesPath(), True) + extensions = [] + for extension, name, editor in features.file_editors: + if extension not in extensions: + extensions.append(extension) + self._ProjectFilesView.SetEditableFileExtensions(extensions) + + if self._ProjectFilesView is not None: self.AppFrame.EditProjectElement(self._ProjectFilesView, name) - elif onlyopened: - self.AppFrame.EditProjectElement(self._ProjectFilesView, name, onlyopened) + return self._ProjectFilesView + + elif name is not None and os.path.isfile(name): + if not self._FileEditors.has_key(name): + file_extension = os.path.splitext(name)[1] + + editors = dict([(editor_name, editor) + for extension, editor_name, editor in features.file_editors + if extension == file_extension]) + + editor_name = None + if len(editors) == 1: + editor_name = editors.keys()[0] + elif len(editors) > 0: + names = editors.keys() + dialog = wx.SingleChoiceDialog(self.ParentWindow, + _("Select an editor:"), _("Editor selection"), + names, wx.OK|wx.CANCEL) + if dialog.ShowModal() == wx.ID_OK: + editor_name = names[dialog.GetSelection()] + dialog.Destroy() + + if editor_name is not None: + editor = editors[editor_name]() + self._FileEditors[name] = editor(self.AppFrame.TabsOpened, self, name, self.AppFrame) + self._FileEditors[name].SetIcon(GetBitmap("FILE")) + + if self._FileEditors.has_key(name): + self.AppFrame.EditProjectElement(self._FileEditors[name], name) - return self._ProjectFilesView - + return self._FileEditors[name] else: return ConfigTreeNode._OpenView(self, name, onlyopened) @@ -1002,6 +1035,8 @@ self._IECRawCodeView = None if self._ProjectFilesView == view: self._ProjectFilesView = None + if view in self._FileEditors.values(): + self._FileEditors.pop(view.GetTagName()) def _Clean(self): self._CloseView(self._IECCodeView) diff -r f5cea1a6851e -r a1d970365e41 canfestival/canfestival.py --- a/canfestival/canfestival.py Thu Jun 28 16:42:07 2012 +0200 +++ b/canfestival/canfestival.py Sun Jul 01 23:20:19 2012 +0200 @@ -108,8 +108,8 @@ def GetCanDevice(self): return self.CanFestivalSlaveNode.getCan_Device() - def _OpenView(self): - ConfigTreeNode._OpenView(self) + def _OpenView(self, name=None, onlyopened=False): + ConfigTreeNode._OpenView(self, name, onlyopened) if self._View is not None: self._View.SetBusId(self.GetCurrentLocation()) return self._View @@ -273,10 +273,8 @@ manager = MiniNodeManager(self, masterpath, self.CTNFullName() + ".generated_master") self._GeneratedMasterView = MasterViewer(app_frame.TabsOpened, manager, app_frame) - app_frame.EditProjectElement(self._GeneratedMasterView, name) - - elif onlyopened: - app_frame.EditProjectElement(self._IECCodeView, name, onlyopened) + if self._GeneratedMasterView is not None: + app_frame.EditProjectElement(self._IECCodeView, name) return self._GeneratedMasterView else: diff -r f5cea1a6851e -r a1d970365e41 features.py --- a/features.py Thu Jun 28 16:42:07 2012 +0200 +++ b/features.py Sun Jul 01 23:20:19 2012 +0200 @@ -1,5 +1,6 @@ -libraries = [('Python','py_ext.PythonLibrary'), - ('SVGUI','svgui.SVGUILibrary')] +libraries = [ + ('Python', 'py_ext.PythonLibrary'), + ('SVGUI', 'svgui.SVGUILibrary')] catalog = [ ('canfestival', _('CANopen support'), _('Map located variables over CANopen'), 'canfestival.canfestival.RootClass'), @@ -8,3 +9,4 @@ ('wxglade_hmi', _('WxGlade GUI'), _('Add a simple WxGlade based GUI.'), 'wxglade_hmi.WxGladeHMI'), ('svgui', _('SVGUI'), _('Experimental web based HMI'), 'svgui.SVGUI')] +file_editors = [] diff -r f5cea1a6851e -r a1d970365e41 images/FILE.png Binary file images/FILE.png has changed diff -r f5cea1a6851e -r a1d970365e41 images/icons.svg --- a/images/icons.svg Thu Jun 28 16:42:07 2012 +0200 +++ b/images/icons.svg Sun Jul 01 23:20:19 2012 +0200 @@ -43,9 +43,9 @@ pagecolor="#ffffff" id="base" showgrid="false" - inkscape:zoom="7.2407738" - inkscape:cx="596.13887" - inkscape:cy="800.65537" + inkscape:zoom="28.963095" + inkscape:cx="519.38634" + inkscape:cy="721.386" inkscape:window-x="0" inkscape:window-y="24" inkscape:current-layer="svg2" @@ -87871,6 +87871,164 @@ id="radialGradient3101" xlink:href="#radialGradient8198" inkscape:collect="always" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %% Extension Cfile Pyfile wxGlade SVGUI FOLDER %% + sodipodi:role="line">%% Extension Cfile Pyfile wxGlade SVGUI FOLDER FILE %% + + + + + + + + + + + + + + + + diff -r f5cea1a6851e -r a1d970365e41 util/FileManagementPanel.py --- a/util/FileManagementPanel.py Thu Jun 28 16:42:07 2012 +0200 +++ b/util/FileManagementPanel.py Sun Jul 01 23:20:19 2012 +0200 @@ -268,7 +268,8 @@ for idx, (name, bitmap, help) in enumerate([ ("DeleteButton", "remove_element", _("Remove file from left folder")), ("LeftCopyButton", "LeftCopy", _("Copy file from right folder to left")), - ("RightCopyButton", "RightCopy", _("copy file from left folder to right"))]): + ("RightCopyButton", "RightCopy", _("copy file from left folder to right")), + ("EditButton", "edit", _("Edit file"))]): button = wx.lib.buttons.GenBitmapButton(self.Editor, bitmap=GetBitmap(bitmap), size=wx.Size(28, 28), style=wx.NO_BORDER) @@ -311,6 +312,9 @@ self.Controler = controler + self.EditableFileExtensions = [] + self.EditButton.Hide() + self.SetIcon(GetBitmap("FOLDER")) def __del__(self): @@ -319,6 +323,11 @@ def GetTitle(self): return self.TagName + def SetEditableFileExtensions(self, extensions): + self.EditableFileExtensions = extensions + if len(self.EditableFileExtensions) > 0: + self.EditButton.Show() + def RefreshView(self): self.ManagedDir.RefreshTree() self.SystemDir.RefreshTree() @@ -331,6 +340,10 @@ self.DeleteButton.Enable(os.path.isfile(managed_filepath)) self.LeftCopyButton.Enable(os.path.isfile(system_filepath)) self.RightCopyButton.Enable(os.path.isfile(managed_filepath)) + if len(self.EditableFileExtensions) > 0: + self.EditButton.Enable( + os.path.isfile(managed_filepath) and + os.path.splitext(managed_filepath)[1] in self.EditableFileExtensions) def OnTreeItemChanged(self, event): self.RefreshButtonsState() @@ -352,6 +365,13 @@ self.ManagedDir.RefreshTree() event.Skip() + def OnEditButton(self, event): + filepath = self.ManagedDir.GetPath() + if (os.path.isfile(filepath) and + os.path.splitext(filepath)[1] in self.EditableFileExtensions): + self.Controler._OpenView(filepath) + event.Skip() + def CopyFile(self, src, dst): if os.path.isfile(src): src_folder, src_filename = os.path.split(src)