# HG changeset patch # User edouard # Date 1257172729 -3600 # Node ID 75fe735972737ae06e1f48f60ec0c99674395e2d # Parent fcd344deae84e07960c432986239c1a3da7cf1cc# Parent 092060fd8afb1d950fe467724ce0209bddc48716 Merge with 092060fd8afb1d950fe467724ce0209bddc48716 diff -r fcd344deae84 -r 75fe73597273 Beremiz.py --- a/Beremiz.py Tue Oct 27 16:32:54 2009 +0100 +++ b/Beremiz.py Mon Nov 02 15:38:49 2009 +0100 @@ -293,6 +293,8 @@ kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O')) AppendMenu(parent, help='', id=wx.ID_SAVE, kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S')) + AppendMenu(parent, help='', id=wx.ID_SAVEAS, + kind=wx.ITEM_NORMAL, text=_(u'Save as\tCTRL+SHIFT+S')) AppendMenu(parent, help='', id=wx.ID_CLOSE, kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W')) AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL, @@ -314,6 +316,7 @@ self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW) self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN) self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE) + self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE) self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL) self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP) @@ -367,6 +370,7 @@ self.PLCConfig.SetBackgroundColour(wx.WHITE) self.PLCConfig.Bind(wx.EVT_LEFT_DOWN, self.OnPanelLeftDown) self.PLCConfig.Bind(wx.EVT_SIZE, self.OnMoveWindow) + self.PLCConfig.Bind(wx.EVT_MOUSEWHEEL, self.OnPLCConfigScroll) self.BottomNoteBook.InsertPage(0, self.PLCConfig, _("Topology"), True) self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='', @@ -388,6 +392,8 @@ self.local_runtime_tmpdir = None self.DisableEvents = False + # Variable allowing disabling of PLCConfig scroll when Popup shown + self.ScrollingEnabled = True self.PluginInfos = {} @@ -477,39 +483,46 @@ infos = self.PluginRoot.ShowError(self.Log, (int(first_line), int(first_column)), (int(last_line), int(last_column))) - + + ## Function displaying an Error dialog in PLCOpenEditor. + # @return False if closing cancelled. + def CheckSaveBeforeClosing(self, title=_("Close Project")): + if self.PluginRoot.ProjectTestModified(): + dialog = wx.MessageDialog(self, + _("There are changes, do you want to save?"), + title, + wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) + answer = dialog.ShowModal() + dialog.Destroy() + if answer == wx.ID_YES: + self.PluginRoot.SaveProject() + elif answer == wx.ID_CANCEL: + return False + return True + def OnCloseFrame(self, event): - if self.PluginRoot is not None: - if self.PluginRoot.ProjectTestModified(): - dialog = wx.MessageDialog(self, - _("Save changes ?"), - _("Close Application"), - wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) - answer = dialog.ShowModal() - dialog.Destroy() - if answer == wx.ID_YES: - self.PluginRoot.SaveProject() - event.Skip() - elif answer == wx.ID_NO: - event.Skip() - return - else: - event.Veto() - return - - self.KillLocalRuntime() - - event.Skip() + if self.PluginRoot is None or self.CheckSaveBeforeClosing(_("Close Application")): + self.KillLocalRuntime() + event.Skip() + else: + event.Veto() def OnMoveWindow(self, event): self.GetBestSize() self.RefreshScrollBars() event.Skip() + def EnableScrolling(self, enable): + self.ScrollingEnabled = enable + + def OnPLCConfigScroll(self, event): + if self.ScrollingEnabled: + event.Skip() + def OnPanelLeftDown(self, event): focused = self.FindFocus() if isinstance(focused, TextCtrlAutoComplete.TextCtrlAutoComplete): - focused._showDropDown(False) + focused.DismissListBox() event.Skip() def RefreshFileMenu(self): @@ -533,6 +546,7 @@ self.FileMenu.Enable(wx.ID_PRINT, False) self.FileMenu.Enable(wx.ID_PAGE_SETUP, True) self.FileMenu.Enable(wx.ID_SAVE, True) + self.FileMenu.Enable(wx.ID_SAVEAS, True) self.FileMenu.Enable(wx.ID_PROPERTIES, True) self.FileMenu.Enable(wx.ID_CLOSE_ALL, True) else: @@ -541,6 +555,7 @@ self.FileMenu.Enable(wx.ID_PREVIEW, False) self.FileMenu.Enable(wx.ID_PRINT, False) self.FileMenu.Enable(wx.ID_SAVE, False) + self.FileMenu.Enable(wx.ID_SAVEAS, False) self.FileMenu.Enable(wx.ID_PROPERTIES, False) self.FileMenu.Enable(wx.ID_CLOSE_ALL, False) @@ -1201,7 +1216,7 @@ id = wx.NewId() if isinstance(element_infos["type"], types.ListType): combobox = wx.ComboBox(id=id, name=element_infos["name"], parent=parent, - pos=wx.Point(0, 0), size=wx.Size(150, 28), style=wx.CB_READONLY) + pos=wx.Point(0, 0), size=wx.Size(300, 28), style=wx.CB_READONLY) boxsizer.AddWindow(combobox, 0, border=0, flag=0) if element_infos["use"] == "optional": combobox.Append("") @@ -1234,7 +1249,7 @@ if "max" in element_infos["type"]: scmax = element_infos["type"]["max"] spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=parent, - pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT) + pos=wx.Point(0, 0), size=wx.Size(300, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT) spinctrl.SetRange(scmin,scmax) boxsizer.AddWindow(spinctrl, 0, border=0, flag=0) spinctrl.SetValue(element_infos["value"]) @@ -1253,7 +1268,7 @@ scmin = -(2**31) scmax = 2**31-1 spinctrl = wx.SpinCtrl(id=id, name=element_infos["name"], parent=parent, - pos=wx.Point(0, 0), size=wx.Size(150, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT) + pos=wx.Point(0, 0), size=wx.Size(300, 25), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT) spinctrl.SetRange(scmin, scmax) boxsizer.AddWindow(spinctrl, 0, border=0, flag=0) spinctrl.SetValue(element_infos["value"]) @@ -1263,10 +1278,11 @@ textctrl = TextCtrlAutoComplete.TextCtrlAutoComplete(id=id, name=element_infos["name"], parent=parent, + appframe=self, choices=choices, element_path=element_path, pos=wx.Point(0, 0), - size=wx.Size(150, 25), + size=wx.Size(300, 25), style=0) boxsizer.AddWindow(textctrl, 0, border=0, flag=0) @@ -1284,6 +1300,9 @@ self.DebugVariablePanel.SetDataProducer(None) def OnNewProjectMenu(self, event): + if self.PluginRoot is not None and not self.CheckSaveBeforeClosing(): + return + if not self.Config.HasEntry("lastopenedfolder"): defaultpath = os.path.expanduser("~") else: @@ -1309,6 +1328,9 @@ self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU) def OnOpenProjectMenu(self, event): + if self.PluginRoot is not None and not self.CheckSaveBeforeClosing(): + return + if not self.Config.HasEntry("lastopenedfolder"): defaultpath = os.path.expanduser("~") else: @@ -1337,21 +1359,12 @@ dialog.Destroy() def OnCloseProjectMenu(self, event): - if self.PluginRoot is not None: - if self.PluginRoot.ProjectTestModified(): - dialog = wx.MessageDialog(self, - _("Save changes ?"), - _("Close Application"), - wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) - answer = dialog.ShowModal() - dialog.Destroy() - if answer == wx.ID_YES: - self.PluginRoot.SaveProject() - elif answer == wx.ID_CANCEL: - return - self.ResetView() - self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU) - self.RefreshAll() + if self.PluginRoot is not None and not self.CheckSaveBeforeClosing(): + return + + self.ResetView() + self._Refresh(TITLE, TOOLBAR, FILEMENU, EDITMENU) + self.RefreshAll() def OnSaveProjectMenu(self, event): if self.PluginRoot is not None: @@ -1359,6 +1372,13 @@ self.RefreshAll() self.RefreshTitle() + def OnSaveProjectAsMenu(self, event): + if self.PluginRoot is not None: + self.PluginRoot.SaveProjectAs() + self.RefreshAll() + self.RefreshTitle() + event.Skip() + def OnPropertiesMenu(self, event): self.ShowProperties() @@ -1391,24 +1411,26 @@ return DeleteButtonFunction def AddPlugin(self, PluginType, plugin): - dialog = wx.TextEntryDialog(self, _("Please enter a name for plugin:"), _("Add Plugin"), "", wx.OK|wx.CANCEL) - if dialog.ShowModal() == wx.ID_OK: - PluginName = dialog.GetValue() - plugin.PlugAddChild(PluginName, PluginType) - self.RefreshPluginTree() - self.PluginRoot.RefreshPluginsBlockLists() - dialog.Destroy() + if self.PluginRoot.CheckProjectPathPerm(): + dialog = wx.TextEntryDialog(self, _("Please enter a name for plugin:"), _("Add Plugin"), "", wx.OK|wx.CANCEL) + if dialog.ShowModal() == wx.ID_OK: + PluginName = dialog.GetValue() + plugin.PlugAddChild(PluginName, PluginType) + self.RefreshPluginTree() + self.PluginRoot.RefreshPluginsBlockLists() + dialog.Destroy() def DeletePlugin(self, plugin): - dialog = wx.MessageDialog(self, _("Really delete plugin ?"), _("Remove plugin"), wx.YES_NO|wx.NO_DEFAULT) - if dialog.ShowModal() == wx.ID_YES: - self.PluginInfos.pop(plugin) - plugin.PlugRemove() - del plugin - self.PluginRoot.RefreshPluginsBlockLists() - self.RefreshPluginTree() - dialog.Destroy() - + if self.PluginRoot.CheckProjectPathPerm(): + dialog = wx.MessageDialog(self, _("Really delete plugin ?"), _("Remove plugin"), wx.YES_NO|wx.NO_DEFAULT) + if dialog.ShowModal() == wx.ID_YES: + self.PluginInfos.pop(plugin) + plugin.PlugRemove() + del plugin + self.PluginRoot.RefreshPluginsBlockLists() + self.RefreshPluginTree() + dialog.Destroy() + #------------------------------------------------------------------------------- # Exception Handler #------------------------------------------------------------------------------- @@ -1436,10 +1458,8 @@ An unhandled exception (bug) occured. Bug report saved at : (%s) -Please contact LOLITech at: -+33 (0)3 29 57 60 42 -or please be kind enough to send this file to: -bugs_beremiz@lolitech.fr +Please be kind enough to send this file to: +edouard.tisserant@gmail.com You should now restart Beremiz. diff -r fcd344deae84 -r 75fe73597273 TextCtrlAutoComplete.py --- a/TextCtrlAutoComplete.py Tue Oct 27 16:32:54 2009 +0100 +++ b/TextCtrlAutoComplete.py Mon Nov 02 15:38:49 2009 +0100 @@ -1,207 +1,250 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -#This file is part of Beremiz, a Integrated Development Environment for -#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. -# -#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD -# -#See COPYING file for copyrights details. -# -#This library is free software; you can redistribute it and/or -#modify it under the terms of the GNU General Public -#License as published by the Free Software Foundation; either -#version 2.1 of the License, or (at your option) any later version. -# -#This library is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -#General Public License for more details. -# -#You should have received a copy of the GNU General Public -#License along with this library; if not, write to the Free Software -#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import wx -import cPickle - -MAX_ITEM_COUNT = 10 -MAX_ITEM_SHOWN = 6 -ITEM_HEIGHT = 25 - -class TextCtrlAutoComplete(wx.TextCtrl): - - def __init__ (self, parent, choices=None, dropDownClick=True, - element_path=None, **therest): - """ - Constructor works just like wx.TextCtrl except you can pass in a - list of choices. You can also change the choice list at any time - by calling setChoices. - """ - - therest['style'] = wx.TE_PROCESS_ENTER | therest.get('style', 0) - - wx.TextCtrl.__init__(self, parent, **therest) - - #Some variables - self._dropDownClick = dropDownClick - self._lastinsertionpoint = None - - self._screenheight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y) - self.element_path = element_path - - #widgets - self.dropdown = wx.PopupWindow(self) - - #Control the style - flags = wx.LB_HSCROLL | wx.LB_SINGLE | wx.LB_SORT - - #Create the list and bind the events - self.dropdownlistbox = wx.ListBox(self.dropdown, style=flags, - pos=wx.Point(0, 0)) - - self.SetChoices(choices) - - #gp = self - #while ( gp != None ) : - # gp.Bind ( wx.EVT_MOVE , self.onControlChanged, gp ) - # gp.Bind ( wx.EVT_SIZE , self.onControlChanged, gp ) - # gp = gp.GetParent() - - self.Bind(wx.EVT_KILL_FOCUS, self.onControlChanged, self) - self.Bind(wx.EVT_TEXT_ENTER, self.onControlChanged, self) - self.Bind(wx.EVT_TEXT, self.onEnteredText, self) - self.Bind(wx.EVT_KEY_DOWN, self.onKeyDown, self) - - #If need drop down on left click - if dropDownClick: - self.Bind(wx.EVT_LEFT_DOWN , self.onClickToggleDown, self) - self.Bind(wx.EVT_LEFT_UP , self.onClickToggleUp, self) - - self.dropdownlistbox.Bind(wx.EVT_LISTBOX, self.onListItemSelected) - self.dropdownlistbox.Bind(wx.EVT_LISTBOX_DCLICK, self.onListItemSelected) - - def ChangeValue(self, value): - wx.TextCtrl.ChangeValue(self, value) - self._refreshListBoxChoices() - - def onEnteredText(self, event): - wx.CallAfter(self._refreshListBoxChoices) - event.Skip() - - def onKeyDown(self, event) : - """ Do some work when the user press on the keys: - up and down: move the cursor - """ - visible = self.dropdown.IsShown() - keycode = event.GetKeyCode() - if keycode in [wx.WXK_DOWN, wx.WXK_UP]: - if not visible: - self._showDropDown() - elif keycode == wx.WXK_DOWN: - self._moveSelection(1) - else: - self._moveSelection(-1) - elif keycode in [wx.WXK_LEFT, wx.WXK_RIGHT, wx.WXK_RETURN] and visible: - if self.dropdownlistbox.GetSelection() != wx.NOT_FOUND: - self._setValueFromSelected() - else: - self._showDropDown(False) - event.Skip() - elif event.GetKeyCode() == wx.WXK_ESCAPE: - self._showDropDown(False) - else: - event.Skip() - - def onListItemSelected(self, event): - self._setValueFromSelected() - event.Skip() - - def onClickToggleDown(self, event): - self._lastinsertionpoint = self.GetInsertionPoint() - event.Skip() - - def onClickToggleUp(self, event): - if self.GetInsertionPoint() == self._lastinsertionpoint: - self._showDropDown(not self.dropdown.IsShown()) - self._lastinsertionpoint = None - event.Skip() - - def onControlChanged(self, event): - res = self.GetValue() - config = wx.ConfigBase.Get() - listentries = cPickle.loads(str(config.Read(self.element_path, cPickle.dumps([])))) - if res and res not in listentries: - listentries = (listentries + [res])[-MAX_ITEM_COUNT:] - config.Write(self.element_path, cPickle.dumps(listentries)) - config.Flush() - self.SetChoices(listentries) - self._showDropDown(False) - event.Skip() - - def SetChoices(self, choices): - self._choices = choices - self._refreshListBoxChoices() - - def GetChoices(self): - return self._choices - -#------------------------------------------------------------------------------- -# Internal methods -#------------------------------------------------------------------------------- - - def _refreshListBoxChoices(self): - text = self.GetValue() - - self.dropdownlistbox.Clear() - for choice in self._choices: - if choice.startswith(text): - self.dropdownlistbox.Append(choice) - - itemcount = min(len(self.dropdownlistbox.GetStrings()), MAX_ITEM_SHOWN) - self.popupsize = wx.Size(self.GetSize()[0], ITEM_HEIGHT * itemcount + 4) - self.dropdownlistbox.SetSize(self.popupsize) - self.dropdown.SetClientSize(self.popupsize) - - def _moveSelection(self, direction): - selected = self.dropdownlistbox.GetSelection() - if selected == wx.NOT_FOUND: - if direction >= 0: - selected = 0 - else: - selected = self.dropdownlistbox.GetCount() - 1 - else: - selected = (selected + direction) % (self.dropdownlistbox.GetCount() + 1) - if selected == self.dropdownlistbox.GetCount(): - selected = wx.NOT_FOUND - self.dropdownlistbox.SetSelection(selected) - - def _setValueFromSelected(self): - """ - Sets the wx.TextCtrl value from the selected wx.ListCtrl item. - Will do nothing if no item is selected in the wx.ListCtrl. - """ - selected = self.dropdownlistbox.GetStringSelection() - if selected: - self.SetValue(selected) - self._showDropDown(False) - - - def _showDropDown(self, show=True) : - """ - Either display the drop down list (show = True) or hide it (show = False). - """ - if show : - size = self.dropdown.GetSize() - width, height = self.GetSizeTuple() - x, y = self.ClientToScreenXY(0, height) - if size.GetWidth() != width : - size.SetWidth(width) - self.dropdown.SetSize(size) - self.dropdownlistbox.SetSize(self.dropdown.GetClientSize()) - if (y + size.GetHeight()) < self._screenheight : - self.dropdown.SetPosition(wx.Point(x, y)) - else: - self.dropdown.SetPosition(wx.Point(x, y - height - size.GetHeight())) - self.dropdown.Show(show) - +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of Beremiz, a Integrated Development Environment for +#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# +#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD +# +#See COPYING file for copyrights details. +# +#This library is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public +#License as published by the Free Software Foundation; either +#version 2.1 of the License, or (at your option) any later version. +# +#This library is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +#General Public License for more details. +# +#You should have received a copy of the GNU General Public +#License along with this library; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import wx +import cPickle + +MAX_ITEM_COUNT = 10 +MAX_ITEM_SHOWN = 6 +if wx.Platform == '__WXMSW__': + ITEM_INTERVAL_HEIGHT = 3 +else: + ITEM_INTERVAL_HEIGHT = 6 + +if wx.Platform == '__WXMSW__': + popupclass = wx.PopupTransientWindow +else: + popupclass = wx.PopupWindow + +class PopupWithListbox(popupclass): + + def __init__(self, parent, choices=[]): + popupclass.__init__(self, parent, wx.SIMPLE_BORDER) + + self.ListBox = wx.ListBox(self, -1, style=wx.LB_HSCROLL|wx.LB_SINGLE|wx.LB_SORT) + if not wx.Platform == '__WXMSW__': + self.ListBox.Bind(wx.EVT_LISTBOX, self.OnListBoxClick) + self.ListBox.Bind(wx.EVT_LISTBOX_DCLICK, self.OnListBoxClick) + + self.SetChoices(choices) + + self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) + + def SetChoices(self, choices): + max_text_width = 0 + max_text_height = 0 + + self.ListBox.Clear() + for choice in choices: + self.ListBox.Append(choice) + w, h = self.ListBox.GetTextExtent(choice) + max_text_width = max(max_text_width, w) + max_text_height = max(max_text_height, h) + + itemcount = min(len(choices), MAX_ITEM_SHOWN) + width = self.Parent.GetSize()[0] + height = max_text_height * itemcount + ITEM_INTERVAL_HEIGHT * (itemcount + 1) + if max_text_width + 10 > width: + height += 15 + size = wx.Size(width, height) + self.ListBox.SetSize(size) + self.SetClientSize(size) + + def MoveSelection(self, direction): + selected = self.ListBox.GetSelection() + if selected == wx.NOT_FOUND: + if direction >= 0: + selected = 0 + else: + selected = self.ListBox.GetCount() - 1 + else: + selected = (selected + direction) % (self.ListBox.GetCount() + 1) + if selected == self.ListBox.GetCount(): + selected = wx.NOT_FOUND + self.ListBox.SetSelection(selected) + + def GetSelection(self): + return self.ListBox.GetStringSelection() + + def ProcessLeftDown(self, event): + selected = self.ListBox.HitTest(wx.Point(event.m_x, event.m_y)) + if selected != wx.NOT_FOUND: + wx.CallAfter(self.Parent.SetValueFromSelected, self.ListBox.GetString(selected)) + return False + + def OnListBoxClick(self, event): + selected = event.GetSelection() + if selected != wx.NOT_FOUND: + wx.CallAfter(self.Parent.SetValueFromSelected, self.ListBox.GetString(selected)) + event.Skip() + + def OnKeyDown(self, event): + self.Parent.ProcessEvent(event) + + def OnDismiss(self): + self.Parent.listbox = None + wx.CallAfter(self.Parent.DismissListBox) + +class TextCtrlAutoComplete(wx.TextCtrl): + + def __init__ (self, parent, appframe, choices=None, dropDownClick=True, + element_path=None, **therest): + """ + Constructor works just like wx.TextCtrl except you can pass in a + list of choices. You can also change the choice list at any time + by calling setChoices. + """ + + therest['style'] = wx.TE_PROCESS_ENTER | therest.get('style', 0) + + wx.TextCtrl.__init__(self, parent, **therest) + self.AppFrame = appframe + + #Some variables + self._dropDownClick = dropDownClick + self._lastinsertionpoint = None + + self._screenheight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y) + self.element_path = element_path + + self.listbox = None + + self.SetChoices(choices) + + #gp = self + #while ( gp != None ) : + # gp.Bind ( wx.EVT_MOVE , self.onControlChanged, gp ) + # gp.Bind ( wx.EVT_SIZE , self.onControlChanged, gp ) + # gp = gp.GetParent() + + self.Bind(wx.EVT_KILL_FOCUS, self.OnControlChanged) + self.Bind(wx.EVT_TEXT_ENTER, self.OnControlChanged) + self.Bind(wx.EVT_TEXT, self.OnEnteredText) + self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) + + #If need drop down on left click + if dropDownClick: + self.Bind(wx.EVT_LEFT_DOWN, self.OnClickToggleDown) + self.Bind(wx.EVT_LEFT_UP, self.OnClickToggleUp) + + def __del__(self): + self.AppFrame = None + + def ChangeValue(self, value): + wx.TextCtrl.ChangeValue(self, value) + self.RefreshListBoxChoices() + + def OnEnteredText(self, event): + wx.CallAfter(self.RefreshListBoxChoices) + event.Skip() + + def OnKeyDown(self, event): + """ Do some work when the user press on the keys: + up and down: move the cursor + """ + keycode = event.GetKeyCode() + if keycode in [wx.WXK_DOWN, wx.WXK_UP]: + self.PopupListBox() + if keycode == wx.WXK_DOWN: + self.listbox.MoveSelection(1) + else: + self.listbox.MoveSelection(-1) + elif keycode in [wx.WXK_LEFT, wx.WXK_RIGHT, wx.WXK_RETURN] and self.listbox is not None: + self.SetValueFromSelected(self.listbox.GetSelection()) + elif event.GetKeyCode() == wx.WXK_ESCAPE: + self.DismissListBox() + else: + event.Skip() + + def OnClickToggleDown(self, event): + self._lastinsertionpoint = self.GetInsertionPoint() + event.Skip() + + def OnClickToggleUp(self, event): + if self.GetInsertionPoint() == self._lastinsertionpoint: + wx.CallAfter(self.PopupListBox) + self._lastinsertionpoint = None + event.Skip() + + def OnControlChanged(self, event): + res = self.GetValue() + config = wx.ConfigBase.Get() + listentries = cPickle.loads(str(config.Read(self.element_path, cPickle.dumps([])))) + if res and res not in listentries: + listentries = (listentries + [res])[-MAX_ITEM_COUNT:] + config.Write(self.element_path, cPickle.dumps(listentries)) + config.Flush() + self.SetChoices(listentries) + self.DismissListBox() + event.Skip() + + def SetChoices(self, choices): + self._choices = choices + self.RefreshListBoxChoices() + + def GetChoices(self): + return self._choices + + def SetValueFromSelected(self, selected): + """ + Sets the wx.TextCtrl value from the selected wx.ListCtrl item. + Will do nothing if no item is selected in the wx.ListCtrl. + """ + if selected != "": + self.SetValue(selected) + self.DismissListBox() + + def RefreshListBoxChoices(self): + if self.listbox is not None: + text = self.GetValue() + choices = [choice for choice in self._choices if choice.startswith(text)] + self.listbox.SetChoices(choices) + + def PopupListBox(self): + if self.listbox is None: + self.listbox = PopupWithListbox(self) + + # Show the popup right below or above the button + # depending on available screen space... + pos = self.ClientToScreen((0, 0)) + sz = self.GetSize() + self.listbox.Position(pos, (0, sz[1])) + + self.RefreshListBoxChoices() + + if wx.Platform == '__WXMSW__': + self.listbox.Popup() + else: + self.listbox.Show() + self.AppFrame.EnableScrolling(False) + + def DismissListBox(self): + if self.listbox is not None: + if wx.Platform == '__WXMSW__': + self.listbox.Dismiss() + else: + self.listbox.Destroy() + self.listbox = None + self.AppFrame.EnableScrolling(True) + diff -r fcd344deae84 -r 75fe73597273 beremiz_postinst.py --- a/beremiz_postinst.py Tue Oct 27 16:32:54 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# La première ligne doit commencer par #! et contenir python. -# Elle sera adaptée au système de destination automatiquement - -""" This is a part of Beremiz project. - - Post installation script for win32 system - - This script creat a shortcut for Beremiz.py in the desktop and the - start menu, and remove them at the uninstallation - -""" - -import os -import sys - -# Ce script sera aussi lancé lors de la désinstallation. -# Pour n'exécuter du code que lors de l'installation : -if sys.argv[1] == '-install': - # On récupère le dossier où mes fichiers seront installés (dossier où python est aussi installé sous windows) - python_path = sys.prefix - # On récupère le chemin de pythonw.exe (l'exécutable python qui n'affiche pas de console). - # Si vous voulez une console, remplacez pythonw.exe par python.exe - pyw_path = os.path.abspath(os.path.join(python_path, 'pythonw.exe')) - # On récupère le dossier coincoin - Beremiz_dir = os.path.abspath(os.path.join(python_path, 'LOLITech', 'Beremiz')) - - # On récupère les chemins de coincoin.py, et de coincoin.ico - # (Ben oui, l'icone est au format ico, oubliez le svg, ici on en est encore à la préhistoire. - # Heureusement que the GIMP sait faire la conversion !) - ico_path = os.path.join(Beremiz_dir, 'Beremiz.ico') - script_path = os.path.join(Beremiz_dir, 'Beremiz.py') - - # Création des raccourcis - # Pour chaque raccourci, on essaye de le faire pour tous les utilisateurs (Windows NT/2000/XP), - # sinon on le fait pour l'utilisateur courant (Windows 95/98/ME) - - # Raccourcis du bureau - # On essaye de trouver un bureau - try: - desktop_path = get_special_folder_path("CSIDL_COMMON_DESKTOPDIRECTORY") - except OSError: - desktop_path = get_special_folder_path("CSIDL_DESKTOPDIRECTORY") - - # On créé le raccourcis - create_shortcut(pyw_path, # programme à lancer - "Can Node Editor", # Description - os.path.join(desktop_path, 'Beremiz.lnk'), # fichier du raccourcis (gardez le .lnk) - script_path, # Argument (script python) - Beremiz_dir, # Dossier courant - ico_path # Fichier de l'icone - ) - # On va cafter au programme de désinstallation qu'on a fait un fichier, pour qu'il soit supprimé - # lors de la désinstallation - file_created(os.path.join(desktop_path, 'Beremiz.lnk')) - - # Raccourcis dans le menu démarrer (idem qu'avant) - try: - start_path = get_special_folder_path("CSIDL_COMMON_PROGRAMS") - except OSError: - start_path = get_special_folder_path("CSIDL_PROGRAMS") - - - - # Création du dossier dans le menu programme - programs_path = os.path.join(start_path, "Beremiz project") - try : - os.mkdir(programs_path) - - except OSError: - - pass - directory_created(programs_path) - - create_shortcut(pyw_path, # Cible - "Can Node Editor", #Description - os.path.join(programs_path, 'Beremiz.lnk'), # Fichier - script_path, # Argument - Beremiz_dir, # Dossier de travail - ico_path # Icone - ) - file_created(os.path.join(programs_path, 'Beremiz.lnk')) - - # End (youpi-message) - # Ce message sera affiché (très) furtivement dans l'installateur. - # Vous pouvez vous en servir comme moyen de communication secret, c'est très in. - sys.stdout.write("Shortcuts created.") - # Fin du bidule - sys.exit() diff -r fcd344deae84 -r 75fe73597273 debian/Beremiz.directory --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/Beremiz.directory Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Directory +Name=Beremiz +Icon=/usr/share/beremiz/images/brz.png diff -r fcd344deae84 -r 75fe73597273 debian/Beremiz_demos.directory --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/Beremiz_demos.directory Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Directory +Name=Demos +Icon= diff -r fcd344deae84 -r 75fe73597273 debian/Beremiz_docs.directory --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/Beremiz_docs.directory Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Directory +Name=Doc +Icon= diff -r fcd344deae84 -r 75fe73597273 debian/README.Debian --- a/debian/README.Debian Tue Oct 27 16:32:54 2009 +0100 +++ b/debian/README.Debian Mon Nov 02 15:38:49 2009 +0100 @@ -3,4 +3,4 @@ - -- lolitech Thu, 29 Nov 2007 14:55:13 +0100 + -- edouard Thu, 29 Nov 2007 14:55:13 +0100 diff -r fcd344deae84 -r 75fe73597273 debian/beremiz.desktop --- a/debian/beremiz.desktop Tue Oct 27 16:32:54 2009 +0100 +++ b/debian/beremiz.desktop Mon Nov 02 15:38:49 2009 +0100 @@ -8,6 +8,6 @@ Terminal=false MultipleArgs=false Type=Application -Categories=Application;Development; +Categories=Beremiz; StartupNotify=true diff -r fcd344deae84 -r 75fe73597273 debian/beremiz.menu --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/beremiz.menu Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,40 @@ + + + Applications + Applications.directory + + + + + + Development + Development.directory + + + + Beremiz + Beremiz.directory + + Beremiz + + + Demos + Beremiz_demos.directory + + Beremiz_demo + + + + Doc + Beremiz_docs.directory + + Beremiz_doc + + + + + + + + diff -r fcd344deae84 -r 75fe73597273 debian/beremiz_doc.desktop --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/beremiz_doc.desktop Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,12 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Manual +Comment=Open Source framework for automation +Comment[fr]=Environnement de développement Open Source pour l'automatisme +Exec=/usr/bin/xpdf /usr/share/beremiz/doc/manual_beremiz.pdf +Icon= +Terminal=false +MultipleArgs=false +Type=Application +Categories=Beremiz_doc; +StartupNotify=true diff -r fcd344deae84 -r 75fe73597273 debian/beremiz_svgui.desktop --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/beremiz_svgui.desktop Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,13 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Beremiz Demo (svgui) +Comment=Open Source framework for automation +Comment[fr]=Environnement de développement Open Source pour l'automatisme +Exec=/usr/bin/beremiz /usr/share/beremiz/tests/svgui +Icon=/usr/share/beremiz/images/brz.png +Terminal=false +MultipleArgs=false +Type=Application +Categories=Beremiz_demo; +StartupNotify=true + diff -r fcd344deae84 -r 75fe73597273 debian/beremiz_wxglade.desktop --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/beremiz_wxglade.desktop Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,13 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Beremiz Demo (wxGlade) +Comment=Open Source framework for automation +Comment[fr]=Environnement de développement Open Source pour l'automatisme +Exec=/usr/bin/beremiz /usr/share/beremiz/tests/wxGlade +Icon=/usr/share/beremiz/images/brz.png +Terminal=false +MultipleArgs=false +Type=Application +Categories=Beremiz_demo; +StartupNotify=true + diff -r fcd344deae84 -r 75fe73597273 debian/changelog --- a/debian/changelog Tue Oct 27 16:32:54 2009 +0100 +++ b/debian/changelog Mon Nov 02 15:38:49 2009 +0100 @@ -2,5 +2,5 @@ * Initial release (Closes: #nnnn) - -- lolitech Thu, 29 Nov 2007 14:55:13 +0100 + -- edouard Thu, 29 Nov 2007 14:55:13 +0100 diff -r fcd344deae84 -r 75fe73597273 debian/control --- a/debian/control Tue Oct 27 16:32:54 2009 +0100 +++ b/debian/control Mon Nov 02 15:38:49 2009 +0100 @@ -1,13 +1,13 @@ Source: beremiz Section: devel Priority: standard -Maintainer: lolitech +Maintainer: edouard Build-Depends: debhelper (>= 5) Standards-Version: 3.7.2 Package: beremiz Architecture: any -Depends: build-essential, python-wxgtk2.8, python-ctypes, python-wxglade, xpdf, canfestival-devel, canfestival-objdictedit, matiec, docutils, pyro, xmlclass, plcopeneditor +Depends: build-essential, python-wxgtk2.8, python-ctypes, python-numpy, python-twisted, python-nevow, python-simplejson, python-wxglade, xpdf, canfestival-devel, canfestival-objdictedit, matiec, docutils, pyro, xmlclass, plcopeneditor Description: Beremiz is an Open Source framework for automation With Beremiz, you can : - Automate everything. diff -r fcd344deae84 -r 75fe73597273 debian/rules --- a/debian/rules Tue Oct 27 16:32:54 2009 +0100 +++ b/debian/rules Mon Nov 02 15:38:49 2009 +0100 @@ -1,17 +1,9 @@ #!/usr/bin/make -f # -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 - - - CFLAGS = -Wall -g ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) @@ -23,8 +15,6 @@ configure: configure-stamp configure-stamp: dh_testdir - # Add here commands to configure the package. - touch configure-stamp @@ -32,21 +22,12 @@ build-stamp: configure-stamp dh_testdir - - # Add here commands to compile the package. - #$(MAKE) - #docbook-to-man debian/beremiz.sgml > beremiz.1 - touch $@ clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp - - # Add here commands to clean up after the build process. - #-$(MAKE) clean - dh_clean install: build @@ -55,35 +36,49 @@ dh_clean -k dh_installdirs - # Add here commands to install the package into debian/beremiz. + # Copy source files mkdir -p $(CURDIR)/debian/beremiz/usr/share/beremiz - mkdir -p $(CURDIR)/debian/beremiz/usr/share/applications - cp -a images $(CURDIR)/debian/beremiz/usr/share/beremiz cp -a plugins $(CURDIR)/debian/beremiz/usr/share/beremiz cp -a runtime $(CURDIR)/debian/beremiz/usr/share/beremiz cp -a tests $(CURDIR)/debian/beremiz/usr/share/beremiz cp -a connectors $(CURDIR)/debian/beremiz/usr/share/beremiz cp -a targets $(CURDIR)/debian/beremiz/usr/share/beremiz - cp *.xml $(CURDIR)/debian/beremiz/usr/share/beremiz + cp -a doc $(CURDIR)/debian/beremiz/usr/share/beremiz + cp -a locale $(CURDIR)/debian/beremiz/usr/share/beremiz + cp *.js $(CURDIR)/debian/beremiz/usr/share/beremiz cp *.py $(CURDIR)/debian/beremiz/usr/share/beremiz - cp debian/beremiz.desktop $(CURDIR)/debian/beremiz/usr/share/applications/beremiz.desktop - + # Copy desktop directory file + mkdir -p $(CURDIR)/debian/beremiz/usr/share/desktop-directories + cp debian/Beremiz.directory $(CURDIR)/debian/beremiz/usr/share/desktop-directories + cp debian/Beremiz_demos.directory $(CURDIR)/debian/beremiz/usr/share/desktop-directories + cp debian/Beremiz_docs.directory $(CURDIR)/debian/beremiz/usr/share/desktop-directories + + # Copy desktop menu file + mkdir -p $(CURDIR)/debian/beremiz/etc/xdg/menus/applications-merged + cp debian/beremiz.menu $(CURDIR)/debian/beremiz/etc/xdg/menus/applications-merged + + # Copy desktop entry files + mkdir -p $(CURDIR)/debian/beremiz/usr/share/applications + cp debian/beremiz.desktop $(CURDIR)/debian/beremiz/usr/share/applications/ + cp debian/beremiz_svgui.desktop $(CURDIR)/debian/beremiz/usr/share/applications/ + cp debian/beremiz_wxglade.desktop $(CURDIR)/debian/beremiz/usr/share/applications/ + cp debian/beremiz_doc.desktop $(CURDIR)/debian/beremiz/usr/share/applications/ + rm -rf `find .|grep CVS` rm -rf `find .|grep .cvsignore` chmod -R a+r $(CURDIR)/debian/beremiz # Build architecture-independent files here. binary-indep: build install -# We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot - dh_installchangelogs - dh_installdocs +# dh_installchangelogs +# dh_installdocs dh_installexamples # dh_install # dh_installmenu diff -r fcd344deae84 -r 75fe73597273 doc/about.html --- a/doc/about.html Tue Oct 27 16:32:54 2009 +0100 +++ b/doc/about.html Mon Nov 02 15:38:49 2009 +0100 @@ -17,15 +17,6 @@ http://www.fe.up.pt/si/web_page.inicial - - - Supported by : - - - LOLITech
- http://www.lolitech.fr - - diff -r fcd344deae84 -r 75fe73597273 i18n/Beremiz_fr_FR.po --- a/i18n/Beremiz_fr_FR.po Tue Oct 27 16:32:54 2009 +0100 +++ b/i18n/Beremiz_fr_FR.po Mon Nov 02 15:38:49 2009 +0100 @@ -7,25 +7,23 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-10-09 16:27+0200\n" -"PO-Revision-Date: 2009-10-09 17:48+0100\n" +"POT-Creation-Date: 2009-11-02 10:40+0100\n" +"PO-Revision-Date: 2009-11-02 10:52+0100\n" "Last-Translator: \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../Beremiz.py:1432 +#: ../Beremiz.py:1457 #, python-format msgid "" "\n" "An unhandled exception (bug) occured. Bug report saved at :\n" "(%s)\n" "\n" -"Please contact LOLITech at:\n" -"+33 (0)3 29 57 60 42\n" -"or please be kind enough to send this file to:\n" -"bugs_beremiz@lolitech.fr\n" +"Please be kind enough to send this file to:\n" +"edouard.tisserant@gmail.com\n" "\n" "You should now restart Beremiz.\n" "\n" @@ -35,20 +33,18 @@ "Une erreur inconnue (bug) est apparu. Le rapport d'erreur a été sauvé dans :\n" "(%s)\n" "\n" -"Veuillez contacter LOLITech au :\n" -"+33 (0)3 29 57 60 42\n" -"ou envoyez ce fichier à l'adresse :\n" -"bugs_beremiz@lolitech.fr\n" +"Envoyez ce fichier à l'adresse :\n" +"edouard.tisserant@gmail.com\n" "\n" "Vous devriez redémarrer Beremiz.\n" "\n" "Origine :\n" -#: ../plugger.py:1370 +#: ../plugger.py:1453 msgid " generation failed !\n" msgstr ": la construction a échouée !\n" -#: ../Beremiz.py:1332 +#: ../Beremiz.py:1357 #, python-format msgid "\"%s\" folder is not a valid Beremiz project\n" msgstr "Le dossier \"%s\" ne contient pas de projet Beremiz valide\n" @@ -57,48 +53,48 @@ msgid "&Edit" msgstr "&Editer" -#: ../Beremiz.py:1420 -#: ../Beremiz.py:1422 -#: ../Beremiz.py:1423 +#: ../Beremiz.py:1445 +#: ../Beremiz.py:1447 +#: ../Beremiz.py:1448 msgid ", " msgstr ", " -#: ../Beremiz.py:1418 +#: ../Beremiz.py:1443 msgid ". " msgstr ". " -#: ../plugger.py:432 +#: ../plugger.py:443 #, python-format msgid "A child names \"%s\" already exist -> \"%s\"\n" msgstr "" -#: ../plugger.py:464 +#: ../plugger.py:475 #, python-format msgid "A child with IEC channel %d already exist -> %d\n" msgstr "" -#: ../Beremiz.py:329 +#: ../Beremiz.py:332 msgid "About" msgstr "A propos" -#: ../Beremiz.py:1369 +#: ../Beremiz.py:1392 msgid "About Beremiz" msgstr "A propos de Beremiz" -#: ../Beremiz.py:1391 +#: ../Beremiz.py:1415 msgid "Add Plugin" msgstr "Ajouter un plugin" -#: ../Beremiz.py:585 -#: ../Beremiz.py:849 +#: ../Beremiz.py:603 +#: ../Beremiz.py:867 msgid "Add a sub plugin" msgstr "Ajouter un sous plugin" -#: ../plugger.py:1683 +#: ../plugger.py:1766 msgid "Already connected. Please disconnect\n" msgstr "Déjà connecté. Veuillez déconnecter\n" -#: ../Beremiz.py:1088 +#: ../Beremiz.py:1106 msgid "Append " msgstr "Ajouter " @@ -108,62 +104,62 @@ msgid "Bad location size : %s" msgstr "Mauvaise taille d'adresse : %s" -#: ../Beremiz.py:417 +#: ../Beremiz.py:426 msgid "Beremiz" msgstr "Beremiz" -#: ../Beremiz.py:327 +#: ../Beremiz.py:330 msgid "Beremiz\tF1" msgstr "Beremiz\tF1" -#: ../plugger.py:1466 +#: ../plugger.py:1549 msgid "Broken" msgstr "Cassé" -#: ../plugger.py:1807 +#: ../plugger.py:1890 msgid "Build" msgstr "Compiler" -#: ../plugger.py:1434 +#: ../plugger.py:1517 msgid "Build directory already clean\n" msgstr "Le répertoire de compilation est déjà nettoyé\n" -#: ../plugger.py:1808 +#: ../plugger.py:1891 msgid "Build project into build folder" msgstr "Compiler le projet dans le répertoire ce compilation" -#: ../plugger.py:1388 +#: ../plugger.py:1471 msgid "C Build crashed !\n" msgstr "La compilation du C a mal fonctionné !\n" -#: ../plugger.py:1385 +#: ../plugger.py:1468 msgid "C Build failed.\n" msgstr "La compilation du C a échouée !\n" -#: ../plugger.py:1374 +#: ../plugger.py:1457 msgid "C code generated successfully.\n" msgstr "Code C généré avec succès.\n" -#: ../targets/toolchain_gcc.py:125 +#: ../targets/toolchain_gcc.py:129 #, python-format msgid "C compilation of %s failed.\n" msgstr "La compilation C de %s a échouée.\n" -#: ../plugger.py:1117 +#: ../plugger.py:1200 #, python-format msgid "Can't find module for target %s!\n" msgstr "Impossible de trouver le module correspondant à la cible %s !\n" -#: ../plugger.py:1756 +#: ../plugger.py:1839 msgid "Cannot compare latest build to target. Please build.\n" msgstr "Impossible de comparer la cible avec la dernière compilation. Veuillez compiler le projet.\n" -#: ../plugger.py:502 +#: ../plugger.py:513 #, python-format msgid "Cannot create child %s of type %s " msgstr "Impossible d'ajouter un élément \"%s\" de type \"%s\"" -#: ../plugger.py:457 +#: ../plugger.py:468 #, python-format msgid "Cannot find lower free IEC channel than %d\n" msgstr "Impossible de trouver un numéro IEC inférieur à %d libre\n" @@ -172,7 +168,7 @@ msgid "Cannot get PLC status - connection failed.\n" msgstr "Impossible d'obtenir le statut de l'automate - la connexion a échoué.\n" -#: ../plugger.py:1215 +#: ../plugger.py:1298 msgid "Cannot open/parse VARIABLES.csv!\n" msgstr "Impossible d'ouvrir ou d'analyser le fichier VARIABLES.csv !\n" @@ -201,8 +197,12 @@ msgid "Choose a SVG file" msgstr "Choisissez un fichier SVG" -#: ../Beremiz.py:1289 -#: ../Beremiz.py:1314 +#: ../plugger.py:969 +msgid "Choose a directory to save project" +msgstr "Choisissez un dossier où enregistrer le projet" + +#: ../Beremiz.py:1311 +#: ../Beremiz.py:1339 msgid "Choose a project" msgstr "Choisissez un projet" @@ -210,48 +210,48 @@ msgid "Choose a working directory " msgstr "Choisissez un dossier de travail" -#: ../plugger.py:882 +#: ../plugger.py:927 msgid "Chosen folder doesn't contain a program. It's not a valid project!" msgstr "Le répertoire ne contient pas de programme. Ce n'est pas un projet valide !" -#: ../plugger.py:847 +#: ../plugger.py:892 msgid "Chosen folder isn't empty. You can't use it for a new project!" msgstr "Le répertoire n'est pas vide. Vous ne pouvez pas l'utiliser pour créer un nouveau projet !" -#: ../plugger.py:1811 +#: ../plugger.py:1894 msgid "Clean" msgstr "Nettoyer" -#: ../plugger.py:1813 +#: ../plugger.py:1896 msgid "Clean project build folder" msgstr "Nettoyer le répertoire de compilation" -#: ../plugger.py:1431 +#: ../plugger.py:1514 msgid "Cleaning the build directory\n" msgstr "Répertoire de compilation en cours de nettoyage\n" -#: ../Beremiz.py:483 -#: ../Beremiz.py:1341 +#: ../Beremiz.py:504 msgid "Close Application" msgstr "Fermer l'application" -#: ../Beremiz.py:299 +#: ../Beremiz.py:301 +#: ../Beremiz.py:489 msgid "Close Project" msgstr "Fermer le projet" -#: ../Beremiz.py:297 +#: ../Beremiz.py:299 msgid "Close Tab\tCTRL+W" msgstr "Fermer l'onglet\tCTRL+W" -#: ../plugger.py:1039 +#: ../plugger.py:1122 msgid "Compiling IEC Program into C code...\n" msgstr "Compilation du program en IEC vers du code C en cours...\n" -#: ../plugger.py:1835 +#: ../plugger.py:1918 msgid "Connect" msgstr "Connecter" -#: ../plugger.py:1836 +#: ../plugger.py:1919 msgid "Connect to the target PLC" msgstr "Connecter à l'automate cible" @@ -260,23 +260,23 @@ msgid "Connecting to URI : %s\n" msgstr "Connection à l'URI %s en cours...\n" -#: ../plugger.py:1702 +#: ../plugger.py:1785 msgid "Connection canceled!\n" msgstr "La connection a été abandonnée !\n" -#: ../plugger.py:1719 +#: ../plugger.py:1802 #, python-format msgid "Connection failed to %s!\n" msgstr "La connection à \"%s\" a échouée !\n" -#: ../plugger.py:625 +#: ../plugger.py:634 #, python-format msgid "" "Could not add child \"%s\", type %s :\n" "%s\n" msgstr "" -#: ../plugger.py:602 +#: ../plugger.py:611 #, python-format msgid "" "Couldn't load plugin base parameters %s :\n" @@ -285,7 +285,7 @@ "Impossible de charger les paramètres de base du plugin %s :\n" " %s" -#: ../plugger.py:613 +#: ../plugger.py:622 #, python-format msgid "" "Couldn't load plugin parameters %s :\n" @@ -294,11 +294,11 @@ "Impossible de charger les paramètres du plugin %s :\n" " %s" -#: ../plugger.py:1647 +#: ../plugger.py:1730 msgid "Couldn't start PLC debug !\n" msgstr "Impossible d'arrêter le débogage de l'automate !\n" -#: ../plugger.py:1677 +#: ../plugger.py:1760 msgid "Couldn't stop PLC !\n" msgstr "Impossible d'arrêter l'automate !\n" @@ -306,54 +306,54 @@ msgid "Create HMI" msgstr "Créer une IHM" -#: ../plugger.py:1821 +#: ../plugger.py:1904 msgid "Debug" msgstr "Déboguer" -#: ../plugger.py:1520 +#: ../plugger.py:1603 #, python-format msgid "Debug : Unknown variable %s\n" msgstr "Débogage : variable \"%s\" inconnue\n" -#: ../plugger.py:1632 +#: ../plugger.py:1715 msgid "Debug Thread couldn't be killed" msgstr "Le thread de débogage n'a pu être détruit" -#: ../plugger.py:1616 +#: ../plugger.py:1699 #, python-format msgid "Debug data not coherent %d != %d\n" msgstr "Les données de débogage ne sont pas cohérentes %d != %d\n" -#: ../plugger.py:1624 +#: ../plugger.py:1707 msgid "Debugger disabled\n" msgstr "Débogueur désactivé\n" -#: ../Beremiz.py:840 +#: ../Beremiz.py:858 msgid "Delete this plugin" msgstr "Supprimer ce plugin" -#: ../plugger.py:1463 +#: ../plugger.py:1546 msgid "Dirty" msgstr "Corrompu" -#: ../plugger.py:1844 +#: ../plugger.py:1927 msgid "Disconnect" msgstr "Déconnecter" -#: ../plugger.py:1846 +#: ../plugger.py:1929 msgid "Disconnect from PLC" msgstr "Déconnecter l'automate" -#: ../plugger.py:1469 +#: ../plugger.py:1552 msgid "Disconnected" msgstr "Déconnecté" -#: ../plugins/c_ext/c_ext.py:236 -#: ../plugins/c_ext/c_ext.py:237 +#: ../plugins/c_ext/c_ext.py:250 +#: ../plugins/c_ext/c_ext.py:251 msgid "Edit C File" msgstr "Editer le fichier C" -#: ../plugins/canfestival/canfestival.py:217 +#: ../plugins/canfestival/canfestival.py:246 msgid "Edit CanOpen Network with NetworkEdit" msgstr "Editer le réseau CANOpen à l'aide de NetworkEdit" @@ -361,19 +361,19 @@ msgid "Edit a WxWidgets GUI with WXGlade" msgstr "Editer une IHM WxWidgets à l'aide de WXGlade" -#: ../plugins/canfestival/canfestival.py:216 +#: ../plugins/canfestival/canfestival.py:245 msgid "Edit network" msgstr "Editer le réseau" -#: ../plugger.py:1855 +#: ../plugger.py:1938 msgid "Edit raw IEC code added to code generated by PLCGenerator" msgstr "Editer le code IEC ajouté au code généré par PLCGenerator" -#: ../plugger.py:1460 +#: ../plugger.py:1543 msgid "Empty" msgstr "Vide" -#: ../Beremiz.py:790 +#: ../Beremiz.py:808 msgid "Enable/Disable this plugin" msgstr "Activer/Désactiver le plugin" @@ -389,23 +389,24 @@ msgid "Enter the IP of the interface to bind" msgstr "Saisissez l'adresse IP de l'interface à lier" -#: ../Beremiz.py:1446 -#: ../Beremiz.py:1456 +#: ../Beremiz.py:1469 +#: ../Beremiz.py:1479 +#: ../plugger.py:873 #: ../Beremiz_service.py:268 #: ../Beremiz_service.py:392 msgid "Error" msgstr "Erreur" -#: ../plugger.py:1087 +#: ../plugger.py:1170 msgid "Error : At least one configuration and one resource must be declared in PLC !\n" msgstr "Erreur : Au moins une configuration ou une ressource doit être déclarée dans l'automate !\n" -#: ../plugger.py:1079 +#: ../plugger.py:1162 #, python-format msgid "Error : IEC to C compiler returned %d\n" msgstr "Erreur : Le compilateur d'IEC en C a retourné %d\n" -#: ../plugger.py:1021 +#: ../plugger.py:1104 #, python-format msgid "" "Error in ST/IL/SFC code generator :\n" @@ -414,33 +415,33 @@ "Erreur dans le générateur de code ST/IL/SFC :\n" "%s\n" -#: ../plugger.py:207 +#: ../plugger.py:218 #, python-format msgid "Error while saving \"%s\"\n" msgstr "Erreur lors de l'enregistrement de \"%s\"\n" -#: ../plugins/canfestival/canfestival.py:208 +#: ../plugins/canfestival/canfestival.py:237 msgid "Error: No Master generated\n" msgstr "Erreur : Aucun maître généré\n" -#: ../plugins/canfestival/canfestival.py:203 +#: ../plugins/canfestival/canfestival.py:232 msgid "Error: No PLC built\n" msgstr "Erreur : Aucun automate compilé\n" -#: ../plugger.py:1713 +#: ../plugger.py:1796 #, python-format msgid "Exception while connecting %s!\n" msgstr "Une exception est apparu au cours de la connexion %s !\n" -#: ../plugger.py:1091 +#: ../plugger.py:1174 msgid "Extracting Located Variables...\n" msgstr "Extraction des variables adressées en cours...\n" -#: ../plugger.py:1771 +#: ../plugger.py:1854 msgid "Failed : Must build before transfer.\n" msgstr "Echec : Le projet doit être compilé avant d'être transféré.\n" -#: ../plugger.py:1379 +#: ../plugger.py:1462 msgid "Fatal : cannot get builder.\n" msgstr "Erreur fatale : impossible de trouver un compilateur.\n" @@ -448,15 +449,15 @@ msgid "Force runtime reload\n" msgstr "Redémarrage du runtime forcé\n" -#: ../plugger.py:1011 +#: ../plugger.py:1094 msgid "Generating SoftPLC IEC-61131 ST/IL/SFC code...\n" msgstr "Création du code ST/IL/SFC de l'automate IEC-61131 en cours...\n" -#: ../plugger.py:1329 +#: ../plugger.py:1412 msgid "Generating plugins C code\n" msgstr "Création du code C des plugins en cours\n" -#: ../plugger.py:1321 +#: ../plugger.py:1404 msgid "IEC-61131-3 code generation failed !\n" msgstr "La création du code IEC-61131-3 a échouée !\n" @@ -480,15 +481,15 @@ msgid "Invalid type \"%s\"-> %d != %d for location\"%s\"" msgstr "Type invalide \"%s\"-> %d != %d pour cette adresse \"%s\"" -#: ../plugger.py:1777 +#: ../plugger.py:1860 msgid "Latest build already matches current target. Transfering anyway...\n" msgstr "La dernière compilation correspond à la cible actuelle...\n" -#: ../plugger.py:1747 +#: ../plugger.py:1830 msgid "Latest build does not match with target, please transfer.\n" msgstr "La dernière compilation ne correspond pas a la cible actuelle, veuillez transférer le programme.\n" -#: ../plugger.py:1751 +#: ../plugger.py:1834 msgid "Latest build matches target, no transfer needed.\n" msgstr "La dernière compilation correspond à la cible actuelle. il n'est pas nécessaire de transférer le programme.\n" @@ -500,7 +501,7 @@ msgid "Launch a live Python shell" msgstr "Lancer une console Python" -#: ../targets/toolchain_gcc.py:133 +#: ../targets/toolchain_gcc.py:137 msgid "Linking :\n" msgstr "Linkage :\n" @@ -508,11 +509,11 @@ msgid "Local" msgstr "Local" -#: ../Beremiz.py:376 +#: ../Beremiz.py:380 msgid "Log Console" msgstr "Console de log" -#: ../plugger.py:512 +#: ../plugger.py:523 #, python-format msgid "Max count (%d) reached for this plugin of type %s " msgstr "Nombre limite(%d) atteint pour les plugin de type %s" @@ -525,7 +526,7 @@ msgid "New\tCTRL+N" msgstr "Nouveau\tCTRL+N" -#: ../plugger.py:1801 +#: ../plugger.py:1884 msgid "No PLC to transfer (did build succeed ?)\n" msgstr "Aucun automate à transférer (la compilation a-t-elle réussi ?)\n" @@ -562,29 +563,49 @@ msgid "Open\tCTRL+O" msgstr "Ouvrir\tCTRL+O" -#: ../targets/toolchain_gcc.py:101 +#: ../plugins/c_ext/c_ext.py:230 +msgid "Open CFileEditor" +msgstr "Ouverture de CFileEditor" + +#: ../plugins/python/modules/svgui/svgui.py:105 +msgid "Open Inkscape" +msgstr "Ouverture de Inkscape" + +#: ../plugins/canfestival/canfestival.py:208 +msgid "Open NetworkEdit" +msgstr "Ouverture de NetworkEdit" + +#: ../plugins/canfestival/canfestival.py:108 +msgid "Open ObjDictEdit" +msgstr "Ouverture de ObjdictEdit" + +#: ../plugins/python/modules/wxglade_hmi/wxglade_hmi.py:107 +msgid "Open wxGlade" +msgstr "Ouverture de wxGlade" + +#: ../targets/toolchain_gcc.py:105 msgid "PLC :\n" msgstr "Automate :\n" -#: ../plugger.py:1489 -#: ../plugger.py:1733 +#: ../plugger.py:1572 +#: ../plugger.py:1816 #, python-format msgid "PLC is %s\n" msgstr "L'automate est dans l'état %s\n" -#: ../Beremiz.py:302 +#: ../Beremiz.py:304 msgid "Page Setup" msgstr "Mise en page..." -#: ../Beremiz.py:1391 +#: ../Beremiz.py:1415 msgid "Please enter a name for plugin:" msgstr "Saisissez un nom pour le plugin :" -#: ../targets/toolchain_gcc.py:99 +#: ../targets/toolchain_gcc.py:103 msgid "Plugin : " msgstr "Plugin :" -#: ../plugger.py:1335 +#: ../plugger.py:1418 msgid "Plugins code generation failed !\n" msgstr "La création du code des plugins a échoué !\n" @@ -596,29 +617,29 @@ msgid "Port number must be an integer!" msgstr "Le numéro de port doit être un entier !" -#: ../Beremiz.py:304 +#: ../Beremiz.py:306 msgid "Preview" msgstr "Aperçu avant impression" -#: ../Beremiz.py:306 +#: ../Beremiz.py:308 msgid "Print" msgstr "Imprimer" -#: ../plugger.py:856 +#: ../plugger.py:901 msgid "Project not created" msgstr "Le projet n'a pu être créé" -#: ../plugger.py:540 +#: ../plugger.py:549 #, python-format msgid "Project tree layout do not match plugin.xml %s!=%s " msgstr "L'organisation du projet ne correspond pas à plugin.xml %s!=%s" -#: ../Beremiz.py:309 +#: ../Beremiz.py:311 msgid "Properties" msgstr "Propriétés" #: ../plugins/python/PythonEditor.py:513 -#: ../plugins/python/PythonEditor.py:566 +#: ../plugins/python/PythonEditor.py:565 msgid "PythonEditor" msgstr "PythonEditor" @@ -626,15 +647,15 @@ msgid "Quit" msgstr "Quitter" -#: ../Beremiz.py:312 +#: ../Beremiz.py:314 msgid "Quit\tCTRL+Q" msgstr "Quitter\tCTRL+Q" -#: ../plugger.py:1854 +#: ../plugger.py:1937 msgid "Raw IEC code" msgstr "Ajout code IEC" -#: ../Beremiz.py:1400 +#: ../Beremiz.py:1425 msgid "Really delete plugin ?" msgstr "Voulez-vous réellement supprimer le plugin ?" @@ -650,11 +671,11 @@ msgid "Refresh\tCTRL+R" msgstr "Actualiser\tCTRL+R" -#: ../Beremiz.py:1400 +#: ../Beremiz.py:1425 msgid "Remove plugin" msgstr "Enlever le plugin" -#: ../plugger.py:1816 +#: ../plugger.py:1899 msgid "Run" msgstr "Exécuter" @@ -666,58 +687,57 @@ msgid "Save\tCTRL+S" msgstr "Enregistrer\tCTRL+S" -#: ../Beremiz.py:482 -#: ../Beremiz.py:1340 -msgid "Save changes ?" -msgstr "Enregistrer les changements ?" +#: ../Beremiz.py:297 +msgid "Save as\tCTRL+SHIFT+S" +msgstr "Enregistrer sous...\tCTRL+SHIFT+S" #: ../discovery.py:81 msgid "Services available:" msgstr "Services disponibles:" -#: ../plugger.py:1851 +#: ../plugger.py:1934 msgid "Show IEC code generated by PLCGenerator" msgstr "Afficher le code IEC généré par PLCGenerator" -#: ../plugins/canfestival/canfestival.py:220 +#: ../plugins/canfestival/canfestival.py:249 msgid "Show Master" msgstr "Afficher le maître" -#: ../plugins/canfestival/canfestival.py:221 +#: ../plugins/canfestival/canfestival.py:250 msgid "Show Master generated by config_utils" msgstr "Afficher le maître généré par config_utils" -#: ../plugger.py:1849 +#: ../plugger.py:1932 msgid "Show code" msgstr "Afficher le code" -#: ../plugger.py:1818 +#: ../plugger.py:1901 #: ../Beremiz_service.py:317 msgid "Start PLC" msgstr "Démarrer l'automate" -#: ../plugger.py:1823 +#: ../plugger.py:1906 msgid "Start PLC (debug mode)" msgstr "Démarrer l'automate (en mode debug)" -#: ../plugger.py:1313 +#: ../plugger.py:1396 #, python-format msgid "Start build in %s\n" msgstr "Début de la compilation dans %s\n" -#: ../plugger.py:1454 +#: ../plugger.py:1537 msgid "Started" msgstr "Démarré" -#: ../plugger.py:1451 +#: ../plugger.py:1534 msgid "Starting" msgstr "Démarrage" -#: ../plugger.py:1641 +#: ../plugger.py:1724 msgid "Starting PLC (debug mode)\n" msgstr "Démarrage de l'automate (en mode debug) en cours\n" -#: ../plugger.py:1830 +#: ../plugger.py:1913 msgid "Stop" msgstr "Arrêter" @@ -725,35 +745,39 @@ msgid "Stop PLC" msgstr "Arrêter l'automate" -#: ../plugger.py:1832 +#: ../plugger.py:1915 msgid "Stop Running PLC" msgstr "Arrêter l'automate en cours d'exécution" -#: ../plugger.py:1457 +#: ../plugger.py:1540 msgid "Stopped" msgstr "Arrêté" -#: ../plugger.py:1673 +#: ../plugger.py:1756 msgid "Stopping debug\n" msgstr "Arrêt du débogage en cours\n" -#: ../Beremiz.py:370 +#: ../Beremiz.py:492 +msgid "There are changes, do you want to save?" +msgstr "Le projet a été modifié, voulez-vous l'enregistrer ?" + +#: ../Beremiz.py:374 msgid "Topology" msgstr "Topologie" -#: ../plugger.py:1839 +#: ../plugger.py:1922 msgid "Transfer" msgstr "Transférer" -#: ../plugger.py:1841 +#: ../plugger.py:1924 msgid "Transfer PLC" msgstr "Transférer l'automate" -#: ../plugger.py:1797 +#: ../plugger.py:1880 msgid "Transfer completed successfully.\n" msgstr "Transfert effectué avec succès.\n" -#: ../plugger.py:1799 +#: ../plugger.py:1882 msgid "Transfer failed\n" msgstr "Le transfert a échoué\n" @@ -785,7 +809,7 @@ msgid "WXGLADE GUI" msgstr "IHM WXGlade" -#: ../plugger.py:1016 +#: ../plugger.py:1099 msgid "Warnings in ST/IL/SFC code generator :\n" msgstr "Mises en garde du generateur de code ST/IL/SFC :\n" @@ -793,21 +817,69 @@ msgid "Wrong URI, please check it !\n" msgstr "URI inconnue, veuillez vérifier l'adresse !\n" -#: ../wxPopen.py:134 +#: ../plugins/c_ext/c_ext.py:229 +msgid "" +"You don't have write permissions.\n" +"Open CFileEditor anyway ?" +msgstr "" +"Vous n'avez pas les permissions d'écriture.\n" +"Ouvrir CFileEditor tout de même ?" + +#: ../plugins/python/modules/svgui/svgui.py:104 +msgid "" +"You don't have write permissions.\n" +"Open Inkscape anyway ?" +msgstr "" +"Vous n'avez pas les permissions d'écriture.\n" +"Ouvrir Inkscape tout de même ?" + +#: ../plugins/canfestival/canfestival.py:207 +msgid "" +"You don't have write permissions.\n" +"Open NetworkEdit anyway ?" +msgstr "" +"Vous n'avez pas les permissions d'écriture.\n" +"Ouvrir NetworkEdit tout de même ?" + +#: ../plugins/canfestival/canfestival.py:107 +msgid "" +"You don't have write permissions.\n" +"Open ObjDictEdit anyway ?" +msgstr "" +"Vous n'avez pas les permissions d'écriture.\n" +"Ouvrir ObjdictEdit tout de même ?" + +#: ../plugins/python/modules/wxglade_hmi/wxglade_hmi.py:106 +msgid "" +"You don't have write permissions.\n" +"Open wxGlade anyway ?" +msgstr "" +"Vous n'avez pas les permissions d'écriture.\n" +"Ouvrir wxGlade tout de même ?" + +#: ../plugger.py:872 +msgid "" +"You must have permission to work on the project\n" +"Work on a project copy ?" +msgstr "" +"Vous n'avez pas la permission de travailler sur le projet.\n" +"Travailler sur une copie du projet ?" + +#: ../wxPopen.py:145 #, python-format msgid "exited with status %s (pid %s)\n" msgstr "a quitté avec le status %s (pid %s)\n" -#: ../Beremiz.py:1420 -#: ../Beremiz.py:1422 +#: ../Beremiz.py:1445 +#: ../Beremiz.py:1447 msgid "file : " msgstr "fichier :" -#: ../Beremiz.py:1423 +#: ../Beremiz.py:1448 msgid "function : " msgstr "fonction :" -#: ../Beremiz.py:1423 +#: ../Beremiz.py:1448 msgid "line : " msgstr "ligne :" @@ -902,6 +974,9 @@ msgid "XenoConfig" msgstr "Config Xenomai" +#~ msgid "Save changes ?" +#~ msgstr "Enregistrer les changements ?" + #, fuzzy #~ msgid "Conflict type for location \"%s\"" #~ msgstr "Conflit entre types pour l'adresse \"%s\"" diff -r fcd344deae84 -r 75fe73597273 i18n/app.fil --- a/i18n/app.fil Tue Oct 27 16:32:54 2009 +0100 +++ b/i18n/app.fil Mon Nov 02 15:38:49 2009 +0100 @@ -1,6 +1,5 @@ ../Beremiz.py ../plugger.py -../beremiz_postinst.py ../Beremiz_service.py ../discovery.py ../wxPopen.py diff -r fcd344deae84 -r 75fe73597273 i18n/messages.pot --- a/i18n/messages.pot Tue Oct 27 16:32:54 2009 +0100 +++ b/i18n/messages.pot Mon Nov 02 15:38:49 2009 +0100 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-10-09 16:27+0200\n" +"POT-Creation-Date: 2009-11-02 10:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,28 +16,26 @@ "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ../Beremiz.py:1432 +#: ../Beremiz.py:1457 #, python-format msgid "" "\n" "An unhandled exception (bug) occured. Bug report saved at :\n" "(%s)\n" "\n" -"Please contact LOLITech at:\n" -"+33 (0)3 29 57 60 42\n" -"or please be kind enough to send this file to:\n" -"bugs_beremiz@lolitech.fr\n" +"Please be kind enough to send this file to:\n" +"edouard.tisserant@gmail.com\n" "\n" "You should now restart Beremiz.\n" "\n" "Traceback:\n" msgstr "" -#: ../plugger.py:1370 +#: ../plugger.py:1453 msgid " generation failed !\n" msgstr "" -#: ../Beremiz.py:1332 +#: ../Beremiz.py:1357 #, python-format msgid "\"%s\" folder is not a valid Beremiz project\n" msgstr "" @@ -46,45 +44,45 @@ msgid "&Edit" msgstr "" -#: ../Beremiz.py:1420 ../Beremiz.py:1422 ../Beremiz.py:1423 +#: ../Beremiz.py:1445 ../Beremiz.py:1447 ../Beremiz.py:1448 msgid ", " msgstr "" -#: ../Beremiz.py:1418 +#: ../Beremiz.py:1443 msgid ". " msgstr "" -#: ../plugger.py:432 +#: ../plugger.py:443 #, python-format msgid "A child names \"%s\" already exist -> \"%s\"\n" msgstr "" -#: ../plugger.py:464 +#: ../plugger.py:475 #, python-format msgid "A child with IEC channel %d already exist -> %d\n" msgstr "" -#: ../Beremiz.py:329 +#: ../Beremiz.py:332 msgid "About" msgstr "" -#: ../Beremiz.py:1369 +#: ../Beremiz.py:1392 msgid "About Beremiz" msgstr "" -#: ../Beremiz.py:1391 +#: ../Beremiz.py:1415 msgid "Add Plugin" msgstr "" -#: ../Beremiz.py:585 ../Beremiz.py:849 +#: ../Beremiz.py:603 ../Beremiz.py:867 msgid "Add a sub plugin" msgstr "" -#: ../plugger.py:1683 +#: ../plugger.py:1766 msgid "Already connected. Please disconnect\n" msgstr "" -#: ../Beremiz.py:1088 +#: ../Beremiz.py:1106 msgid "Append " msgstr "" @@ -94,62 +92,62 @@ msgid "Bad location size : %s" msgstr "" -#: ../Beremiz.py:417 +#: ../Beremiz.py:426 msgid "Beremiz" msgstr "" -#: ../Beremiz.py:327 +#: ../Beremiz.py:330 msgid "Beremiz\tF1" msgstr "" -#: ../plugger.py:1466 +#: ../plugger.py:1549 msgid "Broken" msgstr "" -#: ../plugger.py:1807 +#: ../plugger.py:1890 msgid "Build" msgstr "" -#: ../plugger.py:1434 +#: ../plugger.py:1517 msgid "Build directory already clean\n" msgstr "" -#: ../plugger.py:1808 +#: ../plugger.py:1891 msgid "Build project into build folder" msgstr "" -#: ../plugger.py:1388 +#: ../plugger.py:1471 msgid "C Build crashed !\n" msgstr "" -#: ../plugger.py:1385 +#: ../plugger.py:1468 msgid "C Build failed.\n" msgstr "" -#: ../plugger.py:1374 +#: ../plugger.py:1457 msgid "C code generated successfully.\n" msgstr "" -#: ../targets/toolchain_gcc.py:125 +#: ../targets/toolchain_gcc.py:129 #, python-format msgid "C compilation of %s failed.\n" msgstr "" -#: ../plugger.py:1117 +#: ../plugger.py:1200 #, python-format msgid "Can't find module for target %s!\n" msgstr "" -#: ../plugger.py:1756 +#: ../plugger.py:1839 msgid "Cannot compare latest build to target. Please build.\n" msgstr "" -#: ../plugger.py:502 +#: ../plugger.py:513 #, python-format msgid "Cannot create child %s of type %s " msgstr "" -#: ../plugger.py:457 +#: ../plugger.py:468 #, python-format msgid "Cannot find lower free IEC channel than %d\n" msgstr "" @@ -158,7 +156,7 @@ msgid "Cannot get PLC status - connection failed.\n" msgstr "" -#: ../plugger.py:1215 +#: ../plugger.py:1298 msgid "Cannot open/parse VARIABLES.csv!\n" msgstr "" @@ -187,7 +185,11 @@ msgid "Choose a SVG file" msgstr "" -#: ../Beremiz.py:1289 ../Beremiz.py:1314 +#: ../plugger.py:969 +msgid "Choose a directory to save project" +msgstr "" + +#: ../Beremiz.py:1311 ../Beremiz.py:1339 msgid "Choose a project" msgstr "" @@ -195,47 +197,47 @@ msgid "Choose a working directory " msgstr "" -#: ../plugger.py:882 +#: ../plugger.py:927 msgid "Chosen folder doesn't contain a program. It's not a valid project!" msgstr "" -#: ../plugger.py:847 +#: ../plugger.py:892 msgid "Chosen folder isn't empty. You can't use it for a new project!" msgstr "" -#: ../plugger.py:1811 +#: ../plugger.py:1894 msgid "Clean" msgstr "" -#: ../plugger.py:1813 +#: ../plugger.py:1896 msgid "Clean project build folder" msgstr "" -#: ../plugger.py:1431 +#: ../plugger.py:1514 msgid "Cleaning the build directory\n" msgstr "" -#: ../Beremiz.py:483 ../Beremiz.py:1341 +#: ../Beremiz.py:504 msgid "Close Application" msgstr "" +#: ../Beremiz.py:301 ../Beremiz.py:489 +msgid "Close Project" +msgstr "" + #: ../Beremiz.py:299 -msgid "Close Project" -msgstr "" - -#: ../Beremiz.py:297 msgid "Close Tab\tCTRL+W" msgstr "" -#: ../plugger.py:1039 +#: ../plugger.py:1122 msgid "Compiling IEC Program into C code...\n" msgstr "" -#: ../plugger.py:1835 +#: ../plugger.py:1918 msgid "Connect" msgstr "" -#: ../plugger.py:1836 +#: ../plugger.py:1919 msgid "Connect to the target PLC" msgstr "" @@ -244,41 +246,41 @@ msgid "Connecting to URI : %s\n" msgstr "" -#: ../plugger.py:1702 +#: ../plugger.py:1785 msgid "Connection canceled!\n" msgstr "" -#: ../plugger.py:1719 +#: ../plugger.py:1802 #, python-format msgid "Connection failed to %s!\n" msgstr "" -#: ../plugger.py:625 +#: ../plugger.py:634 #, python-format msgid "" "Could not add child \"%s\", type %s :\n" "%s\n" msgstr "" -#: ../plugger.py:602 +#: ../plugger.py:611 #, python-format msgid "" "Couldn't load plugin base parameters %s :\n" " %s" msgstr "" -#: ../plugger.py:613 +#: ../plugger.py:622 #, python-format msgid "" "Couldn't load plugin parameters %s :\n" " %s" msgstr "" -#: ../plugger.py:1647 +#: ../plugger.py:1730 msgid "Couldn't start PLC debug !\n" msgstr "" -#: ../plugger.py:1677 +#: ../plugger.py:1760 msgid "Couldn't stop PLC !\n" msgstr "" @@ -286,53 +288,53 @@ msgid "Create HMI" msgstr "" -#: ../plugger.py:1821 +#: ../plugger.py:1904 msgid "Debug" msgstr "" -#: ../plugger.py:1520 +#: ../plugger.py:1603 #, python-format msgid "Debug : Unknown variable %s\n" msgstr "" -#: ../plugger.py:1632 +#: ../plugger.py:1715 msgid "Debug Thread couldn't be killed" msgstr "" -#: ../plugger.py:1616 +#: ../plugger.py:1699 #, python-format msgid "Debug data not coherent %d != %d\n" msgstr "" -#: ../plugger.py:1624 +#: ../plugger.py:1707 msgid "Debugger disabled\n" msgstr "" -#: ../Beremiz.py:840 +#: ../Beremiz.py:858 msgid "Delete this plugin" msgstr "" -#: ../plugger.py:1463 +#: ../plugger.py:1546 msgid "Dirty" msgstr "" -#: ../plugger.py:1844 +#: ../plugger.py:1927 msgid "Disconnect" msgstr "" -#: ../plugger.py:1846 +#: ../plugger.py:1929 msgid "Disconnect from PLC" msgstr "" -#: ../plugger.py:1469 +#: ../plugger.py:1552 msgid "Disconnected" msgstr "" -#: ../plugins/c_ext/c_ext.py:236 ../plugins/c_ext/c_ext.py:237 +#: ../plugins/c_ext/c_ext.py:250 ../plugins/c_ext/c_ext.py:251 msgid "Edit C File" msgstr "" -#: ../plugins/canfestival/canfestival.py:217 +#: ../plugins/canfestival/canfestival.py:246 msgid "Edit CanOpen Network with NetworkEdit" msgstr "" @@ -340,19 +342,19 @@ msgid "Edit a WxWidgets GUI with WXGlade" msgstr "" -#: ../plugins/canfestival/canfestival.py:216 +#: ../plugins/canfestival/canfestival.py:245 msgid "Edit network" msgstr "" -#: ../plugger.py:1855 +#: ../plugger.py:1938 msgid "Edit raw IEC code added to code generated by PLCGenerator" msgstr "" -#: ../plugger.py:1460 +#: ../plugger.py:1543 msgid "Empty" msgstr "" -#: ../Beremiz.py:790 +#: ../Beremiz.py:808 msgid "Enable/Disable this plugin" msgstr "" @@ -368,54 +370,54 @@ msgid "Enter the IP of the interface to bind" msgstr "" -#: ../Beremiz.py:1446 ../Beremiz.py:1456 ../Beremiz_service.py:268 -#: ../Beremiz_service.py:392 +#: ../Beremiz.py:1469 ../Beremiz.py:1479 ../plugger.py:873 +#: ../Beremiz_service.py:268 ../Beremiz_service.py:392 msgid "Error" msgstr "" -#: ../plugger.py:1087 +#: ../plugger.py:1170 msgid "Error : At least one configuration and one resource must be declared in PLC !\n" msgstr "" -#: ../plugger.py:1079 +#: ../plugger.py:1162 #, python-format msgid "Error : IEC to C compiler returned %d\n" msgstr "" -#: ../plugger.py:1021 +#: ../plugger.py:1104 #, python-format msgid "" "Error in ST/IL/SFC code generator :\n" "%s\n" msgstr "" -#: ../plugger.py:207 +#: ../plugger.py:218 #, python-format msgid "Error while saving \"%s\"\n" msgstr "" -#: ../plugins/canfestival/canfestival.py:208 +#: ../plugins/canfestival/canfestival.py:237 msgid "Error: No Master generated\n" msgstr "" -#: ../plugins/canfestival/canfestival.py:203 +#: ../plugins/canfestival/canfestival.py:232 msgid "Error: No PLC built\n" msgstr "" -#: ../plugger.py:1713 +#: ../plugger.py:1796 #, python-format msgid "Exception while connecting %s!\n" msgstr "" -#: ../plugger.py:1091 +#: ../plugger.py:1174 msgid "Extracting Located Variables...\n" msgstr "" -#: ../plugger.py:1771 +#: ../plugger.py:1854 msgid "Failed : Must build before transfer.\n" msgstr "" -#: ../plugger.py:1379 +#: ../plugger.py:1462 msgid "Fatal : cannot get builder.\n" msgstr "" @@ -423,15 +425,15 @@ msgid "Force runtime reload\n" msgstr "" -#: ../plugger.py:1011 +#: ../plugger.py:1094 msgid "Generating SoftPLC IEC-61131 ST/IL/SFC code...\n" msgstr "" -#: ../plugger.py:1329 +#: ../plugger.py:1412 msgid "Generating plugins C code\n" msgstr "" -#: ../plugger.py:1321 +#: ../plugger.py:1404 msgid "IEC-61131-3 code generation failed !\n" msgstr "" @@ -454,15 +456,15 @@ msgid "Invalid type \"%s\"-> %d != %d for location\"%s\"" msgstr "" -#: ../plugger.py:1777 +#: ../plugger.py:1860 msgid "Latest build already matches current target. Transfering anyway...\n" msgstr "" -#: ../plugger.py:1747 +#: ../plugger.py:1830 msgid "Latest build does not match with target, please transfer.\n" msgstr "" -#: ../plugger.py:1751 +#: ../plugger.py:1834 msgid "Latest build matches target, no transfer needed.\n" msgstr "" @@ -474,7 +476,7 @@ msgid "Launch a live Python shell" msgstr "" -#: ../targets/toolchain_gcc.py:133 +#: ../targets/toolchain_gcc.py:137 msgid "Linking :\n" msgstr "" @@ -482,11 +484,11 @@ msgid "Local" msgstr "" -#: ../Beremiz.py:376 +#: ../Beremiz.py:380 msgid "Log Console" msgstr "" -#: ../plugger.py:512 +#: ../plugger.py:523 #, python-format msgid "Max count (%d) reached for this plugin of type %s " msgstr "" @@ -499,7 +501,7 @@ msgid "New\tCTRL+N" msgstr "" -#: ../plugger.py:1801 +#: ../plugger.py:1884 msgid "No PLC to transfer (did build succeed ?)\n" msgstr "" @@ -536,28 +538,48 @@ msgid "Open\tCTRL+O" msgstr "" -#: ../targets/toolchain_gcc.py:101 +#: ../plugins/c_ext/c_ext.py:230 +msgid "Open CFileEditor" +msgstr "" + +#: ../plugins/python/modules/svgui/svgui.py:105 +msgid "Open Inkscape" +msgstr "" + +#: ../plugins/canfestival/canfestival.py:208 +msgid "Open NetworkEdit" +msgstr "" + +#: ../plugins/canfestival/canfestival.py:108 +msgid "Open ObjDictEdit" +msgstr "" + +#: ../plugins/python/modules/wxglade_hmi/wxglade_hmi.py:107 +msgid "Open wxGlade" +msgstr "" + +#: ../targets/toolchain_gcc.py:105 msgid "PLC :\n" msgstr "" -#: ../plugger.py:1489 ../plugger.py:1733 +#: ../plugger.py:1572 ../plugger.py:1816 #, python-format msgid "PLC is %s\n" msgstr "" -#: ../Beremiz.py:302 +#: ../Beremiz.py:304 msgid "Page Setup" msgstr "" -#: ../Beremiz.py:1391 +#: ../Beremiz.py:1415 msgid "Please enter a name for plugin:" msgstr "" -#: ../targets/toolchain_gcc.py:99 +#: ../targets/toolchain_gcc.py:103 msgid "Plugin : " msgstr "" -#: ../plugger.py:1335 +#: ../plugger.py:1418 msgid "Plugins code generation failed !\n" msgstr "" @@ -569,28 +591,28 @@ msgid "Port number must be an integer!" msgstr "" -#: ../Beremiz.py:304 +#: ../Beremiz.py:306 msgid "Preview" msgstr "" -#: ../Beremiz.py:306 +#: ../Beremiz.py:308 msgid "Print" msgstr "" -#: ../plugger.py:856 +#: ../plugger.py:901 msgid "Project not created" msgstr "" -#: ../plugger.py:540 +#: ../plugger.py:549 #, python-format msgid "Project tree layout do not match plugin.xml %s!=%s " msgstr "" -#: ../Beremiz.py:309 +#: ../Beremiz.py:311 msgid "Properties" msgstr "" -#: ../plugins/python/PythonEditor.py:513 ../plugins/python/PythonEditor.py:566 +#: ../plugins/python/PythonEditor.py:513 ../plugins/python/PythonEditor.py:565 msgid "PythonEditor" msgstr "" @@ -598,15 +620,15 @@ msgid "Quit" msgstr "" -#: ../Beremiz.py:312 +#: ../Beremiz.py:314 msgid "Quit\tCTRL+Q" msgstr "" -#: ../plugger.py:1854 +#: ../plugger.py:1937 msgid "Raw IEC code" msgstr "" -#: ../Beremiz.py:1400 +#: ../Beremiz.py:1425 msgid "Really delete plugin ?" msgstr "" @@ -622,11 +644,11 @@ msgid "Refresh\tCTRL+R" msgstr "" -#: ../Beremiz.py:1400 +#: ../Beremiz.py:1425 msgid "Remove plugin" msgstr "" -#: ../plugger.py:1816 +#: ../plugger.py:1899 msgid "Run" msgstr "" @@ -638,56 +660,56 @@ msgid "Save\tCTRL+S" msgstr "" -#: ../Beremiz.py:482 ../Beremiz.py:1340 -msgid "Save changes ?" +#: ../Beremiz.py:297 +msgid "Save as\tCTRL+SHIFT+S" msgstr "" #: ../discovery.py:81 msgid "Services available:" msgstr "" -#: ../plugger.py:1851 +#: ../plugger.py:1934 msgid "Show IEC code generated by PLCGenerator" msgstr "" -#: ../plugins/canfestival/canfestival.py:220 +#: ../plugins/canfestival/canfestival.py:249 msgid "Show Master" msgstr "" -#: ../plugins/canfestival/canfestival.py:221 +#: ../plugins/canfestival/canfestival.py:250 msgid "Show Master generated by config_utils" msgstr "" -#: ../plugger.py:1849 +#: ../plugger.py:1932 msgid "Show code" msgstr "" -#: ../plugger.py:1818 ../Beremiz_service.py:317 +#: ../plugger.py:1901 ../Beremiz_service.py:317 msgid "Start PLC" msgstr "" -#: ../plugger.py:1823 +#: ../plugger.py:1906 msgid "Start PLC (debug mode)" msgstr "" -#: ../plugger.py:1313 +#: ../plugger.py:1396 #, python-format msgid "Start build in %s\n" msgstr "" -#: ../plugger.py:1454 +#: ../plugger.py:1537 msgid "Started" msgstr "" -#: ../plugger.py:1451 +#: ../plugger.py:1534 msgid "Starting" msgstr "" -#: ../plugger.py:1641 +#: ../plugger.py:1724 msgid "Starting PLC (debug mode)\n" msgstr "" -#: ../plugger.py:1830 +#: ../plugger.py:1913 msgid "Stop" msgstr "" @@ -695,35 +717,39 @@ msgid "Stop PLC" msgstr "" -#: ../plugger.py:1832 +#: ../plugger.py:1915 msgid "Stop Running PLC" msgstr "" -#: ../plugger.py:1457 +#: ../plugger.py:1540 msgid "Stopped" msgstr "" -#: ../plugger.py:1673 +#: ../plugger.py:1756 msgid "Stopping debug\n" msgstr "" -#: ../Beremiz.py:370 +#: ../Beremiz.py:492 +msgid "There are changes, do you want to save?" +msgstr "" + +#: ../Beremiz.py:374 msgid "Topology" msgstr "" -#: ../plugger.py:1839 +#: ../plugger.py:1922 msgid "Transfer" msgstr "" -#: ../plugger.py:1841 +#: ../plugger.py:1924 msgid "Transfer PLC" msgstr "" -#: ../plugger.py:1797 +#: ../plugger.py:1880 msgid "Transfer completed successfully.\n" msgstr "" -#: ../plugger.py:1799 +#: ../plugger.py:1882 msgid "Transfer failed\n" msgstr "" @@ -755,7 +781,7 @@ msgid "WXGLADE GUI" msgstr "" -#: ../plugger.py:1016 +#: ../plugger.py:1099 msgid "Warnings in ST/IL/SFC code generator :\n" msgstr "" @@ -763,20 +789,56 @@ msgid "Wrong URI, please check it !\n" msgstr "" -#: ../wxPopen.py:134 +#: ../plugins/c_ext/c_ext.py:229 +msgid "" +"You don't have write permissions.\n" +"Open CFileEditor anyway ?" +msgstr "" + +#: ../plugins/python/modules/svgui/svgui.py:104 +msgid "" +"You don't have write permissions.\n" +"Open Inkscape anyway ?" +msgstr "" + +#: ../plugins/canfestival/canfestival.py:207 +msgid "" +"You don't have write permissions.\n" +"Open NetworkEdit anyway ?" +msgstr "" + +#: ../plugins/canfestival/canfestival.py:107 +msgid "" +"You don't have write permissions.\n" +"Open ObjDictEdit anyway ?" +msgstr "" + +#: ../plugins/python/modules/wxglade_hmi/wxglade_hmi.py:106 +msgid "" +"You don't have write permissions.\n" +"Open wxGlade anyway ?" +msgstr "" + +#: ../plugger.py:872 +msgid "" +"You must have permission to work on the project\n" +"Work on a project copy ?" +msgstr "" + +#: ../wxPopen.py:145 #, python-format msgid "exited with status %s (pid %s)\n" msgstr "" -#: ../Beremiz.py:1420 ../Beremiz.py:1422 +#: ../Beremiz.py:1445 ../Beremiz.py:1447 msgid "file : " msgstr "" -#: ../Beremiz.py:1423 +#: ../Beremiz.py:1448 msgid "function : " msgstr "" -#: ../Beremiz.py:1423 +#: ../Beremiz.py:1448 msgid "line : " msgstr "" diff -r fcd344deae84 -r 75fe73597273 images/EditCfile.png Binary file images/EditCfile.png has changed diff -r fcd344deae84 -r 75fe73597273 images/HideVars.png Binary file images/HideVars.png has changed diff -r fcd344deae84 -r 75fe73597273 images/Maximize.png Binary file images/Maximize.png has changed diff -r fcd344deae84 -r 75fe73597273 images/Minimize.png Binary file images/Minimize.png has changed diff -r fcd344deae84 -r 75fe73597273 images/ShowIECcode.png Binary file images/ShowIECcode.png has changed diff -r fcd344deae84 -r 75fe73597273 images/ShowVars.png Binary file images/ShowVars.png has changed diff -r fcd344deae84 -r 75fe73597273 images/editIECrawcode.png Binary file images/editIECrawcode.png has changed diff -r fcd344deae84 -r 75fe73597273 images/editPYTHONcode.png Binary file images/editPYTHONcode.png has changed diff -r fcd344deae84 -r 75fe73597273 images/editWXGLADE.png Binary file images/editWXGLADE.png has changed diff -r fcd344deae84 -r 75fe73597273 images/icons.svg --- a/images/icons.svg Tue Oct 27 16:32:54 2009 +0100 +++ b/images/icons.svg Mon Nov 02 15:38:49 2009 +0100 @@ -29,8 +29,8 @@ 2009.0 Beta - - - - - + transform="matrix(0.5511608,0,0,0.5511608,-977.19352,996.99467)"> \n") - BaseXMLFile.write(self.MandatoryParams[1].generateXMLText(self.MandatoryParams[0], 0)) - BaseXMLFile.close() - - # generate XML for XML parameters controller of the plugin - if self.PlugParams: - XMLFile = open(self.PluginXmlFilePath(),'w') - XMLFile.write("\n") - XMLFile.write(self.PlugParams[1].generateXMLText(self.PlugParams[0], 0)) - XMLFile.close() - - # Call the plugin specific OnPlugSave method - result = self.OnPlugSave() - if not result: - return _("Error while saving \"%s\"\n")%self.PlugPath() - - # mark plugin as saved - self.ChangesToSave = False - # go through all childs and do the same - for PlugChild in self.IterChilds(): - result = PlugChild.PlugRequestSave() - if result: - return result + if self.GetPlugRoot().CheckProjectPathPerm(False): + # If plugin do not have corresponding directory + plugpath = self.PlugPath() + if not os.path.isdir(plugpath): + # Create it + os.mkdir(plugpath) + + # generate XML for base XML parameters controller of the plugin + if self.MandatoryParams: + BaseXMLFile = open(self.PluginBaseXmlFilePath(),'w') + BaseXMLFile.write("\n") + BaseXMLFile.write(self.MandatoryParams[1].generateXMLText(self.MandatoryParams[0], 0).encode("utf-8")) + BaseXMLFile.close() + + # generate XML for XML parameters controller of the plugin + if self.PlugParams: + XMLFile = open(self.PluginXmlFilePath(),'w') + XMLFile.write("\n") + XMLFile.write(self.PlugParams[1].generateXMLText(self.PlugParams[0], 0).encode("utf-8")) + XMLFile.close() + + # Call the plugin specific OnPlugSave method + result = self.OnPlugSave() + if not result: + return _("Error while saving \"%s\"\n")%self.PlugPath() + + # mark plugin as saved + self.ChangesToSave = False + # go through all childs and do the same + for PlugChild in self.IterChilds(): + result = PlugChild.PlugRequestSave() + if result: + return result return None def PlugImport(self, src_PlugPath): @@ -690,7 +701,7 @@ "LREAL" : 8, } -import re +import re, tempfile import targets import connectors from discovery import DiscoveryDialog @@ -764,7 +775,7 @@ self.PlugType = "Beremiz" # After __init__ root plugin is not valid self.ProjectPath = None - self.BuildPath = None + self._setBuildPath(None) self.DebugThread = None self.debug_break = False self.previous_plcstate = None @@ -852,6 +863,23 @@ if path.startswith("BeremizRoot.TargetType.") and self.BeremizRoot.getTargetType().getcontent() is None: self.BeremizRoot.setTargetType(self.GetDefaultTarget()) return PlugTemplate.SetParamsAttribute(self, path, value) + + # helper func to check project path write permission + def CheckProjectPathPerm(self, dosave=True): + if CheckPathPerm(self.ProjectPath): + return True + dialog = wx.MessageDialog(self.AppFrame, + _('You must have permission to work on the project\nWork on a project copy ?'), + _('Error'), + wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) + answer = dialog.ShowModal() + dialog.Destroy() + if answer == wx.ID_YES: + if self.SaveProjectAs(): + self.AppFrame.RefreshAll() + self.AppFrame.RefreshTitle() + return True + return False def NewProject(self, ProjectPath, BuildPath=None): """ @@ -879,7 +907,7 @@ self.PluggedChilds = {} # Keep track of the root plugin (i.e. project path) self.ProjectPath = ProjectPath - self.BuildPath = BuildPath + self._setBuildPath(BuildPath) # get plugins bloclist (is that usefull at project creation?) self.RefreshPluginsBlockLists() # this will create files base XML files @@ -906,7 +934,7 @@ self.PluggedChilds = {} # Keep track of the root plugin (i.e. project path) self.ProjectPath = ProjectPath - self.BuildPath = BuildPath + self._setBuildPath(BuildPath) # If dir have already be made, and file exist if os.path.isdir(self.PlugPath()) and os.path.isfile(self.PluginXmlFilePath()): #Load the plugin.xml file into parameters members @@ -930,11 +958,26 @@ self.ResetAppFrame(None) def SaveProject(self): - if not self.SaveXMLFile(): + if self.CheckProjectPathPerm(False): self.SaveXMLFile(os.path.join(self.ProjectPath, 'plc.xml')) - result = self.PlugRequestSave() - if result: - self.logger.write_error(result) + result = self.PlugRequestSave() + if result: + self.logger.write_error(result) + + def SaveProjectAs(self, dosave=True): + # Ask user to choose a path with write permissions + dirdialog = wx.DirDialog(self.AppFrame , _("Choose a directory to save project"), os.getenv("HOME"), wx.DD_NEW_DIR_BUTTON) + answer = dirdialog.ShowModal() + dirdialog.Destroy() + if answer == wx.ID_OK: + newprojectpath = dirdialog.GetPath() + if os.path.isdir(newprojectpath): + self.ProjectPath = newprojectpath + if dosave: + self.SaveProject() + self._setBuildPath(self.BuildPath) + return True + return False # Update PLCOpenEditor Plugin Block types from loaded plugins def RefreshPluginsBlockLists(self): @@ -971,10 +1014,33 @@ def ParentsBlockTypesFactory(self): return self.BlockTypesFactory() + def _setBuildPath(self, buildpath): + if CheckPathPerm(buildpath): + self.BuildPath = buildpath + else: + self.BuildPath = None + self.BuildPath = buildpath + self.DefaultBuildPath = None + if self._builder is not None: + self._builder.SetBuildPath(self._getBuildPath()) + def _getBuildPath(self): - if self.BuildPath is None: - return os.path.join(self.ProjectPath, "build") - return self.BuildPath + # BuildPath is defined by user + if self.BuildPath is not None: + return self.BuildPath + # BuildPath isn't defined by user but already created by default + if self.DefaultBuildPath is not None: + return self.DefaultBuildPath + # Create a build path in project folder if user has permissions + if CheckPathPerm(self.ProjectPath): + self.DefaultBuildPath = os.path.join(self.ProjectPath, "build") + # Create a build path in temp folder + else: + self.DefaultBuildPath = os.path.join(tempfile.mkdtemp(), os.path.basename(self.ProjectPath), "build") + + if not os.path.exists(self.DefaultBuildPath): + os.makedirs(self.DefaultBuildPath) + return self.DefaultBuildPath def _getExtraFilesPath(self): return os.path.join(self._getBuildPath(), "extra_files") @@ -1287,7 +1353,7 @@ "__publish_%s();"%locstrs[i-1] for i in xrange(len(locstrs), 0, -1)]), "init_calls":"\n ".join([ "init_level=%d; "%(i+1)+ - "if(res = __init_%s(argc,argv)){"%locstr + + "if((res = __init_%s(argc,argv))){"%locstr + #"printf(\"%s\"); "%locstr + #for debug "return res;}" for i,locstr in enumerate(locstrs)]), "cleanup_calls":"\n ".join([ diff -r fcd344deae84 -r 75fe73597273 plugins/c_ext/CFileEditor.py --- a/plugins/c_ext/CFileEditor.py Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/c_ext/CFileEditor.py Mon Nov 02 15:38:49 2009 +0100 @@ -908,14 +908,12 @@ selected = self.PartsOpened.GetSelection() if selected >= 0: self.PartsOpened.DeletePage(selected) - event.Skip() def OnSaveMenu(self, event): if getattr(self, "_onsave", None) != None: self._onsave() self.RefreshTitle() self.RefreshEditMenu() - event.Skip() #------------------------------------------------------------------------------- # Notebook Unified Functions @@ -957,7 +955,6 @@ if selected != -1: window = self.PartsOpened.GetPage(selected) window.RefreshView() - event.Skip() def OnUndoMenu(self, event): self.Controler.LoadPrevious() @@ -967,7 +964,6 @@ window.RefreshView() self.RefreshTitle() self.RefreshEditMenu() - event.Skip() def OnRedoMenu(self, event): self.Controler.LoadNext() @@ -977,7 +973,6 @@ window.RefreshView() self.RefreshTitle() self.RefreshEditMenu() - event.Skip() #------------------------------------------------------------------------------- # CFile Editor Panels Management Functions diff -r fcd344deae84 -r 75fe73597273 plugins/c_ext/c_ext.py --- a/plugins/c_ext/c_ext.py Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/c_ext/c_ext.py Mon Nov 02 15:38:49 2009 +0100 @@ -222,14 +222,28 @@ _View = None def _OpenView(self): if not self._View: - def _onclose(): - self._View = None - def _onsave(): - self.GetPlugRoot().SaveProject() - self._View = CFileEditor(self.GetPlugRoot().AppFrame, self) - self._View._onclose = _onclose - self._View._onsave = _onsave - self._View.Show() + open_cfileeditor = True + has_permissions = self.GetPlugRoot().CheckProjectPathPerm() + if not has_permissions: + dialog = wx.MessageDialog(self.GetPlugRoot().AppFrame, + _("You don't have write permissions.\nOpen CFileEditor anyway ?"), + _("Open CFileEditor"), + wx.YES_NO|wx.ICON_QUESTION) + open_cfileeditor = dialog.ShowModal() == wx.ID_YES + dialog.Destroy() + if open_cfileeditor: + def _onclose(): + self._View = None + if has_permissions: + def _onsave(): + self.GetPlugRoot().SaveProject() + else: + def _onsave(): + pass + self._View = CFileEditor(self.GetPlugRoot().AppFrame, self) + self._View._onclose = _onclose + self._View._onsave = _onsave + self._View.Show() PluginMethods = [ {"bitmap" : os.path.join("images", "EditCfile"), @@ -248,7 +262,7 @@ text += self.CFile.generateXMLText("CFile", 0, extras) xmlfile = open(filepath,"w") - xmlfile.write(text) + xmlfile.write(text.encode("utf-8")) xmlfile.close() self.CFileBuffer.CurrentSaved() diff -r fcd344deae84 -r 75fe73597273 plugins/canfestival/canfestival.py --- a/plugins/canfestival/canfestival.py Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/canfestival/canfestival.py Mon Nov 02 15:38:49 2009 +0100 @@ -100,16 +100,31 @@ _View = None def _OpenView(self): if not self._View: - def _onclose(): - self._View = None - def _onsave(): - self.GetPlugRoot().SaveProject() - self._View = objdictedit(self.GetPlugRoot().AppFrame, self) - # TODO redefine BusId when IEC channel change - self._View.SetBusId(self.GetCurrentLocation()) - self._View._onclose = _onclose - self._View._onsave = _onsave - self._View.Show() + open_objdictedit = True + has_permissions = self.GetPlugRoot().CheckProjectPathPerm() + if not has_permissions: + dialog = wx.MessageDialog(self.GetPlugRoot().AppFrame, + _("You don't have write permissions.\nOpen ObjDictEdit anyway ?"), + _("Open ObjDictEdit"), + wx.YES_NO|wx.ICON_QUESTION) + open_objdictedit = dialog.ShowModal() == wx.ID_YES + dialog.Destroy() + if open_objdictedit: + def _onclose(): + self._View = None + if has_permissions: + def _onsave(): + self.GetPlugRoot().SaveProject() + else: + def _onsave(): + pass + + self._View = objdictedit(self.GetPlugRoot().AppFrame, self) + # TODO redefine BusId when IEC channel change + self._View.SetBusId(self.GetCurrentLocation()) + self._View._onclose = _onclose + self._View._onsave = _onsave + self._View.Show() PluginMethods = [ {"bitmap" : os.path.join("images", "NetworkEdit"), @@ -185,16 +200,30 @@ _View = None def _OpenView(self): if not self._View: - def _onclose(): - self._View = None - def _onsave(): - self.GetPlugRoot().SaveProject() - self._View = networkedit(self.GetPlugRoot().AppFrame, self) - # TODO redefine BusId when IEC channel change - self._View.SetBusId(self.GetCurrentLocation()) - self._View._onclose = _onclose - self._View._onsave = _onsave - self._View.Show() + open_networkedit = True + has_permissions = self.GetPlugRoot().CheckProjectPathPerm() + if not has_permissions: + dialog = wx.MessageDialog(self.GetPlugRoot().AppFrame, + _("You don't have write permissions.\nOpen NetworkEdit anyway ?"), + _("Open NetworkEdit"), + wx.YES_NO|wx.ICON_QUESTION) + open_networkedit = dialog.ShowModal() == wx.ID_YES + dialog.Destroy() + if open_networkedit: + def _onclose(): + self._View = None + if has_permissions: + def _onsave(): + self.GetPlugRoot().SaveProject() + else: + def _onsave(): + pass + self._View = networkedit(self.GetPlugRoot().AppFrame, self) + # TODO redefine BusId when IEC channel change + self._View.SetBusId(self.GetCurrentLocation()) + self._View._onclose = _onclose + self._View._onsave = _onsave + self._View.Show() def _ShowMasterGenerated(self): buildpath = self._getBuildPath() diff -r fcd344deae84 -r 75fe73597273 plugins/python/PythonEditor.py --- a/plugins/python/PythonEditor.py Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/python/PythonEditor.py Mon Nov 02 15:38:49 2009 +0100 @@ -560,7 +560,6 @@ self._onsave() self.RefreshTitle() self.RefreshEditMenu() - event.Skip() def RefreshTitle(self): title = _("PythonEditor") @@ -577,19 +576,17 @@ def OnRefreshMenu(self, event): self.PythonEdited.RefreshView() - event.Skip() def OnUndoMenu(self, event): self.Controler.LoadPrevious() self.PythonEdited.RefreshView() self.RefreshTitle() self.RefreshEditMenu() - event.Skip() def OnRedoMenu(self, event): self.Controler.LoadNext() self.PythonEdited.RefreshView() self.RefreshTitle() self.RefreshEditMenu() - event.Skip() - + + diff -r fcd344deae84 -r 75fe73597273 plugins/python/modules/svgui/pous.xml --- a/plugins/python/modules/svgui/pous.xml Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/python/modules/svgui/pous.xml Mon Nov 02 15:38:49 2009 +0100 @@ -3,7 +3,7 @@ xmlns="http://www.plcopen.org/xml/tc6.xsd" xmlns:xhtml="http://www.w3.org/1999/xhtml" xsi:schemaLocation="http://www.plcopen.org/xml/tc6.xsd"> - diff -r fcd344deae84 -r 75fe73597273 plugins/python/modules/svgui/svgui.py --- a/plugins/python/modules/svgui/svgui.py Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/python/modules/svgui/svgui.py Mon Nov 02 15:38:49 2009 +0100 @@ -98,6 +98,15 @@ def _StartInkscape(self): svgfile = self._getSVGpath() - if not os.path.isfile(svgfile): - svgfile = None - open_svg(svgfile) + open_inkscape = True + if not self.GetPlugRoot().CheckProjectPathPerm(): + dialog = wx.MessageDialog(self.GetPlugRoot().AppFrame, + _("You don't have write permissions.\nOpen Inkscape anyway ?"), + _("Open Inkscape"), + wx.YES_NO|wx.ICON_QUESTION) + open_inkscape = dialog.ShowModal() == wx.ID_YES + dialog.Destroy() + if open_inkscape: + if not os.path.isfile(svgfile): + svgfile = None + open_svg(svgfile) diff -r fcd344deae84 -r 75fe73597273 plugins/python/modules/wxglade_hmi/wxglade_hmi.py --- a/plugins/python/modules/wxglade_hmi/wxglade_hmi.py Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/python/modules/wxglade_hmi/wxglade_hmi.py Mon Nov 02 15:38:49 2009 +0100 @@ -100,16 +100,25 @@ def _editWXGLADE(self): wxg_filename = self._getWXGLADEpath() - if not os.path.exists(wxg_filename): - hmi_name = self.BaseParams.getName() - open(wxg_filename,"w").write(""" - - - - frame_1 - - -""" % {"name": hmi_name, "class": "Class_%s" % hmi_name}) - if wx.Platform == '__WXMSW__': - wxg_filename = "\"%s\""%wxg_filename - self.launch_wxglade([wxg_filename]) + open_wxglade = True + if not self.GetPlugRoot().CheckProjectPathPerm(): + dialog = wx.MessageDialog(self.GetPlugRoot().AppFrame, + _("You don't have write permissions.\nOpen wxGlade anyway ?"), + _("Open wxGlade"), + wx.YES_NO|wx.ICON_QUESTION) + open_wxglade = dialog.ShowModal() == wx.ID_YES + dialog.Destroy() + if open_wxglade: + if not os.path.exists(wxg_filename): + hmi_name = self.BaseParams.getName() + open(wxg_filename,"w").write(""" + + + + frame_1 + + + """ % {"name": hmi_name, "class": "Class_%s" % hmi_name}) + if wx.Platform == '__WXMSW__': + wxg_filename = "\"%s\""%wxg_filename + self.launch_wxglade([wxg_filename]) diff -r fcd344deae84 -r 75fe73597273 plugins/python/pous.xml --- a/plugins/python/pous.xml Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/python/pous.xml Mon Nov 02 15:38:49 2009 +0100 @@ -3,7 +3,7 @@ xmlns="http://www.plcopen.org/xml/tc6.xsd" xmlns:xhtml="http://www.w3.org/1999/xhtml" xsi:schemaLocation="http://www.plcopen.org/xml/tc6.xsd"> - diff -r fcd344deae84 -r 75fe73597273 plugins/python/python.py --- a/plugins/python/python.py Tue Oct 27 16:32:54 2009 +0100 +++ b/plugins/python/python.py Mon Nov 02 15:38:49 2009 +0100 @@ -141,14 +141,28 @@ _View = None def _OpenView(self): if not self._View: - def _onclose(): - self._View = None - def _onsave(): - self.GetPlugRoot().SaveProject() - self._View = PythonEditorFrame(self.GetPlugRoot().AppFrame, self) - self._View._onclose = _onclose - self._View._onsave = _onsave - self._View.Show() + open_pyeditor = True + has_permissions = self.GetPlugRoot().CheckProjectPathPerm() + if not has_permissions: + dialog = wx.MessageDialog(self.GetPlugRoot().AppFrame, + _("You don't have write permissions.\nOpen PythonEditor anyway ?"), + _("Open PythonEditor"), + wx.YES_NO|wx.ICON_QUESTION) + open_pyeditor = dialog.ShowModal() == wx.ID_YES + dialog.Destroy() + if open_pyeditor: + def _onclose(): + self._View = None + if has_permissions: + def _onsave(): + self.GetPlugRoot().SaveProject() + else: + def _onsave(): + pass + self._View = PythonEditorFrame(self.GetPlugRoot().AppFrame, self) + self._View._onclose = _onclose + self._View._onsave = _onsave + self._View.Show() def OnPlugSave(self): filepath = self.PythonFileName() @@ -160,7 +174,7 @@ text += self.PythonCode.generateXMLText("Python", 0, extras) xmlfile = open(filepath,"w") - xmlfile.write(text) + xmlfile.write(text.encode("utf-8")) xmlfile.close() self.PythonBuffer.CurrentSaved() diff -r fcd344deae84 -r 75fe73597273 setup.py --- a/setup.py Tue Oct 27 16:32:54 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -import os,sys,glob -from distutils.core import setup - - -install_dir=os.path.join("LOLITech","beremiz") - -data_files=[] -os.getcwd() -os.chdir(os.getcwd()) - -def generate(base_dir): - listfile=[] - if base_dir == "": - directory = "." - else: - directory = base_dir - data_files.append((os.path.join(install_dir, base_dir), listfile)) - - for element in os.listdir(directory): - element_path=os.path.join(base_dir, element) - if os.path.isdir(element_path): - generate(element_path) - elif os.path.isfile(element_path): - listfile.append(element_path) - -generate("") - - -setup(name='Beremiz', - version='0.1', - description='Open Source framework for automation', - author='Edouard Tisserant, Laurent Bessard', - author_email='edouard.tisserant@lolitech.fr,laurent.bessard@lolitech.fr,gregory.trelat@lolitech.fr', - url='http://www.beremiz.org', - license='GPL', - windows=["Beremiz.py"], - scripts=['beremiz_postinst.py'], - data_files=data_files, # Add files to install -) \ No newline at end of file diff -r fcd344deae84 -r 75fe73597273 targets/Makefile/XSD --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/Makefile/XSD Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,6 @@ + + + + %(toolchain_makefile)s + + \ No newline at end of file diff -r fcd344deae84 -r 75fe73597273 targets/Makefile/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/Makefile/__init__.py Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,7 @@ +from .. import toolchain_makefile + +class Makefile_target(toolchain_makefile): + extension = ".ld" + DebugEnabled = False + def getBuilderLDFLAGS(self): + return toolchain_makefile.getBuilderLDFLAGS(self) diff -r fcd344deae84 -r 75fe73597273 targets/Makefile/plc_Makefile_main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/Makefile/plc_Makefile_main.c Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,93 @@ +/** + * Yagarto specific code + **/ + +//#include + +/* provided by POUS.C */ +extern int common_ticktime__; + +void Target_GetTime(IEC_TIME*); + +long AtomicCompareExchange(long* atomicvar,long compared, long exchange) +{ + return 0; +} + +void PLC_GetTime(IEC_TIME *CURRENT_TIME) +{ + /* Call target GetTime function */ + Target_GetTime(CURRENT_TIME); +} + +void PLC_SetTimer(long long next, long long period) +{ +} + +int startPLC(int argc,char **argv) +{ + if(__init(argc,argv) == 0) + return 0; + else + return 1; +} + +int TryEnterDebugSection(void) +{ + return 0; +} + +void LeaveDebugSection(void) +{ +} + +int stopPLC(void) +{ + __cleanup(); + return 0; +} + +extern unsigned long __tick; +/* from plc_debugger.c */ +int WaitDebugData(void) +{ + return 0; +} + +/* Called by PLC thread when debug_publish finished + * This is supposed to unlock debugger thread in WaitDebugData*/ +void InitiateDebugTransfer(void) +{ +} + +void suspendDebug(void) +{ +} + +void resumeDebug(void) +{ +} + +/* from plc_python.c */ +int WaitPythonCommands(void) +{ + return 0; +} + +/* Called by PLC thread on each new python command*/ +void UnBlockPythonCommands(void) +{ +} + +int TryLockPython(void) +{ + return 0; +} + +void UnLockPython(void) +{ +} + +void LockPython(void) +{ +} diff -r fcd344deae84 -r 75fe73597273 targets/XSD_toolchain_makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/XSD_toolchain_makefile Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,6 @@ + + + + + + diff -r fcd344deae84 -r 75fe73597273 targets/__init__.py --- a/targets/__init__.py Tue Oct 27 16:32:54 2009 +0100 +++ b/targets/__init__.py Mon Nov 02 15:38:49 2009 +0100 @@ -74,4 +74,5 @@ filename = path.join(path.split(__file__)[0],name + ".c") return open(filename).read() -from toolchain_gcc import toolchain_gcc \ No newline at end of file +from toolchain_gcc import toolchain_gcc +from toolchain_makefile import toolchain_makefile \ No newline at end of file diff -r fcd344deae84 -r 75fe73597273 targets/plc_common_main.c --- a/targets/plc_common_main.c Tue Oct 27 16:32:54 2009 +0100 +++ b/targets/plc_common_main.c Mon Nov 02 15:38:49 2009 +0100 @@ -41,7 +41,7 @@ /* * Retrieve input variables, run PLC and publish output variables **/ -void __run() +void __run(void) { __tick++; if (greatest_tick_count__) @@ -66,6 +66,7 @@ int __init(int argc,char **argv) { int res = 0; + init_level = 0; setlocale(LC_NUMERIC, "C"); config_init__(); __init_debug(); @@ -75,7 +76,7 @@ /* * Calls plugin cleanup proc. **/ -void __cleanup() +void __cleanup(void) { %(cleanup_calls)s __cleanup_debug(); diff -r fcd344deae84 -r 75fe73597273 targets/plc_debug.c --- a/targets/plc_debug.c Tue Oct 27 16:32:54 2009 +0100 +++ b/targets/plc_debug.c Mon Nov 02 15:38:49 2009 +0100 @@ -51,17 +51,17 @@ struct_plcvar variable_table[%(variables_pointer_type_table_count)d]; -void __init_debug() +void __init_debug(void) { %(variables_pointer_type_table_initializer)s buffer_state = BUFFER_FREE; } -void __cleanup_debug() +void __cleanup_debug(void) { } -void __retrieve_debug() +void __retrieve_debug(void) { } @@ -71,7 +71,7 @@ extern void InitiateDebugTransfer(void); extern unsigned long __tick; -void __publish_debug() +void __publish_debug(void) { /* Check there is no running debugger re-configuration */ if(TryEnterDebugSection()){ @@ -143,10 +143,11 @@ latest_subscription = subscription_table; } -void FreeDebugData() +void FreeDebugData(void) { /* atomically mark buffer as free */ - long latest_state = AtomicCompareExchange( + long latest_state; + latest_state = AtomicCompareExchange( &buffer_state, BUFFER_BUSY, BUFFER_FREE); @@ -169,8 +170,8 @@ { return old_cursor; }else{ - printf("%%d > %%d\n", old_cursor - debug_buffer, BUFFER_SIZE); - return NULL; + //printf("%%d > %%d\n", old_cursor - debug_buffer, BUFFER_SIZE); + return NULL; } } *idx = -1; diff -r fcd344deae84 -r 75fe73597273 targets/toolchain_gcc.py --- a/targets/toolchain_gcc.py Tue Oct 27 16:32:54 2009 +0100 +++ b/targets/toolchain_gcc.py Mon Nov 02 15:38:49 2009 +0100 @@ -12,11 +12,8 @@ """ def __init__(self, PluginsRootInstance): self.PluginsRootInstance = PluginsRootInstance - self.exe = PluginsRootInstance.GetProjectName() + self.extension - self.buildpath = PluginsRootInstance._getBuildPath() - self.exe_path = os.path.join(self.buildpath, self.exe) - self.md5key = None - self.srcmd5 = {} + self.buildpath = None + self.SetBuildPath(self.PluginsRootInstance._getBuildPath()) def getTarget(self): target = self.PluginsRootInstance.BeremizRoot.getTargetType() @@ -54,7 +51,15 @@ return open(self._GetMD5FileName(), "r").read() except Exception, e: return None - + + def SetBuildPath(self, buildpath): + if self.buildpath != buildpath: + self.buildpath = buildpath + self.exe = self.PluginsRootInstance.GetProjectName() + self.extension + self.exe_path = os.path.join(self.buildpath, self.exe) + self.md5key = None + self.srcmd5 = {} + def check_and_update_hash_and_deps(self, bn): # Get latest computed hash and deps oldhash, deps = self.srcmd5.get(bn,(None,[])) diff -r fcd344deae84 -r 75fe73597273 targets/toolchain_makefile.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/toolchain_makefile.py Mon Nov 02 15:38:49 2009 +0100 @@ -0,0 +1,42 @@ +import os, re, operator +from wxPopen import ProcessLogger +import hashlib, shutil +from toolchain_gcc import toolchain_gcc + +includes_re = re.compile('\s*#include\s*["<]([^">]*)[">].*') + +class toolchain_makefile(toolchain_gcc): + """ + This abstract class contains GCC specific code. + It cannot be used as this and should be inherited in a target specific + class such as target_linux or target_win32 + """ + + def build(self): + srcfiles= [] + cflags = [] + for Location, CFilesAndCFLAGS, DoCalls in self.PluginsRootInstance.LocationCFilesAndCFLAGS: + # Get CFiles list to give it to makefile + for CFile, CFLAGS in CFilesAndCFLAGS: + CFileName = os.path.basename(CFile) + srcfiles.append(CFileName) + if CFLAGS not in cflags: + cflags.append(CFLAGS) + + beremizcommand = {"src": ' '.join(srcfiles), + "cflags": ' '.join(cflags) + } + + target = self.getTarget().getcontent()["value"] + command = target.getCommand().split(' ') +\ + [target.getBuildPath()] +\ + [arg % beremizcommand for arg in target.getArguments().split(' ')] +\ + target.getRule().split(' ') + + # Call Makefile to build PLC code and link it with target specific code + status, result, err_result = ProcessLogger(self.PluginsRootInstance.logger, + command).spin() + if status : + self.PluginsRootInstance.logger.write_error(_("C compilation of %s failed.\n")) + return False + return True diff -r fcd344deae84 -r 75fe73597273 wxPopen.py --- a/wxPopen.py Tue Oct 27 16:32:54 2009 +0100 +++ b/wxPopen.py Mon Nov 02 15:38:49 2009 +0100 @@ -69,16 +69,20 @@ class ProcessLogger: def __init__(self, logger, Command, finish_callback=None, no_stdout=False, no_stderr=False, no_gui=True): self.logger = logger - self.Command_str = Command - self.Command = [] - for i,word in enumerate(Command.replace("'",'"').split('"')): - if i % 2 == 0: - word = word.strip() - if len(word) > 0: - self.Command.extend(word.split()) - else: - self.Command.append(word) - + if not isinstance(Command, list): + self.Command_str = Command + self.Command = [] + for i,word in enumerate(Command.replace("'",'"').split('"')): + if i % 2 == 0: + word = word.strip() + if len(word) > 0: + self.Command.extend(word.split()) + else: + self.Command.append(word) + else: + self.Command = Command + self.Command_str = subprocess.list2cmdline(self.Command) + self.finish_callback = finish_callback self.no_stdout = no_stdout self.no_stderr = no_stderr @@ -95,6 +99,7 @@ "stdin":subprocess.PIPE, "stdout":subprocess.PIPE, "stderr":subprocess.PIPE} + if no_gui == True and wx.Platform == '__WXMSW__': self.startupinfo = subprocess.STARTUPINFO() self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW