# HG changeset patch # User PaulBeltyukov # Date 1487237712 -18000 # Node ID 3291024e00da8d5f317118dc88ab5a4f6c0065ae # Parent 6431f26aa50160943420a75a50f7560af6278e60# Parent 13d15a1ae899fbb74d56c2300835cff31edf3ff3 Merge diff -r 6431f26aa501 -r 3291024e00da .hgignore --- a/.hgignore Thu Feb 16 14:34:40 2017 +0500 +++ b/.hgignore Thu Feb 16 14:35:12 2017 +0500 @@ -2,9 +2,14 @@ syntax: regexp ^tests/.*/build$ +^.idea/.* syntax: regexp ^.*\.pyc$ syntax: regexp ^.*~$ syntax: regexp ^.*\.swp$ + +bug_report.*\.txt +i18n/.*.new$ +revision diff -r 6431f26aa501 -r 3291024e00da Beremiz.py --- a/Beremiz.py Thu Feb 16 14:34:40 2017 +0500 +++ b/Beremiz.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,27 +1,26 @@ #!/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. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 - +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. updateinfo_url = None @@ -31,6 +30,7 @@ import shutil import random import time +import version from types import ListType beremiz_dir = os.path.dirname(os.path.realpath(__file__)) @@ -105,13 +105,17 @@ app.SetAppName('beremiz') if wx.VERSION < (3, 0, 0): - wx.InitAllImageHandlers() + wx.InitAllImageHandlers() # popup splash splash = ShowSplashScreen() + + # load internatialization files + from util.misc import InstallLocalRessources + InstallLocalRessources(beremiz_dir) if updateinfo_url is not None: - updateinfo = "Fetching %s" % updateinfo_url + updateinfo = _("Fetching %s") % updateinfo_url # warn for possible updates def updateinfoproc(): global updateinfo @@ -119,7 +123,7 @@ import urllib2 updateinfo = urllib2.urlopen(updateinfo_url,None).read() except : - updateinfo = "update info unavailable." + updateinfo = _("update info unavailable.") from threading import Thread splash.SetText(text=updateinfo) @@ -130,9 +134,6 @@ splash.SetText(text=updateinfo) wx.Yield() - from util.misc import InstallLocalRessources - InstallLocalRessources(beremiz_dir) - # Load extensions for extfilename in extensions: from util.TranslationCatalogs import AddCatalog @@ -158,6 +159,8 @@ from util.ProcessLogger import ProcessLogger from controls.LogViewer import LogViewer from controls.CustomStyledTextCtrl import CustomStyledTextCtrl +from controls import EnhancedStatusBar as esb +from dialogs.AboutDialog import ShowAboutDialog from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY, ITEM_PROJECT, ITEM_RESOURCE from ProjectController import ProjectController, GetAddMenuItems, MATIEC_ERROR_MODEL, ITEM_CONFNODE @@ -247,12 +250,14 @@ # adding text. It seems that text modifications, even # programmatically, are disabled in StyledTextCtrl when read # only is active + start_pos = self.output.GetLength() self.output.SetReadOnly(False) self.output.AppendText(s) self.output.SetReadOnly(True) + text_len = self.output.GetLength() - start_pos if style != self.black_white: - self.output.SetStyling(len(s), style) + self.output.SetStyling(text_len, style) self.stack = [] self.lock.release() self.output.Thaw() @@ -393,6 +398,11 @@ inspectorID = wx.NewId() self.Bind(wx.EVT_MENU, self.OnOpenWidgetInspector, id=inspectorID) accels = [wx.AcceleratorEntry(wx.ACCEL_CTRL|wx.ACCEL_ALT, ord('I'), inspectorID)] + + keyID = wx.NewId() + self.Bind(wx.EVT_MENU, self.SwitchFullScrMode, id=keyID) + accels += [wx.AcceleratorEntry(wx.ACCEL_NORMAL, wx.WXK_F12, keyID)] + for method,shortcut in [("Stop", wx.WXK_F4), ("Run", wx.WXK_F5), ("Transfer", wx.WXK_F6), @@ -456,13 +466,27 @@ self.AUIManager.Update() - self.ConnectionStatusBar = wx.StatusBar(self, style=wx.ST_SIZEGRIP) + self.ConnectionStatusBar = esb.EnhancedStatusBar(self, style=wx.ST_SIZEGRIP) self._init_coll_ConnectionStatusBar_Fields(self.ConnectionStatusBar) + self.ProgressStatusBar = wx.Gauge(self.ConnectionStatusBar, -1, range = 100) + self.ConnectionStatusBar.AddWidget(self.ProgressStatusBar, esb.ESB_EXACT_FIT, esb.ESB_EXACT_FIT, 2) + self.ProgressStatusBar.Hide() self.SetStatusBar(self.ConnectionStatusBar) + def __init_execute_path(self): + if os.name == 'nt': + # on windows, desktop shortcut launches Beremiz.py + # with working dir set to mingw/bin. + # then we prefix CWD to PATH in order to ensure that + # commands invoked by build process by default are + # found here. + os.environ["PATH"] = os.getcwd()+';'+os.environ["PATH"] + + def __init__(self, parent, projectOpen=None, buildpath=None, ctr=None, debug=True): # Add beremiz's icon in top left corner of the frame self.icon = wx.Icon(Bpath("images", "brz.ico"), wx.BITMAP_TYPE_ICO) + self.__init_execute_path() IDEFrame.__init__(self, parent, debug) self.Log = LogPseudoFile(self.LogConsole,self.SelectTab) @@ -498,7 +522,7 @@ if projectOpen is not None and os.path.isdir(projectOpen): self.CTR = ProjectController(self, self.Log) self.Controler = self.CTR - result = self.CTR.LoadProject(projectOpen, buildpath) + result, err = self.CTR.LoadProject(projectOpen, buildpath) if not result: self.LibraryPanel.SetController(self.Controler) self.ProjectTree.Enable(True) @@ -550,7 +574,7 @@ {False : "-x 0", True :"-x 1"}[taskbaricon], self.local_runtime_tmpdir), no_gui=False, - timeout=500, keyword = "working", + timeout=500, keyword = self.local_runtime_tmpdir, cwd = self.local_runtime_tmpdir) self.local_runtime.spin() return self.runtime_port @@ -733,6 +757,11 @@ self.GetConfigEntry("RecentProjects", [])) except: recent_projects = [] + + while self.RecentProjectsMenu.GetMenuItemCount() > len(recent_projects): + item = self.RecentProjectsMenu.FindItemByPosition(0) + self.RecentProjectsMenu.RemoveItem(item) + self.FileMenu.Enable(ID_FILEMENURECENTPROJECTS, len(recent_projects) > 0) for idx, projectpath in enumerate(recent_projects): text = u'%d: %s' % (idx + 1, projectpath) @@ -872,7 +901,7 @@ self.DebugVariablePanel.SetDataProducer(None) self.ResetConnectionStatusBar() - def RefreshConfigRecentProjects(self, projectpath): + def RefreshConfigRecentProjects(self, projectpath, err=False): try: recent_projects = map(DecodeFileSystemPath, self.GetConfigEntry("RecentProjects", [])) @@ -880,7 +909,8 @@ recent_projects = [] if projectpath in recent_projects: recent_projects.remove(projectpath) - recent_projects.insert(0, projectpath) + if not err: + recent_projects.insert(0, projectpath) self.Config.Write("RecentProjects", cPickle.dumps( map(EncodeFileSystemPath, recent_projects[:MAX_RECENT_PROJECTS]))) self.Config.Flush() @@ -947,12 +977,11 @@ self.ResetView() self.CTR = ProjectController(self, self.Log) self.Controler = self.CTR - result = self.CTR.LoadProject(projectpath) + result, err = self.CTR.LoadProject(projectpath) if not result: self.LibraryPanel.SetController(self.Controler) self.ProjectTree.Enable(True) self.PouInstanceVariablesPanel.SetController(self.Controler) - self.RefreshConfigRecentProjects(projectpath) if self.EnableDebug: self.DebugVariablePanel.SetDataProducer(self.CTR) self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) @@ -960,8 +989,11 @@ self.ResetView() self.ShowErrorMessage(result) self.RefreshAll() + self.SearchResultPanel.ResetSearchResults() else: self.ShowErrorMessage(_("\"%s\" folder is not a valid Beremiz project\n") % projectpath) + err = True + self.RefreshConfigRecentProjects(projectpath, err) self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU) def OnCloseProjectMenu(self, event): @@ -990,13 +1022,15 @@ if self.CTR is not None: self.CTR.SaveProjectAs() self.RefreshAll() + self.RefreshConfigRecentProjects(self.CTR.ProjectPath) self._Refresh(TITLE, FILEMENU, EDITMENU, PAGETITLES) def OnQuitMenu(self, event): self.Close() def OnAboutMenu(self, event): - OpenHtmlFrame(self,_("About Beremiz"), Bpath("doc", _("about.html")), wx.Size(550, 550)) + info = version.GetAboutDialogInfo() + ShowAboutDialog(self, info) def OnProjectTreeItemBeginEdit(self, event): selected = event.GetItem() @@ -1161,7 +1195,7 @@ Please be kind enough to send this file to: beremiz-devel@lists.sourceforge.net -You should now restart Beremiz. +You should now restart program. Traceback: """) % bug_report_path + @@ -1189,45 +1223,48 @@ def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]): + def save_bug_report(e_type, e_value, e_traceback, bug_report_path,date): + info = { + 'app-title': wx.GetApp().GetAppName(), # app_title + 'app-version': app_version, + 'wx-version': wx.VERSION_STRING, + 'wx-platform': wx.Platform, + 'python-version': platform.python_version(), # sys.version.split()[0], + 'platform': platform.platform(), + 'e-type': e_type, + 'e-value': e_value, + 'date': date, + 'cwd': os.getcwd(), + } + if e_traceback: + info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value) + last_tb = get_last_traceback(e_traceback) + exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred + info['locals'] = format_namespace(exception_locals) + if 'self' in exception_locals: + try: + info['self'] = format_namespace(exception_locals['self'].__dict__) + except: + pass + if not os.path.exists(path): + os.mkdir(path) + output = open(bug_report_path, 'w') + lst = info.keys() + lst.sort() + for a in lst: + output.write(a + ":\n" + str(info[a]) + "\n\n") + output.close() + def handle_exception(e_type, e_value, e_traceback): traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func last_tb = get_last_traceback(e_traceback) ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno) if ex not in ignored_exceptions: + ignored_exceptions.append(ex) date = time.ctime() - bug_report_path = path+os.sep+"bug_report_"+date.replace(':','-').replace(' ','_')+".txt" - result = Display_Exception_Dialog(e_type,e_value,e_traceback,bug_report_path) - if result: - ignored_exceptions.append(ex) - info = { - 'app-title' : wx.GetApp().GetAppName(), # app_title - 'app-version' : app_version, - 'wx-version' : wx.VERSION_STRING, - 'wx-platform' : wx.Platform, - 'python-version' : platform.python_version(), #sys.version.split()[0], - 'platform' : platform.platform(), - 'e-type' : e_type, - 'e-value' : e_value, - 'date' : date, - 'cwd' : os.getcwd(), - } - if e_traceback: - info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value) - last_tb = get_last_traceback(e_traceback) - exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred - info['locals'] = format_namespace(exception_locals) - if 'self' in exception_locals: - try : - info['self'] = format_namespace(exception_locals['self'].__dict__) - except : - pass - - output = open(bug_report_path,'w') - lst = info.keys() - lst.sort() - for a in lst: - output.write(a+":\n"+str(info[a])+"\n\n") - + bug_report_path = path + os.sep + "bug_report_" + date.replace(':', '-').replace(' ', '_') + ".txt" + save_bug_report(e_type, e_value, e_traceback, bug_report_path, date) + Display_Exception_Dialog(e_type, e_value, e_traceback, bug_report_path) #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args) sys.excepthook = handle_exception @@ -1247,7 +1284,8 @@ if __name__ == '__main__': # Install a exception handle for bug reports - AddExceptHook(os.getcwd(),updateinfo_url) + logpath = tempfile.gettempdir()+os.sep+'Beremiz' + AddExceptHook(logpath ,version.app_version) frame = Beremiz(None, projectOpen, buildpath) if splash: diff -r 6431f26aa501 -r 3291024e00da Beremiz_service.py --- a/Beremiz_service.py Thu Feb 16 14:34:40 2017 +0500 +++ b/Beremiz_service.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/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. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import os, sys, getopt from threading import Thread @@ -112,10 +112,52 @@ if __name__ == '__main__': __builtin__.__dict__['_'] = lambda x: x +def Bpath(*args): + return os.path.join(beremiz_dir,*args) + +def SetupI18n(): + # Import module for internationalization + import gettext + + # Get folder containing translation files + localedir = os.path.join(beremiz_dir,"locale") + # Get the default language + langid = wx.LANGUAGE_DEFAULT + # Define translation domain (name of translation files) + domain = "Beremiz" + + # Define locale for wx + loc = __builtin__.__dict__.get('loc', None) + if loc is None: + loc = wx.Locale(langid) + __builtin__.__dict__['loc'] = loc + # Define location for searching translation files + loc.AddCatalogLookupPathPrefix(localedir) + # Define locale domain + loc.AddCatalog(domain) + + + import locale + global default_locale + default_locale = locale.getdefaultlocale()[1] + + + # sys.stdout.encoding = default_locale + # if Beremiz_service is started from Beremiz IDE + # sys.stdout.encoding is None (that means 'ascii' encoding'). + # And unicode string returned by wx.GetTranslation() are + # automatically converted to 'ascii' string. + def unicode_translation(message): + return wx.GetTranslation(message).encode(default_locale) + + if __name__ == '__main__': + __builtin__.__dict__['_'] = unicode_translation + # __builtin__.__dict__['_'] = wx.GetTranslation + if enablewx: try: import wxversion - wxversion.select('2.8') + wxversion.select(['2.8', '3.0']) import wx havewx = True except: @@ -126,36 +168,15 @@ import re from threading import Thread, currentThread from types import * - app=wx.App(redirect=False) - - # Import module for internationalization - import gettext - - def Bpath(*args): - return os.path.join(beremiz_dir,*args) - - # Get folder containing translation files - localedir = os.path.join(beremiz_dir,"locale") - # Get the default language - langid = wx.LANGUAGE_DEFAULT - # Define translation domain (name of translation files) - domain = "Beremiz" - - # Define locale for wx - loc = __builtin__.__dict__.get('loc', None) - if loc is None: - loc = wx.Locale(langid) - __builtin__.__dict__['loc'] = loc - # Define location for searching translation files - loc.AddCatalogLookupPathPrefix(localedir) - # Define locale domain - loc.AddCatalog(domain) - - def unicode_translation(message): - return wx.GetTranslation(message).encode("utf-8") - - if __name__ == '__main__': - __builtin__.__dict__['_'] = wx.GetTranslation#unicode_translation + + if wx.VERSION >= (3, 0, 0): + app = wx.App(redirect=False) + else: + app = wx.PySimpleApp(redirect=False) + app.SetTopWindow(wx.Frame(None, -1)) + + default_locale = None + SetupI18n() defaulticon = wx.Image(Bpath("images", "brz.png")) starticon = wx.Image(Bpath("images", "icoplay24.png")) @@ -170,7 +191,7 @@ event(self, function) - def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", + def __init__(self, parent, message, caption = _("Please enter text"), defaultValue = "", style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) @@ -267,14 +288,23 @@ def OnTaskBarStartPLC(self, evt): if self.pyroserver.plcobj is not None: - self.pyroserver.plcobj.StartPLC() + plcstatus = self.pyroserver.plcobj.GetPLCstatus()[0] + if plcstatus is "Stopped": + self.pyroserver.plcobj.StartPLC() + else: + print _("PLC is empty or already started.") def OnTaskBarStopPLC(self, evt): if self.pyroserver.plcobj is not None: - Thread(target=self.pyroserver.plcobj.StopPLC).start() + if self.pyroserver.plcobj.GetPLCstatus()[0] == "Started": + Thread(target=self.pyroserver.plcobj.StopPLC).start() + else: + print _("PLC is not started.") def OnTaskBarChangeInterface(self, evt): - dlg = ParamsEntryDialog(None, _("Enter the IP of the interface to bind"), defaultValue=self.pyroserver.ip_addr) + ip_addr = self.pyroserver.ip_addr + ip_addr = '' if ip_addr is None else ip_addr + dlg = ParamsEntryDialog(None, _("Enter the IP of the interface to bind"), defaultValue=ip_addr) dlg.SetTests([(re.compile('\d{1,3}(?:\.\d{1,3}){3}$').match, _("IP is not valid!")), ( lambda x :len([x for x in x.split(".") if 0 <= int(x) <= 255]) == 4, _("IP is not valid!")) ]) @@ -296,10 +326,12 @@ self.pyroserver.Stop() def OnTaskBarChangeName(self, evt): - dlg = ParamsEntryDialog(None, _("Enter a name "), defaultValue=self.pyroserver.name) + servicename = self.pyroserver.servicename + servicename = '' if servicename is None else servicename + dlg = ParamsEntryDialog(None, _("Enter a name "), defaultValue=servicename) dlg.SetTests([(lambda name : len(name) is not 0 , _("Name must not be null!"))]) if dlg.ShowModal() == wx.ID_OK: - self.pyroserver.name = dlg.GetValue() + self.pyroserver.servicename = dlg.GetValue() self.pyroserver.Restart() def _LiveShellLocals(self): @@ -379,6 +411,7 @@ def Quit(self): self.continueloop = False if self.plcobj is not None: + self.plcobj.StopPLC() self.plcobj.UnLoadPLC() self.Stop() @@ -390,9 +423,13 @@ self.pyruntimevars) uri = self.daemon.connect(self.plcobj,"PLCObject") - print "Pyro port :",self.port - print "Pyro object's uri :",uri - print "Current working directory :",self.workdir + print _("Pyro port :"), self.port + print _("Pyro object's uri :"), uri + + # Beremiz IDE detects daemon start by looking + # for self.workdir in the daemon's stdout. + # Therefore don't delete the following line + print _("Current working directory :"), self.workdir # Configure and publish service # Not publish service if localhost in address params @@ -400,18 +437,20 @@ self.ip_addr is not None and self.ip_addr != "localhost" and self.ip_addr != "127.0.0.1"): - print "Publishing service on local network" + print _("Publishing service on local network") self.servicepublisher = ServicePublisher.ServicePublisher() self.servicepublisher.RegisterService(self.servicename, self.ip_addr, self.port) - if self.autostart : - self.plcobj.AutoLoad() - if self.plcobj.GetPLCstatus()[0] != "Empty": + self.plcobj.AutoLoad() + if self.plcobj.GetPLCstatus()[0] != "Empty": + if self.autostart : self.plcobj.StartPLC() + self.plcobj.StatusChange() sys.stdout.flush() self.daemon.requestLoop() + self.daemon.sock.close() def Stop(self): if self.plcobj is not None: @@ -434,7 +473,7 @@ havetwisted = True except: - print "Twisted unavailable." + print _("Twisted unavailable.") havetwisted = False pyruntimevars = {} @@ -512,7 +551,7 @@ try: import runtime.NevowServer as NS except Exception, e: - print "Nevow/Athena import failed :", e + print _("Nevow/Athena import failed :"), e webport = None NS.WorkingDir = WorkingDir @@ -520,7 +559,7 @@ try: import runtime.WampClient as WC except Exception, e: - print "WAMP import failed :", e + print _("WAMP import failed :"), e wampconf = None # Load extensions @@ -536,7 +575,7 @@ pyruntimevars["website"] = website statuschange.append(NS.website_statuslistener_factory(website)) except Exception, e: - print "Nevow Web service failed.", e + print _("Nevow Web service failed. "), e if wampconf is not None : try: @@ -544,7 +583,7 @@ pyruntimevars["wampsession"] = WC.GetSession WC.SetServer(pyroserver) except Exception, e: - print "WAMP client startup failed.", e + print _("WAMP client startup failed. "), e if havetwisted or havewx: diff -r 6431f26aa501 -r 3291024e00da CodeFileTreeNode.py --- a/CodeFileTreeNode.py Thu Feb 16 14:34:40 2017 +0500 +++ b/CodeFileTreeNode.py Thu Feb 16 14:35:12 2017 +0500 @@ -117,11 +117,12 @@ try: self.CodeFile, error = self.CodeFileParser.LoadXMLString(codefile_xml) if error is not None: - self.GetCTRoot().logger.write_warning( - XSDSchemaErrorMessage % ((self.CODEFILE_NAME,) + error)) + (fname, lnum, src) = ((self.CODEFILE_NAME,) + error) + self.GetCTRoot().logger.write_warning(XSDSchemaErrorMessage.format(a1 = fname, a2 = lnum, a3 = src)) self.CreateCodeFileBuffer(True) except Exception, exc: - self.GetCTRoot().logger.write_error(_("Couldn't load confnode parameters %s :\n %s") % (CTNName, unicode(exc))) + msg = _("Couldn't load confnode parameters {a1} :\n {a2}").format(a1 = CTNName, a2 = unicode(exc)) + self.GetCTRoot().logger.write_error(msg) self.GetCTRoot().logger.write_error(traceback.format_exc()) else: self.CodeFile = self.CodeFileParser.CreateRoot() diff -r 6431f26aa501 -r 3291024e00da ConfigTreeNode.py --- a/ConfigTreeNode.py Thu Feb 16 14:34:40 2017 +0500 +++ b/ConfigTreeNode.py Thu Feb 16 14:35:12 2017 +0500 @@ -53,7 +53,7 @@ """) NameTypeSeparator = '@' -XSDSchemaErrorMessage = _("%s XML file doesn't follow XSD schema at line %d:\n%s") +XSDSchemaErrorMessage = _("{a1} XML file doesn't follow XSD schema at line %{a2}:\n{a3}") class ConfigTreeNode: """ @@ -421,7 +421,8 @@ shutil.move(oldname, self.CTNPath()) # warn user he has two left hands if DesiredName != res: - self.GetCTRoot().logger.write_warning(_("A child named \"%s\" already exist -> \"%s\"\n")%(DesiredName,res)) + msg = _("A child named \"{a1}\" already exists -> \"{a2}\"\n").format(a1 = DesiredName, a2 = res) + self.GetCTRoot().logger.write_warning(msg) return res def GetAllChannels(self): @@ -525,7 +526,7 @@ try: CTNClass, CTNHelp = CTNChildrenTypes[CTNType] except KeyError: - raise Exception, _("Cannot create child %s of type %s ")%(CTNName, CTNType) + raise Exception, _("Cannot create child {a1} of type {a2} ").format(a1 = CTNName, a2 = CTNType) # if CTNClass is a class factory, call it. (prevent unneeded imports) if type(CTNClass) == types.FunctionType: @@ -535,7 +536,8 @@ ChildrenWithSameClass = self.Children.setdefault(CTNType, list()) # Check count if getattr(CTNClass, "CTNMaxCount", None) and len(ChildrenWithSameClass) >= CTNClass.CTNMaxCount: - raise Exception, _("Max count (%d) reached for this confnode of type %s ")%(CTNClass.CTNMaxCount, CTNType) + msg = _("Max count ({a1}) reached for this confnode of type {a2} ").format(a1 = CTNClass.CTNMaxCount, a2 = CTNType) + raise Exception, msg # create the final class, derived of provided confnode and template class FinalCTNClass(CTNClass, ConfigTreeNode): @@ -561,7 +563,9 @@ _self.LoadXMLParams(NewCTNName) # Basic check. Better to fail immediately. if (_self.BaseParams.getName() != NewCTNName): - raise Exception, _("Project tree layout do not match confnode.xml %s!=%s ")%(NewCTNName, _self.BaseParams.getName()) + msg = _("Project tree layout do not match confnode.xml {a1}!={a2} ").\ + format(a1 = NewCTNName, a2 = _self.BaseParams.getName()) + raise Exception, msg # Now, self.CTNPath() should be OK @@ -614,12 +618,13 @@ basexmlfile = open(self.ConfNodeBaseXmlFilePath(CTNName), 'r') self.BaseParams, error = _BaseParamsParser.LoadXMLString(basexmlfile.read()) if error is not None: - self.GetCTRoot().logger.write_warning( - XSDSchemaErrorMessage % ((ConfNodeName + " BaseParams",) + error)) + (fname, lnum, src) = ((ConfNodeName + " BaseParams",) + error) + self.GetCTRoot().logger.write_warning(XSDSchemaErrorMessage.format(a1 = fname, a2 = lnum, a3 = src)) self.MandatoryParams = ("BaseParams", self.BaseParams) basexmlfile.close() except Exception, exc: - self.GetCTRoot().logger.write_error(_("Couldn't load confnode base parameters %s :\n %s") % (ConfNodeName, unicode(exc))) + msg = _("Couldn't load confnode base parameters {a1} :\n {a2}").format(a1 = ConfNodeName, a2 = unicode(exc)) + self.GetCTRoot().logger.write_error(msg) self.GetCTRoot().logger.write_error(traceback.format_exc()) # Get the xml tree @@ -628,14 +633,15 @@ xmlfile = open(self.ConfNodeXmlFilePath(CTNName), 'r') obj, error = self.Parser.LoadXMLString(xmlfile.read()) if error is not None: - self.GetCTRoot().logger.write_warning( - XSDSchemaErrorMessage % ((ConfNodeName,) + error)) + (fname, lnum, src) = ((ConfNodeName,) + error) + self.GetCTRoot().logger.write_warning(XSDSchemaErrorMessage.format(a1 = fname, a2 = lnum, a3 = src)) name = obj.getLocalTag() setattr(self, name, obj) self.CTNParams = (name, obj) xmlfile.close() except Exception, exc: - self.GetCTRoot().logger.write_error(_("Couldn't load confnode parameters %s :\n %s") % (ConfNodeName, unicode(exc))) + msg = _("Couldn't load confnode parameters {a1} :\n {a2}").format(a1 = ConfNodeName, a2 = unicode(exc)) + self.GetCTRoot().logger.write_error(msg) self.GetCTRoot().logger.write_error(traceback.format_exc()) def LoadChildren(self): @@ -647,6 +653,7 @@ try: self.CTNAddChild(pname, ptype) except Exception, exc: - self.GetCTRoot().logger.write_error(_("Could not add child \"%s\", type %s :\n%s\n")%(pname, ptype, unicode(exc))) + msg = _("Could not add child \"{a1}\", type {a2} :\n{a3}\n").format(a1 = pname, a2 = ptype, a3 = unicode(exc)) + self.GetCTRoot().logger.write_error(msg) self.GetCTRoot().logger.write_error(traceback.format_exc()) diff -r 6431f26aa501 -r 3291024e00da IDEFrame.py --- a/IDEFrame.py Thu Feb 16 14:34:40 2017 +0500 +++ b/IDEFrame.py Thu Feb 16 14:35:12 2017 +0500 @@ -64,7 +64,8 @@ # Define PLCOpenEditor DisplayMenu extra items id [ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE, -] = [wx.NewId() for _init_coll_DisplayMenu_Items in range(1)] + ID_PLCOPENEDITORDISPLAYMENUSWITCHPERSPECTIVE, +] = [wx.NewId() for _init_coll_DisplayMenu_Items in range(2)] #------------------------------------------------------------------------------- # EditorToolBar definitions @@ -442,6 +443,10 @@ self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id) parent.AppendSeparator() + AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENUSWITCHPERSPECTIVE, + kind=wx.ITEM_NORMAL, text=_(u'Switch perspective') + '\tF12') + self.Bind(wx.EVT_MENU, self.SwitchFullScrMode, id=ID_PLCOPENEDITORDISPLAYMENUSWITCHPERSPECTIVE) + AppendMenu(parent, help='', id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE, kind=wx.ITEM_NORMAL, text=_(u'Reset Perspective')) self.Bind(wx.EVT_MENU, self.OnResetPerspective, id=ID_PLCOPENEDITORDISPLAYMENURESETPERSPECTIVE) @@ -1255,6 +1260,7 @@ def OnFindMenu(self, event): if not self.FindDialog.IsShown(): self.FindDialog.Show() + self.FindDialog.FindPattern.SetFocus() def CloseFindInPouDialog(self): selected = self.TabsOpened.GetSelection() @@ -1279,10 +1285,11 @@ dialog = SearchInProjectDialog(self) if dialog.ShowModal() == wx.ID_OK: criteria = dialog.GetCriteria() - result = self.Controler.SearchInProject(criteria) - self.ClearSearchResults() - self.SearchResultPanel.SetSearchResults(criteria, result) - self.SelectTab(self.SearchResultPanel) + if len(criteria) > 0: + result = self.Controler.SearchInProject(criteria) + self.ClearSearchResults() + self.SearchResultPanel.SetSearchResults(criteria, result) + self.SelectTab(self.SearchResultPanel) #------------------------------------------------------------------------------- # Display Menu Functions @@ -1438,15 +1445,18 @@ def OnTabsOpenedDClick(event): pos = event.GetPosition() if tabctrl.TabHitTest(pos.x, pos.y, None): - pane = self.AUIManager.GetPane(self.TabsOpened) - if pane.IsMaximized(): - self.AUIManager.RestorePane(pane) - else: - self.AUIManager.MaximizePane(pane) - self.AUIManager.Update() + self.SwitchFullScrMode(event) event.Skip() return OnTabsOpenedDClick + def SwitchFullScrMode(self,evt): + pane = self.AUIManager.GetPane(self.TabsOpened) + if pane.IsMaximized(): + self.AUIManager.RestorePane(pane) + else: + self.AUIManager.MaximizePane(pane) + self.AUIManager.Update() + #------------------------------------------------------------------------------- # Types Tree Management Functions #------------------------------------------------------------------------------- @@ -1481,8 +1491,7 @@ item_name = _(item_name) self.ProjectTree.SetItemText(root, item_name) self.ProjectTree.SetPyData(root, infos) - highlight_colours = self.Highlights.get(infos.get("tagname", None), (wx.WHITE, wx.BLACK)) - self.ProjectTree.SetItemBackgroundColour(root, highlight_colours[0]) + highlight_colours = self.Highlights.get(infos.get("tagname", None), (wx.Colour(255, 255, 255, 0), wx.BLACK)) self.ProjectTree.SetItemTextColour(root, highlight_colours[1]) self.ProjectTree.SetItemExtraImage(root, None) if infos["type"] == ITEM_POU: @@ -1612,6 +1621,8 @@ self.RefreshLibraryPanel() self.RefreshPageTitles() elif item_infos["type"] == ITEM_TRANSITION: + pou_item = self.ProjectTree.GetItemParent(event.GetItem()) + pou_name = self.ProjectTree.GetItemText(pou_item) if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: message = _("A POU named \"%s\" already exists!")%new_name elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames(pou_name) if name != old_name]: @@ -1623,6 +1634,8 @@ self.Controler.ComputePouTransitionName(words[1], new_name)) self.RefreshPageTitles() elif item_infos["type"] == ITEM_ACTION: + pou_item = self.ProjectTree.GetItemParent(event.GetItem()) + pou_name = self.ProjectTree.GetItemText(pou_item) if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]: message = _("A POU named \"%s\" already exists!")%new_name elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames(pou_name) if name != old_name]: diff -r 6431f26aa501 -r 3291024e00da PLCControler.py --- a/PLCControler.py Thu Feb 16 14:34:40 2017 +0500 +++ b/PLCControler.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from xml.dom import minidom from types import StringType, UnicodeType, TupleType @@ -967,7 +967,8 @@ # programs cannot be pasted as functions or function blocks if orig_type == 'functionBlock' and pou_type == 'function' or \ orig_type == 'program' and pou_type in ['function', 'functionBlock']: - return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type) + msg = _('''{a1} "{a2}" can't be pasted as a {a3}.''').format(a1 = orig_type, a2 = name, a3 = pou_type) + return msg new_pou.setpouType(pou_type) @@ -2183,7 +2184,7 @@ if pou is not None: return self.GetPouInterfaceReturnType(pou, tree, debug) elif words[0] == 'T': - return "BOOL" + return ["BOOL", ([], [])] return None # Change the edited element text @@ -3192,7 +3193,14 @@ def SearchInPou(self, tagname, criteria, debug=False): pou = self.GetEditedElement(tagname, debug) if pou is not None: - return pou.Search(criteria) + search_results = pou.Search(criteria, [tagname]) + if tagname.split("::")[0] in ['A', 'T']: + parent_pou_tagname = "P::%s" % (tagname.split("::")[-2]) + parent_pou = self.GetEditedElement(parent_pou_tagname, debug) + for infos, start, end, text in parent_pou.Search(criteria): + if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: + search_results.append((infos, start, end, text)) + return search_results return [] #------------------------------------------------------------------------------- diff -r 6431f26aa501 -r 3291024e00da PLCGenerator.py --- a/PLCGenerator.py Thu Feb 16 14:34:40 2017 +0500 +++ b/PLCGenerator.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from plcopen import PLCOpenParser from plcopen.structures import * @@ -393,6 +393,11 @@ single = task.getsingle() # Single argument if exists if single is not None: + if len(single) == 0: + msg = _("Source signal has to be defined for single task '{a1}' in resource '{a2}.{a3}'.").\ + format(a1 = task.getname(), a2 = config_name, a3 = resource.getname()) + raise PLCGenException, msg + if single[0]=='[' and single[-1]==']' : SNGLKW = "MULTI" else: @@ -763,7 +768,10 @@ content = instance.getconditionContent() if content["type"] == "connection": self.ConnectionTypes[content["value"]] = "BOOL" - for link in content["value"].getconnections(): + connections = content["value"].getconnections() + if not connections: + raise PLCGenException, _("SFC transition in POU \"%s\" must be connected.") % self.Name + for link in connections: connected = self.GetLinkedConnector(link, body) if connected is not None and not self.ConnectionTypes.has_key(connected): for related in self.ExtractRelatedConnections(connected): @@ -775,7 +783,8 @@ for element in body.getcontentInstances(): if isinstance(element, ConnectorClass) and element.getname() == name: if connector is not None: - raise PLCGenException, _("More than one connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name) + msg = _("More than one connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU").format(a1 = name, a2 = self.Name) + raise PLCGenException, msg connector = element if connector is not None: undefined = [instance.connectionPointOut, connector.connectionPointIn] @@ -794,7 +803,8 @@ for connection in related: self.ConnectionTypes[connection] = var_type else: - raise PLCGenException, _("No connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name) + msg = _("No connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU").format(a1 = name, a2 = self.Name) + raise PLCGenException, msg elif isinstance(instance, BlockClass): block_infos = self.GetBlockType(instance.gettypeName(), "undefined") if block_infos is not None: @@ -948,7 +958,7 @@ if block_infos is None: block_infos = self.GetBlockType(block_type) if block_infos is None: - raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name) + raise PLCGenException, _("Undefined block type \"{a1}\" in \"{a2}\" POU").format(a1 = block_type, a2 = self.Name) try: self.GenerateBlock(instance, block_infos, body, None) except ValueError, e: @@ -1088,7 +1098,8 @@ self.Program += JoinList([(", ", ())], vars) self.Program += [(");\n", ())] else: - self.Warnings.append(_("\"%s\" function cancelled in \"%s\" POU: No input connected")%(type, self.TagName.split("::")[-1])) + msg = _("\"{a1}\" function cancelled in \"{a2}\" POU: No input connected").format(a1 = type, a2 = self.TagName.split("::")[-1]) + self.Warnings.append(msg) elif block_infos["type"] == "functionBlock": if not self.ComputedBlocks.get(block, False) and not order: self.ComputedBlocks[block] = True @@ -1177,11 +1188,12 @@ if output_parameter is None: output_parameter = "" if name: - blockname = "%s(%s)" % (name, type) + blockname = "{a1}({a2})".format(a1 = name, a2 = type) else: blockname = type - raise ValueError, _("No output %s variable found in block %s in POU %s. Connection must be broken") % \ - (output_parameter, blockname, self.Name) + msg = _("No output {a1} variable found in block {a2} in POU {a3}. Connection must be broken").\ + format(a1 = output_parameter, a2 = blockname, a3 = self.Name) + raise ValueError, msg def GeneratePaths(self, connections, body, order = False, to_inout = False): paths = [] @@ -1199,7 +1211,8 @@ if block_infos is None: block_infos = self.GetBlockType(block_type) if block_infos is None: - raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name) + msg = _("Undefined block type \"{a1}\" in \"{a2}\" POU").format(a1 = block_type, a2 = self.Name) + raise PLCGenException, msg try: paths.append(str(self.GenerateBlock(next, block_infos, body, connection, order, to_inout))) except ValueError, e: @@ -1214,7 +1227,8 @@ for instance in body.getcontentInstances(): if isinstance(instance, ConnectorClass) and instance.getname() == name: if connector is not None: - raise PLCGenException, _("More than one connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name) + msg = _("More than one connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU").format(a1 = name, a2 = self.Name) + raise PLCGenException, msg connector = instance if connector is not None: connections = connector.connectionPointIn.getconnections() @@ -1224,7 +1238,8 @@ self.ComputedConnectors[name] = expression paths.append(str(expression)) else: - raise PLCGenException, _("No connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name) + msg = _("No connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU").format(a1 = name, a2 = self.Name) + raise PLCGenException, msg elif isinstance(next, ContactClass): contact_info = (self.TagName, "contact", next.getlocalId()) variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) @@ -1372,6 +1387,10 @@ def GenerateSFCJump(self, jump, pou): jump_target = jump.gettargetName() + if not pou.hasstep(jump_target): + pname = pou.getname() + msg = _("SFC jump in pou \"{a1}\" refers to non-existent SFC step \"{a2}\"").format( a1 = pname, a2 = jump_target) + raise PLCGenException, msg if jump.connectionPointIn is not None: instances = [] connections = jump.connectionPointIn.getconnections() @@ -1576,7 +1595,9 @@ elif len(transition_infos["from"]) == 1: self.Program += transition_infos["from"][0] else: - raise PLCGenException, _("Transition with content \"%s\" not connected to a previous step in \"%s\" POU")%(transition_infos["content"], self.Name) + msg = _("Transition with content \"{a1}\" not connected to a previous step in \"{a2}\" POU").\ + format(a1 = transition_infos["content"], a2 = self.Name) + raise PLCGenException, msg self.Program += [(" TO ", ())] if len(transition_infos["to"]) > 1: self.Program += [("(", ())] @@ -1585,7 +1606,9 @@ elif len(transition_infos["to"]) == 1: self.Program += transition_infos["to"][0] else: - raise PLCGenException, _("Transition with content \"%s\" not connected to a next step in \"%s\" POU")%(transition_infos["content"], self.Name) + msg = _("Transition with content \"{a1}\" not connected to a next step in \"{a2}\" POU").\ + format(a1 = transition_infos["content"], a2 = self.Name) + raise PLCGenException, msg self.Program += transition_infos["content"] self.Program += [("%sEND_TRANSITION\n\n"%self.CurrentIndent, ())] for [(step_name, step_infos)] in transition_infos["to"]: diff -r 6431f26aa501 -r 3291024e00da PLCOpenEditor.py --- a/PLCOpenEditor.py Thu Feb 16 14:34:40 2017 +0500 +++ b/PLCOpenEditor.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,29 +1,30 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import os, sys, platform, time, traceback, getopt +import version beremiz_dir = os.path.dirname(os.path.realpath(__file__)) @@ -60,7 +61,11 @@ # Create wxApp (Need to create App before internationalization because of # Windows) - app = wx.PySimpleApp() + if wx.VERSION >= (3, 0, 0): + app = wx.App() + else: + app = wx.PySimpleApp() + from util.misc import InstallLocalRessources InstallLocalRessources(beremiz_dir) @@ -72,6 +77,7 @@ from editors.Viewer import Viewer from PLCControler import PLCControler from dialogs import ProjectDialog +from dialogs.AboutDialog import ShowAboutDialog #------------------------------------------------------------------------------- # PLCOpenEditor Main Class @@ -160,6 +166,7 @@ # @param fileOpen The filepath to open if no controler defined (default: None). # @param debug The filepath to open if no controler defined (default: False). def __init__(self, parent, fileOpen = None): + self.icon = wx.Icon(os.path.join(beremiz_dir, "images", "poe.ico"), wx.BITMAP_TYPE_ICO) IDEFrame.__init__(self, parent) result = None @@ -178,15 +185,15 @@ self._Refresh(PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE) # Define PLCOpenEditor icon - self.SetIcon(wx.Icon(os.path.join(beremiz_dir, "images", "poe.ico"),wx.BITMAP_TYPE_ICO)) + self.SetIcon(self.icon) self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) self._Refresh(TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU) if result is not None: - self.ShowErrorMessage( - _("PLC syntax error at line %d:\n%s") % result) + (num, line) = result + self.ShowErrorMessage(_("PLC syntax error at line {a1}:\n{a2}").format(a1 = num, a2 = line)) def OnCloseFrame(self, event): if self.Controler is None or self.CheckSaveBeforeClosing(_("Close Application")): @@ -298,8 +305,8 @@ dialog.Destroy() if result is not None: - self.ShowErrorMessage( - _("PLC syntax error at line %d:\n%s") % result) + (num, line) = result + self.ShowErrorMessage(_("PLC syntax error at line {a1}:\n{a2}").format(a1 = num, a2 = line)) def OnCloseProjectMenu(self, event): if not self.CheckSaveBeforeClosing(): @@ -343,7 +350,12 @@ open_pdf(os.path.join(beremiz_dir, "plcopen", "TC6_XML_V101.pdf")) def OnAboutMenu(self, event): - OpenHtmlFrame(self,_("About PLCOpenEditor"), os.path.join(beremiz_dir, "doc", _("plcopen_about.html")), wx.Size(350, 350)) + info = version.GetAboutDialogInfo() + info.Name = "PLCOpenEditor" + info.Description = _("PLCOpenEditor is part of Beremiz project.\n\n" + "Beremiz is an ") + info.Description + info.Icon = wx.Icon(os.path.join(beremiz_dir, "images", "aboutlogo.png"), wx.BITMAP_TYPE_PNG) + ShowAboutDialog(self, info) def SaveProject(self): result = self.Controler.SaveXMLFile() @@ -394,16 +406,17 @@ dlg = wx.SingleChoiceDialog(None, _(""" -An error has occurred. - -Click OK to save an error report. +An unhandled exception (bug) occured. Bug report saved at : +(%s) Please be kind enough to send this file to: -edouard.tisserant@gmail.com - -Error: -""") + - str(e_type) + _(" : ") + str(e_value), +beremiz-devel@lists.sourceforge.net + +You should now restart program. + +Traceback: +""") % bug_report_path + + repr(e_type) + " : " + repr(e_value), _("Error"), trcbck_lst) try: @@ -472,10 +485,11 @@ sys.excepthook = handle_exception if __name__ == '__main__': - wx.InitAllImageHandlers() + if wx.VERSION < (3, 0, 0): + wx.InitAllImageHandlers() # Install a exception handle for bug reports - AddExceptHook(os.getcwd(),__version__) + AddExceptHook(os.getcwd(), version.app_version) frame = PLCOpenEditor(None, fileOpen=fileOpen) diff -r 6431f26aa501 -r 3291024e00da ProjectController.py --- a/ProjectController.py Thu Feb 16 14:34:40 2017 +0500 +++ b/ProjectController.py Thu Feb 16 14:35:12 2017 +0500 @@ -84,6 +84,60 @@ def GetAddMenuItems(): return ExtractMenuItemsFromCatalog(features.catalog) +class Iec2CSettings(): + def __init__(self): + self.iec2c = os.path.join(base_folder, "matiec", "iec2c"+(".exe" if wx.Platform == '__WXMSW__' else "")) + self.iec2c_buildopts = None + self.ieclib_path = os.path.join(base_folder, "matiec", "lib") + self.ieclib_c_path = None + + def findLibCPath(self): + path="" + paths=[ + os.path.join(base_folder, "matiec", "lib", "C"), + os.path.join(base_folder, "matiec", "lib") ] + for p in paths: + filename=os.path.join(p, "iec_types.h") + if (os.path.isfile(filename)): + path = p + break + return path + + def findSupportedOptions(self): + buildcmd = "\"%s\" -h"%(self.iec2c) + options =["-f", "-l", "-p"] + + buildopt = "" + try: + # Invoke compiler. Output files are listed to stdout, errors to stderr + status, result, err_result = ProcessLogger(None, buildcmd, + no_stdout=True, no_stderr=True).spin() + except Exception,e: + return buildopt + + for opt in options: + if opt in result: + buildopt = buildopt + " " + opt + return buildopt + + def getCmd(self): + return self.iec2c + + def getOptions(self): + if self.iec2c_buildopts is None: + self.iec2c_buildopts = self.findSupportedOptions() + return self.iec2c_buildopts + + def getLibPath(self): + return self.ieclib_path + + def getLibCPath(self): + if self.ieclib_c_path is None: + self.ieclib_c_path = self.findLibCPath() + return self.ieclib_c_path + +iec2c_cfg = Iec2CSettings() + class ProjectController(ConfigTreeNode, PLCControler): """ This class define Root object of the confnode tree. @@ -139,10 +193,6 @@ self.DebugTicks = [] self.SetAppFrame(frame, logger) - self.iec2c_path = os.path.join(base_folder, "matiec", "iec2c"+(".exe" if wx.Platform == '__WXMSW__' else "")) - self.ieclib_path = os.path.join(base_folder, "matiec", "lib") - self.ieclib_c_path = self._getMatIecCPath() - # Setup debug information self.IECdebug_datas = {} self.IECdebug_lock = Lock() @@ -228,10 +278,10 @@ return self def GetIECLibPath(self): - return self.ieclib_c_path + return iec2c_cfg.getLibCPath() def GetIEC2cPath(self): - return self.iec2c_path + return iec2c_cfg.getCmd() def GetCurrentLocation(self): return () @@ -355,15 +405,15 @@ # Verify that project contains a PLCOpen program plc_file = os.path.join(ProjectPath, "plc.xml") if not os.path.isfile(plc_file): - return _("Chosen folder doesn't contain a program. It's not a valid project!") + return _("Chosen folder doesn't contain a program. It's not a valid project!"), True # Load PLCOpen file error = self.OpenXMLFile(plc_file) if error is not None: if self.Project is not None: - self.logger.write_warning( - XSDSchemaErrorMessage % (("PLC",) + error)) + (fname_err, lnum, src) = (("PLC",) + error) + self.logger.write_warning(XSDSchemaErrorMessage.format(a1 = fname_err, a2 = lnum, a3 = src)) else: - return error + return error, False if len(self.GetProjectConfigNames()) == 0: self.AddProjectDefaultConfiguration() # Change XSD into class members @@ -377,20 +427,12 @@ #Load the confnode.xml file into parameters members result = self.LoadXMLParams() if result: - return result + return result, False #Load and init all the children self.LoadChildren() self.RefreshConfNodesBlockLists() - - if os.path.exists(self._getBuildPath()): - self.EnableMethod("_Clean", True) - - if os.path.isfile(self._getIECcodepath()): - self.ShowMethod("_showIECcode", True) - - self.UpdateMethodsFromPLCStatus() - - return None + self.UpdateButtons() + return None, False def RecursiveConfNodeInfos(self, confnode): values = [] @@ -423,6 +465,21 @@ self.ClearChildren() self.ResetAppFrame(None) + def CheckNewProjectPath(self, old_project_path, new_project_path): + if old_project_path == new_project_path: + message = (_("Save path is the same as path of a project! \n")) + dialog = wx.MessageDialog(self.AppFrame, message, _("Error"), wx.OK | wx.ICON_ERROR) + dialog.ShowModal() + return False + else: + plc_file = os.path.join(new_project_path, "plc.xml") + if os.path.isfile(plc_file): + message = (_("Selected directory already contains another project. Overwrite? \n")) + dialog = wx.MessageDialog(self.AppFrame, message, _("Error"), wx.YES_NO | wx.ICON_ERROR) + answer = dialog.ShowModal() + return answer == wx.ID_YES + return True + def SaveProject(self, from_project_path=None): if self.CheckProjectPathPerm(False): if from_project_path is not None: @@ -447,9 +504,10 @@ if answer == wx.ID_OK: newprojectpath = dirdialog.GetPath() if os.path.isdir(newprojectpath): - self.ProjectPath, old_project_path = newprojectpath, self.ProjectPath - self.SaveProject(old_project_path) - self._setBuildPath(self.BuildPath) + if self.CheckNewProjectPath(self.ProjectPath, newprojectpath): + self.ProjectPath, old_project_path = newprojectpath, self.ProjectPath + self.SaveProject(old_project_path) + self._setBuildPath(self.BuildPath) return True return False @@ -630,43 +688,14 @@ return True - def _getMatIecCPath(self): - path='' - paths=[ - os.path.join(base_folder, "matiec", "lib", "C"), - os.path.join(base_folder, "matiec", "lib") ] - for p in paths: - filename=os.path.join(p, "iec_types.h") - if (os.path.isfile(filename)): - path = p - break - return path - - def _getMatIecOptions(self): - buildpath = self._getBuildPath() - buildcmd = "\"%s\" -h"%(self.iec2c_path) - options =["-f", "-l", "-p"] - - buildopt = "" - try: - # Invoke compiler. Output files are listed to stdout, errors to stderr - status, result, err_result = ProcessLogger(self.logger, buildcmd, - no_stdout=True, no_stderr=True).spin() - except Exception,e: - return buildopt - - for opt in options: - if opt in result: - buildopt = buildopt + " " + opt - return buildopt def _Compile_ST_to_SoftPLC(self): self.logger.write(_("Compiling IEC Program into C code...\n")) buildpath = self._getBuildPath() buildcmd = "\"%s\" %s -I \"%s\" -T \"%s\" \"%s\""%( - self.iec2c_path, - self._getMatIecOptions(), - self.ieclib_path, + iec2c_cfg.getCmd(), + iec2c_cfg.getOptions(), + iec2c_cfg.getLibPath(), buildpath, self._getIECcodepath()) @@ -735,7 +764,7 @@ # Keep track of generated C files for later use by self.CTNGenerate_C self.PLCGeneratedCFiles = C_files # compute CFLAGS for plc - self.plcCFLAGS = '"-I%s" -Wno-unused-function'%self.ieclib_c_path + self.plcCFLAGS = '"-I%s" -Wno-unused-function'%iec2c_cfg.getLibCPath() return True def GetBuilder(self): @@ -971,15 +1000,13 @@ # Eventually create build dir if not os.path.exists(buildpath): os.mkdir(buildpath) - # There is something to clean - self.EnableMethod("_Clean", True) self.logger.flush() self.logger.write(_("Start build in %s\n") % buildpath) # Generate SoftPLC IEC code IECGenRes = self._Generate_SoftPLC() - self.ShowMethod("_showIECcode", True) + self.UpdateButtons() # If IEC code gen fail, bail out. if not IECGenRes: @@ -1090,8 +1117,14 @@ def ShowError(self, logger, from_location, to_location): chunk_infos = self.GetChunkInfos(from_location, to_location) for infos, (start_row, start_col) in chunk_infos: - start = (from_location[0] - start_row, from_location[1] - start_col) - end = (to_location[0] - start_row, to_location[1] - start_col) + row = 1 if from_location[0] < start_row else (from_location[0] - start_row) + col = 1 if (start_row != from_location[0]) else (from_location[1] - start_col) + start = (row, col) + + row = 1 if to_location[0] < start_row else (to_location[0] - start_row) + col = 1 if (start_row != to_location[0]) else (to_location[1] - start_col) + end = (row, col) + if self.AppFrame is not None: self.AppFrame.ShowError(infos, start, end) @@ -1124,6 +1157,7 @@ except: text = '(* No IEC code have been generated at that time ! *)' self._IECCodeView.SetText(text = text) + self._IECCodeView.Editor.SetReadOnly(True) self._IECCodeView.SetIcon(GetBitmap("ST")) setattr(self._IECCodeView, "_OnClose", self.OnCloseEditor) @@ -1220,18 +1254,28 @@ shutil.rmtree(os.path.join(self._getBuildPath())) else: self.logger.write_error(_("Build directory already clean\n")) - self.ShowMethod("_showIECcode", False) - self.EnableMethod("_Clean", False) # kill the builder self._builder = None self.CompareLocalAndRemotePLC() - + self.UpdateButtons() + + def _UpdateButtons(self): + self.EnableMethod("_Clean", os.path.exists(self._getBuildPath())) + self.ShowMethod("_showIECcode", os.path.isfile(self._getIECcodepath())) + if self.AppFrame is not None and not self.UpdateMethodsFromPLCStatus(): + self.AppFrame.RefreshStatusToolBar() + + def UpdateButtons(self): + wx.CallAfter(self._UpdateButtons) + + def UpdatePLCLog(self, log_count): if log_count: if self.AppFrame is not None: self.AppFrame.LogViewer.SetLogCounters(log_count) def UpdateMethodsFromPLCStatus(self): + updated = False status = None if self._connector is not None: PLCstatus = self._connector.GetPLCstatus() @@ -1259,15 +1303,39 @@ self.ShowMethod(*args) self.previous_plcstate = status if self.AppFrame is not None: + updated = True self.AppFrame.RefreshStatusToolBar() if status == "Disconnected": - self.AppFrame.ConnectionStatusBar.SetStatusText(_(status), 1) + self.AppFrame.ConnectionStatusBar.SetStatusText(self.GetTextStatus(status), 1) self.AppFrame.ConnectionStatusBar.SetStatusText('', 2) else: self.AppFrame.ConnectionStatusBar.SetStatusText( _("Connected to URI: %s") % self.BeremizRoot.getURI_location().strip(), 1) - self.AppFrame.ConnectionStatusBar.SetStatusText(_(status), 2) - + self.AppFrame.ConnectionStatusBar.SetStatusText(self.GetTextStatus(status), 2) + return updated + + def GetTextStatus(self, status): + msgs = { + "Started": _("Started"), + "Stopped": _("Stopped"), + "Empty": _("Empty"), + "Broken": _("Broken"), + "Disconnected": _("Disconnected") + } + return msgs.get(status, status) + + def ShowPLCProgress(self, status = "", progress = 0): + self.AppFrame.ProgressStatusBar.Show() + self.AppFrame.ConnectionStatusBar.SetStatusText(self.GetTextStatus(status), 1) + self.AppFrame.ProgressStatusBar.SetValue(progress) + + def HidePLCProgress(self): + # clear previous_plcstate to restore status + # in UpdateMethodsFromPLCStatus() + self.previous_plcstate = "" + self.AppFrame.ProgressStatusBar.Hide() + self.UpdateMethodsFromPLCStatus() + def PullPLCStatusProc(self, event): self.UpdateMethodsFromPLCStatus() @@ -1561,11 +1629,8 @@ if connector is not None: if self.StatusTimer is not None: # Start the status Timer - # Suppress WXDEBUG assertions, as happens by default with wx2.8 - try: - self.StatusTimer.Start(milliseconds=500, oneShot=False) - except: - pass + wx.Yield() + self.StatusTimer.Start(milliseconds=500, oneShot=False) else: if self.StatusTimer is not None: # Stop the status Timer @@ -1714,6 +1779,7 @@ self.logger.write(_("Transfer completed successfully.\n")) else: self.logger.write_error(_("Transfer failed\n")) + self.HidePLCProgress() else: self.logger.write_error(_("No PLC to transfer (did build succeed ?)\n")) diff -r 6431f26aa501 -r 3291024e00da canfestival/config_utils.py --- a/canfestival/config_utils.py Thu Feb 16 14:34:40 2017 +0500 +++ b/canfestival/config_utils.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/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. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from types import * @@ -352,14 +352,16 @@ # Check Id is in slave node list if nodeid not in self.NodeList.SlaveNodes.keys(): - raise PDOmappingException, _("Non existing node ID : %d (variable %s)") % (nodeid,name) + raise PDOmappingException, _("Non existing node ID : {a1} (variable {a2})").format(a1 = nodeid, a2 = name) # Get the model for this node (made from EDS) node = self.NodeList.SlaveNodes[nodeid]["Node"] # Extract and check index and subindex if not node.IsEntry(index, subindex): - raise PDOmappingException, _("No such index/subindex (%x,%x) in ID : %d (variable %s)") % (index,subindex,nodeid,name) + msg = _("No such index/subindex ({a1},{a2}) in ID : {a3} (variable {a4})").\ + format(a1 = "%x" % index, a2 ="%x" % subindex, a3 = nodeid, a4 = name) + raise PDOmappingException, msg # Get the entry info subentry_infos = node.GetSubentryInfos(index, subindex) @@ -369,19 +371,23 @@ if sizelocation == "X" and len(loc) > 3: numbit = loc[3] elif sizelocation != "X" and len(loc) > 3: - raise PDOmappingException, _("Cannot set bit offset for non bool '%s' variable (ID:%d,Idx:%x,sIdx:%x))") % (name,nodeid,index,subindex) + msg = _("Cannot set bit offset for non bool '{a1}' variable (ID:{a2},Idx:{a3},sIdx:{a4}))").\ + format(a1 = name, a2 = nodeid, a3 = "%x" % index, a4 = "%x" % subindex) + raise PDOmappingException, msg else: numbit = None if location["IEC_TYPE"] != "BOOL" and subentry_infos["type"] != COlocationtype: - raise PDOmappingException, _("Invalid type \"%s\"-> %d != %d for location\"%s\"") % (location["IEC_TYPE"], COlocationtype, subentry_infos["type"] , name) + raise PDOmappingException, _("Invalid type \"{a1}\"-> {a2} != {a3} for location\"{a4}\"").\ + format(a1 = location["IEC_TYPE"], a2 = COlocationtype, a3 = subentry_infos["type"] , a4 = name) typeinfos = node.GetEntryInfos(COlocationtype) self.IECLocations[name] = {"type":COlocationtype, "pdotype":SlavePDOType[direction], "nodeid": nodeid, "index": index,"subindex": subindex, "bit": numbit, "size": typeinfos["size"], "sizelocation": sizelocation} else: - raise PDOmappingException, _("Not PDO mappable variable : '%s' (ID:%d,Idx:%x,sIdx:%x))") % (name,nodeid,index,subindex) + raise PDOmappingException, _("Not PDO mappable variable : '{a1}' (ID:{a2},Idx:{a3},sIdx:{a4}))").\ + format(a1 = name, a2 = nodeid, a3 = "%x" % index, a4 = "%x" % subindex) #------------------------------------------------------------------------------- # Search for locations already mapped @@ -630,12 +636,14 @@ # Extract and check index and subindex if not slave.IsEntry(index, subindex): - raise PDOmappingException, _("No such index/subindex (%x,%x) (variable %s)") % (index, subindex, name) + raise PDOmappingException, _("No such index/subindex ({a1},{a2}) (variable {a3})").\ + format(a1 = "%x" % index, a2 = "%x" % subindex, a3 = name) # Get the entry info subentry_infos = slave.GetSubentryInfos(index, subindex) if subentry_infos["type"] != COlocationtype: - raise PDOmappingException, _("Invalid type \"%s\"-> %d != %d for location\"%s\"") % (location["IEC_TYPE"], COlocationtype, subentry_infos["type"] , name) + raise PDOmappingException, _("Invalid type \"{a1}\"-> {a2} != {a3} for location \"{a4}\"").\ + format( a1 = location["IEC_TYPE"], a2 = COlocationtype, a3 = subentry_infos["type"] , a4 = name) IECLocations[name] = COlocationtype pointers[(index, subindex)] = name diff -r 6431f26aa501 -r 3291024e00da connectors/PYRO/__init__.py --- a/connectors/PYRO/__init__.py Thu Feb 16 14:34:40 2017 +0500 +++ b/connectors/PYRO/__init__.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,23 +1,27 @@ #!/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 program 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 +# of the License, or (at your option) any later version. # -# This library is distributed in the hope that it will be useful, +# This program 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. +# 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + import Pyro import Pyro.core import Pyro.util @@ -83,7 +87,7 @@ ip = str(socket.inet_ntoa(i.getAddress())) port = str(i.getPort()) newlocation = ip + ':' + port - confnodesroot.logger.write(_("'%s' is located at %s\n") % (location, newlocation)) + confnodesroot.logger.write(_("'{a1}' is located at {a2}\n").format(a1 = location, a2 = newlocation)) location = newlocation r.close() except Exception, msg: @@ -108,10 +112,10 @@ try: return func(*args, **kwargs) except Pyro.errors.ConnectionClosedError, e: - confnodesroot.logger.write_error("Connection lost!\n") + confnodesroot.logger.write_error(_("Connection lost!\n")) confnodesroot._SetConnector(None) except Pyro.errors.ProtocolError, e: - confnodesroot.logger.write_error("Pyro exception: " + str(e) + "\n") + confnodesroot.logger.write_error(_("Pyro exception: %s\n") % e) except Exception, e: # confnodesroot.logger.write_error(traceback.format_exc()) errmess = ''.join(Pyro.util.getPyroTraceback(e)) diff -r 6431f26aa501 -r 3291024e00da connectors/WAMP/__init__.py --- a/connectors/WAMP/__init__.py Thu Feb 16 14:34:40 2017 +0500 +++ b/connectors/WAMP/__init__.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,23 +1,26 @@ #!/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) 2015: Edouard TISSERANT +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import sys, traceback, atexit #from twisted.python import log @@ -105,7 +108,7 @@ reactor, _WampSession.call, wampfuncname, *args,**kwargs) except TransportLost, e: - confnodesroot.logger.write_error("Connection lost!\n") + confnodesroot.logger.write_error(_("Connection lost!\n")) confnodesroot._SetConnector(None) except Exception,e: errmess = traceback.format_exc() diff -r 6431f26aa501 -r 3291024e00da connectors/__init__.py --- a/connectors/__init__.py Thu Feb 16 14:34:40 2017 +0500 +++ b/connectors/__init__.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,23 +1,26 @@ #!/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 program 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 +# of the License, or (at your option) any later version. # -# This library is distributed in the hope that it will be useful, +# This program 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. +# 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Package initialisation diff -r 6431f26aa501 -r 3291024e00da controls/CustomEditableListBox.py --- a/controls/CustomEditableListBox.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/CustomEditableListBox.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import wx.gizmos diff -r 6431f26aa501 -r 3291024e00da controls/CustomGrid.py --- a/controls/CustomGrid.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/CustomGrid.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import wx.grid @@ -37,8 +37,8 @@ self.UpButton = None self.DownButton = None - self.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, 'Sans')) - self.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, False, 'Sans')) + self.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, 'Sans')) + self.SetLabelFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, 'Sans')) self.SetSelectionBackground(wx.WHITE) self.SetSelectionForeground(wx.BLACK) self.DisableDragRowSize() diff -r 6431f26aa501 -r 3291024e00da controls/CustomTable.py --- a/controls/CustomTable.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/CustomTable.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,19 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import wx.grid diff -r 6431f26aa501 -r 3291024e00da controls/CustomToolTip.py --- a/controls/CustomToolTip.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/CustomToolTip.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da controls/CustomTree.py --- a/controls/CustomTree.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/CustomTree.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,19 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#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 file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#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. +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#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 +# See COPYING file for copyrights details. +# +# This program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import wx.lib.agw.customtreectrl as CT diff -r 6431f26aa501 -r 3291024e00da controls/DebugVariablePanel/DebugVariableGraphicViewer.py --- a/controls/DebugVariablePanel/DebugVariableGraphicViewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/DebugVariablePanel/DebugVariableGraphicViewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from types import TupleType from time import time as gettime diff -r 6431f26aa501 -r 3291024e00da controls/DebugVariablePanel/DebugVariableItem.py --- a/controls/DebugVariablePanel/DebugVariableItem.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/DebugVariablePanel/DebugVariableItem.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#Copyright (C) 2012: 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 +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# +# See COPYING file for copyrights details. +# +# This program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import numpy import binascii diff -r 6431f26aa501 -r 3291024e00da controls/DebugVariablePanel/DebugVariablePanel.py --- a/controls/DebugVariablePanel/DebugVariablePanel.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/DebugVariablePanel/DebugVariablePanel.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from types import TupleType import math @@ -50,10 +50,10 @@ # List of values possible for graph range # Format is [(time_in_plain_text, value_in_nanosecond),...] RANGE_VALUES = \ - [("%dms" % i, i * MILLISECOND) for i in (10, 20, 50, 100, 200, 500)] + \ - [("%ds" % i, i * SECOND) for i in (1, 2, 5, 10, 20, 30)] + \ - [("%dm" % i, i * MINUTE) for i in (1, 2, 5, 10, 20, 30)] + \ - [("%dh" % i, i * HOUR) for i in (1, 2, 3, 6, 12, 24)] + [(_("%dms") % i, i * MILLISECOND) for i in (10, 20, 50, 100, 200, 500)] + \ + [(_("%ds") % i, i * SECOND) for i in (1, 2, 5, 10, 20, 30)] + \ + [(_("%dm") % i, i * MINUTE) for i in (1, 2, 5, 10, 20, 30)] + \ + [(_("%dh") % i, i * HOUR) for i in (1, 2, 3, 6, 12, 24)] # Scrollbar increment in pixel SCROLLBAR_UNIT = 10 @@ -291,6 +291,7 @@ DebugViewer.__init__(self, producer, True) self.SetSizer(main_sizer) + self.SetTickTime() def SetTickTime(self, ticktime=0): """ @@ -561,20 +562,20 @@ else: tick = None if tick is not None: - self.TickLabel.SetLabel("Tick: %d" % tick) + self.TickLabel.SetLabel(label=_("Tick: %d") % tick) tick_duration = int(tick * self.Ticktime) not_null = False duration = "" - for value, format in [(tick_duration / DAY, "%dd"), - ((tick_duration % DAY) / HOUR, "%dh"), - ((tick_duration % HOUR) / MINUTE, "%dm"), - ((tick_duration % MINUTE) / SECOND, "%ds")]: + for value, format in [(tick_duration / DAY, _("%dd")), + ((tick_duration % DAY) / HOUR, _("%dh")), + ((tick_duration % HOUR) / MINUTE, _("%dm")), + ((tick_duration % MINUTE) / SECOND, _("%ds"))]: if value > 0 or not_null: duration += format % value not_null = True - duration += "%gms" % (float(tick_duration % SECOND) / MILLISECOND) + duration += _("%03gms") % (float(tick_duration % SECOND) / MILLISECOND) self.TickTimeLabel.SetLabel("t: %s" % duration) else: self.TickLabel.SetLabel("") diff -r 6431f26aa501 -r 3291024e00da controls/DebugVariablePanel/DebugVariableTextViewer.py --- a/controls/DebugVariablePanel/DebugVariableTextViewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/DebugVariablePanel/DebugVariableTextViewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#Copyright (C) 2012: 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 +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# +# See COPYING file for copyrights details. +# +# This program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from types import TupleType diff -r 6431f26aa501 -r 3291024e00da controls/DebugVariablePanel/DebugVariableViewer.py --- a/controls/DebugVariablePanel/DebugVariableViewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/DebugVariablePanel/DebugVariableViewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from collections import OrderedDict diff -r 6431f26aa501 -r 3291024e00da controls/DebugVariablePanel/GraphButton.py --- a/controls/DebugVariablePanel/GraphButton.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/DebugVariablePanel/GraphButton.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da controls/DebugVariablePanel/__init__.py --- a/controls/DebugVariablePanel/__init__.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/DebugVariablePanel/__init__.py Thu Feb 16 14:35:12 2017 +0500 @@ -4,7 +4,7 @@ # 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 +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # # See COPYING file for copyrights details. # diff -r 6431f26aa501 -r 3291024e00da controls/DurationCellEditor.py --- a/controls/DurationCellEditor.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/DurationCellEditor.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -128,11 +128,11 @@ if wx.VERSION >= (3, 0, 0): def EndEdit(self, row, col, grid, oldval): - self.EndEditInternal(row, col, grid, oldval) + return self.EndEditInternal(row, col, grid, oldval) else: def EndEdit(self, row, col, grid): oldval = self.Table.GetValueByName(row, self.Colname) - self.EndEditInternal(row, col, grid, oldval) + return self.EndEditInternal(row, col, grid, oldval) def SetSize(self, rect): self.CellControl.SetDimensions(rect.x + 1, rect.y, diff -r 6431f26aa501 -r 3291024e00da controls/EnhancedStatusBar.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controls/EnhancedStatusBar.py Thu Feb 16 14:35:12 2017 +0500 @@ -0,0 +1,248 @@ +# --------------------------------------------------------------------------- # +# ENHANCEDSTATUSBAR wxPython IMPLEMENTATION +# Python Code By: +# +# Andrea Gavana, @ 31 May 2005 +# Nitro, @ 21 September 2005 +# Latest Revision: 21 September 2005, 19.57.20 GMT+2 +# Latest Revision before Latest Revision: 21 September 2005, 18.29.35 GMT+2 +# Latest Revision before Latest Revision before Latest Revision: 31 May 2005, 23.17 CET +# +# +# TODO List/Caveats +# +# 1. Some Requests/Features To Add? +# +# +# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please +# Write To Me At: +# +# +# andrea.gavana@agip.it +# andrea_gavan@tin.it +# +# Or, Obviously, To The wxPython Mailing List!!! +# +# +# licensed under wxWidgets License (GPL compatible) +# End Of Comments +# --------------------------------------------------------------------------- # + +""" Description: + +EnhancedStatusBar Is A Slight Modification (Actually A Subclassing) Of wx.StatusBar. +It Allows You To Add Almost Any Widget You Like To The wx.StatusBar Of Your Main +Frame Application And Also To Layout Them Properly. + + +What It Can Do: + +1) Almost All The Functionalities Of wx.StatusBar Are Still Present; +2) You Can Add Different Kind Of Widgets Into Every Field Of The EnhancedStatusBar; +3) The AddWidget() Methods Accepts 2 Layout Inputs: + - horizontalalignment: This Specify The Horizontal Alignment For Your Widget, + And Can Be ESB_EXACT_FIT, ESB_ALIGN_CENTER_HORIZONTAL, ESB_ALIGN_LEFT And + ESB_ALIGN_RIGHT; + - varticalalignment: This Specify The Vertical Alignment For Your Widget, + And Can Be ESB_EXACT_FIT, ESB_ALIGN_CENTER_VERTICAL, ESB_ALIGN_BOTTOM And + ESB_ALIGN_LEFT; + +EnhancedStatusBar Is Freeware And Distributed Under The wxPython License. + +Latest Revision: 21 September 2005, 19.57.20 GMT+2 +Latest Revision before Latest Revision: 21 September 2005, 18.29.35 GMT+2 +Latest Revision before Latest Revision before Latest Revision: 31 May 2005, 23.17 CET + +""" + +import wx + +# Horizontal Alignment Constants +ESB_ALIGN_CENTER_VERTICAL = 1 +ESB_ALIGN_TOP = 2 +ESB_ALIGN_BOTTOM = 3 + +# Vertical Alignment Constants +ESB_ALIGN_CENTER_HORIZONTAL = 11 +ESB_ALIGN_LEFT = 12 +ESB_ALIGN_RIGHT = 13 + +# Exact Fit (Either Horizontal Or Vertical Or Both) Constant +ESB_EXACT_FIT = 20 + + +# --------------------------------------------------------------- +# Class EnhancedStatusBar +# --------------------------------------------------------------- +# This Is The Main Class Implementation. See The Demo For Details +# --------------------------------------------------------------- +class EnhancedStatusBarItem(object): + def __init__(self, widget, pos, horizontalalignment=ESB_ALIGN_CENTER_HORIZONTAL, verticalalignment=ESB_ALIGN_CENTER_VERTICAL): + self.__dict__.update( locals() ) + +class EnhancedStatusBar(wx.StatusBar): + + def __init__(self, parent, id=wx.ID_ANY, style=wx.ST_SIZEGRIP, + name="EnhancedStatusBar"): + """Default Class Constructor. + + EnhancedStatusBar.__init__(self, parent, id=wx.ID_ANY, + style=wx.ST_SIZEGRIP, + name="EnhancedStatusBar") + """ + + wx.StatusBar.__init__(self, parent, id, style, name) + + self._items = {} + self._curPos = 0 + self._parent = parent + + wx.EVT_SIZE(self, self.OnSize) + wx.CallAfter(self.OnSize, None) + + + def OnSize(self, event): + """Handles The wx.EVT_SIZE Events For The StatusBar. + + Actually, All The Calculations Linked To HorizontalAlignment And + VerticalAlignment Are Done In This Function.""" + + for pos, item in self._items.items(): + widget, horizontalalignment, verticalalignment = item.widget, item.horizontalalignment, item.verticalalignment + + rect = self.GetFieldRect(pos) + widgetpos = widget.GetPosition() + widgetsize = widget.GetSize() + + rect = self.GetFieldRect(pos) + + if horizontalalignment == ESB_EXACT_FIT: + + if verticalalignment == ESB_EXACT_FIT: + """ 1 September 2015 Fix fit align """ + widget.SetSize((rect.width-4, rect.height-4)) + widget.SetPosition((rect.x+2, rect.y+2)) + elif verticalalignment == ESB_ALIGN_CENTER_VERTICAL: + if widgetsize[1] < rect.width - 1: + diffs = (rect.height - widgetsize[1])/2 + widget.SetSize((rect.width-2, widgetsize[1])) + widget.SetPosition((rect.x-1, rect.y+diffs)) + else: + widget.SetSize((rect.width-2, widgetsize[1])) + widget.SetPosition((rect.x-1, rect.y-1)) + elif verticalalignment == ESB_ALIGN_TOP: + widget.SetSize((rect.width-2, widgetsize[1])) + widget.SetPosition((rect.x-1, rect.y)) + elif verticalalignment == ESB_ALIGN_BOTTOM: + widget.SetSize((rect.width-2, widgetsize[1])) + widget.SetPosition((rect.x-1, rect.height-widgetsize[1])) + + elif horizontalalignment == ESB_ALIGN_LEFT: + + xpos = rect.x - 1 + if verticalalignment == ESB_EXACT_FIT: + widget.SetSize((widgetsize[0], rect.height-2)) + widget.SetPosition((xpos, rect.y-1)) + elif verticalalignment == ESB_ALIGN_CENTER_VERTICAL: + if widgetsize[1] < rect.height - 1: + diffs = (rect.height - widgetsize[1])/2 + widget.SetPosition((xpos, rect.y+diffs)) + else: + widget.SetSize((widgetsize[0], rect.height-2)) + widget.SetPosition((xpos, rect.y-1)) + elif verticalalignment == ESB_ALIGN_TOP: + widget.SetPosition((xpos, rect.y)) + elif verticalalignment == ESB_ALIGN_BOTTOM: + widget.SetPosition((xpos, rect.height-widgetsize[1])) + + elif horizontalalignment == ESB_ALIGN_RIGHT: + + xpos = rect.x + rect.width - widgetsize[0] - 1 + if verticalalignment == ESB_EXACT_FIT: + widget.SetSize((widgetsize[0], rect.height-2)) + widget.SetPosition((xpos, rect.y-1)) + elif verticalalignment == ESB_ALIGN_CENTER_VERTICAL: + if widgetsize[1] < rect.height - 1: + diffs = (rect.height - widgetsize[1])/2 + widget.SetPosition((xpos, rect.y+diffs)) + else: + widget.SetSize((widgetsize[0], rect.height-2)) + widget.SetPosition((xpos, rect.y-1)) + elif verticalalignment == ESB_ALIGN_TOP: + widget.SetPosition((xpos, rect.y)) + elif verticalalignment == ESB_ALIGN_BOTTOM: + widget.SetPosition((xpos, rect.height-widgetsize[1])) + + elif horizontalalignment == ESB_ALIGN_CENTER_HORIZONTAL: + + xpos = rect.x + (rect.width - widgetsize[0])/2 - 1 + if verticalalignment == ESB_EXACT_FIT: + widget.SetSize((widgetsize[0], rect.height)) + widget.SetPosition((xpos, rect.y)) + elif verticalalignment == ESB_ALIGN_CENTER_VERTICAL: + if widgetsize[1] < rect.height - 1: + diffs = (rect.height - widgetsize[1])/2 + widget.SetPosition((xpos, rect.y+diffs)) + else: + widget.SetSize((widgetsize[0], rect.height-1)) + widget.SetPosition((xpos, rect.y+1)) + elif verticalalignment == ESB_ALIGN_TOP: + widget.SetPosition((xpos, rect.y)) + elif verticalalignment == ESB_ALIGN_BOTTOM: + widget.SetPosition((xpos, rect.height-widgetsize[1])) + + + if event is not None: + event.Skip() + + + def AddWidget(self, widget, horizontalalignment=ESB_ALIGN_CENTER_HORIZONTAL, + verticalalignment=ESB_ALIGN_CENTER_VERTICAL, pos = -1): + """Add A Widget To The EnhancedStatusBar. + + Parameters: + + - horizontalalignment: This Can Be One Of: + a) ESB_EXACT_FIT: The Widget Will Fit Horizontally The StatusBar Field Width; + b) ESB_ALIGN_CENTER_HORIZONTAL: The Widget Will Be Centered Horizontally In + The StatusBar Field; + c) ESB_ALIGN_LEFT: The Widget Will Be Left Aligned In The StatusBar Field; + d) ESB_ALIGN_RIGHT: The Widget Will Be Right Aligned In The StatusBar Field; + + - verticalalignment: + a) ESB_EXACT_FIT: The Widget Will Fit Vertically The StatusBar Field Height; + b) ESB_ALIGN_CENTER_VERTICAL: The Widget Will Be Centered Vertically In + The StatusBar Field; + c) ESB_ALIGN_BOTTOM: The Widget Will Be Bottom Aligned In The StatusBar Field; + d) ESB_ALIGN_TOP: The Widget Will Be TOP Aligned In The StatusBar Field; + + """ + + if pos == -1: + pos = self._curPos + self._curPos += 1 + + if self.GetFieldsCount() <= pos: + raise "\nERROR: EnhancedStatusBar has a max of %d items, you tried to set item #%d" % (self.GetFieldsCount(), pos) + + if horizontalalignment not in [ESB_ALIGN_CENTER_HORIZONTAL, ESB_EXACT_FIT, + ESB_ALIGN_LEFT, ESB_ALIGN_RIGHT]: + raise '\nERROR: Parameter "horizontalalignment" Should Be One Of '\ + '"ESB_ALIGN_CENTER_HORIZONTAL", "ESB_ALIGN_LEFT", "ESB_ALIGN_RIGHT"' \ + '"ESB_EXACT_FIT"' + + if verticalalignment not in [ESB_ALIGN_CENTER_VERTICAL, ESB_EXACT_FIT, + ESB_ALIGN_TOP, ESB_ALIGN_BOTTOM]: + raise '\nERROR: Parameter "verticalalignment" Should Be One Of '\ + '"ESB_ALIGN_CENTER_VERTICAL", "ESB_ALIGN_TOP", "ESB_ALIGN_BOTTOM"' \ + '"ESB_EXACT_FIT"' + + + try: + self.RemoveChild(self._items[pos].widget) + self._items[pos].widget.Destroy() + except KeyError: pass + + self._items[pos] = EnhancedStatusBarItem(widget, pos, horizontalalignment, verticalalignment) + + wx.CallAfter(self.OnSize, None) diff -r 6431f26aa501 -r 3291024e00da controls/FolderTree.py --- a/controls/FolderTree.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/FolderTree.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#Copyright (C) 2013: 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 +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# +# Copyright (C) 2013: Edouard TISSERANT and Laurent BESSARD +# +# See COPYING file for copyrights details. +# +# This program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import os diff -r 6431f26aa501 -r 3291024e00da controls/LibraryPanel.py --- a/controls/LibraryPanel.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/LibraryPanel.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -67,8 +67,12 @@ self.OnSearchButtonClick, self.SearchCtrl) # Bind keyboard event on SearchCtrl text control to catch UP and DOWN # for search previous and next occurrence - search_textctrl = self.SearchCtrl.GetChildren()[0] - search_textctrl.Bind(wx.EVT_CHAR, self.OnKeyDown) + + # This protects from fail to start when no children[0] available (possible for wxPython 3.0) + if self.SearchCtrl.GetChildren(): + search_textctrl = self.SearchCtrl.GetChildren()[0] + search_textctrl.Bind(wx.EVT_CHAR, self.OnKeyDown) + main_sizer.AddWindow(self.SearchCtrl, flag=wx.GROW) # Add Splitter window for tree and block comment to main sizer diff -r 6431f26aa501 -r 3291024e00da controls/LocationCellEditor.py --- a/controls/LocationCellEditor.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/LocationCellEditor.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -95,7 +95,7 @@ if not infos["location"].startswith("%"): dialog = wx.SingleChoiceDialog(self, _("Select a variable class:"), _("Variable class"), - ["Input", "Output", "Memory"], + [_("Input"), _("Output"), _("Memory")], wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: selected = dialog.GetSelection() @@ -161,15 +161,22 @@ self.CellControl.SetVarType(self.Table.GetValueByName(row, 'Type')) self.CellControl.SetFocus() - def EndEdit(self, row, col, grid): + def EndEditInternal(self, row, col, grid, old_loc): loc = self.CellControl.GetValue() - old_loc = self.Table.GetValueByName(row, 'Location') changed = loc != old_loc if changed: self.Table.SetValueByName(row, 'Location', loc) self.Table.SetValueByName(row, 'Type', self.CellControl.GetVarType()) self.CellControl.Disable() return changed + + if wx.VERSION >= (3, 0, 0): + def EndEdit(self, row, col, grid, oldval): + return self.EndEditInternal(row, col, grid, oldval) + else: + def EndEdit(self, row, col, grid): + old_loc = self.Table.GetValueByName(row, 'Location') + return self.EndEditInternal(row, col, grid, old_loc) def SetSize(self, rect): self.CellControl.SetDimensions(rect.x + 1, rect.y, diff -r 6431f26aa501 -r 3291024e00da controls/LogViewer.py --- a/controls/LogViewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/LogViewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,27 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2013: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2013: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + from datetime import datetime from time import time as gettime @@ -176,7 +177,7 @@ dc.EndDrawing() event.Skip() -BUTTON_SIZE = (30, 15) +BUTTON_SIZE = (70, 15) class LogButton(): diff -r 6431f26aa501 -r 3291024e00da controls/PouInstanceVariablesPanel.py --- a/controls/PouInstanceVariablesPanel.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/PouInstanceVariablesPanel.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from collections import namedtuple @@ -93,7 +93,7 @@ images_bbx = self.GetItemRightImagesBBox(item) r_image_w, r_image_h = self._imageListRight.GetSize(rightimages[0]) - dc.SetBrush(wx.WHITE_BRUSH) + dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.SetPen(wx.TRANSPARENT_PEN) bg_width = (r_image_w + 4) * len(rightimages) + 4 diff -r 6431f26aa501 -r 3291024e00da controls/ProjectPropertiesPanel.py --- a/controls/ProjectPropertiesPanel.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/ProjectPropertiesPanel.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#Copyright (C) 2012: 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 +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# +# See COPYING file for copyrights details. +# +# This program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -212,7 +212,7 @@ for param in REQUIRED_PARAMS: getattr(self, param).Enable(enable_required) - languages = ["", "en-US", "fr-FR", "zh-CN"] + languages = ["", "en-US", "fr-FR", "zh-CN", "ru-RU"] for language in languages: self.Language.Append(language) diff -r 6431f26aa501 -r 3291024e00da controls/SearchResultPanel.py --- a/controls/SearchResultPanel.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/SearchResultPanel.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from types import TupleType @@ -232,28 +232,15 @@ break if element_type == ITEM_RESOURCE: search_results_tree_children.append(element_infos) - else: - _tagname = self.ParentWindow.Controler.ComputePouName(words[1]) - _element_type = self.ParentWindow.Controler.GetPouType(words[1]) - - _element_infos = {"name": words[1], - "type": _element_type, - "data": _tagname, - "text": None, - "matches": 1, - "children": [element_infos]} - - search_results_tree_children.append(_element_infos) - else: search_results_tree_children.append(element_infos) if matches_number < 2: - header_format = _("'%s' - %d match in project") + header_format = _("'{a1}' - {a2} match in project") else: - header_format = _("'%s' - %d matches in project") - - self.HeaderLabel.SetLabel(header_format % (self.Criteria["raw_pattern"], matches_number)) + header_format = _("'{a1}' - {a2} matches in project") + + self.HeaderLabel.SetLabel(header_format.format(a1 = self.Criteria["find_pattern"], a2 = matches_number)) self.ResetButton.Enable(True) if matches_number > 0: @@ -337,6 +324,7 @@ search_results = [data] else: search_results = self.SearchResults.get(data, []) + self.ParentWindow.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) for infos, start, end, text in search_results: self.ParentWindow.ShowSearchResult(infos, start, end) diff -r 6431f26aa501 -r 3291024e00da controls/TextCtrlAutoComplete.py --- a/controls/TextCtrlAutoComplete.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/TextCtrlAutoComplete.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import cPickle diff -r 6431f26aa501 -r 3291024e00da controls/VariablePanel.py --- a/controls/VariablePanel.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/VariablePanel.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import os import re @@ -144,6 +144,14 @@ def GetOldValue(self): return self.old_value + def _GetRowEdit(self, row): + row_edit = self.GetValueByName(row, "Edit") + var_type = self.Parent.GetTagName() + bodytype = self.Parent.Controler.GetEditedElementBodyType(var_type) + if bodytype in ["ST", "IL"]: + row_edit = True; + return row_edit + def _updateColAttrs(self, grid): """ wx.grid.Grid -> update the column attributes to add the @@ -171,7 +179,7 @@ editor.SetParameters(",".join(map(_, options))) else: grid.SetReadOnly(row, col, True) - elif col != 0 and self.GetValueByName(row, "Edit"): + elif col != 0 and self._GetRowEdit(row): grid.SetReadOnly(row, col, False) if colname == "Name": editor = wx.grid.GridCellTextEditor() @@ -238,7 +246,7 @@ self.ParentWindow.ParentWindow.Select() x, y = self.ParentWindow.VariablesGrid.CalcUnscrolledPosition(x, y) col = self.ParentWindow.VariablesGrid.XToCol(x) - row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize()) + row = self.ParentWindow.VariablesGrid.YToRow(y) message = None element_type = self.ParentWindow.ElementType try: @@ -265,7 +273,8 @@ if values[2] is not None: base_location_type = self.ParentWindow.Controler.GetBaseType(values[2]) if values[2] != variable_type and base_type != base_location_type: - message = _("Incompatible data types between \"%s\" and \"%s\"")%(values[2], variable_type) + message = _("Incompatible data types between \"{a1}\" and \"{a2}\"").\ + format(a1 = values[2], a2 = variable_type) if message is None: if not location.startswith("%"): @@ -274,11 +283,12 @@ elif location[0] not in LOCATIONDATATYPES: message = _("Unrecognized data size \"%s\"")%location[0] elif base_type not in LOCATIONDATATYPES[location[0]]: - message = _("Incompatible size of data between \"%s\" and \"%s\"")%(location, variable_type) + message = _("Incompatible size of data between \"{a1}\" and \"{a2}\"").\ + format(a1 = location, a2 = variable_type) else: dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, _("Select a variable class:"), _("Variable class"), - ["Input", "Output", "Memory"], + [_("Input"), _("Output"), _("Memory")], wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: selected = dialog.GetSelection() @@ -316,7 +326,7 @@ dlg = wx.TextEntryDialog( self.ParentWindow.ParentWindow.ParentWindow, _("Confirm or change variable name"), - 'Variable Drop', var_name) + _('Variable Drop'), var_name) dlg.SetValue(var_name) var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None dlg.Destroy() @@ -338,7 +348,7 @@ if not location.startswith("%"): dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, _("Select a variable class:"), _("Variable class"), - ["Input", "Output", "Memory"], + [_("Input"), _("Output"), _("Memory")], wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: selected = dialog.GetSelection() diff -r 6431f26aa501 -r 3291024e00da controls/__init__.py --- a/controls/__init__.py Thu Feb 16 14:34:40 2017 +0500 +++ b/controls/__init__.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Package initialization diff -r 6431f26aa501 -r 3291024e00da dialogs/AboutDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/AboutDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -0,0 +1,182 @@ +#!/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. +# This file is based on code written for Whyteboard project. +# +# Copyright (c) 2009, 2010 by Steven Sproat +# Copyright (c) 2016 by Andrey Skvortsov +# +# See COPYING file for copyrights details. +# +# This program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + + +""" +This module contains classes extended from wx.Dialog used by the GUI. +""" + +import os +import sys +import time +import wx +from wx.lib.agw.hyperlink import HyperLinkCtrl + + +#---------------------------------------------------------------------- + +class AboutDialog(wx.Dialog): + """ + A replacement About Dialog for Windows, as it uses a generic frame that + well...sucks. + """ + def __init__(self, parent, info): + title = _("About") + " " + info.Name + wx.Dialog.__init__(self, parent, title=title) + self.info = info + + if parent and parent.GetIcon(): + self.SetIcon(parent.GetIcon()) + + image = None + if self.info.Icon: + bitmap = wx.BitmapFromIcon(self.info.Icon) + image = wx.StaticBitmap(self, bitmap=bitmap) + + name = wx.StaticText(self, label="%s %s" % (info.Name, info.Version)) + description = wx.StaticText(self, label=info.Description) + description.Wrap(400) + copyright = wx.StaticText(self, label=info.Copyright) + url = HyperLinkCtrl(self, label=info.WebSite[0], URL=info.WebSite[1]) + + font = name.GetClassDefaultAttributes().font + font.SetWeight(wx.FONTWEIGHT_BOLD) + font.SetPointSize(18) + name.SetFont(font) + + credits = wx.Button(self, id=wx.ID_ABOUT, label=_("C&redits")) + license = wx.Button(self, label=_("&License")) + close = wx.Button(self, id=wx.ID_CANCEL, label=_("&Close")) + + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + btnSizer.Add(credits, flag=wx.CENTER | wx.LEFT | wx.RIGHT, border=5) + btnSizer.Add(license, flag=wx.CENTER | wx.RIGHT, border=5) + btnSizer.Add(close, flag=wx.CENTER | wx.RIGHT, border=5) + + sizer = wx.BoxSizer(wx.VERTICAL) + if image: + sizer.Add(image, flag=wx.CENTER | wx.TOP | wx.BOTTOM, border=5) + sizer.Add(name, flag=wx.CENTER | wx.BOTTOM, border=10) + sizer.Add(description, flag=wx.CENTER | wx.BOTTOM, border=10) + sizer.Add(copyright, flag=wx.CENTER | wx.BOTTOM, border=10) + sizer.Add(url, flag=wx.CENTER | wx.BOTTOM, border=15) + sizer.Add(btnSizer, flag=wx.CENTER | wx.BOTTOM, border=5) + + container = wx.BoxSizer(wx.VERTICAL) + container.Add(sizer, flag=wx.ALL, border=10) + self.SetSizer(container) + self.Layout() + self.Fit() + self.Centre() + self.Show(True) + self.SetEscapeId(close.GetId()) + + credits.Bind(wx.EVT_BUTTON, self.on_credits) + license.Bind(wx.EVT_BUTTON, self.on_license) + close.Bind(wx.EVT_BUTTON, lambda evt: self.Destroy()) + + def on_license(self, event): + LicenseDialog(self, self.info) + + def on_credits(self, event): + CreditsDialog(self, self.info) + + +#---------------------------------------------------------------------- + +class CreditsDialog(wx.Dialog): + def __init__(self, parent, info): + wx.Dialog.__init__(self, parent, title=_("Credits"), size=(475, 320), + style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) + + if parent and parent.GetIcon(): + self.SetIcon(parent.GetIcon()) + + self.SetMinSize((300, 200)) + notebook = wx.Notebook(self) + close = wx.Button(self, id=wx.ID_CLOSE, label=_("&Close")) + close.SetDefault() + + developer = wx.TextCtrl(notebook, style=wx.TE_READONLY | wx.TE_MULTILINE) + translators = wx.TextCtrl(notebook, style=wx.TE_READONLY | wx.TE_MULTILINE) + + developer.SetValue(u'\n'.join(info.Developers)) + translators.SetValue(u'\n'.join(info.Translators)) + + notebook.AddPage(developer, text=_("Written by")) + notebook.AddPage(translators, text=_("Translated by")) + + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + btnSizer.Add(close) + + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(notebook, 1, wx.EXPAND | wx.ALL, 10) + sizer.Add(btnSizer, flag=wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, border=10) + self.SetSizer(sizer) + self.Layout() + self.Show() + self.SetEscapeId(close.GetId()) + + close.Bind(wx.EVT_BUTTON, lambda evt: self.Destroy()) + + +#---------------------------------------------------------------------- + +class LicenseDialog(wx.Dialog): + def __init__(self, parent, info): + wx.Dialog.__init__(self, parent, title=_("License"), size=(500, 400), + style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) + + if parent and parent.GetIcon(): + self.SetIcon(parent.GetIcon()) + + self.SetMinSize((400, 300)) + close = wx.Button(self, id=wx.ID_CLOSE, label=_("&Close")) + + ctrl = wx.TextCtrl(self, style=wx.TE_READONLY | wx.TE_MULTILINE) + ctrl.SetValue(info.License) + + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + btnSizer.Add(close) + + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(ctrl, 1, wx.EXPAND | wx.ALL, 10) + sizer.Add(btnSizer, flag=wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, border=10) + self.SetSizer(sizer) + self.Layout() + self.Show() + self.SetEscapeId(close.GetId()) + + close.Bind(wx.EVT_BUTTON, lambda evt: self.Destroy()) + +#---------------------------------------------------------------------- + +def ShowAboutDialog(parent, info): + if os.name == "nt": + AboutDialog(parent, info) + else: + wx.AboutBox(info) diff -r 6431f26aa501 -r 3291024e00da dialogs/ActionBlockDialog.py --- a/dialogs/ActionBlockDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/ActionBlockDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,25 @@ # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import wx.grid diff -r 6431f26aa501 -r 3291024e00da dialogs/ArrayTypeDialog.py --- a/dialogs/ArrayTypeDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/ArrayTypeDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,25 @@ # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re from types import TupleType diff -r 6431f26aa501 -r 3291024e00da dialogs/BlockPreviewDialog.py --- a/dialogs/BlockPreviewDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/BlockPreviewDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#Copyright (C) 2013: 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 +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. +# +# Copyright (C) 2013: Edouard TISSERANT and Laurent BESSARD +# +# See COPYING file for copyrights details. +# +# This program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -300,4 +300,4 @@ """ self.RefreshPreview() event.Skip() - \ No newline at end of file + diff -r 6431f26aa501 -r 3291024e00da dialogs/BrowseLocationsDialog.py --- a/dialogs/BrowseLocationsDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/BrowseLocationsDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,21 +1,26 @@ -# -#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 +#!/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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.# import os diff -r 6431f26aa501 -r 3291024e00da dialogs/BrowseValuesLibraryDialog.py --- a/dialogs/BrowseValuesLibraryDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/BrowseValuesLibraryDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/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. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/ConnectionDialog.py --- a/dialogs/ConnectionDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/ConnectionDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/DiscoveryDialog.py --- a/dialogs/DiscoveryDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/DiscoveryDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,26 @@ +#!/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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import socket import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/DurationEditorDialog.py --- a/dialogs/DurationEditorDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/DurationEditorDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re diff -r 6431f26aa501 -r 3291024e00da dialogs/FBDBlockDialog.py --- a/dialogs/FBDBlockDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/FBDBlockDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re diff -r 6431f26aa501 -r 3291024e00da dialogs/FBDVariableDialog.py --- a/dialogs/FBDVariableDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/FBDVariableDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -287,4 +287,4 @@ # Call BlockPreviewDialog function BlockPreviewDialog.RefreshPreview(self) - \ No newline at end of file + diff -r 6431f26aa501 -r 3291024e00da dialogs/FindInPouDialog.py --- a/dialogs/FindInPouDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/FindInPouDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,30 +1,31 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx +from plcopen.plcopen import * -class FindInPouDialog(wx.Frame): +class FindInPouDialog(wx.Dialog): def _init_icon(self, parent): if parent and parent.icon: @@ -32,12 +33,11 @@ def __init__(self, parent): - wx.Frame.__init__(self, parent, title=_("Find"), - size=wx.Size(400, 250), style=wx.CAPTION| + wx.Dialog.__init__(self, parent, title=_("Find"), + size=wx.Size(500, 280), style=wx.CAPTION| wx.CLOSE_BOX| wx.CLIP_CHILDREN| - wx.RESIZE_BORDER| - wx.STAY_ON_TOP) + wx.RESIZE_BORDER) self._init_icon(parent) panel = wx.Panel(self, style=wx.TAB_TRAVERSAL) @@ -59,6 +59,7 @@ self.FindPattern = wx.TextCtrl(panel) self.Bind(wx.EVT_TEXT, self.OnFindPatternChanged, self.FindPattern) + self.Bind(wx.EVT_CHAR_HOOK, self.OnEscapeKey) patterns_sizer.AddWindow(self.FindPattern, flag=wx.GROW) params_sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -110,13 +111,18 @@ self.CloseButton = wx.Button(panel, label=_("Close")) self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.CloseButton) buttons_sizer.AddWindow(self.CloseButton) + + self.StatusLabel = wx.StaticText(panel, label= "") + controls_sizer.AddWindow(self.StatusLabel, flag=wx.ALIGN_CENTER_VERTICAL) panel.SetSizer(main_sizer) + main_sizer.Fit(self) self.ParentWindow = parent self.Bind(wx.EVT_CLOSE, self.OnCloseFrame) - + self.infosPrev = {} + self.criteria = {} self.FindPattern.SetFocus() self.RefreshButtonsState() @@ -132,17 +138,41 @@ self.Hide() event.Skip() + def OnEscapeKey(self, event): + keycode = event.GetKeyCode() + if keycode == wx.WXK_ESCAPE: + self.OnCloseButton(event) + else: + event.Skip() + def OnFindPatternChanged(self, event): self.RefreshButtonsState() event.Skip() + def SetStatusText(self, msg): + self.StatusLabel.SetLabel(msg) + self.Layout() + def OnFindButton(self, event): infos = { "find_pattern": self.FindPattern.GetValue(), "wrap": self.WrapSearch.GetValue(), "case_sensitive": self.CaseSensitive.GetValue(), - "regular_expression": self.RegularExpressions.GetValue()} - wx.CallAfter(self.ParentWindow.FindInPou, - {True: 1, False:-1}[self.Forward.GetValue()], - infos) + "regular_expression": self.RegularExpressions.GetValue(), + "filter": "all"} + + if self.infosPrev != infos: + self.infosPrev = infos + message = "" + try: + self.criteria = infos + CompilePattern(self.criteria) + except: + self.criteria.clear() + message = _("Syntax error in regular expression of pattern to search!") + self.SetStatusText(message) + if len(self.criteria) > 0: + wx.CallAfter(self.ParentWindow.FindInPou, + {True: 1, False:-1}[self.Forward.GetValue()], + self.criteria) event.Skip() diff -r 6431f26aa501 -r 3291024e00da dialogs/ForceVariableDialog.py --- a/dialogs/ForceVariableDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/ForceVariableDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,25 @@ # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re import datetime @@ -174,7 +174,7 @@ if value == "": message = _("You must type a value!") elif GetTypeValue[self.IEC_Type](value) is None: - message = _("Invalid value \"%s\" for \"%s\" variable!") % (value, self.IEC_Type) + message = _("Invalid value \"{a1}\" for \"{a2}\" variable!").format(a1 = value, a2 = self.IEC_Type) if message is not None: dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) dialog.ShowModal() diff -r 6431f26aa501 -r 3291024e00da dialogs/LDElementDialog.py --- a/dialogs/LDElementDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/LDElementDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/LDPowerRailDialog.py --- a/dialogs/LDPowerRailDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/LDPowerRailDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,26 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/PouActionDialog.py --- a/dialogs/PouActionDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/PouActionDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/PouDialog.py --- a/dialogs/PouDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/PouDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/PouNameDialog.py --- a/dialogs/PouNameDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/PouNameDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,26 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/PouTransitionDialog.py --- a/dialogs/PouTransitionDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/PouTransitionDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -32,7 +32,12 @@ def GetTransitionLanguages(): _ = lambda x : x - return [_("IL"), _("ST"), _("LD"), _("FBD")] + # + # IL language is temporary disabled because + # matiec freezes if transition is written in IL + # + # return [_("IL"), _("ST"), _("LD"), _("FBD")] + return [ _("ST"), _("LD"), _("FBD")] TRANSITION_LANGUAGES_DICT = dict([(_(language), language) for language in GetTransitionLanguages()]) class PouTransitionDialog(wx.Dialog): diff -r 6431f26aa501 -r 3291024e00da dialogs/ProjectDialog.py --- a/dialogs/ProjectDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/ProjectDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# This file is part of Beremiz, a Integrated Development Environment for +# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. # -#Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD +# Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/SFCDivergenceDialog.py --- a/dialogs/SFCDivergenceDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/SFCDivergenceDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,26 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -39,12 +40,13 @@ class SFCDivergenceDialog(BlockPreviewDialog): - def __init__(self, parent, controller, tagname): + def __init__(self, parent, controller, tagname, poss_div_types = None): """ Constructor @param parent: Parent wx.Window of dialog for modal @param controller: Reference to project controller @param tagname: Tagname of project POU edited + @param poss_div_types: Types of divergence that will be available in the dialog window """ BlockPreviewDialog.__init__(self, parent, controller, tagname, size=wx.Size(500, 300), @@ -58,19 +60,28 @@ self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW) # Create radio buttons for selecting divergence type + divergence_buttons = [ + (SELECTION_DIVERGENCE, _('Selection Divergence')), + (SELECTION_CONVERGENCE, _('Selection Convergence')), + (SIMULTANEOUS_DIVERGENCE, _('Simultaneous Divergence')), + (SIMULTANEOUS_CONVERGENCE, _('Simultaneous Convergence'))] + poss_div_btns = [] + if poss_div_types is not None: + for val in poss_div_types: + poss_div_btns.append(divergence_buttons[val]) + else: + poss_div_btns = divergence_buttons self.TypeRadioButtons = {} first = True - for type, label in [ - (SELECTION_DIVERGENCE, _('Selection Divergence')), - (SELECTION_CONVERGENCE, _('Selection Convergence')), - (SIMULTANEOUS_DIVERGENCE, _('Simultaneous Divergence')), - (SIMULTANEOUS_CONVERGENCE, _('Simultaneous Convergence'))]: + focusbtn = None + for type, label in poss_div_btns: radio_button = wx.RadioButton(self, label=label, style=(wx.RB_GROUP if first else 0)) radio_button.SetValue(first) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button) self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW) self.TypeRadioButtons[type] = radio_button + if first: focusbtn = type first = False # Create label for number of divergence sequences @@ -79,7 +90,7 @@ self.LeftGridSizer.AddWindow(sequences_label, flag=wx.GROW) # Create spin control for defining number of divergence sequences - self.Sequences = wx.SpinCtrl(self, min=2, max=20) + self.Sequences = wx.SpinCtrl(self, min=2, max=20, initial=2) self.Bind(wx.EVT_SPINCTRL, self.OnSequencesChanged, self.Sequences) self.LeftGridSizer.AddWindow(self.Sequences, flag=wx.GROW) @@ -93,7 +104,7 @@ # Selection divergence radio button is default control having keyboard # focus - self.TypeRadioButtons[SELECTION_DIVERGENCE].SetFocus() + self.TypeRadioButtons[focusbtn].SetFocus() def GetMinElementSize(self): """ @@ -151,4 +162,4 @@ # Call BlockPreviewDialog function BlockPreviewDialog.RefreshPreview(self) - \ No newline at end of file + diff -r 6431f26aa501 -r 3291024e00da dialogs/SFCStepDialog.py --- a/dialogs/SFCStepDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/SFCStepDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,26 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -70,6 +71,8 @@ ("output", _("Output")), ("action", _("Action"))]: check_box = wx.CheckBox(self, label=label) + if name == "output" or (name == "input" and not initial): + check_box.SetValue(True) self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, check_box) self.LeftGridSizer.AddWindow(check_box, flag=wx.GROW) self.ConnectorsCheckBox[name] = check_box diff -r 6431f26aa501 -r 3291024e00da dialogs/SFCStepNameDialog.py --- a/dialogs/SFCStepNameDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/SFCStepNameDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,26 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da dialogs/SFCTransitionDialog.py --- a/dialogs/SFCTransitionDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/SFCTransitionDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,25 +1,26 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -47,7 +48,7 @@ connection (default: True) """ BlockPreviewDialog.__init__(self, parent, controller, tagname, - size=wx.Size(350, 300), title=_('Edit transition')) + size=wx.Size(350, 350), title=_('Edit transition')) # Init common sizers self._init_sizers(2, 0, 8, None, 2, 1) diff -r 6431f26aa501 -r 3291024e00da dialogs/SearchInProjectDialog.py --- a/dialogs/SearchInProjectDialog.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/SearchInProjectDialog.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,39 +1,31 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re - +from plcopen.plcopen import * import wx -RE_ESCAPED_CHARACTERS = ".*+()[]?:|{}^$<>=-," - -def EscapeText(text): - text = text.replace('\\', '\\\\') - for c in RE_ESCAPED_CHARACTERS: - text = text.replace(c, '\\' + c) - return text - #------------------------------------------------------------------------------- # Search In Project Dialog #------------------------------------------------------------------------------- @@ -68,8 +60,9 @@ pattern_sizer.AddWindow(self.CaseSensitive, flag=wx.GROW) self.Pattern = wx.TextCtrl(self) + self.Bind(wx.EVT_TEXT, self.FindPatternChanged, self.Pattern) pattern_sizer.AddWindow(self.Pattern, flag=wx.GROW) - + self.Bind(wx.EVT_CHAR_HOOK, self.OnEscapeKey) self.RegularExpression = wx.CheckBox(self, label=_('Regular expression')) pattern_sizer.AddWindow(self.RegularExpression, flag=wx.GROW) @@ -99,58 +92,76 @@ self.ElementsList.Enable(False) scope_sizer.AddWindow(self.ElementsList, 1, border=5, flag=wx.GROW|wx.TOP|wx.RIGHT|wx.BOTTOM) - - self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - ok_button = self.ButtonSizer.GetAffirmativeButton() - ok_button.SetLabel(_('Search')) - self.Bind(wx.EVT_BUTTON, self.OnOK, ok_button) - main_sizer.AddSizer(self.ButtonSizer, border=20, - flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + buttons_sizer = wx.BoxSizer(wx.HORIZONTAL) + main_sizer.AddSizer(buttons_sizer, border=20, + flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_RIGHT) + + self.FindButton = wx.Button(self, label=_("Find")) + self.FindButton.SetDefault() + self.Bind(wx.EVT_BUTTON, self.OnFindButton, self.FindButton) + buttons_sizer.AddWindow(self.FindButton, border=5, flag=wx.RIGHT) + + self.CloseButton = wx.Button(self, label=_("Close")) + self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.CloseButton) + buttons_sizer.AddWindow(self.CloseButton) self.SetSizer(main_sizer) for name, label in GetElementsChoices(): self.ElementsList.Append(_(label)) - + self.infosPrev = {} + self.criteria = {} self.Pattern.SetFocus() + self.RefreshButtonsState() + + def RefreshButtonsState(self): + find_pattern = self.Pattern.GetValue() + self.FindButton.Enable(find_pattern != "") def GetCriteria(self): - raw_pattern = pattern = self.Pattern.GetValue() - if not self.CaseSensitive.GetValue(): - pattern = pattern.upper() - if not self.RegularExpression.GetValue(): - pattern = EscapeText(pattern) - criteria = { - "raw_pattern": raw_pattern, - "pattern": re.compile(pattern), + return self.criteria + + def FindPatternChanged(self, event): + self.RefreshButtonsState() + event.Skip() + + def OnScopeChanged(self, event): + self.ElementsList.Enable(self.OnlyElements.GetValue()) + event.Skip() + + def OnCloseButton(self, event): + self.EndModal(wx.ID_CANCEL) + + def OnEscapeKey(self, event): + keycode = event.GetKeyCode() + if keycode == wx.WXK_ESCAPE: + self.OnCloseButton(event) + else: + event.Skip() + + def OnFindButton(self, event): + message = None + infos = { + "find_pattern": self.Pattern.GetValue(), "case_sensitive": self.CaseSensitive.GetValue(), "regular_expression": self.RegularExpression.GetValue(), } if self.WholeProject.GetValue(): - criteria["filter"] = "all" + infos["filter"] = "all" elif self.OnlyElements.GetValue(): - criteria["filter"] = [] + infos["filter"] = [] for index, (name, label) in enumerate(GetElementsChoices()): if self.ElementsList.IsChecked(index): - criteria["filter"].append(name) - return criteria - - def OnScopeChanged(self, event): - self.ElementsList.Enable(self.OnlyElements.GetValue()) - event.Skip() - - def OnOK(self, event): - message = None - if self.Pattern.GetValue() == "": - message = _("Form isn't complete. Pattern to search must be filled!") - else: - wrong_pattern = False - if self.RegularExpression.GetValue(): - try: - re.compile(self.Pattern.GetValue()) - except: - wrong_pattern = True - if wrong_pattern: + infos["filter"].append(name) + + if self.infosPrev != infos: + try: + self.criteria = infos + CompilePattern(self.criteria) + self.infosPrev = infos + except: + self.criteria.clear() message = _("Syntax error in regular expression of pattern to search!") if message is not None: diff -r 6431f26aa501 -r 3291024e00da dialogs/__init__.py --- a/dialogs/__init__.py Thu Feb 16 14:34:40 2017 +0500 +++ b/dialogs/__init__.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,27 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + # Package initialization diff -r 6431f26aa501 -r 3291024e00da doc/about.html --- a/doc/about.html Thu Feb 16 14:34:40 2017 +0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ - - - -
- -

-Beremiz is an Open Source framework for automation. -

-http://www.beremiz.org/ -

- - - - - - - - -
- Contributor : - - University of Porto
- http://www.fe.up.pt/si/web_page.inicial -
-


- Beremiz is distrubuted under the term
of the - GNU - General Public License (GPL) version 2 or -
(at your option) any later version. -
-
- - diff -r 6431f26aa501 -r 3291024e00da doc/about.ru.html --- a/doc/about.ru.html Thu Feb 16 14:34:40 2017 +0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ - - - - О Beremiz - - -
- -

- Beremiz - это свободное программное обеспечение для автоматизации. -

- http://www.beremiz.org/ -

- - - - - - - - -
- Спонсор разработки: - - Университет Порту
- http://www.fe.up.pt/si/web_page.inicial -
-


- Beremiz распространяется на условиях
- Стандартной - общественной лицензии GNU (GPL) версии 2 -
или (на ваше усмотрение) более поздней версии. -
-
- - diff -r 6431f26aa501 -r 3291024e00da doc/plcopen_about.html --- a/doc/plcopen_about.html Thu Feb 16 14:34:40 2017 +0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ - - -
- -

-The PLCopen Editor saves and loads XML projects,
accordingly to PLCopen TC6-XML Schemes.
-

-More informations on : -http://www.beremiz.org/ -

-
- - \ No newline at end of file diff -r 6431f26aa501 -r 3291024e00da doc/plcopen_about.ru.html --- a/doc/plcopen_about.ru.html Thu Feb 16 14:34:40 2017 +0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ - - - О PLCOpen Editor - - -
- -

-PLCopen Editor сохраняет и загружает XML - проекты,
созданные согласно PLCopen TC6-XML схемам.
-

-За подробной информацией обращаться: -http://www.beremiz.org/ -

-
- - diff -r 6431f26aa501 -r 3291024e00da docutil/__init__.py --- a/docutil/__init__.py Thu Feb 16 14:34:40 2017 +0500 +++ b/docutil/__init__.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,27 +1,27 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from dochtml import * from docpdf import * -from docsvg import * \ No newline at end of file +from docsvg import * diff -r 6431f26aa501 -r 3291024e00da docutil/dochtml.py --- a/docutil/dochtml.py Thu Feb 16 14:34:40 2017 +0500 +++ b/docutil/dochtml.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx, os, wx.html, subprocess @@ -94,4 +94,4 @@ elif subprocess.call("firefox %s"%url, shell=True) != 0: wx.MessageBox("""Firefox browser not found.\nPlease point your browser at :\n%s""" % url) except ImportError: - wx.MessageBox('Please point your browser at: %s' % url) \ No newline at end of file + wx.MessageBox('Please point your browser at: %s' % url) diff -r 6431f26aa501 -r 3291024e00da docutil/docpdf.py --- a/docutil/docpdf.py Thu Feb 16 14:34:40 2017 +0500 +++ b/docutil/docpdf.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx, os @@ -53,7 +53,7 @@ if pagenum == None : os.system("%s -remote DS301 %s &"%(readerexepath, pdffile)) else: - print "Open pdf %s at page %d"%(pdffile, pagenum) + print "Open pdf %s at page %d"%(pdffile, pagenum) os.system("%s -remote DS301 %s %d &"%(readerexepath, pdffile, pagenum)) def open_pdf(pdffile, pagenum = None): diff -r 6431f26aa501 -r 3291024e00da docutil/docsvg.py --- a/docutil/docsvg.py Thu Feb 16 14:34:40 2017 +0500 +++ b/docutil/docsvg.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx, os, subprocess diff -r 6431f26aa501 -r 3291024e00da editors/CodeFileEditor.py --- a/editors/CodeFileEditor.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/CodeFileEditor.py Thu Feb 16 14:35:12 2017 +0500 @@ -506,17 +506,11 @@ self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) self.SearchParams = search_params - criteria = { - "raw_pattern": search_params["find_pattern"], - "pattern": re.compile(search_params["find_pattern"]), - "case_sensitive": search_params["case_sensitive"], - "regular_expression": search_params["regular_expression"], - "filter": "all"} self.SearchResults = [ (start, end, SEARCH_RESULT_HIGHLIGHT) for start, end, text in - TestTextElement(self.GetText(), criteria)] + TestTextElement(self.GetText(), search_params)] self.CurrentFindHighlight = None if len(self.SearchResults) > 0: diff -r 6431f26aa501 -r 3291024e00da editors/ConfTreeNodeEditor.py --- a/editors/ConfTreeNodeEditor.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/ConfTreeNodeEditor.py Thu Feb 16 14:35:12 2017 +0500 @@ -342,25 +342,20 @@ staticbox = wx.StaticBox(self.ParamsEditor, label=_(label), size=wx.Size(10, 0)) staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL) + flags = (wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT) if first: - sizer.AddSizer(staticboxsizer, border=5, - flag=wx.GROW|wx.TOP|wx.BOTTOM) - else: - sizer.AddSizer(staticboxsizer, border=5, - flag=wx.GROW|wx.BOTTOM) + flags |= wx.TOP + sizer.AddSizer(staticboxsizer, border=5, flag=flags) self.GenerateSizerElements(staticboxsizer, element_infos["children"], element_path) else: boxsizer = wx.FlexGridSizer(cols=3, rows=1) boxsizer.AddGrowableCol(1) + flags = (wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT) if first: - sizer.AddSizer(boxsizer, border=5, - flag=wx.GROW|wx.ALL) - else: - sizer.AddSizer(boxsizer, border=5, - flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM) - + flags |= wx.TOP + sizer.AddSizer(boxsizer, border=5, flag=flags) staticbitmap = GenStaticBitmap(ID=-1, bitmapname=element_infos["name"], name="%s_bitmap"%element_infos["name"], parent=self.ParamsEditor, pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0) @@ -408,7 +403,7 @@ staticbox = wx.StaticBox(self.ParamsEditor, label="%s - %s"%(_(name), _(value)), size=wx.Size(10, 0)) staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL) - sizer.AddSizer(staticboxsizer, border=5, flag=wx.GROW|wx.BOTTOM) + sizer.AddSizer(staticboxsizer, border=5, flag=wx.GROW | wx.BOTTOM | wx.LEFT | wx.RIGHT) self.GenerateSizerElements(staticboxsizer, element_infos["children"], element_path) callback = self.GetChoiceContentCallBackFunction(combobox, staticboxsizer, element_path) else: @@ -479,6 +474,8 @@ textctrl.Bind(wx.EVT_TEXT_ENTER, callback) textctrl.Bind(wx.EVT_KILL_FOCUS, callback) first = False + sizer.Layout() + self.RefreshScrollbars() def GetItemChannelChangedFunction(self, dir): diff -r 6431f26aa501 -r 3291024e00da editors/DataTypeEditor.py --- a/editors/DataTypeEditor.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/DataTypeEditor.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re from types import TupleType diff -r 6431f26aa501 -r 3291024e00da editors/DebugViewer.py --- a/editors/DebugViewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/DebugViewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from threading import Lock, Timer from time import time as gettime diff -r 6431f26aa501 -r 3291024e00da editors/EditorPanel.py --- a/editors/EditorPanel.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/EditorPanel.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -79,7 +79,7 @@ self.ParentWindow.EditProjectElement(None, self.GetTagName(), True) def GetTitle(self): - return "-".join(self.TagName.split("::")[1:]) + return ".".join(self.TagName.split("::")[1:]) def GetIcon(self): return self.Icon diff -r 6431f26aa501 -r 3291024e00da editors/FileManagementPanel.py --- a/editors/FileManagementPanel.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/FileManagementPanel.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import os import shutil @@ -211,4 +211,4 @@ dragSource = wx.DropSource(self) dragSource.SetData(data) dragSource.DoDragDrop() - \ No newline at end of file + diff -r 6431f26aa501 -r 3291024e00da editors/LDViewer.py --- a/editors/LDViewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/LDViewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import time diff -r 6431f26aa501 -r 3291024e00da editors/ResourceEditor.py --- a/editors/ResourceEditor.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/ResourceEditor.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx import wx.lib.buttons @@ -434,17 +434,18 @@ def OnTasksGridCellChange(self, event): row, col = event.GetRow(), event.GetCol() - if self.TasksTable.GetColLabelValue(col) == "Name": + if self.TasksTable.GetColLabelValue(col, False) == "Name": tasklist = [name for name in self.TaskList.split(",") if name != ""] for i in xrange(self.TasksTable.GetNumberRows()): task = self.TasksTable.GetValueByName(i, "Name") if task in tasklist: tasklist.remove(task) if len(tasklist) > 0: - old_name = tasklist[0] + old_name = tasklist[0].upper() new_name = self.TasksTable.GetValue(row, col) for i in xrange(self.InstancesTable.GetNumberRows()): - if self.InstancesTable.GetValueByName(i, "Task") == old_name: + name = self.InstancesTable.GetValueByName(i, "Task").upper() + if old_name == name: self.InstancesTable.SetValueByName(i, "Task", new_name) self.RefreshModel() colname = self.TasksTable.GetColLabelValue(col, False) diff -r 6431f26aa501 -r 3291024e00da editors/SFCViewer.py --- a/editors/SFCViewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/SFCViewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,35 +1,87 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from types import * import wx from Viewer import * +from graphics.SFC_Objects import * +from graphics.GraphicCommons import SELECTION_DIVERGENCE, \ + SELECTION_CONVERGENCE, SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE, EAST, NORTH, WEST, SOUTH + +SFC_Objects = (SFC_Step, SFC_ActionBlock, SFC_Transition, SFC_Divergence, SFC_Jump) + class SFC_Viewer(Viewer): + SFC_StandardRules = { + # The key of this dict is a block that user try to connect, + # and the value is a list of blocks, that can be connected with the current block + # and with directions of connection + "SFC_Step": [("SFC_ActionBlock", EAST), + ("SFC_Transition", SOUTH), + (SELECTION_DIVERGENCE, SOUTH), + (SIMULTANEOUS_CONVERGENCE, SOUTH)], + + "SFC_ActionBlock": [("SFC_Step", EAST)], + + "SFC_Transition": [("SFC_Step", SOUTH), + (SELECTION_CONVERGENCE, SOUTH), + (SIMULTANEOUS_DIVERGENCE, SOUTH), + ("SFC_Jump", SOUTH), + ("FBD_Block", EAST), + ("FBD_Variable", EAST), + ("FBD_Connector", EAST), + ("LD_Contact", EAST), + ("LD_PowerRail", EAST), + ("LD_Coil", EAST)], + + SELECTION_DIVERGENCE: [("SFC_Transition", SOUTH)], + + SELECTION_CONVERGENCE: [("SFC_Step", SOUTH), + ("SFC_Jump", SOUTH)], + + SIMULTANEOUS_DIVERGENCE: [("SFC_Step", SOUTH)], + + SIMULTANEOUS_CONVERGENCE: [("SFC_Transition", SOUTH)], + + "SFC_Jump": [], + + "FBD_Block": [("SFC_Transition", WEST)], + + "FBD_Variable": [("SFC_Transition", WEST)], + + "FBD_Connector": [("SFC_Transition", WEST)], + + "LD_Contact": [("SFC_Transition", WEST)], + + "LD_PowerRail": [("SFC_Transition", WEST)], + + "LD_Coil": [("SFC_Transition", WEST)] + } + def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""): Viewer.__init__(self, parent, tagname, window, controler, debug, instancepath) self.CurrentLanguage = "SFC" @@ -282,6 +334,28 @@ self.UpdateScrollPos(event) event.Skip() + def GetBlockName(self, block): + blockName = block.__class__.__name__ + if blockName == "SFC_Divergence": + blockName = block.Type + return blockName + + # This method check the IEC 61131-3 compatibility between two SFC blocks + def BlockCompatibility(self,startblock = None, endblock = None, direction = None): + if startblock!= None and endblock != None and (isinstance(startblock,SFC_Objects)\ + or isinstance(endblock,SFC_Objects)): + # Full "SFC_StandardRules" table would be symmetrical and + # to avoid duplicate records and minimize the table only upper part is defined. + if (direction == SOUTH or direction == EAST): + startblock, endblock = endblock, startblock + start = self.GetBlockName(startblock) + end = self.GetBlockName(endblock) + for val in self.SFC_StandardRules[start]: + if end in val: + return True + return False + return True + #------------------------------------------------------------------------------- # Keyboard event functions #------------------------------------------------------------------------------- diff -r 6431f26aa501 -r 3291024e00da editors/TextViewer.py --- a/editors/TextViewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/TextViewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re from types import * @@ -289,7 +289,7 @@ dlg = wx.TextEntryDialog( self.ParentWindow, _("Confirm or change variable name"), - 'Variable Drop', var_name) + _('Variable Drop'), var_name) dlg.SetValue(var_name) var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None dlg.Destroy() @@ -304,7 +304,7 @@ if not location.startswith("%"): dialog = wx.SingleChoiceDialog(self.ParentWindow, _("Select a variable class:"), _("Variable class"), - ["Input", "Output", "Memory"], + [_("Input"), _("Output"), _("Memory")], wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: selected = dialog.GetSelection() @@ -340,7 +340,7 @@ dlg = wx.TextEntryDialog( self.ParentWindow, _("Confirm or change variable name"), - 'Variable Drop', var_name) + _('Variable Drop'), var_name) dlg.SetValue(var_name) var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None dlg.Destroy() @@ -363,7 +363,7 @@ dlg = wx.TextEntryDialog( self.ParentWindow, _("Confirm or change variable name"), - 'Variable Drop', var_name) + _('Variable Drop'), var_name) dlg.SetValue(var_name) var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None dlg.Destroy() @@ -414,7 +414,7 @@ self.Colourise(0, -1) def RefreshJumpList(self): - if self.TextSyntax != "IL": + if self.TextSyntax == "IL": self.Jumps = [jump.upper() for jump in LABEL_MODEL.findall(self.GetText())] self.Colourise(0, -1) @@ -629,6 +629,10 @@ self.SetStyling(current_pos - last_styled_pos + 2, STC_PLC_COMMENT) last_styled_pos = current_pos + 1 state = SPACE + if len(self.CallStack) > 0: + current_call = self.CallStack.pop() + else: + current_call = None elif state == PRAGMA: if line.endswith("}"): self.SetStyling(current_pos - last_styled_pos, STC_PLC_EMPTY) @@ -806,17 +810,10 @@ self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) self.SearchParams = search_params - criteria = { - "raw_pattern": search_params["find_pattern"], - "pattern": re.compile(search_params["find_pattern"]), - "case_sensitive": search_params["case_sensitive"], - "regular_expression": search_params["regular_expression"], - "filter": "all"} - self.SearchResults = [ (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT) for infos, start, end, text in - self.Search(criteria)] + self.Search(search_params)] self.CurrentFindHighlight = None if len(self.SearchResults) > 0: @@ -897,14 +894,15 @@ key_handled = True elif key == wx.WXK_BACK: if self.TextSyntax in ["ST", "ALL"]: - indent = self.Editor.GetLineIndentation(line) - if lineText.strip() == "" and indent > 0: - self.Editor.DelLineLeft() - self.Editor.AddText(" " * ((max(0, indent - 1) / 2) * 2)) - key_handled = True + if not self.Editor.GetSelectedText(): + indent = self.Editor.GetColumn(self.Editor.GetCurrentPos()) + if lineText.strip() == "" and len(lineText) > 0 and indent > 0: + self.Editor.DelLineLeft() + self.Editor.AddText(" " * ((max(0, indent - 1) / 2) * 2)) + key_handled = True if not key_handled: event.Skip() - elif key in NAVIGATION_KEYS: + else: event.Skip() def OnKillFocus(self, event): diff -r 6431f26aa501 -r 3291024e00da editors/Viewer.py --- a/editors/Viewer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/editors/Viewer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import re import math @@ -43,6 +43,7 @@ SCROLL_ZONE = 10 CURSORS = None +SFC_Objects = (SFC_Step, SFC_ActionBlock, SFC_Transition, SFC_Divergence, SFC_Jump) def ResetCursors(): global CURSORS @@ -146,6 +147,9 @@ specific_values.priority, id) return transition +divergence_types = [SELECTION_DIVERGENCE, + SELECTION_CONVERGENCE, SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE] + def GetDivergenceCreationFunction(divergence_type): def divergenceCreationFunction(viewer, id, specific_values): return SFC_Divergence(viewer, divergence_type, @@ -243,7 +247,7 @@ elif pou_type == "function" and values[1] != "function": message = _("Function Blocks can't be used in Functions!") elif self.ParentWindow.Controler.PouIsUsedBy(pou_name, values[0], self.ParentWindow.Debug): - message = _("\"%s\" is already used by \"%s\"!")%(pou_name, values[0]) + message = _("\"{a1}\" is already used by \"{a2}\"!").format(a1 = pou_name, a2 = values[0]) else: blockname = values[2] if len(values) > 3: @@ -282,7 +286,7 @@ if not location.startswith("%"): dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow, _("Select a variable class:"), _("Variable class"), - ["Input", "Output", "Memory"], + [_("Input"), _("Output"), _("Memory")], wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: selected = dialog.GetSelection() @@ -301,7 +305,7 @@ dlg = wx.TextEntryDialog( self.ParentWindow.ParentWindow, _("Confirm or change variable name"), - 'Variable Drop', var_name) + _('Variable Drop'), var_name) dlg.SetValue(var_name) var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None dlg.Destroy() @@ -331,7 +335,7 @@ dlg = wx.TextEntryDialog( self.ParentWindow.ParentWindow, _("Confirm or change variable name"), - 'Variable Drop', var_name) + _('Variable Drop'), var_name) dlg.SetValue(var_name) var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None dlg.Destroy() @@ -353,7 +357,7 @@ dlg = wx.TextEntryDialog( self.ParentWindow.ParentWindow, _("Confirm or change variable name"), - 'Variable Drop', var_name) + _('Variable Drop'), var_name) dlg.SetValue(var_name) var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None dlg.Destroy() @@ -573,11 +577,11 @@ [ID_CLEAR_EXEC_ORDER, ID_RESET_EXEC_ORDER] = [wx.NewId() for i in xrange(2)] # Create menu items - self.AddMenuItems(menu, [ - (ID_CLEAR_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Clear Execution Order'), '', self.OnClearExecutionOrderMenu), - (ID_RESET_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Reset Execution Order'), '', self.OnResetExecutionOrderMenu)]) - - menu.AppendSeparator() + if self.CurrentLanguage == 'FBD': + self.AddMenuItems(menu, [ + (ID_CLEAR_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Clear Execution Order'), '', self.OnClearExecutionOrderMenu), + (ID_RESET_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Reset Execution Order'), '', self.OnResetExecutionOrderMenu)]) + menu.AppendSeparator() add_menu = wx.Menu(title='') self.AddAddMenuItems(add_menu) @@ -883,6 +887,15 @@ comments.sort(lambda x, y: cmp(x.GetId(), y.GetId())) return blocks + wires + comments + def GetContinuationByName(self, name): + blocks = [] + for block in self.Blocks.itervalues(): + if isinstance(block, FBD_Connector) and\ + block.GetType() == CONTINUATION and\ + block.GetName() == name: + blocks.append(block) + return blocks + def GetConnectorByName(self, name): for block in self.Blocks.itervalues(): if isinstance(block, FBD_Connector) and\ @@ -959,6 +972,16 @@ return connector.GetEdge() return "none" + def CorrectElementSize(self, element, width, height): + min_width, min_height = element.GetMinSize() + if width < min_width: + width = min_width + if height < min_height: + height = min_height + if element.Size != (width, height): + element.SetSize(width, height) + element.RefreshModel() + #------------------------------------------------------------------------------- # Reset functions #------------------------------------------------------------------------------- @@ -1371,6 +1394,7 @@ if not self.CreateWires(connector, instance.id, input_connector.links, remaining_instances, selection): element.RefreshModel() element.RefreshConnectors() + self.CorrectElementSize(element, instance.width, instance.height) if selection is not None and selection[0].get(instance.id, False): self.SelectInGroup(element) @@ -1462,12 +1486,24 @@ return None def FindBlockConnector(self, pos, direction = None, exclude = None): + result, error = self.FindBlockConnectorWithError(pos, direction, exclude) + return result + + def FindBlockConnectorWithError(self, pos, direction = None, exclude = None): + error = False + startblock = None for block in self.Blocks.itervalues(): - result = block.TestConnector(pos, direction, exclude) - if result: - return result - return None - + connector = block.TestConnector(pos, direction, exclude) + if connector: + if self.IsWire(self.SelectedElement): + startblock = self.SelectedElement.StartConnected.GetParentBlock() + avail, error = connector.ConnectionAvailable(direction, exclude) + if not avail or not self.BlockCompatibility(startblock, block, direction): + connector = None + error = True + return connector, error + return None, error + def FindElementById(self, id): block = self.Blocks.get(id, None) if block is not None: @@ -2048,47 +2084,7 @@ self.SelectedElement.HighlightPoint(pos) self.RefreshBuffer() elif connector is None or self.SelectedElement.GetDragging(): - start_connector = self.SelectedElement.GetStartConnected() - start_direction = start_connector.GetDirection() - - items = [] - - if self.CurrentLanguage == "SFC" and start_direction == SOUTH: - items.extend([ - (_(u'Initial Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, True)), - (_(u'Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, False)), - (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, False)), - (_(u'Divergence'), self.GetAddToWireMenuCallBack(self.AddNewDivergence)), - (_(u'Jump'), self.GetAddToWireMenuCallBack(self.AddNewJump)), - ]) - - elif start_direction == EAST: - - if isinstance(start_connector.GetParentBlock(), SFC_Step): - items.append( - (_(u'Action Block'), self.GetAddToWireMenuCallBack(self.AddNewActionBlock)) - ) - else: - items.extend([ - (_(u'Block'), self.GetAddToWireMenuCallBack(self.AddNewBlock)), - (_(u'Variable'), self.GetAddToWireMenuCallBack(self.AddNewVariable, True)), - (_(u'Connection'), self.GetAddToWireMenuCallBack(self.AddNewConnection)), - ]) - - if self.CurrentLanguage != "FBD": - items.append( - (_(u'Contact'), self.GetAddToWireMenuCallBack(self.AddNewContact)) - ) - if self.CurrentLanguage == "LD": - items.extend([ - (_(u'Coil'), self.GetAddToWireMenuCallBack(self.AddNewCoil)), - (_(u'Power Rail'), self.GetAddToWireMenuCallBack(self.AddNewPowerRail)), - ]) - if self.CurrentLanguage == "SFC": - items.append( - (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, True)) - ) - + items = self.GetPopupMenuItems() if len(items) > 0: if self.Editor.HasCapture(): self.Editor.ReleaseMouse() @@ -2273,7 +2269,8 @@ self.rubberBand.OnMotion(event, dc, self.Scaling) elif not self.Debug and self.Mode == MODE_SELECTION and self.SelectedElement is not None: if self.DrawingWire: - connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection(), self.SelectedElement.EndConnected) + connector, errorHighlight = self.FindBlockConnectorWithError(pos, self.SelectedElement.GetConnectionDirection(), self.SelectedElement.EndConnected) + self.SelectedElement.ErrHighlight = errorHighlight; if not connector or self.SelectedElement.EndConnected == None: self.SelectedElement.ResetPoints() movex, movey = self.SelectedElement.OnMotion(event, dc, self.Scaling) @@ -2340,6 +2337,54 @@ self.Scroll(xstart + move_window.x, ystart + move_window.y) self.RefreshScrollBars(move_window.x, move_window.y) + def BlockCompatibility(self, startblock=None, endblock=None, direction = None): + return True + + def GetPopupMenuItems(self): + start_connector = self.SelectedElement.GetStartConnected() + start_direction = start_connector.GetDirection() + startblock = start_connector.GetParentBlock() + items = [] + if isinstance(startblock, SFC_Objects): + startblockname = self.GetBlockName(startblock) + poss_div_types = [] + + SFC_WireMenu_Buttons = { + 'SFC_Step': (_(u'Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, False)), + 'SFC_Jump': (_(u'Jump'), self.GetAddToWireMenuCallBack(self.AddNewJump)), + 'SFC_Transition': (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, False)), + 'SFC_ActionBlock': (_(u'Action Block'), self.GetAddToWireMenuCallBack(self.AddNewActionBlock))} + + for endblock in self.SFC_StandardRules.get(startblockname): + if start_direction in endblock: + if endblock[0] in divergence_types: + poss_div_types.append(endblock[0]) + else: + items.append(SFC_WireMenu_Buttons[endblock[0]]) + if len(poss_div_types) > 0: + items.append((_(u'Divergence'), self.GetAddToWireMenuCallBack(self.AddNewDivergence, + poss_div_types))) + elif start_direction == EAST: + items.extend([ + (_(u'Block'), self.GetAddToWireMenuCallBack(self.AddNewBlock)), + (_(u'Connection'), self.GetAddToWireMenuCallBack(self.AddNewConnection))]) + + if self.CurrentLanguage != "FBD": + items.append((_(u'Contact'), self.GetAddToWireMenuCallBack(self.AddNewContact))) + + if self.CurrentLanguage == "LD": + items.extend([ + (_(u'Coil'), self.GetAddToWireMenuCallBack(self.AddNewCoil)), + (_(u'Power Rail'), self.GetAddToWireMenuCallBack(self.AddNewPowerRail))]) + + if self.CurrentLanguage == "SFC": + items.append( + (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, True))) + else: + items.append( + (_(u'Variable'), self.GetAddToWireMenuCallBack(self.AddNewVariable, True))) + return items + #------------------------------------------------------------------------------- # Keyboard event functions #------------------------------------------------------------------------------- @@ -2607,7 +2652,7 @@ "name": self.Controler.GenerateNewName( self.TagName, None, "Step%d", 0), "input": True, - "output": False, + "output": True, "action":False} else: dialog = SFCStepDialog(self.ParentWindow, self.Controler, self.TagName, initial) @@ -2651,8 +2696,8 @@ connector = transition.GetConnectors()["inputs"][0] self.AddNewElement(transition, bbox, wire, connector) - def AddNewDivergence(self, bbox, wire=None): - dialog = SFCDivergenceDialog(self.ParentWindow, self.Controler, self.TagName) + def AddNewDivergence(self, bbox, poss_div_types = None, wire=None): + dialog = SFCDivergenceDialog(self.ParentWindow, self.Controler, self.TagName, poss_div_types) dialog.SetPreviewFont(self.GetFont()) dialog.SetMinElementSize((bbox.width, bbox.height)) if dialog.ShowModal() == wx.ID_OK: @@ -2868,7 +2913,20 @@ if dialog.ShowModal() == wx.ID_OK: values = dialog.GetValues() rect = step.GetRedrawRect(1, 1) - step.SetName(values["name"]) + + new_name = values["name"] + if self.GetDrawingMode() == DRIVENDRAWING_MODE: + old_name = step.GetName().upper() + if new_name.upper() != old_name: + for block in self.Blocks.itervalues(): + if isinstance(block, SFC_Jump): + if old_name == block.GetTarget().upper(): + block.SetTarget(new_name) + block.RefreshModel() + rect = rect.Union(block.GetRedrawRect()) + block.Refresh(rect) + step.SetName(new_name) + if values["input"]: step.AddInput() else: @@ -2915,7 +2973,12 @@ dialog = wx.SingleChoiceDialog(self.ParentWindow, _("Edit jump target"), _("Please choose a target"), choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) - dialog.SetSelection(choices.index(jump.GetTarget())) + try: + indx = choices.index(jump.GetTarget()) + dialog.SetSelection(indx) + except ValueError: + pass + if dialog.ShowModal() == wx.ID_OK: value = dialog.GetStringSelection() rect = jump.GetRedrawRect(1, 1) @@ -3216,6 +3279,17 @@ if element not in elements: elements.append(element) step.Clean() + + if self.GetDrawingMode() == DRIVENDRAWING_MODE: + name = step.GetName().upper() + remove_jumps = [] + for block in self.Blocks.itervalues(): + if isinstance(block, SFC_Jump): + if name == block.GetTarget().upper(): + remove_jumps.append(block) + for jump in remove_jumps: + self.DeleteJump(jump) + self.RemoveBlock(step) self.Controler.RemoveEditedElementInstance(self.TagName, step.GetId()) for element in elements: @@ -3399,22 +3473,16 @@ self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) self.SearchParams = search_params - criteria = { - "raw_pattern": search_params["find_pattern"], - "pattern": re.compile(search_params["find_pattern"]), - "case_sensitive": search_params["case_sensitive"], - "regular_expression": search_params["regular_expression"], - "filter": "all"} - self.SearchResults = [] blocks = [] - for infos, start, end, text in self.Controler.SearchInPou(self.TagName, criteria, self.Debug): - if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: - self.SearchResults.append((infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)) - else: - block = self.Blocks.get(infos[2]) - if block is not None: - blocks.append((block, (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT))) + for infos, start, end, text in self.Controler.SearchInPou(self.TagName, search_params, self.Debug): + if (infos[0] == self.TagName or self.TagName.split("::")[0] in ['A', 'T']) and infos[1] is not 'name': + if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: + self.SearchResults.append((infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)) + else: + block = self.Blocks.get(infos[2]) + if block is not None: + blocks.append((block, (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT))) blocks.sort(sort_blocks) self.SearchResults.extend([infos for block, infos in blocks]) self.CurrentFindHighlight = None @@ -3592,13 +3660,16 @@ scalex, scaley = dc.GetUserScale() dc.SetUserScale(1, 1) - is_action = self.TagName.split("::")[0] == "A" + # is_action = self.TagName.split("::")[0] == "A" text = _("Debug: %s") % self.InstancePath - if is_action and self.Value is not None: - text += " (" + '''if is_action and self.Value is not None: + text += " ("''' text_offset_x, text_offset_y = self.CalcUnscrolledPosition(2, 2) dc.DrawText(text, text_offset_x, text_offset_y) - if is_action and self.Value is not None: + # TODO Fix self.Value in LD_Viewer instance. + # This code used to highlight with green color text in upper-left corner + # (path to current instance) in debug mode, if current instance active. Only SFC actions are affected. + '''if is_action and self.Value is not None: value_text = self.VALUE_TRANSLATION[self.Value] tw, th = dc.GetTextExtent(text) if self.Value: @@ -3607,7 +3678,7 @@ if self.Value: dc.SetTextForeground(wx.BLACK) vw, vh = dc.GetTextExtent(value_text) - dc.DrawText(")", text_offset_x + tw + vw + 2, text_offset_y) + dc.DrawText(")", text_offset_x + tw + vw + 2, text_offset_y)''' dc.SetUserScale(scalex, scaley) diff -r 6431f26aa501 -r 3291024e00da graphics/.cvsignore --- a/graphics/.cvsignore Thu Feb 16 14:34:40 2017 +0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -*.pyc diff -r 6431f26aa501 -r 3291024e00da graphics/DebugDataConsumer.py --- a/graphics/DebugDataConsumer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/graphics/DebugDataConsumer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. -# -#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 +# 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 program 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 +# of the License, or (at your option) any later version. +# +# This program 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 program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import datetime diff -r 6431f26aa501 -r 3291024e00da graphics/FBD_Objects.py --- a/graphics/FBD_Objects.py Thu Feb 16 14:34:40 2017 +0500 +++ b/graphics/FBD_Objects.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx @@ -902,7 +902,15 @@ else: connectors["outputs"].append(self.Connector) return connectors - + + def SpreadCurrent(self): + if self.Type == CONNECTOR: + continuations = self.Parent.GetContinuationByName(self.Name) + if continuations is not None: + value = self.Connector.ReceivingCurrent() + for cont in continuations: + cont.Connector.SpreadCurrent(value) + # Changes the variable type def SetType(self, type): if type != self.Type: diff -r 6431f26aa501 -r 3291024e00da graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Thu Feb 16 14:34:40 2017 +0500 +++ b/graphics/GraphicCommons.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx from math import * @@ -1351,19 +1351,35 @@ self.Edge = edge self.Negated = False + # assume that pointer is already inside of this connector + def ConnectionAvailable(self, direction=None, exclude=True): + wire_nums = len(self.Wires) + + connector_free = (wire_nums<= 0) + connector_max_used = ((wire_nums > 0) and self.OneConnected) + if (self.Parent.CurrentLanguage in ["SFC", "LD"]) and (self.Type == "BOOL"): + connector_max_used = False; + + # connector is available for new connection + connect = connector_free or not connector_max_used + return connect, connector_max_used + # Tests if the point given is near from the end point of this connector - def TestPoint(self, pt, direction = None, exclude = True): - parent_pos = self.ParentBlock.GetPosition() - if (not (len(self.Wires) > 0 and self.OneConnected and exclude) or self.Type == "BOOL")\ - and direction is None or self.Direction == direction: + def TestPoint(self, pt, direction=None, exclude=True): + inside = False; + check_point = (not exclude) and (direction is None or self.Direction == direction); + + if check_point: # Calculate a square around the end point of this connector + parent_pos = self.ParentBlock.GetPosition() x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE rect = wx.Rect(x, y, width, height) - return rect.InsideXY(pt.x, pt.y) - return False + inside = rect.InsideXY(pt.x, pt.y); + + return inside # Draws the highlightment of this element if it is highlighted def DrawHighlightment(self, dc): @@ -1551,6 +1567,7 @@ self.OverEnd = False self.ComputingType = False self.Font = parent.GetMiniFont() + self.ErrHighlight = False def GetDefinition(self): if self.StartConnected is not None and self.EndConnected is not None: @@ -2590,8 +2607,13 @@ def DrawHighlightment(self, dc): scalex, scaley = dc.GetUserScale() dc.SetUserScale(1, 1) - dc.SetPen(MiterPen(HIGHLIGHTCOLOR, (2 * scalex + 5))) - dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) + # If user trying to connect wire with wrong input, highlight will become red. + if self.ErrHighlight == True and not (self.EndConnected): + highlightcolor = wx.RED + else: + highlightcolor = HIGHLIGHTCOLOR + dc.SetPen(MiterPen(highlightcolor, (2 * scalex + 5))) + dc.SetBrush(wx.Brush(highlightcolor)) dc.SetLogicalFunction(wx.AND) # Draw the start and end points if they are not connected or the mouse is over them if len(self.Points) > 0 and (not self.StartConnected or self.OverStart): @@ -2873,10 +2895,15 @@ wx.Point(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1]), wx.Point(self.Pos.x, self.Pos.y + self.Size[1])] dc.DrawPolygon(polygon) + + # dc.SetBrush call is workaround for the issue with wx.PrinterDC + # with wxPython 3.0 on GNU/Linux (don't remove it) + dc.SetBrush(wx.WHITE_BRUSH) lines = [wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y), wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y + 10), wx.Point(self.Pos.x + self.Size[0], self.Pos.y + 10)] dc.DrawLines(lines) + # Draws the comment content y = self.Pos.y + 10 for idx, line in enumerate(self.Content.splitlines()): diff -r 6431f26aa501 -r 3291024e00da graphics/LD_Objects.py --- a/graphics/LD_Objects.py Thu Feb 16 14:34:40 2017 +0500 +++ b/graphics/LD_Objects.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da graphics/RubberBand.py --- a/graphics/RubberBand.py Thu Feb 16 14:34:40 2017 +0500 +++ b/graphics/RubberBand.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da graphics/SFC_Objects.py --- a/graphics/SFC_Objects.py Thu Feb 16 14:34:40 2017 +0500 +++ b/graphics/SFC_Objects.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da graphics/ToolTipProducer.py --- a/graphics/ToolTipProducer.py Thu Feb 16 14:34:40 2017 +0500 +++ b/graphics/ToolTipProducer.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import wx diff -r 6431f26aa501 -r 3291024e00da graphics/__init__.py --- a/graphics/__init__.py Thu Feb 16 14:34:40 2017 +0500 +++ b/graphics/__init__.py Thu Feb 16 14:35:12 2017 +0500 @@ -1,26 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor -#based on the plcopen standard. +# 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 +# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD # -#See COPYING file for copyrights details. +# 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 program 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 +# 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. +# This program 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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Package initialisation @@ -29,4 +29,4 @@ from LD_Objects import * from SFC_Objects import * from RubberBand import RubberBand -from DebugDataConsumer import DebugDataConsumer \ No newline at end of file +from DebugDataConsumer import DebugDataConsumer diff -r 6431f26aa501 -r 3291024e00da i18n/Beremiz_ru_RU.po --- a/i18n/Beremiz_ru_RU.po Thu Feb 16 14:34:40 2017 +0500 +++ b/i18n/Beremiz_ru_RU.po Thu Feb 16 14:35:12 2017 +0500 @@ -7,39 +7,17 @@ msgstr "" "Project-Id-Version: Beremiz\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-04-21 17:11+0300\n" -"PO-Revision-Date: 2016-04-21 17:22+0300\n" -"Last-Translator: \n" +"POT-Creation-Date: 2017-01-12 14:39+0300\n" +"PO-Revision-Date: 2017-01-12 14:41+0300\n" +"Last-Translator: Andrey Skvortsov \n" "Language-Team: Andrey Skvortsov \n" "Language: ru_RU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.7.1\n" - -#: ../PLCOpenEditor.py:396 -msgid "" -"\n" -"An error has occurred.\n" -"\n" -"Click OK to save an error report.\n" -"\n" -"Please be kind enough to send this file to:\n" -"edouard.tisserant@gmail.com\n" -"\n" -"Error:\n" -msgstr "" -"\n" -"Произошла ошибка.\n" -"\n" -"Нажмите OK, чтобы сохранить репорт об ошибке.\n" -"\n" -"Будьте так добры, пошлите этот файл:\n" -"edouard.tisserant@gmail.com\n" -"\n" -"Ошибка:\n" - -#: ../Beremiz.py:1155 +"X-Generator: Poedit 1.8.11\n" + +#: ../PLCOpenEditor.py:408 ../Beremiz.py:1191 #, python-format msgid "" "\n" @@ -49,399 +27,427 @@ "Please be kind enough to send this file to:\n" "beremiz-devel@lists.sourceforge.net\n" "\n" -"You should now restart Beremiz.\n" +"You should now restart program.\n" "\n" "Traceback:\n" msgstr "" "\n" -"Произошла невосстанавливаемая ошибка (bug). Отчет об ошибке сохранен:\n" +"Произошла невосстанавливаемая ошибка (bug). Отчет об ошибке сохранен в:\n" "(%s)\n" "\n" "Будьте добры, отправьте этот файл по адресу\n" "beremiz-devel@lists.sourceforge.net\n" "\n" -"Для дальнейшей работы перезапустите Beremiz.\n" +"Для дальнейшей работы перезапустите программу.\n" "\n" "Traceback:\n" #: ../controls/VariablePanel.py:72 msgid " External" -msgstr "Внешний" +msgstr " Внешний" #: ../controls/VariablePanel.py:71 msgid " InOut" -msgstr "Вход/Выход" +msgstr " Вход/Выход" #: ../controls/VariablePanel.py:71 msgid " Input" -msgstr "Вход" +msgstr " Вход" #: ../controls/VariablePanel.py:72 msgid " Local" -msgstr "Локальный" +msgstr " Локальный" #: ../controls/VariablePanel.py:71 msgid " Output" -msgstr "Выход" +msgstr " Выход" #: ../controls/VariablePanel.py:73 msgid " Temp" -msgstr "Временный" - -#: ../PLCOpenEditor.py:406 -msgid " : " -msgstr "" - -#: ../dialogs/PouTransitionDialog.py:94 ../dialogs/ProjectDialog.py:66 +msgstr " Временный" + +#: ../dialogs/PouTransitionDialog.py:99 ../dialogs/ProjectDialog.py:66 #: ../dialogs/PouActionDialog.py:91 ../dialogs/PouDialog.py:113 #, python-format msgid " and %s" msgstr "и %s" -#: ../ProjectController.py:1027 +#: ../ProjectController.py:1089 msgid " generation failed !\n" msgstr "неудачная генерация кода!\n" -#: ../plcopen/plcopen.py:883 +#: ../plcopen/plcopen.py:881 #, python-format msgid "\"%s\" Data Type doesn't exist !!!" msgstr "Тип данных \"%s\" не существует!!!" -#: ../plcopen/plcopen.py:901 +#: ../plcopen/plcopen.py:899 #, python-format msgid "\"%s\" POU already exists !!!" msgstr "POU \"%s\" уже существует!!!" -#: ../plcopen/plcopen.py:922 +#: ../plcopen/plcopen.py:920 #, python-format msgid "\"%s\" POU doesn't exist !!!" msgstr "POU \"%s\" не найден!!!" -#: ../editors/Viewer.py:242 +#: ../editors/Viewer.py:246 #, python-format msgid "\"%s\" can't use itself!" msgstr "\"%s\" не может использовать сам себя!!!" -#: ../IDEFrame.py:1615 ../IDEFrame.py:1634 +#: ../IDEFrame.py:1652 ../IDEFrame.py:1671 #, python-format msgid "\"%s\" config already exists!" msgstr "Конфигурация \"%s\" уже существует!!!" -#: ../plcopen/plcopen.py:471 +#: ../plcopen/plcopen.py:467 #, python-format msgid "\"%s\" configuration already exists !!!" msgstr "Конфигурация \"%s\" уже существует!!!" -#: ../IDEFrame.py:1569 +#: ../IDEFrame.py:1602 #, python-format msgid "\"%s\" data type already exists!" msgstr "Тип данных \"%s\" уже существует!!!" -#: ../dialogs/PouTransitionDialog.py:105 ../dialogs/BlockPreviewDialog.py:219 -#: ../dialogs/PouActionDialog.py:102 ../editors/Viewer.py:258 -#: ../editors/Viewer.py:326 ../editors/Viewer.py:350 ../editors/Viewer.py:370 -#: ../editors/TextViewer.py:270 ../editors/TextViewer.py:299 -#: ../controls/VariablePanel.py:386 +#: ../dialogs/PouTransitionDialog.py:110 ../dialogs/BlockPreviewDialog.py:219 +#: ../dialogs/PouActionDialog.py:102 ../editors/Viewer.py:262 +#: ../editors/Viewer.py:330 ../editors/Viewer.py:354 ../editors/Viewer.py:374 +#: ../editors/TextViewer.py:272 ../editors/TextViewer.py:301 +#: ../controls/VariablePanel.py:396 #, python-format msgid "\"%s\" element for this pou already exists!" msgstr "Элемент с именем \"%s\" уже существует в этом POU!!!" -#: ../Beremiz.py:962 +#: ../Beremiz.py:994 #, python-format msgid "\"%s\" folder is not a valid Beremiz project\n" msgstr "Директория \"%s\" не является проектом Beremiz\n" -#: ../PLCGenerator.py:1091 -#, python-format -msgid "\"%s\" function cancelled in \"%s\" POU: No input connected" -msgstr "Функция \"%s\" не используется в POU \"%s\": входы не подключены" - -#: ../dialogs/SFCStepNameDialog.py:51 ../dialogs/PouTransitionDialog.py:101 -#: ../dialogs/BlockPreviewDialog.py:207 ../dialogs/PouNameDialog.py:49 +#: ../dialogs/SFCStepNameDialog.py:52 ../dialogs/PouTransitionDialog.py:106 +#: ../dialogs/BlockPreviewDialog.py:207 ../dialogs/PouNameDialog.py:50 #: ../dialogs/PouActionDialog.py:98 ../dialogs/PouDialog.py:120 -#: ../editors/DataTypeEditor.py:554 ../editors/DataTypeEditor.py:583 -#: ../editors/CodeFileEditor.py:750 ../controls/VariablePanel.py:733 -#: ../IDEFrame.py:1560 +#: ../editors/DataTypeEditor.py:555 ../editors/DataTypeEditor.py:584 +#: ../editors/CodeFileEditor.py:770 ../controls/VariablePanel.py:751 +#: ../IDEFrame.py:1593 #, python-format msgid "\"%s\" is a keyword. It can't be used!" msgstr "\"%s\" является ключевым словом и не может быть использован!" -#: ../editors/Viewer.py:246 -#, python-format -msgid "\"%s\" is already used by \"%s\"!" -msgstr "\"%s\" уже используется \"%s\"!" - -#: ../plcopen/plcopen.py:2405 +#: ../plcopen/plcopen.py:2412 #, python-format msgid "\"%s\" is an invalid value!" msgstr "\"%s\" недопустимое значение!" -#: ../PLCOpenEditor.py:332 ../PLCOpenEditor.py:369 +#: ../PLCOpenEditor.py:339 ../PLCOpenEditor.py:381 #, python-format msgid "\"%s\" is not a valid folder!" msgstr "\"%s\" не является директорией!" -#: ../dialogs/SFCStepNameDialog.py:49 ../dialogs/PouTransitionDialog.py:99 -#: ../dialogs/BlockPreviewDialog.py:203 ../dialogs/PouNameDialog.py:47 +#: ../dialogs/SFCStepNameDialog.py:50 ../dialogs/PouTransitionDialog.py:104 +#: ../dialogs/BlockPreviewDialog.py:203 ../dialogs/PouNameDialog.py:48 #: ../dialogs/PouActionDialog.py:96 ../dialogs/PouDialog.py:118 -#: ../editors/DataTypeEditor.py:578 ../editors/CodeFileEditor.py:748 -#: ../controls/VariablePanel.py:731 ../IDEFrame.py:1558 +#: ../editors/DataTypeEditor.py:579 ../editors/CodeFileEditor.py:768 +#: ../controls/VariablePanel.py:749 ../IDEFrame.py:1591 #, python-format msgid "\"%s\" is not a valid identifier!" msgstr "\"%s\" неверный идентификатор!" -#: ../IDEFrame.py:2362 +#: ../IDEFrame.py:2396 #, python-format msgid "\"%s\" is used by one or more POUs. Do you wish to continue?" msgstr "\"%s\" используется более чем одним POU. Продолжить?" #: ../dialogs/BlockPreviewDialog.py:211 ../dialogs/PouDialog.py:122 -#: ../editors/Viewer.py:256 ../editors/Viewer.py:311 ../editors/Viewer.py:341 -#: ../editors/Viewer.py:363 ../editors/TextViewer.py:268 -#: ../editors/TextViewer.py:297 ../editors/TextViewer.py:348 -#: ../editors/TextViewer.py:371 ../controls/VariablePanel.py:328 -#: ../IDEFrame.py:1578 +#: ../editors/Viewer.py:260 ../editors/Viewer.py:315 ../editors/Viewer.py:345 +#: ../editors/Viewer.py:367 ../editors/TextViewer.py:270 +#: ../editors/TextViewer.py:299 ../editors/TextViewer.py:350 +#: ../editors/TextViewer.py:373 ../controls/VariablePanel.py:338 +#: ../IDEFrame.py:1611 #, python-format msgid "\"%s\" pou already exists!" msgstr "POU \"%s\" уже существует!" -#: ../plcopen/plcopen.py:495 -#, python-format -msgid "\"%s\" resource already exists in \"%s\" configuration !!!" -msgstr "Ресурс \"%s\" уже существует в конфигурации \"%s\"!!!" - -#: ../plcopen/plcopen.py:512 -#, python-format -msgid "\"%s\" resource doesn't exist in \"%s\" configuration !!!" -msgstr "Ресурс \"%s\" отсутствует в конфигурации \"%s\"!!!" - -#: ../dialogs/SFCStepNameDialog.py:57 +#: ../dialogs/SFCStepNameDialog.py:58 #, python-format msgid "\"%s\" step already exists!" msgstr "Шаг \"%s\" уже существует!" -#: ../editors/DataTypeEditor.py:549 +#: ../editors/DataTypeEditor.py:550 #, python-format msgid "\"%s\" value already defined!" msgstr "\"%s\" значение уже задано!" -#: ../dialogs/ArrayTypeDialog.py:97 ../editors/DataTypeEditor.py:744 +#: ../dialogs/ArrayTypeDialog.py:97 ../editors/DataTypeEditor.py:745 #, python-format msgid "\"%s\" value isn't a valid array dimension!" msgstr "\"%s\" не является корректной размерностью для массива! " -#: ../dialogs/ArrayTypeDialog.py:103 ../editors/DataTypeEditor.py:751 +#: ../dialogs/ArrayTypeDialog.py:103 ../editors/DataTypeEditor.py:752 #, python-format msgid "" "\"%s\" value isn't a valid array dimension!\n" "Right value must be greater than left value." msgstr "\"%s\" не является корректной размерностью массива! Правое значение должно быть больше левого." -#: ../editors/CodeFileEditor.py:663 -msgid "#" -msgstr "" +#: ../PLCGenerator.py:1101 +#, python-brace-format +msgid "\"{a1}\" function cancelled in \"{a2}\" POU: No input connected" +msgstr "Функция \"{a1}\" не используется в POU \"{a2}\": входы не подключены" + +#: ../editors/Viewer.py:250 +#, python-brace-format +msgid "\"{a1}\" is already used by \"{a2}\"!" +msgstr "\"{a1}\" уже используется \"{a2}\"!" + +#: ../plcopen/plcopen.py:491 +#, python-brace-format +msgid "\"{a1}\" resource already exists in \"{a2}\" configuration !!!" +msgstr "Ресурс \"{a1}\" уже существует в конфигурации \"{a2}\"!!!" + +#: ../plcopen/plcopen.py:509 +#, python-brace-format +msgid "\"{a1}\" resource doesn't exist in \"{a2}\" configuration !!!" +msgstr "Ресурс \"{a1}\" отсутствует в конфигурации \"{a2}\"!!!" msgid "%(codefile_name)s" msgstr "%(codefile_name)" -#: ../PLCControler.py:970 -#, python-format -msgid "%s \"%s\" can't be pasted as a %s." -msgstr "%s \"%s\" не может быть вставлен как %s." - -#: ../PLCControler.py:1530 +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:578 +#, python-format +msgid "%03gms" +msgstr "%03gмс" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:569 +#, python-format +msgid "%dd" +msgstr "%dд" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:56 +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:570 +#, python-format +msgid "%dh" +msgstr "%dч" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:55 +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:571 +#, python-format +msgid "%dm" +msgstr "%dм" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:53 +#, python-format +msgid "%dms" +msgstr "%dмс" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:54 +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:572 +#, python-format +msgid "%ds" +msgstr "%dc" + +#: ../PLCControler.py:1531 #, python-format msgid "%s Data Types" msgstr "%s типы данных" -#: ../PLCControler.py:1513 +#: ../PLCControler.py:1514 #, python-format msgid "%s POUs" msgstr "%s POU" -#: ../canfestival/SlaveEditor.py:46 ../canfestival/NetworkEditor.py:67 +#: ../canfestival/SlaveEditor.py:69 ../canfestival/NetworkEditor.py:90 #, python-format msgid "%s Profile" msgstr "%s профиль" -#: ../ConfigTreeNode.py:32 -#, python-format -msgid "" -"%s XML file doesn't follow XSD schema at line %d:\n" -"%s" -msgstr "" -"%s XML файл не следует XSD-схеме в строке %d:\n" -"%s" - -#: ../plcopen/plcopen.py:1638 ../plcopen/plcopen.py:1645 -#: ../plcopen/plcopen.py:1657 ../plcopen/plcopen.py:1665 -#: ../plcopen/plcopen.py:1675 +#: ../plcopen/plcopen.py:1645 ../plcopen/plcopen.py:1652 +#: ../plcopen/plcopen.py:1664 ../plcopen/plcopen.py:1672 +#: ../plcopen/plcopen.py:1682 #, python-format msgid "%s body don't have instances!" msgstr "Тело %s не содержит экземпляров!" -#: ../plcopen/plcopen.py:1693 ../plcopen/plcopen.py:1700 -#: ../plcopen/plcopen.py:1707 +#: ../plcopen/plcopen.py:1700 ../plcopen/plcopen.py:1707 +#: ../plcopen/plcopen.py:1714 #, python-format msgid "%s body don't have text!" msgstr "Тело %s не содержит никакой текст!" -#: ../IDEFrame.py:362 +#: ../IDEFrame.py:386 msgid "&Add Element" msgstr "&Добавить элемент" -#: ../IDEFrame.py:332 +#: ../dialogs/AboutDialog.py:65 ../dialogs/AboutDialog.py:113 +#: ../dialogs/AboutDialog.py:150 +msgid "&Close" +msgstr "&Закрыть" + +#: ../IDEFrame.py:356 msgid "&Configuration" msgstr "&Конфигурация" -#: ../IDEFrame.py:321 +#: ../IDEFrame.py:345 msgid "&Data Type" msgstr "&Типы данных" -#: ../IDEFrame.py:366 +#: ../IDEFrame.py:390 msgid "&Delete" msgstr "&Удалить" -#: ../IDEFrame.py:313 +#: ../IDEFrame.py:337 msgid "&Display" msgstr "&Вид" -#: ../IDEFrame.py:312 +#: ../IDEFrame.py:336 msgid "&Edit" msgstr "&Редактировать" -#: ../IDEFrame.py:311 +#: ../IDEFrame.py:335 msgid "&File" msgstr "&Файл" -#: ../IDEFrame.py:323 +#: ../IDEFrame.py:347 msgid "&Function" msgstr "&Функции" -#: ../IDEFrame.py:314 +#: ../IDEFrame.py:338 msgid "&Help" msgstr "&Помощь" -#: ../IDEFrame.py:327 +#: ../dialogs/AboutDialog.py:64 +msgid "&License" +msgstr "&Лицензия" + +#: ../IDEFrame.py:351 msgid "&Program" msgstr "&Программы" -#: ../PLCOpenEditor.py:119 +#: ../PLCOpenEditor.py:125 msgid "&Properties" msgstr "&Свойства" -#: ../Beremiz.py:317 +#: ../Beremiz.py:324 msgid "&Recent Projects" msgstr "&Недавние проекты" -#: ../IDEFrame.py:329 +#: ../IDEFrame.py:353 msgid "&Resource" msgstr "&Ресурсы" -#: ../controls/SearchResultPanel.py:252 -#, python-format -msgid "'%s' - %d match in project" -msgstr "'%s'- %d совпадений в проекте" - -#: ../controls/SearchResultPanel.py:254 -#, python-format -msgid "'%s' - %d matches in project" -msgstr "'%s' - %d совпадений в проекте" - -#: ../connectors/PYRO/__init__.py:86 -#, python-format -msgid "'%s' is located at %s\n" -msgstr "'%s' находится %s\n" - -#: ../controls/SearchResultPanel.py:304 +#: ../controls/SearchResultPanel.py:239 +#, python-brace-format +msgid "'{a1}' - {a2} match in project" +msgstr "'{a1}'- {a2} совпадений в проекте" + +#: ../controls/SearchResultPanel.py:241 +#, python-brace-format +msgid "'{a1}' - {a2} matches in project" +msgstr "'{a1}' - {a2} совпадений в проекте" + +#: ../connectors/PYRO/__init__.py:90 +#, python-brace-format +msgid "'{a1}' is located at {a2}\n" +msgstr "'{a1}' находится {a2}\n" + +#: ../controls/SearchResultPanel.py:291 #, python-format msgid "(%d matches)" msgstr "(%d совпадений)" -#: ../PLCOpenEditor.py:384 ../PLCOpenEditor.py:386 ../PLCOpenEditor.py:387 +#: ../PLCOpenEditor.py:396 ../PLCOpenEditor.py:398 ../PLCOpenEditor.py:399 msgid ", " -msgstr "" - -#: ../dialogs/PouTransitionDialog.py:96 ../dialogs/PouActionDialog.py:93 +msgstr ", " + +#: ../dialogs/PouTransitionDialog.py:101 ../dialogs/PouActionDialog.py:93 #: ../dialogs/PouDialog.py:115 #, python-format msgid ", %s" -msgstr "" - -#: ../PLCOpenEditor.py:382 +msgstr ", %s" + +#: ../PLCOpenEditor.py:394 msgid ". " -msgstr "" - -#: ../controls/LogViewer.py:278 +msgstr ". " + +#: Extra TC6 documentation strings +msgid "0 - current time, 1 - load time from PDT" +msgstr "0 - текущее время, 1 - отклонение от PDT" + +msgid "0 - manual , 1 - automatic" +msgstr "0 - ручной, 1 - автоматический" + +msgid "0 - track X0, 1 - ramp to/track X1" +msgstr "0 - вход X0, 1 - нарастание до значения X1" + +msgid "0 = reset" +msgstr "0 = сброс" + +msgid "1 = integrate, 0 = hold" +msgstr "1 = интегрировать, 0 = остановка" + +#: ../controls/LogViewer.py:279 msgid "1d" msgstr "1 день" -#: ../controls/LogViewer.py:279 +#: ../controls/LogViewer.py:280 msgid "1h" msgstr "1 час" -#: ../controls/LogViewer.py:280 +#: ../controls/LogViewer.py:281 msgid "1m" msgstr "1 мин" -#: ../controls/LogViewer.py:281 +#: ../controls/LogViewer.py:282 msgid "1s" msgstr "1 сек" -#: ../dialogs/PouDialog.py:124 ../IDEFrame.py:1581 ../IDEFrame.py:1623 -#: ../IDEFrame.py:1642 +#: ../dialogs/PouDialog.py:124 ../IDEFrame.py:1614 ../IDEFrame.py:1660 +#: ../IDEFrame.py:1679 #, python-format msgid "A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?" msgstr "В POU присутствует элемент с именем \"%s\". Это может вызвать конфликт. Хотите продолжить?" -#: ../dialogs/SFCStepNameDialog.py:53 ../dialogs/PouTransitionDialog.py:103 -#: ../dialogs/PouNameDialog.py:51 ../dialogs/PouActionDialog.py:100 -#: ../controls/VariablePanel.py:735 ../IDEFrame.py:1593 ../IDEFrame.py:1604 +#: ../dialogs/SFCStepNameDialog.py:54 ../dialogs/PouTransitionDialog.py:108 +#: ../dialogs/PouNameDialog.py:52 ../dialogs/PouActionDialog.py:100 +#: ../controls/VariablePanel.py:753 ../IDEFrame.py:1628 ../IDEFrame.py:1641 #, python-format msgid "A POU named \"%s\" already exists!" msgstr "POU с именем \"%s\" уже существует!" -#: ../ConfigTreeNode.py:400 -#, python-format -msgid "A child named \"%s\" already exist -> \"%s\"\n" -msgstr "Дочерний элемент с именем \"%s\" уже существует -> \"%s\"\n" - -#: ../dialogs/BrowseLocationsDialog.py:211 +#: ../ConfigTreeNode.py:424 +#, python-brace-format +msgid "A child named \"{a1}\" already exists -> \"{a2}\"\n" +msgstr "Дочерний элемент с именем \"{a1}\" уже существует -> \"{a2}\"\n" + +#: ../dialogs/BrowseLocationsDialog.py:216 msgid "A location must be selected!" msgstr "Необходимо выбрать размещение!" -#: ../dialogs/SFCStepNameDialog.py:55 ../controls/VariablePanel.py:737 -#: ../IDEFrame.py:1595 ../IDEFrame.py:1606 +#: ../dialogs/SFCStepNameDialog.py:56 ../controls/VariablePanel.py:755 +#: ../IDEFrame.py:1630 ../IDEFrame.py:1643 #, python-format msgid "A variable with \"%s\" as name already exists in this pou!" msgstr "Переменная с именем \"%s\" уже существует в этом POU!" -#: ../editors/CodeFileEditor.py:754 +#: ../editors/CodeFileEditor.py:774 #, python-format msgid "A variable with \"%s\" as name already exists!" msgstr "Переменная с именем \"%s\" уже существует!" -#: ../PLCOpenEditor.py:152 ../Beremiz.py:374 +#: ../dialogs/AboutDialog.py:40 ../PLCOpenEditor.py:158 ../Beremiz.py:381 msgid "About" msgstr "О программе" -#: ../Beremiz.py:997 -msgid "About Beremiz" -msgstr "О Beremiz" - -#: ../PLCOpenEditor.py:346 -msgid "About PLCOpenEditor" -msgstr "О PLCOpenEditor" - #: ../plcopen/iec_std.csv:22 msgid "Absolute number" msgstr "Абсолютный номер" -#: ../dialogs/SFCStepDialog.py:71 ../dialogs/ActionBlockDialog.py:42 +#: ../dialogs/SFCStepDialog.py:72 ../dialogs/ActionBlockDialog.py:42 msgid "Action" msgstr "Действие" -#: ../editors/Viewer.py:551 ../editors/Viewer.py:2069 +#: ../editors/Viewer.py:555 ../editors/Viewer.py:2345 msgid "Action Block" msgstr "Блок действия" @@ -453,7 +459,7 @@ msgid "Action Name:" msgstr "Имя действия:" -#: ../plcopen/plcopen.py:1356 +#: ../plcopen/plcopen.py:1359 #, python-format msgid "Action with name %s doesn't exist!" msgstr "Действие с именем %s не существует!" @@ -466,72 +472,72 @@ msgid "Actions:" msgstr "Действия:" -#: ../editors/Viewer.py:1087 +#: ../editors/Viewer.py:1100 msgid "Active" msgstr "Активный" -#: ../canfestival/SlaveEditor.py:57 ../canfestival/NetworkEditor.py:78 -#: ../editors/Viewer.py:584 ../Beremiz.py:1024 +#: ../canfestival/SlaveEditor.py:80 ../canfestival/NetworkEditor.py:101 +#: ../editors/Viewer.py:588 ../Beremiz.py:1060 msgid "Add" msgstr "Добавить" -#: ../IDEFrame.py:1856 ../IDEFrame.py:1891 +#: ../IDEFrame.py:1890 ../IDEFrame.py:1925 msgid "Add Action" msgstr "Добавить действие" -#: ../features.py:8 +#: ../features.py:32 msgid "Add C code accessing located variables synchronously" msgstr "Добавить C-код с синхронным доступом к локальным переменным" -#: ../IDEFrame.py:1839 +#: ../IDEFrame.py:1873 msgid "Add Configuration" msgstr "Добавить конфигурацию" -#: ../IDEFrame.py:1819 +#: ../IDEFrame.py:1853 msgid "Add DataType" msgstr "Добавить тип данных" -#: ../editors/Viewer.py:509 +#: ../editors/Viewer.py:513 msgid "Add Divergence Branch" msgstr "Добавить ветвление" -#: ../dialogs/DiscoveryDialog.py:115 +#: ../dialogs/DiscoveryDialog.py:116 msgid "Add IP" msgstr "Добавить IP адрес" -#: ../IDEFrame.py:1827 +#: ../IDEFrame.py:1861 msgid "Add POU" msgstr "Добавить POU" -#: ../features.py:9 +#: ../features.py:33 msgid "Add Python code executed asynchronously" msgstr "Добавить асинхронно вызываемый код на Python" -#: ../IDEFrame.py:1867 ../IDEFrame.py:1917 +#: ../IDEFrame.py:1901 ../IDEFrame.py:1951 msgid "Add Resource" msgstr "Добавить ресурс" -#: ../IDEFrame.py:1845 ../IDEFrame.py:1888 +#: ../IDEFrame.py:1879 ../IDEFrame.py:1922 msgid "Add Transition" msgstr "Добавить переход" -#: ../editors/Viewer.py:496 +#: ../editors/Viewer.py:500 msgid "Add Wire Segment" msgstr "Добавить провод" -#: ../editors/SFCViewer.py:359 +#: ../editors/SFCViewer.py:433 msgid "Add a new initial step" msgstr "Добавить новый исходный шаг" -#: ../editors/Viewer.py:2672 ../editors/SFCViewer.py:696 +#: ../editors/Viewer.py:2706 ../editors/SFCViewer.py:770 msgid "Add a new jump" msgstr "Добавить новый безусловный переход" -#: ../editors/SFCViewer.py:381 +#: ../editors/SFCViewer.py:455 msgid "Add a new step" msgstr "Добавить новый шаг" -#: ../features.py:10 +#: ../features.py:34 msgid "Add a simple WxGlade based GUI." msgstr "Добавить простой GUI на WxGlade " @@ -539,7 +545,7 @@ msgid "Add action" msgstr "Добавить действие" -#: ../editors/DataTypeEditor.py:351 +#: ../editors/DataTypeEditor.py:352 msgid "Add element" msgstr "Добавить элемент" @@ -547,7 +553,7 @@ msgid "Add instance" msgstr "Добавить экземпляр" -#: ../canfestival/NetworkEditor.py:80 +#: ../canfestival/NetworkEditor.py:103 msgid "Add slave" msgstr "Добавить слэйв" @@ -555,7 +561,7 @@ msgid "Add task" msgstr "Добавить задачу" -#: ../editors/CodeFileEditor.py:640 ../controls/VariablePanel.py:440 +#: ../editors/CodeFileEditor.py:658 ../controls/VariablePanel.py:450 msgid "Add variable" msgstr "Добавить переменную" @@ -563,22 +569,22 @@ msgid "Addition" msgstr "Сложение" -#: ../plcopen/definitions.py:22 +#: ../plcopen/definitions.py:47 msgid "Additional function blocks" msgstr "Дополнительные функциональные блоки" -#: ../editors/Viewer.py:567 +#: ../editors/Viewer.py:571 msgid "Adjust Block Size" msgstr "Скорректировать размер элемента" -#: ../editors/Viewer.py:1612 +#: ../editors/Viewer.py:1637 msgid "Alignment" msgstr "Выравнивание" -#: ../dialogs/BrowseLocationsDialog.py:34 -#: ../dialogs/BrowseLocationsDialog.py:42 -#: ../dialogs/BrowseLocationsDialog.py:135 -#: ../dialogs/BrowseLocationsDialog.py:138 ../controls/LogViewer.py:297 +#: ../dialogs/BrowseLocationsDialog.py:39 +#: ../dialogs/BrowseLocationsDialog.py:47 +#: ../dialogs/BrowseLocationsDialog.py:140 +#: ../dialogs/BrowseLocationsDialog.py:143 ../controls/LogViewer.py:298 #: ../controls/VariablePanel.py:70 msgid "All" msgstr "Все" @@ -587,11 +593,11 @@ msgid "All files (*.*)|*.*|CSV files (*.csv)|*.csv" msgstr "Все файлы (*.*)|*.*|CSV files (*.csv)|*.csv" -#: ../ProjectController.py:1523 +#: ../ProjectController.py:1623 msgid "Already connected. Please disconnect\n" msgstr "Уже подключен. Пожалуйста, отключитесь сначала.\n" -#: ../editors/DataTypeEditor.py:593 +#: ../editors/DataTypeEditor.py:594 #, python-format msgid "An element named \"%s\" already exists in this structure!" msgstr "Поле с именем \"%s\" уже существует в данной структуре!" @@ -616,8 +622,8 @@ msgid "Arithmetic" msgstr "Математика" -#: ../editors/DataTypeEditor.py:54 ../editors/DataTypeEditor.py:634 -#: ../controls/VariablePanel.py:811 +#: ../editors/DataTypeEditor.py:54 ../editors/DataTypeEditor.py:635 +#: ../controls/VariablePanel.py:829 msgid "Array" msgstr "Массив" @@ -637,7 +643,10 @@ msgid "Author Name (optional):" msgstr "Имя автора (опционально):" -#: ../dialogs/FindInPouDialog.py:78 +msgid "BUSY = 1 during ramping period" +msgstr "BOSY = 1 во время " + +#: ../dialogs/FindInPouDialog.py:79 msgid "Backward" msgstr "Назад" @@ -649,26 +658,26 @@ msgid "Bad domain name at " msgstr "Неправильное доменное имя в" -#: ../canfestival/config_utils.py:342 ../canfestival/config_utils.py:624 +#: ../canfestival/config_utils.py:342 ../canfestival/config_utils.py:630 #, python-format msgid "Bad location size : %s" msgstr "Неправильный размер: %s" -#: ../dialogs/ArrayTypeDialog.py:55 ../editors/DataTypeEditor.py:174 -#: ../editors/DataTypeEditor.py:204 ../editors/DataTypeEditor.py:296 +#: ../dialogs/ArrayTypeDialog.py:55 ../editors/DataTypeEditor.py:175 +#: ../editors/DataTypeEditor.py:205 ../editors/DataTypeEditor.py:297 msgid "Base Type:" msgstr "Базовый тип:" -#: ../editors/DataTypeEditor.py:624 ../controls/VariablePanel.py:769 +#: ../editors/DataTypeEditor.py:625 ../controls/VariablePanel.py:787 msgid "Base Types" msgstr "Базовые типы" msgid "BaseParams" msgstr "Базовые параметры" -#: ../Beremiz.py:527 +#: ../Beremiz.py:553 msgid "Beremiz" -msgstr "" +msgstr "Beremiz" msgid "BeremizRoot" msgstr "Настройки Beremiz " @@ -701,7 +710,7 @@ msgid "Bitwise inverting" msgstr "Битовое НЕ" -#: ../editors/Viewer.py:521 ../editors/Viewer.py:2073 +#: ../editors/Viewer.py:525 ../editors/Viewer.py:2358 msgid "Block" msgstr "Блок" @@ -709,69 +718,77 @@ msgid "Block Properties" msgstr "Свойства блока" -#: ../editors/TextViewer.py:261 +#: ../editors/TextViewer.py:262 msgid "Block name" msgstr "Имя блока" -#: ../editors/Viewer.py:487 +#: ../editors/Viewer.py:491 msgid "Bottom" msgstr "Низ" +#: ../ProjectController.py:1301 +msgid "Broken" +msgstr "Ошибка" + #: ../dialogs/BrowseValuesLibraryDialog.py:37 #, python-format msgid "Browse %s values library" -msgstr "" - -#: ../dialogs/BrowseLocationsDialog.py:60 +msgstr "Browse %s values library" + +#: ../dialogs/BrowseLocationsDialog.py:65 msgid "Browse Locations" msgstr "Просмотр директорий" -#: ../ProjectController.py:1668 +#: ../ProjectController.py:1769 msgid "Build" msgstr "Сборка" -#: ../ProjectController.py:1166 +#: ../ProjectController.py:1235 msgid "Build directory already clean\n" msgstr "Директория сборки уже пуста\n" -#: ../ProjectController.py:1669 +#: ../ProjectController.py:1770 msgid "Build project into build folder" msgstr "Сборка проекта в директории сборки" -#: ../ProjectController.py:956 +#: ../ProjectController.py:1018 msgid "C Build crashed !\n" msgstr "Крэш во время сборки C-кода!\n" -#: ../ProjectController.py:953 +#: ../ProjectController.py:1015 msgid "C Build failed.\n" msgstr "Ошибка сборки C-кода.\n" -#: ../c_ext/CFileEditor.py:40 +#: ../c_ext/CFileEditor.py:63 msgid "C code" msgstr "C код " -#: ../ProjectController.py:1031 +#: ../ProjectController.py:1093 msgid "C code generated successfully.\n" msgstr "C-код успешно сгенерирован.\n" -#: ../targets/toolchain_makefile.py:108 +#: ../targets/toolchain_makefile.py:122 msgid "C compilation failed.\n" msgstr "Ошибка компиляции.\n" -#: ../targets/toolchain_gcc.py:132 +#: ../targets/toolchain_gcc.py:156 #, python-format msgid "C compilation of %s failed.\n" msgstr "Ошибка компиляции %s.\n" -#: ../features.py:8 +#: ../features.py:32 msgid "C extension" msgstr "С-расширение" -#: ../canfestival/NetworkEditor.py:29 +#: ../dialogs/AboutDialog.py:63 +msgid "C&redits" +msgstr "&Благодарности" + +#: ../canfestival/NetworkEditor.py:52 msgid "CANOpen network" msgstr "Сеть CANOpen" -#: ../canfestival/SlaveEditor.py:21 +#: ../canfestival/SlaveEditor.py:44 msgid "CANOpen slave" msgstr "CANOpen ведущий" @@ -784,37 +801,37 @@ msgid "CAN_Driver" msgstr "CAN драйвер" -#: ../features.py:7 +#: ../features.py:31 msgid "CANopen support" msgstr "Поддержка CANOpen" msgid "CFLAGS" -msgstr "" - -#: ../plcopen/plcopen.py:1580 ../plcopen/plcopen.py:1594 -#: ../plcopen/plcopen.py:1615 ../plcopen/plcopen.py:1631 +msgstr "CFLAGS" + +#: ../plcopen/plcopen.py:1584 ../plcopen/plcopen.py:1598 +#: ../plcopen/plcopen.py:1622 ../plcopen/plcopen.py:1638 msgid "Can only generate execution order on FBD networks!" msgstr "Можно сгенерировать порядок исполнения только для FBD!" -#: ../controls/VariablePanel.py:259 +#: ../controls/VariablePanel.py:267 msgid "Can only give a location to local or global variables" msgstr "Можно задать размещение только локальным или глобальным переменны" -#: ../PLCOpenEditor.py:327 +#: ../PLCOpenEditor.py:334 #, python-format msgid "Can't generate program to file %s!" msgstr "Нельзя сгенерировать программу в файл %s!" -#: ../controls/VariablePanel.py:257 +#: ../controls/VariablePanel.py:265 msgid "Can't give a location to a function block instance" msgstr "Нельзя задать размещение для экземпляра функционального блока" -#: ../PLCOpenEditor.py:367 +#: ../PLCOpenEditor.py:379 #, python-format msgid "Can't save project to file %s!" msgstr "Нельзя сохранить проект в файл %s!" -#: ../controls/VariablePanel.py:303 +#: ../controls/VariablePanel.py:313 msgid "Can't set an initial value to a function block instance" msgstr "Нельзя задать исходное значение экземпляру функционального блока" @@ -828,54 +845,54 @@ msgid "CanFestivalSlaveNode" msgstr "" -#: ../ConfigTreeNode.py:504 -#, python-format -msgid "Cannot create child %s of type %s " -msgstr "Нельзя создать дочерний элемент %s типа %s" - -#: ../ConfigTreeNode.py:429 +#: ../ConfigTreeNode.py:529 +#, python-brace-format +msgid "Cannot create child {a1} of type {a2} " +msgstr "Нельзя создать дочерний элемент {a1} типа {a2}" + +#: ../ConfigTreeNode.py:454 #, python-format msgid "Cannot find lower free IEC channel than %d\n" msgstr "Не удалось найти свободный МЭК-канал с номером меньше чем %d\n" -#: ../connectors/PYRO/__init__.py:127 +#: ../connectors/PYRO/__init__.py:131 msgid "Cannot get PLC status - connection failed.\n" msgstr "Невозможно получить состояние ПЛК - ошибка подключения.\n" -#: ../ProjectController.py:817 +#: ../ProjectController.py:881 msgid "Cannot open/parse VARIABLES.csv!\n" msgstr "Не удалось открыть/прочитать VARIABLES.csv\n" -#: ../canfestival/config_utils.py:372 -#, python-format -msgid "Cannot set bit offset for non bool '%s' variable (ID:%d,Idx:%x,sIdx:%x))" -msgstr "Невозможно установить битовое смещение для небулевой переменной '%s' (ID:%d,Idx:%x,sIdx:%x))" - -#: ../dialogs/SearchInProjectDialog.py:67 ../dialogs/FindInPouDialog.py:87 +#: ../canfestival/config_utils.py:374 +#, python-brace-format +msgid "Cannot set bit offset for non bool '{a1}' variable (ID:{a2},Idx:{a3},sIdx:{a4}))" +msgstr "Невозможно установить битовое смещение для небулевой переменной '{a1}' (ID:{a2},Idx:{a3},sIdx:{a4}))" + +#: ../dialogs/SearchInProjectDialog.py:59 ../dialogs/FindInPouDialog.py:88 msgid "Case sensitive" msgstr "Регистрозависимый" -#: ../editors/Viewer.py:482 +#: ../editors/Viewer.py:486 msgid "Center" msgstr "Центр" -#: ../Beremiz_service.py:245 +#: ../Beremiz_service.py:266 msgid "Change IP of interface to bind" msgstr "Сменить IP-адрес интерфейса для привязки сокета" -#: ../Beremiz_service.py:244 +#: ../Beremiz_service.py:265 msgid "Change Name" msgstr "Сменить имя" -#: ../IDEFrame.py:1909 +#: ../IDEFrame.py:1943 msgid "Change POU Type To" msgstr "Сменить тип POU на" -#: ../Beremiz_service.py:246 +#: ../Beremiz_service.py:267 msgid "Change Port Number" msgstr "Сменить номер порта" -#: ../Beremiz_service.py:247 +#: ../Beremiz_service.py:268 msgid "Change working directory" msgstr "Сменить рабочую директорию" @@ -883,37 +900,37 @@ msgid "Character string" msgstr "Строковые операции" -#: ../svgui/svgui.py:101 +#: ../svgui/svgui.py:125 msgid "Choose a SVG file" -msgstr "Выберете SVG-файл" - -#: ../ProjectController.py:420 +msgstr "Выберите SVG-файл" + +#: ../ProjectController.py:451 msgid "Choose a directory to save project" -msgstr "Выберете директорию, чтобы сохранить проект" - -#: ../canfestival/canfestival.py:136 ../PLCOpenEditor.py:285 -#: ../PLCOpenEditor.py:317 ../PLCOpenEditor.py:361 +msgstr "Выберите директорию, чтобы сохранить проект" + +#: ../canfestival/canfestival.py:160 ../PLCOpenEditor.py:292 +#: ../PLCOpenEditor.py:324 ../PLCOpenEditor.py:373 msgid "Choose a file" -msgstr "Выберете файл" - -#: ../Beremiz.py:899 ../Beremiz.py:934 +msgstr "Выберите файл" + +#: ../Beremiz.py:931 ../Beremiz.py:966 msgid "Choose a project" -msgstr "Выберете проект" +msgstr "Выберите проект" #: ../dialogs/BrowseValuesLibraryDialog.py:42 #, python-format msgid "Choose a value for %s:" -msgstr "Выберете значение для %s:" - -#: ../Beremiz_service.py:293 +msgstr "Выберите значение для %s:" + +#: ../Beremiz_service.py:323 msgid "Choose a working directory " -msgstr "Выберете рабочую директорию" - -#: ../ProjectController.py:334 +msgstr "Выберите рабочую директорию" + +#: ../ProjectController.py:358 msgid "Chosen folder doesn't contain a program. It's not a valid project!" msgstr "Выбранная директория не содержит программы. Это некорректный проект!" -#: ../ProjectController.py:301 +#: ../ProjectController.py:325 msgid "Chosen folder isn't empty. You can't use it for a new project!" msgstr "Выбранная директория не пуста и не может использоваться для нового проекта!" @@ -921,7 +938,7 @@ msgid "Class" msgstr "Класс" -#: ../controls/VariablePanel.py:431 +#: ../controls/VariablePanel.py:441 msgid "Class Filter:" msgstr "Фильтр класса:" @@ -929,55 +946,55 @@ msgid "Class:" msgstr "Класс:" -#: ../ProjectController.py:1672 +#: ../ProjectController.py:1773 msgid "Clean" msgstr "Очистить" -#: ../controls/LogViewer.py:317 +#: ../controls/LogViewer.py:318 msgid "Clean log messages" msgstr "Очистить лог" -#: ../ProjectController.py:1674 +#: ../ProjectController.py:1775 msgid "Clean project build folder" msgstr "Очистить директорию сборки проекта" -#: ../ProjectController.py:1163 +#: ../ProjectController.py:1232 msgid "Cleaning the build directory\n" msgstr "Очистка директории сборки\n" -#: ../IDEFrame.py:411 +#: ../IDEFrame.py:435 msgid "Clear Errors" msgstr "Очистить ошибки" -#: ../editors/Viewer.py:577 +#: ../editors/Viewer.py:582 msgid "Clear Execution Order" msgstr "Очистить порядок исполнения" -#: ../dialogs/FindInPouDialog.py:110 +#: ../dialogs/SearchInProjectDialog.py:105 ../dialogs/FindInPouDialog.py:111 msgid "Close" msgstr "Закрыть" -#: ../PLCOpenEditor.py:192 ../Beremiz.py:667 +#: ../PLCOpenEditor.py:199 ../Beremiz.py:693 msgid "Close Application" msgstr "Закрыть приложение" -#: ../PLCOpenEditor.py:102 ../Beremiz.py:326 ../Beremiz.py:611 -#: ../IDEFrame.py:981 +#: ../PLCOpenEditor.py:108 ../Beremiz.py:333 ../Beremiz.py:637 +#: ../IDEFrame.py:1009 msgid "Close Project" msgstr "Закрыть проект" -#: ../PLCOpenEditor.py:100 ../Beremiz.py:324 +#: ../PLCOpenEditor.py:106 ../Beremiz.py:331 msgid "Close Tab" msgstr "Закрыть вкладку" -#: ../editors/Viewer.py:537 ../editors/Viewer.py:2084 +#: ../editors/Viewer.py:541 ../editors/Viewer.py:2366 msgid "Coil" msgstr "Катушка" msgid "Command" msgstr "Комманда" -#: ../editors/Viewer.py:557 ../editors/LDViewer.py:506 +#: ../editors/Viewer.py:561 ../editors/LDViewer.py:506 msgid "Comment" msgstr "Комментарий" @@ -1000,7 +1017,7 @@ msgid "Compiler" msgstr "Компилятор" -#: ../ProjectController.py:609 +#: ../ProjectController.py:672 msgid "Compiling IEC Program into C code...\n" msgstr "Компиляция МЭК-программы в C-код...\n" @@ -1008,15 +1025,15 @@ msgid "Concatenation" msgstr "Объединение" -#: ../editors/ConfTreeNodeEditor.py:206 +#: ../editors/ConfTreeNodeEditor.py:229 msgid "Config" msgstr "Конфигурация" -#: ../editors/ProjectNodeEditor.py:13 +#: ../editors/ProjectNodeEditor.py:36 msgid "Config variables" msgstr "Конфигурационные переменные" -#: ../dialogs/SearchInProjectDialog.py:47 +#: ../dialogs/SearchInProjectDialog.py:39 msgid "Configuration" msgstr "Конфигурация" @@ -1024,27 +1041,27 @@ msgid "Configurations" msgstr "Конфигурации" -#: ../editors/Viewer.py:303 ../editors/Viewer.py:333 ../editors/Viewer.py:355 -#: ../editors/TextViewer.py:289 ../editors/TextViewer.py:340 -#: ../editors/TextViewer.py:363 ../controls/VariablePanel.py:318 +#: ../editors/Viewer.py:307 ../editors/Viewer.py:337 ../editors/Viewer.py:359 +#: ../editors/TextViewer.py:291 ../editors/TextViewer.py:342 +#: ../editors/TextViewer.py:365 ../controls/VariablePanel.py:328 msgid "Confirm or change variable name" msgstr "Подтвердить или поменять имя переменной" -#: ../ProjectController.py:1687 +#: ../ProjectController.py:1788 msgid "Connect" msgstr "Подключиться" -#: ../ProjectController.py:1688 +#: ../ProjectController.py:1789 msgid "Connect to the target PLC" msgstr "Подключиться к целевому ПЛК" -#: ../ProjectController.py:1212 +#: ../ProjectController.py:1292 #, python-format msgid "Connected to URI: %s" msgstr "Подключен к URI: %s" -#: ../dialogs/SFCTransitionDialog.py:75 ../editors/Viewer.py:523 -#: ../editors/Viewer.py:2075 +#: ../dialogs/SFCTransitionDialog.py:76 ../editors/Viewer.py:527 +#: ../editors/Viewer.py:2359 msgid "Connection" msgstr "Подключение" @@ -1052,29 +1069,33 @@ msgid "Connection Properties" msgstr "Свойства подключение" -#: ../ProjectController.py:1547 +#: ../ProjectController.py:1647 msgid "Connection canceled!\n" msgstr "Подключение отменено!\n" -#: ../ProjectController.py:1572 +#: ../ProjectController.py:1672 #, python-format msgid "Connection failed to %s!\n" msgstr "Неудачное подключение к %s!\n" -#: ../connectors/PYRO/__init__.py:98 +#: ../connectors/PYRO/__init__.py:115 ../connectors/WAMP/__init__.py:111 +msgid "Connection lost!\n" +msgstr "Подключение прервано!\n" + +#: ../connectors/PYRO/__init__.py:102 #, python-format msgid "Connection to '%s' failed.\n" msgstr "Неудачное подключение к %s!\n" -#: ../dialogs/ConnectionDialog.py:64 ../editors/Viewer.py:1569 +#: ../dialogs/ConnectionDialog.py:64 ../editors/Viewer.py:1594 msgid "Connector" msgstr "Коннектор" -#: ../dialogs/SFCStepDialog.py:64 +#: ../dialogs/SFCStepDialog.py:65 msgid "Connectors:" msgstr "Коннекторы:" -#: ../Beremiz.py:436 +#: ../Beremiz.py:448 msgid "Console" msgstr "Консоль" @@ -1082,7 +1103,7 @@ msgid "Constant" msgstr "Константа" -#: ../editors/Viewer.py:533 ../editors/Viewer.py:2080 +#: ../editors/Viewer.py:537 ../editors/Viewer.py:2362 msgid "Contact" msgstr "Контакт" @@ -1090,7 +1111,7 @@ msgid "Content Description (optional):" msgstr "Описание содержимого (опционально):" -#: ../dialogs/ConnectionDialog.py:65 ../editors/Viewer.py:1570 +#: ../dialogs/ConnectionDialog.py:65 ../editors/Viewer.py:1595 msgid "Continuation" msgstr "Продолжение" @@ -1110,12 +1131,12 @@ msgid "Conversion to time-of-day" msgstr "Преобразование во время суток" -#: ../editors/Viewer.py:593 ../controls/LogViewer.py:692 ../IDEFrame.py:346 -#: ../IDEFrame.py:401 +#: ../editors/Viewer.py:597 ../controls/LogViewer.py:693 ../IDEFrame.py:370 +#: ../IDEFrame.py:425 msgid "Copy" msgstr "Копировать" -#: ../IDEFrame.py:1896 +#: ../IDEFrame.py:1930 msgid "Copy POU" msgstr "Копировать POU" @@ -1127,55 +1148,62 @@ msgid "Copy file from right folder to left" msgstr "Скопировать файл с правой директории в левую" +msgid "Copy of IN" +msgstr "Копия входа IN" + #: ../plcopen/iec_std.csv:28 msgid "Cosine" msgstr "Косинус" -#: ../ConfigTreeNode.py:626 -#, python-format +#: ../ConfigTreeNode.py:656 +#, python-brace-format msgid "" -"Could not add child \"%s\", type %s :\n" -"%s\n" +"Could not add child \"{a1}\", type {a2} :\n" +"{a3}\n" msgstr "" -"Невозможно добавить дочерний элемент \"%s\", тип %s:\n" -"%s\n" - -#: ../py_ext/PythonFileCTNMixin.py:53 +"Невозможно добавить дочерний элемент \"{a1}\", тип {a2}:\n" +"{a3}\n" + +#: ../py_ext/PythonFileCTNMixin.py:77 #, python-format msgid "Couldn't import old %s file." msgstr "Невозможно импортировать старый файл %s." -#: ../ConfigTreeNode.py:598 -#, python-format +#: ../ConfigTreeNode.py:626 +#, python-brace-format msgid "" -"Couldn't load confnode base parameters %s :\n" -" %s" -msgstr "Невозможно загрузить базовые параметры confnode %s: %s" - -#: ../ConfigTreeNode.py:614 ../CodeFileTreeNode.py:99 -#, python-format +"Couldn't load confnode base parameters {a1} :\n" +" {a2}" +msgstr "" +"Невозможно загрузить базовые параметры confnode {a1}:\n" +" {a2}" + +#: ../ConfigTreeNode.py:643 ../CodeFileTreeNode.py:124 +#, python-brace-format msgid "" -"Couldn't load confnode parameters %s :\n" -" %s" -msgstr "Невозможно загрузить параметры confnode %s: %s" +"Couldn't load confnode parameters {a1} :\n" +" {a2}" +msgstr "" +"Невозможно загрузить параметры confnode {a1}:\n" +" {a2}" #: ../PLCControler.py:946 msgid "Couldn't paste non-POU object." msgstr "Невозможно вставить не-POU." -#: ../ProjectController.py:1486 +#: ../ProjectController.py:1589 msgid "Couldn't start PLC !\n" msgstr "Невозможно запустить ПЛК!\n" -#: ../ProjectController.py:1494 +#: ../ProjectController.py:1597 msgid "Couldn't stop PLC !\n" msgstr "Невозможно остановить ПЛК!\n" -#: ../ProjectController.py:1458 +#: ../ProjectController.py:1561 msgid "Couldn't stop debugger.\n" msgstr "Невозможно остановить отладчик.\n" -#: ../svgui/svgui.py:23 +#: ../svgui/svgui.py:47 msgid "Create HMI" msgstr "Создать HMI" @@ -1187,71 +1215,79 @@ msgid "Create a new action" msgstr "Создать новое действие" -#: ../IDEFrame.py:135 +#: ../IDEFrame.py:159 msgid "Create a new action block" msgstr "Создать новый блок действие" -#: ../IDEFrame.py:84 ../IDEFrame.py:114 ../IDEFrame.py:147 +#: ../IDEFrame.py:108 ../IDEFrame.py:138 ../IDEFrame.py:171 msgid "Create a new block" msgstr "Создать новый блок" -#: ../IDEFrame.py:108 +#: ../IDEFrame.py:132 msgid "Create a new branch" msgstr "Создать новое ветвление" -#: ../IDEFrame.py:102 +#: ../IDEFrame.py:126 msgid "Create a new coil" msgstr "Создать новую катушку" -#: ../IDEFrame.py:78 ../IDEFrame.py:93 ../IDEFrame.py:123 +#: ../IDEFrame.py:102 ../IDEFrame.py:117 ../IDEFrame.py:147 msgid "Create a new comment" msgstr "Создать новый комментарий" -#: ../IDEFrame.py:87 ../IDEFrame.py:117 ../IDEFrame.py:150 +#: ../IDEFrame.py:111 ../IDEFrame.py:141 ../IDEFrame.py:174 msgid "Create a new connection" msgstr "Создать новое подключение" -#: ../IDEFrame.py:105 ../IDEFrame.py:156 +#: ../IDEFrame.py:129 ../IDEFrame.py:180 msgid "Create a new contact" msgstr "Создать новый контакт" -#: ../IDEFrame.py:138 +#: ../IDEFrame.py:162 msgid "Create a new divergence" msgstr "Создать новое ветвление" -#: ../dialogs/SFCDivergenceDialog.py:51 +#: ../dialogs/SFCDivergenceDialog.py:53 msgid "Create a new divergence or convergence" msgstr "Создать новое ветвление или объединение" -#: ../IDEFrame.py:126 +#: ../IDEFrame.py:150 msgid "Create a new initial step" msgstr "Создать исходный шаг" -#: ../IDEFrame.py:141 +#: ../IDEFrame.py:165 msgid "Create a new jump" -msgstr "Создать новый переход" - -#: ../IDEFrame.py:96 ../IDEFrame.py:153 +msgstr "Создать новый безусловный переход" + +#: ../IDEFrame.py:120 ../IDEFrame.py:177 msgid "Create a new power rail" msgstr "Создать новую линию питания" -#: ../IDEFrame.py:99 +#: ../IDEFrame.py:123 msgid "Create a new rung" msgstr "Создать новую цепь" -#: ../IDEFrame.py:129 +#: ../IDEFrame.py:153 msgid "Create a new step" msgstr "Создать новый шаг" -#: ../dialogs/PouTransitionDialog.py:42 ../IDEFrame.py:132 +#: ../dialogs/PouTransitionDialog.py:47 ../IDEFrame.py:156 msgid "Create a new transition" msgstr "Создать новый переход" -#: ../IDEFrame.py:81 ../IDEFrame.py:111 ../IDEFrame.py:144 +#: ../IDEFrame.py:105 ../IDEFrame.py:135 ../IDEFrame.py:168 msgid "Create a new variable" msgstr "Создать новую переменную" -#: ../editors/Viewer.py:592 ../IDEFrame.py:344 ../IDEFrame.py:400 +#: ../dialogs/AboutDialog.py:105 +msgid "Credits" +msgstr "Благодарности" + +#: ../Beremiz_service.py:432 +msgid "Current working directory :" +msgstr "Текущая рабочая директория :" + +#: ../editors/Viewer.py:596 ../IDEFrame.py:368 ../IDEFrame.py:424 msgid "Cut" msgstr "Вырезать" @@ -1267,15 +1303,15 @@ msgid "DEPRECATED" msgstr "УСТАРЕЛО" -#: ../canfestival/SlaveEditor.py:53 ../canfestival/NetworkEditor.py:74 +#: ../canfestival/SlaveEditor.py:76 ../canfestival/NetworkEditor.py:97 msgid "DS-301 Profile" msgstr "Профиль DS-301" -#: ../canfestival/SlaveEditor.py:54 ../canfestival/NetworkEditor.py:75 +#: ../canfestival/SlaveEditor.py:77 ../canfestival/NetworkEditor.py:98 msgid "DS-302 Profile" msgstr "Профиль DS-302" -#: ../dialogs/SearchInProjectDialog.py:43 +#: ../dialogs/SearchInProjectDialog.py:35 msgid "Data Type" msgstr "Тип данных" @@ -1300,11 +1336,14 @@ msgid "Date subtraction" msgstr "Вычитание дат" +msgid "Datetime, current or relative to PDT" +msgstr "Текущие дата и время, абсолютные или относительные от PDT" + #: ../dialogs/DurationEditorDialog.py:43 msgid "Days:" msgstr "Дни:" -#: ../ProjectController.py:1594 +#: ../ProjectController.py:1694 msgid "Debug does not match PLC - stop/transfert/start to re-enable\n" msgstr "Отлаживаемая программа не соответствует программе в ПЛК - остановите/загрузите/запустите, чтобы разрешить отладку\n" @@ -1312,42 +1351,42 @@ msgid "Debug instance" msgstr "Отладка экземпляра" -#: ../editors/Viewer.py:1104 ../editors/Viewer.py:3596 +#: ../editors/Viewer.py:1117 ../editors/Viewer.py:3653 #, python-format msgid "Debug: %s" msgstr "Отладка: %s" -#: ../ProjectController.py:1247 +#: ../ProjectController.py:1350 #, python-format msgid "Debug: Unknown variable '%s'\n" msgstr "Отладка: неизвестная переменная '%s'\n" -#: ../ProjectController.py:1245 +#: ../ProjectController.py:1348 #, python-format msgid "Debug: Unsupported type to debug '%s'\n" msgstr "Отладка: неподдерживамый отладкой тип '%s'\n" -#: ../IDEFrame.py:611 +#: ../IDEFrame.py:639 msgid "Debugger" msgstr "Отладчик" -#: ../ProjectController.py:1427 +#: ../ProjectController.py:1530 msgid "Debugger disabled\n" msgstr "Отладчик запрещен\n" -#: ../ProjectController.py:1591 +#: ../ProjectController.py:1691 msgid "Debugger ready\n" msgstr "Отладчик готов\n" -#: ../ProjectController.py:1460 +#: ../ProjectController.py:1563 msgid "Debugger stopped.\n" msgstr "Отладчик остановлен.\n" -#: ../editors/Viewer.py:568 ../Beremiz.py:1028 ../IDEFrame.py:1925 +#: ../editors/Viewer.py:572 ../Beremiz.py:1064 ../IDEFrame.py:1959 msgid "Delete" msgstr "Удалить" -#: ../editors/Viewer.py:510 +#: ../editors/Viewer.py:514 msgid "Delete Divergence Branch" msgstr "Удалить ветвь" @@ -1355,7 +1394,7 @@ msgid "Delete File" msgstr "Удалить файл" -#: ../editors/Viewer.py:497 +#: ../editors/Viewer.py:501 msgid "Delete Wire Segment" msgstr "Удалить сегмент цепи" @@ -1367,35 +1406,29 @@ msgid "Deletion (within)" msgstr "Удаление подстроки" -#: ../editors/DataTypeEditor.py:152 +#: ../editors/DataTypeEditor.py:153 msgid "Derivation Type:" msgstr "Механизм создания типа:" -#: ../plcopen/definitions.py:41 -msgid "" -"Derivative\n" -"The derivative function block produces an output XOUT proportional to the rate of change of the input XIN." -msgstr "" -"Производная\n" -"Функциональный блок формирует выход XOUT пропорционально частоте изменения входа XIN." - -#: ../editors/CodeFileEditor.py:664 -msgid "Description" -msgstr "Описание" - -#: ../controls/VariablePanel.py:422 +msgid "Derivative time constant" +msgstr "Постоянная времени дифференцирования" + +#: ../controls/VariablePanel.py:432 msgid "Description:" msgstr "Описание:" -#: ../dialogs/ArrayTypeDialog.py:61 ../editors/DataTypeEditor.py:320 +msgid "Differentiated output" +msgstr "Дифференцированный выход" + +#: ../dialogs/ArrayTypeDialog.py:61 ../editors/DataTypeEditor.py:321 msgid "Dimensions:" msgstr "Размеры:" -#: ../dialogs/FindInPouDialog.py:67 +#: ../dialogs/FindInPouDialog.py:68 msgid "Direction" -msgstr "Неправление" - -#: ../dialogs/BrowseLocationsDialog.py:85 +msgstr "Направление" + +#: ../dialogs/BrowseLocationsDialog.py:90 msgid "Direction:" msgstr "Направление:" @@ -1406,15 +1439,19 @@ msgid "Disable_Extensions" msgstr "Запретить расширения" -#: ../ProjectController.py:1696 +#: ../ProjectController.py:1797 msgid "Disconnect" msgstr "Отключиться" -#: ../ProjectController.py:1698 +#: ../ProjectController.py:1799 msgid "Disconnect from PLC" msgstr "Отключиться от ПЛК" -#: ../editors/Viewer.py:552 ../editors/Viewer.py:2061 +#: ../ProjectController.py:1302 +msgid "Disconnected" +msgstr "Отключено" + +#: ../editors/Viewer.py:556 ../editors/Viewer.py:2354 msgid "Divergence" msgstr "Ветвление" @@ -1431,27 +1468,19 @@ msgid "Documentation" msgstr "Описание" -#: ../PLCOpenEditor.py:321 +#: ../PLCOpenEditor.py:328 msgid "Done" msgstr "Завершено" -#: ../plcopen/definitions.py:34 -msgid "" -"Down-counter\n" -"The down-counter can be used to signal when a count has reached zero, on counting down from a preset value." -msgstr "" -"Декрементный счетчик\n" -"Декрементный счетчик может использоваться, когда необходимо сигнализировать, что счетчик достиг нулевого значения с исходного заданного значения." - #: ../dialogs/ActionBlockDialog.py:38 msgid "Duration" msgstr "Длительность" -#: ../canfestival/canfestival.py:139 +#: ../canfestival/canfestival.py:163 msgid "EDS files (*.eds)|*.eds|All files|*.*" msgstr "Файлы EDS (*.eds)|*.eds|All files|*.*" -#: ../editors/Viewer.py:566 +#: ../editors/Viewer.py:570 msgid "Edit Block" msgstr "Редактировать блок" @@ -1467,11 +1496,11 @@ msgid "Edit Duration" msgstr "Редактировать длительность" -#: ../dialogs/SFCStepDialog.py:49 +#: ../dialogs/SFCStepDialog.py:50 msgid "Edit Step" msgstr "Редактировать шаг" -#: ../wxglade_hmi/wxglade_hmi.py:12 +#: ../wxglade_hmi/wxglade_hmi.py:36 msgid "Edit a WxWidgets GUI with WXGlade" msgstr "Редактировать WxWidgets GUI с помощью WXGlade" @@ -1483,7 +1512,7 @@ msgid "Edit array type properties" msgstr "Редактировать свойства массива" -#: ../editors/Viewer.py:2541 ../editors/Viewer.py:2952 +#: ../editors/Viewer.py:2575 ../editors/Viewer.py:3004 msgid "Edit comment" msgstr "Редактировать комментарий" @@ -1495,50 +1524,57 @@ msgid "Edit item" msgstr "Редактировать элемент" -#: ../editors/Viewer.py:2916 +#: ../editors/Viewer.py:2963 msgid "Edit jump target" msgstr "Редактирование безусловного перехода" -#: ../ProjectController.py:1710 +#: ../ProjectController.py:1811 msgid "Edit raw IEC code added to code generated by PLCGenerator" msgstr "Редактировать МЭК-код добавленный к коду сгенерированному PLCGenerator" -#: ../editors/SFCViewer.py:725 +#: ../editors/SFCViewer.py:799 msgid "Edit step name" msgstr "Редактировать имя шага" -#: ../dialogs/SFCTransitionDialog.py:50 +#: ../dialogs/SFCTransitionDialog.py:51 msgid "Edit transition" msgstr "Редактировать переход" -#: ../IDEFrame.py:583 +#: ../IDEFrame.py:611 msgid "Editor ToolBar" msgstr "Редактор панели инструментов" -#: ../ProjectController.py:1126 +#: ../ProjectController.py:1195 msgid "Editor selection" msgstr "Редактор выделения" -#: ../editors/DataTypeEditor.py:347 +msgid "Elapsed time of ramp" +msgstr "Прошедшее время нарастания" + +#: ../editors/DataTypeEditor.py:348 msgid "Elements :" msgstr "Элементы:" -#: ../IDEFrame.py:341 +#: ../ProjectController.py:1300 +msgid "Empty" +msgstr "Нет программы" + +#: ../IDEFrame.py:365 msgid "Enable Undo/Redo" msgstr "Разрешить отмену и повтор операций" msgid "Enabled" msgstr "Разрешено" -#: ../Beremiz_service.py:299 +#: ../Beremiz_service.py:331 msgid "Enter a name " msgstr "Введите имя" -#: ../Beremiz_service.py:286 +#: ../Beremiz_service.py:316 msgid "Enter a port number " msgstr "Введите номер порта" -#: ../Beremiz_service.py:277 +#: ../Beremiz_service.py:307 msgid "Enter the IP of the interface to bind" msgstr "Введите IP-адрес используемого интерфейса" @@ -1551,66 +1587,67 @@ msgstr "Равно" #: ../dialogs/ForceVariableDialog.py:179 -#: ../dialogs/SearchInProjectDialog.py:157 ../dialogs/SFCStepNameDialog.py:59 +#: ../dialogs/SearchInProjectDialog.py:168 ../dialogs/SFCStepNameDialog.py:60 #: ../dialogs/DurationEditorDialog.py:121 -#: ../dialogs/DurationEditorDialog.py:163 ../dialogs/PouTransitionDialog.py:107 +#: ../dialogs/DurationEditorDialog.py:163 ../dialogs/PouTransitionDialog.py:112 #: ../dialogs/BlockPreviewDialog.py:236 ../dialogs/ProjectDialog.py:71 #: ../dialogs/ArrayTypeDialog.py:97 ../dialogs/ArrayTypeDialog.py:103 -#: ../dialogs/PouNameDialog.py:53 ../dialogs/BrowseLocationsDialog.py:211 +#: ../dialogs/PouNameDialog.py:54 ../dialogs/BrowseLocationsDialog.py:216 #: ../dialogs/BrowseValuesLibraryDialog.py:83 ../dialogs/PouActionDialog.py:104 -#: ../dialogs/PouDialog.py:134 ../PLCOpenEditor.py:328 ../PLCOpenEditor.py:333 -#: ../PLCOpenEditor.py:407 ../PLCOpenEditor.py:417 ../editors/Viewer.py:419 +#: ../dialogs/PouDialog.py:134 ../PLCOpenEditor.py:335 ../PLCOpenEditor.py:340 +#: ../PLCOpenEditor.py:420 ../PLCOpenEditor.py:430 ../editors/Viewer.py:423 #: ../editors/LDViewer.py:666 ../editors/LDViewer.py:882 -#: ../editors/LDViewer.py:886 ../editors/DataTypeEditor.py:549 -#: ../editors/DataTypeEditor.py:554 ../editors/DataTypeEditor.py:578 -#: ../editors/DataTypeEditor.py:583 ../editors/DataTypeEditor.py:593 -#: ../editors/DataTypeEditor.py:744 ../editors/DataTypeEditor.py:751 -#: ../editors/TextViewer.py:387 ../editors/CodeFileEditor.py:763 -#: ../ProjectController.py:269 ../controls/FolderTree.py:217 +#: ../editors/LDViewer.py:886 ../editors/DataTypeEditor.py:550 +#: ../editors/DataTypeEditor.py:555 ../editors/DataTypeEditor.py:579 +#: ../editors/DataTypeEditor.py:584 ../editors/DataTypeEditor.py:594 +#: ../editors/DataTypeEditor.py:745 ../editors/DataTypeEditor.py:752 +#: ../editors/TextViewer.py:389 ../editors/CodeFileEditor.py:783 +#: ../ProjectController.py:293 ../ProjectController.py:421 +#: ../ProjectController.py:428 ../controls/FolderTree.py:217 #: ../controls/DebugVariablePanel/DebugVariablePanel.py:166 #: ../controls/DebugVariablePanel/DebugVariableTextViewer.py:137 -#: ../controls/DebugVariablePanel/DebugVariableGraphicViewer.py:225 -#: ../controls/VariablePanel.py:392 ../controls/VariablePanel.py:754 -#: ../Beremiz.py:1167 ../IDEFrame.py:975 ../IDEFrame.py:1581 -#: ../IDEFrame.py:1618 ../IDEFrame.py:1623 ../IDEFrame.py:1637 -#: ../IDEFrame.py:1642 ../Beremiz_service.py:190 +#: ../controls/DebugVariablePanel/DebugVariableGraphicViewer.py:231 +#: ../controls/VariablePanel.py:402 ../controls/VariablePanel.py:772 +#: ../Beremiz.py:1203 ../IDEFrame.py:1003 ../IDEFrame.py:1614 +#: ../IDEFrame.py:1655 ../IDEFrame.py:1660 ../IDEFrame.py:1674 +#: ../IDEFrame.py:1679 ../Beremiz_service.py:211 msgid "Error" msgstr "Ошибка" -#: ../ProjectController.py:663 +#: ../ProjectController.py:727 msgid "Error : At least one configuration and one resource must be declared in PLC !\n" msgstr "Ошибка: Как минимум одна конфигурация и один ресурс должны быть задекларированы в ПЛК!\n" -#: ../ProjectController.py:655 +#: ../ProjectController.py:719 #, python-format msgid "Error : IEC to C compiler returned %d\n" msgstr "Ошибка: компилятор МЭК в C вернул код ошибки %d\n" -#: ../ProjectController.py:589 +#: ../ProjectController.py:621 #, python-format msgid "" "Error in ST/IL/SFC code generator :\n" "%s\n" msgstr "Ошибка в ST/IL/SFC кодогенераторе: %s\n" -#: ../ConfigTreeNode.py:192 +#: ../ConfigTreeNode.py:216 #, python-format msgid "Error while saving \"%s\"\n" msgstr "Ошибка во время сохранения \"%s\"\n" -#: ../canfestival/canfestival.py:144 +#: ../canfestival/canfestival.py:168 msgid "Error: Export slave failed\n" msgstr "Ошибка: неудачный экспорт ведомого\n" -#: ../canfestival/canfestival.py:345 +#: ../canfestival/canfestival.py:369 msgid "Error: No Master generated\n" msgstr "Ошибка: мастер не сгенерирован\n" -#: ../canfestival/canfestival.py:340 +#: ../canfestival/canfestival.py:364 msgid "Error: No PLC built\n" msgstr "Ошибка: ПЛК не собран\n" -#: ../ProjectController.py:1566 +#: ../ProjectController.py:1666 #, python-format msgid "Exception while connecting %s!\n" msgstr "Исключение во время подключения %s!\n" @@ -1623,7 +1660,7 @@ msgid "Execution Order:" msgstr "Порядок исполнения:" -#: ../features.py:11 +#: ../features.py:35 msgid "Experimental web based HMI" msgstr "Экспериментальный WEB-HMI" @@ -1635,7 +1672,7 @@ msgid "Exponentiation" msgstr "Взятие экспоненты" -#: ../canfestival/canfestival.py:150 +#: ../canfestival/canfestival.py:174 msgid "Export CanOpen slave to EDS file" msgstr "Экспортировать CanOpen ведомое устройство в EDS файл" @@ -1643,7 +1680,7 @@ msgid "Export graph values to clipboard" msgstr "Экспортировать график значений в буфер обмена" -#: ../canfestival/canfestival.py:149 +#: ../canfestival/canfestival.py:173 msgid "Export slave" msgstr "Экспортировать ведомое устройство" @@ -1655,35 +1692,38 @@ msgid "External" msgstr "Внешний" -#: ../ProjectController.py:676 +#: ../ProjectController.py:740 msgid "Extracting Located Variables...\n" msgstr "Экспорт локальных переменных...\n" -#: ../dialogs/PouTransitionDialog.py:35 ../dialogs/PouActionDialog.py:31 +msgid "FB for derivative term" +msgstr "ФБ дифференцирования" + +msgid "FB for integral term" +msgstr "ФД интегрирования" + +#: ../dialogs/PouTransitionDialog.py:40 ../dialogs/PouActionDialog.py:31 #: ../dialogs/PouDialog.py:36 ../controls/ProjectPropertiesPanel.py:143 msgid "FBD" -msgstr "" - -#: ../ProjectController.py:1629 +msgstr "FBD" + +#: ../ProjectController.py:1729 msgid "Failed : Must build before transfer.\n" msgstr "Ошибка: необходима сборка перед передачей.\n" -#: ../dialogs/LDElementDialog.py:77 ../editors/Viewer.py:458 +#: ../dialogs/LDElementDialog.py:77 ../editors/Viewer.py:462 msgid "Falling Edge" msgstr "Спадающий фронт" -#: ../plcopen/definitions.py:32 -msgid "" -"Falling edge detector\n" -"The output produces a single pulse when a falling edge is detected." -msgstr "" -"Детектор падающего фронта\n" -"На выходе формируется одиночный импульс, если обнаружен падающий фронт." - -#: ../ProjectController.py:946 +#: ../ProjectController.py:1008 msgid "Fatal : cannot get builder.\n" msgstr "Ошибка: невозможно получить сборщик.\n" +#: ../Beremiz.py:118 +#, python-format +msgid "Fetching %s" +msgstr "Проверка %s" + #: ../dialogs/DurationEditorDialog.py:160 #, python-format msgid "Field %s hasn't a valid value!" @@ -1699,16 +1739,16 @@ msgid "File '%s' already exists!" msgstr "Файл '%s' уже существует!" -#: ../dialogs/FindInPouDialog.py:35 ../dialogs/FindInPouDialog.py:105 -#: ../IDEFrame.py:351 +#: ../dialogs/SearchInProjectDialog.py:100 ../dialogs/FindInPouDialog.py:36 +#: ../dialogs/FindInPouDialog.py:106 ../IDEFrame.py:375 msgid "Find" msgstr "Поиск" -#: ../IDEFrame.py:353 +#: ../IDEFrame.py:377 msgid "Find Next" msgstr "Поиск следующего" -#: ../IDEFrame.py:355 +#: ../IDEFrame.py:379 msgid "Find Previous" msgstr "Поиск предыдущего" @@ -1720,11 +1760,11 @@ msgid "Find:" msgstr "Поиск:" -#: ../connectors/PYRO/__init__.py:159 +#: ../connectors/PYRO/__init__.py:163 msgid "Force runtime reload\n" msgstr "Принудительный перезапуск системы исполнения\n" -#: ../editors/Viewer.py:1528 +#: ../editors/Viewer.py:1553 msgid "Force value" msgstr "Фиксировать значение" @@ -1732,44 +1772,40 @@ msgid "Forcing Variable Value" msgstr "Форсировать значение переменной" -#: ../dialogs/SFCTransitionDialog.py:178 ../dialogs/PouTransitionDialog.py:97 +#: ../dialogs/SFCTransitionDialog.py:179 ../dialogs/PouTransitionDialog.py:102 #: ../dialogs/ProjectDialog.py:70 ../dialogs/PouActionDialog.py:94 #: ../dialogs/PouDialog.py:116 #, python-format msgid "Form isn't complete. %s must be filled!" msgstr "Форма заполнена неполностью. %s должен быть заполнен!" -#: ../dialogs/SFCStepDialog.py:141 ../dialogs/FBDBlockDialog.py:232 +#: ../dialogs/SFCStepDialog.py:144 ../dialogs/FBDBlockDialog.py:232 #: ../dialogs/ConnectionDialog.py:160 msgid "Form isn't complete. Name must be filled!" msgstr "Форма заполнена неполностью. Имя должно быть заполнено!" -#: ../dialogs/SearchInProjectDialog.py:145 -msgid "Form isn't complete. Pattern to search must be filled!" -msgstr "Форма заполнена неполностью. Шаблон поиска должен быть заполнен!" - #: ../dialogs/FBDBlockDialog.py:228 msgid "Form isn't complete. Valid block type must be selected!" msgstr "Форма заполнена неполностью. Должен быть выбран корректный тип блока!" -#: ../dialogs/FindInPouDialog.py:73 +#: ../dialogs/FindInPouDialog.py:74 msgid "Forward" msgstr "Вперед" -#: ../dialogs/SearchInProjectDialog.py:44 ../IDEFrame.py:1712 +#: ../dialogs/SearchInProjectDialog.py:36 ../IDEFrame.py:1746 msgid "Function" msgstr "Функция" -#: ../IDEFrame.py:325 +#: ../IDEFrame.py:349 msgid "Function &Block" msgstr "Функциональный &блок" -#: ../dialogs/SearchInProjectDialog.py:45 ../IDEFrame.py:1711 -#: ../IDEFrame.py:1904 +#: ../dialogs/SearchInProjectDialog.py:37 ../IDEFrame.py:1745 +#: ../IDEFrame.py:1938 msgid "Function Block" msgstr "Функциональный блок" -#: ../controls/VariablePanel.py:807 +#: ../controls/VariablePanel.py:825 msgid "Function Block Types" msgstr "Типы функциональных блоков" @@ -1777,11 +1813,11 @@ msgid "Function Blocks" msgstr "Функциональные блоки" -#: ../editors/Viewer.py:244 +#: ../editors/Viewer.py:248 msgid "Function Blocks can't be used in Functions!" msgstr "Функциональные блоки не могут использоваться в функциях!" -#: ../PLCControler.py:2336 +#: ../PLCControler.py:2337 #, python-format msgid "FunctionBlock \"%s\" can't be pasted in a Function!!!" msgstr "Функциональный блок \"%s\" не может быть вставлен в функцию!!!" @@ -1790,16 +1826,16 @@ msgid "Functions" msgstr "Функции" -#: ../PLCOpenEditor.py:109 +#: ../PLCOpenEditor.py:115 msgid "Generate Program" msgstr "Сгенерировать программу" -#: ../ProjectController.py:580 +#: ../ProjectController.py:612 msgid "Generating SoftPLC IEC-61131 ST/IL/SFC code...\n" msgstr "Генерация МЭК-61131 ST/IL/SFC кода ПЛК...\n" msgid "Generic" -msgstr "" +msgstr "Generic" #: ../controls/VariablePanel.py:73 msgid "Global" @@ -1825,6 +1861,10 @@ msgid "Grid Resolution:" msgstr "Шаг сетки:" +#: ../runtime/NevowServer.py:181 +msgid "HTTP interface port :" +msgstr "Порт HTTP-интерфейса :" + #: ../controls/ProjectPropertiesPanel.py:120 msgid "Height:" msgstr "Высота:" @@ -1841,67 +1881,54 @@ msgid "Hours:" msgstr "Часы:" -#: ../plcopen/definitions.py:44 -msgid "" -"Hysteresis\n" -"The hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2." -msgstr "" -"Гистерезис\n" -"Функциональный блок формирует дискретный выход с гистерезисом в зависимости от разницы двух вещественных входов XIN1 и XIN2." - msgid "IEC_Channel" msgstr "МЭК-канал" -#: ../dialogs/PouTransitionDialog.py:35 ../dialogs/PouActionDialog.py:31 -#: ../dialogs/PouDialog.py:36 +#: ../dialogs/PouActionDialog.py:31 ../dialogs/PouDialog.py:36 msgid "IL" -msgstr "" - -#: ../dialogs/DiscoveryDialog.py:93 +msgstr "IL" + +#: ../dialogs/DiscoveryDialog.py:94 msgid "IP" -msgstr "" - -#: ../Beremiz_service.py:278 ../Beremiz_service.py:279 +msgstr "IP" + +#: ../Beremiz_service.py:308 ../Beremiz_service.py:309 msgid "IP is not valid!" msgstr "Неверный IP-адрес" -#: ../svgui/svgui.py:18 ../svgui/svgui.py:19 +#: ../svgui/svgui.py:42 ../svgui/svgui.py:43 msgid "Import SVG" msgstr "Импорт SVG" -#: ../dialogs/FBDVariableDialog.py:38 ../editors/Viewer.py:1555 +#: ../dialogs/FBDVariableDialog.py:38 ../editors/Viewer.py:1580 #: ../controls/VariablePanel.py:71 msgid "InOut" msgstr "Вход/Выход" -#: ../editors/Viewer.py:1087 +#: ../editors/Viewer.py:1100 msgid "Inactive" msgstr "Неактивный" -#: ../controls/VariablePanel.py:268 -#, python-format -msgid "Incompatible data types between \"%s\" and \"%s\"" -msgstr "\"%s\" и \"%s\" имеют несовместимые типы данных" - -#: ../controls/VariablePanel.py:277 -#, python-format -msgid "Incompatible size of data between \"%s\" and \"%s\"" -msgstr "\"%s\" и \"%s\" имеют несовместимый размер данных" - -#: ../controls/VariablePanel.py:273 +#: ../controls/VariablePanel.py:276 +#, python-brace-format +msgid "Incompatible data types between \"{a1}\" and \"{a2}\"" +msgstr "\"{a1}\" и \"{a2}\" имеют несовместимые типы данных" + +#: ../controls/VariablePanel.py:282 #, python-format msgid "Incompatible size of data between \"%s\" and \"BOOL\"" msgstr "Несовместимый размер данных \"%s\" с типом \"BOOL\"" +#: ../controls/VariablePanel.py:286 +#, python-brace-format +msgid "Incompatible size of data between \"{a1}\" and \"{a2}\"" +msgstr "\"{a1}\" и \"{a2}\" имеют несовместимый размер данных" + #: ../dialogs/ActionBlockDialog.py:38 msgid "Indicator" msgstr "Индикатор" -#: ../editors/CodeFileEditor.py:663 -msgid "Initial" -msgstr "Исходное значение" - -#: ../editors/Viewer.py:548 ../editors/Viewer.py:2058 +#: ../editors/Viewer.py:552 msgid "Initial Step" msgstr "Исходный шаг" @@ -1910,25 +1937,36 @@ msgid "Initial Value" msgstr "Исходное значение" -#: ../editors/DataTypeEditor.py:184 ../editors/DataTypeEditor.py:215 -#: ../editors/DataTypeEditor.py:271 ../editors/DataTypeEditor.py:309 +#: ../editors/DataTypeEditor.py:185 ../editors/DataTypeEditor.py:216 +#: ../editors/DataTypeEditor.py:272 ../editors/DataTypeEditor.py:310 msgid "Initial Value:" msgstr "Исходное значение:" -#: ../svgui/svgui.py:22 +msgid "Initial value" +msgstr "Исходное значение" + +#: ../svgui/svgui.py:46 msgid "Inkscape" -msgstr "" - -#: ../dialogs/SFCTransitionDialog.py:74 ../dialogs/ActionBlockDialog.py:42 +msgstr "Inkscape" + +#: ../dialogs/SFCTransitionDialog.py:75 ../dialogs/ActionBlockDialog.py:42 msgid "Inline" msgstr "Непосредственно" -#: ../dialogs/SFCStepDialog.py:69 ../dialogs/FBDVariableDialog.py:37 -#: ../dialogs/BrowseLocationsDialog.py:35 ../editors/Viewer.py:1553 -#: ../controls/VariablePanel.py:71 +#: ../dialogs/SFCStepDialog.py:70 ../dialogs/FBDVariableDialog.py:37 +#: ../dialogs/BrowseLocationsDialog.py:40 ../editors/Viewer.py:289 +#: ../editors/Viewer.py:1578 ../editors/TextViewer.py:307 +#: ../controls/LocationCellEditor.py:98 ../controls/VariablePanel.py:71 +#: ../controls/VariablePanel.py:291 ../controls/VariablePanel.py:351 msgid "Input" msgstr "Вход" +msgid "Input to be differentiated" +msgstr "Вход для дифференцирования" + +msgid "Input variable" +msgstr "Входная переменная" + #: ../dialogs/FBDBlockDialog.py:93 msgid "Inputs:" msgstr "Входы:" @@ -1937,7 +1975,7 @@ msgid "Insertion (into)" msgstr "Вставка подстроки" -#: ../plcopen/plcopen.py:1684 +#: ../plcopen/plcopen.py:1691 #, python-format msgid "Instance with id %d doesn't exist!" msgstr "Экземпляр с id %d не существует!" @@ -1946,13 +1984,8 @@ msgid "Instances:" msgstr "Экземпляры:" -#: ../plcopen/definitions.py:40 -msgid "" -"Integral\n" -"The integral function block integrates the value of input XIN over time." -msgstr "" -"Интеграл\n" -"Функциональный блок интегрирует входное значение XIN во времени." +msgid "Integrated output" +msgstr "Интегрированный выход" #: ../controls/VariablePanel.py:70 msgid "Interface" @@ -1966,36 +1999,41 @@ msgid "Interval" msgstr "Интервал" -#: ../PLCControler.py:2324 +#: ../PLCControler.py:2325 msgid "Invalid plcopen element(s)!!!" msgstr "Некорректный PlcOpen элемент(ы)!!!" -#: ../canfestival/config_utils.py:377 ../canfestival/config_utils.py:638 -#, python-format -msgid "Invalid type \"%s\"-> %d != %d for location\"%s\"" -msgstr "Неправильный тип \"%s\"->\"%d != %d для \"%s\"" - -#: ../dialogs/ForceVariableDialog.py:177 -#, python-format -msgid "Invalid value \"%s\" for \"%s\" variable!" -msgstr "Неверное значение \"%s\" для переменной \"%s\"!" +#: ../canfestival/config_utils.py:381 +#, python-brace-format +msgid "Invalid type \"{a1}\"-> {a2} != {a3} for location\"{a4}\"" +msgstr "Неправильный тип \"{a1}\"-> {a2} != {a3} для \"{a4}\"" + +#: ../canfestival/config_utils.py:645 +#, python-brace-format +msgid "Invalid type \"{a1}\"-> {a2} != {a3} for location \"{a4}\"" +msgstr "Неправильный тип \"{a1}\"-> {a2} != {a3} для \"{a4}\"" #: ../controls/DebugVariablePanel/DebugVariablePanel.py:132 #: ../controls/DebugVariablePanel/DebugVariableTextViewer.py:92 -#: ../controls/DebugVariablePanel/DebugVariableGraphicViewer.py:160 +#: ../controls/DebugVariablePanel/DebugVariableGraphicViewer.py:166 #, python-format msgid "Invalid value \"%s\" for debug variable" msgstr "Неверное значение \"%s\" для отлаживаемой переменной" -#: ../controls/VariablePanel.py:247 ../controls/VariablePanel.py:250 +#: ../controls/VariablePanel.py:255 ../controls/VariablePanel.py:258 #, python-format msgid "Invalid value \"%s\" for variable grid element" -msgstr "" - -#: ../editors/Viewer.py:229 ../editors/Viewer.py:232 +msgstr "Неверное значение \"%s\" для значения размещения переменной" + +#: ../editors/Viewer.py:233 ../editors/Viewer.py:236 #, python-format msgid "Invalid value \"%s\" for viewer block" -msgstr "" +msgstr "Неверное значение \"%s\" для вставки в редактор" + +#: ../dialogs/ForceVariableDialog.py:177 +#, python-brace-format +msgid "Invalid value \"{a1}\" for \"{a2}\" variable!" +msgstr "Неверное значение \"{a1}\" для переменной \"{a2}\"!" #: ../dialogs/DurationEditorDialog.py:121 msgid "" @@ -2005,24 +2043,24 @@ "Неверное значение!\n" "Необходимо ввести числовое значение." -#: ../editors/Viewer.py:553 ../editors/Viewer.py:2062 +#: ../editors/Viewer.py:557 ../editors/Viewer.py:2343 msgid "Jump" -msgstr "Переход" - -#: ../dialogs/PouTransitionDialog.py:35 ../dialogs/PouActionDialog.py:31 +msgstr "Безусловный переход" + +#: ../dialogs/PouTransitionDialog.py:40 ../dialogs/PouActionDialog.py:31 #: ../dialogs/PouDialog.py:36 ../controls/ProjectPropertiesPanel.py:143 msgid "LD" -msgstr "" +msgstr "LD" msgid "LDFLAGS" -msgstr "" +msgstr "LDFLAGS" #: ../editors/LDViewer.py:215 ../editors/LDViewer.py:231 #, python-format msgid "Ladder element with id %d is on more than one rung." msgstr "Элемент лестничной диаграммы с id %d более чем на одной ступени." -#: ../dialogs/PouTransitionDialog.py:86 ../dialogs/PouActionDialog.py:83 +#: ../dialogs/PouTransitionDialog.py:91 ../dialogs/PouActionDialog.py:83 #: ../dialogs/PouDialog.py:104 msgid "Language" msgstr "Язык" @@ -2031,28 +2069,28 @@ msgid "Language (optional):" msgstr "Язык (опционально):" -#: ../dialogs/PouTransitionDialog.py:60 ../dialogs/PouActionDialog.py:56 +#: ../dialogs/PouTransitionDialog.py:65 ../dialogs/PouActionDialog.py:56 #: ../dialogs/PouDialog.py:73 msgid "Language:" msgstr "Язык:" -#: ../ProjectController.py:1635 +#: ../ProjectController.py:1735 msgid "Latest build already matches current target. Transfering anyway...\n" msgstr "Загружаемая программа совпадает с текущий программой в целевом ПЛК. Загрузка продолжена...\n" -#: ../Beremiz_service.py:250 +#: ../Beremiz_service.py:271 msgid "Launch WX GUI inspector" msgstr "Запустить WX GUI Inspector" -#: ../Beremiz_service.py:249 +#: ../Beremiz_service.py:270 msgid "Launch a live Python shell" msgstr "Запустить консоль Python" -#: ../editors/Viewer.py:481 +#: ../editors/Viewer.py:485 msgid "Left" msgstr "Слева" -#: ../dialogs/LDPowerRailDialog.py:61 +#: ../dialogs/LDPowerRailDialog.py:62 msgid "Left PowerRail" msgstr "Левая шина питания" @@ -2071,9 +2109,13 @@ msgid "Libraries" msgstr "Библиотеки" -#: ../IDEFrame.py:603 +#: ../IDEFrame.py:631 msgid "Library" -msgstr "Библиотека" +msgstr "Библиотеки" + +#: ../dialogs/AboutDialog.py:143 +msgid "License" +msgstr "Лицензия" #: ../plcopen/iec_std.csv:73 msgid "Limitation" @@ -2082,22 +2124,22 @@ msgid "Linker" msgstr "Линковщик" -#: ../targets/toolchain_gcc.py:142 +#: ../targets/toolchain_gcc.py:166 msgid "Linking :\n" msgstr "Линковка:\n" msgid "Linux" msgstr "GNU/Linux" -#: ../dialogs/DiscoveryDialog.py:110 ../controls/VariablePanel.py:72 +#: ../dialogs/DiscoveryDialog.py:111 ../controls/VariablePanel.py:72 msgid "Local" msgstr "Локальный" -#: ../canfestival/canfestival.py:322 +#: ../canfestival/canfestival.py:346 msgid "Local entries" msgstr "Локальные записи" -#: ../ProjectController.py:1541 +#: ../ProjectController.py:1641 msgid "Local service discovery failed!\n" msgstr "Локальный сервис не найден!\n" @@ -2105,7 +2147,7 @@ msgid "Location" msgstr "Размещение" -#: ../dialogs/BrowseLocationsDialog.py:67 +#: ../dialogs/BrowseLocationsDialog.py:72 msgid "Locations available:" msgstr "Доступные размещения:" @@ -2113,41 +2155,46 @@ msgid "Logarithm to base 10" msgstr "Десятичный логарифм" -#: ../connectors/PYRO/__init__.py:90 +#: ../connectors/PYRO/__init__.py:94 #, python-format msgid "MDNS resolution failure for '%s'\n" msgstr "MDNS разрешение неудачно для '%s'\n" -#: ../canfestival/SlaveEditor.py:41 ../canfestival/NetworkEditor.py:62 +msgid "Manual output adjustment - Typically from transfer station" +msgstr "Ручной выход" + +#: ../canfestival/SlaveEditor.py:64 ../canfestival/NetworkEditor.py:85 msgid "Map Variable" msgstr "Отображение переменной" -#: ../features.py:7 +#: ../features.py:31 msgid "Map located variables over CANopen" msgstr "Отображение переменных по CANopen" -#: ../canfestival/NetworkEditor.py:83 +#: ../canfestival/NetworkEditor.py:106 msgid "Master" msgstr "Ведущий" -#: ../ConfigTreeNode.py:514 -#, python-format -msgid "Max count (%d) reached for this confnode of type %s " -msgstr "Достигнуто максимальное количество (%d) для типа узла конфигурации %s" +#: ../ConfigTreeNode.py:539 +#, python-brace-format +msgid "Max count ({a1}) reached for this confnode of type {a2} " +msgstr "Достигнуто максимальное количество ({a1}) для типа узла конфигурации {a2} " #: ../plcopen/iec_std.csv:71 msgid "Maximum" msgstr "Максимум" -#: ../editors/DataTypeEditor.py:238 +#: ../editors/DataTypeEditor.py:239 msgid "Maximum:" msgstr "Максимум:" -#: ../dialogs/BrowseLocationsDialog.py:37 +#: ../dialogs/BrowseLocationsDialog.py:42 ../editors/Viewer.py:289 +#: ../editors/TextViewer.py:307 ../controls/LocationCellEditor.py:98 +#: ../controls/VariablePanel.py:291 ../controls/VariablePanel.py:351 msgid "Memory" msgstr "Память" -#: ../IDEFrame.py:571 +#: ../IDEFrame.py:599 msgid "Menu ToolBar" msgstr "Меню" @@ -2155,7 +2202,7 @@ msgid "Microseconds:" msgstr "Микросекунды:" -#: ../editors/Viewer.py:486 +#: ../editors/Viewer.py:490 msgid "Middle" msgstr "Посередине" @@ -2167,7 +2214,7 @@ msgid "Minimum" msgstr "Минимум" -#: ../editors/DataTypeEditor.py:225 +#: ../editors/DataTypeEditor.py:226 msgid "Minimum:" msgstr "Минимум:" @@ -2183,10 +2230,10 @@ msgid "Modifier:" msgstr "Модификатор:" -#: ../PLCGenerator.py:778 ../PLCGenerator.py:1217 -#, python-format -msgid "More than one connector found corresponding to \"%s\" continuation in \"%s\" POU" -msgstr "Более одного коннектора соответствуют продолжению цепи \"%s\" в POU \"%s\"" +#: ../PLCGenerator.py:786 ../PLCGenerator.py:1230 +#, python-brace-format +msgid "More than one connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU" +msgstr "Более одного коннектора соответствуют продолжению цепи \"{a1}\" в POU \"{a2}\"" #: ../dialogs/ActionBlockDialog.py:140 msgid "Move action down" @@ -2200,11 +2247,11 @@ msgid "Move down" msgstr "Переместить ниже" -#: ../editors/DataTypeEditor.py:354 +#: ../editors/DataTypeEditor.py:355 msgid "Move element down" msgstr "Переместить элемент ниже" -#: ../editors/DataTypeEditor.py:353 +#: ../editors/DataTypeEditor.py:354 msgid "Move element up" msgstr "Переместить элементы выше" @@ -2224,7 +2271,7 @@ msgid "Move task up" msgstr "Переместить задачу выше" -#: ../IDEFrame.py:75 ../IDEFrame.py:90 ../IDEFrame.py:120 ../IDEFrame.py:161 +#: ../IDEFrame.py:99 ../IDEFrame.py:114 ../IDEFrame.py:144 ../IDEFrame.py:185 msgid "Move the view" msgstr "Переместить отображение" @@ -2232,11 +2279,11 @@ msgid "Move up" msgstr "Переместить выше" -#: ../editors/CodeFileEditor.py:643 ../controls/VariablePanel.py:443 +#: ../editors/CodeFileEditor.py:661 ../controls/VariablePanel.py:453 msgid "Move variable down" msgstr "Переместить переменную ниже" -#: ../editors/CodeFileEditor.py:642 ../controls/VariablePanel.py:442 +#: ../editors/CodeFileEditor.py:660 ../controls/VariablePanel.py:452 msgid "Move variable up" msgstr "Переместить переменную выше" @@ -2252,21 +2299,24 @@ msgid "My Computer:" msgstr "Мой компьютер:" -#: ../dialogs/DiscoveryDialog.py:91 +#: ../dialogs/DiscoveryDialog.py:92 msgid "NAME" msgstr "Имя" +msgid "NOT R1" +msgstr "НЕ R1" + #: ../editors/ResourceEditor.py:68 ../editors/ResourceEditor.py:83 -#: ../editors/DataTypeEditor.py:50 ../editors/CodeFileEditor.py:663 -#: ../controls/VariablePanel.py:53 ../controls/VariablePanel.py:54 +#: ../editors/DataTypeEditor.py:50 ../controls/VariablePanel.py:53 +#: ../controls/VariablePanel.py:54 msgid "Name" msgstr "Имя" -#: ../Beremiz_service.py:300 +#: ../Beremiz_service.py:332 msgid "Name must not be null!" msgstr "Имя не может быть null!" -#: ../dialogs/SFCStepDialog.py:55 ../dialogs/FBDBlockDialog.py:83 +#: ../dialogs/SFCStepDialog.py:56 ../dialogs/FBDBlockDialog.py:83 #: ../dialogs/ConnectionDialog.py:75 msgid "Name:" msgstr "Имя:" @@ -2275,12 +2325,20 @@ msgid "Natural logarithm" msgstr "Натуральный логарифм" -#: ../dialogs/LDElementDialog.py:75 ../editors/Viewer.py:456 +#: ../dialogs/LDElementDialog.py:75 ../editors/Viewer.py:460 msgid "Negated" msgstr "Инверсия" -#: ../PLCOpenEditor.py:96 ../PLCOpenEditor.py:138 ../Beremiz.py:314 -#: ../Beremiz.py:349 +#: ../Beremiz_service.py:578 +msgid "Nevow Web service failed. " +msgstr "Ошибка Web сервиса Nevow. " + +#: ../Beremiz_service.py:554 +msgid "Nevow/Athena import failed :" +msgstr "Ошибка импорта Nevow/Athena :" + +#: ../PLCOpenEditor.py:102 ../PLCOpenEditor.py:144 ../Beremiz.py:321 +#: ../Beremiz.py:356 msgid "New" msgstr "Новый" @@ -2288,25 +2346,25 @@ msgid "New item" msgstr "Новый элемент" -#: ../editors/Viewer.py:455 +#: ../editors/Viewer.py:459 msgid "No Modifier" msgstr "Нет модификатора" -#: ../ProjectController.py:1662 +#: ../ProjectController.py:1763 msgid "No PLC to transfer (did build succeed ?)\n" msgstr "Нет ПЛК для передачи (была сборка успешна?)\n" -#: ../PLCGenerator.py:1608 +#: ../PLCGenerator.py:1631 #, python-format msgid "No body defined in \"%s\" POU" msgstr "Нет тела для POU \"%s\"" -#: ../PLCGenerator.py:797 ../PLCGenerator.py:1227 -#, python-format -msgid "No connector found corresponding to \"%s\" continuation in \"%s\" POU" -msgstr "Не найден коннектор, соответствующий продолжению цепи \"%s\" в POU \"%s\"" - -#: ../PLCOpenEditor.py:340 +#: ../PLCGenerator.py:806 ../PLCGenerator.py:1241 +#, python-brace-format +msgid "No connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU" +msgstr "Не найден коннектор, соответствующий продолжению цепи \"{a1}\" в POU \"{a2}\"" + +#: ../PLCOpenEditor.py:347 msgid "" "No documentation available.\n" "Coming soon." @@ -2314,40 +2372,40 @@ "Документация отсутствует.\n" "В разработке." -#: ../PLCGenerator.py:819 +#: ../PLCGenerator.py:829 #, python-format msgid "No informations found for \"%s\" block" msgstr "Не найдена информация по блоку \"%s\"" -#: ../PLCGenerator.py:1183 -#, python-format -msgid "No output %s variable found in block %s in POU %s. Connection must be broken" -msgstr "Выходная переменная %s не найдена в блоке %s в POU %s." +#: ../PLCGenerator.py:1194 +#, python-brace-format +msgid "No output {a1} variable found in block {a2} in POU {a3}. Connection must be broken" +msgstr "Выходная переменная {a1} не найдена в блоке {a2} в POU {a3}." #: ../controls/SearchResultPanel.py:169 msgid "No search results available." msgstr "Ничего не найдено." -#: ../svgui/svgui.py:107 +#: ../svgui/svgui.py:131 #, python-format msgid "No such SVG file: %s\n" msgstr "Нет такого SVG файла: %s\n" -#: ../canfestival/config_utils.py:633 -#, python-format -msgid "No such index/subindex (%x,%x) (variable %s)" -msgstr "Нет индекса/подиндекса (%x,%x) (переменная %s)" +#: ../canfestival/config_utils.py:639 +#, python-brace-format +msgid "No such index/subindex ({a1},{a2}) (variable {a3})" +msgstr "Нет индекса/подиндекса ({a1},{a2}) (переменная {a3})" #: ../canfestival/config_utils.py:362 -#, python-format -msgid "No such index/subindex (%x,%x) in ID : %d (variable %s)" -msgstr "Нет индекса/подиндекса (%x,%x) в ID: %d (переменная %s)" +#, python-brace-format +msgid "No such index/subindex ({a1},{a2}) in ID : {a3} (variable {a4})" +msgstr "Нет индекса/подиндекса ({a1},{a2}) в ID: {a3} (переменная {a4})" #: ../dialogs/BrowseValuesLibraryDialog.py:83 msgid "No valid value selected!" msgstr "Не выбрано допустимое значение!" -#: ../PLCGenerator.py:1606 +#: ../PLCGenerator.py:1629 #, python-format msgid "No variable defined in \"%s\" POU" msgstr "Переменная не определена в POU \"%s\"" @@ -2356,9 +2414,9 @@ msgstr "ID узла" #: ../canfestival/config_utils.py:355 -#, python-format -msgid "Non existing node ID : %d (variable %s)" -msgstr "Несуществующий ID узла: %d (переменная %s)" +#, python-brace-format +msgid "Non existing node ID : {a1} (variable {a2})" +msgstr "Несуществующий ID узла: {a1} (переменная {a2})" #: ../controls/VariablePanel.py:64 msgid "Non-Retain" @@ -2368,16 +2426,16 @@ msgid "Normal" msgstr "Обычный" -#: ../canfestival/config_utils.py:384 -#, python-format -msgid "Not PDO mappable variable : '%s' (ID:%d,Idx:%x,sIdx:%x))" -msgstr "Не переменная для отображения в PDO: '%s' (ID:%d,Idx:%x,sIdx:%x))" +#: ../canfestival/config_utils.py:389 +#, python-brace-format +msgid "Not PDO mappable variable : '{a1}' (ID:{a2},Idx:{a3},sIdx:{a4}))" +msgstr "Не переменная для отображения в PDO: '{a1}' (ID:{a2},Idx:{a3},sIdx:{a4}))" #: ../plcopen/iec_std.csv:80 msgid "Not equal to" msgstr "Не равно" -#: ../dialogs/SFCDivergenceDialog.py:78 +#: ../dialogs/SFCDivergenceDialog.py:89 msgid "Number of sequences:" msgstr "Число ветвей:" @@ -2385,44 +2443,28 @@ msgid "Numerical" msgstr "Математические функции" -#: ../plcopen/definitions.py:38 -msgid "" -"Off-delay timer\n" -"The off-delay timer can be used to delay setting an output false, for fixed period after input goes false." -msgstr "" -"Таймер выключения\n" -"Таймер выключения может быть использован, чтобы внести задержку установки выхода в FALSE на фиксированный период времени после того, как вход стал FALSE." - -#: ../plcopen/definitions.py:37 -msgid "" -"On-delay timer\n" -"The on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true." -msgstr "" -"Таймер включения\n" -"Таймер выключения может быть использован, чтобы внести задержку установки выхода в TRUE на фиксированный период времени после того, как вход стал TRUE." - -#: ../editors/CodeFileEditor.py:664 -msgid "OnChange" -msgstr "" - -#: ../dialogs/SearchInProjectDialog.py:93 +#: ../dialogs/SearchInProjectDialog.py:86 msgid "Only Elements" msgstr "Только элементы" -#: ../PLCOpenEditor.py:98 ../PLCOpenEditor.py:139 ../Beremiz.py:316 -#: ../Beremiz.py:350 +#: ../PLCOpenEditor.py:104 ../PLCOpenEditor.py:145 ../Beremiz.py:323 +#: ../Beremiz.py:357 msgid "Open" msgstr "Открыть" -#: ../svgui/svgui.py:116 +#: ../svgui/svgui.py:140 msgid "Open Inkscape" msgstr "Открыть Inkscape" -#: ../ProjectController.py:1714 +#: ../version.py:66 +msgid "Open Source framework for automation, implemented IEC 61131 IDE with constantly growing set of extensions and flexible PLC runtime." +msgstr "Свободное программное обеспечение для промышленной автоматизации, состоящие из среды разработки программ по стандарту МЭК 61131 с постоянно расширяющимся набором плагинов и гибкой системой исполнения для ПЛК." + +#: ../ProjectController.py:1815 msgid "Open a file explorer to manage project files" msgstr "Открыть файловый менеджер для просмотра файлов проекта" -#: ../wxglade_hmi/wxglade_hmi.py:114 +#: ../wxglade_hmi/wxglade_hmi.py:138 msgid "Open wxGlade" msgstr "Открыть wxGlade" @@ -2430,7 +2472,7 @@ msgid "Option" msgstr "Настройка" -#: ../dialogs/FindInPouDialog.py:82 ../editors/CodeFileEditor.py:664 +#: ../dialogs/FindInPouDialog.py:83 msgid "Options" msgstr "Настройки" @@ -2438,62 +2480,80 @@ msgid "Organization (optional):" msgstr "Организация (опционально):" -#: ../canfestival/SlaveEditor.py:51 ../canfestival/NetworkEditor.py:72 +#: ../canfestival/SlaveEditor.py:74 ../canfestival/NetworkEditor.py:95 msgid "Other Profile" msgstr "Другой профиль" -#: ../dialogs/SFCStepDialog.py:70 ../dialogs/FBDVariableDialog.py:39 -#: ../dialogs/BrowseLocationsDialog.py:36 ../editors/Viewer.py:1554 -#: ../controls/VariablePanel.py:71 +#: ../dialogs/SFCStepDialog.py:71 ../dialogs/FBDVariableDialog.py:39 +#: ../dialogs/BrowseLocationsDialog.py:41 ../editors/Viewer.py:289 +#: ../editors/Viewer.py:1579 ../editors/TextViewer.py:307 +#: ../controls/LocationCellEditor.py:98 ../controls/VariablePanel.py:71 +#: ../controls/VariablePanel.py:291 ../controls/VariablePanel.py:351 msgid "Output" msgstr "Выход" -#: ../canfestival/SlaveEditor.py:40 ../canfestival/NetworkEditor.py:61 +msgid "Overriding reset" +msgstr "Сброс интегратора" + +#: ../canfestival/SlaveEditor.py:63 ../canfestival/NetworkEditor.py:84 msgid "PDO Receive" msgstr "PDO приема" -#: ../canfestival/SlaveEditor.py:39 ../canfestival/NetworkEditor.py:60 +#: ../canfestival/SlaveEditor.py:62 ../canfestival/NetworkEditor.py:83 msgid "PDO Transmit" msgstr "PDO передачи" -#: ../plcopen/definitions.py:42 -msgid "" -"PID\n" -"The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control." -msgstr "" -"ПИД\n" -"ПИД (Пропорциональный Интегральный Дифференциальный) ФБ - классический регулятор, используемый в системах с обратной связью." - -#: ../targets/toolchain_gcc.py:107 +msgid "PLC" +msgstr "ПЛК" + +#: ../targets/toolchain_gcc.py:131 msgid "PLC :\n" msgstr "ПЛК:\n" -#: ../Beremiz.py:441 +#: ../Beremiz.py:453 msgid "PLC Log" msgstr "Лог ПЛК" -#: ../ProjectController.py:930 +#: ../ProjectController.py:992 msgid "PLC code generation failed !\n" msgstr "Неудачная генерация кода!\n" -#: ../PLCOpenEditor.py:189 ../PLCOpenEditor.py:302 -#, python-format +#: ../Beremiz_service.py:295 +msgid "PLC is empty or already started." +msgstr "В ПЛК нет программы или он уже запущен." + +#: ../Beremiz_service.py:302 +msgid "PLC is not started." +msgstr "ПЛК незапущен." + +#: ../PLCOpenEditor.py:196 ../PLCOpenEditor.py:309 +#, python-brace-format msgid "" -"PLC syntax error at line %d:\n" -"%s" +"PLC syntax error at line {a1}:\n" +"{a2}" msgstr "" -"Синтаксическая ошибка в строке %d:\n" -"%s" - -#: ../PLCOpenEditor.py:285 ../PLCOpenEditor.py:361 +"Синтаксическая ошибка в строке {a1}:\n" +"{a2}" + +#: ../PLCOpenEditor.py:292 ../PLCOpenEditor.py:373 msgid "PLCOpen files (*.xml)|*.xml|All files|*.*" msgstr "PLCOpen файлы (*.xml)|*.xml|All files|*.*" -#: ../PLCOpenEditor.py:146 ../PLCOpenEditor.py:202 +#: ../PLCOpenEditor.py:152 ../PLCOpenEditor.py:209 msgid "PLCOpenEditor" +msgstr "PLCOpenEditor" + +#: ../PLCOpenEditor.py:355 +msgid "" +"PLCOpenEditor is part of Beremiz project.\n" +"\n" +"Beremiz is an " msgstr "" - -#: ../dialogs/DiscoveryDialog.py:94 +"PLCOpenEditor является частью проекта Beremiz.\n" +"\n" +"Beremiz — " + +#: ../dialogs/DiscoveryDialog.py:95 msgid "PORT" msgstr "Порт" @@ -2513,17 +2573,20 @@ msgid "POU Type:" msgstr "Тип POU:" -#: ../connectors/PYRO/__init__.py:41 +msgid "PV - SP" +msgstr "Ошибка, PV - SP" + +#: ../connectors/PYRO/__init__.py:45 #, python-format msgid "PYRO connecting to URI : %s\n" msgstr "PYRO подключение к URI: %s\n" -#: ../connectors/PYRO/__init__.py:57 +#: ../connectors/PYRO/__init__.py:61 #, python-format msgid "PYRO using certificates in '%s' \n" msgstr "PYRO использует сертификаты в '%s'\n" -#: ../PLCOpenEditor.py:112 ../Beremiz.py:329 +#: ../PLCOpenEditor.py:118 ../Beremiz.py:336 msgid "Page Setup" msgstr "Настройки страницы" @@ -2531,7 +2594,7 @@ msgid "Page Size (optional):" msgstr "Размер страницы (опционально):" -#: ../IDEFrame.py:2565 +#: ../IDEFrame.py:2599 #, python-format msgid "Page: %d" msgstr "Страница: %d" @@ -2540,62 +2603,69 @@ msgid "Parent instance" msgstr "Родительский экземпляр" -#: ../editors/Viewer.py:594 ../IDEFrame.py:348 ../IDEFrame.py:402 +#: ../editors/Viewer.py:598 ../IDEFrame.py:372 ../IDEFrame.py:426 msgid "Paste" msgstr "Вставить" -#: ../IDEFrame.py:1831 +#: ../IDEFrame.py:1865 msgid "Paste POU" msgstr "Вставить POU" -#: ../dialogs/SearchInProjectDialog.py:64 +#: ../dialogs/SearchInProjectDialog.py:56 msgid "Pattern to search:" msgstr "Шаблон поиска:" -#: ../dialogs/LDPowerRailDialog.py:72 +#: ../dialogs/LDPowerRailDialog.py:73 msgid "Pin number:" msgstr "Номер пина:" -#: ../editors/Viewer.py:2672 ../editors/Viewer.py:2916 -#: ../editors/SFCViewer.py:696 +#: ../editors/Viewer.py:2706 ../editors/Viewer.py:2963 +#: ../editors/SFCViewer.py:770 msgid "Please choose a target" -msgstr "Выберете цель перехода" - -#: ../editors/TextViewer.py:261 +msgstr "Выберите цель перехода" + +#: ../editors/TextViewer.py:262 msgid "Please enter a block name" msgstr "Введите имя блока" -#: ../editors/Viewer.py:2542 ../editors/Viewer.py:2953 +#: ../editors/Viewer.py:2576 ../editors/Viewer.py:3005 msgid "Please enter comment text" msgstr "Введите текст комментария" -#: ../editors/SFCViewer.py:359 ../editors/SFCViewer.py:381 -#: ../editors/SFCViewer.py:725 +#: ../editors/SFCViewer.py:433 ../editors/SFCViewer.py:455 +#: ../editors/SFCViewer.py:799 msgid "Please enter step name" msgstr "Введите имя шага" +#: ../Beremiz_service.py:194 +msgid "Please enter text" +msgstr "Введите текст" + #: ../dialogs/ForceVariableDialog.py:163 #, python-format msgid "Please enter value for a \"%s\" variable:" msgstr "Введите значение для переменной \"%s\":" -#: ../Beremiz_service.py:287 +#: ../Beremiz_service.py:317 msgid "Port number must be 0 <= port <= 65535!" msgstr "Номер порта должен быть в диапазоне от 0 до 65535!" -#: ../Beremiz_service.py:287 +#: ../Beremiz_service.py:317 msgid "Port number must be an integer!" msgstr "Номер порта должен быть целым числом!" -#: ../editors/Viewer.py:532 ../editors/Viewer.py:2085 +#: ../editors/Viewer.py:536 ../editors/Viewer.py:2367 msgid "Power Rail" msgstr "Шина питания" -#: ../dialogs/LDPowerRailDialog.py:49 +#: ../dialogs/LDPowerRailDialog.py:50 msgid "Power Rail Properties" msgstr "Свойства шины питания" -#: ../PLCOpenEditor.py:114 ../Beremiz.py:331 +msgid "Preset datetime" +msgstr "Основное время" + +#: ../PLCOpenEditor.py:120 ../Beremiz.py:338 msgid "Preview" msgstr "Просмотр" @@ -2603,12 +2673,12 @@ msgid "Preview:" msgstr "Просмотр:" -#: ../PLCOpenEditor.py:116 ../PLCOpenEditor.py:142 ../Beremiz.py:333 -#: ../Beremiz.py:353 +#: ../PLCOpenEditor.py:122 ../PLCOpenEditor.py:148 ../Beremiz.py:340 +#: ../Beremiz.py:360 msgid "Print" msgstr "Печать" -#: ../IDEFrame.py:1047 +#: ../IDEFrame.py:1075 msgid "Print preview" msgstr "Предварительный просмотр" @@ -2616,15 +2686,18 @@ msgid "Priority" msgstr "Приоритет" -#: ../dialogs/SFCTransitionDialog.py:88 +#: ../dialogs/SFCTransitionDialog.py:89 msgid "Priority:" msgstr "Приоритет:" -#: ../runtime/PLCObject.py:369 +#: ../runtime/PLCObject.py:370 #, python-format msgid "Problem starting PLC : error %d" msgstr "Проблема запуска ПЛК: ошибка %d" +msgid "Process variable" +msgstr "Текущее значение регулируемой переменной" + #: ../dialogs/ProjectDialog.py:55 msgid "Product Name" msgstr "Имя продукта" @@ -2645,12 +2718,12 @@ msgid "Product Version (required):" msgstr "Версия продукта (обязательно):" -#: ../dialogs/SearchInProjectDialog.py:46 ../IDEFrame.py:1710 -#: ../IDEFrame.py:1907 +#: ../dialogs/SearchInProjectDialog.py:38 ../IDEFrame.py:1744 +#: ../IDEFrame.py:1941 msgid "Program" msgstr "Программа" -#: ../PLCOpenEditor.py:330 +#: ../PLCOpenEditor.py:337 msgid "Program was successfully generated!" msgstr "Программа успешно сгенерирована!" @@ -2658,11 +2731,11 @@ msgid "Programs" msgstr "Программы" -#: ../editors/Viewer.py:238 +#: ../editors/Viewer.py:242 msgid "Programs can't be used by other POUs!" msgstr "Программы не могут использоваться другими POU!" -#: ../controls/ProjectPropertiesPanel.py:84 ../IDEFrame.py:556 +#: ../controls/ProjectPropertiesPanel.py:84 ../IDEFrame.py:584 msgid "Project" msgstr "Проект" @@ -2671,7 +2744,7 @@ msgid "Project '%s':" msgstr "Проект '%s':" -#: ../ProjectController.py:1713 +#: ../ProjectController.py:1814 msgid "Project Files" msgstr "Файлы проекта" @@ -2687,7 +2760,7 @@ msgid "Project Version (optional):" msgstr "Версия проекта (опционально):" -#: ../PLCControler.py:3157 +#: ../PLCControler.py:3158 msgid "" "Project file syntax error:\n" "\n" @@ -2695,14 +2768,14 @@ "Синтаксическая ошибка в файле проекта:\n" "\n" -#: ../dialogs/ProjectDialog.py:32 ../editors/ProjectNodeEditor.py:14 +#: ../dialogs/ProjectDialog.py:32 ../editors/ProjectNodeEditor.py:37 msgid "Project properties" msgstr "Свойства проекта" -#: ../ConfigTreeNode.py:540 -#, python-format -msgid "Project tree layout do not match confnode.xml %s!=%s " -msgstr "Дерево проекта не соответствует confnode.xml %s!=%s" +#: ../ConfigTreeNode.py:566 +#, python-brace-format +msgid "Project tree layout do not match confnode.xml {a1}!={a2} " +msgstr "Дерево проекта не соответствует confnode.xml {a1}!={a2} " #: ../dialogs/ConnectionDialog.py:94 msgid "Propagate Name" @@ -2712,19 +2785,31 @@ msgid "Properties" msgstr "Свойства" -#: ../plcopen/definitions.py:36 -msgid "" -"Pulse timer\n" -"The pulse timer can be used to generate output pulses of a given time duration." -msgstr "" -"Генератор импульсов\n" -"Функциональный блок используется для генерации выходных импульсов заданной длительности." - -#: ../py_ext/PythonEditor.py:57 +msgid "Proportionality constant" +msgstr "Коэффициент пропорциональности" + +#: ../Beremiz_service.py:440 +msgid "Publishing service on local network" +msgstr "Сервис доступен в локальной сети" + +#: ../connectors/PYRO/__init__.py:118 +#, python-format +msgid "Pyro exception: %s\n" +msgstr "Исключение Pyro: %s\n" + +#: ../Beremiz_service.py:427 +msgid "Pyro object's uri :" +msgstr "URI для Pyro :" + +#: ../Beremiz_service.py:426 +msgid "Pyro port :" +msgstr "Порт Pyro :" + +#: ../py_ext/PythonEditor.py:81 msgid "Python code" msgstr "Код на python" -#: ../features.py:9 +#: ../features.py:33 msgid "Python file" msgstr "Python файл" @@ -2732,68 +2817,47 @@ msgid "Qualifier" msgstr "Спецификатор" -#: ../PLCOpenEditor.py:122 ../Beremiz.py:336 ../Beremiz_service.py:252 +#: ../PLCOpenEditor.py:128 ../Beremiz.py:343 ../Beremiz_service.py:273 msgid "Quit" msgstr "Выход" -#: ../plcopen/definitions.py:29 -msgid "" -"RS bistable\n" -"The RS bistable is a latch where the Reset dominates." -msgstr "" -"RS триггер\n" -"RS триггер - переключатель с доминантой выключения." - -#: ../plcopen/definitions.py:43 -msgid "" -"Ramp\n" -"The RAMP function block is modelled on example given in the standard." -msgstr "" -"Ограничитель скорости изменения сигнала\n" -"Функциональный блок написан согласно примеру, приведенному в стандарте." +msgid "Ramp duration" +msgstr "Длительность нарастания" #: ../controls/DebugVariablePanel/DebugVariablePanel.py:225 msgid "Range:" msgstr "Диапазон:" -#: ../ProjectController.py:1709 +#: ../ProjectController.py:1810 msgid "Raw IEC code" msgstr "МЭК-код" -#: ../plcopen/definitions.py:39 -msgid "" -"Real time clock\n" -"The real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on." -msgstr "" -"RTC часы\n" -"Часы реального времени используется для получения меток времени, установки даты и времени дня в отчетах, сообщениях об авариях и пр." - -#: ../Beremiz.py:1107 +#: ../Beremiz.py:1143 #, python-format msgid "Really delete node '%s'?" msgstr "Действительно удалить элемент '%s'?" -#: ../IDEFrame.py:338 ../IDEFrame.py:398 +#: ../IDEFrame.py:362 ../IDEFrame.py:422 msgid "Redo" msgstr "Повторить" -#: ../dialogs/SFCTransitionDialog.py:73 +#: ../dialogs/SFCTransitionDialog.py:74 msgid "Reference" msgstr "Ссылка" -#: ../dialogs/DiscoveryDialog.py:105 ../IDEFrame.py:408 +#: ../dialogs/DiscoveryDialog.py:106 ../IDEFrame.py:432 msgid "Refresh" msgstr "Обновить" -#: ../dialogs/SearchInProjectDialog.py:73 +#: ../dialogs/SearchInProjectDialog.py:66 msgid "Regular expression" msgstr "Регулярное выражение" -#: ../dialogs/FindInPouDialog.py:97 +#: ../dialogs/FindInPouDialog.py:98 msgid "Regular expressions" msgstr "Регулярные выражения" -#: ../editors/Viewer.py:1531 +#: ../editors/Viewer.py:1556 msgid "Release value" msgstr "Освободить значение" @@ -2801,16 +2865,16 @@ msgid "Remainder (modulo)" msgstr "Остаток от деления (modulo)" -#: ../Beremiz.py:1108 +#: ../Beremiz.py:1144 #, python-format msgid "Remove %s node" msgstr "Удалить %s элемент" -#: ../IDEFrame.py:2371 +#: ../IDEFrame.py:2405 msgid "Remove Datatype" msgstr "Удалить тип данных" -#: ../IDEFrame.py:2376 +#: ../IDEFrame.py:2410 msgid "Remove Pou" msgstr "Удалить POU" @@ -2818,7 +2882,7 @@ msgid "Remove action" msgstr "Удалить действие" -#: ../editors/DataTypeEditor.py:352 +#: ../editors/DataTypeEditor.py:353 msgid "Remove element" msgstr "Удалить элемент" @@ -2830,7 +2894,7 @@ msgid "Remove instance" msgstr "Удалить экземпляр" -#: ../canfestival/NetworkEditor.py:81 +#: ../canfestival/NetworkEditor.py:104 msgid "Remove slave" msgstr "Удалить ведомое устройство" @@ -2838,11 +2902,11 @@ msgid "Remove task" msgstr "Удалить задачу" -#: ../editors/CodeFileEditor.py:641 ../controls/VariablePanel.py:441 +#: ../editors/CodeFileEditor.py:659 ../controls/VariablePanel.py:451 msgid "Remove variable" msgstr "Удалить переменную" -#: ../IDEFrame.py:1911 +#: ../IDEFrame.py:1945 msgid "Rename" msgstr "Переименовать" @@ -2850,7 +2914,7 @@ msgid "Replace File" msgstr "Заменить файл" -#: ../editors/Viewer.py:498 +#: ../editors/Viewer.py:502 msgid "Replace Wire by connections" msgstr "Заменить цепь подключениями" @@ -2862,11 +2926,11 @@ msgid "Reset" msgstr "Сброс" -#: ../editors/Viewer.py:578 +#: ../editors/Viewer.py:583 msgid "Reset Execution Order" msgstr "Сбросить порядок исполнения" -#: ../IDEFrame.py:423 +#: ../IDEFrame.py:451 msgid "Reset Perspective" msgstr "Сбросить представление" @@ -2874,38 +2938,33 @@ msgid "Reset search result" msgstr "Сбросить результаты поиска" -#: ../PLCControler.py:97 ../Beremiz.py:1039 +msgid "Reset time" +msgstr "Постоянная времени интегрирования" + +#: ../PLCControler.py:97 ../Beremiz.py:1075 msgid "Resources" msgstr "Ресурсы" #: ../controls/VariablePanel.py:62 msgid "Retain" -msgstr "" - -#: ../controls/VariablePanel.py:414 +msgstr "Retain" + +#: ../controls/VariablePanel.py:424 msgid "Return Type:" msgstr "Возвращаемый тип:" -#: ../editors/Viewer.py:483 +#: ../editors/Viewer.py:487 msgid "Right" msgstr "Право" -#: ../dialogs/LDPowerRailDialog.py:62 +#: ../dialogs/LDPowerRailDialog.py:63 msgid "Right PowerRail" msgstr "Правая шина питания" -#: ../dialogs/LDElementDialog.py:77 ../editors/Viewer.py:457 +#: ../dialogs/LDElementDialog.py:77 ../editors/Viewer.py:461 msgid "Rising Edge" msgstr "Нарастающий фронт" -#: ../plcopen/definitions.py:31 -msgid "" -"Rising edge detector\n" -"The output produces a single pulse when a rising edge is detected." -msgstr "" -"Детектор нарастающего фронта\n" -"На выходе формируется одиночный импульс, если обнаружен нарастающий фронт." - #: ../plcopen/iec_std.csv:65 msgid "Rotate left" msgstr "Циклический сдвиг влево" @@ -2918,77 +2977,86 @@ msgid "Rounding up/down" msgstr "Округление вверх/вниз" -#: ../ProjectController.py:1677 +#: ../ProjectController.py:1778 msgid "Run" msgstr "Старт" -#: ../ProjectController.py:975 +#: ../ProjectController.py:1037 msgid "Runtime IO extensions C code generation failed !\n" msgstr "Ошибка генерации C-кода для расширений ввода-вывода!\n" -#: ../ProjectController.py:984 +#: ../ProjectController.py:1046 msgid "Runtime library extensions C code generation failed !\n" msgstr "Ошибка генерации C-кода для библиотеки расширений системы исполнения!\n" -#: ../canfestival/SlaveEditor.py:38 ../canfestival/NetworkEditor.py:59 +#: ../canfestival/SlaveEditor.py:61 ../canfestival/NetworkEditor.py:82 msgid "SDO Client" msgstr "SDO клиент" -#: ../canfestival/SlaveEditor.py:37 ../canfestival/NetworkEditor.py:58 +#: ../canfestival/SlaveEditor.py:60 ../canfestival/NetworkEditor.py:81 msgid "SDO Server" msgstr "SDO сервер" #: ../dialogs/PouDialog.py:36 ../controls/ProjectPropertiesPanel.py:143 msgid "SFC" -msgstr "" - -#: ../plcopen/definitions.py:28 -msgid "" -"SR bistable\n" -"The SR bistable is a latch where the Set dominates." -msgstr "" -"SR триггер\n" -"SR триггер - переключатель с доминантой включения." - -#: ../dialogs/PouTransitionDialog.py:35 ../dialogs/PouActionDialog.py:31 +msgstr "SFC" + +#: ../PLCGenerator.py:1392 +#, python-brace-format +msgid "SFC jump in pou \"{a1}\" refers to non-existent SFC step \"{a2}\"" +msgstr "Безусловный переход в POU \"{a1}\" ссылается на несуществующий SFC шаг \"{a2}\"" + +#: ../PLCGenerator.py:773 +#, python-format +msgid "SFC transition in POU \"%s\" must be connected." +msgstr "SFC переход в POU \"%s\" должен быть подключен." + +#: ../dialogs/PouTransitionDialog.py:40 ../dialogs/PouActionDialog.py:31 #: ../dialogs/PouDialog.py:36 msgid "ST" -msgstr "" - -#: ../PLCOpenEditor.py:317 +msgstr "ST" + +#: ../PLCOpenEditor.py:324 msgid "ST files (*.st)|*.st|All files|*.*" msgstr "ST файлы (*.st)|*.st|Все файлы|*.*" -#: ../svgui/svgui.py:101 +#: ../svgui/svgui.py:125 msgid "SVG files (*.svg)|*.svg|All files|*.*" msgstr "SVG файлы (*.svg)|*.svg|Все файлы|*.*" -#: ../features.py:11 +#: ../features.py:35 msgid "SVGUI" -msgstr "" - -#: ../PLCOpenEditor.py:105 ../PLCOpenEditor.py:140 ../Beremiz.py:320 -#: ../Beremiz.py:351 +msgstr "SVGUI" + +msgid "Sampling period" +msgstr "Период сэмплирования" + +#: ../PLCOpenEditor.py:111 ../PLCOpenEditor.py:146 ../Beremiz.py:327 +#: ../Beremiz.py:358 msgid "Save" msgstr "Сохранить" -#: ../PLCOpenEditor.py:107 ../PLCOpenEditor.py:141 ../Beremiz.py:352 +#: ../PLCOpenEditor.py:113 ../PLCOpenEditor.py:147 ../Beremiz.py:359 msgid "Save As..." msgstr "Сохранить как..." -#: ../Beremiz.py:322 +#: ../Beremiz.py:329 msgid "Save as" msgstr "Сохранить как" -#: ../dialogs/SearchInProjectDialog.py:76 +#: ../ProjectController.py:420 +msgid "Save path is the same as path of a project! \n" +msgstr "Выбранный путь совпадает с путём проекта!\n" + +#: ../dialogs/SearchInProjectDialog.py:69 msgid "Scope" msgstr "Область действия" -#: ../dialogs/SearchInProjectDialog.py:105 ../IDEFrame.py:595 +#: ../IDEFrame.py:623 msgid "Search" msgstr "Поиск" -#: ../dialogs/SearchInProjectDialog.py:52 ../IDEFrame.py:358 ../IDEFrame.py:404 +#: ../dialogs/SearchInProjectDialog.py:44 ../IDEFrame.py:382 ../IDEFrame.py:428 msgid "Search in Project" msgstr "Поиск в проекте" @@ -2996,27 +3064,31 @@ msgid "Seconds:" msgstr "Секунды:" -#: ../IDEFrame.py:364 +#: ../IDEFrame.py:388 msgid "Select All" msgstr "Выделить все" -#: ../editors/Viewer.py:284 ../editors/TextViewer.py:304 -#: ../controls/LocationCellEditor.py:97 ../controls/VariablePanel.py:280 -#: ../controls/VariablePanel.py:340 +#: ../editors/Viewer.py:288 ../editors/TextViewer.py:306 +#: ../controls/LocationCellEditor.py:97 ../controls/VariablePanel.py:290 +#: ../controls/VariablePanel.py:350 msgid "Select a variable class:" -msgstr "" - -#: ../ProjectController.py:1126 +msgstr "Выберите класс переменной:" + +#: ../ProjectController.py:1195 msgid "Select an editor:" -msgstr "Выберете редактор:" +msgstr "Выберите редактор:" #: ../controls/PouInstanceVariablesPanel.py:276 msgid "Select an instance" -msgstr "Выберете экземпляр" - -#: ../IDEFrame.py:579 +msgstr "Выберите экземпляр" + +#: ../IDEFrame.py:607 msgid "Select an object" -msgstr "Выберете объект" +msgstr "Выберите объект" + +#: ../ProjectController.py:427 +msgid "Selected directory already contains another project. Overwrite? \n" +msgstr "Выбранная директория уже содержит другой проект. Перезаписать?\n" #: ../plcopen/iec_std.csv:70 msgid "Selection" @@ -3030,19 +3102,11 @@ msgid "Selection Divergence" msgstr "Альтернативное ветвление" -#: ../plcopen/definitions.py:30 -msgid "" -"Semaphore\n" -"The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources." -msgstr "" -"Семафор\n" -"Семафор предоставляет собой программный механизм синхронизации для обеспечения исключительного доступа к определенным ресурсам." - -#: ../dialogs/DiscoveryDialog.py:81 +#: ../dialogs/DiscoveryDialog.py:82 msgid "Service Discovery" msgstr "Поиск сервиса" -#: ../dialogs/DiscoveryDialog.py:84 +#: ../dialogs/DiscoveryDialog.py:85 msgid "Services available:" msgstr "Сервисы доступны:" @@ -3050,6 +3114,9 @@ msgid "Set" msgstr "Установить" +msgid "Set point" +msgstr "Уставка" + #: ../plcopen/iec_std.csv:62 msgid "Shift left" msgstr "Сдвиг влево" @@ -3058,19 +3125,19 @@ msgid "Shift right" msgstr "Сдвиг вправо" -#: ../ProjectController.py:1703 +#: ../ProjectController.py:1804 msgid "Show IEC code generated by PLCGenerator" msgstr "Показать год, сгенерированный PLCGenerator" -#: ../canfestival/canfestival.py:363 +#: ../canfestival/canfestival.py:387 msgid "Show Master" msgstr "Показать ведущего" -#: ../canfestival/canfestival.py:364 +#: ../canfestival/canfestival.py:388 msgid "Show Master generated by config_utils" msgstr "Показать ведущий узел сгенерированный config_utils" -#: ../ProjectController.py:1701 +#: ../ProjectController.py:1802 msgid "Show code" msgstr "Показать код" @@ -3088,54 +3155,67 @@ #: ../editors/ResourceEditor.py:68 msgid "Single" -msgstr "Источник прерывания" - -#: ../targets/toolchain_makefile.py:112 +msgstr "Источник" + +#: ../targets/toolchain_makefile.py:126 msgid "Source didn't change, no build.\n" msgstr "Исходные файлы не изменились, сборка не нужна.\n" +#: ../PLCGenerator.py:397 +#, python-brace-format +msgid "Source signal has to be defined for single task '{a1}' in resource '{a2}.{a3}'." +msgstr "Для задачи '{a1}' в ресурсе '{a2}.{a3}' отсутсвует задание источника." + #: ../plcopen/iec_std.csv:23 msgid "Square root (base 2)" msgstr "Квадратный корень" -#: ../plcopen/definitions.py:21 +#: ../plcopen/definitions.py:46 msgid "Standard function blocks" msgstr "Стандартные функциональные блоки" -#: ../ProjectController.py:1679 ../Beremiz_service.py:240 +#: ../ProjectController.py:1780 ../Beremiz_service.py:261 msgid "Start PLC" msgstr "Запустить ПЛК" -#: ../ProjectController.py:922 +#: ../ProjectController.py:984 #, python-format msgid "Start build in %s\n" msgstr "Сборка запущена в %s\n" -#: ../ProjectController.py:1483 +#: ../ProjectController.py:1298 +msgid "Started" +msgstr "Работа" + +#: ../ProjectController.py:1586 msgid "Starting PLC\n" -msgstr "ПЛК запускается\\n\n" - -#: ../Beremiz.py:451 +msgstr "ПЛК запускается\n" + +#: ../Beremiz.py:463 msgid "Status ToolBar" msgstr "Панель статуса" -#: ../editors/Viewer.py:549 ../editors/Viewer.py:2059 +#: ../editors/Viewer.py:553 ../editors/Viewer.py:2342 msgid "Step" msgstr "Шаг" -#: ../ProjectController.py:1682 +#: ../ProjectController.py:1783 msgid "Stop" msgstr "Стоп" -#: ../Beremiz_service.py:241 +#: ../Beremiz_service.py:262 msgid "Stop PLC" msgstr "Остановить ПЛК" -#: ../ProjectController.py:1684 +#: ../ProjectController.py:1785 msgid "Stop Running PLC" msgstr "Остановить запущенный ПЛК" -#: ../ProjectController.py:1455 +#: ../ProjectController.py:1299 +msgid "Stopped" +msgstr "Стоп" + +#: ../ProjectController.py:1558 msgid "Stopping debugger...\n" msgstr "Остановка отладчика...\n" @@ -3151,10 +3231,14 @@ msgid "Subtraction" msgstr "Вычитание" -#: ../ProjectController.py:961 +#: ../ProjectController.py:1023 msgid "Successfully built.\n" msgstr "Сборка прошла успешно.\n" +#: ../IDEFrame.py:447 +msgid "Switch perspective" +msgstr "Сменить представление" + msgid "Sync_Align" msgstr "" @@ -3164,11 +3248,11 @@ msgid "Sync_TPDOs" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:154 +#: ../dialogs/SearchInProjectDialog.py:165 ../dialogs/FindInPouDialog.py:172 msgid "Syntax error in regular expression of pattern to search!" msgstr "Синтаксическая ошибка в регулярном выражении шаблона поиска!" -#: ../dialogs/DiscoveryDialog.py:92 +#: ../dialogs/DiscoveryDialog.py:93 msgid "TYPE" msgstr "Тип" @@ -3191,6 +3275,24 @@ msgid "Temp" msgstr "Временный" +msgid "The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control." +msgstr "ПИД (Пропорциональный Интегральный Дифференциальный) ФБ - классический регулятор, используемый в системах с обратной связью." + +msgid "The RAMP function block is modelled on example given in the standard." +msgstr "Ограничитель скорости изменения сигнала. Функциональный блок написан согласно примеру, приведенному в стандарте." + +msgid "The RS bistable is a latch where the Reset dominates." +msgstr "RS-триггер с приоритетом выключения." + +msgid "The SR bistable is a latch where the Set dominates." +msgstr "SR-триггер с приоритетом включения." + +msgid "The derivative function block produces an output XOUT proportional to the rate of change of the input XIN." +msgstr "Функциональный блок формирует выход XOUT пропорционально частоте изменения входа XIN." + +msgid "The down-counter can be used to signal when a count has reached zero, on counting down from a preset value." +msgstr "Декрементный счетчик может использоваться, когда необходимо сигнализировать, что счетчик достиг нулевого значения с исходного заданного значения." + #: ../editors/FileManagementPanel.py:180 #, python-format msgid "" @@ -3202,18 +3304,51 @@ #: ../editors/LDViewer.py:882 msgid "The group of block must be coherent!" -msgstr "" - -#: ../Beremiz.py:614 ../IDEFrame.py:983 +msgstr "Группа блоков должна быть связанной!" + +msgid "The hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2." +msgstr "Функциональный блок формирует дискретный выход с гистерезисом в зависимости от разницы двух вещественных входов XIN1 и XIN2." + +msgid "The integral function block integrates the value of input XIN over time." +msgstr "Функциональный блок интегрирует входное значение XIN во времени." + +msgid "The off-delay timer can be used to delay setting an output false, for fixed period after input goes false." +msgstr "Таймер выключения может быть использован, чтобы внести задержку установки выхода в FALSE на фиксированный период времени после того, как вход стал FALSE." + +msgid "The on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true." +msgstr "Таймер выключения может быть использован, чтобы внести задержку установки выхода в TRUE на фиксированный период времени после того, как вход стал TRUE." + +msgid "The output produces a single pulse when a falling edge is detected." +msgstr "Детектор падающего фронта. На выходе формируется одиночный импульс, если обнаружен падающий фронт." + +msgid "The output produces a single pulse when a rising edge is detected." +msgstr "Детектор нарастающего фронта. На выходе формируется одиночный импульс, если обнаружен нарастающий фронт." + +msgid "The pulse timer can be used to generate output pulses of a given time duration." +msgstr "Генератор импульсов. Функциональный блок используется для генерации выходных импульсов заданной длительности." + +msgid "The real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on." +msgstr "Часы реального времени используется для получения меток времени, установки даты и времени дня в отчетах, сообщениях об авариях и пр." + +msgid "The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources." +msgstr "Семафор предоставляет собой программный механизм синхронизации для обеспечения исключительного доступа к определенным ресурсам." + +msgid "The up-counter can be used to signal when a count has reached a maximum value." +msgstr "Инкрементный счетчик может использоваться, когда необходимо сигнализировать, что счетчик достиг максимального значения." + +msgid "The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other." +msgstr "Инкрементный/декрементный счетчик имеет два входа CU и CD. Он может использоваться для счета вверх по одному входу и для счета низ по другому." + +#: ../Beremiz.py:640 ../IDEFrame.py:1011 msgid "There are changes, do you want to save?" msgstr "Хотите сохранить изменения?" -#: ../IDEFrame.py:1618 ../IDEFrame.py:1637 +#: ../IDEFrame.py:1655 ../IDEFrame.py:1674 #, python-format msgid "There is a POU named \"%s\". This could cause a conflict. Do you wish to continue?" msgstr "Существует POU с именем \"%s\". Это может вызвать конфликт. Хотите продолжить?" -#: ../IDEFrame.py:1070 +#: ../IDEFrame.py:1098 msgid "" "There was a problem printing.\n" "Perhaps your current printer is not set correctly?" @@ -3225,6 +3360,11 @@ msgid "This option isn't available yet!" msgstr "Это опция еще не доступна!" +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:565 +#, python-format +msgid "Tick: %d" +msgstr "Цикл: %d" + #: ../plcopen/iec_std.csv:40 msgid "Time" msgstr "Время" @@ -3258,54 +3398,54 @@ msgid "Time-of-day subtraction" msgstr "Вычитание времени суток" -#: ../editors/Viewer.py:485 +#: ../editors/Viewer.py:489 msgid "Top" msgstr "Верх" -#: ../ProjectController.py:1691 +#: ../ProjectController.py:1792 msgid "Transfer" msgstr "Передать" -#: ../ProjectController.py:1693 +#: ../ProjectController.py:1794 msgid "Transfer PLC" msgstr "Передать ПЛК" -#: ../ProjectController.py:1658 +#: ../ProjectController.py:1758 msgid "Transfer completed successfully.\n" msgstr "Передача успешно завершена.\n" -#: ../ProjectController.py:1660 +#: ../ProjectController.py:1760 msgid "Transfer failed\n" msgstr "Ошибка передачи\n" -#: ../editors/Viewer.py:550 ../editors/Viewer.py:2060 ../editors/Viewer.py:2089 +#: ../editors/Viewer.py:554 ../editors/Viewer.py:2344 ../editors/Viewer.py:2371 msgid "Transition" msgstr "Переход" -#: ../PLCGenerator.py:1499 +#: ../PLCGenerator.py:1518 #, python-format msgid "Transition \"%s\" body must contain an output variable or coil referring to its name" msgstr "Тело перехода \"%s\" должно содержать выходную переменную или катушку, ссылающуюся на его имя" -#: ../dialogs/PouTransitionDialog.py:84 +#: ../dialogs/PouTransitionDialog.py:89 msgid "Transition Name" msgstr "Имя перехода" -#: ../dialogs/PouTransitionDialog.py:53 +#: ../dialogs/PouTransitionDialog.py:58 msgid "Transition Name:" msgstr "Имя перехода:" -#: ../PLCGenerator.py:1588 -#, python-format -msgid "Transition with content \"%s\" not connected to a next step in \"%s\" POU" -msgstr "Переход с содержимым \"%s\" не подключен к следующему шагу в POU \"%s\"" - -#: ../PLCGenerator.py:1579 -#, python-format -msgid "Transition with content \"%s\" not connected to a previous step in \"%s\" POU" -msgstr "Переход с содержимым \"%s\" не подключен к предыдущему шагу в POU \"%s\"" - -#: ../plcopen/plcopen.py:1315 +#: ../PLCGenerator.py:1609 +#, python-brace-format +msgid "Transition with content \"{a1}\" not connected to a next step in \"{a2}\" POU" +msgstr "Переход с содержимым \"{a1}\" не подключен к следующему шагу в POU \"{a2}\"" + +#: ../PLCGenerator.py:1598 +#, python-brace-format +msgid "Transition with content \"{a1}\" not connected to a previous step in \"{a2}\" POU" +msgstr "Переход с содержимым \"{a1}\" не подключен к предыдущему шагу в POU \"{a2}\"" + +#: ../plcopen/plcopen.py:1318 #, python-format msgid "Transition with name %s doesn't exist!" msgstr "Переход с именем %s отсутствует!" @@ -3314,21 +3454,29 @@ msgid "Transitions" msgstr "Переходы" +#: ../dialogs/AboutDialog.py:123 +msgid "Translated by" +msgstr "Перевод" + #: ../editors/ResourceEditor.py:68 msgid "Triggering" msgstr "Запуск" +#: ../Beremiz_service.py:476 +msgid "Twisted unavailable." +msgstr "Модуль Twisted недоступен." + #: ../dialogs/ActionBlockDialog.py:38 ../editors/ResourceEditor.py:83 -#: ../editors/DataTypeEditor.py:50 ../editors/CodeFileEditor.py:663 -#: ../controls/VariablePanel.py:53 ../controls/VariablePanel.py:54 +#: ../editors/DataTypeEditor.py:50 ../controls/VariablePanel.py:53 +#: ../controls/VariablePanel.py:54 msgid "Type" msgstr "Тип" -#: ../dialogs/BrowseLocationsDialog.py:43 +#: ../dialogs/BrowseLocationsDialog.py:48 msgid "Type and derivated" msgstr "Тип и его производные" -#: ../canfestival/config_utils.py:336 ../canfestival/config_utils.py:618 +#: ../canfestival/config_utils.py:336 ../canfestival/config_utils.py:624 #, python-format msgid "Type conflict for location \"%s\"" msgstr "Конфликт типов \"%s\"" @@ -3337,16 +3485,16 @@ msgid "Type conversion" msgstr "Преобразование типов" -#: ../editors/DataTypeEditor.py:161 +#: ../editors/DataTypeEditor.py:162 msgid "Type infos:" msgstr "Информация о типе:" -#: ../dialogs/BrowseLocationsDialog.py:44 +#: ../dialogs/BrowseLocationsDialog.py:49 msgid "Type strict" msgstr "Только данный тип" -#: ../dialogs/SFCDivergenceDialog.py:57 ../dialogs/SFCTransitionDialog.py:56 -#: ../dialogs/LDPowerRailDialog.py:55 ../dialogs/BrowseLocationsDialog.py:94 +#: ../dialogs/SFCDivergenceDialog.py:59 ../dialogs/SFCTransitionDialog.py:57 +#: ../dialogs/LDPowerRailDialog.py:56 ../dialogs/BrowseLocationsDialog.py:99 #: ../dialogs/FBDBlockDialog.py:65 ../dialogs/ConnectionDialog.py:58 msgid "Type:" msgstr "Тип:" @@ -3354,74 +3502,58 @@ msgid "URI_location" msgstr "URI системы исполнения" -#: ../canfestival/config_utils.py:456 ../canfestival/config_utils.py:470 +#: ../canfestival/config_utils.py:462 ../canfestival/config_utils.py:476 #, python-format msgid "Unable to define PDO mapping for node %02x" msgstr "Невозможно определить отображение PDO для узла %02x" -#: ../targets/Xenomai/__init__.py:15 +#: ../targets/Xenomai/__init__.py:39 #, python-format msgid "Unable to get Xenomai's %s \n" msgstr "Невозможно получить Xenomai %s\n" -#: ../PLCGenerator.py:951 ../PLCGenerator.py:1202 -#, python-format -msgid "Undefined block type \"%s\" in \"%s\" POU" -msgstr "Неопределенный тип блока \"%s\" в POU \"%s\"" +#: ../PLCGenerator.py:961 ../PLCGenerator.py:1214 +#, python-brace-format +msgid "Undefined block type \"{a1}\" in \"{a2}\" POU" +msgstr "Неопределенный тип блока \"{a1}\" в POU \"{a2}\"" #: ../PLCGenerator.py:254 #, python-format msgid "Undefined pou type \"%s\"" msgstr "Неопределенный тип POU \"%s\"" -#: ../IDEFrame.py:336 ../IDEFrame.py:397 +#: ../IDEFrame.py:360 ../IDEFrame.py:421 msgid "Undo" msgstr "Отмена" -#: ../ProjectController.py:308 +#: ../ProjectController.py:332 msgid "Unknown" msgstr "Неизвестно" -#: ../editors/Viewer.py:389 +#: ../editors/Viewer.py:393 #, python-format msgid "Unknown variable \"%s\" for this POU!" msgstr "Неизвестная переменная \"%s\" для этого POU!" -#: ../ProjectController.py:305 ../ProjectController.py:306 +#: ../ProjectController.py:329 ../ProjectController.py:330 msgid "Unnamed" -msgstr "" +msgstr "Unnamed" #: ../PLCControler.py:636 #, python-format msgid "Unnamed%d" -msgstr "" - -#: ../controls/VariablePanel.py:275 +msgstr "Unnamed%d" + +#: ../controls/VariablePanel.py:284 #, python-format msgid "Unrecognized data size \"%s\"" msgstr "Неопределенный размер данных \"%s\"" -#: ../plcopen/definitions.py:33 -msgid "" -"Up-counter\n" -"The up-counter can be used to signal when a count has reached a maximum value." -msgstr "" -"Инкрементный счетчик\n" -"Инкрементный счетчик может использоваться, когда необходимо сигнализировать, что счетчик достиг максимального значения." - -#: ../plcopen/definitions.py:35 -msgid "" -"Up-down counter\n" -"The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other." -msgstr "" -"Инкрементный/декрементный счетчик\n" -"Инкрементный/декрементный счетчик имеет два входа CU и CD. Он может использоваться для счета вверх по одному входу и для счета низ по другому." - -#: ../editors/DataTypeEditor.py:631 ../controls/VariablePanel.py:780 +#: ../editors/DataTypeEditor.py:632 ../controls/VariablePanel.py:798 msgid "User Data Types" msgstr "Пользовательские типы данных" -#: ../canfestival/SlaveEditor.py:42 ../canfestival/NetworkEditor.py:63 +#: ../canfestival/SlaveEditor.py:65 ../canfestival/NetworkEditor.py:86 msgid "User Type" msgstr "Пользовательский тип" @@ -3433,26 +3565,32 @@ msgid "Value" msgstr "Значение" -#: ../editors/DataTypeEditor.py:258 +#: ../editors/DataTypeEditor.py:259 msgid "Values:" msgstr "Значения:" -#: ../dialogs/ActionBlockDialog.py:42 ../editors/Viewer.py:522 -#: ../editors/Viewer.py:2074 +#: ../dialogs/ActionBlockDialog.py:42 ../editors/Viewer.py:526 +#: ../editors/Viewer.py:2374 msgid "Variable" msgstr "Переменная" +#: ../editors/Viewer.py:308 ../editors/Viewer.py:338 ../editors/Viewer.py:360 +#: ../editors/TextViewer.py:292 ../editors/TextViewer.py:343 +#: ../editors/TextViewer.py:366 ../controls/VariablePanel.py:329 +msgid "Variable Drop" +msgstr "Перетаскивание переменной" + #: ../dialogs/FBDVariableDialog.py:63 msgid "Variable Properties" msgstr "Свойства переменных" -#: ../editors/Viewer.py:284 ../editors/TextViewer.py:304 -#: ../controls/LocationCellEditor.py:97 ../controls/VariablePanel.py:280 -#: ../controls/VariablePanel.py:340 +#: ../editors/Viewer.py:288 ../editors/TextViewer.py:306 +#: ../controls/LocationCellEditor.py:97 ../controls/VariablePanel.py:290 +#: ../controls/VariablePanel.py:350 msgid "Variable class" -msgstr "" - -#: ../editors/Viewer.py:391 ../editors/TextViewer.py:385 +msgstr "Класс переменной" + +#: ../editors/Viewer.py:395 ../editors/TextViewer.py:387 msgid "Variable don't belong to this POU!" msgstr "Переменная не принадлежит этому POU!" @@ -3468,33 +3606,41 @@ msgid "Vertical:" msgstr "Вертикальный:" -#: ../connectors/WAMP/__init__.py:88 +#: ../Beremiz_service.py:586 +msgid "WAMP client startup failed. " +msgstr "Ошибка импорта WAMP. " + +#: ../connectors/WAMP/__init__.py:91 #, python-format msgid "WAMP connecting to URL : %s\n" msgstr "WAMP подключение к URI: %s\n" -#: ../connectors/WAMP/__init__.py:128 +#: ../connectors/WAMP/__init__.py:131 msgid "WAMP connection timeout" msgstr "Тайм-аут WAMP подключения " -#: ../connectors/WAMP/__init__.py:147 +#: ../connectors/WAMP/__init__.py:150 #, python-format msgid "WAMP connection to '%s' failed.\n" msgstr "Не удалось установить WAMP подключение к %s.\n" -#: ../wxglade_hmi/wxglade_hmi.py:11 +#: ../Beremiz_service.py:562 +msgid "WAMP import failed :" +msgstr "Ошибка импорта WAMP :" + +#: ../wxglade_hmi/wxglade_hmi.py:35 msgid "WXGLADE GUI" -msgstr "" +msgstr "WXGLADE GUI" #: ../dialogs/PouDialog.py:128 ../editors/LDViewer.py:891 msgid "Warning" msgstr "Предупреждение" -#: ../ProjectController.py:584 +#: ../ProjectController.py:616 msgid "Warnings in ST/IL/SFC code generator :\n" msgstr "Предупреждения в ST/IL/SFC коде генераторе:\n" -#: ../dialogs/SearchInProjectDialog.py:85 +#: ../dialogs/SearchInProjectDialog.py:78 msgid "Whole Project" msgstr "Целый проект" @@ -3503,23 +3649,27 @@ msgstr "Ширина:" msgid "Win32" -msgstr "" - -#: ../dialogs/FindInPouDialog.py:92 +msgstr "Win32" + +#: ../dialogs/FindInPouDialog.py:93 msgid "Wrap search" msgstr "Продолжить поиск сначала" -#: ../features.py:10 +#: ../dialogs/AboutDialog.py:122 +msgid "Written by" +msgstr "Авторы" + +#: ../features.py:34 msgid "WxGlade GUI" -msgstr "" +msgstr "WxGlade GUI" msgid "XenoConfig" msgstr "Настройки Xenomai" msgid "Xenomai" -msgstr "" - -#: ../svgui/svgui.py:115 +msgstr "Xenomai" + +#: ../svgui/svgui.py:139 msgid "" "You don't have write permissions.\n" "Open Inkscape anyway ?" @@ -3527,7 +3677,7 @@ "У вас недостаточно прав для записи.\n" "Открыть Inkscape все равно?" -#: ../wxglade_hmi/wxglade_hmi.py:113 +#: ../wxglade_hmi/wxglade_hmi.py:137 msgid "" "You don't have write permissions.\n" "Open wxGlade anyway ?" @@ -3535,7 +3685,7 @@ "У вас недостаточно прав для записи.\n" "Открыть wxGlade все равно?" -#: ../ProjectController.py:268 +#: ../ProjectController.py:292 msgid "" "You must have permission to work on the project\n" "Work on a project copy ?" @@ -3545,13 +3695,13 @@ #: ../editors/LDViewer.py:886 msgid "You must select the block or group of blocks around which a branch should be added!" -msgstr "Выберете блок или группу блоков, вокруг которых нужно добавить ветвление!" +msgstr "Выберите блок или группу блоков, вокруг которых нужно добавить ветвление!" #: ../editors/LDViewer.py:666 msgid "You must select the wire where a contact should be added!" -msgstr "Выберете провод, куда должен быть добавлен контакт!" - -#: ../dialogs/SFCStepNameDialog.py:47 ../dialogs/PouNameDialog.py:45 +msgstr "Выберите провод, куда должен быть добавлен контакт!" + +#: ../dialogs/SFCStepNameDialog.py:48 ../dialogs/PouNameDialog.py:46 msgid "You must type a name!" msgstr "Введите имя!" @@ -3559,14 +3709,10 @@ msgid "You must type a value!" msgstr "Введите значение!" -#: ../IDEFrame.py:414 +#: ../IDEFrame.py:438 msgid "Zoom" msgstr "Приближение" -#: ../Beremiz.py:997 -msgid "about.html" -msgstr "about.ru.html" - msgid "class" msgstr "класс" @@ -3577,25 +3723,31 @@ msgid "desc" msgstr "" -#: ../PLCOpenEditor.py:326 +#: ../PLCOpenEditor.py:333 #, python-format msgid "error: %s\n" msgstr "ошибка: %s\n" -#: ../util/ProcessLogger.py:166 -#, python-format -msgid "exited with status %s (pid %s)\n" -msgstr "завершился с кодом %s (pid %s)\n" - -#: ../PLCOpenEditor.py:384 ../PLCOpenEditor.py:386 +#: ../util/ProcessLogger.py:169 +#, python-brace-format +msgid "exited with status {a1} (pid {a2})\n" +msgstr "завершился с кодом {a1} (pid {a2})\n" + +#: ../PLCOpenEditor.py:396 ../PLCOpenEditor.py:398 msgid "file : " msgstr "файл:" +msgid "first input parameter" +msgstr "первый входной параметр" + +msgid "first output parameter" +msgstr "первый выходной параметр" + #: ../dialogs/PouDialog.py:31 msgid "function" msgstr "функция" -#: ../PLCOpenEditor.py:387 +#: ../PLCOpenEditor.py:399 msgid "function : " msgstr "функция: " @@ -3610,7 +3762,10 @@ msgid "initial" msgstr "исходный" -#: ../PLCOpenEditor.py:387 +msgid "internal state: 0-reset, 1-counting, 2-set" +msgstr "состояние: 0 - сброс, 1 - счёт, 2 - установка" + +#: ../PLCOpenEditor.py:399 msgid "line : " msgstr "строка:" @@ -3631,14 +3786,16 @@ msgid "opts" msgstr "" -#: ../PLCOpenEditor.py:346 -msgid "plcopen_about.html" -msgstr "plcopen_about.ru.html" - #: ../dialogs/PouDialog.py:31 msgid "program" msgstr "программа" +msgid "second input parameter" +msgstr "второй входной параметр" + +msgid "second output parameter" +msgstr "второй выходной параметр" + #: ../dialogs/DurationEditorDialog.py:152 msgid "seconds" msgstr "секунды" @@ -3658,29 +3815,130 @@ msgid "type" msgstr "тип" +#: ../Beremiz.py:126 +msgid "update info unavailable." +msgstr "информация об обновлениях недоступна." + msgid "variable" msgstr "переменная" msgid "variables" msgstr "переменные" -#: ../PLCOpenEditor.py:324 +#: ../PLCOpenEditor.py:331 #, python-format msgid "warning: %s\n" msgstr "предупреждение: %s\n" +#: ../PLCControler.py:970 +#, python-brace-format +msgid "{a1} \"{a2}\" can't be pasted as a {a3}." +msgstr "{a1} \"{a2}\" не может быть вставлен как {a3}." + +#: ../ConfigTreeNode.py:56 +#, python-brace-format +msgid "" +"{a1} XML file doesn't follow XSD schema at line %{a2}:\n" +"{a3}" +msgstr "" +"{a1} XML файл не следует XSD-схеме в строке {a2}:\n" +"{a3}" + +#~ msgid "" +#~ "\n" +#~ "An error has occurred.\n" +#~ "\n" +#~ "Click OK to save an error report.\n" +#~ "\n" +#~ "Please be kind enough to send this file to:\n" +#~ "edouard.tisserant@gmail.com\n" +#~ "\n" +#~ "Error:\n" +#~ msgstr "" +#~ "\n" +#~ "Произошла ошибка.\n" +#~ "\n" +#~ "Нажмите OK, чтобы сохранить репорт об ошибке.\n" +#~ "\n" +#~ "Будьте так добры, пошлите этот файл:\n" +#~ "edouard.tisserant@gmail.com\n" +#~ "\n" +#~ "Ошибка:\n" + +#~ msgid " -> Nothing to do\n" +#~ msgstr " -> Ничего не нужно делать\n" + +#~ msgid " : " +#~ msgstr " : " + #~ msgid "\"%s\" element can't be pasted here!!!" #~ msgstr "Элемент \"%s\" не может быть вставлен сюда!!!" #~ msgid "... debugger recovered\n" #~ msgstr "... отладчик восстановлен\n" +#~ msgid "About Beremiz" +#~ msgstr "О Beremiz" + +#~ msgid "About PLCOpenEditor" +#~ msgstr "О PLCOpenEditor" + #~ msgid "Clear the graph values" #~ msgstr "Очистить значения на графике" +#~ msgid "" +#~ "Derivative\n" +#~ "The derivative function block produces an output XOUT proportional to the rate of change of the input XIN." +#~ msgstr "" +#~ "Производная\n" +#~ "Функциональный блок формирует выход XOUT пропорционально частоте изменения входа XIN." + +#~ msgid "Description" +#~ msgstr "Описание" + +#~ msgid "" +#~ "Down-counter\n" +#~ "The down-counter can be used to signal when a count has reached zero, on counting down from a preset value." +#~ msgstr "" +#~ "Декрементный счетчик\n" +#~ "Декрементный счетчик может использоваться, когда необходимо сигнализировать, что счетчик достиг нулевого значения с исходного заданного значения." + +#~ msgid "Enable_Native_Library" +#~ msgstr "Разрешить библиотеку Native" + +#~ msgid "" +#~ "Falling edge detector\n" +#~ "The output produces a single pulse when a falling edge is detected." +#~ msgstr "" +#~ "Детектор падающего фронта\n" +#~ "На выходе формируется одиночный импульс, если обнаружен падающий фронт." + +#~ msgid "Form isn't complete. Pattern to search must be filled!" +#~ msgstr "Форма заполнена неполностью. Шаблон поиска должен быть заполнен!" + +#~ msgid "" +#~ "Hysteresis\n" +#~ "The hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2." +#~ msgstr "" +#~ "Гистерезис\n" +#~ "Функциональный блок формирует дискретный выход с гистерезисом в зависимости от разницы двух вещественных входов XIN1 и XIN2." + #~ msgid "IEC-61131-3 code generation failed !\n" #~ msgstr "Неудачная генерация МЭК-61131-3 кода!\n" +#~ msgid "In section: " +#~ msgstr "В секции: " + +#~ msgid "Initial" +#~ msgstr "Исходное значение" + +#~ msgid "" +#~ "Integral\n" +#~ "The integral function block integrates the value of input XIN over time." +#~ msgstr "" +#~ "Интеграл\n" +#~ "Функциональный блок интегрирует входное значение XIN во времени." + #~ msgid "Move debug variable down" #~ msgstr "Переместить отлаживаемую переменную ниже" @@ -3693,18 +3951,102 @@ #~ msgid "No output variable found" #~ msgstr "Выходная переменная не найдена" +#~ msgid "" +#~ "Off-delay timer\n" +#~ "The off-delay timer can be used to delay setting an output false, for fixed period after input goes false." +#~ msgstr "" +#~ "Таймер выключения\n" +#~ "Таймер выключения может быть использован, чтобы внести задержку установки выхода в FALSE на фиксированный период времени после того, как вход стал FALSE." + +#~ msgid "" +#~ "On-delay timer\n" +#~ "The on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true." +#~ msgstr "" +#~ "Таймер включения\n" +#~ "Таймер выключения может быть использован, чтобы внести задержку установки выхода в TRUE на фиксированный период времени после того, как вход стал TRUE." + +#~ msgid "" +#~ "PID\n" +#~ "The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control." +#~ msgstr "" +#~ "ПИД\n" +#~ "ПИД (Пропорциональный Интегральный Дифференциальный) ФБ - классический регулятор, используемый в системах с обратной связью." + #~ msgid "Position:" #~ msgstr "Позиция:" +#~ msgid "" +#~ "Pulse timer\n" +#~ "The pulse timer can be used to generate output pulses of a given time duration." +#~ msgstr "" +#~ "Генератор импульсов\n" +#~ "Функциональный блок используется для генерации выходных импульсов заданной длительности." + +#~ msgid "" +#~ "RS bistable\n" +#~ "The RS bistable is a latch where the Reset dominates." +#~ msgstr "" +#~ "RS триггер\n" +#~ "RS триггер - переключатель с доминантой выключения." + +#~ msgid "" +#~ "Ramp\n" +#~ "The RAMP function block is modelled on example given in the standard." +#~ msgstr "" +#~ "Ограничитель скорости изменения сигнала\n" +#~ "Функциональный блок написан согласно примеру, приведенному в стандарте." + +#~ msgid "" +#~ "Real time clock\n" +#~ "The real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on." +#~ msgstr "" +#~ "RTC часы\n" +#~ "Часы реального времени используется для получения меток времени, установки даты и времени дня в отчетах, сообщениях об авариях и пр." + #~ msgid "Remove debug variable" #~ msgstr "Удалить отлаживаемую переменную" #~ msgid "Reset zoom and offset" #~ msgstr "Сбросить приближение и смещение" +#~ msgid "" +#~ "Rising edge detector\n" +#~ "The output produces a single pulse when a rising edge is detected." +#~ msgstr "" +#~ "Детектор нарастающего фронта\n" +#~ "На выходе формируется одиночный импульс, если обнаружен нарастающий фронт." + +#~ msgid "" +#~ "SR bistable\n" +#~ "The SR bistable is a latch where the Set dominates." +#~ msgstr "" +#~ "SR триггер\n" +#~ "SR триггер - переключатель с доминантой включения." + +#~ msgid "" +#~ "Semaphore\n" +#~ "The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources." +#~ msgstr "" +#~ "Семафор\n" +#~ "Семафор предоставляет собой программный механизм синхронизации для обеспечения исключительного доступа к определенным ресурсам." + #~ msgid "Tick" #~ msgstr "Тик" +#~ msgid "" +#~ "Up-counter\n" +#~ "The up-counter can be used to signal when a count has reached a maximum value." +#~ msgstr "" +#~ "Инкрементный счетчик\n" +#~ "Инкрементный счетчик может использоваться, когда необходимо сигнализировать, что счетчик достиг максимального значения." + +#~ msgid "" +#~ "Up-down counter\n" +#~ "The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other." +#~ msgstr "" +#~ "Инкрементный/декрементный счетчик\n" +#~ "Инкрементный/декрементный счетчик имеет два входа CU и CD. Он может использоваться для счета вверх по одному входу и для счета низ по другому." + #~ msgid "Values" #~ msgstr "Значения" @@ -3713,3 +4055,9 @@ #~ msgid "Zoom:" #~ msgstr "Приближение:" + +#~ msgid "about.html" +#~ msgstr "about.ru.html" + +#~ msgid "plcopen_about.html" +#~ msgstr "plcopen_about.ru.html" diff -r 6431f26aa501 -r 3291024e00da i18n/app.fil --- a/i18n/app.fil Thu Feb 16 14:34:40 2017 +0500 +++ b/i18n/app.fil Thu Feb 16 14:35:12 2017 +0500 @@ -14,6 +14,7 @@ ../dialogs/PouTransitionDialog.py ../dialogs/FBDVariableDialog.py ../dialogs/BlockPreviewDialog.py +../dialogs/AboutDialog.py ../dialogs/ProjectDialog.py ../dialogs/LDPowerRailDialog.py ../dialogs/ArrayTypeDialog.py @@ -41,6 +42,7 @@ ../targets/Xenomai/__init__.py ../targets/Xenomai/XSD ../targets/XSD_toolchain_gcc +../targets/PLC/XSD ../targets/__init__.py ../targets/toolchain_gcc.py ../targets/toolchain_makefile.py @@ -97,6 +99,7 @@ ../xmlclass/xsdschema.py ../xmlclass/xmlclass.py ../Beremiz.py +../version.py ../POULibrary.py ../util/MiniTextControler.py ../util/Zeroconf.py @@ -113,3 +116,5 @@ ../IDEFrame.py ../PLCGenerator.py ../Beremiz_service.py +../plcopen/Additional_Function_Blocks.xml +../plcopen/Standard_Function_Blocks.xml \ No newline at end of file diff -r 6431f26aa501 -r 3291024e00da i18n/messages.pot --- a/i18n/messages.pot Thu Feb 16 14:34:40 2017 +0500 +++ b/i18n/messages.pot Thu Feb 16 14:35:12 2017 +0500 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-04-21 17:11+0300\n" +"POT-Creation-Date: 2017-01-12 14:39+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,20 +17,7 @@ "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ../PLCOpenEditor.py:396 -msgid "" -"\n" -"An error has occurred.\n" -"\n" -"Click OK to save an error report.\n" -"\n" -"Please be kind enough to send this file to:\n" -"edouard.tisserant@gmail.com\n" -"\n" -"Error:\n" -msgstr "" - -#: ../Beremiz.py:1155 +#: ../PLCOpenEditor.py:408 ../Beremiz.py:1191 #, python-format msgid "" "\n" @@ -40,7 +27,7 @@ "Please be kind enough to send this file to:\n" "beremiz-devel@lists.sourceforge.net\n" "\n" -"You should now restart Beremiz.\n" +"You should now restart program.\n" "\n" "Traceback:\n" msgstr "" @@ -69,355 +56,369 @@ msgid " Temp" msgstr "" -#: ../PLCOpenEditor.py:406 -msgid " : " -msgstr "" - -#: ../dialogs/PouTransitionDialog.py:94 ../dialogs/ProjectDialog.py:66 +#: ../dialogs/PouTransitionDialog.py:99 ../dialogs/ProjectDialog.py:66 #: ../dialogs/PouActionDialog.py:91 ../dialogs/PouDialog.py:113 #, python-format msgid " and %s" msgstr "" -#: ../ProjectController.py:1027 +#: ../ProjectController.py:1089 msgid " generation failed !\n" msgstr "" -#: ../plcopen/plcopen.py:883 +#: ../plcopen/plcopen.py:881 #, python-format msgid "\"%s\" Data Type doesn't exist !!!" msgstr "" -#: ../plcopen/plcopen.py:901 +#: ../plcopen/plcopen.py:899 #, python-format msgid "\"%s\" POU already exists !!!" msgstr "" -#: ../plcopen/plcopen.py:922 +#: ../plcopen/plcopen.py:920 #, python-format msgid "\"%s\" POU doesn't exist !!!" msgstr "" -#: ../editors/Viewer.py:242 +#: ../editors/Viewer.py:246 #, python-format msgid "\"%s\" can't use itself!" msgstr "" -#: ../IDEFrame.py:1615 ../IDEFrame.py:1634 +#: ../IDEFrame.py:1652 ../IDEFrame.py:1671 #, python-format msgid "\"%s\" config already exists!" msgstr "" -#: ../plcopen/plcopen.py:471 +#: ../plcopen/plcopen.py:467 #, python-format msgid "\"%s\" configuration already exists !!!" msgstr "" -#: ../IDEFrame.py:1569 +#: ../IDEFrame.py:1602 #, python-format msgid "\"%s\" data type already exists!" msgstr "" -#: ../dialogs/PouTransitionDialog.py:105 ../dialogs/BlockPreviewDialog.py:219 -#: ../dialogs/PouActionDialog.py:102 ../editors/Viewer.py:258 -#: ../editors/Viewer.py:326 ../editors/Viewer.py:350 ../editors/Viewer.py:370 -#: ../editors/TextViewer.py:270 ../editors/TextViewer.py:299 -#: ../controls/VariablePanel.py:386 +#: ../dialogs/PouTransitionDialog.py:110 ../dialogs/BlockPreviewDialog.py:219 +#: ../dialogs/PouActionDialog.py:102 ../editors/Viewer.py:262 +#: ../editors/Viewer.py:330 ../editors/Viewer.py:354 ../editors/Viewer.py:374 +#: ../editors/TextViewer.py:272 ../editors/TextViewer.py:301 +#: ../controls/VariablePanel.py:396 #, python-format msgid "\"%s\" element for this pou already exists!" msgstr "" -#: ../Beremiz.py:962 +#: ../Beremiz.py:994 #, python-format msgid "\"%s\" folder is not a valid Beremiz project\n" msgstr "" -#: ../PLCGenerator.py:1091 -#, python-format -msgid "\"%s\" function cancelled in \"%s\" POU: No input connected" -msgstr "" - -#: ../dialogs/SFCStepNameDialog.py:51 ../dialogs/PouTransitionDialog.py:101 -#: ../dialogs/BlockPreviewDialog.py:207 ../dialogs/PouNameDialog.py:49 +#: ../dialogs/SFCStepNameDialog.py:52 ../dialogs/PouTransitionDialog.py:106 +#: ../dialogs/BlockPreviewDialog.py:207 ../dialogs/PouNameDialog.py:50 #: ../dialogs/PouActionDialog.py:98 ../dialogs/PouDialog.py:120 -#: ../editors/DataTypeEditor.py:554 ../editors/DataTypeEditor.py:583 -#: ../editors/CodeFileEditor.py:750 ../controls/VariablePanel.py:733 -#: ../IDEFrame.py:1560 +#: ../editors/DataTypeEditor.py:555 ../editors/DataTypeEditor.py:584 +#: ../editors/CodeFileEditor.py:770 ../controls/VariablePanel.py:751 +#: ../IDEFrame.py:1593 #, python-format msgid "\"%s\" is a keyword. It can't be used!" msgstr "" -#: ../editors/Viewer.py:246 -#, python-format -msgid "\"%s\" is already used by \"%s\"!" -msgstr "" - -#: ../plcopen/plcopen.py:2405 +#: ../plcopen/plcopen.py:2412 #, python-format msgid "\"%s\" is an invalid value!" msgstr "" -#: ../PLCOpenEditor.py:332 ../PLCOpenEditor.py:369 +#: ../PLCOpenEditor.py:339 ../PLCOpenEditor.py:381 #, python-format msgid "\"%s\" is not a valid folder!" msgstr "" -#: ../dialogs/SFCStepNameDialog.py:49 ../dialogs/PouTransitionDialog.py:99 -#: ../dialogs/BlockPreviewDialog.py:203 ../dialogs/PouNameDialog.py:47 +#: ../dialogs/SFCStepNameDialog.py:50 ../dialogs/PouTransitionDialog.py:104 +#: ../dialogs/BlockPreviewDialog.py:203 ../dialogs/PouNameDialog.py:48 #: ../dialogs/PouActionDialog.py:96 ../dialogs/PouDialog.py:118 -#: ../editors/DataTypeEditor.py:578 ../editors/CodeFileEditor.py:748 -#: ../controls/VariablePanel.py:731 ../IDEFrame.py:1558 +#: ../editors/DataTypeEditor.py:579 ../editors/CodeFileEditor.py:768 +#: ../controls/VariablePanel.py:749 ../IDEFrame.py:1591 #, python-format msgid "\"%s\" is not a valid identifier!" msgstr "" -#: ../IDEFrame.py:2362 +#: ../IDEFrame.py:2396 #, python-format msgid "\"%s\" is used by one or more POUs. Do you wish to continue?" msgstr "" #: ../dialogs/BlockPreviewDialog.py:211 ../dialogs/PouDialog.py:122 -#: ../editors/Viewer.py:256 ../editors/Viewer.py:311 ../editors/Viewer.py:341 -#: ../editors/Viewer.py:363 ../editors/TextViewer.py:268 -#: ../editors/TextViewer.py:297 ../editors/TextViewer.py:348 -#: ../editors/TextViewer.py:371 ../controls/VariablePanel.py:328 -#: ../IDEFrame.py:1578 +#: ../editors/Viewer.py:260 ../editors/Viewer.py:315 ../editors/Viewer.py:345 +#: ../editors/Viewer.py:367 ../editors/TextViewer.py:270 +#: ../editors/TextViewer.py:299 ../editors/TextViewer.py:350 +#: ../editors/TextViewer.py:373 ../controls/VariablePanel.py:338 +#: ../IDEFrame.py:1611 #, python-format msgid "\"%s\" pou already exists!" msgstr "" -#: ../plcopen/plcopen.py:495 -#, python-format -msgid "\"%s\" resource already exists in \"%s\" configuration !!!" -msgstr "" - -#: ../plcopen/plcopen.py:512 -#, python-format -msgid "\"%s\" resource doesn't exist in \"%s\" configuration !!!" -msgstr "" - -#: ../dialogs/SFCStepNameDialog.py:57 +#: ../dialogs/SFCStepNameDialog.py:58 #, python-format msgid "\"%s\" step already exists!" msgstr "" -#: ../editors/DataTypeEditor.py:549 +#: ../editors/DataTypeEditor.py:550 #, python-format msgid "\"%s\" value already defined!" msgstr "" -#: ../dialogs/ArrayTypeDialog.py:97 ../editors/DataTypeEditor.py:744 +#: ../dialogs/ArrayTypeDialog.py:97 ../editors/DataTypeEditor.py:745 #, python-format msgid "\"%s\" value isn't a valid array dimension!" msgstr "" -#: ../dialogs/ArrayTypeDialog.py:103 ../editors/DataTypeEditor.py:751 +#: ../dialogs/ArrayTypeDialog.py:103 ../editors/DataTypeEditor.py:752 #, python-format msgid "" "\"%s\" value isn't a valid array dimension!\n" "Right value must be greater than left value." msgstr "" -#: ../editors/CodeFileEditor.py:663 -msgid "#" -msgstr "" - -#: ../PLCControler.py:970 -#, python-format -msgid "%s \"%s\" can't be pasted as a %s." -msgstr "" - -#: ../PLCControler.py:1530 +#: ../PLCGenerator.py:1101 +#, python-brace-format +msgid "\"{a1}\" function cancelled in \"{a2}\" POU: No input connected" +msgstr "" + +#: ../editors/Viewer.py:250 +#, python-brace-format +msgid "\"{a1}\" is already used by \"{a2}\"!" +msgstr "" + +#: ../plcopen/plcopen.py:491 +#, python-brace-format +msgid "\"{a1}\" resource already exists in \"{a2}\" configuration !!!" +msgstr "" + +#: ../plcopen/plcopen.py:509 +#, python-brace-format +msgid "\"{a1}\" resource doesn't exist in \"{a2}\" configuration !!!" +msgstr "" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:578 +#, python-format +msgid "%03gms" +msgstr "" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:569 +#, python-format +msgid "%dd" +msgstr "" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:56 +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:570 +#, python-format +msgid "%dh" +msgstr "" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:55 +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:571 +#, python-format +msgid "%dm" +msgstr "" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:53 +#, python-format +msgid "%dms" +msgstr "" + +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:54 +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:572 +#, python-format +msgid "%ds" +msgstr "" + +#: ../PLCControler.py:1531 #, python-format msgid "%s Data Types" msgstr "" -#: ../PLCControler.py:1513 +#: ../PLCControler.py:1514 #, python-format msgid "%s POUs" msgstr "" -#: ../canfestival/SlaveEditor.py:46 ../canfestival/NetworkEditor.py:67 +#: ../canfestival/SlaveEditor.py:69 ../canfestival/NetworkEditor.py:90 #, python-format msgid "%s Profile" msgstr "" -#: ../ConfigTreeNode.py:32 -#, python-format -msgid "" -"%s XML file doesn't follow XSD schema at line %d:\n" -"%s" -msgstr "" - -#: ../plcopen/plcopen.py:1638 ../plcopen/plcopen.py:1645 -#: ../plcopen/plcopen.py:1657 ../plcopen/plcopen.py:1665 -#: ../plcopen/plcopen.py:1675 +#: ../plcopen/plcopen.py:1645 ../plcopen/plcopen.py:1652 +#: ../plcopen/plcopen.py:1664 ../plcopen/plcopen.py:1672 +#: ../plcopen/plcopen.py:1682 #, python-format msgid "%s body don't have instances!" msgstr "" -#: ../plcopen/plcopen.py:1693 ../plcopen/plcopen.py:1700 -#: ../plcopen/plcopen.py:1707 +#: ../plcopen/plcopen.py:1700 ../plcopen/plcopen.py:1707 +#: ../plcopen/plcopen.py:1714 #, python-format msgid "%s body don't have text!" msgstr "" -#: ../IDEFrame.py:362 +#: ../IDEFrame.py:386 msgid "&Add Element" msgstr "" -#: ../IDEFrame.py:332 +#: ../dialogs/AboutDialog.py:65 ../dialogs/AboutDialog.py:113 +#: ../dialogs/AboutDialog.py:150 +msgid "&Close" +msgstr "" + +#: ../IDEFrame.py:356 msgid "&Configuration" msgstr "" -#: ../IDEFrame.py:321 +#: ../IDEFrame.py:345 msgid "&Data Type" msgstr "" -#: ../IDEFrame.py:366 +#: ../IDEFrame.py:390 msgid "&Delete" msgstr "" -#: ../IDEFrame.py:313 +#: ../IDEFrame.py:337 msgid "&Display" msgstr "" -#: ../IDEFrame.py:312 +#: ../IDEFrame.py:336 msgid "&Edit" msgstr "" -#: ../IDEFrame.py:311 +#: ../IDEFrame.py:335 msgid "&File" msgstr "" -#: ../IDEFrame.py:323 +#: ../IDEFrame.py:347 msgid "&Function" msgstr "" -#: ../IDEFrame.py:314 +#: ../IDEFrame.py:338 msgid "&Help" msgstr "" -#: ../IDEFrame.py:327 +#: ../dialogs/AboutDialog.py:64 +msgid "&License" +msgstr "" + +#: ../IDEFrame.py:351 msgid "&Program" msgstr "" -#: ../PLCOpenEditor.py:119 +#: ../PLCOpenEditor.py:125 msgid "&Properties" msgstr "" -#: ../Beremiz.py:317 +#: ../Beremiz.py:324 msgid "&Recent Projects" msgstr "" -#: ../IDEFrame.py:329 +#: ../IDEFrame.py:353 msgid "&Resource" msgstr "" -#: ../controls/SearchResultPanel.py:252 -#, python-format -msgid "'%s' - %d match in project" -msgstr "" - -#: ../controls/SearchResultPanel.py:254 -#, python-format -msgid "'%s' - %d matches in project" -msgstr "" - -#: ../connectors/PYRO/__init__.py:86 -#, python-format -msgid "'%s' is located at %s\n" -msgstr "" - -#: ../controls/SearchResultPanel.py:304 +#: ../controls/SearchResultPanel.py:239 +#, python-brace-format +msgid "'{a1}' - {a2} match in project" +msgstr "" + +#: ../controls/SearchResultPanel.py:241 +#, python-brace-format +msgid "'{a1}' - {a2} matches in project" +msgstr "" + +#: ../connectors/PYRO/__init__.py:90 +#, python-brace-format +msgid "'{a1}' is located at {a2}\n" +msgstr "" + +#: ../controls/SearchResultPanel.py:291 #, python-format msgid "(%d matches)" msgstr "" -#: ../PLCOpenEditor.py:384 ../PLCOpenEditor.py:386 ../PLCOpenEditor.py:387 +#: ../PLCOpenEditor.py:396 ../PLCOpenEditor.py:398 ../PLCOpenEditor.py:399 msgid ", " msgstr "" -#: ../dialogs/PouTransitionDialog.py:96 ../dialogs/PouActionDialog.py:93 +#: ../dialogs/PouTransitionDialog.py:101 ../dialogs/PouActionDialog.py:93 #: ../dialogs/PouDialog.py:115 #, python-format msgid ", %s" msgstr "" -#: ../PLCOpenEditor.py:382 +#: ../PLCOpenEditor.py:394 msgid ". " msgstr "" -#: ../controls/LogViewer.py:278 +#: ../controls/LogViewer.py:279 msgid "1d" msgstr "" -#: ../controls/LogViewer.py:279 +#: ../controls/LogViewer.py:280 msgid "1h" msgstr "" -#: ../controls/LogViewer.py:280 +#: ../controls/LogViewer.py:281 msgid "1m" msgstr "" -#: ../controls/LogViewer.py:281 +#: ../controls/LogViewer.py:282 msgid "1s" msgstr "" -#: ../dialogs/PouDialog.py:124 ../IDEFrame.py:1581 ../IDEFrame.py:1623 -#: ../IDEFrame.py:1642 +#: ../dialogs/PouDialog.py:124 ../IDEFrame.py:1614 ../IDEFrame.py:1660 +#: ../IDEFrame.py:1679 #, python-format msgid "A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?" msgstr "" -#: ../dialogs/SFCStepNameDialog.py:53 ../dialogs/PouTransitionDialog.py:103 -#: ../dialogs/PouNameDialog.py:51 ../dialogs/PouActionDialog.py:100 -#: ../controls/VariablePanel.py:735 ../IDEFrame.py:1593 ../IDEFrame.py:1604 +#: ../dialogs/SFCStepNameDialog.py:54 ../dialogs/PouTransitionDialog.py:108 +#: ../dialogs/PouNameDialog.py:52 ../dialogs/PouActionDialog.py:100 +#: ../controls/VariablePanel.py:753 ../IDEFrame.py:1628 ../IDEFrame.py:1641 #, python-format msgid "A POU named \"%s\" already exists!" msgstr "" -#: ../ConfigTreeNode.py:400 -#, python-format -msgid "A child named \"%s\" already exist -> \"%s\"\n" -msgstr "" - -#: ../dialogs/BrowseLocationsDialog.py:211 +#: ../ConfigTreeNode.py:424 +#, python-brace-format +msgid "A child named \"{a1}\" already exists -> \"{a2}\"\n" +msgstr "" + +#: ../dialogs/BrowseLocationsDialog.py:216 msgid "A location must be selected!" msgstr "" -#: ../dialogs/SFCStepNameDialog.py:55 ../controls/VariablePanel.py:737 -#: ../IDEFrame.py:1595 ../IDEFrame.py:1606 +#: ../dialogs/SFCStepNameDialog.py:56 ../controls/VariablePanel.py:755 +#: ../IDEFrame.py:1630 ../IDEFrame.py:1643 #, python-format msgid "A variable with \"%s\" as name already exists in this pou!" msgstr "" -#: ../editors/CodeFileEditor.py:754 +#: ../editors/CodeFileEditor.py:774 #, python-format msgid "A variable with \"%s\" as name already exists!" msgstr "" -#: ../PLCOpenEditor.py:152 ../Beremiz.py:374 +#: ../dialogs/AboutDialog.py:40 ../PLCOpenEditor.py:158 ../Beremiz.py:381 msgid "About" msgstr "" -#: ../Beremiz.py:997 -msgid "About Beremiz" -msgstr "" - -#: ../PLCOpenEditor.py:346 -msgid "About PLCOpenEditor" -msgstr "" - #: ../plcopen/iec_std.csv:22 msgid "Absolute number" msgstr "" -#: ../dialogs/SFCStepDialog.py:71 ../dialogs/ActionBlockDialog.py:42 +#: ../dialogs/SFCStepDialog.py:72 ../dialogs/ActionBlockDialog.py:42 msgid "Action" msgstr "" -#: ../editors/Viewer.py:551 ../editors/Viewer.py:2069 +#: ../editors/Viewer.py:555 ../editors/Viewer.py:2345 msgid "Action Block" msgstr "" @@ -429,7 +430,7 @@ msgid "Action Name:" msgstr "" -#: ../plcopen/plcopen.py:1356 +#: ../plcopen/plcopen.py:1359 #, python-format msgid "Action with name %s doesn't exist!" msgstr "" @@ -442,72 +443,72 @@ msgid "Actions:" msgstr "" -#: ../editors/Viewer.py:1087 +#: ../editors/Viewer.py:1100 msgid "Active" msgstr "" -#: ../canfestival/SlaveEditor.py:57 ../canfestival/NetworkEditor.py:78 -#: ../editors/Viewer.py:584 ../Beremiz.py:1024 +#: ../canfestival/SlaveEditor.py:80 ../canfestival/NetworkEditor.py:101 +#: ../editors/Viewer.py:588 ../Beremiz.py:1060 msgid "Add" msgstr "" -#: ../IDEFrame.py:1856 ../IDEFrame.py:1891 +#: ../IDEFrame.py:1890 ../IDEFrame.py:1925 msgid "Add Action" msgstr "" -#: ../features.py:8 +#: ../features.py:32 msgid "Add C code accessing located variables synchronously" msgstr "" -#: ../IDEFrame.py:1839 +#: ../IDEFrame.py:1873 msgid "Add Configuration" msgstr "" -#: ../IDEFrame.py:1819 +#: ../IDEFrame.py:1853 msgid "Add DataType" msgstr "" -#: ../editors/Viewer.py:509 +#: ../editors/Viewer.py:513 msgid "Add Divergence Branch" msgstr "" -#: ../dialogs/DiscoveryDialog.py:115 +#: ../dialogs/DiscoveryDialog.py:116 msgid "Add IP" msgstr "" -#: ../IDEFrame.py:1827 +#: ../IDEFrame.py:1861 msgid "Add POU" msgstr "" -#: ../features.py:9 +#: ../features.py:33 msgid "Add Python code executed asynchronously" msgstr "" -#: ../IDEFrame.py:1867 ../IDEFrame.py:1917 +#: ../IDEFrame.py:1901 ../IDEFrame.py:1951 msgid "Add Resource" msgstr "" -#: ../IDEFrame.py:1845 ../IDEFrame.py:1888 +#: ../IDEFrame.py:1879 ../IDEFrame.py:1922 msgid "Add Transition" msgstr "" -#: ../editors/Viewer.py:496 +#: ../editors/Viewer.py:500 msgid "Add Wire Segment" msgstr "" -#: ../editors/SFCViewer.py:359 +#: ../editors/SFCViewer.py:433 msgid "Add a new initial step" msgstr "" -#: ../editors/Viewer.py:2672 ../editors/SFCViewer.py:696 +#: ../editors/Viewer.py:2706 ../editors/SFCViewer.py:770 msgid "Add a new jump" msgstr "" -#: ../editors/SFCViewer.py:381 +#: ../editors/SFCViewer.py:455 msgid "Add a new step" msgstr "" -#: ../features.py:10 +#: ../features.py:34 msgid "Add a simple WxGlade based GUI." msgstr "" @@ -515,7 +516,7 @@ msgid "Add action" msgstr "" -#: ../editors/DataTypeEditor.py:351 +#: ../editors/DataTypeEditor.py:352 msgid "Add element" msgstr "" @@ -523,7 +524,7 @@ msgid "Add instance" msgstr "" -#: ../canfestival/NetworkEditor.py:80 +#: ../canfestival/NetworkEditor.py:103 msgid "Add slave" msgstr "" @@ -531,7 +532,7 @@ msgid "Add task" msgstr "" -#: ../editors/CodeFileEditor.py:640 ../controls/VariablePanel.py:440 +#: ../editors/CodeFileEditor.py:658 ../controls/VariablePanel.py:450 msgid "Add variable" msgstr "" @@ -539,22 +540,22 @@ msgid "Addition" msgstr "" -#: ../plcopen/definitions.py:22 +#: ../plcopen/definitions.py:47 msgid "Additional function blocks" msgstr "" -#: ../editors/Viewer.py:567 +#: ../editors/Viewer.py:571 msgid "Adjust Block Size" msgstr "" -#: ../editors/Viewer.py:1612 +#: ../editors/Viewer.py:1637 msgid "Alignment" msgstr "" -#: ../dialogs/BrowseLocationsDialog.py:34 -#: ../dialogs/BrowseLocationsDialog.py:42 -#: ../dialogs/BrowseLocationsDialog.py:135 -#: ../dialogs/BrowseLocationsDialog.py:138 ../controls/LogViewer.py:297 +#: ../dialogs/BrowseLocationsDialog.py:39 +#: ../dialogs/BrowseLocationsDialog.py:47 +#: ../dialogs/BrowseLocationsDialog.py:140 +#: ../dialogs/BrowseLocationsDialog.py:143 ../controls/LogViewer.py:298 #: ../controls/VariablePanel.py:70 msgid "All" msgstr "" @@ -563,11 +564,11 @@ msgid "All files (*.*)|*.*|CSV files (*.csv)|*.csv" msgstr "" -#: ../ProjectController.py:1523 +#: ../ProjectController.py:1623 msgid "Already connected. Please disconnect\n" msgstr "" -#: ../editors/DataTypeEditor.py:593 +#: ../editors/DataTypeEditor.py:594 #, python-format msgid "An element named \"%s\" already exists in this structure!" msgstr "" @@ -592,8 +593,8 @@ msgid "Arithmetic" msgstr "" -#: ../editors/DataTypeEditor.py:54 ../editors/DataTypeEditor.py:634 -#: ../controls/VariablePanel.py:811 +#: ../editors/DataTypeEditor.py:54 ../editors/DataTypeEditor.py:635 +#: ../controls/VariablePanel.py:829 msgid "Array" msgstr "" @@ -613,7 +614,7 @@ msgid "Author Name (optional):" msgstr "" -#: ../dialogs/FindInPouDialog.py:78 +#: ../dialogs/FindInPouDialog.py:79 msgid "Backward" msgstr "" @@ -625,21 +626,21 @@ msgid "Bad domain name at " msgstr "" -#: ../canfestival/config_utils.py:342 ../canfestival/config_utils.py:624 +#: ../canfestival/config_utils.py:342 ../canfestival/config_utils.py:630 #, python-format msgid "Bad location size : %s" msgstr "" -#: ../dialogs/ArrayTypeDialog.py:55 ../editors/DataTypeEditor.py:174 -#: ../editors/DataTypeEditor.py:204 ../editors/DataTypeEditor.py:296 +#: ../dialogs/ArrayTypeDialog.py:55 ../editors/DataTypeEditor.py:175 +#: ../editors/DataTypeEditor.py:205 ../editors/DataTypeEditor.py:297 msgid "Base Type:" msgstr "" -#: ../editors/DataTypeEditor.py:624 ../controls/VariablePanel.py:769 +#: ../editors/DataTypeEditor.py:625 ../controls/VariablePanel.py:787 msgid "Base Types" msgstr "" -#: ../Beremiz.py:527 +#: ../Beremiz.py:553 msgid "Beremiz" msgstr "" @@ -671,7 +672,7 @@ msgid "Bitwise inverting" msgstr "" -#: ../editors/Viewer.py:521 ../editors/Viewer.py:2073 +#: ../editors/Viewer.py:525 ../editors/Viewer.py:2358 msgid "Block" msgstr "" @@ -679,151 +680,159 @@ msgid "Block Properties" msgstr "" -#: ../editors/TextViewer.py:261 +#: ../editors/TextViewer.py:262 msgid "Block name" msgstr "" -#: ../editors/Viewer.py:487 +#: ../editors/Viewer.py:491 msgid "Bottom" msgstr "" +#: ../ProjectController.py:1301 +msgid "Broken" +msgstr "" + #: ../dialogs/BrowseValuesLibraryDialog.py:37 #, python-format msgid "Browse %s values library" msgstr "" -#: ../dialogs/BrowseLocationsDialog.py:60 +#: ../dialogs/BrowseLocationsDialog.py:65 msgid "Browse Locations" msgstr "" -#: ../ProjectController.py:1668 +#: ../ProjectController.py:1769 msgid "Build" msgstr "" -#: ../ProjectController.py:1166 +#: ../ProjectController.py:1235 msgid "Build directory already clean\n" msgstr "" -#: ../ProjectController.py:1669 +#: ../ProjectController.py:1770 msgid "Build project into build folder" msgstr "" -#: ../ProjectController.py:956 +#: ../ProjectController.py:1018 msgid "C Build crashed !\n" msgstr "" -#: ../ProjectController.py:953 +#: ../ProjectController.py:1015 msgid "C Build failed.\n" msgstr "" -#: ../c_ext/CFileEditor.py:40 +#: ../c_ext/CFileEditor.py:63 msgid "C code" msgstr "" -#: ../ProjectController.py:1031 +#: ../ProjectController.py:1093 msgid "C code generated successfully.\n" msgstr "" -#: ../targets/toolchain_makefile.py:108 +#: ../targets/toolchain_makefile.py:122 msgid "C compilation failed.\n" msgstr "" -#: ../targets/toolchain_gcc.py:132 +#: ../targets/toolchain_gcc.py:156 #, python-format msgid "C compilation of %s failed.\n" msgstr "" -#: ../features.py:8 +#: ../features.py:32 msgid "C extension" msgstr "" -#: ../canfestival/NetworkEditor.py:29 +#: ../dialogs/AboutDialog.py:63 +msgid "C&redits" +msgstr "" + +#: ../canfestival/NetworkEditor.py:52 msgid "CANOpen network" msgstr "" -#: ../canfestival/SlaveEditor.py:21 +#: ../canfestival/SlaveEditor.py:44 msgid "CANOpen slave" msgstr "" -#: ../features.py:7 +#: ../features.py:31 msgid "CANopen support" msgstr "" -#: ../plcopen/plcopen.py:1580 ../plcopen/plcopen.py:1594 -#: ../plcopen/plcopen.py:1615 ../plcopen/plcopen.py:1631 +#: ../plcopen/plcopen.py:1584 ../plcopen/plcopen.py:1598 +#: ../plcopen/plcopen.py:1622 ../plcopen/plcopen.py:1638 msgid "Can only generate execution order on FBD networks!" msgstr "" -#: ../controls/VariablePanel.py:259 +#: ../controls/VariablePanel.py:267 msgid "Can only give a location to local or global variables" msgstr "" -#: ../PLCOpenEditor.py:327 +#: ../PLCOpenEditor.py:334 #, python-format msgid "Can't generate program to file %s!" msgstr "" -#: ../controls/VariablePanel.py:257 +#: ../controls/VariablePanel.py:265 msgid "Can't give a location to a function block instance" msgstr "" -#: ../PLCOpenEditor.py:367 +#: ../PLCOpenEditor.py:379 #, python-format msgid "Can't save project to file %s!" msgstr "" -#: ../controls/VariablePanel.py:303 +#: ../controls/VariablePanel.py:313 msgid "Can't set an initial value to a function block instance" msgstr "" -#: ../ConfigTreeNode.py:504 -#, python-format -msgid "Cannot create child %s of type %s " -msgstr "" - -#: ../ConfigTreeNode.py:429 +#: ../ConfigTreeNode.py:529 +#, python-brace-format +msgid "Cannot create child {a1} of type {a2} " +msgstr "" + +#: ../ConfigTreeNode.py:454 #, python-format msgid "Cannot find lower free IEC channel than %d\n" msgstr "" -#: ../connectors/PYRO/__init__.py:127 +#: ../connectors/PYRO/__init__.py:131 msgid "Cannot get PLC status - connection failed.\n" msgstr "" -#: ../ProjectController.py:817 +#: ../ProjectController.py:881 msgid "Cannot open/parse VARIABLES.csv!\n" msgstr "" -#: ../canfestival/config_utils.py:372 -#, python-format -msgid "Cannot set bit offset for non bool '%s' variable (ID:%d,Idx:%x,sIdx:%x))" -msgstr "" - -#: ../dialogs/SearchInProjectDialog.py:67 ../dialogs/FindInPouDialog.py:87 +#: ../canfestival/config_utils.py:374 +#, python-brace-format +msgid "Cannot set bit offset for non bool '{a1}' variable (ID:{a2},Idx:{a3},sIdx:{a4}))" +msgstr "" + +#: ../dialogs/SearchInProjectDialog.py:59 ../dialogs/FindInPouDialog.py:88 msgid "Case sensitive" msgstr "" -#: ../editors/Viewer.py:482 +#: ../editors/Viewer.py:486 msgid "Center" msgstr "" -#: ../Beremiz_service.py:245 +#: ../Beremiz_service.py:266 msgid "Change IP of interface to bind" msgstr "" -#: ../Beremiz_service.py:244 +#: ../Beremiz_service.py:265 msgid "Change Name" msgstr "" -#: ../IDEFrame.py:1909 +#: ../IDEFrame.py:1943 msgid "Change POU Type To" msgstr "" -#: ../Beremiz_service.py:246 +#: ../Beremiz_service.py:267 msgid "Change Port Number" msgstr "" -#: ../Beremiz_service.py:247 +#: ../Beremiz_service.py:268 msgid "Change working directory" msgstr "" @@ -831,20 +840,20 @@ msgid "Character string" msgstr "" -#: ../svgui/svgui.py:101 +#: ../svgui/svgui.py:125 msgid "Choose a SVG file" msgstr "" -#: ../ProjectController.py:420 +#: ../ProjectController.py:451 msgid "Choose a directory to save project" msgstr "" -#: ../canfestival/canfestival.py:136 ../PLCOpenEditor.py:285 -#: ../PLCOpenEditor.py:317 ../PLCOpenEditor.py:361 +#: ../canfestival/canfestival.py:160 ../PLCOpenEditor.py:292 +#: ../PLCOpenEditor.py:324 ../PLCOpenEditor.py:373 msgid "Choose a file" msgstr "" -#: ../Beremiz.py:899 ../Beremiz.py:934 +#: ../Beremiz.py:931 ../Beremiz.py:966 msgid "Choose a project" msgstr "" @@ -853,15 +862,15 @@ msgid "Choose a value for %s:" msgstr "" -#: ../Beremiz_service.py:293 +#: ../Beremiz_service.py:323 msgid "Choose a working directory " msgstr "" -#: ../ProjectController.py:334 +#: ../ProjectController.py:358 msgid "Chosen folder doesn't contain a program. It's not a valid project!" msgstr "" -#: ../ProjectController.py:301 +#: ../ProjectController.py:325 msgid "Chosen folder isn't empty. You can't use it for a new project!" msgstr "" @@ -869,7 +878,7 @@ msgid "Class" msgstr "" -#: ../controls/VariablePanel.py:431 +#: ../controls/VariablePanel.py:441 msgid "Class Filter:" msgstr "" @@ -877,52 +886,52 @@ msgid "Class:" msgstr "" -#: ../ProjectController.py:1672 +#: ../ProjectController.py:1773 msgid "Clean" msgstr "" -#: ../controls/LogViewer.py:317 +#: ../controls/LogViewer.py:318 msgid "Clean log messages" msgstr "" -#: ../ProjectController.py:1674 +#: ../ProjectController.py:1775 msgid "Clean project build folder" msgstr "" -#: ../ProjectController.py:1163 +#: ../ProjectController.py:1232 msgid "Cleaning the build directory\n" msgstr "" -#: ../IDEFrame.py:411 +#: ../IDEFrame.py:435 msgid "Clear Errors" msgstr "" -#: ../editors/Viewer.py:577 +#: ../editors/Viewer.py:582 msgid "Clear Execution Order" msgstr "" -#: ../dialogs/FindInPouDialog.py:110 +#: ../dialogs/SearchInProjectDialog.py:105 ../dialogs/FindInPouDialog.py:111 msgid "Close" msgstr "" -#: ../PLCOpenEditor.py:192 ../Beremiz.py:667 +#: ../PLCOpenEditor.py:199 ../Beremiz.py:693 msgid "Close Application" msgstr "" -#: ../PLCOpenEditor.py:102 ../Beremiz.py:326 ../Beremiz.py:611 -#: ../IDEFrame.py:981 +#: ../PLCOpenEditor.py:108 ../Beremiz.py:333 ../Beremiz.py:637 +#: ../IDEFrame.py:1009 msgid "Close Project" msgstr "" -#: ../PLCOpenEditor.py:100 ../Beremiz.py:324 +#: ../PLCOpenEditor.py:106 ../Beremiz.py:331 msgid "Close Tab" msgstr "" -#: ../editors/Viewer.py:537 ../editors/Viewer.py:2084 +#: ../editors/Viewer.py:541 ../editors/Viewer.py:2366 msgid "Coil" msgstr "" -#: ../editors/Viewer.py:557 ../editors/LDViewer.py:506 +#: ../editors/Viewer.py:561 ../editors/LDViewer.py:506 msgid "Comment" msgstr "" @@ -942,7 +951,7 @@ msgid "Comparison" msgstr "" -#: ../ProjectController.py:609 +#: ../ProjectController.py:672 msgid "Compiling IEC Program into C code...\n" msgstr "" @@ -950,15 +959,15 @@ msgid "Concatenation" msgstr "" -#: ../editors/ConfTreeNodeEditor.py:206 +#: ../editors/ConfTreeNodeEditor.py:229 msgid "Config" msgstr "" -#: ../editors/ProjectNodeEditor.py:13 +#: ../editors/ProjectNodeEditor.py:36 msgid "Config variables" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:47 +#: ../dialogs/SearchInProjectDialog.py:39 msgid "Configuration" msgstr "" @@ -966,27 +975,27 @@ msgid "Configurations" msgstr "" -#: ../editors/Viewer.py:303 ../editors/Viewer.py:333 ../editors/Viewer.py:355 -#: ../editors/TextViewer.py:289 ../editors/TextViewer.py:340 -#: ../editors/TextViewer.py:363 ../controls/VariablePanel.py:318 +#: ../editors/Viewer.py:307 ../editors/Viewer.py:337 ../editors/Viewer.py:359 +#: ../editors/TextViewer.py:291 ../editors/TextViewer.py:342 +#: ../editors/TextViewer.py:365 ../controls/VariablePanel.py:328 msgid "Confirm or change variable name" msgstr "" -#: ../ProjectController.py:1687 +#: ../ProjectController.py:1788 msgid "Connect" msgstr "" -#: ../ProjectController.py:1688 +#: ../ProjectController.py:1789 msgid "Connect to the target PLC" msgstr "" -#: ../ProjectController.py:1212 +#: ../ProjectController.py:1292 #, python-format msgid "Connected to URI: %s" msgstr "" -#: ../dialogs/SFCTransitionDialog.py:75 ../editors/Viewer.py:523 -#: ../editors/Viewer.py:2075 +#: ../dialogs/SFCTransitionDialog.py:76 ../editors/Viewer.py:527 +#: ../editors/Viewer.py:2359 msgid "Connection" msgstr "" @@ -994,29 +1003,33 @@ msgid "Connection Properties" msgstr "" -#: ../ProjectController.py:1547 +#: ../ProjectController.py:1647 msgid "Connection canceled!\n" msgstr "" -#: ../ProjectController.py:1572 +#: ../ProjectController.py:1672 #, python-format msgid "Connection failed to %s!\n" msgstr "" -#: ../connectors/PYRO/__init__.py:98 +#: ../connectors/PYRO/__init__.py:115 ../connectors/WAMP/__init__.py:111 +msgid "Connection lost!\n" +msgstr "" + +#: ../connectors/PYRO/__init__.py:102 #, python-format msgid "Connection to '%s' failed.\n" msgstr "" -#: ../dialogs/ConnectionDialog.py:64 ../editors/Viewer.py:1569 +#: ../dialogs/ConnectionDialog.py:64 ../editors/Viewer.py:1594 msgid "Connector" msgstr "" -#: ../dialogs/SFCStepDialog.py:64 +#: ../dialogs/SFCStepDialog.py:65 msgid "Connectors:" msgstr "" -#: ../Beremiz.py:436 +#: ../Beremiz.py:448 msgid "Console" msgstr "" @@ -1024,7 +1037,7 @@ msgid "Constant" msgstr "" -#: ../editors/Viewer.py:533 ../editors/Viewer.py:2080 +#: ../editors/Viewer.py:537 ../editors/Viewer.py:2362 msgid "Contact" msgstr "" @@ -1032,7 +1045,7 @@ msgid "Content Description (optional):" msgstr "" -#: ../dialogs/ConnectionDialog.py:65 ../editors/Viewer.py:1570 +#: ../dialogs/ConnectionDialog.py:65 ../editors/Viewer.py:1595 msgid "Continuation" msgstr "" @@ -1052,12 +1065,12 @@ msgid "Conversion to time-of-day" msgstr "" -#: ../editors/Viewer.py:593 ../controls/LogViewer.py:692 ../IDEFrame.py:346 -#: ../IDEFrame.py:401 +#: ../editors/Viewer.py:597 ../controls/LogViewer.py:693 ../IDEFrame.py:370 +#: ../IDEFrame.py:425 msgid "Copy" msgstr "" -#: ../IDEFrame.py:1896 +#: ../IDEFrame.py:1930 msgid "Copy POU" msgstr "" @@ -1073,49 +1086,49 @@ msgid "Cosine" msgstr "" +#: ../ConfigTreeNode.py:656 +#, python-brace-format +msgid "" +"Could not add child \"{a1}\", type {a2} :\n" +"{a3}\n" +msgstr "" + +#: ../py_ext/PythonFileCTNMixin.py:77 +#, python-format +msgid "Couldn't import old %s file." +msgstr "" + #: ../ConfigTreeNode.py:626 -#, python-format +#, python-brace-format msgid "" -"Could not add child \"%s\", type %s :\n" -"%s\n" -msgstr "" - -#: ../py_ext/PythonFileCTNMixin.py:53 -#, python-format -msgid "Couldn't import old %s file." -msgstr "" - -#: ../ConfigTreeNode.py:598 -#, python-format +"Couldn't load confnode base parameters {a1} :\n" +" {a2}" +msgstr "" + +#: ../ConfigTreeNode.py:643 ../CodeFileTreeNode.py:124 +#, python-brace-format msgid "" -"Couldn't load confnode base parameters %s :\n" -" %s" -msgstr "" - -#: ../ConfigTreeNode.py:614 ../CodeFileTreeNode.py:99 -#, python-format -msgid "" -"Couldn't load confnode parameters %s :\n" -" %s" +"Couldn't load confnode parameters {a1} :\n" +" {a2}" msgstr "" #: ../PLCControler.py:946 msgid "Couldn't paste non-POU object." msgstr "" -#: ../ProjectController.py:1486 +#: ../ProjectController.py:1589 msgid "Couldn't start PLC !\n" msgstr "" -#: ../ProjectController.py:1494 +#: ../ProjectController.py:1597 msgid "Couldn't stop PLC !\n" msgstr "" -#: ../ProjectController.py:1458 +#: ../ProjectController.py:1561 msgid "Couldn't stop debugger.\n" msgstr "" -#: ../svgui/svgui.py:23 +#: ../svgui/svgui.py:47 msgid "Create HMI" msgstr "" @@ -1127,71 +1140,79 @@ msgid "Create a new action" msgstr "" -#: ../IDEFrame.py:135 +#: ../IDEFrame.py:159 msgid "Create a new action block" msgstr "" -#: ../IDEFrame.py:84 ../IDEFrame.py:114 ../IDEFrame.py:147 +#: ../IDEFrame.py:108 ../IDEFrame.py:138 ../IDEFrame.py:171 msgid "Create a new block" msgstr "" -#: ../IDEFrame.py:108 +#: ../IDEFrame.py:132 msgid "Create a new branch" msgstr "" -#: ../IDEFrame.py:102 +#: ../IDEFrame.py:126 msgid "Create a new coil" msgstr "" -#: ../IDEFrame.py:78 ../IDEFrame.py:93 ../IDEFrame.py:123 +#: ../IDEFrame.py:102 ../IDEFrame.py:117 ../IDEFrame.py:147 msgid "Create a new comment" msgstr "" -#: ../IDEFrame.py:87 ../IDEFrame.py:117 ../IDEFrame.py:150 +#: ../IDEFrame.py:111 ../IDEFrame.py:141 ../IDEFrame.py:174 msgid "Create a new connection" msgstr "" -#: ../IDEFrame.py:105 ../IDEFrame.py:156 +#: ../IDEFrame.py:129 ../IDEFrame.py:180 msgid "Create a new contact" msgstr "" -#: ../IDEFrame.py:138 +#: ../IDEFrame.py:162 msgid "Create a new divergence" msgstr "" -#: ../dialogs/SFCDivergenceDialog.py:51 +#: ../dialogs/SFCDivergenceDialog.py:53 msgid "Create a new divergence or convergence" msgstr "" -#: ../IDEFrame.py:126 +#: ../IDEFrame.py:150 msgid "Create a new initial step" msgstr "" -#: ../IDEFrame.py:141 +#: ../IDEFrame.py:165 msgid "Create a new jump" msgstr "" -#: ../IDEFrame.py:96 ../IDEFrame.py:153 +#: ../IDEFrame.py:120 ../IDEFrame.py:177 msgid "Create a new power rail" msgstr "" -#: ../IDEFrame.py:99 +#: ../IDEFrame.py:123 msgid "Create a new rung" msgstr "" -#: ../IDEFrame.py:129 +#: ../IDEFrame.py:153 msgid "Create a new step" msgstr "" -#: ../dialogs/PouTransitionDialog.py:42 ../IDEFrame.py:132 +#: ../dialogs/PouTransitionDialog.py:47 ../IDEFrame.py:156 msgid "Create a new transition" msgstr "" -#: ../IDEFrame.py:81 ../IDEFrame.py:111 ../IDEFrame.py:144 +#: ../IDEFrame.py:105 ../IDEFrame.py:135 ../IDEFrame.py:168 msgid "Create a new variable" msgstr "" -#: ../editors/Viewer.py:592 ../IDEFrame.py:344 ../IDEFrame.py:400 +#: ../dialogs/AboutDialog.py:105 +msgid "Credits" +msgstr "" + +#: ../Beremiz_service.py:432 +msgid "Current working directory :" +msgstr "" + +#: ../editors/Viewer.py:596 ../IDEFrame.py:368 ../IDEFrame.py:424 msgid "Cut" msgstr "" @@ -1207,15 +1228,15 @@ msgid "DEPRECATED" msgstr "" -#: ../canfestival/SlaveEditor.py:53 ../canfestival/NetworkEditor.py:74 +#: ../canfestival/SlaveEditor.py:76 ../canfestival/NetworkEditor.py:97 msgid "DS-301 Profile" msgstr "" -#: ../canfestival/SlaveEditor.py:54 ../canfestival/NetworkEditor.py:75 +#: ../canfestival/SlaveEditor.py:77 ../canfestival/NetworkEditor.py:98 msgid "DS-302 Profile" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:43 +#: ../dialogs/SearchInProjectDialog.py:35 msgid "Data Type" msgstr "" @@ -1244,7 +1265,7 @@ msgid "Days:" msgstr "" -#: ../ProjectController.py:1594 +#: ../ProjectController.py:1694 msgid "Debug does not match PLC - stop/transfert/start to re-enable\n" msgstr "" @@ -1252,42 +1273,42 @@ msgid "Debug instance" msgstr "" -#: ../editors/Viewer.py:1104 ../editors/Viewer.py:3596 +#: ../editors/Viewer.py:1117 ../editors/Viewer.py:3653 #, python-format msgid "Debug: %s" msgstr "" -#: ../ProjectController.py:1247 +#: ../ProjectController.py:1350 #, python-format msgid "Debug: Unknown variable '%s'\n" msgstr "" -#: ../ProjectController.py:1245 +#: ../ProjectController.py:1348 #, python-format msgid "Debug: Unsupported type to debug '%s'\n" msgstr "" -#: ../IDEFrame.py:611 +#: ../IDEFrame.py:639 msgid "Debugger" msgstr "" -#: ../ProjectController.py:1427 +#: ../ProjectController.py:1530 msgid "Debugger disabled\n" msgstr "" -#: ../ProjectController.py:1591 +#: ../ProjectController.py:1691 msgid "Debugger ready\n" msgstr "" -#: ../ProjectController.py:1460 +#: ../ProjectController.py:1563 msgid "Debugger stopped.\n" msgstr "" -#: ../editors/Viewer.py:568 ../Beremiz.py:1028 ../IDEFrame.py:1925 +#: ../editors/Viewer.py:572 ../Beremiz.py:1064 ../IDEFrame.py:1959 msgid "Delete" msgstr "" -#: ../editors/Viewer.py:510 +#: ../editors/Viewer.py:514 msgid "Delete Divergence Branch" msgstr "" @@ -1295,7 +1316,7 @@ msgid "Delete File" msgstr "" -#: ../editors/Viewer.py:497 +#: ../editors/Viewer.py:501 msgid "Delete Wire Segment" msgstr "" @@ -1307,33 +1328,23 @@ msgid "Deletion (within)" msgstr "" -#: ../editors/DataTypeEditor.py:152 +#: ../editors/DataTypeEditor.py:153 msgid "Derivation Type:" msgstr "" -#: ../plcopen/definitions.py:41 -msgid "" -"Derivative\n" -"The derivative function block produces an output XOUT proportional to the rate of change of the input XIN." -msgstr "" - -#: ../editors/CodeFileEditor.py:664 -msgid "Description" -msgstr "" - -#: ../controls/VariablePanel.py:422 +#: ../controls/VariablePanel.py:432 msgid "Description:" msgstr "" -#: ../dialogs/ArrayTypeDialog.py:61 ../editors/DataTypeEditor.py:320 +#: ../dialogs/ArrayTypeDialog.py:61 ../editors/DataTypeEditor.py:321 msgid "Dimensions:" msgstr "" -#: ../dialogs/FindInPouDialog.py:67 +#: ../dialogs/FindInPouDialog.py:68 msgid "Direction" msgstr "" -#: ../dialogs/BrowseLocationsDialog.py:85 +#: ../dialogs/BrowseLocationsDialog.py:90 msgid "Direction:" msgstr "" @@ -1341,15 +1352,19 @@ msgid "Directly" msgstr "" -#: ../ProjectController.py:1696 +#: ../ProjectController.py:1797 msgid "Disconnect" msgstr "" -#: ../ProjectController.py:1698 +#: ../ProjectController.py:1799 msgid "Disconnect from PLC" msgstr "" -#: ../editors/Viewer.py:552 ../editors/Viewer.py:2061 +#: ../ProjectController.py:1302 +msgid "Disconnected" +msgstr "" + +#: ../editors/Viewer.py:556 ../editors/Viewer.py:2354 msgid "Divergence" msgstr "" @@ -1366,25 +1381,19 @@ msgid "Documentation" msgstr "" -#: ../PLCOpenEditor.py:321 +#: ../PLCOpenEditor.py:328 msgid "Done" msgstr "" -#: ../plcopen/definitions.py:34 -msgid "" -"Down-counter\n" -"The down-counter can be used to signal when a count has reached zero, on counting down from a preset value." -msgstr "" - #: ../dialogs/ActionBlockDialog.py:38 msgid "Duration" msgstr "" -#: ../canfestival/canfestival.py:139 +#: ../canfestival/canfestival.py:163 msgid "EDS files (*.eds)|*.eds|All files|*.*" msgstr "" -#: ../editors/Viewer.py:566 +#: ../editors/Viewer.py:570 msgid "Edit Block" msgstr "" @@ -1400,11 +1409,11 @@ msgid "Edit Duration" msgstr "" -#: ../dialogs/SFCStepDialog.py:49 +#: ../dialogs/SFCStepDialog.py:50 msgid "Edit Step" msgstr "" -#: ../wxglade_hmi/wxglade_hmi.py:12 +#: ../wxglade_hmi/wxglade_hmi.py:36 msgid "Edit a WxWidgets GUI with WXGlade" msgstr "" @@ -1416,7 +1425,7 @@ msgid "Edit array type properties" msgstr "" -#: ../editors/Viewer.py:2541 ../editors/Viewer.py:2952 +#: ../editors/Viewer.py:2575 ../editors/Viewer.py:3004 msgid "Edit comment" msgstr "" @@ -1428,47 +1437,51 @@ msgid "Edit item" msgstr "" -#: ../editors/Viewer.py:2916 +#: ../editors/Viewer.py:2963 msgid "Edit jump target" msgstr "" -#: ../ProjectController.py:1710 +#: ../ProjectController.py:1811 msgid "Edit raw IEC code added to code generated by PLCGenerator" msgstr "" -#: ../editors/SFCViewer.py:725 +#: ../editors/SFCViewer.py:799 msgid "Edit step name" msgstr "" -#: ../dialogs/SFCTransitionDialog.py:50 +#: ../dialogs/SFCTransitionDialog.py:51 msgid "Edit transition" msgstr "" -#: ../IDEFrame.py:583 +#: ../IDEFrame.py:611 msgid "Editor ToolBar" msgstr "" -#: ../ProjectController.py:1126 +#: ../ProjectController.py:1195 msgid "Editor selection" msgstr "" -#: ../editors/DataTypeEditor.py:347 +#: ../editors/DataTypeEditor.py:348 msgid "Elements :" msgstr "" -#: ../IDEFrame.py:341 +#: ../ProjectController.py:1300 +msgid "Empty" +msgstr "" + +#: ../IDEFrame.py:365 msgid "Enable Undo/Redo" msgstr "" -#: ../Beremiz_service.py:299 +#: ../Beremiz_service.py:331 msgid "Enter a name " msgstr "" -#: ../Beremiz_service.py:286 +#: ../Beremiz_service.py:316 msgid "Enter a port number " msgstr "" -#: ../Beremiz_service.py:277 +#: ../Beremiz_service.py:307 msgid "Enter the IP of the interface to bind" msgstr "" @@ -1481,66 +1494,67 @@ msgstr "" #: ../dialogs/ForceVariableDialog.py:179 -#: ../dialogs/SearchInProjectDialog.py:157 ../dialogs/SFCStepNameDialog.py:59 +#: ../dialogs/SearchInProjectDialog.py:168 ../dialogs/SFCStepNameDialog.py:60 #: ../dialogs/DurationEditorDialog.py:121 -#: ../dialogs/DurationEditorDialog.py:163 ../dialogs/PouTransitionDialog.py:107 +#: ../dialogs/DurationEditorDialog.py:163 ../dialogs/PouTransitionDialog.py:112 #: ../dialogs/BlockPreviewDialog.py:236 ../dialogs/ProjectDialog.py:71 #: ../dialogs/ArrayTypeDialog.py:97 ../dialogs/ArrayTypeDialog.py:103 -#: ../dialogs/PouNameDialog.py:53 ../dialogs/BrowseLocationsDialog.py:211 +#: ../dialogs/PouNameDialog.py:54 ../dialogs/BrowseLocationsDialog.py:216 #: ../dialogs/BrowseValuesLibraryDialog.py:83 ../dialogs/PouActionDialog.py:104 -#: ../dialogs/PouDialog.py:134 ../PLCOpenEditor.py:328 ../PLCOpenEditor.py:333 -#: ../PLCOpenEditor.py:407 ../PLCOpenEditor.py:417 ../editors/Viewer.py:419 +#: ../dialogs/PouDialog.py:134 ../PLCOpenEditor.py:335 ../PLCOpenEditor.py:340 +#: ../PLCOpenEditor.py:420 ../PLCOpenEditor.py:430 ../editors/Viewer.py:423 #: ../editors/LDViewer.py:666 ../editors/LDViewer.py:882 -#: ../editors/LDViewer.py:886 ../editors/DataTypeEditor.py:549 -#: ../editors/DataTypeEditor.py:554 ../editors/DataTypeEditor.py:578 -#: ../editors/DataTypeEditor.py:583 ../editors/DataTypeEditor.py:593 -#: ../editors/DataTypeEditor.py:744 ../editors/DataTypeEditor.py:751 -#: ../editors/TextViewer.py:387 ../editors/CodeFileEditor.py:763 -#: ../ProjectController.py:269 ../controls/FolderTree.py:217 +#: ../editors/LDViewer.py:886 ../editors/DataTypeEditor.py:550 +#: ../editors/DataTypeEditor.py:555 ../editors/DataTypeEditor.py:579 +#: ../editors/DataTypeEditor.py:584 ../editors/DataTypeEditor.py:594 +#: ../editors/DataTypeEditor.py:745 ../editors/DataTypeEditor.py:752 +#: ../editors/TextViewer.py:389 ../editors/CodeFileEditor.py:783 +#: ../ProjectController.py:293 ../ProjectController.py:421 +#: ../ProjectController.py:428 ../controls/FolderTree.py:217 #: ../controls/DebugVariablePanel/DebugVariablePanel.py:166 #: ../controls/DebugVariablePanel/DebugVariableTextViewer.py:137 -#: ../controls/DebugVariablePanel/DebugVariableGraphicViewer.py:225 -#: ../controls/VariablePanel.py:392 ../controls/VariablePanel.py:754 -#: ../Beremiz.py:1167 ../IDEFrame.py:975 ../IDEFrame.py:1581 -#: ../IDEFrame.py:1618 ../IDEFrame.py:1623 ../IDEFrame.py:1637 -#: ../IDEFrame.py:1642 ../Beremiz_service.py:190 +#: ../controls/DebugVariablePanel/DebugVariableGraphicViewer.py:231 +#: ../controls/VariablePanel.py:402 ../controls/VariablePanel.py:772 +#: ../Beremiz.py:1203 ../IDEFrame.py:1003 ../IDEFrame.py:1614 +#: ../IDEFrame.py:1655 ../IDEFrame.py:1660 ../IDEFrame.py:1674 +#: ../IDEFrame.py:1679 ../Beremiz_service.py:211 msgid "Error" msgstr "" -#: ../ProjectController.py:663 +#: ../ProjectController.py:727 msgid "Error : At least one configuration and one resource must be declared in PLC !\n" msgstr "" -#: ../ProjectController.py:655 +#: ../ProjectController.py:719 #, python-format msgid "Error : IEC to C compiler returned %d\n" msgstr "" -#: ../ProjectController.py:589 +#: ../ProjectController.py:621 #, python-format msgid "" "Error in ST/IL/SFC code generator :\n" "%s\n" msgstr "" -#: ../ConfigTreeNode.py:192 +#: ../ConfigTreeNode.py:216 #, python-format msgid "Error while saving \"%s\"\n" msgstr "" -#: ../canfestival/canfestival.py:144 +#: ../canfestival/canfestival.py:168 msgid "Error: Export slave failed\n" msgstr "" -#: ../canfestival/canfestival.py:345 +#: ../canfestival/canfestival.py:369 msgid "Error: No Master generated\n" msgstr "" -#: ../canfestival/canfestival.py:340 +#: ../canfestival/canfestival.py:364 msgid "Error: No PLC built\n" msgstr "" -#: ../ProjectController.py:1566 +#: ../ProjectController.py:1666 #, python-format msgid "Exception while connecting %s!\n" msgstr "" @@ -1553,7 +1567,7 @@ msgid "Execution Order:" msgstr "" -#: ../features.py:11 +#: ../features.py:35 msgid "Experimental web based HMI" msgstr "" @@ -1565,7 +1579,7 @@ msgid "Exponentiation" msgstr "" -#: ../canfestival/canfestival.py:150 +#: ../canfestival/canfestival.py:174 msgid "Export CanOpen slave to EDS file" msgstr "" @@ -1573,7 +1587,7 @@ msgid "Export graph values to clipboard" msgstr "" -#: ../canfestival/canfestival.py:149 +#: ../canfestival/canfestival.py:173 msgid "Export slave" msgstr "" @@ -1585,33 +1599,32 @@ msgid "External" msgstr "" -#: ../ProjectController.py:676 +#: ../ProjectController.py:740 msgid "Extracting Located Variables...\n" msgstr "" -#: ../dialogs/PouTransitionDialog.py:35 ../dialogs/PouActionDialog.py:31 +#: ../dialogs/PouTransitionDialog.py:40 ../dialogs/PouActionDialog.py:31 #: ../dialogs/PouDialog.py:36 ../controls/ProjectPropertiesPanel.py:143 msgid "FBD" msgstr "" -#: ../ProjectController.py:1629 +#: ../ProjectController.py:1729 msgid "Failed : Must build before transfer.\n" msgstr "" -#: ../dialogs/LDElementDialog.py:77 ../editors/Viewer.py:458 +#: ../dialogs/LDElementDialog.py:77 ../editors/Viewer.py:462 msgid "Falling Edge" msgstr "" -#: ../plcopen/definitions.py:32 -msgid "" -"Falling edge detector\n" -"The output produces a single pulse when a falling edge is detected." -msgstr "" - -#: ../ProjectController.py:946 +#: ../ProjectController.py:1008 msgid "Fatal : cannot get builder.\n" msgstr "" +#: ../Beremiz.py:118 +#, python-format +msgid "Fetching %s" +msgstr "" + #: ../dialogs/DurationEditorDialog.py:160 #, python-format msgid "Field %s hasn't a valid value!" @@ -1627,16 +1640,16 @@ msgid "File '%s' already exists!" msgstr "" -#: ../dialogs/FindInPouDialog.py:35 ../dialogs/FindInPouDialog.py:105 -#: ../IDEFrame.py:351 +#: ../dialogs/SearchInProjectDialog.py:100 ../dialogs/FindInPouDialog.py:36 +#: ../dialogs/FindInPouDialog.py:106 ../IDEFrame.py:375 msgid "Find" msgstr "" -#: ../IDEFrame.py:353 +#: ../IDEFrame.py:377 msgid "Find Next" msgstr "" -#: ../IDEFrame.py:355 +#: ../IDEFrame.py:379 msgid "Find Previous" msgstr "" @@ -1648,11 +1661,11 @@ msgid "Find:" msgstr "" -#: ../connectors/PYRO/__init__.py:159 +#: ../connectors/PYRO/__init__.py:163 msgid "Force runtime reload\n" msgstr "" -#: ../editors/Viewer.py:1528 +#: ../editors/Viewer.py:1553 msgid "Force value" msgstr "" @@ -1660,44 +1673,40 @@ msgid "Forcing Variable Value" msgstr "" -#: ../dialogs/SFCTransitionDialog.py:178 ../dialogs/PouTransitionDialog.py:97 +#: ../dialogs/SFCTransitionDialog.py:179 ../dialogs/PouTransitionDialog.py:102 #: ../dialogs/ProjectDialog.py:70 ../dialogs/PouActionDialog.py:94 #: ../dialogs/PouDialog.py:116 #, python-format msgid "Form isn't complete. %s must be filled!" msgstr "" -#: ../dialogs/SFCStepDialog.py:141 ../dialogs/FBDBlockDialog.py:232 +#: ../dialogs/SFCStepDialog.py:144 ../dialogs/FBDBlockDialog.py:232 #: ../dialogs/ConnectionDialog.py:160 msgid "Form isn't complete. Name must be filled!" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:145 -msgid "Form isn't complete. Pattern to search must be filled!" -msgstr "" - #: ../dialogs/FBDBlockDialog.py:228 msgid "Form isn't complete. Valid block type must be selected!" msgstr "" -#: ../dialogs/FindInPouDialog.py:73 +#: ../dialogs/FindInPouDialog.py:74 msgid "Forward" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:44 ../IDEFrame.py:1712 +#: ../dialogs/SearchInProjectDialog.py:36 ../IDEFrame.py:1746 msgid "Function" msgstr "" -#: ../IDEFrame.py:325 +#: ../IDEFrame.py:349 msgid "Function &Block" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:45 ../IDEFrame.py:1711 -#: ../IDEFrame.py:1904 +#: ../dialogs/SearchInProjectDialog.py:37 ../IDEFrame.py:1745 +#: ../IDEFrame.py:1938 msgid "Function Block" msgstr "" -#: ../controls/VariablePanel.py:807 +#: ../controls/VariablePanel.py:825 msgid "Function Block Types" msgstr "" @@ -1705,11 +1714,11 @@ msgid "Function Blocks" msgstr "" -#: ../editors/Viewer.py:244 +#: ../editors/Viewer.py:248 msgid "Function Blocks can't be used in Functions!" msgstr "" -#: ../PLCControler.py:2336 +#: ../PLCControler.py:2337 #, python-format msgid "FunctionBlock \"%s\" can't be pasted in a Function!!!" msgstr "" @@ -1718,11 +1727,11 @@ msgid "Functions" msgstr "" -#: ../PLCOpenEditor.py:109 +#: ../PLCOpenEditor.py:115 msgid "Generate Program" msgstr "" -#: ../ProjectController.py:580 +#: ../ProjectController.py:612 msgid "Generating SoftPLC IEC-61131 ST/IL/SFC code...\n" msgstr "" @@ -1750,6 +1759,10 @@ msgid "Grid Resolution:" msgstr "" +#: ../runtime/NevowServer.py:181 +msgid "HTTP interface port :" +msgstr "" + #: ../controls/ProjectPropertiesPanel.py:120 msgid "Height:" msgstr "" @@ -1766,62 +1779,51 @@ msgid "Hours:" msgstr "" -#: ../plcopen/definitions.py:44 -msgid "" -"Hysteresis\n" -"The hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2." -msgstr "" - -#: ../dialogs/PouTransitionDialog.py:35 ../dialogs/PouActionDialog.py:31 -#: ../dialogs/PouDialog.py:36 +#: ../dialogs/PouActionDialog.py:31 ../dialogs/PouDialog.py:36 msgid "IL" msgstr "" -#: ../dialogs/DiscoveryDialog.py:93 +#: ../dialogs/DiscoveryDialog.py:94 msgid "IP" msgstr "" -#: ../Beremiz_service.py:278 ../Beremiz_service.py:279 +#: ../Beremiz_service.py:308 ../Beremiz_service.py:309 msgid "IP is not valid!" msgstr "" -#: ../svgui/svgui.py:18 ../svgui/svgui.py:19 +#: ../svgui/svgui.py:42 ../svgui/svgui.py:43 msgid "Import SVG" msgstr "" -#: ../dialogs/FBDVariableDialog.py:38 ../editors/Viewer.py:1555 +#: ../dialogs/FBDVariableDialog.py:38 ../editors/Viewer.py:1580 #: ../controls/VariablePanel.py:71 msgid "InOut" msgstr "" -#: ../editors/Viewer.py:1087 +#: ../editors/Viewer.py:1100 msgid "Inactive" msgstr "" -#: ../controls/VariablePanel.py:268 -#, python-format -msgid "Incompatible data types between \"%s\" and \"%s\"" -msgstr "" - -#: ../controls/VariablePanel.py:277 -#, python-format -msgid "Incompatible size of data between \"%s\" and \"%s\"" -msgstr "" - -#: ../controls/VariablePanel.py:273 +#: ../controls/VariablePanel.py:276 +#, python-brace-format +msgid "Incompatible data types between \"{a1}\" and \"{a2}\"" +msgstr "" + +#: ../controls/VariablePanel.py:282 #, python-format msgid "Incompatible size of data between \"%s\" and \"BOOL\"" msgstr "" +#: ../controls/VariablePanel.py:286 +#, python-brace-format +msgid "Incompatible size of data between \"{a1}\" and \"{a2}\"" +msgstr "" + #: ../dialogs/ActionBlockDialog.py:38 msgid "Indicator" msgstr "" -#: ../editors/CodeFileEditor.py:663 -msgid "Initial" -msgstr "" - -#: ../editors/Viewer.py:548 ../editors/Viewer.py:2058 +#: ../editors/Viewer.py:552 msgid "Initial Step" msgstr "" @@ -1830,22 +1832,24 @@ msgid "Initial Value" msgstr "" -#: ../editors/DataTypeEditor.py:184 ../editors/DataTypeEditor.py:215 -#: ../editors/DataTypeEditor.py:271 ../editors/DataTypeEditor.py:309 +#: ../editors/DataTypeEditor.py:185 ../editors/DataTypeEditor.py:216 +#: ../editors/DataTypeEditor.py:272 ../editors/DataTypeEditor.py:310 msgid "Initial Value:" msgstr "" -#: ../svgui/svgui.py:22 +#: ../svgui/svgui.py:46 msgid "Inkscape" msgstr "" -#: ../dialogs/SFCTransitionDialog.py:74 ../dialogs/ActionBlockDialog.py:42 +#: ../dialogs/SFCTransitionDialog.py:75 ../dialogs/ActionBlockDialog.py:42 msgid "Inline" msgstr "" -#: ../dialogs/SFCStepDialog.py:69 ../dialogs/FBDVariableDialog.py:37 -#: ../dialogs/BrowseLocationsDialog.py:35 ../editors/Viewer.py:1553 -#: ../controls/VariablePanel.py:71 +#: ../dialogs/SFCStepDialog.py:70 ../dialogs/FBDVariableDialog.py:37 +#: ../dialogs/BrowseLocationsDialog.py:40 ../editors/Viewer.py:289 +#: ../editors/Viewer.py:1578 ../editors/TextViewer.py:307 +#: ../controls/LocationCellEditor.py:98 ../controls/VariablePanel.py:71 +#: ../controls/VariablePanel.py:291 ../controls/VariablePanel.py:351 msgid "Input" msgstr "" @@ -1857,7 +1861,7 @@ msgid "Insertion (into)" msgstr "" -#: ../plcopen/plcopen.py:1684 +#: ../plcopen/plcopen.py:1691 #, python-format msgid "Instance with id %d doesn't exist!" msgstr "" @@ -1866,12 +1870,6 @@ msgid "Instances:" msgstr "" -#: ../plcopen/definitions.py:40 -msgid "" -"Integral\n" -"The integral function block integrates the value of input XIN over time." -msgstr "" - #: ../controls/VariablePanel.py:70 msgid "Interface" msgstr "" @@ -1884,48 +1882,53 @@ msgid "Interval" msgstr "" -#: ../PLCControler.py:2324 +#: ../PLCControler.py:2325 msgid "Invalid plcopen element(s)!!!" msgstr "" -#: ../canfestival/config_utils.py:377 ../canfestival/config_utils.py:638 -#, python-format -msgid "Invalid type \"%s\"-> %d != %d for location\"%s\"" -msgstr "" - -#: ../dialogs/ForceVariableDialog.py:177 -#, python-format -msgid "Invalid value \"%s\" for \"%s\" variable!" +#: ../canfestival/config_utils.py:381 +#, python-brace-format +msgid "Invalid type \"{a1}\"-> {a2} != {a3} for location\"{a4}\"" +msgstr "" + +#: ../canfestival/config_utils.py:645 +#, python-brace-format +msgid "Invalid type \"{a1}\"-> {a2} != {a3} for location \"{a4}\"" msgstr "" #: ../controls/DebugVariablePanel/DebugVariablePanel.py:132 #: ../controls/DebugVariablePanel/DebugVariableTextViewer.py:92 -#: ../controls/DebugVariablePanel/DebugVariableGraphicViewer.py:160 +#: ../controls/DebugVariablePanel/DebugVariableGraphicViewer.py:166 #, python-format msgid "Invalid value \"%s\" for debug variable" msgstr "" -#: ../controls/VariablePanel.py:247 ../controls/VariablePanel.py:250 +#: ../controls/VariablePanel.py:255 ../controls/VariablePanel.py:258 #, python-format msgid "Invalid value \"%s\" for variable grid element" msgstr "" -#: ../editors/Viewer.py:229 ../editors/Viewer.py:232 +#: ../editors/Viewer.py:233 ../editors/Viewer.py:236 #, python-format msgid "Invalid value \"%s\" for viewer block" msgstr "" +#: ../dialogs/ForceVariableDialog.py:177 +#, python-brace-format +msgid "Invalid value \"{a1}\" for \"{a2}\" variable!" +msgstr "" + #: ../dialogs/DurationEditorDialog.py:121 msgid "" "Invalid value!\n" "You must fill a numeric value." msgstr "" -#: ../editors/Viewer.py:553 ../editors/Viewer.py:2062 +#: ../editors/Viewer.py:557 ../editors/Viewer.py:2343 msgid "Jump" msgstr "" -#: ../dialogs/PouTransitionDialog.py:35 ../dialogs/PouActionDialog.py:31 +#: ../dialogs/PouTransitionDialog.py:40 ../dialogs/PouActionDialog.py:31 #: ../dialogs/PouDialog.py:36 ../controls/ProjectPropertiesPanel.py:143 msgid "LD" msgstr "" @@ -1935,7 +1938,7 @@ msgid "Ladder element with id %d is on more than one rung." msgstr "" -#: ../dialogs/PouTransitionDialog.py:86 ../dialogs/PouActionDialog.py:83 +#: ../dialogs/PouTransitionDialog.py:91 ../dialogs/PouActionDialog.py:83 #: ../dialogs/PouDialog.py:104 msgid "Language" msgstr "" @@ -1944,28 +1947,28 @@ msgid "Language (optional):" msgstr "" -#: ../dialogs/PouTransitionDialog.py:60 ../dialogs/PouActionDialog.py:56 +#: ../dialogs/PouTransitionDialog.py:65 ../dialogs/PouActionDialog.py:56 #: ../dialogs/PouDialog.py:73 msgid "Language:" msgstr "" -#: ../ProjectController.py:1635 +#: ../ProjectController.py:1735 msgid "Latest build already matches current target. Transfering anyway...\n" msgstr "" -#: ../Beremiz_service.py:250 +#: ../Beremiz_service.py:271 msgid "Launch WX GUI inspector" msgstr "" -#: ../Beremiz_service.py:249 +#: ../Beremiz_service.py:270 msgid "Launch a live Python shell" msgstr "" -#: ../editors/Viewer.py:481 +#: ../editors/Viewer.py:485 msgid "Left" msgstr "" -#: ../dialogs/LDPowerRailDialog.py:61 +#: ../dialogs/LDPowerRailDialog.py:62 msgid "Left PowerRail" msgstr "" @@ -1981,27 +1984,31 @@ msgid "Less than or equal to" msgstr "" -#: ../IDEFrame.py:603 +#: ../IDEFrame.py:631 msgid "Library" msgstr "" +#: ../dialogs/AboutDialog.py:143 +msgid "License" +msgstr "" + #: ../plcopen/iec_std.csv:73 msgid "Limitation" msgstr "" -#: ../targets/toolchain_gcc.py:142 +#: ../targets/toolchain_gcc.py:166 msgid "Linking :\n" msgstr "" -#: ../dialogs/DiscoveryDialog.py:110 ../controls/VariablePanel.py:72 +#: ../dialogs/DiscoveryDialog.py:111 ../controls/VariablePanel.py:72 msgid "Local" msgstr "" -#: ../canfestival/canfestival.py:322 +#: ../canfestival/canfestival.py:346 msgid "Local entries" msgstr "" -#: ../ProjectController.py:1541 +#: ../ProjectController.py:1641 msgid "Local service discovery failed!\n" msgstr "" @@ -2009,7 +2016,7 @@ msgid "Location" msgstr "" -#: ../dialogs/BrowseLocationsDialog.py:67 +#: ../dialogs/BrowseLocationsDialog.py:72 msgid "Locations available:" msgstr "" @@ -2017,41 +2024,43 @@ msgid "Logarithm to base 10" msgstr "" -#: ../connectors/PYRO/__init__.py:90 +#: ../connectors/PYRO/__init__.py:94 #, python-format msgid "MDNS resolution failure for '%s'\n" msgstr "" -#: ../canfestival/SlaveEditor.py:41 ../canfestival/NetworkEditor.py:62 +#: ../canfestival/SlaveEditor.py:64 ../canfestival/NetworkEditor.py:85 msgid "Map Variable" msgstr "" -#: ../features.py:7 +#: ../features.py:31 msgid "Map located variables over CANopen" msgstr "" -#: ../canfestival/NetworkEditor.py:83 +#: ../canfestival/NetworkEditor.py:106 msgid "Master" msgstr "" -#: ../ConfigTreeNode.py:514 -#, python-format -msgid "Max count (%d) reached for this confnode of type %s " +#: ../ConfigTreeNode.py:539 +#, python-brace-format +msgid "Max count ({a1}) reached for this confnode of type {a2} " msgstr "" #: ../plcopen/iec_std.csv:71 msgid "Maximum" msgstr "" -#: ../editors/DataTypeEditor.py:238 +#: ../editors/DataTypeEditor.py:239 msgid "Maximum:" msgstr "" -#: ../dialogs/BrowseLocationsDialog.py:37 +#: ../dialogs/BrowseLocationsDialog.py:42 ../editors/Viewer.py:289 +#: ../editors/TextViewer.py:307 ../controls/LocationCellEditor.py:98 +#: ../controls/VariablePanel.py:291 ../controls/VariablePanel.py:351 msgid "Memory" msgstr "" -#: ../IDEFrame.py:571 +#: ../IDEFrame.py:599 msgid "Menu ToolBar" msgstr "" @@ -2059,7 +2068,7 @@ msgid "Microseconds:" msgstr "" -#: ../editors/Viewer.py:486 +#: ../editors/Viewer.py:490 msgid "Middle" msgstr "" @@ -2071,7 +2080,7 @@ msgid "Minimum" msgstr "" -#: ../editors/DataTypeEditor.py:225 +#: ../editors/DataTypeEditor.py:226 msgid "Minimum:" msgstr "" @@ -2087,9 +2096,9 @@ msgid "Modifier:" msgstr "" -#: ../PLCGenerator.py:778 ../PLCGenerator.py:1217 -#, python-format -msgid "More than one connector found corresponding to \"%s\" continuation in \"%s\" POU" +#: ../PLCGenerator.py:786 ../PLCGenerator.py:1230 +#, python-brace-format +msgid "More than one connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU" msgstr "" #: ../dialogs/ActionBlockDialog.py:140 @@ -2104,11 +2113,11 @@ msgid "Move down" msgstr "" +#: ../editors/DataTypeEditor.py:355 +msgid "Move element down" +msgstr "" + #: ../editors/DataTypeEditor.py:354 -msgid "Move element down" -msgstr "" - -#: ../editors/DataTypeEditor.py:353 msgid "Move element up" msgstr "" @@ -2128,7 +2137,7 @@ msgid "Move task up" msgstr "" -#: ../IDEFrame.py:75 ../IDEFrame.py:90 ../IDEFrame.py:120 ../IDEFrame.py:161 +#: ../IDEFrame.py:99 ../IDEFrame.py:114 ../IDEFrame.py:144 ../IDEFrame.py:185 msgid "Move the view" msgstr "" @@ -2136,11 +2145,11 @@ msgid "Move up" msgstr "" -#: ../editors/CodeFileEditor.py:643 ../controls/VariablePanel.py:443 +#: ../editors/CodeFileEditor.py:661 ../controls/VariablePanel.py:453 msgid "Move variable down" msgstr "" -#: ../editors/CodeFileEditor.py:642 ../controls/VariablePanel.py:442 +#: ../editors/CodeFileEditor.py:660 ../controls/VariablePanel.py:452 msgid "Move variable up" msgstr "" @@ -2156,21 +2165,21 @@ msgid "My Computer:" msgstr "" -#: ../dialogs/DiscoveryDialog.py:91 +#: ../dialogs/DiscoveryDialog.py:92 msgid "NAME" msgstr "" #: ../editors/ResourceEditor.py:68 ../editors/ResourceEditor.py:83 -#: ../editors/DataTypeEditor.py:50 ../editors/CodeFileEditor.py:663 -#: ../controls/VariablePanel.py:53 ../controls/VariablePanel.py:54 +#: ../editors/DataTypeEditor.py:50 ../controls/VariablePanel.py:53 +#: ../controls/VariablePanel.py:54 msgid "Name" msgstr "" -#: ../Beremiz_service.py:300 +#: ../Beremiz_service.py:332 msgid "Name must not be null!" msgstr "" -#: ../dialogs/SFCStepDialog.py:55 ../dialogs/FBDBlockDialog.py:83 +#: ../dialogs/SFCStepDialog.py:56 ../dialogs/FBDBlockDialog.py:83 #: ../dialogs/ConnectionDialog.py:75 msgid "Name:" msgstr "" @@ -2179,12 +2188,20 @@ msgid "Natural logarithm" msgstr "" -#: ../dialogs/LDElementDialog.py:75 ../editors/Viewer.py:456 +#: ../dialogs/LDElementDialog.py:75 ../editors/Viewer.py:460 msgid "Negated" msgstr "" -#: ../PLCOpenEditor.py:96 ../PLCOpenEditor.py:138 ../Beremiz.py:314 -#: ../Beremiz.py:349 +#: ../Beremiz_service.py:578 +msgid "Nevow Web service failed. " +msgstr "" + +#: ../Beremiz_service.py:554 +msgid "Nevow/Athena import failed :" +msgstr "" + +#: ../PLCOpenEditor.py:102 ../PLCOpenEditor.py:144 ../Beremiz.py:321 +#: ../Beremiz.py:356 msgid "New" msgstr "" @@ -2192,71 +2209,71 @@ msgid "New item" msgstr "" -#: ../editors/Viewer.py:455 +#: ../editors/Viewer.py:459 msgid "No Modifier" msgstr "" -#: ../ProjectController.py:1662 +#: ../ProjectController.py:1763 msgid "No PLC to transfer (did build succeed ?)\n" msgstr "" -#: ../PLCGenerator.py:1608 +#: ../PLCGenerator.py:1631 #, python-format msgid "No body defined in \"%s\" POU" msgstr "" -#: ../PLCGenerator.py:797 ../PLCGenerator.py:1227 -#, python-format -msgid "No connector found corresponding to \"%s\" continuation in \"%s\" POU" -msgstr "" - -#: ../PLCOpenEditor.py:340 +#: ../PLCGenerator.py:806 ../PLCGenerator.py:1241 +#, python-brace-format +msgid "No connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU" +msgstr "" + +#: ../PLCOpenEditor.py:347 msgid "" "No documentation available.\n" "Coming soon." msgstr "" -#: ../PLCGenerator.py:819 +#: ../PLCGenerator.py:829 #, python-format msgid "No informations found for \"%s\" block" msgstr "" -#: ../PLCGenerator.py:1183 -#, python-format -msgid "No output %s variable found in block %s in POU %s. Connection must be broken" +#: ../PLCGenerator.py:1194 +#, python-brace-format +msgid "No output {a1} variable found in block {a2} in POU {a3}. Connection must be broken" msgstr "" #: ../controls/SearchResultPanel.py:169 msgid "No search results available." msgstr "" -#: ../svgui/svgui.py:107 +#: ../svgui/svgui.py:131 #, python-format msgid "No such SVG file: %s\n" msgstr "" -#: ../canfestival/config_utils.py:633 -#, python-format -msgid "No such index/subindex (%x,%x) (variable %s)" +#: ../canfestival/config_utils.py:639 +#, python-brace-format +msgid "No such index/subindex ({a1},{a2}) (variable {a3})" msgstr "" #: ../canfestival/config_utils.py:362 -#, python-format -msgid "No such index/subindex (%x,%x) in ID : %d (variable %s)" +#, python-brace-format +msgid "No such index/subindex ({a1},{a2}) in ID : {a3} (variable {a4})" msgstr "" #: ../dialogs/BrowseValuesLibraryDialog.py:83 msgid "No valid value selected!" msgstr "" -#: ../PLCGenerator.py:1606 +#: ../PLCGenerator.py:1629 #, python-format msgid "No variable defined in \"%s\" POU" msgstr "" #: ../canfestival/config_utils.py:355 -#, python-format -msgid "Non existing node ID : %d (variable %s)" +#, python-brace-format +msgid "Non existing node ID : {a1} (variable {a2})" msgstr "" #: ../controls/VariablePanel.py:64 @@ -2267,16 +2284,16 @@ msgid "Normal" msgstr "" -#: ../canfestival/config_utils.py:384 -#, python-format -msgid "Not PDO mappable variable : '%s' (ID:%d,Idx:%x,sIdx:%x))" +#: ../canfestival/config_utils.py:389 +#, python-brace-format +msgid "Not PDO mappable variable : '{a1}' (ID:{a2},Idx:{a3},sIdx:{a4}))" msgstr "" #: ../plcopen/iec_std.csv:80 msgid "Not equal to" msgstr "" -#: ../dialogs/SFCDivergenceDialog.py:78 +#: ../dialogs/SFCDivergenceDialog.py:89 msgid "Number of sequences:" msgstr "" @@ -2284,40 +2301,28 @@ msgid "Numerical" msgstr "" -#: ../plcopen/definitions.py:38 -msgid "" -"Off-delay timer\n" -"The off-delay timer can be used to delay setting an output false, for fixed period after input goes false." -msgstr "" - -#: ../plcopen/definitions.py:37 -msgid "" -"On-delay timer\n" -"The on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true." -msgstr "" - -#: ../editors/CodeFileEditor.py:664 -msgid "OnChange" -msgstr "" - -#: ../dialogs/SearchInProjectDialog.py:93 +#: ../dialogs/SearchInProjectDialog.py:86 msgid "Only Elements" msgstr "" -#: ../PLCOpenEditor.py:98 ../PLCOpenEditor.py:139 ../Beremiz.py:316 -#: ../Beremiz.py:350 +#: ../PLCOpenEditor.py:104 ../PLCOpenEditor.py:145 ../Beremiz.py:323 +#: ../Beremiz.py:357 msgid "Open" msgstr "" -#: ../svgui/svgui.py:116 +#: ../svgui/svgui.py:140 msgid "Open Inkscape" msgstr "" -#: ../ProjectController.py:1714 +#: ../version.py:66 +msgid "Open Source framework for automation, implemented IEC 61131 IDE with constantly growing set of extensions and flexible PLC runtime." +msgstr "" + +#: ../ProjectController.py:1815 msgid "Open a file explorer to manage project files" msgstr "" -#: ../wxglade_hmi/wxglade_hmi.py:114 +#: ../wxglade_hmi/wxglade_hmi.py:138 msgid "Open wxGlade" msgstr "" @@ -2325,7 +2330,7 @@ msgid "Option" msgstr "" -#: ../dialogs/FindInPouDialog.py:82 ../editors/CodeFileEditor.py:664 +#: ../dialogs/FindInPouDialog.py:83 msgid "Options" msgstr "" @@ -2333,58 +2338,69 @@ msgid "Organization (optional):" msgstr "" -#: ../canfestival/SlaveEditor.py:51 ../canfestival/NetworkEditor.py:72 +#: ../canfestival/SlaveEditor.py:74 ../canfestival/NetworkEditor.py:95 msgid "Other Profile" msgstr "" -#: ../dialogs/SFCStepDialog.py:70 ../dialogs/FBDVariableDialog.py:39 -#: ../dialogs/BrowseLocationsDialog.py:36 ../editors/Viewer.py:1554 -#: ../controls/VariablePanel.py:71 +#: ../dialogs/SFCStepDialog.py:71 ../dialogs/FBDVariableDialog.py:39 +#: ../dialogs/BrowseLocationsDialog.py:41 ../editors/Viewer.py:289 +#: ../editors/Viewer.py:1579 ../editors/TextViewer.py:307 +#: ../controls/LocationCellEditor.py:98 ../controls/VariablePanel.py:71 +#: ../controls/VariablePanel.py:291 ../controls/VariablePanel.py:351 msgid "Output" msgstr "" -#: ../canfestival/SlaveEditor.py:40 ../canfestival/NetworkEditor.py:61 +#: ../canfestival/SlaveEditor.py:63 ../canfestival/NetworkEditor.py:84 msgid "PDO Receive" msgstr "" -#: ../canfestival/SlaveEditor.py:39 ../canfestival/NetworkEditor.py:60 +#: ../canfestival/SlaveEditor.py:62 ../canfestival/NetworkEditor.py:83 msgid "PDO Transmit" msgstr "" -#: ../plcopen/definitions.py:42 +#: ../targets/toolchain_gcc.py:131 +msgid "PLC :\n" +msgstr "" + +#: ../Beremiz.py:453 +msgid "PLC Log" +msgstr "" + +#: ../ProjectController.py:992 +msgid "PLC code generation failed !\n" +msgstr "" + +#: ../Beremiz_service.py:295 +msgid "PLC is empty or already started." +msgstr "" + +#: ../Beremiz_service.py:302 +msgid "PLC is not started." +msgstr "" + +#: ../PLCOpenEditor.py:196 ../PLCOpenEditor.py:309 +#, python-brace-format msgid "" -"PID\n" -"The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control." -msgstr "" - -#: ../targets/toolchain_gcc.py:107 -msgid "PLC :\n" -msgstr "" - -#: ../Beremiz.py:441 -msgid "PLC Log" -msgstr "" - -#: ../ProjectController.py:930 -msgid "PLC code generation failed !\n" -msgstr "" - -#: ../PLCOpenEditor.py:189 ../PLCOpenEditor.py:302 -#, python-format +"PLC syntax error at line {a1}:\n" +"{a2}" +msgstr "" + +#: ../PLCOpenEditor.py:292 ../PLCOpenEditor.py:373 +msgid "PLCOpen files (*.xml)|*.xml|All files|*.*" +msgstr "" + +#: ../PLCOpenEditor.py:152 ../PLCOpenEditor.py:209 +msgid "PLCOpenEditor" +msgstr "" + +#: ../PLCOpenEditor.py:355 msgid "" -"PLC syntax error at line %d:\n" -"%s" -msgstr "" - -#: ../PLCOpenEditor.py:285 ../PLCOpenEditor.py:361 -msgid "PLCOpen files (*.xml)|*.xml|All files|*.*" -msgstr "" - -#: ../PLCOpenEditor.py:146 ../PLCOpenEditor.py:202 -msgid "PLCOpenEditor" -msgstr "" - -#: ../dialogs/DiscoveryDialog.py:94 +"PLCOpenEditor is part of Beremiz project.\n" +"\n" +"Beremiz is an " +msgstr "" + +#: ../dialogs/DiscoveryDialog.py:95 msgid "PORT" msgstr "" @@ -2404,17 +2420,17 @@ msgid "POU Type:" msgstr "" -#: ../connectors/PYRO/__init__.py:41 +#: ../connectors/PYRO/__init__.py:45 #, python-format msgid "PYRO connecting to URI : %s\n" msgstr "" -#: ../connectors/PYRO/__init__.py:57 +#: ../connectors/PYRO/__init__.py:61 #, python-format msgid "PYRO using certificates in '%s' \n" msgstr "" -#: ../PLCOpenEditor.py:112 ../Beremiz.py:329 +#: ../PLCOpenEditor.py:118 ../Beremiz.py:336 msgid "Page Setup" msgstr "" @@ -2422,7 +2438,7 @@ msgid "Page Size (optional):" msgstr "" -#: ../IDEFrame.py:2565 +#: ../IDEFrame.py:2599 #, python-format msgid "Page: %d" msgstr "" @@ -2431,62 +2447,66 @@ msgid "Parent instance" msgstr "" -#: ../editors/Viewer.py:594 ../IDEFrame.py:348 ../IDEFrame.py:402 +#: ../editors/Viewer.py:598 ../IDEFrame.py:372 ../IDEFrame.py:426 msgid "Paste" msgstr "" -#: ../IDEFrame.py:1831 +#: ../IDEFrame.py:1865 msgid "Paste POU" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:64 +#: ../dialogs/SearchInProjectDialog.py:56 msgid "Pattern to search:" msgstr "" -#: ../dialogs/LDPowerRailDialog.py:72 +#: ../dialogs/LDPowerRailDialog.py:73 msgid "Pin number:" msgstr "" -#: ../editors/Viewer.py:2672 ../editors/Viewer.py:2916 -#: ../editors/SFCViewer.py:696 +#: ../editors/Viewer.py:2706 ../editors/Viewer.py:2963 +#: ../editors/SFCViewer.py:770 msgid "Please choose a target" msgstr "" -#: ../editors/TextViewer.py:261 +#: ../editors/TextViewer.py:262 msgid "Please enter a block name" msgstr "" -#: ../editors/Viewer.py:2542 ../editors/Viewer.py:2953 +#: ../editors/Viewer.py:2576 ../editors/Viewer.py:3005 msgid "Please enter comment text" msgstr "" -#: ../editors/SFCViewer.py:359 ../editors/SFCViewer.py:381 -#: ../editors/SFCViewer.py:725 +#: ../editors/SFCViewer.py:433 ../editors/SFCViewer.py:455 +#: ../editors/SFCViewer.py:799 msgid "Please enter step name" msgstr "" +#: ../Beremiz_service.py:194 +msgid "Please enter text" +msgstr "" + #: ../dialogs/ForceVariableDialog.py:163 #, python-format msgid "Please enter value for a \"%s\" variable:" msgstr "" -#: ../Beremiz_service.py:287 +#: ../Beremiz_service.py:317 msgid "Port number must be 0 <= port <= 65535!" msgstr "" -#: ../Beremiz_service.py:287 +#: ../Beremiz_service.py:317 msgid "Port number must be an integer!" msgstr "" -#: ../editors/Viewer.py:532 ../editors/Viewer.py:2085 +#: ../editors/Viewer.py:536 ../editors/Viewer.py:2367 msgid "Power Rail" msgstr "" -#: ../dialogs/LDPowerRailDialog.py:49 +#: ../dialogs/LDPowerRailDialog.py:50 msgid "Power Rail Properties" msgstr "" -#: ../PLCOpenEditor.py:114 ../Beremiz.py:331 +#: ../PLCOpenEditor.py:120 ../Beremiz.py:338 msgid "Preview" msgstr "" @@ -2494,12 +2514,12 @@ msgid "Preview:" msgstr "" -#: ../PLCOpenEditor.py:116 ../PLCOpenEditor.py:142 ../Beremiz.py:333 -#: ../Beremiz.py:353 +#: ../PLCOpenEditor.py:122 ../PLCOpenEditor.py:148 ../Beremiz.py:340 +#: ../Beremiz.py:360 msgid "Print" msgstr "" -#: ../IDEFrame.py:1047 +#: ../IDEFrame.py:1075 msgid "Print preview" msgstr "" @@ -2507,11 +2527,11 @@ msgid "Priority" msgstr "" -#: ../dialogs/SFCTransitionDialog.py:88 +#: ../dialogs/SFCTransitionDialog.py:89 msgid "Priority:" msgstr "" -#: ../runtime/PLCObject.py:369 +#: ../runtime/PLCObject.py:370 #, python-format msgid "Problem starting PLC : error %d" msgstr "" @@ -2536,12 +2556,12 @@ msgid "Product Version (required):" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:46 ../IDEFrame.py:1710 -#: ../IDEFrame.py:1907 +#: ../dialogs/SearchInProjectDialog.py:38 ../IDEFrame.py:1744 +#: ../IDEFrame.py:1941 msgid "Program" msgstr "" -#: ../PLCOpenEditor.py:330 +#: ../PLCOpenEditor.py:337 msgid "Program was successfully generated!" msgstr "" @@ -2549,11 +2569,11 @@ msgid "Programs" msgstr "" -#: ../editors/Viewer.py:238 +#: ../editors/Viewer.py:242 msgid "Programs can't be used by other POUs!" msgstr "" -#: ../controls/ProjectPropertiesPanel.py:84 ../IDEFrame.py:556 +#: ../controls/ProjectPropertiesPanel.py:84 ../IDEFrame.py:584 msgid "Project" msgstr "" @@ -2562,7 +2582,7 @@ msgid "Project '%s':" msgstr "" -#: ../ProjectController.py:1713 +#: ../ProjectController.py:1814 msgid "Project Files" msgstr "" @@ -2578,19 +2598,19 @@ msgid "Project Version (optional):" msgstr "" -#: ../PLCControler.py:3157 +#: ../PLCControler.py:3158 msgid "" "Project file syntax error:\n" "\n" msgstr "" -#: ../dialogs/ProjectDialog.py:32 ../editors/ProjectNodeEditor.py:14 +#: ../dialogs/ProjectDialog.py:32 ../editors/ProjectNodeEditor.py:37 msgid "Project properties" msgstr "" -#: ../ConfigTreeNode.py:540 -#, python-format -msgid "Project tree layout do not match confnode.xml %s!=%s " +#: ../ConfigTreeNode.py:566 +#, python-brace-format +msgid "Project tree layout do not match confnode.xml {a1}!={a2} " msgstr "" #: ../dialogs/ConnectionDialog.py:94 @@ -2601,17 +2621,28 @@ msgid "Properties" msgstr "" -#: ../plcopen/definitions.py:36 -msgid "" -"Pulse timer\n" -"The pulse timer can be used to generate output pulses of a given time duration." -msgstr "" - -#: ../py_ext/PythonEditor.py:57 +#: ../Beremiz_service.py:440 +msgid "Publishing service on local network" +msgstr "" + +#: ../connectors/PYRO/__init__.py:118 +#, python-format +msgid "Pyro exception: %s\n" +msgstr "" + +#: ../Beremiz_service.py:427 +msgid "Pyro object's uri :" +msgstr "" + +#: ../Beremiz_service.py:426 +msgid "Pyro port :" +msgstr "" + +#: ../py_ext/PythonEditor.py:81 msgid "Python code" msgstr "" -#: ../features.py:9 +#: ../features.py:33 msgid "Python file" msgstr "" @@ -2619,62 +2650,44 @@ msgid "Qualifier" msgstr "" -#: ../PLCOpenEditor.py:122 ../Beremiz.py:336 ../Beremiz_service.py:252 +#: ../PLCOpenEditor.py:128 ../Beremiz.py:343 ../Beremiz_service.py:273 msgid "Quit" msgstr "" -#: ../plcopen/definitions.py:29 -msgid "" -"RS bistable\n" -"The RS bistable is a latch where the Reset dominates." -msgstr "" - -#: ../plcopen/definitions.py:43 -msgid "" -"Ramp\n" -"The RAMP function block is modelled on example given in the standard." -msgstr "" - #: ../controls/DebugVariablePanel/DebugVariablePanel.py:225 msgid "Range:" msgstr "" -#: ../ProjectController.py:1709 +#: ../ProjectController.py:1810 msgid "Raw IEC code" msgstr "" -#: ../plcopen/definitions.py:39 -msgid "" -"Real time clock\n" -"The real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on." -msgstr "" - -#: ../Beremiz.py:1107 +#: ../Beremiz.py:1143 #, python-format msgid "Really delete node '%s'?" msgstr "" -#: ../IDEFrame.py:338 ../IDEFrame.py:398 +#: ../IDEFrame.py:362 ../IDEFrame.py:422 msgid "Redo" msgstr "" -#: ../dialogs/SFCTransitionDialog.py:73 +#: ../dialogs/SFCTransitionDialog.py:74 msgid "Reference" msgstr "" -#: ../dialogs/DiscoveryDialog.py:105 ../IDEFrame.py:408 +#: ../dialogs/DiscoveryDialog.py:106 ../IDEFrame.py:432 msgid "Refresh" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:73 +#: ../dialogs/SearchInProjectDialog.py:66 msgid "Regular expression" msgstr "" -#: ../dialogs/FindInPouDialog.py:97 +#: ../dialogs/FindInPouDialog.py:98 msgid "Regular expressions" msgstr "" -#: ../editors/Viewer.py:1531 +#: ../editors/Viewer.py:1556 msgid "Release value" msgstr "" @@ -2682,16 +2695,16 @@ msgid "Remainder (modulo)" msgstr "" -#: ../Beremiz.py:1108 +#: ../Beremiz.py:1144 #, python-format msgid "Remove %s node" msgstr "" -#: ../IDEFrame.py:2371 +#: ../IDEFrame.py:2405 msgid "Remove Datatype" msgstr "" -#: ../IDEFrame.py:2376 +#: ../IDEFrame.py:2410 msgid "Remove Pou" msgstr "" @@ -2699,7 +2712,7 @@ msgid "Remove action" msgstr "" -#: ../editors/DataTypeEditor.py:352 +#: ../editors/DataTypeEditor.py:353 msgid "Remove element" msgstr "" @@ -2711,7 +2724,7 @@ msgid "Remove instance" msgstr "" -#: ../canfestival/NetworkEditor.py:81 +#: ../canfestival/NetworkEditor.py:104 msgid "Remove slave" msgstr "" @@ -2719,11 +2732,11 @@ msgid "Remove task" msgstr "" -#: ../editors/CodeFileEditor.py:641 ../controls/VariablePanel.py:441 +#: ../editors/CodeFileEditor.py:659 ../controls/VariablePanel.py:451 msgid "Remove variable" msgstr "" -#: ../IDEFrame.py:1911 +#: ../IDEFrame.py:1945 msgid "Rename" msgstr "" @@ -2731,7 +2744,7 @@ msgid "Replace File" msgstr "" -#: ../editors/Viewer.py:498 +#: ../editors/Viewer.py:502 msgid "Replace Wire by connections" msgstr "" @@ -2743,11 +2756,11 @@ msgid "Reset" msgstr "" -#: ../editors/Viewer.py:578 +#: ../editors/Viewer.py:583 msgid "Reset Execution Order" msgstr "" -#: ../IDEFrame.py:423 +#: ../IDEFrame.py:451 msgid "Reset Perspective" msgstr "" @@ -2755,7 +2768,7 @@ msgid "Reset search result" msgstr "" -#: ../PLCControler.py:97 ../Beremiz.py:1039 +#: ../PLCControler.py:97 ../Beremiz.py:1075 msgid "Resources" msgstr "" @@ -2763,28 +2776,22 @@ msgid "Retain" msgstr "" -#: ../controls/VariablePanel.py:414 +#: ../controls/VariablePanel.py:424 msgid "Return Type:" msgstr "" -#: ../editors/Viewer.py:483 +#: ../editors/Viewer.py:487 msgid "Right" msgstr "" -#: ../dialogs/LDPowerRailDialog.py:62 +#: ../dialogs/LDPowerRailDialog.py:63 msgid "Right PowerRail" msgstr "" -#: ../dialogs/LDElementDialog.py:77 ../editors/Viewer.py:457 +#: ../dialogs/LDElementDialog.py:77 ../editors/Viewer.py:461 msgid "Rising Edge" msgstr "" -#: ../plcopen/definitions.py:31 -msgid "" -"Rising edge detector\n" -"The output produces a single pulse when a rising edge is detected." -msgstr "" - #: ../plcopen/iec_std.csv:65 msgid "Rotate left" msgstr "" @@ -2797,23 +2804,23 @@ msgid "Rounding up/down" msgstr "" -#: ../ProjectController.py:1677 +#: ../ProjectController.py:1778 msgid "Run" msgstr "" -#: ../ProjectController.py:975 +#: ../ProjectController.py:1037 msgid "Runtime IO extensions C code generation failed !\n" msgstr "" -#: ../ProjectController.py:984 +#: ../ProjectController.py:1046 msgid "Runtime library extensions C code generation failed !\n" msgstr "" -#: ../canfestival/SlaveEditor.py:38 ../canfestival/NetworkEditor.py:59 +#: ../canfestival/SlaveEditor.py:61 ../canfestival/NetworkEditor.py:82 msgid "SDO Client" msgstr "" -#: ../canfestival/SlaveEditor.py:37 ../canfestival/NetworkEditor.py:58 +#: ../canfestival/SlaveEditor.py:60 ../canfestival/NetworkEditor.py:81 msgid "SDO Server" msgstr "" @@ -2821,51 +2828,59 @@ msgid "SFC" msgstr "" -#: ../plcopen/definitions.py:28 -msgid "" -"SR bistable\n" -"The SR bistable is a latch where the Set dominates." -msgstr "" - -#: ../dialogs/PouTransitionDialog.py:35 ../dialogs/PouActionDialog.py:31 +#: ../PLCGenerator.py:1392 +#, python-brace-format +msgid "SFC jump in pou \"{a1}\" refers to non-existent SFC step \"{a2}\"" +msgstr "" + +#: ../PLCGenerator.py:773 +#, python-format +msgid "SFC transition in POU \"%s\" must be connected." +msgstr "" + +#: ../dialogs/PouTransitionDialog.py:40 ../dialogs/PouActionDialog.py:31 #: ../dialogs/PouDialog.py:36 msgid "ST" msgstr "" -#: ../PLCOpenEditor.py:317 +#: ../PLCOpenEditor.py:324 msgid "ST files (*.st)|*.st|All files|*.*" msgstr "" -#: ../svgui/svgui.py:101 +#: ../svgui/svgui.py:125 msgid "SVG files (*.svg)|*.svg|All files|*.*" msgstr "" -#: ../features.py:11 +#: ../features.py:35 msgid "SVGUI" msgstr "" -#: ../PLCOpenEditor.py:105 ../PLCOpenEditor.py:140 ../Beremiz.py:320 -#: ../Beremiz.py:351 +#: ../PLCOpenEditor.py:111 ../PLCOpenEditor.py:146 ../Beremiz.py:327 +#: ../Beremiz.py:358 msgid "Save" msgstr "" -#: ../PLCOpenEditor.py:107 ../PLCOpenEditor.py:141 ../Beremiz.py:352 +#: ../PLCOpenEditor.py:113 ../PLCOpenEditor.py:147 ../Beremiz.py:359 msgid "Save As..." msgstr "" -#: ../Beremiz.py:322 +#: ../Beremiz.py:329 msgid "Save as" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:76 +#: ../ProjectController.py:420 +msgid "Save path is the same as path of a project! \n" +msgstr "" + +#: ../dialogs/SearchInProjectDialog.py:69 msgid "Scope" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:105 ../IDEFrame.py:595 +#: ../IDEFrame.py:623 msgid "Search" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:52 ../IDEFrame.py:358 ../IDEFrame.py:404 +#: ../dialogs/SearchInProjectDialog.py:44 ../IDEFrame.py:382 ../IDEFrame.py:428 msgid "Search in Project" msgstr "" @@ -2873,17 +2888,17 @@ msgid "Seconds:" msgstr "" -#: ../IDEFrame.py:364 +#: ../IDEFrame.py:388 msgid "Select All" msgstr "" -#: ../editors/Viewer.py:284 ../editors/TextViewer.py:304 -#: ../controls/LocationCellEditor.py:97 ../controls/VariablePanel.py:280 -#: ../controls/VariablePanel.py:340 +#: ../editors/Viewer.py:288 ../editors/TextViewer.py:306 +#: ../controls/LocationCellEditor.py:97 ../controls/VariablePanel.py:290 +#: ../controls/VariablePanel.py:350 msgid "Select a variable class:" msgstr "" -#: ../ProjectController.py:1126 +#: ../ProjectController.py:1195 msgid "Select an editor:" msgstr "" @@ -2891,10 +2906,14 @@ msgid "Select an instance" msgstr "" -#: ../IDEFrame.py:579 +#: ../IDEFrame.py:607 msgid "Select an object" msgstr "" +#: ../ProjectController.py:427 +msgid "Selected directory already contains another project. Overwrite? \n" +msgstr "" + #: ../plcopen/iec_std.csv:70 msgid "Selection" msgstr "" @@ -2907,17 +2926,11 @@ msgid "Selection Divergence" msgstr "" -#: ../plcopen/definitions.py:30 -msgid "" -"Semaphore\n" -"The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources." -msgstr "" - -#: ../dialogs/DiscoveryDialog.py:81 +#: ../dialogs/DiscoveryDialog.py:82 msgid "Service Discovery" msgstr "" -#: ../dialogs/DiscoveryDialog.py:84 +#: ../dialogs/DiscoveryDialog.py:85 msgid "Services available:" msgstr "" @@ -2933,19 +2946,19 @@ msgid "Shift right" msgstr "" -#: ../ProjectController.py:1703 +#: ../ProjectController.py:1804 msgid "Show IEC code generated by PLCGenerator" msgstr "" -#: ../canfestival/canfestival.py:363 +#: ../canfestival/canfestival.py:387 msgid "Show Master" msgstr "" -#: ../canfestival/canfestival.py:364 +#: ../canfestival/canfestival.py:388 msgid "Show Master generated by config_utils" msgstr "" -#: ../ProjectController.py:1701 +#: ../ProjectController.py:1802 msgid "Show code" msgstr "" @@ -2965,52 +2978,65 @@ msgid "Single" msgstr "" -#: ../targets/toolchain_makefile.py:112 +#: ../targets/toolchain_makefile.py:126 msgid "Source didn't change, no build.\n" msgstr "" +#: ../PLCGenerator.py:397 +#, python-brace-format +msgid "Source signal has to be defined for single task '{a1}' in resource '{a2}.{a3}'." +msgstr "" + #: ../plcopen/iec_std.csv:23 msgid "Square root (base 2)" msgstr "" -#: ../plcopen/definitions.py:21 +#: ../plcopen/definitions.py:46 msgid "Standard function blocks" msgstr "" -#: ../ProjectController.py:1679 ../Beremiz_service.py:240 +#: ../ProjectController.py:1780 ../Beremiz_service.py:261 msgid "Start PLC" msgstr "" -#: ../ProjectController.py:922 +#: ../ProjectController.py:984 #, python-format msgid "Start build in %s\n" msgstr "" -#: ../ProjectController.py:1483 +#: ../ProjectController.py:1298 +msgid "Started" +msgstr "" + +#: ../ProjectController.py:1586 msgid "Starting PLC\n" msgstr "" -#: ../Beremiz.py:451 +#: ../Beremiz.py:463 msgid "Status ToolBar" msgstr "" -#: ../editors/Viewer.py:549 ../editors/Viewer.py:2059 +#: ../editors/Viewer.py:553 ../editors/Viewer.py:2342 msgid "Step" msgstr "" -#: ../ProjectController.py:1682 +#: ../ProjectController.py:1783 msgid "Stop" msgstr "" -#: ../Beremiz_service.py:241 +#: ../Beremiz_service.py:262 msgid "Stop PLC" msgstr "" -#: ../ProjectController.py:1684 +#: ../ProjectController.py:1785 msgid "Stop Running PLC" msgstr "" -#: ../ProjectController.py:1455 +#: ../ProjectController.py:1299 +msgid "Stopped" +msgstr "" + +#: ../ProjectController.py:1558 msgid "Stopping debugger...\n" msgstr "" @@ -3026,15 +3052,19 @@ msgid "Subtraction" msgstr "" -#: ../ProjectController.py:961 +#: ../ProjectController.py:1023 msgid "Successfully built.\n" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:154 +#: ../IDEFrame.py:447 +msgid "Switch perspective" +msgstr "" + +#: ../dialogs/SearchInProjectDialog.py:165 ../dialogs/FindInPouDialog.py:172 msgid "Syntax error in regular expression of pattern to search!" msgstr "" -#: ../dialogs/DiscoveryDialog.py:92 +#: ../dialogs/DiscoveryDialog.py:93 msgid "TYPE" msgstr "" @@ -3065,16 +3095,16 @@ msgid "The group of block must be coherent!" msgstr "" -#: ../Beremiz.py:614 ../IDEFrame.py:983 +#: ../Beremiz.py:640 ../IDEFrame.py:1011 msgid "There are changes, do you want to save?" msgstr "" -#: ../IDEFrame.py:1618 ../IDEFrame.py:1637 +#: ../IDEFrame.py:1655 ../IDEFrame.py:1674 #, python-format msgid "There is a POU named \"%s\". This could cause a conflict. Do you wish to continue?" msgstr "" -#: ../IDEFrame.py:1070 +#: ../IDEFrame.py:1098 msgid "" "There was a problem printing.\n" "Perhaps your current printer is not set correctly?" @@ -3084,6 +3114,11 @@ msgid "This option isn't available yet!" msgstr "" +#: ../controls/DebugVariablePanel/DebugVariablePanel.py:565 +#, python-format +msgid "Tick: %d" +msgstr "" + #: ../plcopen/iec_std.csv:40 msgid "Time" msgstr "" @@ -3117,54 +3152,54 @@ msgid "Time-of-day subtraction" msgstr "" -#: ../editors/Viewer.py:485 +#: ../editors/Viewer.py:489 msgid "Top" msgstr "" -#: ../ProjectController.py:1691 +#: ../ProjectController.py:1792 msgid "Transfer" msgstr "" -#: ../ProjectController.py:1693 +#: ../ProjectController.py:1794 msgid "Transfer PLC" msgstr "" -#: ../ProjectController.py:1658 +#: ../ProjectController.py:1758 msgid "Transfer completed successfully.\n" msgstr "" -#: ../ProjectController.py:1660 +#: ../ProjectController.py:1760 msgid "Transfer failed\n" msgstr "" -#: ../editors/Viewer.py:550 ../editors/Viewer.py:2060 ../editors/Viewer.py:2089 +#: ../editors/Viewer.py:554 ../editors/Viewer.py:2344 ../editors/Viewer.py:2371 msgid "Transition" msgstr "" -#: ../PLCGenerator.py:1499 +#: ../PLCGenerator.py:1518 #, python-format msgid "Transition \"%s\" body must contain an output variable or coil referring to its name" msgstr "" -#: ../dialogs/PouTransitionDialog.py:84 +#: ../dialogs/PouTransitionDialog.py:89 msgid "Transition Name" msgstr "" -#: ../dialogs/PouTransitionDialog.py:53 +#: ../dialogs/PouTransitionDialog.py:58 msgid "Transition Name:" msgstr "" -#: ../PLCGenerator.py:1588 -#, python-format -msgid "Transition with content \"%s\" not connected to a next step in \"%s\" POU" -msgstr "" - -#: ../PLCGenerator.py:1579 -#, python-format -msgid "Transition with content \"%s\" not connected to a previous step in \"%s\" POU" -msgstr "" - -#: ../plcopen/plcopen.py:1315 +#: ../PLCGenerator.py:1609 +#, python-brace-format +msgid "Transition with content \"{a1}\" not connected to a next step in \"{a2}\" POU" +msgstr "" + +#: ../PLCGenerator.py:1598 +#, python-brace-format +msgid "Transition with content \"{a1}\" not connected to a previous step in \"{a2}\" POU" +msgstr "" + +#: ../plcopen/plcopen.py:1318 #, python-format msgid "Transition with name %s doesn't exist!" msgstr "" @@ -3173,21 +3208,29 @@ msgid "Transitions" msgstr "" +#: ../dialogs/AboutDialog.py:123 +msgid "Translated by" +msgstr "" + #: ../editors/ResourceEditor.py:68 msgid "Triggering" msgstr "" +#: ../Beremiz_service.py:476 +msgid "Twisted unavailable." +msgstr "" + #: ../dialogs/ActionBlockDialog.py:38 ../editors/ResourceEditor.py:83 -#: ../editors/DataTypeEditor.py:50 ../editors/CodeFileEditor.py:663 -#: ../controls/VariablePanel.py:53 ../controls/VariablePanel.py:54 +#: ../editors/DataTypeEditor.py:50 ../controls/VariablePanel.py:53 +#: ../controls/VariablePanel.py:54 msgid "Type" msgstr "" -#: ../dialogs/BrowseLocationsDialog.py:43 +#: ../dialogs/BrowseLocationsDialog.py:48 msgid "Type and derivated" msgstr "" -#: ../canfestival/config_utils.py:336 ../canfestival/config_utils.py:618 +#: ../canfestival/config_utils.py:336 ../canfestival/config_utils.py:624 #, python-format msgid "Type conflict for location \"%s\"" msgstr "" @@ -3196,33 +3239,33 @@ msgid "Type conversion" msgstr "" -#: ../editors/DataTypeEditor.py:161 +#: ../editors/DataTypeEditor.py:162 msgid "Type infos:" msgstr "" -#: ../dialogs/BrowseLocationsDialog.py:44 +#: ../dialogs/BrowseLocationsDialog.py:49 msgid "Type strict" msgstr "" -#: ../dialogs/SFCDivergenceDialog.py:57 ../dialogs/SFCTransitionDialog.py:56 -#: ../dialogs/LDPowerRailDialog.py:55 ../dialogs/BrowseLocationsDialog.py:94 +#: ../dialogs/SFCDivergenceDialog.py:59 ../dialogs/SFCTransitionDialog.py:57 +#: ../dialogs/LDPowerRailDialog.py:56 ../dialogs/BrowseLocationsDialog.py:99 #: ../dialogs/FBDBlockDialog.py:65 ../dialogs/ConnectionDialog.py:58 msgid "Type:" msgstr "" -#: ../canfestival/config_utils.py:456 ../canfestival/config_utils.py:470 +#: ../canfestival/config_utils.py:462 ../canfestival/config_utils.py:476 #, python-format msgid "Unable to define PDO mapping for node %02x" msgstr "" -#: ../targets/Xenomai/__init__.py:15 +#: ../targets/Xenomai/__init__.py:39 #, python-format msgid "Unable to get Xenomai's %s \n" msgstr "" -#: ../PLCGenerator.py:951 ../PLCGenerator.py:1202 -#, python-format -msgid "Undefined block type \"%s\" in \"%s\" POU" +#: ../PLCGenerator.py:961 ../PLCGenerator.py:1214 +#, python-brace-format +msgid "Undefined block type \"{a1}\" in \"{a2}\" POU" msgstr "" #: ../PLCGenerator.py:254 @@ -3230,20 +3273,20 @@ msgid "Undefined pou type \"%s\"" msgstr "" -#: ../IDEFrame.py:336 ../IDEFrame.py:397 +#: ../IDEFrame.py:360 ../IDEFrame.py:421 msgid "Undo" msgstr "" -#: ../ProjectController.py:308 +#: ../ProjectController.py:332 msgid "Unknown" msgstr "" -#: ../editors/Viewer.py:389 +#: ../editors/Viewer.py:393 #, python-format msgid "Unknown variable \"%s\" for this POU!" msgstr "" -#: ../ProjectController.py:305 ../ProjectController.py:306 +#: ../ProjectController.py:329 ../ProjectController.py:330 msgid "Unnamed" msgstr "" @@ -3252,28 +3295,16 @@ msgid "Unnamed%d" msgstr "" -#: ../controls/VariablePanel.py:275 +#: ../controls/VariablePanel.py:284 #, python-format msgid "Unrecognized data size \"%s\"" msgstr "" -#: ../plcopen/definitions.py:33 -msgid "" -"Up-counter\n" -"The up-counter can be used to signal when a count has reached a maximum value." -msgstr "" - -#: ../plcopen/definitions.py:35 -msgid "" -"Up-down counter\n" -"The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other." -msgstr "" - -#: ../editors/DataTypeEditor.py:631 ../controls/VariablePanel.py:780 +#: ../editors/DataTypeEditor.py:632 ../controls/VariablePanel.py:798 msgid "User Data Types" msgstr "" -#: ../canfestival/SlaveEditor.py:42 ../canfestival/NetworkEditor.py:63 +#: ../canfestival/SlaveEditor.py:65 ../canfestival/NetworkEditor.py:86 msgid "User Type" msgstr "" @@ -3285,26 +3316,32 @@ msgid "Value" msgstr "" -#: ../editors/DataTypeEditor.py:258 +#: ../editors/DataTypeEditor.py:259 msgid "Values:" msgstr "" -#: ../dialogs/ActionBlockDialog.py:42 ../editors/Viewer.py:522 -#: ../editors/Viewer.py:2074 +#: ../dialogs/ActionBlockDialog.py:42 ../editors/Viewer.py:526 +#: ../editors/Viewer.py:2374 msgid "Variable" msgstr "" +#: ../editors/Viewer.py:308 ../editors/Viewer.py:338 ../editors/Viewer.py:360 +#: ../editors/TextViewer.py:292 ../editors/TextViewer.py:343 +#: ../editors/TextViewer.py:366 ../controls/VariablePanel.py:329 +msgid "Variable Drop" +msgstr "" + #: ../dialogs/FBDVariableDialog.py:63 msgid "Variable Properties" msgstr "" -#: ../editors/Viewer.py:284 ../editors/TextViewer.py:304 -#: ../controls/LocationCellEditor.py:97 ../controls/VariablePanel.py:280 -#: ../controls/VariablePanel.py:340 +#: ../editors/Viewer.py:288 ../editors/TextViewer.py:306 +#: ../controls/LocationCellEditor.py:97 ../controls/VariablePanel.py:290 +#: ../controls/VariablePanel.py:350 msgid "Variable class" msgstr "" -#: ../editors/Viewer.py:391 ../editors/TextViewer.py:385 +#: ../editors/Viewer.py:395 ../editors/TextViewer.py:387 msgid "Variable don't belong to this POU!" msgstr "" @@ -3320,21 +3357,29 @@ msgid "Vertical:" msgstr "" -#: ../connectors/WAMP/__init__.py:88 +#: ../Beremiz_service.py:586 +msgid "WAMP client startup failed. " +msgstr "" + +#: ../connectors/WAMP/__init__.py:91 #, python-format msgid "WAMP connecting to URL : %s\n" msgstr "" -#: ../connectors/WAMP/__init__.py:128 +#: ../connectors/WAMP/__init__.py:131 msgid "WAMP connection timeout" msgstr "" -#: ../connectors/WAMP/__init__.py:147 +#: ../connectors/WAMP/__init__.py:150 #, python-format msgid "WAMP connection to '%s' failed.\n" msgstr "" -#: ../wxglade_hmi/wxglade_hmi.py:11 +#: ../Beremiz_service.py:562 +msgid "WAMP import failed :" +msgstr "" + +#: ../wxglade_hmi/wxglade_hmi.py:35 msgid "WXGLADE GUI" msgstr "" @@ -3342,11 +3387,11 @@ msgid "Warning" msgstr "" -#: ../ProjectController.py:584 +#: ../ProjectController.py:616 msgid "Warnings in ST/IL/SFC code generator :\n" msgstr "" -#: ../dialogs/SearchInProjectDialog.py:85 +#: ../dialogs/SearchInProjectDialog.py:78 msgid "Whole Project" msgstr "" @@ -3354,27 +3399,31 @@ msgid "Width:" msgstr "" -#: ../dialogs/FindInPouDialog.py:92 +#: ../dialogs/FindInPouDialog.py:93 msgid "Wrap search" msgstr "" -#: ../features.py:10 +#: ../dialogs/AboutDialog.py:122 +msgid "Written by" +msgstr "" + +#: ../features.py:34 msgid "WxGlade GUI" msgstr "" -#: ../svgui/svgui.py:115 +#: ../svgui/svgui.py:139 msgid "" "You don't have write permissions.\n" "Open Inkscape anyway ?" msgstr "" -#: ../wxglade_hmi/wxglade_hmi.py:113 +#: ../wxglade_hmi/wxglade_hmi.py:137 msgid "" "You don't have write permissions.\n" "Open wxGlade anyway ?" msgstr "" -#: ../ProjectController.py:268 +#: ../ProjectController.py:292 msgid "" "You must have permission to work on the project\n" "Work on a project copy ?" @@ -3388,7 +3437,7 @@ msgid "You must select the wire where a contact should be added!" msgstr "" -#: ../dialogs/SFCStepNameDialog.py:47 ../dialogs/PouNameDialog.py:45 +#: ../dialogs/SFCStepNameDialog.py:48 ../dialogs/PouNameDialog.py:46 msgid "You must type a name!" msgstr "" @@ -3396,29 +3445,25 @@ msgid "You must type a value!" msgstr "" -#: ../IDEFrame.py:414 +#: ../IDEFrame.py:438 msgid "Zoom" msgstr "" -#: ../Beremiz.py:997 -msgid "about.html" -msgstr "" - #: ../dialogs/DurationEditorDialog.py:151 msgid "days" msgstr "" -#: ../PLCOpenEditor.py:326 +#: ../PLCOpenEditor.py:333 #, python-format msgid "error: %s\n" msgstr "" -#: ../util/ProcessLogger.py:166 -#, python-format -msgid "exited with status %s (pid %s)\n" -msgstr "" - -#: ../PLCOpenEditor.py:384 ../PLCOpenEditor.py:386 +#: ../util/ProcessLogger.py:169 +#, python-brace-format +msgid "exited with status {a1} (pid {a2})\n" +msgstr "" + +#: ../PLCOpenEditor.py:396 ../PLCOpenEditor.py:398 msgid "file : " msgstr "" @@ -3426,7 +3471,7 @@ msgid "function" msgstr "" -#: ../PLCOpenEditor.py:387 +#: ../PLCOpenEditor.py:399 msgid "function : " msgstr "" @@ -3438,7 +3483,7 @@ msgid "hours" msgstr "" -#: ../PLCOpenEditor.py:387 +#: ../PLCOpenEditor.py:399 msgid "line : " msgstr "" @@ -3450,10 +3495,6 @@ msgid "minutes" msgstr "" -#: ../PLCOpenEditor.py:346 -msgid "plcopen_about.html" -msgstr "" - #: ../dialogs/PouDialog.py:31 msgid "program" msgstr "" @@ -3474,13 +3515,30 @@ msgid "string right of" msgstr "" -#: ../PLCOpenEditor.py:324 +#: ../Beremiz.py:126 +msgid "update info unavailable." +msgstr "" + +#: ../PLCOpenEditor.py:331 #, python-format msgid "warning: %s\n" msgstr "" +#: ../PLCControler.py:970 +#, python-brace-format +msgid "{a1} \"{a2}\" can't be pasted as a {a3}." +msgstr "" + +#: ../ConfigTreeNode.py:56 +#, python-brace-format +msgid "" +"{a1} XML file doesn't follow XSD schema at line %{a2}:\n" +"{a3}" +msgstr "" + #: Extra XSD strings + msgid "CanFestivalSlaveNode" msgstr "" @@ -3535,6 +3593,9 @@ msgid "LDFLAGS" msgstr "" +msgid "PLC" +msgstr "" + msgid "Linux" msgstr "" @@ -3594,3 +3655,156 @@ msgid "opts" msgstr "" + +#: Extra TC6 documentation strings + + +msgid "0 - current time, 1 - load time from PDT" +msgstr "" + +msgid "Preset datetime" +msgstr "" + +msgid "Copy of IN" +msgstr "" + +msgid "Datetime, current or relative to PDT" +msgstr "" + +msgid "The real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on." +msgstr "" + +msgid "1 = integrate, 0 = hold" +msgstr "" + +msgid "Overriding reset" +msgstr "" + +msgid "Input variable" +msgstr "" + +msgid "Initial value" +msgstr "" + +msgid "Sampling period" +msgstr "" + +msgid "NOT R1" +msgstr "" + +msgid "Integrated output" +msgstr "" + +msgid "The integral function block integrates the value of input XIN over time." +msgstr "" + +msgid "0 = reset" +msgstr "" + +msgid "Input to be differentiated" +msgstr "" + +msgid "Differentiated output" +msgstr "" + +msgid "The derivative function block produces an output XOUT proportional to the rate of change of the input XIN." +msgstr "" + +msgid "0 - manual , 1 - automatic" +msgstr "" + +msgid "Process variable" +msgstr "" + +msgid "Set point" +msgstr "" + +msgid "Manual output adjustment - Typically from transfer station" +msgstr "" + +msgid "Proportionality constant" +msgstr "" + +msgid "Reset time" +msgstr "" + +msgid "Derivative time constant" +msgstr "" + +msgid "PV - SP" +msgstr "" + +msgid "FB for integral term" +msgstr "" + +msgid "FB for derivative term" +msgstr "" + +msgid "The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control." +msgstr "" + +msgid "0 - track X0, 1 - ramp to/track X1" +msgstr "" + +msgid "Ramp duration" +msgstr "" + +msgid "BUSY = 1 during ramping period" +msgstr "" + +msgid "Elapsed time of ramp" +msgstr "" + +msgid "The RAMP function block is modelled on example given in the standard." +msgstr "" + +msgid "The hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2." +msgstr "" + +msgid "The SR bistable is a latch where the Set dominates." +msgstr "" + +msgid "The RS bistable is a latch where the Reset dominates." +msgstr "" + +msgid "The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources." +msgstr "" + +msgid "The output produces a single pulse when a rising edge is detected." +msgstr "" + +msgid "The output produces a single pulse when a falling edge is detected." +msgstr "" + +msgid "The up-counter can be used to signal when a count has reached a maximum value." +msgstr "" + +msgid "The down-counter can be used to signal when a count has reached zero, on counting down from a preset value." +msgstr "" + +msgid "The up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other." +msgstr "" + +msgid "first input parameter" +msgstr "" + +msgid "second input parameter" +msgstr "" + +msgid "first output parameter" +msgstr "" + +msgid "second output parameter" +msgstr "" + +msgid "internal state: 0-reset, 1-counting, 2-set" +msgstr "" + +msgid "The pulse timer can be used to generate output pulses of a given time duration." +msgstr "" + +msgid "The on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true." +msgstr "" + +msgid "The off-delay timer can be used to delay setting an output false, for fixed period after input goes false." +msgstr "" diff -r 6431f26aa501 -r 3291024e00da i18n/mki18n.py --- a/i18n/mki18n.py Thu Feb 16 14:34:40 2017 +0500 +++ b/i18n/mki18n.py Thu Feb 16 14:35:12 2017 +0500 @@ -108,7 +108,33 @@ return languageDict -XSD_STRING_MODEL = re.compile("]*\>") + + +def processCustomFiles(filein, fileout, regexp, prefix = ''): + appfil_file = open(filein, 'r') + messages_file = open(fileout, 'r') + messages = messages_file.read() + messages_file.close() + messages_file = open(fileout, 'a') + messages_file.write('\n') + messages_file.write('#: %s\n' % prefix) + messages_file.write('\n') + + words_found = {} + for filepath in appfil_file.xreadlines(): + code_file = open(filepath.strip(), 'r') + for match in regexp.finditer(code_file.read()): + word = match.group(1) + if not words_found.get(word, False) and messages.find("msgid \"%s\"\nmsgstr \"\"" % word) == -1: + words_found[word] = True + messages_file.write('\n') + messages_file.write("msgid \"%s\"\n"%word) + messages_file.write("msgstr \"\"\n") + code_file.close() + + messages_file.close() + appfil_file.close() + # ----------------------------------------------------------------------------- # m a k e P O ( ) -- Build the Portable Object file for the application -- @@ -143,10 +169,12 @@ else: applicationName = applicationDomain currentDir = os.getcwd() - os.chdir(applicationDirectoryPath) - if not os.path.exists('app.fil'): - raise IOError(2,'No module file: app.fil') - + os.chdir(applicationDirectoryPath) + filelist = 'app.fil' + if not os.path.exists(filelist): + raise IOError(2,'No module file: ' % filelist) + + fileout = 'messages.pot' # Steps: # Use xgettext to parse all application modules # The following switches are used: @@ -154,33 +182,16 @@ # -s : sort output by string content (easier to use when we need to merge several .po files) # --files-from=app.fil : The list of files is taken from the file: app.fil # --output= : specifies the name of the output file (using a .pot extension) - cmd = 'xgettext -s --no-wrap --language=Python --files-from=app.fil --output=messages.pot' + cmd = 'xgettext -s --no-wrap --language=Python --files-from=' + filelist + ' --output=' + fileout if verbose: print cmd os.system(cmd) - appfil_file = open("app.fil", 'r') - messages_file = open("messages.pot", 'r') - messages = messages_file.read() - messages_file.close() - messages_file = open("messages.pot", 'a') - messages_file.write(""" -#: Extra XSD strings -""") - words_found = {} - for filepath in appfil_file.xreadlines(): - code_file = open(filepath.strip(), 'r') - for match in XSD_STRING_MODEL.finditer(code_file.read()): - word = match.group(1) - if not words_found.get(word, False) and messages.find("msgid \"%s\"\nmsgstr \"\"" % word) == -1: - words_found[word] = True - messages_file.write(""" -msgid "%s" -msgstr "" -"""%word) - code_file.close() - messages_file.close() - appfil_file.close() - + XSD_STRING_MODEL = re.compile("]*\>") + processCustomFiles(filelist, fileout, XSD_STRING_MODEL, 'Extra XSD strings') + + XML_TC6_STRING_MODEL = re.compile("\s*\s*", re.MULTILINE | re.DOTALL) + processCustomFiles(filelist, fileout, XML_TC6_STRING_MODEL, 'Extra TC6 documentation strings') + languageDict = getlanguageDict() for langCode in languageDict.keys(): @@ -189,7 +200,7 @@ else: langPOfileName = "%s_%s.po" % (applicationName , langCode) if os.path.exists(langPOfileName): - cmd = 'msgmerge -s --no-wrap "%s" messages.pot > "%s.new"' % (langPOfileName, langPOfileName) + cmd = 'msgmerge -s --no-wrap "%s" %s > "%s.new"' % (langPOfileName, fileout, langPOfileName) if verbose: print cmd os.system(cmd) os.chdir(currentDir) diff -r 6431f26aa501 -r 3291024e00da images/about_brz_logo.png Binary file images/about_brz_logo.png has changed diff -r 6431f26aa501 -r 3291024e00da images/icons.svg --- a/images/icons.svg Thu Feb 16 14:34:40 2017 +0500 +++ b/images/icons.svg Thu Feb 16 14:35:12 2017 +0500 @@ -15,7 +15,7 @@ height="1052.3622" id="svg2" sodipodi:version="0.32" - inkscape:version="0.48.3.1 r9886" + inkscape:version="0.91 r13725" sodipodi:docname="icons.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style="fill:#84c225;fill-rule:evenodd;stroke:#5d9d35;stroke-width:2.82220006" /> + style="fill:#84c225;fill-rule:evenodd;stroke:#5d9d35;stroke-width:2.82220006" /> + cx="0" /> + cx="0" /> + cx="0" /> + cx="0" /> + cx="0" /> + style="fill:#84c225;fill-rule:evenodd;stroke:#5d9d35;stroke-width:2.82220006" /> + %% about_brz_logo %% +