# HG changeset patch # User laurent # Date 1248448379 -7200 # Node ID 07447ee3538ee4ca1fefd87847afb961e1fae1bf # Parent 020420ad89148aaa6d174266a0300de8842933d6 Adding support for internationalization diff -r 020420ad8914 -r 07447ee3538e DataTypeEditor.py --- a/DataTypeEditor.py Fri Jul 24 12:49:57 2009 +0200 +++ b/DataTypeEditor.py Fri Jul 24 17:12:59 2009 +0200 @@ -41,6 +41,10 @@ # Structure Elements Table #------------------------------------------------------------------------------- +def GetElementsTableColnames(): + _ = lambda x : x + return ["#", _("Name"), _("Type"), _("Initial Value")] + class ElementsTable(wx.grid.PyGridTableBase): """ @@ -66,23 +70,25 @@ def GetNumberRows(self): return len(self.data) - def GetColLabelValue(self, col): + def GetColLabelValue(self, col, translate=True): if col < len(self.colnames): + if translate: + return _(self.colnames[col]) return self.colnames[col] - def GetRowLabelValues(self, row): + def GetRowLabelValues(self, row, translate=True): return row def GetValue(self, row, col): if row < self.GetNumberRows(): if col == 0: return row + 1 - name = str(self.data[row].get(self.GetColLabelValue(col), "")) + name = str(self.data[row].get(self.GetColLabelValue(col, False), "")) return name def SetValue(self, row, col, value): if col < len(self.colnames): - colname = self.GetColLabelValue(col) + colname = self.GetColLabelValue(col, False) if colname == "Name": self.old_value = self.data[row][colname] self.data[row][colname] = value @@ -140,13 +146,11 @@ Otherwise default to the default renderer. """ - typelist = None - accesslist = None for row in range(self.GetNumberRows()): for col in range(self.GetNumberCols()): editor = None renderer = None - colname = self.GetColLabelValue(col) + colname = self.GetColLabelValue(col, False) if col != 0: grid.SetReadOnly(row, col, False) if colname == "Name": @@ -227,6 +231,11 @@ ID_DATATYPEEDITORSTATICTEXT11, ] = [wx.NewId() for _init_ctrls in range(35)] +def GetDatatypeTypes(): + _ = lambda x : x + return [_("Directly"), _("Subrange"), _("Enumerated"), _("Array"), _("Structure")] +DATATYPE_TYPES_DICT = dict([(_(datatype), datatype) for datatype in GetDatatypeTypes()]) + class DataTypeEditor(wx.Panel): def _init_coll_MainSizer_Items(self, parent): @@ -238,8 +247,8 @@ parent.AddGrowableRow(1) def _init_coll_TopSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=5, flag=wx.GROW|wx.LEFT) - parent.AddWindow(self.DerivationType, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.staticText1, 0, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT) + parent.AddWindow(self.DerivationType, 0, border=5, flag=wx.GROW|wx.RIGHT) def _init_coll_TypeInfosSizer_Items(self, parent): parent.AddWindow(self.DirectlyPanel, 1, border=0, flag=wx.ALL) @@ -249,31 +258,34 @@ parent.AddWindow(self.StructurePanel, 1, border=0, flag=wx.GROW|wx.ALL) def _init_coll_DirectlyPanelSizer_Items(self, parent): - parent.AddWindow(self.staticText2, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText2, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.DirectlyBaseType, 1, border=5, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.staticText3, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText3, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.DirectlyInitialValue, 1, border=5, flag=wx.GROW|wx.ALL) def _init_coll_SubrangePanelSizer_Items(self, parent): - parent.AddWindow(self.staticText4, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText4, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.SubrangeBaseType, 1, border=5, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.staticText5, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText5, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.SubrangeInitialValue, 1, border=5, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.staticText6, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText6, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.SubrangeMinimum, 1, border=5, flag=wx.GROW|wx.ALL) parent.AddWindow(wx.Size(0, 0), 1, border=5, flag=wx.GROW|wx.ALL) parent.AddWindow(wx.Size(0, 0), 1, border=5, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.staticText7, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText7, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.SubrangeMaximum, 1, border=5, flag=wx.GROW|wx.ALL) def _init_coll_EnumeratedPanelSizer_Items(self, parent): - parent.AddWindow(self.EnumeratedValues, 2, border=5, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.staticText8, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.EnumeratedValues, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddSizer(self.EnumeratedPanelRightSizer, 1, border=0, flag=0) + + def _init_coll_EnumeratedPanelRightSizer_Items(self, parent): + parent.AddWindow(self.staticText8, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.EnumeratedInitialValue, 1, border=5, flag=wx.ALL) def _init_coll_ArrayPanelSizer_Items(self, parent): parent.AddSizer(self.ArrayPanelLeftSizer, 0, border=0, flag=wx.GROW) - parent.AddSizer(self.ArrayPanelRightSizer, 0, border=0, flag=wx.GROW) + parent.AddSizer(self.ArrayPanelRightSizer, 0, border=0, flag=0) parent.AddWindow(self.ArrayDimensions, 0, border=5, flag=wx.GROW|wx.ALL) def _init_coll_ArrayPanelSizer_Growables(self, parent): @@ -282,15 +294,15 @@ parent.AddGrowableRow(1) def _init_coll_ArrayPanelLeftSizer_Items(self, parent): - parent.AddWindow(self.staticText9, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText9, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.ArrayBaseType, 1, border=5, flag=wx.GROW|wx.ALL) def _init_coll_ArrayPanelRightSizer_Items(self, parent): - parent.AddWindow(self.staticText10, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText10, 1, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.ArrayInitialValue, 1, border=5, flag=wx.GROW|wx.ALL) def _init_coll_StructurePanelSizer_Items(self, parent): - parent.AddWindow(self.staticText11, 0, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.staticText11, 0, border=5, flag=wx.ALL) parent.AddWindow(self.StructureElementsGrid, 0, border=0, flag=wx.GROW) parent.AddSizer(self.StructurePanelButtonSizer, 0, border=0, flag=wx.ALIGN_RIGHT) @@ -299,22 +311,23 @@ parent.AddGrowableRow(1) def _init_coll_StructurePanelButtonSizer_Items(self, parent): - parent.AddWindow(self.StructureAddButton, 1, border=5, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.StructureDeleteButton, 1, border=5, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.StructureUpButton, 1, border=5, flag=wx.GROW|wx.ALL) - parent.AddWindow(self.StructureDownButton, 1, border=5, flag=wx.GROW|wx.ALL) + parent.AddWindow(self.StructureAddButton, 0, border=5, flag=wx.ALL) + parent.AddWindow(self.StructureDeleteButton, 0, border=5, flag=wx.ALL) + parent.AddWindow(self.StructureUpButton, 0, border=5, flag=wx.ALL) + parent.AddWindow(self.StructureDownButton, 0, border=5, flag=wx.ALL) def _init_sizers(self): self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) self.TopSizer = wx.BoxSizer(wx.HORIZONTAL) self.TypeInfosSizer = wx.StaticBoxSizer(self.staticbox, wx.HORIZONTAL) self.DirectlyPanelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.SubrangePanelSizer = wx.GridSizer(cols=4, hgap=0, rows=3, vgap=0) + self.SubrangePanelSizer = wx.GridSizer(cols=4, hgap=5, rows=3, vgap=0) self.EnumeratedPanelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ArrayPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=0) + self.EnumeratedPanelRightSizer = wx.BoxSizer(wx.HORIZONTAL) + self.ArrayPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=0) self.ArrayPanelLeftSizer = wx.BoxSizer(wx.HORIZONTAL) self.ArrayPanelRightSizer = wx.BoxSizer(wx.HORIZONTAL) - self.StructurePanelSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=0) + self.StructurePanelSizer = wx.FlexGridSizer(cols=1, hgap=5, rows=3, vgap=0) self.StructurePanelButtonSizer = wx.BoxSizer(wx.HORIZONTAL) self._init_coll_MainSizer_Items(self.MainSizer) self._init_coll_MainSizer_Growables(self.MainSizer) @@ -323,6 +336,7 @@ self._init_coll_DirectlyPanelSizer_Items(self.DirectlyPanelSizer) self._init_coll_SubrangePanelSizer_Items(self.SubrangePanelSizer) self._init_coll_EnumeratedPanelSizer_Items(self.EnumeratedPanelSizer) + self._init_coll_EnumeratedPanelRightSizer_Items(self.EnumeratedPanelRightSizer) self._init_coll_ArrayPanelSizer_Items(self.ArrayPanelSizer) self._init_coll_ArrayPanelSizer_Growables(self.ArrayPanelSizer) self._init_coll_ArrayPanelLeftSizer_Items(self.ArrayPanelLeftSizer) @@ -343,12 +357,12 @@ size=wx.Size(0, 0), style=wx.SUNKEN_BORDER) self.staticbox = wx.StaticBox(id=ID_DATATYPEEDITORSTATICBOX, - label='Type infos:', name='staticBox1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(10, 0), style=0) + label=_('Type infos:'), name='staticBox1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.staticText1 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT1, - label='Derivation Type:', name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Derivation Type:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.DerivationType = wx.ComboBox(id=ID_DATATYPEEDITORDERIVATIONTYPE, name='DerivationType', parent=self, pos=wx.Point(0, 0), @@ -362,8 +376,8 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText2 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT2, - label='Base Type:', name='staticText2', parent=self.DirectlyPanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Base Type:'), name='staticText2', parent=self.DirectlyPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.DirectlyBaseType = wx.ComboBox(id=ID_DATATYPEEDITORDIRECTLYBASETYPE, name='DirectlyBaseType', parent=self.DirectlyPanel, pos=wx.Point(0, 0), @@ -371,8 +385,8 @@ self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, id=ID_DATATYPEEDITORDIRECTLYBASETYPE) self.staticText3 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT3, - label='Initial Value:', name='staticText3', parent=self.DirectlyPanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Initial Value:'), name='staticText3', parent=self.DirectlyPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.DirectlyInitialValue = wx.TextCtrl(id=ID_DATATYPEEDITORDIRECTLYINITIALVALUE, name='DirectlyInitialValue', parent=self.DirectlyPanel, pos=wx.Point(0, 0), @@ -386,8 +400,8 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText4 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT4, - label='Base Type:', name='staticText4', parent=self.SubrangePanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Base Type:'), name='staticText4', parent=self.SubrangePanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.SubrangeBaseType = wx.ComboBox(id=ID_DATATYPEEDITORSUBRANGEBASETYPE, name='SubrangeBaseType', parent=self.SubrangePanel, pos=wx.Point(0, 0), @@ -395,8 +409,8 @@ self.Bind(wx.EVT_COMBOBOX, self.OnSubrangeBaseTypeChanged, id=ID_DATATYPEEDITORSUBRANGEBASETYPE) self.staticText5 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT5, - label='Initial Value:', name='staticText5', parent=self.SubrangePanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Initial Value:'), name='staticText5', parent=self.SubrangePanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.SubrangeInitialValue = wx.SpinCtrl(id=ID_DATATYPEEDITORSUBRANGEINITIALVALUE, name='SubrangeInitialValue', parent=self.SubrangePanel, pos=wx.Point(0, 0), @@ -404,8 +418,8 @@ self.Bind(wx.EVT_SPINCTRL, self.OnInfosChanged, id=ID_DATATYPEEDITORSUBRANGEINITIALVALUE) self.staticText6 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT6, - label='Minimum:', name='staticText6', parent=self.SubrangePanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Minimum:'), name='staticText6', parent=self.SubrangePanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.SubrangeMinimum = wx.SpinCtrl(id=ID_DATATYPEEDITORSUBRANGEMINIMUM, name='SubrangeMinimum', parent=self.SubrangePanel, pos=wx.Point(0, 0), @@ -413,8 +427,8 @@ self.Bind(wx.EVT_SPINCTRL, self.OnSubrangeMinimumChanged, id=ID_DATATYPEEDITORSUBRANGEMINIMUM) self.staticText7 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT7, - label='Maximum:', name='staticText7', parent=self.SubrangePanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Maximum:'), name='staticText7', parent=self.SubrangePanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.SubrangeMaximum = wx.SpinCtrl(id=ID_DATATYPEEDITORSUBRANGEMAXIMUM, name='SubrangeMaximum', parent=self.SubrangePanel, pos=wx.Point(0, 0), @@ -428,17 +442,26 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.EnumeratedValues = wx.gizmos.EditableListBox(id=ID_DATATYPEEDITORENUMERATEDVALUES, - name='EnumeratedValues', parent=self.EnumeratedPanel, label="Values:", pos=wx.Point(0, 0), + name='EnumeratedValues', parent=self.EnumeratedPanel, label=_("Values:"), pos=wx.Point(0, 0), size=wx.Size(0, 0), style=wx.gizmos.EL_ALLOW_NEW | wx.gizmos.EL_ALLOW_EDIT | wx.gizmos.EL_ALLOW_DELETE) self.EnumeratedValues.GetListCtrl().Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEnumeratedValueEndEdit) - self.EnumeratedValues.GetNewButton().Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged) - self.EnumeratedValues.GetDelButton().Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged) - self.EnumeratedValues.GetUpButton().Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged) - self.EnumeratedValues.GetDownButton().Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged) + self.EnumeratedValues.GetEditButton().SetToolTipString(_("Edit item")) + new_button = self.EnumeratedValues.GetNewButton() + new_button.SetToolTipString(_("New item")) + new_button.Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged) + del_button = self.EnumeratedValues.GetDelButton() + del_button.SetToolTipString(_("Delete item")) + del_button.Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged) + up_button = self.EnumeratedValues.GetUpButton() + up_button.SetToolTipString(_("Move up")) + up_button.Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged) + down_button = self.EnumeratedValues.GetDownButton() + down_button.SetToolTipString(_("Move down")) + down_button.Bind(wx.EVT_BUTTON, self.OnEnumeratedValuesChanged) self.staticText8 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT8, - label='Initial Value:', name='staticText8', parent=self.EnumeratedPanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Initial Value:'), name='staticText8', parent=self.EnumeratedPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.EnumeratedInitialValue = wx.ComboBox(id=ID_DATATYPEEDITORENUMERATEDINITIALVALUE, name='EnumeratedInitialValue', parent=self.EnumeratedPanel, pos=wx.Point(0, 0), @@ -452,8 +475,8 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText9 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT9, - label='Base Type:', name='staticText9', parent=self.ArrayPanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Base Type:'), name='staticText9', parent=self.ArrayPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ArrayBaseType = wx.ComboBox(id=ID_DATATYPEEDITORARRAYBASETYPE, name='SubrangeBaseType', parent=self.ArrayPanel, pos=wx.Point(0, 0), @@ -461,17 +484,26 @@ self.Bind(wx.EVT_COMBOBOX, self.OnInfosChanged, id=ID_DATATYPEEDITORARRAYBASETYPE) self.ArrayDimensions = wx.gizmos.EditableListBox(id=ID_DATATYPEEDITORARRAYDIMENSIONS, - name='ArrayDimensions', parent=self.ArrayPanel, label="Dimensions:", pos=wx.Point(0, 0), + name='ArrayDimensions', parent=self.ArrayPanel, label=_("Dimensions:"), pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.gizmos.EL_ALLOW_NEW | wx.gizmos.EL_ALLOW_EDIT | wx.gizmos.EL_ALLOW_DELETE) self.ArrayDimensions.GetListCtrl().Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnDimensionsChanged) - self.ArrayDimensions.GetNewButton().Bind(wx.EVT_BUTTON, self.OnDimensionsChanged) - self.ArrayDimensions.GetDelButton().Bind(wx.EVT_BUTTON, self.OnDimensionsChanged) - self.ArrayDimensions.GetUpButton().Bind(wx.EVT_BUTTON, self.OnDimensionsChanged) - self.ArrayDimensions.GetDownButton().Bind(wx.EVT_BUTTON, self.OnDimensionsChanged) + self.ArrayDimensions.GetEditButton().SetToolTipString(_("Edit item")) + new_button = self.ArrayDimensions.GetNewButton() + new_button.SetToolTipString(_("New item")) + new_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged) + del_button = self.ArrayDimensions.GetDelButton() + del_button.SetToolTipString(_("Delete item")) + del_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged) + up_button = self.ArrayDimensions.GetUpButton() + up_button.SetToolTipString(_("Move up")) + up_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged) + down_button = self.ArrayDimensions.GetDownButton() + down_button.SetToolTipString(_("Move down")) + down_button.Bind(wx.EVT_BUTTON, self.OnDimensionsChanged) self.staticText10 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT10, - label='Initial Value:', name='staticText10', parent=self.ArrayPanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Initial Value:'), name='staticText10', parent=self.ArrayPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ArrayInitialValue = wx.TextCtrl(id=ID_DATATYPEEDITORARRAYINITIALVALUE, name='ArrayInitialValue', parent=self.ArrayPanel, pos=wx.Point(0, 0), @@ -485,8 +517,8 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText11 = wx.StaticText(id=ID_DATATYPEEDITORSTATICTEXT11, - label='Elements :', name='staticText11', parent=self.StructurePanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Elements :'), name='staticText11', parent=self.StructurePanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.StructureElementsGrid = wx.grid.Grid(id=ID_DATATYPEEDITORSTRUCTUREELEMENTSGRID, name='StructureElementsGrid', parent=self.StructurePanel, pos=wx.Point(0, 0), @@ -504,14 +536,14 @@ wx.grid.EVT_GRID_CELL_CHANGE(self.StructureElementsGrid, self.OnStructureElementsGridCellChange) wx.grid.EVT_GRID_EDITOR_SHOWN(self.StructureElementsGrid, self.OnStructureElementsGridEditorShown) - self.StructureAddButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREADDBUTTON, label='Add', + self.StructureAddButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREADDBUTTON, label=_('Add'), name='StructureAddButton', parent=self.StructurePanel, pos=wx.Point(0, 0), - size=wx.Size(72, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnStructureAddButton, id=ID_DATATYPEEDITORSTRUCTUREADDBUTTON) - self.StructureDeleteButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREDELETEBUTTON, label='Delete', + self.StructureDeleteButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREDELETEBUTTON, label=_('Delete'), name='StructureDeleteButton', parent=self.StructurePanel, pos=wx.Point(0, 0), - size=wx.Size(72, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnStructureDeleteButton, id=ID_DATATYPEEDITORSTRUCTUREDELETEBUTTON) self.StructureUpButton = wx.Button(id=ID_DATATYPEEDITORSTRUCTUREUPBUTTON, label='^', @@ -530,7 +562,7 @@ self._init_ctrls(parent) self.StructureElementDefaultValue = {"Name" : "", "Type" : "INT", "Initial Value" : ""} - self.StructureElementsTable = ElementsTable(self, [], ["#", "Name", "Type", "Initial Value"]) + self.StructureElementsTable = ElementsTable(self, [], GetElementsTableColnames()) self.StructureColSizes = [40, 150, 100, 250] self.StructureColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT] @@ -540,13 +572,11 @@ attr = wx.grid.GridCellAttr() attr.SetAlignment(self.StructureColAlignements[col], wx.ALIGN_CENTRE) self.StructureElementsGrid.SetColAttr(col, attr) - self.StructureElementsGrid.SetColSize(col, self.StructureColSizes[col]) - - self.DerivationType.Append("Directly") - self.DerivationType.Append("Subrange") - self.DerivationType.Append("Enumerated") - self.DerivationType.Append("Array") - self.DerivationType.Append("Structure") + self.StructureElementsGrid.SetColMinimalWidth(col, self.StructureColSizes[col]) + self.StructureElementsGrid.AutoSizeColumn(col, False) + + for datatype in GetDatatypeTypes(): + self.DerivationType.Append(_(datatype)) self.SubrangePanel.Hide() self.EnumeratedPanel.Hide() self.ArrayPanel.Hide() @@ -590,7 +620,8 @@ self.RefreshBoundsRange() type_infos = self.Controler.GetDataTypeInfos(self.TagName) if type_infos is not None: - self.DerivationType.SetStringSelection(type_infos["type"]) + datatype = type_infos["type"] + self.DerivationType.SetStringSelection(_(datatype)) if type_infos["type"] == "Directly": self.DirectlyBaseType.SetStringSelection(type_infos["base_type"]) self.DirectlyInitialValue.SetValue(type_infos["initial"]) @@ -663,12 +694,12 @@ index = event.GetIndex() if index >= len(values) or values[index].upper() != text.upper(): if text.upper() in [value.upper() for value in values]: - message = wx.MessageDialog(self, "\"%s\" value already defined!"%text, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" value already defined!")%text, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Veto() elif text.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%text, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%text, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -723,12 +754,12 @@ value = self.StructureElementsTable.GetValue(row, col) if colname == "Name": if not TestIdentifier(value): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%value, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%value, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Veto() elif value.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%value, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%value, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Veto() @@ -738,7 +769,7 @@ ## message.Destroy() ## event.Veto() elif value.upper() in [var["Name"].upper() for idx, var in enumerate(self.StructureElementsTable.GetData()) if idx != row]: - message = wx.MessageDialog(self, "A element with \"%s\" as name exists in this structure!"%value, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A element with \"%s\" as name exists in this structure!")%value, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Veto() @@ -764,13 +795,13 @@ new_id = wx.NewId() AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type) self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(base_type), id=new_id) - type_menu.AppendMenu(wx.NewId(), "Base Types", base_menu) + type_menu.AppendMenu(wx.NewId(), _("Base Types"), base_menu) datatype_menu = wx.Menu(title='') for datatype in self.Controler.GetDataTypes(self.TagName, False, self.ParentWindow.Debug): new_id = wx.NewId() AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) self.Bind(wx.EVT_MENU, self.GetElementTypeFunction(datatype), id=new_id) - type_menu.AppendMenu(wx.NewId(), "User Data Types", datatype_menu) + type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu) ## functionblock_menu = wx.Menu(title='') ## bodytype = self.Controler.GetEditedElementBodyType(self.TagName, self.ParentWindow.Debug) ## pouname, poutype = self.Controler.GetEditedElementType(self.TagName, self.ParentWindow.Debug) @@ -779,7 +810,7 @@ ## new_id = wx.NewId() ## AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type) ## self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id) -## type_menu.AppendMenu(wx.NewId(), "Function Block Types", functionblock_menu) +## type_menu.AppendMenu(wx.NewId(), _("Function Block Types"), functionblock_menu) rect = self.StructureElementsGrid.BlockToDeviceRect((row, col), (row, col)) self.StructureElementsGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.StructureElementsGrid.GetColLabelSize()) event.Veto() @@ -796,7 +827,7 @@ return ElementTypeFunction def RefreshDisplayedInfos(self): - selected = self.DerivationType.GetStringSelection() + selected = DATATYPE_TYPES_DICT[self.DerivationType.GetStringSelection()] if selected != self.CurrentPanel: if self.CurrentPanel == "Directly": self.DirectlyPanel.Hide() @@ -842,7 +873,7 @@ self.SubrangeInitialValue.SetRange(self.SubrangeMinimum.GetValue(), self.SubrangeMaximum.GetValue()) def RefreshTypeInfos(self): - selected = self.DerivationType.GetStringSelection() + selected = DATATYPE_TYPES_DICT[self.DerivationType.GetStringSelection()] infos = {"type" : selected} if selected == "Directly": infos["base_type"] = self.DirectlyBaseType.GetStringSelection() @@ -865,14 +896,14 @@ for dimensions in self.ArrayDimensions.GetStrings(): result = DIMENSION_MODEL.match(dimensions) if result is None: - message = wx.MessageDialog(self, "\"%s\" value isn't a valid array dimension!"%dimensions, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" value isn't a valid array dimension!")%dimensions, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() self.RefreshView() return bounds = result.groups() if bounds[0] >= bounds[1]: - message = wx.MessageDialog(self, "\"%s\" value isn't a valid array dimension!\nRight value must be greater than left value."%dimensions, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" value isn't a valid array dimension!\nRight value must be greater than left value.")%dimensions, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() self.RefreshView() diff -r 020420ad8914 -r 07447ee3538e Dialogs.py --- a/Dialogs.py Fri Jul 24 12:49:57 2009 +0200 +++ b/Dialogs.py Fri Jul 24 17:12:59 2009 +0200 @@ -77,21 +77,24 @@ parent.AddGrowableRow(2) def _init_coll_RightUpGridSizer_Items(self, parent): - parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.BlockName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText3, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText3, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.Inputs, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText4, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText4, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText5, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText5, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.ExecutionControl, 0, border=0, flag=wx.GROW) - + + def _init_coll_RightUpGridSizer_Growables(self, parent): + parent.AddGrowableCol(1) + def _init_sizers(self): self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) self.MainSizer = wx.BoxSizer(wx.HORIZONTAL) self.LeftBoxSizer = wx.StaticBoxSizer(self.staticbox1, wx.VERTICAL) self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5) - self.RightUpGridSizer = wx.GridSizer(cols=2, hgap=5, rows=4, vgap=5) + self.RightUpGridSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=5) self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) @@ -100,6 +103,7 @@ self._init_coll_RightGridSizer_Items(self.RightGridSizer) self._init_coll_RightGridSizer_Growables(self.RightGridSizer) self._init_coll_RightUpGridSizer_Items(self.RightUpGridSizer) + self._init_coll_RightUpGridSizer_Growables(self.RightUpGridSizer) self.SetSizer(self.flexGridSizer1) @@ -107,32 +111,32 @@ wx.Dialog.__init__(self, id=ID_BLOCKPROPERTIESDIALOG, name='BlockPropertiesDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, - title='Block Properties') + title=_('Block Properties')) self.SetClientSize(wx.Size(600, 400)) self.staticbox1 = wx.StaticBox(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, - label='Type:', name='staticBox1', parent=self, + label=_('Type:'), name='staticBox1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) self.staticText2 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, - label='Name:', name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + label=_('Name:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.staticText3 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, - label='Inputs:', name='staticText4', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + label=_('Inputs:'), name='staticText4', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.staticText4 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT4, - label='Execution Order:', name='staticText4', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + label=_('Execution Order:'), name='staticText4', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.staticText5 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT5, - label='Execution Control:', name='staticText5', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + label=_('Execution Control:'), name='staticText5', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.staticText6 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT6, - label='Preview:', name='staticText6', parent=self, - pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) + label=_('Preview:'), name='staticText6', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) if wx.Platform == '__WXMSW__': treestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER @@ -234,27 +238,27 @@ block_name = self.BlockName.GetValue() name_enabled = self.BlockName.IsEnabled() if not selected.IsOk() or self.TypeTree.GetItemParent(selected) == self.TypeTree.GetRootItem() or selected == self.TypeTree.GetRootItem(): - message = wx.MessageDialog(self, "Form isn't complete. Valid block type must be selected!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("Form isn't complete. Valid block type must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif name_enabled and block_name == "": - message = wx.MessageDialog(self, "Form isn't complete. Name must be filled!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif name_enabled and not TestIdentifier(block_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%block_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif name_enabled and block_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%block_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif name_enabled and block_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "\"%s\" pou already exists!"%block_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif name_enabled and block_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, "\"%s\" element for this pou already exists!"%block_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%block_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -262,12 +266,13 @@ def SetBlockList(self, blocktypes): if wx.Platform == '__WXMSW__': - root = self.TypeTree.AddRoot("Block Types") + root = self.TypeTree.AddRoot(_("Block Types")) else: root = self.TypeTree.AddRoot("") self.TypeTree.SetPyData(root, {"type" : CATEGORY}) for category in blocktypes: - category_item = self.TypeTree.AppendItem(root, category["name"]) + category_name = category["name"] + category_item = self.TypeTree.AppendItem(root, _(category_name)) self.TypeTree.SetPyData(category_item, {"type" : CATEGORY}) for blocktype in category["list"]: blocktype_item = self.TypeTree.AppendItem(category_item, blocktype["name"]) @@ -330,7 +335,8 @@ self.Inputs.SetValue(len(blocktype["inputs"])) self.Inputs.Enable(blocktype["extensible"]) self.BlockName.Enable(blocktype["type"] != "function") - self.TypeDesc.SetValue(blocktype["comment"]) + comment = blocktype["comment"] + self.TypeDesc.SetValue(_(comment) + blocktype.get("usage", "")) wx.CallAfter(self.RefreshPreview) else: self.BlockName.Enable(False) @@ -416,6 +422,11 @@ ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT5 ] = [wx.NewId() for _init_ctrls in range(12)] +VARIABLE_CLASSES_DICT = {INPUT : _("Input"), + INOUT : _("InOut"), + OUTPUT : _("Output")} +VARIABLE_CLASSES_DICT_REVERSE = dict([(value, key) for key, value in VARIABLE_CLASSES_DICT.iteritems()]) + class VariablePropertiesDialog(wx.Dialog): if wx.VERSION < (2, 6, 0): @@ -490,27 +501,27 @@ wx.Dialog.__init__(self, id=ID_VARIABLEPROPERTIESDIALOG, name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(400, 380), style=wx.DEFAULT_DIALOG_STYLE, - title='Variable Properties') + title=_('Variable Properties')) self.SetClientSize(wx.Size(400, 380)) self.staticText1 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, - label='Class:', name='staticText1', parent=self, + label=_('Class:'), name='staticText1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText2 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, - label='Expression:', name='staticText2', parent=self, + label=_('Expression:'), name='staticText2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText3 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, - label='Execution Order:', name='staticText3', parent=self, + label=_('Execution Order:'), name='staticText3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText4 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4, - label='Name:', name='staticText4', parent=self, + label=_('Name:'), name='staticText4', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText5 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT5, - label='Preview:', name='staticText5', parent=self, + label=_('Preview:'), name='staticText5', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.Class = wx.ComboBox(id=ID_VARIABLEPROPERTIESDIALOGCLASS, @@ -561,28 +572,30 @@ self.Variable = None self.VarList = [] self.MinVariableSize = None + + for choice in VARIABLE_CLASSES_DICT.itervalues(): + self.Class.Append(choice) + self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[INPUT]) + self.RefreshNameList() - - for choice in ["Input", "Output", "InOut"]: - self.Class.Append(choice) - self.Class.SetStringSelection("Input") def SetPreviewFont(self, font): self.Preview.SetFont(font) def RefreshNameList(self): selected = self.VariableName.GetStringSelection() + var_class = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] self.VariableName.Clear() self.VariableName.Append("") for name, var_type, value_type in self.VarList: - if var_type != "Input" or self.Class.GetStringSelection() == "Input": + if var_type != "Input" or var_class == INPUT: self.VariableName.Append(name) if selected != "" and self.VariableName.FindString(selected) != wx.NOT_FOUND: self.VariableName.SetStringSelection(selected) self.Expression.Enable(False) else: self.VariableName.SetStringSelection("") - self.Expression.Enable(self.Class.GetStringSelection() == "Input") + self.Expression.Enable(var_class == INPUT) self.VariableName.Enable(self.VariableName.GetCount() > 0) def SetMinVariableSize(self, size): @@ -596,12 +609,7 @@ value_type = values.get("type", None) value_name = values.get("name", None) if value_type: - if value_type == INPUT: - self.Class.SetStringSelection("Input") - if value_type == OUTPUT: - self.Class.SetStringSelection("Output") - if value_type == INOUT: - self.Class.SetStringSelection("InOut") + self.Class.SetStringSelection(VARIABLE_CLASSES_DICT[value_type]) self.RefreshNameList() if value_name: if self.VariableName.FindString(value_name) != wx.NOT_FOUND: @@ -616,13 +624,7 @@ def GetValues(self): values = {} - classtype = self.Class.GetStringSelection() - if classtype == "Input": - values["type"] = INPUT - elif classtype == "Output": - values["type"] = OUTPUT - elif classtype == "InOut": - values["type"] = INOUT + values["type"] = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] expression = self.Expression.GetValue() if self.Expression.IsEnabled() and expression != "": values["name"] = expression @@ -643,11 +645,11 @@ else: value = self.VariableName.GetStringSelection() if value == "": - message = wx.MessageDialog(self, "At least a variable or an expression must be selected!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("At least a variable or an expression must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif value.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%value, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%value, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -661,7 +663,7 @@ def OnNameChanged(self, event): if self.VariableName.GetStringSelection() != "": self.Expression.Enable(False) - elif self.Class.GetStringSelection() == "Input": + elif VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] == INPUT: self.Expression.Enable(True) self.RefreshPreview() event.Skip() @@ -691,13 +693,8 @@ for var_name, var_type, value_type in self.VarList: if var_name == name: type = value_type - classtype = self.Class.GetStringSelection() - if classtype == "Input": - self.Variable = FBD_Variable(self.Preview, INPUT, name, type, executionOrder = self.ExecutionOrder.GetValue()) - elif classtype == "Output": - self.Variable = FBD_Variable(self.Preview, OUTPUT, name, type, executionOrder = self.ExecutionOrder.GetValue()) - elif classtype == "InOut": - self.Variable = FBD_Variable(self.Preview, INOUT, name, type, executionOrder = self.ExecutionOrder.GetValue()) + classtype = VARIABLE_CLASSES_DICT_REVERSE[self.Class.GetStringSelection()] + self.Variable = FBD_Variable(self.Preview, classtype, name, type, executionOrder = self.ExecutionOrder.GetValue()) width, height = self.MinVariableSize min_width, min_height = self.Variable.GetMinSize() width, height = max(min_width, width), max(min_height, height) @@ -784,29 +781,29 @@ wx.Dialog.__init__(self, id=ID_CONNECTIONPROPERTIESDIALOG, name='ConnectionPropertiesDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(350, 220), style=wx.DEFAULT_DIALOG_STYLE, - title='Connection Properties') + title=_('Connection Properties')) self.SetClientSize(wx.Size(350, 220)) self.staticText1 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1, - label='Type:', name='staticText1', parent=self, + label=_('Type:'), name='staticText1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText2 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2, - label='Name:', name='staticText2', parent=self, + label=_('Name:'), name='staticText2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText3 = wx.StaticText(id=ID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3, - label='Preview:', name='staticText3', parent=self, + label=_('Preview:'), name='staticText3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.radioButton1 = wx.RadioButton(id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, - label='Connector', name='radioButton1', parent=self, + label=_('Connector'), name='radioButton1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1) self.radioButton1.SetValue(True) self.radioButton2 = wx.RadioButton(id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, - label='Continuation', name='radioButton2', parent=self, + label=_('Continuation'), name='radioButton2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2) self.radioButton2.SetValue(False) @@ -882,23 +879,23 @@ def OnOK(self, event): connection_name = self.ConnectionName.GetValue() if connection_name == "": - message = wx.MessageDialog(self, "Form isn't complete. Name must be filled!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(connection_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%connection_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif connection_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%connection_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif connection_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "\"%s\" pou already exists!"%connection_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif connection_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, "\"%s\" element for this pou already exists!"%connection_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%connection_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -1022,45 +1019,45 @@ self.SetClientSize(wx.Size(350, 260 + extra_size)) self.staticText1 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT1, - label='Modifier:', name='staticText1', parent=self, + label=_('Modifier:'), name='staticText1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText2 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT2, - label='Name:', name='staticText2', parent=self, + label=_('Name:'), name='staticText2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText3 = wx.StaticText(id=ID_LDELEMENTDIALOGSTATICTEXT3, - label='Preview:', name='staticText3', parent=self, + label=_('Preview:'), name='staticText3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.radioButton1 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON1, - label="Normal", name='radioButton1', parent=self, + label=_("Normal"), name='radioButton1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON1) self.radioButton1.SetValue(True) self.radioButton2 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON2, - label="Negated", name='radioButton2', parent=self, + label=_("Negated"), name='radioButton2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON2) self.radioButton3 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON3, - label="Set", name='radioButton3', parent=self, + label=_("Set"), name='radioButton3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON3) self.radioButton4 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON4, - label="Reset", name='radioButton4', parent=self, + label=_("Reset"), name='radioButton4', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON4) self.radioButton5 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON5, - label="Rising Edge", name='radioButton5', parent=self, + label=_("Rising Edge"), name='radioButton5', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON5) self.radioButton6 = wx.RadioButton(id=ID_LDELEMENTDIALOGRADIOBUTTON6, - label="Falling Edge", name='radioButton6', parent=self, + label=_("Falling Edge"), name='radioButton6', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDELEMENTDIALOGRADIOBUTTON6) @@ -1093,12 +1090,12 @@ def __init__(self, parent, controler, type): self.Type = type if type == "contact": - self._init_ctrls(parent, controler, "Edit Contact Values") + self._init_ctrls(parent, controler, _("Edit Contact Values")) self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "") self.radioButton3.Hide() self.radioButton4.Hide() elif type == "coil": - self._init_ctrls(parent, controler, "Edit Coil Values", 50) + self._init_ctrls(parent, controler, _("Edit Coil Values"), 50) self.Element = LD_Coil(self.Preview, COIL_NORMAL, "") @@ -1271,29 +1268,29 @@ wx.Dialog.__init__(self, id=ID_LDPOWERRAILDIALOG, name='PowerRailDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE, - title='Power Rail Properties') + title=_('Power Rail Properties')) self.SetClientSize(wx.Size(350, 260)) self.staticText1 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT1, - label='Type:', name='staticText1', parent=self, + label=_('Type:'), name='staticText1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText2 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT2, - label='Pin number:', name='staticText2', parent=self, + label=_('Pin number:'), name='staticText2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText3 = wx.StaticText(id=ID_LDPOWERRAILDIALOGSTATICTEXT3, - label='Preview:', name='staticText3', parent=self, + label=_('Preview:'), name='staticText3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.radioButton1 = wx.RadioButton(id=ID_LDPOWERRAILDIALOGRADIOBUTTON1, - label='Left PowerRail', name='radioButton1', parent=self, + label=_('Left PowerRail'), name='radioButton1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDPOWERRAILDIALOGRADIOBUTTON1) self.radioButton1.SetValue(True) self.radioButton2 = wx.RadioButton(id=ID_LDPOWERRAILDIALOGRADIOBUTTON2, - label='Right PowerRail', name='radioButton2', parent=self, + label=_('Right PowerRail'), name='radioButton2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_LDPOWERRAILDIALOGRADIOBUTTON2) @@ -1451,19 +1448,19 @@ wx.Dialog.__init__(self, id=ID_STEPCONTENTDIALOG, name='StepContentDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(400, 250), style=wx.DEFAULT_DIALOG_STYLE, - title='Edit Step') + title=_('Edit Step')) self.SetClientSize(wx.Size(400, 250)) self.staticText1 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT1, - label='Name:', name='staticText1', parent=self, + label=_('Name:'), name='staticText1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText2 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT2, - label='Connectors:', name='staticText2', parent=self, + label=_('Connectors:'), name='staticText2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText3 = wx.StaticText(id=ID_STEPCONTENTDIALOGSTATICTEXT3, - label='Preview:', name='staticText4', parent=self, + label=_('Preview:'), name='staticText4', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.StepName = wx.TextCtrl(id=ID_STEPCONTENTDIALOGNAME, @@ -1472,17 +1469,17 @@ self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_STEPCONTENTDIALOGNAME) self.checkBox1 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX1, - label="Input", name='checkBox1', parent=self, + label=_("Input"), name='checkBox1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX1) self.checkBox2 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX2, - label="Output", name='checkBox2', parent=self, + label=_("Output"), name='checkBox2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX2) self.checkBox3 = wx.CheckBox(id=ID_STEPCONTENTDIALOGCHECKBOX3, - label="Action", name='checkBox3', parent=self, + label=_("Action"), name='checkBox3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_CHECKBOX, self.OnConnectorsChanged, id=ID_STEPCONTENTDIALOGCHECKBOX3) @@ -1525,27 +1522,27 @@ def OnOK(self, event): step_name = self.StepName.GetValue() if step_name == "": - message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(step_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in self.Variables: - message = wx.MessageDialog(self, "A variable with \"%s\" as name exists!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in self.StepNames: - message = wx.MessageDialog(self, "\"%s\" step already exists!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" step already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -1698,23 +1695,23 @@ wx.Dialog.__init__(self, id=ID_TRANSITIONCONTENTDIALOG, name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(350, 300), style=wx.DEFAULT_DIALOG_STYLE, - title='Edit transition') + title=_('Edit transition')) self.SetClientSize(wx.Size(350, 300)) self.staticText1 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT1, - label='Type:', name='staticText1', parent=self, + label=_('Type:'), name='staticText1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText2 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT2, - label='Preview:', name='staticText2', parent=self, + label=_('Preview:'), name='staticText2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.staticText3 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT3, - label='Priority:', name='staticText3', parent=self, + label=_('Priority:'), name='staticText3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.radioButton1 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1, - label='Reference', name='radioButton1', parent=self, + label=_('Reference'), name='radioButton1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1) self.radioButton1.SetValue(True) @@ -1725,7 +1722,7 @@ self.Bind(wx.EVT_COMBOBOX, self.OnReferenceChanged, id=ID_TRANSITIONCONTENTDIALOGREFERENCE) self.radioButton2 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2, - label='Inline', name='radioButton2', parent=self, + label=_('Inline'), name='radioButton2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2) self.radioButton2.SetValue(False) @@ -1737,7 +1734,7 @@ self.Inline.Enable(False) self.radioButton3 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3, - label='Connection', name='radioButton3', parent=self, + label=_('Connection'), name='radioButton3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3) self.radioButton3.SetValue(False) @@ -1791,19 +1788,19 @@ def OnOK(self, event): error = [] if self.radioButton1.GetValue() and self.Reference.GetStringSelection() == "": - error.append("Reference") + error.append(_("Reference")) if self.radioButton2.GetValue() and self.Inline.GetValue() == "": - error.append("Inline") + error.append(_("Inline")) if len(error) > 0: text = "" for i, item in enumerate(error): if i == 0: text += item elif i == len(error) - 1: - text += " and %s"%item + text += _(" and %s")%item else: - text += ", %s"%item - message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) + text += _(", %s")%item + message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -1976,39 +1973,39 @@ wx.Dialog.__init__(self, id=ID_DIVERGENCECREATEDIALOG, name='DivergencePropertiesDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE, - title='Create a new divergence or convergence') + title=_('Create a new divergence or convergence')) self.SetClientSize(wx.Size(500, 300)) self.staticText1 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT1, - label='Type:', name='staticText1', parent=self, + label=_('Type:'), name='staticText1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.radioButton1 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON1, - label='Selection Divergence', name='radioButton1', parent=self, + label=_('Selection Divergence'), name='radioButton1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.RB_GROUP) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON1) self.radioButton1.SetValue(True) self.radioButton2 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON2, - label='Selection Convergence', name='radioButton2', parent=self, + label=_('Selection Convergence'), name='radioButton2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON2) self.radioButton2.SetValue(False) self.radioButton3 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON3, - label='Simultaneous Divergence', name='radioButton3', parent=self, + label=_('Simultaneous Divergence'), name='radioButton3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON3) self.radioButton3.SetValue(False) self.radioButton4 = wx.RadioButton(id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON4, - label='Simultaneous Convergence', name='radioButton4', parent=self, + label=_('Simultaneous Convergence'), name='radioButton4', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, id=ID_DIVERGENCECREATEDIALOGRADIOBUTTON4) self.radioButton4.SetValue(False) self.staticText2 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT2, - label='Number of sequences:', name='staticText2', parent=self, + label=_('Number of sequences:'), name='staticText2', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.Sequences = wx.SpinCtrl(id=ID_DIVERGENCECREATEDIALOGSEQUENCES, @@ -2017,7 +2014,7 @@ self.Bind(wx.EVT_SPINCTRL, self.OnSequencesChanged, id=ID_DIVERGENCECREATEDIALOGSEQUENCES) self.staticText3 = wx.StaticText(id=ID_DIVERGENCECREATEDIALOGSTATICTEXT3, - label='Preview:', name='staticText3', parent=self, + label=_('Preview:'), name='staticText3', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.Preview = wx.Panel(id=ID_DIVERGENCECREATEDIALOGPREVIEW, @@ -2103,6 +2100,14 @@ # Action Block Dialog #------------------------------------------------------------------------------- +def GetActionTableColnames(): + _ = lambda x: x + return [_("Qualifier"), _("Duration"), _("Type"), _("Value"), _("Indicator")] + +def GetTypeList(): + _ = lambda x: x + return [_("Action"), _("Variable"), _("Inline")] + class ActionTable(wx.grid.PyGridTableBase): """ @@ -2126,16 +2131,22 @@ def GetNumberRows(self): return len(self.data) - def GetColLabelValue(self, col): + def GetColLabelValue(self, col, translate=True): if col < len(self.colnames): - return self.colnames[col] - - def GetRowLabelValues(self, row): + colname = self.colnames[col] + if translate: + return _(colname) + return colname + + def GetRowLabelValues(self, row, translate=True): return row def GetValue(self, row, col): if row < self.GetNumberRows(): - name = str(self.data[row].get(self.GetColLabelValue(col), "")) + colname = self.GetColLabelValue(col, False) + name = str(self.data[row].get(colname, "")) + if colname == "Type": + return _(name) return name def GetValueByName(self, row, colname): @@ -2143,7 +2154,10 @@ def SetValue(self, row, col, value): if col < len(self.colnames): - self.data[row][self.GetColLabelValue(col)] = value + colname = self.GetColLabelValue(col, False) + if colname == "Type": + value = self.Parent.TranslateType[value] + self.data[row][colname] = value def ResetView(self, grid): """ @@ -2187,20 +2201,12 @@ Otherwise default to the default renderer. """ - for col in range(self.GetNumberCols()): - attr = wx.grid.GridCellAttr() - attr.SetAlignment(self.Parent.ColAlignements[col], wx.ALIGN_CENTRE) - grid.SetColAttr(col, attr) - grid.SetColSize(col, self.Parent.ColSizes[col]) - - typelist = None - accesslist = None for row in range(self.GetNumberRows()): for col in range(self.GetNumberCols()): editor = None renderer = None readonly = False - colname = self.GetColLabelValue(col) + colname = self.GetColLabelValue(col, False) if colname == "Qualifier": editor = wx.grid.GridCellChoiceEditor() editor.SetParameters(self.Parent.QualifierList) @@ -2319,11 +2325,11 @@ wx.Dialog.__init__(self, id=ID_ACTIONBLOCKDIALOG, name='ActionBlockDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(500, 300), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, - title='Edit action block properties') + title=_('Edit action block properties')) self.SetClientSize(wx.Size(500, 300)) self.staticText1 = wx.StaticText(id=ID_ACTIONBLOCKDIALOGSTATICTEXT1, - label='Actions:', name='staticText1', parent=self, + label=_('Actions:'), name='staticText1', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0) self.ActionsGrid = wx.grid.Grid(id=ID_ACTIONBLOCKDIALOGVARIABLESGRID, @@ -2337,14 +2343,14 @@ self.ActionsGrid.EnableScrolling(False, True) self.ActionsGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnActionsGridCellChange) - self.AddButton = wx.Button(id=ID_ACTIONBLOCKDIALOGADDBUTTON, label='Add', + self.AddButton = wx.Button(id=ID_ACTIONBLOCKDIALOGADDBUTTON, label=_('Add'), name='AddButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(72, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_ACTIONBLOCKDIALOGADDBUTTON) - self.DeleteButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDELETEBUTTON, label='Delete', + self.DeleteButton = wx.Button(id=ID_ACTIONBLOCKDIALOGDELETEBUTTON, label=_('Delete'), name='DeleteButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(72, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_ACTIONBLOCKDIALOGDELETEBUTTON) self.UpButton = wx.Button(id=ID_ACTIONBLOCKDIALOGUPBUTTON, label='^', @@ -2369,14 +2375,23 @@ self._init_ctrls(parent) self.DefaultValue = {"Qualifier" : "N", "Duration" : "", "Type" : "Action", "Value" : "", "Indicator" : ""} - self.Table = ActionTable(self, [], ["Qualifier","Duration","Type","Value","Indicator"]) - self.TypeList = "Action,Variable,Inline" + self.Table = ActionTable(self, [], GetActionTableColnames()) + typelist = GetTypeList() + self.TypeList = ",".join(map(_,typelist)) + self.TranslateType = dict([(_(value), value) for value in typelist]) self.ColSizes = [60, 90, 80, 110, 80] self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT] self.ActionsGrid.SetTable(self.Table) self.ActionsGrid.SetRowLabelSize(0) + for col in range(self.Table.GetNumberCols()): + attr = wx.grid.GridCellAttr() + attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) + self.ActionsGrid.SetColAttr(col, attr) + self.ActionsGrid.SetColMinimalWidth(col, self.ColSizes[col]) + self.ActionsGrid.AutoSizeColumn(col, False) + self.Table.ResetView(self.ActionsGrid) def OnOK(self, event): @@ -2490,27 +2505,27 @@ def OnOK(self, event): step_name = self.GetSizer().GetItem(1).GetWindow().GetValue() if step_name == "": - message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(step_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in self.Variables: - message = wx.MessageDialog(self, "A variable with \"%s\" as name exists!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in self.StepNames: - message = wx.MessageDialog(self, "\"%s\" step already exists!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" step already exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -2557,19 +2572,19 @@ def OnOK(self, event): step_name = self.GetSizer().GetItem(1).GetWindow().GetValue() if step_name == "": - message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(step_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif step_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%step_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%step_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -2579,4 +2594,4 @@ self.PouNames = [pou_name.upper() for pou_name in pou_names] def GetValue(self): - return self.GetSizer().GetItem(1).GetWindow().GetValue() \ No newline at end of file + return self.GetSizer().GetItem(1).GetWindow().GetValue() diff -r 020420ad8914 -r 07447ee3538e GraphicViewer.py --- a/GraphicViewer.py Fri Jul 24 12:49:57 2009 +0200 +++ b/GraphicViewer.py Fri Jul 24 17:12:59 2009 +0200 @@ -59,9 +59,9 @@ def _init_coll_RangeSizer_Items(self, parent): # generated method, don't edit - parent.AddWindow(self.staticbox1, 0, border=5, flag=wx.ALL) + parent.AddWindow(self.staticbox1, 0, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.CanvasRange, 0, border=5, flag=wx.ALL) - parent.AddWindow(self.staticText2, 0, border=5, flag=wx.ALL) + parent.AddWindow(self.staticText2, 0, border=5, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALL) parent.AddWindow(self.CanvasPosition, 0, border=5, flag=wx.GROW|wx.ALL) parent.AddWindow(self.ResetButton, 0, border=5, flag=wx.ALL) parent.AddWindow(self.CurrentButton, 0, border=5, flag=wx.ALL) @@ -103,8 +103,8 @@ self.Canvas.SetYSpec('border') self.staticbox1 = wx.StaticText(id=ID_GRAPHICVIEWERSTATICTEXT1, - label='Range:', name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(45, 17), style=0) + label=_('Range:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.CanvasRange = wx.ComboBox(id=ID_GRAPHICVIEWERCANVASRANGE, name='CanvasRange', parent=self, pos=wx.Point(0, 0), @@ -114,8 +114,8 @@ self.Bind(wx.EVT_TEXT_ENTER, self.OnRangeChanged, id=ID_GRAPHICVIEWERCANVASRANGE) self.staticText2 = wx.StaticText(id=ID_GRAPHICVIEWERSTATICTEXT2, - label='Position:', name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(60, 17), style=0) + label=_('Position:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.CanvasPosition = wx.ScrollBar(id=ID_GRAPHICVIEWERCANVASPOSITION, name='Position', parent=self, pos=wx.Point(0, 0), @@ -178,7 +178,7 @@ self.VariableGraphic = plot.PolyLine(self.Datas[self.CurrentValue:self.CurrentValue + self.CurrentRange], legend=var_name, colour=colours[0]) - self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], "%s Graphics" % var_name, "Tick", "Values") + self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values")) datas_length = len(self.Datas) if datas_length > 1: start = self.Datas[self.CurrentValue][0] diff -r 020420ad8914 -r 07447ee3538e LDViewer.py --- a/LDViewer.py Fri Jul 24 12:49:57 2009 +0200 +++ b/LDViewer.py Fri Jul 24 17:12:59 2009 +0200 @@ -210,7 +210,7 @@ if rung not in rungs: rungs.append(rung) if len(rungs) > 1: - raise "ValueError", "Ladder element with id %d is on more than one rung."%instance["id"] + raise ValueError, _("Ladder element with id %d is on more than one rung.")%instance["id"] element = self.FindElementById(instance["id"]) self.Rungs[rungs[0]].SelectElement(element) for connector in element.GetConnectors(): @@ -225,7 +225,7 @@ if rung not in rungs: rungs.append(rung) if len(rungs) > 1: - raise "ValueError", "Ladder element with id %d is on more than one rung."%instance["id"] + raise ValueError, _("Ladder element with id %d is on more than one rung.")%instance["id"] element = self.FindElementById(instance["id"]) self.Rungs[rungs[0]].SelectElement(element) for wire, num in element.GetConnectors()["input"].GetWires(): @@ -475,7 +475,7 @@ rung = Graphic_Group(self) # Create comment id = self.GetNewId() - comment = Comment(self, "Commentaire", id) + comment = Comment(self, _("Comment"), id) comment.SetPosition(startx, starty) comment.SetSize(LD_COMMENT_DEFAULTSIZE[0], LD_COMMENT_DEFAULTSIZE[1]) self.AddComment(comment) @@ -625,7 +625,7 @@ self.RefreshScrollBars() self.Refresh(False) else: - message = wx.MessageDialog(self, "You must select the wire where a contact should be added!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("You must select the wire where a contact should be added!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() @@ -847,16 +847,16 @@ self.RefreshScrollBars() self.Refresh(False) else: - message = wx.MessageDialog(self, "The group of block must be coherent!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("The group of block must be coherent!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: - message = wx.MessageDialog(self, "You must select the block or group of blocks around which a branch should be added!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("You must select the block or group of blocks around which a branch should be added!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() def AddLadderBlock(self): - message = wx.MessageDialog(self, "This option isn't available yet!", "Warning", wx.OK|wx.ICON_EXCLAMATION) + message = wx.MessageDialog(self, _("This option isn't available yet!"), _("Warning"), wx.OK|wx.ICON_EXCLAMATION) message.ShowModal() message.Destroy() diff -r 020420ad8914 -r 07447ee3538e PLCControler.py --- a/PLCControler.py Fri Jul 24 12:49:57 2009 +0200 +++ b/PLCControler.py Fri Jul 24 17:12:59 2009 +0200 @@ -77,6 +77,16 @@ ScriptDirectory = os.path.split(os.path.realpath(__file__))[0] +def GetUneditableNames(): + _ = lambda x:x + return [_("User-defined POUs"), _("Functions"), _("Function Blocks"), + _("Programs"), _("Data Types"), _("Transitions"), _("Actions"), + _("Configurations"), _("Resources"), _("Properties")] +UNEDITABLE_NAMES = GetUneditableNames() +[USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, + DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, + RESOURCES, PROPERTIES] = UNEDITABLE_NAMES + #------------------------------------------------------------------------------- # Undo Buffer for PLCOpenEditor #------------------------------------------------------------------------------- @@ -280,7 +290,7 @@ self.FilePath = filepath if filepath == "": self.LastNewIndex += 1 - self.FileName = "Unnamed%d"%self.LastNewIndex + self.FileName = _("Unnamed%d")%self.LastNewIndex else: self.FileName = os.path.splitext(os.path.basename(filepath))[0] @@ -309,13 +319,13 @@ project = self.GetProject(debug) if project is not None: infos = {"name": project.getname(), "type": ITEM_PROJECT} - datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "values":[]} + datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values":[]} for datatype in project.getdataTypes(): datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []}) - pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "values":[]}, - "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "values":[]}, - "program": {"name": "Programs", "type": ITEM_PROGRAM, "values":[]}} + pou_types = {"function": {"name": FUNCTIONS, "type": ITEM_FUNCTION, "values":[]}, + "functionBlock": {"name": FUNCTION_BLOCKS, "type": ITEM_FUNCTIONBLOCK, "values":[]}, + "program": {"name": PROGRAMS, "type": ITEM_PROGRAM, "values":[]}} for pou in project.getpous(): pou_type = pou.getpouType() pou_infos = {"name": pou.getname(), "type": ITEM_POU, @@ -327,23 +337,23 @@ transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), "values": []}) - pou_values.append({"name": "Transitions", "type": ITEM_TRANSITIONS, "values": transitions}) + pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions}) actions = [] for action in pou.getactionList(): actions.append({"name": action.getname(), "type": ITEM_ACTION, "tagname": self.ComputePouActionName(pou.getname(), action.getname()), "values": []}) - pou_values.append({"name": "Actions", "type": ITEM_ACTIONS, "values": actions}) + pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions}) if pou_type in pou_types: pou_infos["values"] = pou_values pou_types[pou_type]["values"].append(pou_infos) - configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, "values": []} + configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []} for config in project.getconfigurations(): config_name = config.getname() config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, "tagname": self.ComputeConfigurationName(config.getname()), "values": []} - resources = {"name": "Resources", "type": ITEM_RESOURCES, "values": []} + resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []} for resource in config.getresource(): resource_name = resource.getname() resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, @@ -352,7 +362,7 @@ resources["values"].append(resource_infos) config_infos["values"] = [resources] configurations["values"].append(config_infos) - infos["values"] = [{"name": "Properties", "type": ITEM_PROPERTIES, "values": []}, + infos["values"] = [{"name": PROPERTIES, "type": ITEM_PROPERTIES, "values": []}, datatypes, pou_types["function"], pou_types["functionBlock"], pou_types["program"], configurations] return infos @@ -1165,7 +1175,7 @@ blocktypes = [category for category in BlockTypes + self.PluginTypes] project = self.GetProject(debug) if project is not None: - blocktypes.append({"name" : "User-defined POUs", "list": project.GetCustomBlockTypes(name, type == "function" or words[0] == "T")}) + blocktypes.append({"name" : USER_DEFINED_POUS, "list": project.GetCustomBlockTypes(name, type == "function" or words[0] == "T")}) return blocktypes # Return Function Block types checking for recursion @@ -2522,7 +2532,7 @@ self.Buffering = False self.CurrentElementEditing = None return None - return "No PLC project found" + return _("No PLC project found") def SaveXMLFile(self, filepath = None): if not filepath and self.FilePath == "": diff -r 020420ad8914 -r 07447ee3538e PLCGenerator.py --- a/PLCGenerator.py Fri Jul 24 12:49:57 2009 +0200 +++ b/PLCGenerator.py Fri Jul 24 17:12:59 2009 +0200 @@ -229,7 +229,7 @@ program = pou_program.GenerateProgram(pou) self.Program += program else: - raise PLCGenException, "Undefined pou type \"%s\""%pou_type + raise PLCGenException, _("Undefined pou type \"%s\"")%pou_type # Generate a POU defined and used in text def GeneratePouProgramInText(self, text): @@ -669,7 +669,7 @@ for element in body.getcontentInstances(): if isinstance(element, plcopen.commonObjects_connector) 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) + raise PLCGenException, _("More than one connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name) connector = element if connector is not None: undefined = [instance.connectionPointOut, connector.connectionPointIn] @@ -688,7 +688,7 @@ 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) + raise PLCGenException, _("No connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name) elif isinstance(instance, plcopen.fbdObjects_block): block_infos = self.GetBlockType(instance.gettypeName()) if block_infos is not None: @@ -873,7 +873,7 @@ for instance in body.getcontentInstances(): if isinstance(instance, plcopen.commonObjects_connector) 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) + raise PLCGenException, _("More than one connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name) connector = instance if connector is not None: connections = connector.connectionPointIn.getconnections() @@ -882,7 +882,7 @@ self.ComputedConnectors[name] = expression paths.append(str(expression)) else: - raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name) + raise PLCGenException, _("No connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name) elif isinstance(next, plcopen.ldObjects_contact): contact_info = (self.TagName, "contact", next.getlocalId()) variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) @@ -1225,7 +1225,7 @@ 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) + raise PLCGenException, _("Transition with content \"%s\" not connected to a previous step in \"%s\" POU")%(transition_infos["content"], self.Name) self.Program += [(" TO ", ())] if len(transition_infos["to"]) > 1: self.Program += [("(", ())] @@ -1234,7 +1234,7 @@ 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) + raise PLCGenException, _("Transition with content \"%s\" not connected to a next step in \"%s\" POU")%(transition_infos["content"], self.Name) self.Program += transition_infos["content"] self.Program += [("%sEND_TRANSITION\n\n"%self.CurrentIndent, ())] for [(step_name, step_infos)] in transition_infos["to"]: @@ -1252,9 +1252,9 @@ (self.ReturnType, (self.TagName, "return"))] program += [("\n", ())] if len(self.Interface) == 0: - raise PLCGenException, "No variable defined in \"%s\" POU"%self.Name + raise PLCGenException, _("No variable defined in \"%s\" POU")%self.Name if len(self.Program) == 0 : - raise PLCGenException, "No body defined in \"%s\" POU"%self.Name + raise PLCGenException, _("No body defined in \"%s\" POU")%self.Name var_number = 0 for list_type, retain, constant, located, variables in self.Interface: program += [(" %s"%list_type, ())] diff -r 020420ad8914 -r 07447ee3538e PLCOpenEditor.py --- a/PLCOpenEditor.py Fri Jul 24 12:49:57 2009 +0200 +++ b/PLCOpenEditor.py Fri Jul 24 17:12:59 2009 +0200 @@ -31,6 +31,75 @@ else: USE_AUI = False +import os, re, platform, sys, time, traceback, getopt +import cPickle + +CWD = os.path.split(os.path.realpath(__file__))[0] +base_folder = os.path.split(CWD)[0] +sys.path.append(base_folder) +from docutils import * + +from types import TupleType + +__version__ = "$Revision: 1.130 $" + +if __name__ == '__main__': + # Usage message displayed when help request or when error detected in + # command line + def usage(): + print "\nUsage of PLCOpenEditor.py :" + print "\n %s [Filepath]\n"%sys.argv[0] + + # Parse options given to PLCOpenEditor in command line + try: + opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) + except getopt.GetoptError: + # print help information and exit: + usage() + sys.exit(2) + + # Extract if help has been requested + for o, a in opts: + if o in ("-h", "--help"): + usage() + sys.exit() + + # Extract the optional filename to open + fileOpen = None + if len(args) > 1: + usage() + sys.exit() + elif len(args) == 1: + fileOpen = args[0] + + # Create wxApp (Need to create App before internationalization because of + # Windows) + app = wx.PySimpleApp() + +# Import module for internationalization +import gettext +import __builtin__ + +# Get folder containing translation files +localedir = os.path.join(CWD,"locale") +# Get the default language +langid = wx.LANGUAGE_DEFAULT +# Define translation domain (name of translation files) +domain = "PLCOpenEditor" + +# 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) + +if __name__ == '__main__': + __builtin__.__dict__['_'] = wx.GetTranslation + from SFCViewer import * from LDViewer import * from Viewer import * @@ -41,18 +110,7 @@ from PLCControler import * from plcopen.structures import LOCATIONDATATYPES -import os, re, platform, sys, time, traceback, getopt - -base_folder = os.path.split(sys.path[0])[0] -sys.path.append(base_folder) -from docutils import * - -from types import TupleType - -__version__ = "$Revision$" - -CWD = os.path.split(os.path.realpath(__file__))[0] - +# Define PLCOpenEditor controls id [ID_PLCOPENEDITOR, ID_PLCOPENEDITORTREENOTEBOOK, ID_PLCOPENEDITORTYPESTREE, ID_PLCOPENEDITORINSTANCESTREE, ID_PLCOPENEDITORMAINSPLITTER, ID_PLCOPENEDITORSECONDSPLITTER, @@ -102,79 +160,79 @@ ToolBarItems = { "FBD" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", - "add_comment.png", "Create a new comment"), + "add_comment.png", _("Create a new comment")), (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool", - "add_variable.png", "Create a new variable"), + "add_variable.png", _("Create a new variable")), (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool", - "add_block.png", "Create a new block"), + "add_block.png", _("Create a new block")), (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", - "add_connection.png", "Create a new connection")], + "add_connection.png", _("Create a new connection"))], "LD" : [(True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", - "add_comment.png", "Create a new comment"), + "add_comment.png", _("Create a new comment")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARPOWERRAIL, "OnPowerRailTool", - "add_powerrail.png", "Create a new power rail"), + "add_powerrail.png", _("Create a new power rail")), (False, DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARRUNG, "OnRungTool", - "add_rung.png", "Create a new rung"), + "add_rung.png", _("Create a new rung")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCOIL, "OnCoilTool", - "add_coil.png", "Create a new coil"), + "add_coil.png", _("Create a new coil")), (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCONTACT, "OnContactTool", - "add_contact.png", "Create a new contact"), + "add_contact.png", _("Create a new contact")), (False, DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARBRANCH, "OnBranchTool", - "add_branch.png", "Create a new branch"), + "add_branch.png", _("Create a new branch")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool", - "add_variable.png", "Create a new variable"), + "add_variable.png", _("Create a new variable")), (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool", - "add_block.png", "Create a new block"), + "add_block.png", _("Create a new block")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", - "add_connection.png", "Create a new connection")], + "add_connection.png", _("Create a new connection"))], "SFC" : [(True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCOMMENT, "OnCommentTool", - "add_comment.png", "Create a new comment"), + "add_comment.png", _("Create a new comment")), (True, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARINITIALSTEP, "OnInitialStepTool", - "add_initial_step.png", "Create a new initial step"), + "add_initial_step.png", _("Create a new initial step")), (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARSTEP, "OnStepTool", - "add_step.png", "Create a new step"), + "add_step.png", _("Create a new step")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARTRANSITION, "OnTransitionTool", - "add_transition.png", "Create a new transition"), + "add_transition.png", _("Create a new transition")), (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARACTIONBLOCK, "OnActionBlockTool", - "add_action.png", "Create a new action block"), + "add_action.png", _("Create a new action block")), (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARDIVERGENCE, "OnDivergenceTool", - "add_divergence.png", "Create a new divergence"), + "add_divergence.png", _("Create a new divergence")), (False, FREEDRAWING_MODE|DRIVENDRAWING_MODE, ID_PLCOPENEDITORTOOLBARJUMP, "OnJumpTool", - "add_jump.png", "Create a new jump"), + "add_jump.png", _("Create a new jump")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARVARIABLE, "OnVariableTool", - "add_variable.png", "Create a new variable"), + "add_variable.png", _("Create a new variable")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARBLOCK, "OnBlockTool", - "add_block.png", "Create a new block"), + "add_block.png", _("Create a new block")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCONNECTION, "OnConnectionTool", - "add_connection.png", "Create a new connection"), + "add_connection.png", _("Create a new connection")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARPOWERRAIL, "OnPowerRailTool", - "add_powerrail.png", "Create a new power rail"), + "add_powerrail.png", _("Create a new power rail")), (True, FREEDRAWING_MODE, ID_PLCOPENEDITORTOOLBARCONTACT, "OnContactTool", - "add_contact.png", "Create a new contact")], + "add_contact.png", _("Create a new contact"))], "ST" : [], "IL" : [] } @@ -222,13 +280,15 @@ else: remove_function(self.Controler, name) else: - self.ShowErrorMessage("\"%s\" is used by one or more POUs. It can't be removed!"%name) + self.ShowErrorMessage(_("\"%s\" is used by one or more POUs. It can't be removed!")%name) return DeleteElementFunction #------------------------------------------------------------------------------- # PLCOpenEditor Main Class #------------------------------------------------------------------------------- +UNEDITABLE_NAMES_DICT = dict([(_(name), name) for name in UNEDITABLE_NAMES]) + class PLCOpenEditor(wx.Frame): # Compatibility function for wx versions < 2.6 @@ -240,50 +300,50 @@ event(self, function) def _init_coll_MenuBar_Menus(self, parent): - parent.Append(menu=self.FileMenu, title=u'File') + parent.Append(menu=self.FileMenu, title=_(u'File')) if not self.Debug: - parent.Append(menu=self.EditMenu, title=u'Edit') - parent.Append(menu=self.DisplayMenu, title=u'Display') - parent.Append(menu=self.HelpMenu, title=u'Help') + parent.Append(menu=self.EditMenu, title=_(u'Edit')) + parent.Append(menu=self.DisplayMenu, title=_(u'Display')) + parent.Append(menu=self.HelpMenu, title=_(u'Help')) def _init_coll_FileMenu_Items(self, parent): if self.ModeSolo: AppendMenu(parent, help='', id=wx.ID_NEW, - kind=wx.ITEM_NORMAL, text=u'New\tCTRL+N') + kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N')) AppendMenu(parent, help='', id=wx.ID_OPEN, - kind=wx.ITEM_NORMAL, text=u'Open\tCTRL+O') + kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O')) AppendMenu(parent, help='', id=wx.ID_CLOSE, - kind=wx.ITEM_NORMAL, text=u'Close Tab\tCTRL+W') + kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W')) if self.ModeSolo: AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL, - kind=wx.ITEM_NORMAL, text=u'Close Project') + kind=wx.ITEM_NORMAL, text=_(u'Close Project')) parent.AppendSeparator() if not self.Debug: AppendMenu(parent, help='', id=wx.ID_SAVE, - kind=wx.ITEM_NORMAL, text=u'Save\tCTRL+S') + kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S')) if self.ModeSolo: AppendMenu(parent, help='', id=wx.ID_SAVEAS, - kind=wx.ITEM_NORMAL, text=u'Save As...\tCTRL+SHIFT+S') + kind=wx.ITEM_NORMAL, text=_(u'Save As...\tCTRL+SHIFT+S')) AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE, - kind=wx.ITEM_NORMAL, text=u'Generate Program\tCTRL+G') + kind=wx.ITEM_NORMAL, text=_(u'Generate Program\tCTRL+G')) parent.AppendSeparator() AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, - kind=wx.ITEM_NORMAL, text=u'Page Setup') + kind=wx.ITEM_NORMAL, text=_(u'Page Setup')) AppendMenu(parent, help='', id=wx.ID_PREVIEW, - kind=wx.ITEM_NORMAL, text=u'Preview') + kind=wx.ITEM_NORMAL, text=_(u'Preview')) AppendMenu(parent, help='', id=wx.ID_PRINT, - kind=wx.ITEM_NORMAL, text=u'Print') + kind=wx.ITEM_NORMAL, text=_(u'Print')) if not self.Debug: parent.AppendSeparator() AppendMenu(parent, help='', id=wx.ID_PROPERTIES, - kind=wx.ITEM_NORMAL, text=u'Properties') + kind=wx.ITEM_NORMAL, text=_(u'Properties')) parent.AppendSeparator() if self.ModeSolo: AppendMenu(parent, help='', id=wx.ID_EXIT, - kind=wx.ITEM_NORMAL, text=u'Quit\tCTRL+Q') + kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q')) else: AppendMenu(parent, help='', id=wx.ID_STOP, - kind=wx.ITEM_NORMAL, text=u'Close\tCTRL+Q') + kind=wx.ITEM_NORMAL, text=_(u'Close\tCTRL+Q')) if self.ModeSolo: self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW) @@ -309,35 +369,33 @@ def _init_coll_EditMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_UNDO, - kind=wx.ITEM_NORMAL, text=u'Undo\tCTRL+Z') + kind=wx.ITEM_NORMAL, text=_(u'Undo\tCTRL+Z')) AppendMenu(parent, help='', id=wx.ID_REDO, - kind=wx.ITEM_NORMAL, text=u'Redo\tCTRL+Y') - AppendMenu(parent, help='', id=ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO, - kind=wx.ITEM_CHECK, text=u'Enable Undo/Redo') + kind=wx.ITEM_NORMAL, text=_(u'Redo\tCTRL+Y')) parent.AppendSeparator() AppendMenu(parent, help='', id=wx.ID_CUT, - kind=wx.ITEM_NORMAL, text=u'Cut\tCTRL+X') + kind=wx.ITEM_NORMAL, text=_(u'Cut\tCTRL+X')) AppendMenu(parent, help='', id=wx.ID_COPY, - kind=wx.ITEM_NORMAL, text=u'Copy\tCTRL+C') + kind=wx.ITEM_NORMAL, text=_(u'Copy\tCTRL+C')) AppendMenu(parent, help='', id=wx.ID_PASTE, - kind=wx.ITEM_NORMAL, text=u'Paste\tCTRL+V') + kind=wx.ITEM_NORMAL, text=_(u'Paste\tCTRL+V')) parent.AppendSeparator() addmenu = wx.Menu(title='') - parent.AppendMenu(wx.ID_ADD, "Add Element", addmenu) + parent.AppendMenu(wx.ID_ADD, _("Add Element"), addmenu) AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE, - kind=wx.ITEM_NORMAL, text=u'Data Type') + kind=wx.ITEM_NORMAL, text=_(u'Data Type')) AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION, - kind=wx.ITEM_NORMAL, text=u'Function') + kind=wx.ITEM_NORMAL, text=_(u'Function')) AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, - kind=wx.ITEM_NORMAL, text=u'Function Block') + kind=wx.ITEM_NORMAL, text=_(u'Function Block')) AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM, - kind=wx.ITEM_NORMAL, text=u'Program') + kind=wx.ITEM_NORMAL, text=_(u'Program')) AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, - kind=wx.ITEM_NORMAL, text=u'Configuration') + kind=wx.ITEM_NORMAL, text=_(u'Configuration')) AppendMenu(parent, help='', id=wx.ID_SELECTALL, - kind=wx.ITEM_NORMAL, text=u'Select All\tCTRL+A') + kind=wx.ITEM_NORMAL, text=_(u'Select All\tCTRL+A')) AppendMenu(parent, help='', id=wx.ID_DELETE, - kind=wx.ITEM_NORMAL, text=u'Delete') + kind=wx.ITEM_NORMAL, text=_(u'Delete')) self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO) self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO) self.Bind(wx.EVT_MENU, self.OnEnableUndoRedoMenu, id=ID_PLCOPENEDITOREDITMENUENABLEUNDOREDO) @@ -359,13 +417,13 @@ def _init_coll_DisplayMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_REFRESH, - kind=wx.ITEM_NORMAL, text=u'Refresh\tF5') + kind=wx.ITEM_NORMAL, text=_(u'Refresh\tF5')) if not self.Debug and not self.ModeSolo: AppendMenu(parent, help='', id=wx.ID_CLEAR, - kind=wx.ITEM_NORMAL, text=u'Clear Errors\tCTRL+K') + kind=wx.ITEM_NORMAL, text=_(u'Clear Errors\tCTRL+K')) parent.AppendSeparator() zoommenu = wx.Menu(title='') - parent.AppendMenu(wx.ID_ZOOM_FIT, "ZOOM", zoommenu) + parent.AppendMenu(wx.ID_ZOOM_FIT, _("Zoom"), zoommenu) for idx, value in enumerate(ZOOM_FACTORS): new_id = wx.NewId() AppendMenu(zoommenu, help='', id=new_id, @@ -377,14 +435,14 @@ def _init_coll_HelpMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_HELP, - kind=wx.ITEM_NORMAL, text=u'PLCOpenEditor\tF1') + kind=wx.ITEM_NORMAL, text=_(u'PLCOpenEditor\tF1')) #AppendMenu(parent, help='', id=wx.ID_HELP_CONTENTS, # kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2') #AppendMenu(parent, help='', id=wx.ID_HELP_CONTEXT, # kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3') if self.ModeSolo: AppendMenu(parent, help='', id=wx.ID_ABOUT, - kind=wx.ITEM_NORMAL, text=u'About') + kind=wx.ITEM_NORMAL, text=_(u'About')) self.Bind(wx.EVT_MENU, self.OnPLCOpenEditorMenu, id=wx.ID_HELP) #self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu, id=wx.ID_HELP_CONTENTS) self.Bind(wx.EVT_MENU, self.OnAboutMenu, id=wx.ID_ABOUT) @@ -424,7 +482,7 @@ def _init_ctrls(self, prnt): wx.Frame.__init__(self, id=ID_PLCOPENEDITOR, name=u'PLCOpenEditor', parent=prnt, pos=wx.DefaultPosition, size=wx.Size(1000, 600), - style=wx.DEFAULT_FRAME_STYLE, title=u'PLCOpenEditor') + style=wx.DEFAULT_FRAME_STYLE, title=_(u'PLCOpenEditor')) self._init_utils() self.SetClientSize(wx.Size(1000, 600)) self.SetMenuBar(self.MenuBar) @@ -436,7 +494,7 @@ self.Panes = {} self.TreeNoteBook = wx.aui.AuiNotebook(self) - self.AUIManager.AddPane(self.TreeNoteBook, wx.aui.AuiPaneInfo().Caption("Project").Left().Layer(1).BestSize(wx.Size(200, 500)).CloseButton(False)) + self.AUIManager.AddPane(self.TreeNoteBook, wx.aui.AuiPaneInfo().Caption(_("Project")).Left().Layer(1).BestSize(wx.Size(200, 500)).CloseButton(False)) else: self.MainSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORMAINSPLITTER, @@ -498,8 +556,8 @@ self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnInstancesTreeItemActivated, id=ID_PLCOPENEDITORINSTANCESTREE) - self.TreeNoteBook.AddPage(self.InstancesTree, "Instances") - self.TreeNoteBook.AddPage(self.TypesTree, "Types") + self.TreeNoteBook.AddPage(self.InstancesTree, _("Instances")) + self.TreeNoteBook.AddPage(self.TypesTree, _("Types")) if USE_AUI: self.TabsOpened = wx.aui.AuiNotebook(self) @@ -512,7 +570,7 @@ self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane()) self.DebugVariablePanel = DebugVariablePanel(self, self.Controler) - self.AUIManager.AddPane(self.DebugVariablePanel, wx.aui.AuiPaneInfo().Caption("Variables").Right().Layer(0).BestSize(wx.Size(250, 600)).CloseButton(False)) + self.AUIManager.AddPane(self.DebugVariablePanel, wx.aui.AuiPaneInfo().Caption(_("Variables")).Right().Layer(0).BestSize(wx.Size(250, 600)).CloseButton(False)) else: self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER, name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0), @@ -535,19 +593,19 @@ self.SecondSplitter.SplitVertically(self.TabsOpened, self.DebugVariablePanel, -250) else: - self.TreeNoteBook.AddPage(self.TypesTree, "Types") - self.TreeNoteBook.AddPage(self.InstancesTree, "Instances") + self.TreeNoteBook.AddPage(self.TypesTree, _("Types")) + self.TreeNoteBook.AddPage(self.InstancesTree, _("Instances")) if USE_AUI: ToolBar = wx.ToolBar(self, ID_PLCOPENEDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize, wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER) ToolBar.SetToolBitmapSize(wx.Size(25, 25)) ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, - wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, "Select an object") + wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object")) ToolBar.Realize() self.Panes["ToolBar"] = ToolBar self.AUIManager.AddPane(ToolBar, wx.aui.AuiPaneInfo(). - Name("ToolBar").Caption("Toolbar"). + Name("ToolBar").Caption(_("Toolbar")). ToolbarPane().Top(). LeftDockable(False).RightDockable(False)) else: @@ -555,7 +613,7 @@ ID_PLCOPENEDITORTOOLBAR, 'ToolBar') self.ToolBar.SetToolBitmapSize(wx.Size(25, 25)) self.ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, - wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, "Select an object") + wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, _("Select an object")) self.ToolBar.Realize() self.Bind(wx.EVT_TOOL, self.OnSelectionTool, @@ -563,7 +621,7 @@ if USE_AUI: self.VariablePanelIndexer = VariablePanelIndexer(self, self, self.Controler) - self.AUIManager.AddPane(self.VariablePanelIndexer, wx.aui.AuiPaneInfo().Caption("Variables").Bottom().Layer(0).BestSize(wx.Size(800, 200)).CloseButton(False)) + self.AUIManager.AddPane(self.VariablePanelIndexer, wx.aui.AuiPaneInfo().Caption(_("Variables")).Bottom().Layer(0).BestSize(wx.Size(800, 200)).CloseButton(False)) self.TabsOpened = wx.aui.AuiNotebook(self) self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, @@ -577,7 +635,7 @@ self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL, name='LibraryPanel', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) - self.AUIManager.AddPane(self.LibraryPanel, wx.aui.AuiPaneInfo().Caption("Library").Right().Layer(0).BestSize(wx.Size(250, 400)).CloseButton(False)) + self.AUIManager.AddPane(self.LibraryPanel, wx.aui.AuiPaneInfo().Caption(_("Library")).Right().Layer(0).BestSize(wx.Size(250, 400)).CloseButton(False)) else: self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER, name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0), @@ -777,9 +835,9 @@ return self.DrawingMode def RefreshTitle(self): - name = "PLCOpenEditor" + name = _("PLCOpenEditor") if self.Debug: - name += " (Debug)" + name += _(" (Debug)") if self.Controler.HasOpenedProject() > 0: self.SetTitle("%s - %s"%(name, self.Controler.GetFilename())) else: @@ -892,7 +950,7 @@ ## Function displaying an Error dialog in PLCOpenEditor. # @param message The message to display. def ShowErrorMessage(self, message): - dialog = wx.MessageDialog(self, message, "Error", wx.OK|wx.ICON_ERROR) + dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR) dialog.ShowModal() dialog.Destroy() @@ -900,7 +958,7 @@ # @return False if closing cancelled. def CheckSaveBeforeClosing(self): if not self.Controler.ProjectIsSaved(): - dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) + dialog = wx.MessageDialog(self, _("There are changes, do you want to save?"), _("Close Application"), wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION) answer = dialog.ShowModal() dialog.Destroy() if answer == wx.ID_YES: @@ -970,7 +1028,7 @@ directory = os.path.dirname(filepath) else: directory = os.getcwd() - dialog = wx.FileDialog(self, "Choose a file", directory, "", "PLCOpen files (*.xml)|*.xml|All files|*.*", wx.OPEN) + dialog = wx.FileDialog(self, _("Choose a file"), directory, "", _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.OPEN) if dialog.ShowModal() == wx.ID_OK: filepath = dialog.GetPath() if os.path.isfile(filepath): @@ -1021,23 +1079,23 @@ event.Skip() def OnGenerateProgramMenu(self, event): - dialog = wx.FileDialog(self, "Choose a file", os.getcwd(), self.Controler.GetProgramFilePath(), "ST files (*.st)|*.st|All files|*.*", wx.SAVE|wx.CHANGE_DIR) + dialog = wx.FileDialog(self, _("Choose a file"), os.getcwd(), self.Controler.GetProgramFilePath(), _("ST files (*.st)|*.st|All files|*.*"), wx.SAVE|wx.CHANGE_DIR) if dialog.ShowModal() == wx.ID_OK: filepath = dialog.GetPath() message_text = "" - header, icon = "Done", wx.ICON_INFORMATION + header, icon = _("Done"), wx.ICON_INFORMATION if os.path.isdir(os.path.dirname(filepath)): program, errors, warnings = self.Controler.GenerateProgram(filepath) - message_text += "".join(["warning: %s\n" for warning in warnings]) + message_text += "".join([_("warning: %s\n") for warning in warnings]) if len(errors) > 0: - message_text += "".join(["error: %s\n" for warning in warnings]) - message_text += "Can't generate program to file %s!"%filepath - header, icon = "Error", wx.ICON_ERROR + message_text += "".join([_("error: %s\n") for warning in warnings]) + message_text += _("Can't generate program to file %s!")%filepath + header, icon = _("Error"), wx.ICON_ERROR else: - message_text += "Program was successfully generated!" + message_text += _("Program was successfully generated!") else: - message_text += "%s is not a valid folder!"%os.path.dirname(filepath) - header, icon = "Error", wx.ICON_ERROR + message_text += _("\"%s\" is not a valid folder!")%os.path.dirname(filepath) + header, icon = _("Error"), wx.ICON_ERROR message = wx.MessageDialog(self, message_text, header, wx.OK|icon) message.ShowModal() message.Destroy() @@ -1057,15 +1115,15 @@ directory, filename = os.path.split(filepath) else: directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties(self.Debug) - dialog = wx.FileDialog(self, "Choose a file", directory, filename, "PLCOpen files (*.xml)|*.xml|All files|*.*", wx.SAVE|wx.OVERWRITE_PROMPT) + dialog = wx.FileDialog(self, _("Choose a file"), directory, filename, _("PLCOpen files (*.xml)|*.xml|All files|*.*"), wx.SAVE|wx.OVERWRITE_PROMPT) if dialog.ShowModal() == wx.ID_OK: filepath = dialog.GetPath() if os.path.isdir(os.path.dirname(filepath)): result = self.Controler.SaveXMLFile(filepath) if not result: - self.ShowErrorMessage("Can't save project to file %s!"%filepath) + self.ShowErrorMessage(_("Can't save project to file %s!")%filepath) else: - self.ShowErrorMessage("\"%s\" is not a valid folder!"%os.path.dirname(filepath)) + self.ShowErrorMessage(_("\"%s\" is not a valid folder!")%os.path.dirname(filepath)) self.RefreshTitle() dialog.Destroy() @@ -1089,7 +1147,7 @@ preview = wx.PrintPreview(printout, printout2, data) if preview.Ok(): - preview_frame = wx.PreviewFrame(preview, self, "Print preview") + preview_frame = wx.PreviewFrame(preview, self, _("Print preview")) preview_frame.Initialize() @@ -1108,7 +1166,7 @@ printout = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins) if not printer.Print(self, printout, True): - self.ShowErrorMessage("There was a problem printing.\nPerhaps your current printer is not set correctly?") + self.ShowErrorMessage(_("There was a problem printing.\nPerhaps your current printer is not set correctly?")) printout.Destroy() event.Skip() @@ -1403,7 +1461,8 @@ def GenerateTypesTreeBranch(self, root, infos, topology=False): to_delete = [] - self.TypesTree.SetItemText(root, infos["name"]) + item_name = infos["name"] + self.TypesTree.SetItemText(root, _(item_name)) self.TypesTree.SetPyData(root, infos["type"]) if infos.get("tagname", None) in self.Errors: self.TypesTree.SetItemBackgroundColour(root, wx.Colour(255, 255, 0)) @@ -1498,9 +1557,9 @@ new_name = event.GetLabel() if new_name != "": if not TestIdentifier(new_name): - message = "\"%s\" is not a valid identifier!"%new_name + message = _("\"%s\" is not a valid identifier!")%new_name elif new_name.upper() in IEC_KEYWORDS: - message = "\"%s\" is a keyword. It can't be used!"%new_name + message = _("\"%s\" is a keyword. It can't be used!")%new_name else: item = event.GetItem() old_name = self.TypesTree.GetItemText(item) @@ -1509,7 +1568,7 @@ self.Controler.SetProjectProperties(name = new_name) elif itemtype == ITEM_DATATYPE: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames(self.Debug) if name != old_name]: - message = "\"%s\" data type already exists!"%new_name + message = _("\"%s\" data type already exists!")%new_name abort = True if not abort: self.Controler.ChangeDataTypeName(old_name, new_name) @@ -1518,10 +1577,10 @@ self.RefreshPageTitles() elif itemtype == ITEM_POU: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug) if name != old_name]: - message = "\"%s\" pou already exists!"%new_name + message = _("\"%s\" pou already exists!")%new_name abort = True elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: - messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) + messageDialog = wx.MessageDialog(self, _("A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True messageDialog.Destroy() @@ -1534,9 +1593,9 @@ elif itemtype == ITEM_TRANSITION: pou_name = GetParentName(self.TypesTree, item, ITEM_POU) if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: - message = "A pou with \"%s\" as name exists!"%new_name + message = _("A pou with \"%s\" as name exists!")%new_name elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]: - message = "A variable with \"%s\" as name already exists in this pou!"%new_name + message = _("A variable with \"%s\" as name already exists in this pou!")%new_name else: self.Controler.ChangePouTransitionName(pou_name, old_name, new_name) self.RefreshEditorNames(self.Controler.ComputePouTransitionName(pou_name, old_name), @@ -1545,9 +1604,9 @@ elif itemtype == ITEM_ACTION: pou_name = GetParentName(self.TypesTree, item, ITEM_POU) if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: - message = "A pou with \"%s\" as name exists!"%new_name + message = _("A pou with \"%s\" as name exists!")%new_name elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]: - message = "A variable with \"%s\" as name already exists in this pou!"%new_name + message = _("A variable with \"%s\" as name already exists in this pou!")%new_name else: self.Controler.ChangePouActionName(pou_name, old_name, new_name) self.RefreshEditorNames(self.Controler.ComputePouActionName(pou_name, old_name), @@ -1555,15 +1614,15 @@ self.RefreshPageTitles() elif itemtype == ITEM_CONFIGURATION: if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug) if name != old_name]: - message = "\"%s\" config already exists!"%new_name + message = _("\"%s\" config already exists!")%new_name abort = True elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: - messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) + messageDialog = wx.MessageDialog(self, _("A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True messageDialog.Destroy() elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: - messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) + messageDialog = wx.MessageDialog(self, _("A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True messageDialog.Destroy() @@ -1575,15 +1634,15 @@ elif itemtype == ITEM_RESOURCE: config_name = GetParentName(self.TypesTree, item, ITEM_CONFIGURATION) if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug)]: - message = "\"%s\" config already exists!"%new_name + message = _("\"%s\" config already exists!")%new_name abort = True elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]: - messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) + messageDialog = wx.MessageDialog(self, _("A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True messageDialog.Destroy() elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]: - messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION) + messageDialog = wx.MessageDialog(self, _("A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION) if messageDialog.ShowModal() == wx.ID_NO: abort = True messageDialog.Destroy() @@ -1608,7 +1667,7 @@ selected = event.GetItem() name = self.TypesTree.GetItemText(selected) data = self.TypesTree.GetPyData(selected) - if name == "Properties": + if UNEDITABLE_NAMES_DICT.get(name, name) == "Properties": self.ShowProperties() if data == ITEM_DATATYPE: self.EditProjectElement(data, self.Controler.ComputeDataTypeName(name)) @@ -1735,71 +1794,72 @@ menu = wx.Menu(title='') if self.Controler.GetPouBodyType(name, self.Debug) == "SFC": new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Transition") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition")) self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(name), id=new_id) new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Action") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action")) self.Bind(wx.EVT_MENU, self.GenerateAddActionFunction(name), id=new_id) menu.AppendSeparator() new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Create A New POU From") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Create a new POU from")) self.Bind(wx.EVT_MENU, self.OnCreatePouFromMenu, id=new_id) pou_type = self.Controler.GetPouType(name, self.Debug) if pou_type in ["function", "functionBlock"]: change_menu = wx.Menu(title='') if pou_type == "function": new_id = wx.NewId() - AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Function Block") + AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Function Block")) self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "functionBlock"), id=new_id) new_id = wx.NewId() - AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Program") + AppendMenu(change_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Program")) self.Bind(wx.EVT_MENU, self.GenerateChangePouTypeFunction(name, "program"), id=new_id) - menu.AppendMenu(wx.NewId(), "Change POU Type To", change_menu) + menu.AppendMenu(wx.NewId(), _("Change POU Type To"), change_menu) new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Rename") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Rename")) self.Bind(wx.EVT_MENU, self.OnRenamePouMenu, id=new_id) new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete")) self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id) self.PopupMenu(menu) elif type == ITEM_CONFIGURATION: menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Resource") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource")) self.Bind(wx.EVT_MENU, self.GenerateAddResourceFunction(name), id=new_id) new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete")) self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id) self.PopupMenu(menu) elif type in [ITEM_DATATYPE, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE]: menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Delete") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete")) self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=new_id) self.PopupMenu(menu) elif type in ITEMS_UNEDITABLE: + name = UNEDITABLE_NAMES_DICT[name] if name == "Data Types": menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add DataType") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add DataType")) self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, id=new_id) self.PopupMenu(menu) elif name in ["Functions", "Function Blocks", "Programs"]: menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Pou") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Pou")) self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction({"Functions" : "function", "Function Blocks" : "functionBlock", "Programs" : "program"}[name]), id=new_id) self.PopupMenu(menu) elif name == "Configurations": menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Configuration") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Configuration")) self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, id=new_id) self.PopupMenu(menu) elif name == "Transitions": menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Transition") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Transition")) parent = self.TypesTree.GetItemParent(item) parent_type = self.TypesTree.GetPyData(parent) while parent_type != ITEM_POU: @@ -1810,7 +1870,7 @@ elif name == "Actions": menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Action") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Action")) parent = self.TypesTree.GetItemParent(item) parent_type = self.TypesTree.GetPyData(parent) while parent_type != ITEM_POU: @@ -1821,7 +1881,7 @@ elif name == "Resources": menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Resource") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Add Resource")) parent = self.TypesTree.GetItemParent(item) parent_type = self.TypesTree.GetPyData(parent) while parent_type != ITEM_CONFIGURATION: @@ -1965,10 +2025,10 @@ menu = wx.Menu(title='') new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Graphic Panel") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Graphic Panel")) self.Bind(wx.EVT_MENU, self.AddVariableGraphicFunction(var_path), id=new_id) new_id = wx.NewId() - AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="CSV Log") + AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("CSV Log")) self.PopupMenu(menu) event.Skip() @@ -2014,7 +2074,7 @@ root = self.LibraryTree.GetRootItem() if not root.IsOk(): if wx.Platform == '__WXMSW__': - root = self.LibraryTree.AddRoot("Block Types") + root = self.LibraryTree.AddRoot(_("Block Types")) self.LibraryTree.SetPyData(root, {"type" : CATEGORY}) else: root = self.LibraryTree.AddRoot("") @@ -2023,12 +2083,13 @@ else: category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0) for category in blocktypes: + category_name = category["name"] if not category_item.IsOk(): - category_item = self.LibraryTree.AppendItem(root, category["name"]) + category_item = self.LibraryTree.AppendItem(root, _(category_name)) if wx.Platform != '__WXMSW__': category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie) else: - self.LibraryTree.SetItemText(category_item, category["name"]) + self.LibraryTree.SetItemText(category_item, _(category_name)) self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY}) if wx.VERSION >= (2, 6, 0): blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item) @@ -2061,7 +2122,8 @@ if pydata is not None and pydata["type"] != CATEGORY: blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"], debug = self.Debug) if blocktype: - self.LibraryComment.SetValue(blocktype["comment"]) + comment = blocktype["comment"] + self.LibraryComment.SetValue(_(comment) + blocktype.get("usage", "")) else: self.LibraryComment.SetValue("") else: @@ -2294,7 +2356,7 @@ #------------------------------------------------------------------------------- def OnAddDataTypeMenu(self, event): - dialog = DataTypeDialog(self, "Add a new data type", "Please enter data type name", "", wx.OK|wx.CANCEL) + dialog = DataTypeDialog(self, _("Add a new data type"), _("Please enter data type name"), "", wx.OK|wx.CANCEL) dialog.SetDataTypeNames(self.Controler.GetProjectDataTypeNames(self.Debug)) if dialog.ShowModal() == wx.ID_OK: self.Controler.ProjectAddDataType(dialog.GetValue()) @@ -2351,7 +2413,7 @@ return OnAddActionMenu def OnAddConfigurationMenu(self, event): - dialog = ConfigurationNameDialog(self, "Please enter configuration name", "Add new configuration") + dialog = ConfigurationNameDialog(self, _("Please enter configuration name"), _("Add new configuration")) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug)) if dialog.ShowModal() == wx.ID_OK: @@ -2366,7 +2428,7 @@ def GenerateAddResourceFunction(self, config_name): def OnAddResourceMenu(event): - dialog = ResourceNameDialog(self, "Please enter resource name", "Add new resource") + dialog = ResourceNameDialog(self, _("Please enter resource name"), _("Add new resource")) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug)) if dialog.ShowModal() == wx.ID_OK: @@ -2396,7 +2458,7 @@ def OnCreatePouFromMenu(self, event): selected = self.TypesTree.GetSelection() if self.TypesTree.GetPyData(selected) == ITEM_POU: - dialog = PouNameDialog(self, "Please enter POU name", "Create a new POU from", "", wx.OK|wx.CANCEL) + dialog = PouNameDialog(self, _("Please enter POU name"), _("Create a new POU from"), "", wx.OK|wx.CANCEL) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) if dialog.ShowModal() == wx.ID_OK: self.Controler.ProjectCreatePouFrom(dialog.GetValue(), self.TypesTree.GetItemText(selected)) @@ -2426,7 +2488,7 @@ self.RefreshTypesTree() self.RefreshToolBar() else: - message = wx.MessageDialog(self, "\"%s\" is used by one or more POUs. It can't be removed!"%name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is used by one or more POUs. It can't be removed!")%name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Skip() @@ -2455,7 +2517,7 @@ self.RefreshLibraryTree() self.RefreshToolBar() else: - message = wx.MessageDialog(self, "\"%s\" is used by one or more POUs. It can't be removed!"%name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is used by one or more POUs. It can't be removed!")%name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Skip() @@ -2541,7 +2603,7 @@ event.Skip() def OnPLCOpenEditorMenu(self, event): - wx.MessageBox("No documentation available.\nComing soon.") + wx.MessageBox(_("No documentation available.\nComing soon.")) #event.Skip() def OnPLCOpenMenu(self, event): @@ -2549,7 +2611,7 @@ event.Skip() def OnAboutMenu(self, event): - OpenHtmlFrame(self,"About PLCOpenEditor", os.path.join(CWD, "doc","about.html"), wx.Size(350, 350)) + OpenHtmlFrame(self,_("About PLCOpenEditor"), os.path.join(CWD, "doc","about.html"), wx.Size(350, 350)) event.Skip() @@ -2610,16 +2672,16 @@ class ScalingPanel(wx.Panel): def _init_coll_ScalingPanelSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT) + parent.AddWindow(self.staticText1, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT) parent.AddWindow(self.XScale, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT) - parent.AddWindow(self.staticText2, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT) + parent.AddWindow(self.staticText2, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT) parent.AddWindow(self.YScale, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT) def _init_coll_ScalingPanelSizer_Growables(self, parent): parent.AddGrowableCol(1) def _init_sizers(self): - self.ScalingPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=5) + self.ScalingPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5) self._init_coll_ScalingPanelSizer_Items(self.ScalingPanelSizer) self._init_coll_ScalingPanelSizer_Growables(self.ScalingPanelSizer) @@ -2632,16 +2694,16 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText1 = wx.StaticText(id=ID_SCALINGPANELSTATICTEXT1, - label='X Scale:', name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('X Scale:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.XScale = wx.SpinCtrl(id=ID_SCALINGPANELXSCALE, name='XScale', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0, min=0, max=2**16) self.staticText2 = wx.StaticText(id=ID_SCALINGPANELSTATICTEXT2, - label='Y Scale:', name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Y Scale:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.YScale = wx.SpinCtrl(id=ID_SCALINGPANELYSCALE, name='YScale', parent=self, pos=wx.Point(0, 0), @@ -2696,37 +2758,37 @@ parent.AddGrowableRow(0) def _init_coll_ProjectPanelSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT) + parent.AddWindow(self.staticText1, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT) parent.AddWindow(self.ProjectName, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT) - parent.AddWindow(self.staticText2, 0, border=10, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.staticText2, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT) parent.AddWindow(self.ProjectVersion, 0, border=10, flag=wx.GROW|wx.RIGHT) - parent.AddWindow(self.staticText3, 0, border=10, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.staticText3, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT) parent.AddWindow(self.ProductName, 0, border=10, flag=wx.GROW|wx.RIGHT) - parent.AddWindow(self.staticText4, 0, border=10, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.staticText4, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT) parent.AddWindow(self.ProductVersion, 0, border=10, flag=wx.GROW|wx.RIGHT) - parent.AddWindow(self.staticText5, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT) + parent.AddWindow(self.staticText5, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT) parent.AddWindow(self.ProductRelease, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT) def _init_coll_ProjectPanelSizer_Growables(self, parent): parent.AddGrowableCol(1) def _init_coll_AuthorPanelSizer_Items(self, parent): - parent.AddWindow(self.staticText6, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT) + parent.AddWindow(self.staticText6, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT) parent.AddWindow(self.CompanyName, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT) - parent.AddWindow(self.staticText7, 0, border=10, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.staticText7, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT) parent.AddWindow(self.CompanyURL, 0, border=10, flag=wx.GROW|wx.RIGHT) - parent.AddWindow(self.staticText8, 0, border=10, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.staticText8, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT) parent.AddWindow(self.AuthorName, 0, border=10, flag=wx.GROW|wx.RIGHT) - parent.AddWindow(self.staticText9, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT) + parent.AddWindow(self.staticText9, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM|wx.LEFT) parent.AddWindow(self.Organization, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT) def _init_coll_AuthorPanelSizer_Growables(self, parent): parent.AddGrowableCol(1) def _init_coll_GraphicsPanelSizer_Items(self, parent): - parent.AddWindow(self.staticText12, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddWindow(self.staticText12, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT|wx.RIGHT) parent.AddSizer(self.GraphicsPageSizeSizer, 0, border=10, flag=wx.GROW|wx.LEFT|wx.RIGHT) - parent.AddWindow(self.staticText15, 0, border=10, flag=wx.GROW|wx.LEFT|wx.RIGHT) + parent.AddWindow(self.staticText15, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT) parent.AddWindow(self.ScalingNotebook, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT) def _init_coll_GraphicsPanelSizer_Growables(self, parent): @@ -2734,18 +2796,18 @@ parent.AddGrowableRow(3) def _init_coll_GraphicsPageSizeSizer_Items(self, parent): - parent.AddWindow(self.staticText13, 0, border=12, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.staticText13, 0, border=12, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT) parent.AddWindow(self.PageWidth, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText14, 0, border=12, flag=wx.GROW|wx.LEFT) + parent.AddWindow(self.staticText14, 0, border=12, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT) parent.AddWindow(self.PageHeight, 0, border=0, flag=wx.GROW) def _init_coll_GraphicsPageSizeSizer_Growables(self, parent): parent.AddGrowableCol(1) def _init_coll_MiscellaneousPanelSizer_Items(self, parent): - parent.AddWindow(self.staticText10, 0, border=10, flag=wx.GROW|wx.TOP|wx.LEFT) + parent.AddWindow(self.staticText10, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT) parent.AddWindow(self.Language, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT) - parent.AddWindow(self.staticText11, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT) + parent.AddWindow(self.staticText11, 0, border=10, flag=wx.BOTTOM|wx.LEFT) parent.AddWindow(self.ContentDescription, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT) def _init_coll_MiscellaneousPanelSizer_Growables(self, parent): @@ -2754,11 +2816,11 @@ def _init_sizers(self): self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.ProjectPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=5, vgap=15) - self.AuthorPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=4, vgap=15) - self.GraphicsPanelSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=4, vgap=5) - self.GraphicsPageSizeSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=5) - self.MiscellaneousPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=15) + self.ProjectPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=5, vgap=15) + self.AuthorPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=15) + self.GraphicsPanelSizer = wx.FlexGridSizer(cols=1, hgap=5, rows=4, vgap=5) + self.GraphicsPageSizeSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5) + self.MiscellaneousPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15) self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) @@ -2783,7 +2845,7 @@ wx.Dialog.__init__(self, id=ID_PROJECTDIALOG, name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(500, 350), style=wx.DEFAULT_DIALOG_STYLE, - title='Project properties') + title=_('Project properties')) self.SetClientSize(wx.Size(500, 350)) self.MainNotebook = wx.Notebook(id=ID_PROJECTDIALOGMAINNOTEBOOK, @@ -2797,46 +2859,46 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText1 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT1, - label='Project Name (required):', name='staticText1', parent=self.ProjectPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Project Name (required):'), name='staticText1', parent=self.ProjectPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ProjectName = wx.TextCtrl(id=ID_PROJECTDIALOGPROJECTNAME, name='ProjectName', parent=self.ProjectPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText2 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT2, - label='Project Version (optional):', name='staticText2', parent=self.ProjectPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Project Version (optional):'), name='staticText2', parent=self.ProjectPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ProjectVersion = wx.TextCtrl(id=ID_PROJECTDIALOGPROJECTVERSION, name='ProjectVersion', parent=self.ProjectPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText3 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT3, - label='Product Name (required):', name='staticText3', parent=self.ProjectPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Product Name (required):'), name='staticText3', parent=self.ProjectPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ProductName = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTNAME, name='ProductName', parent=self.ProjectPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText4 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT4, - label='Product Version (required):', name='staticText4', parent=self.ProjectPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Product Version (required):'), name='staticText4', parent=self.ProjectPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ProductVersion = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTVERSION, name='ProductVersion', parent=self.ProjectPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText5 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT5, - label='Product Release (optional):', name='staticText5', parent=self.ProjectPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Product Release (optional):'), name='staticText5', parent=self.ProjectPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ProductRelease = wx.TextCtrl(id=ID_PROJECTDIALOGPRODUCTRELEASE, name='ProductRelease', parent=self.ProjectPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.MainNotebook.AddPage(self.ProjectPanel, "Project") + self.MainNotebook.AddPage(self.ProjectPanel, _("Project")) # Author Panel elements @@ -2845,38 +2907,38 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText6 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT6, - label='Company Name (required):', name='staticText6', parent=self.AuthorPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Company Name (required):'), name='staticText6', parent=self.AuthorPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.CompanyName = wx.TextCtrl(id=ID_PROJECTDIALOGCOMPANYNAME, name='CompanyName', parent=self.AuthorPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText7 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT7, - label='Company URL (optional):', name='staticText7', parent=self.AuthorPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Company URL (optional):'), name='staticText7', parent=self.AuthorPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.CompanyURL = wx.TextCtrl(id=ID_PROJECTDIALOGCOMPANYURL, name='CompanyURL', parent=self.AuthorPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText8 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT8, - label='Author Name (optional):', name='staticText8', parent=self.AuthorPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Author Name (optional):'), name='staticText8', parent=self.AuthorPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.AuthorName = wx.TextCtrl(id=ID_PROJECTDIALOGAUTHORNAME, name='AuthorName', parent=self.AuthorPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText9 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT9, - label='Organization (optional):', name='staticText9', parent=self.AuthorPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Organization (optional):'), name='staticText9', parent=self.AuthorPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.Organization = wx.TextCtrl(id=ID_PROJECTDIALOGORGANIZATION, name='Organization', parent=self.AuthorPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) - self.MainNotebook.AddPage(self.AuthorPanel, "Author") + self.MainNotebook.AddPage(self.AuthorPanel, _("Author")) # Graphics Panel elements @@ -2885,40 +2947,40 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText12 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT12, - label='Page Size (optional):', name='staticText12', parent=self.GraphicsPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Page Size (optional):'), name='staticText12', parent=self.GraphicsPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.staticText13 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT13, - label='Width:', name='staticText13', parent=self.GraphicsPanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Width:'), name='staticText13', parent=self.GraphicsPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.PageWidth = wx.SpinCtrl(id=ID_PROJECTDIALOGPAGEWIDTH, name='PageWidth', parent=self.GraphicsPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0, min=0, max=2**16) self.staticText14 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT14, - label='Height:', name='staticText14', parent=self.GraphicsPanel, - pos=wx.Point(0, 0), size=wx.Size(150, 17), style=0) + label=_('Height:'), name='staticText14', parent=self.GraphicsPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.PageHeight = wx.SpinCtrl(id=ID_PROJECTDIALOGPAGEHEIGHT, name='PageHeight', parent=self.GraphicsPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0, min=0, max=2**16) self.staticText15 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT15, - label='Scaling:', name='staticText15', parent=self.GraphicsPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Scaling:'), name='staticText15', parent=self.GraphicsPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ScalingNotebook = wx.Notebook(id=ID_PROJECTDIALOGSCALINGNOTEBOOK, name='ScalingNotebook', parent=self.GraphicsPanel, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) self.Scalings = {} - for language in ["FBD", "LD", "SFC"]: + for language, translation in [("FBD",_("FBD")), ("LD",_("LD")), ("SFC",_("SFC"))]: window = ScalingPanel(self.ScalingNotebook) self.Scalings[language] = window - self.ScalingNotebook.AddPage(window, language) - - self.MainNotebook.AddPage(self.GraphicsPanel, "Graphics") + self.ScalingNotebook.AddPage(window, translation) + + self.MainNotebook.AddPage(self.GraphicsPanel, _("Graphics")) # Miscellaneous Panel elements @@ -2927,22 +2989,22 @@ size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) self.staticText10 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT10, - label='Language (optional):', name='staticText10', parent=self.MiscellaneousPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Language (optional):'), name='staticText10', parent=self.MiscellaneousPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.Language = wx.ComboBox(id=ID_PROJECTDIALOGLANGUAGE, name='Language', parent=self.MiscellaneousPanel, pos=wx.Point(0, 0), size=wx.Size(0, 28), style=wx.CB_READONLY) self.staticText11 = wx.StaticText(id=ID_PROJECTDIALOGSTATICTEXT11, - label='Content Description (optional):', name='staticText11', parent=self.MiscellaneousPanel, - pos=wx.Point(0, 0), size=wx.Size(200, 17), style=0) + label=_('Content Description (optional):'), name='staticText11', parent=self.MiscellaneousPanel, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ContentDescription = wx.TextCtrl(id=ID_PROJECTDIALOGCONTENTDESCRIPTION, name='ContentDescription', parent=self.MiscellaneousPanel, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=wx.TE_MULTILINE) - self.MainNotebook.AddPage(self.MiscellaneousPanel, "Miscellaneous") + self.MainNotebook.AddPage(self.MiscellaneousPanel, _("Miscellaneous")) self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) @@ -2952,7 +3014,7 @@ def __init__(self, parent): self._init_ctrls(parent) - languages = ["", "en-US", "fr-FR"] + languages = ["", "en-US", "fr-FR", "zh-CN"] for language in languages: self.Language.Append(language) @@ -2976,7 +3038,7 @@ text += " and %s"%item else: text += ", %s"%item - message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -3053,7 +3115,7 @@ else: 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) @@ -3068,19 +3130,19 @@ def OnOK(self, event): datatype_name = self.GetSizer().GetItem(1).GetWindow().GetValue() if datatype_name == "": - message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(datatype_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%datatype_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif datatype_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%datatype_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif datatype_name.upper() in self.DataTypeNames: - message = wx.MessageDialog(self, "\"%s\" data type already exists!"%datatype_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" data type already exists!")%datatype_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -3101,6 +3163,21 @@ ID_POUDIALOGSTATICTEXT2, ID_POUDIALOGSTATICTEXT3, ] = [wx.NewId() for _init_ctrls in range(7)] +def GetTransitionLanguages(): + _ = lambda x : x + return [_("IL"), _("ST"), _("LD"), _("FBD")] +TRANSITION_LANGUAGES_DICT = dict([(_(language), language) for language in GetTransitionLanguages()]) + +def GetPouTypes(): + _ = lambda x : x + return [_("function"), _("functionBlock"), _("program")] +POU_TYPES_DICT = dict([(_(pou_type), pou_type) for pou_type in GetPouTypes()]) + +def GetPouLanguages(): + _ = lambda x : x + return [_("IL"), _("ST"), _("LD"), _("FBD"), _("SFC")] +POU_LANGUAGES_DICT = dict([(_(language), language) for language in GetPouLanguages()]) + class PouDialog(wx.Dialog): if wx.VERSION < (2, 6, 0): def Bind(self, event, function, id = None): @@ -3118,11 +3195,11 @@ parent.AddGrowableRow(0) def _init_coll_MainSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.PouName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.PouType, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText3, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText3, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW) def _init_coll_MainSizer_Growables(self, parent): @@ -3130,7 +3207,7 @@ def _init_sizers(self): self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=3, vgap=15) + self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=15) self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) @@ -3143,20 +3220,20 @@ wx.Dialog.__init__(self, id=ID_POUDIALOG, name='PouDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE, - title='Create a new POU') + title=_('Create a new POU')) self.SetClientSize(wx.Size(300, 200)) self.staticText1 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT1, - label='POU Name:', name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) + label=_('POU Name:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.PouName = wx.TextCtrl(id=ID_POUDIALOGPOUNAME, name='POUName', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText2 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT2, - label='POU Type:', name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) + label=_('POU Type:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.PouType = wx.ComboBox(id=ID_POUDIALOGPOUTYPE, name='POUType', parent=self, pos=wx.Point(0, 0), @@ -3164,8 +3241,8 @@ self.Bind(wx.EVT_COMBOBOX, self.OnTypeChanged, id=ID_POUDIALOGPOUTYPE) self.staticText3 = wx.StaticText(id=ID_POUDIALOGSTATICTEXT3, - label='Language:', name='staticText3', parent=self, - pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) + label=_('Language:'), name='staticText3', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.Language = wx.ComboBox(id=ID_POUDIALOGLANGUAGE, name='Language', parent=self, pos=wx.Point(0, 0), @@ -3179,10 +3256,10 @@ def __init__(self, parent, pou_type = None): self._init_ctrls(parent) - for option in ["function", "functionBlock", "program"]: - self.PouType.Append(option) + for option in GetPouTypes(): + self.PouType.Append(_(option)) if pou_type is not None: - self.PouType.SetStringSelection(pou_type) + self.PouType.SetStringSelection(_(pou_type)) self.RefreshLanguage() self.PouNames = [] @@ -3192,37 +3269,37 @@ error = [] pou_name = self.PouName.GetValue() if pou_name == "": - error.append("POU Name") - if self.PouType.GetStringSelection() == "": - error.append("POU Type") - if self.Language.GetStringSelection() == "": - error.append("Language") + error.append(_("POU Name")) + if self.PouType.GetSelection() == -1: + error.append(_("POU Type")) + if self.Language.GetSelection() == -1: + error.append(_("Language")) if len(error) > 0: text = "" for i, item in enumerate(error): if i == 0: text += item elif i == len(error) - 1: - text += " and %s"%item + text += _(" and %s")%item else: - text += ", %s"%item - message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) + text += _(", %s")%item + message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(pou_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%pou_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif pou_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%pou_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif pou_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "\"%s\" pou already exists!"%pou_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" pou already exists!")%pou_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif pou_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, "A pou has an element with \"%s\" for name. It can generate a conflict. Do you wish to continue?"%pou_name, "Warning", wx.YES_NO|wx.ICON_EXCLAMATION) + message = wx.MessageDialog(self, _("A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?")%pou_name, _("Warning"), wx.YES_NO|wx.ICON_EXCLAMATION) result = message.ShowModal() message.Destroy() if result == wx.ID_YES: @@ -3231,13 +3308,13 @@ self.EndModal(wx.ID_OK) def RefreshLanguage(self): - selection = self.Language.GetStringSelection() + selection = POU_LANGUAGES_DICT.get(self.Language.GetStringSelection(), "") self.Language.Clear() - for option in ["IL","ST","LD","FBD","SFC"]: - if option != "SFC" or self.PouType.GetStringSelection() != "function": - self.Language.Append(option) - if self.Language.FindString(selection) != wx.NOT_FOUND: - self.Language.SetStringSelection(selection) + for language in GetPouLanguages(): + if language != "SFC" or POU_TYPES_DICT[self.PouType.GetStringSelection()] != "function": + self.Language.Append(language) + if self.Language.FindString(_(selection)) != wx.NOT_FOUND: + self.Language.SetStringSelection(_(selection)) def OnTypeChanged(self, event): self.RefreshLanguage() @@ -3254,15 +3331,15 @@ if item == "pouName": self.PouName.SetValue(value) elif item == "pouType": - self.PouType.SetStringSelection(value) + self.PouType.SetStringSelection(_(value)) elif item == "language": - self.Language.SetStringSelection(value) + self.Language.SetStringSelection(_(POU_LANGUAGES_DICT)) def GetValues(self): values = {} values["pouName"] = self.PouName.GetValue() - values["pouType"] = self.PouType.GetStringSelection() - values["language"] = self.Language.GetStringSelection() + values["pouType"] = POU_TYPES_DICT[self.PouType.GetStringSelection()] + values["language"] = POU_LANGUAGES_DICT[self.Language.GetStringSelection()] return values @@ -3275,6 +3352,11 @@ ID_POUTRANSITIONDIALOGSTATICTEXT2, ] = [wx.NewId() for _init_ctrls in range(5)] +def GetTransitionLanguages(): + _ = lambda x : x + return [_("IL"), _("ST"), _("LD"), _("FBD")] +TRANSITION_LANGUAGES_DICT = dict([(_(language), language) for language in GetTransitionLanguages()]) + class PouTransitionDialog(wx.Dialog): if wx.VERSION < (2, 6, 0): def Bind(self, event, function, id = None): @@ -3292,9 +3374,9 @@ parent.AddGrowableRow(0) def _init_coll_MainSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.TransitionName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW) def _init_coll_MainSizer_Growables(self, parent): @@ -3302,7 +3384,7 @@ def _init_sizers(self): self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=15) + self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15) self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) @@ -3315,20 +3397,20 @@ wx.Dialog.__init__(self, id=ID_POUTRANSITIONDIALOG, name='PouTransitionDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(350, 200), style=wx.DEFAULT_DIALOG_STYLE, - title='Create a new transition') + title=_('Create a new transition')) self.SetClientSize(wx.Size(350, 160)) self.staticText1 = wx.StaticText(id=ID_POUTRANSITIONDIALOGSTATICTEXT1, - label='Transition Name:', name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(120, 17), style=0) + label=_('Transition Name:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.TransitionName = wx.TextCtrl(id=ID_POUTRANSITIONDIALOGTRANSITIONNAME, name='TransitionName', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText2 = wx.StaticText(id=ID_POUTRANSITIONDIALOGSTATICTEXT2, - label='Language:', name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(120, 17), style=0) + label=_('Language:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.Language = wx.ComboBox(id=ID_POUTRANSITIONDIALOGLANGUAGE, name='Language', parent=self, pos=wx.Point(0, 0), @@ -3342,8 +3424,8 @@ def __init__(self, parent): self._init_ctrls(parent) - for option in ["IL","ST","LD","FBD"]: - self.Language.Append(option) + for language in GetTransitionLanguages(): + self.Language.Append(_(language)) self.PouNames = [] self.PouElementNames = [] @@ -3352,35 +3434,35 @@ error = [] transition_name = self.TransitionName.GetValue() if self.TransitionName.GetValue() == "": - error.append("Transition Name") - if self.Language.GetStringSelection() == "": - error.append("Language") + error.append(_("Transition Name")) + if self.Language.GetSelection() == -1: + error.append(_("Language")) if len(error) > 0: text = "" for i, item in enumerate(error): if i == 0: text += item elif i == len(error) - 1: - text += " and %s"%item + text += _(" and %s")%item else: - text += ", %s"%item - message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) + text += _(", %s")%item + message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(transition_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%transition_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif transition_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%transition_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif transition_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "A pou with \"%s\" for name exists!"%transition_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif transition_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, "\"%s\" element for this pou already exists!"%transition_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%transition_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -3397,12 +3479,12 @@ if item == "transitionName": self.TransitionName.SetValue(value) elif item == "language": - self.Language.SetStringSelection(value) + self.Language.SetSelection(_(value)) def GetValues(self): values = {} values["transitionName"] = self.TransitionName.GetValue() - values["language"] = self.Language.GetStringSelection() + values["language"] = TRANSITION_LANGUAGES_DICT[self.Language.GetStringSelection()] return values #------------------------------------------------------------------------------- @@ -3414,6 +3496,11 @@ ID_POUACTIONDIALOGSTATICTEXT2, ] = [wx.NewId() for _init_ctrls in range(5)] +def GetActionLanguages(): + _ = lambda x : x + return [_("IL"), _("ST"), _("LD"), _("FBD")] +ACTION_LANGUAGES_DICT = dict([(_(language), language) for language in GetActionLanguages()]) + class PouActionDialog(wx.Dialog): if wx.VERSION < (2, 6, 0): def Bind(self, event, function, id = None): @@ -3431,9 +3518,9 @@ parent.AddGrowableRow(0) def _init_coll_MainSizer_Items(self, parent): - parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText1, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.ActionName, 0, border=0, flag=wx.GROW) - parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP) + parent.AddWindow(self.staticText2, 0, border=4, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP) parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW) def _init_coll_MainSizer_Growables(self, parent): @@ -3441,7 +3528,7 @@ def _init_sizers(self): self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) - self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=2, vgap=15) + self.MainSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15) self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) @@ -3454,20 +3541,20 @@ wx.Dialog.__init__(self, id=ID_POUACTIONDIALOG, name='PouActionDialog', parent=prnt, pos=wx.Point(376, 223), size=wx.Size(320, 200), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, - title='Create a new action') + title=_('Create a new action')) self.SetClientSize(wx.Size(320, 160)) self.staticText1 = wx.StaticText(id=ID_POUACTIONDIALOGSTATICTEXT1, - label='Action Name:', name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) + label=_('Action Name:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.ActionName = wx.TextCtrl(id=ID_POUACTIONDIALOGACTIONNAME, name='ActionName', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0) self.staticText2 = wx.StaticText(id=ID_POUACTIONDIALOGSTATICTEXT2, - label='Language:', name='staticText2', parent=self, - pos=wx.Point(0, 0), size=wx.Size(100, 17), style=0) + label=_('Language:'), name='staticText2', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) self.Language = wx.ComboBox(id=ID_POUACTIONDIALOGLANGUAGE, name='Language', parent=self, pos=wx.Point(0, 0), @@ -3481,8 +3568,8 @@ def __init__(self, parent): self._init_ctrls(parent) - for option in ["IL","ST","LD","FBD"]: - self.Language.Append(option) + for option in GetActionLanguages(): + self.Language.Append(_(option)) self.PouNames = [] self.PouElementNames = [] @@ -3491,35 +3578,35 @@ error = [] action_name = self.ActionName.GetValue() if action_name == "": - error.append("Action Name") - if self.Language.GetStringSelection() == "": - error.append("Language") + error.append(_("Action Name")) + if self.Language.GetSelection() == -1: + error.append(_("Language")) if len(error) > 0: text = "" for i, item in enumerate(error): if i == 0: text += item elif i == len(error) - 1: - text += " and %s"%item + text += _(" and %s")%item else: - text += ", %s"%item - message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR) + text += _(", %s")%item + message = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(action_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%action_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif action_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%action_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif action_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "A pou with \"%s\" for name exists!"%action_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif action_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, "\"%s\" element for this pou already exists!"%action_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" element for this pou already exists!")%action_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() else: @@ -3536,12 +3623,12 @@ if item == "actionName": self.ActionName.SetValue(value) elif item == "language": - self.Language.SetStringSelection(value) + self.Language.SetStringSelection(_(value)) def GetValues(self): values = {} values["actionName"] = self.ActionName.GetValue() - values["language"] = self.Language.GetStringSelection() + values["language"] = ACTION_LANGUAGES_DICT[self.Language.GetStringSelection()] return values #------------------------------------------------------------------------------- @@ -3557,7 +3644,7 @@ else: event(self, function) - def __init__(self, parent, message, caption = "Please enter configuration name", defaultValue = "", + def __init__(self, parent, message, caption = _("Please enter configuration name"), defaultValue = "", style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) @@ -3574,23 +3661,23 @@ def OnOK(self, event): config_name = self.GetSizer().GetItem(1).GetWindow().GetValue() if config_name == "": - message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(config_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%config_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif config_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%config_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif config_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%config_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%config_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif config_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, "A pou has an element with \"%s\" for name. It can generate a conflict. Do you wish to continue?"%config_name, "Warning", wx.YES_NO|wx.ICON_EXCLAMATION) + message = wx.MessageDialog(self, _("A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?")%config_name, _("Warning"), wx.YES_NO|wx.ICON_EXCLAMATION) result = message.ShowModal() message.Destroy() if result == wx.ID_YES: @@ -3620,7 +3707,7 @@ else: event(self, function) - def __init__(self, parent, message, caption = "Please enter resource name", defaultValue = "", + def __init__(self, parent, message, caption = _("Please enter resource name"), defaultValue = "", style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) @@ -3637,23 +3724,23 @@ def OnOK(self, event): resource_name = self.GetSizer().GetItem(1).GetWindow().GetValue() if resource_name == "": - message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("You must type a name!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif not TestIdentifier(resource_name): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%resource_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif resource_name.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%resource_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif resource_name.upper() in self.PouNames: - message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%resource_name, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%resource_name, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() elif resource_name.upper() in self.PouElementNames: - message = wx.MessageDialog(self, "A pou has an element with \"%s\" for name. It can generate a conflict. Do you wish to continue?"%resource_name, "Warning", wx.YES_NO|wx.ICON_EXCLAMATION) + message = wx.MessageDialog(self, _("A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?")%resource_name, _("Warning"), wx.YES_NO|wx.ICON_EXCLAMATION) result = message.ShowModal() message.Destroy() if result == wx.ID_YES: @@ -3755,6 +3842,25 @@ # Variables Editor Panel #------------------------------------------------------------------------------- +def GetVariableTableColnames(location): + _ = lambda x : x + if location: + return ["#", _("Name"), _("Class"), _("Type"), _("Location"), _("Initial Value"), _("Retain"), _("Constant")] + return ["#", _("Name"), _("Class"), _("Type"), _("Initial Value"), _("Retain"), _("Constant")] + +def GetAlternativeOptions(): + _ = lambda x : x + return [_("Yes"), _("No")] +ALTERNATIVE_OPTIONS_DICT = dict([(_(option), option) for option in GetAlternativeOptions()]) + +def GetFilterChoiceTransfer(): + _ = lambda x : x + return {_("All"): _("All"), _("Interface"): _("Interface"), + _(" Input"): _("Input"), _(" Output"): _("Output"), _(" InOut"): _("InOut"), + _(" External"): _("External"), _("Variables"): _("Variables"), _(" Local"): _("Local"), + _(" Temp"): _("Temp"), _("Global"): _("Global")}#, _("Access") : _("Access")} +VARIABLE_CLASSES_DICT = dict([(_(_class), _class) for _class in GetFilterChoiceTransfer().itervalues()]) + class VariableTable(wx.grid.PyGridTableBase): """ @@ -3780,25 +3886,34 @@ def GetNumberRows(self): return len(self.data) - def GetColLabelValue(self, col): + def GetColLabelValue(self, col, translate=True): if col < len(self.colnames): + if translate: + return _(self.colnames[col]) return self.colnames[col] - def GetRowLabelValues(self, row): + def GetRowLabelValues(self, row, translate=True): return row def GetValue(self, row, col): if row < self.GetNumberRows(): if col == 0: return self.data[row]["Number"] - name = str(self.data[row].get(self.GetColLabelValue(col), "")) - return name + colname = self.GetColLabelValue(col, False) + value = str(self.data[row].get(colname, "")) + if colname in ["Class", "Retain", "Constant"]: + return _(value) + return value def SetValue(self, row, col, value): if col < len(self.colnames): - colname = self.GetColLabelValue(col) + colname = self.GetColLabelValue(col, False) if colname == "Name": self.old_value = self.data[row][colname] + elif colname == "Class": + value = VARIABLE_CLASSES_DICT[value] + elif colname in ["Retain", "Constant"]: + value = ALTERNATIVE_OPTIONS_DICT[value] self.data[row][colname] = value def GetValueByName(self, row, colname): @@ -3854,13 +3969,11 @@ Otherwise default to the default renderer. """ - typelist = None - accesslist = None for row in range(self.GetNumberRows()): for col in range(self.GetNumberCols()): editor = None renderer = None - colname = self.GetColLabelValue(col) + colname = self.GetColLabelValue(col, False) if col != 0 and self.GetValueByName(row, "Edit"): grid.SetReadOnly(row, col, False) if colname == "Name": @@ -3888,10 +4001,10 @@ excluded.extend(["Input","Output","InOut"]) if self.Parent.IsFunctionBlockType(self.data[row]["Type"]): excluded.extend(["Local","Temp"]) - editor.SetParameters(",".join([choice for choice in self.Parent.ClassList if choice not in excluded])) + editor.SetParameters(",".join([_(choice) for choice in self.Parent.ClassList if choice not in excluded])) elif colname in ["Retain", "Constant"]: editor = wx.grid.GridCellChoiceEditor() - editor.SetParameters(self.Parent.OptionList) + editor.SetParameters(",".join(map(_, self.Parent.OptionList))) elif colname == "Type": editor = wx.grid.GridCellTextEditor() else: @@ -3950,21 +4063,21 @@ col = self.ParentWindow.VariablesGrid.XToCol(x) row = self.ParentWindow.VariablesGrid.YToRow(y - self.ParentWindow.VariablesGrid.GetColLabelSize()) if col != wx.NOT_FOUND and row != wx.NOT_FOUND: - if self.ParentWindow.Table.GetColLabelValue(col) != "Location": + if self.ParentWindow.Table.GetColLabelValue(col, False) != "Location": return message = None if not self.ParentWindow.Table.GetValueByName(row, "Edit"): - message = "Can't affect a location to a function block instance" + message = _("Can't affect a location to a function block instance") elif self.ParentWindow.Table.GetValueByName(row, "Class") not in ["Local", "Global"]: - message = "Can affect a location only to local or global variables" + message = _("Can affect a location only to local or global variables") else: try: values = eval(data) except: - message = "Invalid value \"%s\" for location"%data + message = _("Invalid value \"%s\" for location")%data values = None if not isinstance(values, TupleType): - message = "Invalid value \"%s\" for location"%data + message = _("Invalid value \"%s\" for location")%data values = None if values is not None and values[1] == "location": location = values[0] @@ -3973,20 +4086,20 @@ message = None if location.startswith("%"): if base_type != values[2]: - message = "Incompatible data types between \"%s\" and \"%s\""%(values[2], variable_type) + message = _("Incompatible data types between \"%s\" and \"%s\"")%(values[2], variable_type) else: self.ParentWindow.Table.SetValue(row, col, location) self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid) self.ParentWindow.SaveValues() else: if location[0].isdigit() and base_type != "BOOL": - message = "Incompatible size of data between \"%s\" and \"BOOL\""%location + message = _("Incompatible size of data between \"%s\" and \"BOOL\"")%location elif location[0] not in LOCATIONDATATYPES: - message = "Unrecognized data size \"%s\""%location[0] + 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 \"%s\" and \"%s\"")%(location, variable_type) else: - dialog = wx.SingleChoiceDialog(self.ParentWindow, "Select a variable class:", "Variable class", ["Input", "Output", "Memory"], wx.OK|wx.CANCEL) + dialog = wx.SingleChoiceDialog(self.ParentWindow, _("Select a variable class:"), _("Variable class"), ["Input", "Output", "Memory"], wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: selected = dialog.GetSelection() if selected == 0: @@ -4003,7 +4116,7 @@ wx.CallAfter(self.ShowMessage, message) def ShowMessage(self, message): - message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() @@ -4111,8 +4224,8 @@ self.ControlPanel.SetScrollRate(0, 10) self.staticText1 = wx.StaticText(id=ID_VARIABLEEDITORPANELSTATICTEXT1, - label='Return Type:', name='staticText1', parent=self.ControlPanel, - pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0) + label=_('Return Type:'), name='staticText1', parent=self.ControlPanel, + pos=wx.Point(0, 0), size=wx.Size(145, 17), style=0) self.ReturnType = wx.ComboBox(id=ID_VARIABLEEDITORPANELRETURNTYPE, name='ReturnType', parent=self.ControlPanel, pos=wx.Point(0, 0), @@ -4120,22 +4233,22 @@ self.Bind(wx.EVT_COMBOBOX, self.OnReturnTypeChanged, id=ID_VARIABLEEDITORPANELRETURNTYPE) self.staticText2 = wx.StaticText(id=ID_VARIABLEEDITORPANELSTATICTEXT2, - label='Class Filter:', name='staticText2', parent=self.ControlPanel, - pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0) + label=_('Class Filter:'), name='staticText2', parent=self.ControlPanel, + pos=wx.Point(0, 0), size=wx.Size(145, 17), style=0) self.ClassFilter = wx.ComboBox(id=ID_VARIABLEEDITORPANELCLASSFILTER, name='ClassFilter', parent=self.ControlPanel, pos=wx.Point(0, 0), size=wx.Size(145, 28), style=wx.CB_READONLY) self.Bind(wx.EVT_COMBOBOX, self.OnClassFilter, id=ID_VARIABLEEDITORPANELCLASSFILTER) - self.AddButton = wx.Button(id=ID_VARIABLEEDITORPANELADDBUTTON, label='Add', + self.AddButton = wx.Button(id=ID_VARIABLEEDITORPANELADDBUTTON, label=_('Add'), name='AddButton', parent=self.ControlPanel, pos=wx.Point(0, 0), - size=wx.Size(72, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_VARIABLEEDITORPANELADDBUTTON) - self.DeleteButton = wx.Button(id=ID_VARIABLEEDITORPANELDELETEBUTTON, label='Delete', + self.DeleteButton = wx.Button(id=ID_VARIABLEEDITORPANELDELETEBUTTON, label=_('Delete'), name='DeleteButton', parent=self.ControlPanel, pos=wx.Point(0, 0), - size=wx.Size(72, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_VARIABLEEDITORPANELDELETEBUTTON) self.UpButton = wx.Button(id=ID_VARIABLEEDITORPANELUPBUTTON, label='^', @@ -4158,10 +4271,7 @@ self.Filter = "All" self.FilterChoices = [] - self.FilterChoiceTransfer = {"All" : "All", "Interface" : "Interface", - " Input" : "Input", " Output" : "Output", " InOut" : "InOut", - " External" : "External", "Variables" : "Variables", " Local" : "Local", - " Temp" : "Temp", "Global" : "Global", "Access" : "Access"} + self.FilterChoiceTransfer = GetFilterChoiceTransfer() if element_type in ["config", "resource"]: self.DefaultTypes = {"All" : "Global"} @@ -4170,27 +4280,30 @@ self.DefaultTypes = {"All" : "Local", "Interface" : "Input", "Variables" : "Local"} self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No", "Edit" : True} if element_type in ["config", "resource"] or element_type in ["program", "transition", "action"]: - self.Table = VariableTable(self, [], ["#", "Name", "Class", "Type", "Location", "Initial Value", "Retain", "Constant"]) + self.Table = VariableTable(self, [], GetVariableTableColnames(True)) if element_type not in ["config", "resource"]: - self.FilterChoices = ["All","Interface"," Input"," Output"," InOut"," External","Variables"," Local"," Temp","Global","Access"] + self.FilterChoices = ["All", "Interface", " Input", " Output", " InOut", " External", "Variables", " Local", " Temp"]#,"Access"] else: - self.FilterChoices = ["All","Global","Access"] + self.FilterChoices = ["All", "Global"]#,"Access"] self.ColSizes = [40, 80, 70, 80, 80, 80, 60, 70] self.ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER] else: - self.Table = VariableTable(self, [], ["#", "Name", "Class", "Type", "Initial Value", "Retain", "Constant"]) - self.FilterChoices = ["All","Interface"," Input"," Output"," InOut"," External","Variables"," Local"," Temp"] + self.Table = VariableTable(self, [], GetVariableTableColnames(False)) + if element_type == "function": + self.FilterChoices = ["All", "Interface", " Input", " Output", " InOut", "Variables", " Local", " Temp"] + else: + self.FilterChoices = ["All", "Interface", " Input", " Output", " InOut", " External", "Variables", " Local", " Temp"] self.ColSizes = [40, 120, 70, 80, 120, 60, 70] self.ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER] for choice in self.FilterChoices: - self.ClassFilter.Append(choice) + self.ClassFilter.Append(_(choice)) reverse_transfer = {} for filter, choice in self.FilterChoiceTransfer.items(): reverse_transfer[choice] = filter - self.ClassFilter.SetStringSelection(reverse_transfer[self.Filter]) + self.ClassFilter.SetStringSelection(_(reverse_transfer[self.Filter])) self.RefreshTypeList() - self.OptionList = "Yes,No" + self.OptionList = GetAlternativeOptions() if element_type == "function": for base_type in self.Controler.GetBaseTypes(): @@ -4207,7 +4320,8 @@ attr = wx.grid.GridCellAttr() attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) self.VariablesGrid.SetColAttr(col, attr) - self.VariablesGrid.SetColSize(col, self.ColSizes[col]) + self.VariablesGrid.SetColMinimalWidth(col, self.ColSizes[col]) + self.VariablesGrid.AutoSizeColumn(col, False) def SetTagName(self, tagname): self.TagName = tagname @@ -4327,22 +4441,22 @@ value = self.Table.GetValue(row, col) if colname == "Name" and value != "": if not TestIdentifier(value): - message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%value, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is not a valid identifier!")%value, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Veto() elif value.upper() in IEC_KEYWORDS: - message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%value, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("\"%s\" is a keyword. It can't be used!")%value, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Veto() elif value.upper() in self.PouNames: - message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%value, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A pou with \"%s\" as name exists!")%value, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Veto() elif value.upper() in [var["Name"].upper() for var in self.Values if var != self.Table.data[row]]: - message = wx.MessageDialog(self, "A variable with \"%s\" as name exists in this pou!"%value, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self, _("A variable with \"%s\" as name already exists in this pou!")%value, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Veto() @@ -4374,13 +4488,13 @@ new_id = wx.NewId() AppendMenu(base_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type) self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(base_type), id=new_id) - type_menu.AppendMenu(wx.NewId(), "Base Types", base_menu) + type_menu.AppendMenu(wx.NewId(), _("Base Types"), base_menu) datatype_menu = wx.Menu(title='') for datatype in self.Controler.GetDataTypes(basetypes = False, debug = self.ParentWindow.Debug): new_id = wx.NewId() AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id) - type_menu.AppendMenu(wx.NewId(), "User Data Types", datatype_menu) + type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu) functionblock_menu = wx.Menu(title='') bodytype = self.Controler.GetEditedElementBodyType(self.TagName, self.ParentWindow.Debug) pouname, poutype = self.Controler.GetEditedElementType(self.TagName, self.ParentWindow.Debug) @@ -4389,7 +4503,7 @@ new_id = wx.NewId() AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type) self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id) - type_menu.AppendMenu(wx.NewId(), "Function Block Types", functionblock_menu) + type_menu.AppendMenu(wx.NewId(), _("Function Block Types"), functionblock_menu) rect = self.VariablesGrid.BlockToDeviceRect((row, col), (row, col)) self.VariablesGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.VariablesGrid.GetColLabelSize()) event.Veto() @@ -4495,6 +4609,10 @@ # Debug Variables Panel #------------------------------------------------------------------------------- +def GetDebugVariablesTableColnames(): + _ = lambda x : x + return [_("Variable"), _("Value")] + class VariableTableItem(DebugDataConsumer): def __init__(self, parent, variable, value): @@ -4545,21 +4663,23 @@ def GetNumberRows(self): return len(self.data) - def GetColLabelValue(self, col): + def GetColLabelValue(self, col, translate=True): if col < len(self.colnames): + if translate: + return _(self.colnames[col]) return self.colnames[col] - def GetRowLabelValues(self, row): + def GetRowLabelValues(self, row, translate=True): return row def GetValue(self, row, col): if row < self.GetNumberRows(): - return self.GetValueByName(row, self.GetColLabelValue(col)) + return self.GetValueByName(row, self.GetColLabelValue(col, False)) return "" def SetValue(self, row, col, value): if col < len(self.colnames): - self.SetValueByName(row, self.GetColLabelValue(col), value) + self.SetValueByName(row, self.GetColLabelValue(col, False), value) def GetValueByName(self, row, colname): if row < self.GetNumberRows(): @@ -4661,10 +4781,10 @@ try: values = eval(data) except: - message = "Invalid value \"%s\" for debug variable"%data + message = _("Invalid value \"%s\" for debug variable")%data values = None if not isinstance(values, TupleType): - message = "Invalid value \"%s\" for debug variable"%data + message = _("Invalid value \"%s\" for debug variable")%data values = None if values is not None and values[1] == "debug": self.ParentWindow.InsertValue(row, values[0]) @@ -4672,7 +4792,7 @@ wx.CallAfter(self.ShowMessage, message) def ShowMessage(self, message): - message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() @@ -4739,7 +4859,7 @@ size=wx.Size(32, 32), style=0) self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_DEBUGVARIABLEPANELDOWNBUTTON) - self.DeleteButton = wx.Button(id=ID_DEBUGVARIABLEPANELDELETEBUTTON, label='Delete', + self.DeleteButton = wx.Button(id=ID_DEBUGVARIABLEPANELDELETEBUTTON, label=_('Delete'), name='DeleteButton', parent=self, pos=wx.Point(0, 0), size=wx.Size(72, 32), style=0) self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_DEBUGVARIABLEPANELDELETEBUTTON) @@ -4752,7 +4872,7 @@ self.Controler = controler self.HasNewData = False - self.Table = DebugVariableTable(self, [], ["Variable", "Value"]) + self.Table = DebugVariableTable(self, [], GetDebugVariablesTableColnames()) self.VariablesGrid.SetTable(self.Table) self.VariablesGrid.SetRowLabelSize(0) @@ -4877,7 +4997,7 @@ block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:]) text_width, text_height = dc.GetTextExtent(block_name) dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin) - dc.DrawText("Page: %d" % page, margin_left, margin_top + area_height + self.TextMargin) + dc.DrawText(_("Page: %d") % page, margin_left, margin_top + area_height + self.TextMargin) # Calculate the position on the DC for centering the graphic posX = area_width * ((page - 1) % self.PageGrid[0]) @@ -4907,12 +5027,12 @@ def Display_Exception_Dialog(e_type,e_value,e_tb): trcbck_lst = [] for i,line in enumerate(traceback.extract_tb(e_tb)): - trcbck = " " + str(i+1) + ". " + trcbck = " " + str(i+1) + _(". ") if line[0].find(os.getcwd()) == -1: - trcbck += "file : " + str(line[0]) + ", " - else: - trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", " - trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2]) + trcbck += _("file : ") + str(line[0]) + _(", ") + else: + trcbck += _("file : ") + str(line[0][len(os.getcwd()):]) + _(", ") + trcbck += _("line : ") + str(line[1]) + _(", ") + _("function : ") + str(line[2]) trcbck_lst.append(trcbck) # Allow clicking.... @@ -4921,7 +5041,7 @@ cap.ReleaseMouse() dlg = wx.SingleChoiceDialog(None, - """ + _(""" An error happens. Click on OK for saving an error report. @@ -4932,9 +5052,9 @@ Error: -""" + - str(e_type) + " : " + str(e_value), - "Error", +""") + + str(e_type) + _(" : ") + str(e_value), + _("Error"), trcbck_lst) try: res = (dlg.ShowModal() == wx.ID_OK) @@ -4944,7 +5064,7 @@ return res def Display_Error_Dialog(e_value): - message = wx.MessageDialog(None, str(e_value), "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(None, str(e_value), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() @@ -5002,30 +5122,6 @@ sys.excepthook = handle_exception if __name__ == '__main__': - def usage(): - print "\nUsage of PLCOpenEditor.py :" - print "\n %s [Filepath]\n"%sys.argv[0] - - try: - opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) - except getopt.GetoptError: - # print help information and exit: - usage() - sys.exit(2) - - for o, a in opts: - if o in ("-h", "--help"): - usage() - sys.exit() - - fileOpen = None - if len(args) > 1: - usage() - sys.exit() - elif len(args) == 1: - fileOpen = args[0] - - app = wx.PySimpleApp() wx.InitAllImageHandlers() # Install a exception handle for bug reports diff -r 020420ad8914 -r 07447ee3538e RessourceEditor.py --- a/RessourceEditor.py Fri Jul 24 12:49:57 2009 +0200 +++ b/RessourceEditor.py Fri Jul 24 17:12:59 2009 +0200 @@ -74,6 +74,14 @@ # Resource Editor class #------------------------------------------------------------------------------- +def GetTasksTableColnames(): + _ = lambda x : x + return [_("Name"), _("Single"), _("Interval"), _("Priority")] + +def GetInstancesTableColnames(): + _ = lambda x : x + return [_("Name"), _("Type"), _("Task")] + class ResourceTable(wx.grid.PyGridTableBase): """ @@ -113,16 +121,18 @@ def GetNumberRows(self): return len(self.data) - def GetColLabelValue(self, col): + def GetColLabelValue(self, col, translate=True): if col < len(self.colnames): + if translate: + return _(self.colnames[col]) return self.colnames[col] - def GetRowLabelValues(self, row): + def GetRowLabelValues(self, row, translate=True): return row def GetValue(self, row, col): if row < self.GetNumberRows(): - name = str(self.data[row].get(self.GetColLabelValue(col), "")) + name = str(self.data[row].get(self.GetColLabelValue(col, False), "")) return name def GetValueByName(self, row, colname): @@ -130,7 +140,7 @@ def SetValue(self, row, col, value): if col < len(self.colnames): - self.data[row][self.GetColLabelValue(col)] = value + self.data[row][self.GetColLabelValue(col, False)] = value def SetValueByName(self, row, colname, value): if colname in self.colnames: @@ -188,7 +198,7 @@ for col in range(self.GetNumberCols()): editor = None renderer = None - colname = self.GetColLabelValue(col) + colname = self.GetColLabelValue(col, False) grid.SetReadOnly(row, col, False) if colname in ["Name","Interval"]: editor = wx.grid.GridCellTextEditor() @@ -345,8 +355,8 @@ size=wx.Size(0, 0), style=wx.SUNKEN_BORDER) self.staticText1 = wx.StaticText(id=ID_RESOURCEEDITORSTATICTEXT1, - label=u'Tasks:', name='staticText2', parent=self, pos=wx.Point(0, - 0), size=wx.Size(60, 17), style=wx.ALIGN_CENTER) + label=_(u'Tasks:'), name='staticText2', parent=self, pos=wx.Point(0, + 0), size=wx.DefaultSize, style=wx.ALIGN_CENTER) self.TasksGrid = wx.grid.Grid(id=ID_RESOURCEEDITORTASKSGRID, name='TasksGrid', parent=self, pos=wx.Point(0, 0), @@ -360,14 +370,14 @@ else: wx.grid.EVT_GRID_CELL_CHANGE(self.TasksGrid, self.OnTasksGridCellChange) - self.AddTaskButton = wx.Button(id=ID_RESOURCEEDITORADDTASKBUTTON, label='Add Task', + self.AddTaskButton = wx.Button(id=ID_RESOURCEEDITORADDTASKBUTTON, label=_('Add Task'), name='AddTaskButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(102, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnAddTaskButton, id=ID_RESOURCEEDITORADDTASKBUTTON) - self.DeleteTaskButton = wx.Button(id=ID_RESOURCEEDITORDELETETASKBUTTON, label='Delete Task', + self.DeleteTaskButton = wx.Button(id=ID_RESOURCEEDITORDELETETASKBUTTON, label=_('Delete Task'), name='DeleteTaskButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(102, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnDeleteTaskButton, id=ID_RESOURCEEDITORDELETETASKBUTTON) self.UpTaskButton = wx.Button(id=ID_RESOURCEEDITORUPTASKBUTTON, label='^', @@ -381,8 +391,8 @@ self.Bind(wx.EVT_BUTTON, self.OnDownTaskButton, id=ID_RESOURCEEDITORDOWNTASKBUTTON) self.staticText2 = wx.StaticText(id=ID_RESOURCEEDITORSTATICTEXT2, - label=u'Instances:', name='staticText1', parent=self, - pos=wx.Point(0, 0), size=wx.Size(85, 17), style=wx.ALIGN_CENTER) + label=_(u'Instances:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=wx.ALIGN_CENTER) self.InstancesGrid = wx.grid.Grid(id=ID_RESOURCEEDITORINSTANCESGRID, name='InstancesGrid', parent=self, pos=wx.Point(0, 0), @@ -396,14 +406,14 @@ else: wx.grid.EVT_GRID_CELL_CHANGE(self.InstancesGrid, self.OnInstancesGridCellChange) - self.AddInstanceButton = wx.Button(id=ID_RESOURCEEDITORADDINSTANCEBUTTON, label='Add Instance', + self.AddInstanceButton = wx.Button(id=ID_RESOURCEEDITORADDINSTANCEBUTTON, label=_('Add Instance'), name='AddInstanceButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(122, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnAddInstanceButton, id=ID_RESOURCEEDITORADDINSTANCEBUTTON) - self.DeleteInstanceButton = wx.Button(id=ID_RESOURCEEDITORDELETEINSTANCEBUTTON, label='Delete Instance', + self.DeleteInstanceButton = wx.Button(id=ID_RESOURCEEDITORDELETEINSTANCEBUTTON, label=_('Delete Instance'), name='DeleteInstanceButton', parent=self, pos=wx.Point(0, 0), - size=wx.Size(122, 32), style=0) + size=wx.DefaultSize, style=0) self.Bind(wx.EVT_BUTTON, self.OnDeleteInstanceButton, id=ID_RESOURCEEDITORDELETEINSTANCEBUTTON) self.UpInstanceButton = wx.Button(id=ID_RESOURCEEDITORUPINSTANCEBUTTON, label='^', @@ -426,7 +436,7 @@ self.TagName = tagname self.TasksDefaultValue = {"Name" : "", "Single" : "", "Interval" : "", "Priority" : 0} - self.TasksTable = ResourceTable(self, [], ["Name", "Single", "Interval", "Priority"]) + self.TasksTable = ResourceTable(self, [], GetTasksTableColnames()) self.TasksTable.SetColAlignements([wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT]) self.TasksTable.SetColSizes([200, 100, 100, 100]) self.TasksGrid.SetTable(self.TasksTable) @@ -434,7 +444,7 @@ self.TasksTable.ResetView(self.TasksGrid) self.InstancesDefaultValue = {"Name" : "", "Type" : "", "Task" : ""} - self.InstancesTable = ResourceTable(self, [], ["Name", "Type", "Task"]) + self.InstancesTable = ResourceTable(self, [], GetInstancesTableColnames()) self.InstancesTable.SetColAlignements([wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT]) self.InstancesTable.SetColSizes([200, 150, 150]) self.InstancesGrid.SetTable(self.InstancesTable) @@ -593,4 +603,4 @@ self.TasksTable.AddError(infos[1:]) elif infos[0] == "instance": self.InstancesTable.AddError(infos[1:]) - \ No newline at end of file + diff -r 020420ad8914 -r 07447ee3538e SFCViewer.py --- a/SFCViewer.py Fri Jul 24 12:49:57 2009 +0200 +++ b/SFCViewer.py Fri Jul 24 17:12:59 2009 +0200 @@ -359,7 +359,7 @@ #------------------------------------------------------------------------------- def AddInitialStep(self, pos): - dialog = StepNameDialog(self.ParentWindow, "Please enter step name", "Add a new initial step", "", wx.OK|wx.CANCEL) + dialog = StepNameDialog(self.ParentWindow, _("Please enter step name"), _("Add a new initial step"), "", wx.OK|wx.CANCEL) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)) dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)]) @@ -381,7 +381,7 @@ def AddStep(self): if self.SelectedElement in self.Wires or isinstance(self.SelectedElement, SFC_Step): - dialog = StepNameDialog(self.ParentWindow, "Add a new step", "Please enter step name", "", wx.OK|wx.CANCEL) + dialog = StepNameDialog(self.ParentWindow, _("Add a new step"), _("Please enter step name"), "", wx.OK|wx.CANCEL) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)) dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)]) @@ -695,7 +695,7 @@ for block in self.Blocks: if isinstance(block, SFC_Step): choices.append(block.GetName()) - dialog = wx.SingleChoiceDialog(self.ParentWindow, "Add a new jump", "Please choose a target", choices, wx.OK|wx.CANCEL) + dialog = wx.SingleChoiceDialog(self.ParentWindow, _("Add a new jump"), _("Please choose a target"), choices, wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: value = dialog.GetStringSelection() self.SelectedElement.AddOutput() @@ -723,7 +723,7 @@ if self.GetDrawingMode() == FREEDRAWING_MODE: Viewer.EditStepContent(self, step) else: - dialog = StepNameDialog(self.ParentWindow, "Edit step name", "Please enter step name", step.GetName(), wx.OK|wx.CANCEL) + dialog = StepNameDialog(self.ParentWindow, _("Edit step name"), _("Please enter step name"), step.GetName(), wx.OK|wx.CANCEL) dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug)) dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)) dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step) and block.GetName() != step.GetName()]) diff -r 020420ad8914 -r 07447ee3538e TextViewer.py --- a/TextViewer.py Fri Jul 24 12:49:57 2009 +0200 +++ b/TextViewer.py Fri Jul 24 17:12:59 2009 +0200 @@ -221,7 +221,7 @@ wx.CallAfter(self.RefreshModel) else: event.SetDragText("") - message = wx.MessageDialog(self.ParentWindow, "Variable don't belong to this POU!", "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self.ParentWindow, _("Variable don't belong to this POU!"), _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() event.Skip() diff -r 020420ad8914 -r 07447ee3538e Viewer.py --- a/Viewer.py Fri Jul 24 12:49:57 2009 +0200 +++ b/Viewer.py Fri Jul 24 17:12:59 2009 +0200 @@ -208,27 +208,27 @@ try: values = eval(data) except: - message = "Invalid value \"%s\" for viewer block"%data + message = _("Invalid value \"%s\" for viewer block")%data values = None if not isinstance(values, TupleType): - message = "Invalid value \"%s\" for viewer block"%data + message = _("Invalid value \"%s\" for viewer block")%data values = None if values is not None: if values[1] == "debug": pass elif values[1] == "program": - message = "Programs can't be used by other POUs!" + message = _("Programs can't be used by other POUs!") elif values[1] in ["function", "functionBlock", "program"]: name, type = self.ParentWindow.Controler.GetEditedElementType(self.ParentWindow.GetTagName(), self.ParentWindow.Debug) words = self.ParentWindow.TagName.split("::") if name == values[0]: - message = "\"%s\" can't use itself!"%name + message = _("\"%s\" can't use itself!")%name elif type == "function" and values[1] != "function": - message = "Function Blocks can't be used in Functions!" + message = _("Function Blocks can't be used in Functions!") elif words[0] == "T" and values[1] != "function": - message = "Function Blocks can't be used in Transitions!" + message = _("Function Blocks can't be used in Transitions!") elif self.ParentWindow.Controler.PouIsUsedBy(name, values[0], self.ParentWindow.Debug): - message = "\"%s\" is already used by \"%s\"!"%(name, values[0]) + message = _("\"%s\" is already used by \"%s\"!")%(name, values[0]) else: blockname = values[2] if len(values) > 3: @@ -243,9 +243,9 @@ return dialog.Destroy() if blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]: - message = "\"%s\" pou already exists!"%blockname + message = _("\"%s\" pou already exists!")%blockname elif blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(self.ParentWindow.GetTagName(), self.ParentWindow.Debug)]: - message = "\"%s\" element for this pou already exists!"%blockname + message = _("\"%s\" element for this pou already exists!")%blockname else: id = self.ParentWindow.GetNewId() block = FBD_Block(self.ParentWindow, values[0], blockname, id, inputs = blockinputs) @@ -283,9 +283,9 @@ else: self.AddParentVariableBlock(x, y, scaling, var_class, values[0], values[2]) else: - message = "Unknown variable \"%s\" this POU!" % values[0] + message = _("Unknown variable \"%s\" for this POU!") % values[0] else: - message = "Variable don't belong to this POU!" + message = _("Variable don't belong to this POU!") if message is not None: wx.CallAfter(self.ShowMessage, message) @@ -332,7 +332,7 @@ self.ParentWindow.Refresh(False) def ShowMessage(self, message): - message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR) + message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR) message.ShowModal() message.Destroy() @@ -355,18 +355,18 @@ def _init_coll_AlignmentMenu_Items(self, parent): # Create menu items AppendMenu(parent, help='', id=ID_VIEWERALIGNMENTMENUITEMS0, - kind=wx.ITEM_NORMAL, text=u'Left') + kind=wx.ITEM_NORMAL, text=_(u'Left')) AppendMenu(parent, help='', id=ID_VIEWERALIGNMENTMENUITEMS1, - kind=wx.ITEM_NORMAL, text=u'Center') + kind=wx.ITEM_NORMAL, text=_(u'Center')) AppendMenu(parent, help='', id=ID_VIEWERALIGNMENTMENUITEMS2, - kind=wx.ITEM_NORMAL, text=u'Right') + kind=wx.ITEM_NORMAL, text=_(u'Right')) parent.AppendSeparator() AppendMenu(parent, help='', id=ID_VIEWERALIGNMENTMENUITEMS4, - kind=wx.ITEM_NORMAL, text=u'Top') + kind=wx.ITEM_NORMAL, text=_(u'Top')) AppendMenu(parent, help='', id=ID_VIEWERALIGNMENTMENUITEMS5, - kind=wx.ITEM_NORMAL, text=u'Middle') + kind=wx.ITEM_NORMAL, text=_(u'Middle')) AppendMenu(parent, help='', id=ID_VIEWERALIGNMENTMENUITEMS6, - kind=wx.ITEM_NORMAL, text=u'Bottom') + kind=wx.ITEM_NORMAL, text=_(u'Bottom')) # Link menu event to corresponding called functions self.Bind(wx.EVT_MENU, self.OnAlignLeftMenu, id=ID_VIEWERALIGNMENTMENUITEMS0) @@ -385,35 +385,35 @@ def _init_coll_ContextualMenu_Items(self, parent): # Create menu items AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS0, - kind=wx.ITEM_RADIO, text=u'No Modifier') + kind=wx.ITEM_RADIO, text=_(u'No Modifier')) AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS1, - kind=wx.ITEM_RADIO, text=u'Negated') + kind=wx.ITEM_RADIO, text=_(u'Negated')) AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS2, - kind=wx.ITEM_RADIO, text=u'Rising Edge') + kind=wx.ITEM_RADIO, text=_(u'Rising Edge')) AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS3, - kind=wx.ITEM_RADIO, text=u'Falling Edge') + kind=wx.ITEM_RADIO, text=_(u'Falling Edge')) parent.AppendSeparator() AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS5, - kind=wx.ITEM_NORMAL, text=u'Add Wire Segment') + kind=wx.ITEM_NORMAL, text=_(u'Add Wire Segment')) AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS6, - kind=wx.ITEM_NORMAL, text=u'Delete Wire Segment') + kind=wx.ITEM_NORMAL, text=_(u'Delete Wire Segment')) parent.AppendSeparator() AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS8, - kind=wx.ITEM_NORMAL, text=u'Add Divergence Branch') + kind=wx.ITEM_NORMAL, text=_(u'Add Divergence Branch')) AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS9, - kind=wx.ITEM_NORMAL, text=u'Delete Divergence Branch') + kind=wx.ITEM_NORMAL, text=_(u'Delete Divergence Branch')) parent.AppendSeparator() AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS11, - kind=wx.ITEM_NORMAL, text=u'Clear Execution Order') + kind=wx.ITEM_NORMAL, text=_(u'Clear Execution Order')) AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS12, - kind=wx.ITEM_NORMAL, text=u'Reset Execution Order') + kind=wx.ITEM_NORMAL, text=_(u'Reset Execution Order')) parent.AppendSeparator() - parent.AppendMenu(ID_VIEWERCONTEXTUALMENUITEMS14, "Alignment", self.AlignmentMenu) + parent.AppendMenu(ID_VIEWERCONTEXTUALMENUITEMS14, _("Alignment"), self.AlignmentMenu) parent.AppendSeparator() AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS16, - kind=wx.ITEM_NORMAL, text=u'Edit Block') + kind=wx.ITEM_NORMAL, text=_(u'Edit Block')) AppendMenu(parent, help='', id=ID_VIEWERCONTEXTUALMENUITEMS17, - kind=wx.ITEM_NORMAL, text=u'Delete') + kind=wx.ITEM_NORMAL, text=_(u'Delete')) # Link menu event to corresponding called functions self.Bind(wx.EVT_MENU, self.OnNoModifierMenu, id=ID_VIEWERCONTEXTUALMENUITEMS0) @@ -1793,9 +1793,9 @@ def AddNewComment(self, bbox): if wx.VERSION >= (2, 5, 0): - dialog = wx.TextEntryDialog(self.ParentWindow, "Edit comment", "Please enter comment text", "", wx.OK|wx.CANCEL|wx.TE_MULTILINE) + dialog = wx.TextEntryDialog(self.ParentWindow, _("Edit comment"), _("Please enter comment text"), "", wx.OK|wx.CANCEL|wx.TE_MULTILINE) else: - dialog = wx.TextEntryDialog(self.ParentWindow, "Edit comment", "Please enter comment text", "", wx.OK|wx.CANCEL) + dialog = wx.TextEntryDialog(self.ParentWindow, _("Edit comment"), _("Please enter comment text"), "", wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: value = dialog.GetValue() id = self.GetNewId() @@ -1968,7 +1968,7 @@ for block in self.Blocks.itervalues(): if isinstance(block, SFC_Step): choices.append(block.GetName()) - dialog = wx.SingleChoiceDialog(self.ParentWindow, "Add a new jump", "Please choose a target", choices, wx.OK|wx.CANCEL) + dialog = wx.SingleChoiceDialog(self.ParentWindow, _("Add a new jump"), _("Please choose a target"), choices, wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: id = self.GetNewId() value = dialog.GetStringSelection() @@ -2207,9 +2207,9 @@ dialog.SetMinStepSize(step.GetSize()) values = {"name" : step.GetName()} connectors = step.GetConnectors() - values["input"] = connectors["input"] != None - values["output"] = connectors["output"] != None - values["action"] = connectors["action"] != None + values["input"] = len(connectors["inputs"]) > 0 + values["output"] = len(connectors["outputs"]) > 0 + values["action"] = step.GetActionConnector() != None dialog.SetValues(values) if dialog.ShowModal() == wx.ID_OK: values = dialog.GetValues() @@ -2259,7 +2259,7 @@ for block in self.Blocks.itervalues(): if isinstance(block, SFC_Step): choices.append(block.GetName()) - dialog = wx.SingleChoiceDialog(self.ParentWindow, "Edit jump target", "Please choose a target", choices, wx.OK|wx.CANCEL) + dialog = wx.SingleChoiceDialog(self.ParentWindow, _("Edit jump target"), _("Please choose a target"), choices, wx.OK|wx.CANCEL) dialog.SetSelection(choices.index(jump.GetTarget())) if dialog.ShowModal() == wx.ID_OK: value = dialog.GetStringSelection() @@ -2294,9 +2294,9 @@ def EditCommentContent(self, comment): if wx.VERSION >= (2, 5, 0): - dialog = wx.TextEntryDialog(self.ParentWindow, "Edit comment", "Please enter comment text", comment.GetContent(), wx.OK|wx.CANCEL|wx.TE_MULTILINE) + dialog = wx.TextEntryDialog(self.ParentWindow, _("Edit comment"), _("Please enter comment text"), comment.GetContent(), wx.OK|wx.CANCEL|wx.TE_MULTILINE) else: - dialog = wx.TextEntryDialog(self.ParentWindow, "Edit comment", "Please enter comment text", comment.GetContent(), wx.OK|wx.CANCEL) + dialog = wx.TextEntryDialog(self.ParentWindow, _("Edit comment"), _("Please enter comment text"), comment.GetContent(), wx.OK|wx.CANCEL) if dialog.ShowModal() == wx.ID_OK: value = dialog.GetValue() rect = comment.GetRedrawRect(1, 1) diff -r 020420ad8914 -r 07447ee3538e i18n/PLCOpenEditor_fr_FR.po --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i18n/PLCOpenEditor_fr_FR.po Fri Jul 24 17:12:59 2009 +0200 @@ -0,0 +1,2302 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-07-24 16:55+0200\n" +"PO-Revision-Date: 2009-07-24 17:02+0100\n" +"Last-Translator: \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../PLCOpenEditor.py:5044 +msgid "" +"\n" +"An error happens.\n" +"\n" +"Click on OK for saving an error report.\n" +"\n" +"Please contact LOLITech at:\n" +"+33 (0)3 29 57 60 42\n" +"bugs_PLCOpenEditor@lolitech.fr\n" +"\n" +"\n" +"Error:\n" +msgstr "" +"\n" +"Une erreur est apparue.\n" +"\n" +"Appuyer sur 'Valider' pour enregistrer un rapport d'erreur.\n" +"\n" +"Veuillez contacter LOLITech au :\n" +"+33 (0)3 29 57 60 42\n" +"bugs_PLCOpenEditor@lolitech.fr\n" +"\n" +"\n" +"Erreur:\n" + +#: ../PLCOpenEditor.py:3860 +msgid " External" +msgstr " Externe" + +#: ../PLCOpenEditor.py:3859 +msgid " InOut" +msgstr " Entrée-Sortie" + +#: ../PLCOpenEditor.py:3859 +msgid " Input" +msgstr " Entrée" + +#: ../PLCOpenEditor.py:3860 +msgid " Local" +msgstr " Locale" + +#: ../PLCOpenEditor.py:3859 +msgid " Output" +msgstr " Sortie" + +#: ../PLCOpenEditor.py:3861 +msgid " Temp" +msgstr " Temporaire" + +#: ../PLCOpenEditor.py:840 +msgid " (Debug)" +msgstr " (Debug)" + +#: ../PLCOpenEditor.py:5056 +msgid " : " +msgstr " : " + +#: ../PLCOpenEditor.py:3283 +#: ../PLCOpenEditor.py:3446 +#: ../PLCOpenEditor.py:3590 +#: ../Dialogs.py:1800 +#, python-format +msgid " and %s" +msgstr " et %s" + +#: ../plcopen/plcopen.py:782 +#, python-format +msgid "\"%s\" Data Type doesn't exist !!!" +msgstr "Le type de donnée \"%s\" n'existe pas !!!" + +#: ../plcopen/plcopen.py:800 +#, python-format +msgid "\"%s\" POU already exists !!!" +msgstr "Le POU \"%s\" existe déjà !!!" + +#: ../plcopen/plcopen.py:821 +#, python-format +msgid "\"%s\" POU doesn't exist !!!" +msgstr "Le POU \"%s\" n'existe pas !!!" + +#: ../Viewer.py:225 +#, python-format +msgid "\"%s\" can't use itself!" +msgstr "\"%s\" ne peut pas s'utiliser lui-même !" + +#: ../PLCOpenEditor.py:1617 +#: ../PLCOpenEditor.py:1637 +#, python-format +msgid "\"%s\" config already exists!" +msgstr "La configuration \"%s\" existe déjà !" + +#: ../plcopen/plcopen.py:256 +#, python-format +msgid "\"%s\" configuration already exists !!!" +msgstr "La configuration \"%s\" existe déjà !!!" + +#: ../PLCOpenEditor.py:1571 +#: ../PLCOpenEditor.py:3145 +#, python-format +msgid "\"%s\" data type already exists!" +msgstr "Le type de données \"%s\" existe déjà !" + +#: ../PLCControler.py:1663 +#, python-format +msgid "\"%s\" element can't be paste here!!!" +msgstr "L'élément \"%s\" ne peut être collé ici !!!" + +#: ../PLCOpenEditor.py:3465 +#: ../PLCOpenEditor.py:3609 +#: ../Viewer.py:248 +#: ../Dialogs.py:261 +#: ../Dialogs.py:898 +#, python-format +msgid "\"%s\" element for this pou already exists!" +msgstr "Un élément \"%s\" existe déjà dans ce POU !" + +#: ../plcopen/structures.py:97 +#, python-format +msgid "\"%s\" function cancelled in \"%s\" POU: No input connected" +msgstr "L'appel à la fonction \"%s\" dans le POU \"%s\" a été abandonné : aucune entrée connectée" + +#: ../PLCOpenEditor.py:1562 +#: ../PLCOpenEditor.py:3141 +#: ../PLCOpenEditor.py:3294 +#: ../PLCOpenEditor.py:3457 +#: ../PLCOpenEditor.py:3601 +#: ../PLCOpenEditor.py:3672 +#: ../PLCOpenEditor.py:3735 +#: ../PLCOpenEditor.py:4449 +#: ../Dialogs.py:253 +#: ../Dialogs.py:652 +#: ../Dialogs.py:890 +#: ../Dialogs.py:1533 +#: ../Dialogs.py:2516 +#: ../Dialogs.py:2583 +#: ../DataTypeEditor.py:702 +#: ../DataTypeEditor.py:762 +#, python-format +msgid "\"%s\" is a keyword. It can't be used!" +msgstr "\"%s\" est un mot réservé. Il ne peut être utilisé !" + +#: ../Viewer.py:231 +#, python-format +msgid "\"%s\" is already used by \"%s\"!" +msgstr "\"%s\" est déjà utilisé par \"%s\" !" + +#: ../plcopen/plcopen.py:2120 +#, python-format +msgid "\"%s\" is an invalid value!" +msgstr "\"%s\" n'est pas une valeur valide !" + +#: ../PLCOpenEditor.py:1097 +#: ../PLCOpenEditor.py:1126 +#, python-format +msgid "\"%s\" is not a valid folder!" +msgstr "\"%s\" n'est pas un répertoire valide !" + +#: ../PLCOpenEditor.py:1560 +#: ../PLCOpenEditor.py:3137 +#: ../PLCOpenEditor.py:3290 +#: ../PLCOpenEditor.py:3453 +#: ../PLCOpenEditor.py:3597 +#: ../PLCOpenEditor.py:3668 +#: ../PLCOpenEditor.py:3731 +#: ../PLCOpenEditor.py:4444 +#: ../Dialogs.py:249 +#: ../Dialogs.py:886 +#: ../Dialogs.py:1529 +#: ../Dialogs.py:2512 +#: ../Dialogs.py:2579 +#: ../DataTypeEditor.py:757 +#, python-format +msgid "\"%s\" is not a valid identifier!" +msgstr "\"%s\" n'est pas un identifiant valide !" + +#: ../PLCOpenEditor.py:283 +#: ../PLCOpenEditor.py:2491 +#: ../PLCOpenEditor.py:2520 +#, python-format +msgid "\"%s\" is used by one or more POUs. It can't be removed!" +msgstr "Le POU \"%s\" est utilisé par un ou plusieurs POUs. Il ne peut être supprimé !" + +#: ../PLCOpenEditor.py:1580 +#: ../PLCOpenEditor.py:3298 +#: ../Viewer.py:246 +#: ../Dialogs.py:257 +#: ../Dialogs.py:894 +#, python-format +msgid "\"%s\" pou already exists!" +msgstr "Le POU \"%s\" existe déjà !" + +#: ../plcopen/plcopen.py:287 +#, python-format +msgid "\"%s\" resource already exists in \"%s\" configuration !!!" +msgstr "La ressource \"%s\" existe déjà dans la configuration \"%\" !!!" + +#: ../plcopen/plcopen.py:303 +#, python-format +msgid "\"%s\" resource doesn't exist in \"%s\" configuration !!!" +msgstr "La ressource \"%s\" n'existe pas dans la configuration \"%s\" !!!" + +#: ../Dialogs.py:1545 +#: ../Dialogs.py:2528 +#, python-format +msgid "\"%s\" step already exists!" +msgstr "L'étape \"%s\" existe déjà !" + +#: ../DataTypeEditor.py:697 +#, python-format +msgid "\"%s\" value already defined!" +msgstr "La valeur \"%s\" est déjà définie !" + +#: ../DataTypeEditor.py:899 +#, python-format +msgid "\"%s\" value isn't a valid array dimension!" +msgstr "\"%s\" n'est pas une dimension de tableau valide !" + +#: ../DataTypeEditor.py:906 +#, python-format +msgid "" +"\"%s\" value isn't a valid array dimension!\n" +"Right value must be greater than left value." +msgstr "" +"\"%s\" n'est pas une dimension de tableau valide !\n" +"La valeur de droite doit être supérieur à celle de gauche." + +#: ../GraphicViewer.py:181 +#, python-format +msgid "%s Graphics" +msgstr "Graphique %s" + +#: ../plcopen/plcopen.py:1276 +#: ../plcopen/plcopen.py:1286 +#: ../plcopen/plcopen.py:1296 +#: ../plcopen/plcopen.py:1306 +#: ../plcopen/plcopen.py:1315 +#, python-format +msgid "%s body don't have instances!" +msgstr "Le code d'un %s n'a pas d'instances !" + +#: ../plcopen/plcopen.py:1338 +#: ../plcopen/plcopen.py:1345 +#, python-format +msgid "%s body don't have text!" +msgstr "Le code d'un %s n'a pas de texte !" + +#: ../PLCOpenEditor.py:5032 +#: ../PLCOpenEditor.py:5034 +#: ../PLCOpenEditor.py:5035 +msgid ", " +msgstr ", " + +#: ../PLCOpenEditor.py:3285 +#: ../PLCOpenEditor.py:3448 +#: ../PLCOpenEditor.py:3592 +#: ../Dialogs.py:1802 +#, python-format +msgid ", %s" +msgstr ", %s" + +#: ../PLCOpenEditor.py:5030 +msgid ". " +msgstr ". " + +#: ../DataTypeEditor.py:772 +#, python-format +msgid "A element with \"%s\" as name exists in this structure!" +msgstr "Un élément nommé \"%s\" existe déjà dans la structure !" + +#: ../PLCOpenEditor.py:1583 +#: ../PLCOpenEditor.py:1625 +#: ../PLCOpenEditor.py:1645 +#: ../PLCOpenEditor.py:3302 +#: ../PLCOpenEditor.py:3680 +#: ../PLCOpenEditor.py:3743 +#, python-format +msgid "A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?" +msgstr "Un POU a un élément nommé \"%s\". Cela peut générer des conflits. Voulez-vous continuer ?" + +#: ../PLCOpenEditor.py:1620 +#: ../PLCOpenEditor.py:1640 +#, python-format +msgid "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?" +msgstr "Un POU a pour nom \"%s\". Cela peut générer des conflits. Voulez-vous continuer ?" + +#: ../PLCOpenEditor.py:1596 +#: ../PLCOpenEditor.py:1607 +#: ../PLCOpenEditor.py:3461 +#: ../PLCOpenEditor.py:3605 +#: ../PLCOpenEditor.py:3676 +#: ../PLCOpenEditor.py:3739 +#: ../PLCOpenEditor.py:4454 +#: ../Dialogs.py:1537 +#: ../Dialogs.py:2520 +#: ../Dialogs.py:2587 +#, python-format +msgid "A pou with \"%s\" as name exists!" +msgstr "Un POU nommé \"%s\" existe déjà !" + +#: ../PLCOpenEditor.py:1598 +#: ../PLCOpenEditor.py:1609 +#: ../PLCOpenEditor.py:4459 +#: ../Dialogs.py:1541 +#: ../Dialogs.py:2524 +#, python-format +msgid "A variable with \"%s\" as name already exists in this pou!" +msgstr "Une variable nommée \"%s\" existe déjà dans ce POU !" + +#: ../PLCOpenEditor.py:445 +msgid "About" +msgstr "A propos" + +#: ../PLCOpenEditor.py:2614 +msgid "About PLCOpenEditor" +msgstr "A propos de PLCOpenEditor" + +#: ../plcopen/iec_std.csv:22 +msgid "Absolute number" +msgstr "Nombre absolu" + +#: ../Dialogs.py:1482 +#: ../Dialogs.py:2109 +msgid "Action" +msgstr "Action" + +#: ../PLCOpenEditor.py:3581 +msgid "Action Name" +msgstr "Nom de l'action" + +#: ../PLCOpenEditor.py:3548 +msgid "Action Name:" +msgstr "Nom de l'action :" + +#: ../plcopen/plcopen.py:1073 +#, python-format +msgid "Action with name %s doesn't exists!" +msgstr "L'action nommée %s n'existe pas !" + +#: ../PLCControler.py:83 +msgid "Actions" +msgstr "Actions" + +#: ../Dialogs.py:2332 +msgid "Actions:" +msgstr "Actions :" + +#: ../PLCOpenEditor.py:4244 +#: ../Dialogs.py:2346 +#: ../DataTypeEditor.py:539 +msgid "Add" +msgstr "Ajouter" + +#: ../PLCOpenEditor.py:1800 +#: ../PLCOpenEditor.py:1873 +msgid "Add Action" +msgstr "Ajouter une action" + +#: ../PLCOpenEditor.py:1856 +msgid "Add Configuration" +msgstr "Ajouter une configuration" + +#: ../PLCOpenEditor.py:1844 +msgid "Add DataType" +msgstr "Ajouter un type de donnée" + +#: ../Viewer.py:402 +msgid "Add Divergence Branch" +msgstr "Ajouter une branche à la divergence" + +#: ../PLCOpenEditor.py:384 +msgid "Add Element" +msgstr "Ajouter un élément" + +#: ../RessourceEditor.py:409 +msgid "Add Instance" +msgstr "Ajouter une instance" + +#: ../PLCOpenEditor.py:1850 +msgid "Add Pou" +msgstr "Ajouter un POU" + +#: ../PLCOpenEditor.py:1827 +#: ../PLCOpenEditor.py:1884 +msgid "Add Resource" +msgstr "Ajouter une resource" + +#: ../RessourceEditor.py:373 +msgid "Add Task" +msgstr "Ajouter une tâche" + +#: ../PLCOpenEditor.py:1797 +#: ../PLCOpenEditor.py:1862 +msgid "Add Transition" +msgstr "Ajouter une transition" + +#: ../Viewer.py:397 +msgid "Add Wire Segment" +msgstr "Ajouter un segment au fil" + +#: ../PLCOpenEditor.py:2359 +msgid "Add a new data type" +msgstr "Ajouter un nouveau type de données" + +#: ../SFCViewer.py:362 +msgid "Add a new initial step" +msgstr "Ajouter une nouvelle étape initiale" + +#: ../Viewer.py:1971 +#: ../SFCViewer.py:698 +msgid "Add a new jump" +msgstr "Ajouter un nouveau renvoi" + +#: ../SFCViewer.py:384 +msgid "Add a new step" +msgstr "Ajouter une nouvelle étape" + +#: ../PLCOpenEditor.py:2416 +msgid "Add new configuration" +msgstr "Ajouter une nouvelle configuration" + +#: ../PLCOpenEditor.py:2431 +msgid "Add new resource" +msgstr "Ajouter une nouvelle resource" + +#: ../plcopen/iec_std.csv:33 +msgid "Addition" +msgstr "Addition" + +#: ../plcopen/structures.py:222 +msgid "Additionnal function blocks" +msgstr "Blocs fonctionnels additionnels" + +#: ../Viewer.py:411 +msgid "Alignment" +msgstr "Alignement" + +#: ../PLCOpenEditor.py:3858 +msgid "All" +msgstr "Toutes" + +#: ../plcopen/iec_std.csv:31 +msgid "Arc cosine" +msgstr "Arc cosinus" + +#: ../plcopen/iec_std.csv:30 +msgid "Arc sine" +msgstr "Arc sinus" + +#: ../plcopen/iec_std.csv:32 +msgid "Arc tangent" +msgstr "Arc tangente" + +#: ../plcopen/iec_std.csv:33 +msgid "Arithmetic" +msgstr "Arithmétique" + +#: ../DataTypeEditor.py:236 +msgid "Array" +msgstr "Tableau" + +#: ../plcopen/iec_std.csv:50 +msgid "Assignment" +msgstr "Assignation" + +#: ../Dialogs.py:648 +msgid "At least a variable or an expression must be selected!" +msgstr "Au moins une variable ou une expression doit être sélectionné !" + +#: ../PLCOpenEditor.py:2941 +msgid "Author" +msgstr "Auteur" + +#: ../PLCOpenEditor.py:2926 +msgid "Author Name (optional):" +msgstr "Nom de l'auteur (optionel) :" + +#: ../DataTypeEditor.py:379 +#: ../DataTypeEditor.py:403 +#: ../DataTypeEditor.py:478 +msgid "Base Type:" +msgstr "Type de base :" + +#: ../PLCOpenEditor.py:4491 +#: ../DataTypeEditor.py:798 +msgid "Base Types" +msgstr "Types de base" + +#: ../plcopen/iec_std.csv:59 +msgid "Binary selection (1 of 2)" +msgstr "Selection binaire (sélectionne 1 sur 2)" + +#: ../plcopen/iec_std.csv:51 +msgid "Bit-shift" +msgstr "Décalage de bit" + +#: ../plcopen/iec_std.csv:55 +msgid "Bitwise" +msgstr "Bit à bit" + +#: ../plcopen/iec_std.csv:55 +msgid "Bitwise AND" +msgstr "ET bit à bit" + +#: ../plcopen/iec_std.csv:56 +msgid "Bitwise OR" +msgstr "OU bit à bit" + +#: ../plcopen/iec_std.csv:57 +msgid "Bitwise XOR" +msgstr "OU exclusif bit à bit" + +#: ../plcopen/iec_std.csv:58 +msgid "Bitwise inverting" +msgstr "Inversion bit à bit" + +#: ../Dialogs.py:114 +msgid "Block Properties" +msgstr "Propriétés du bloc" + +#: ../PLCOpenEditor.py:2077 +#: ../Dialogs.py:269 +msgid "Block Types" +msgstr "Types de blocs" + +#: ../Viewer.py:369 +msgid "Bottom" +msgstr "Bas" + +#: ../PLCOpenEditor.py:2031 +msgid "CSV Log" +msgstr "Log CVS" + +#: ../PLCOpenEditor.py:4072 +msgid "Can affect a location only to local or global variables" +msgstr "Une adresse ne peut être affecté qu'à des variables locales ou globales" + +#: ../plcopen/plcopen.py:1218 +#: ../plcopen/plcopen.py:1232 +#: ../plcopen/plcopen.py:1253 +#: ../plcopen/plcopen.py:1269 +msgid "Can only generate execution order on FBD networks!" +msgstr "L'ordre d'exécution ne peut être généré que dans les FBD !" + +#: ../PLCOpenEditor.py:4070 +msgid "Can't affect a location to a function block instance" +msgstr "Une adresse ne peut être affectée une instance de Function Block" + +#: ../PLCOpenEditor.py:1092 +#, python-format +msgid "Can't generate program to file %s!" +msgstr "Le programme n'a pu être généré dans le fichier \"%s\" !" + +#: ../PLCOpenEditor.py:1124 +#, python-format +msgid "Can't save project to file %s!" +msgstr "Le projet n'a pu être sauvé dans le fichier \"%s\" !" + +#: ../Viewer.py:360 +msgid "Center" +msgstr "Centre" + +#: ../PLCOpenEditor.py:1816 +msgid "Change POU Type To" +msgstr "Changer le type du POU pour" + +#: ../plcopen/iec_std.csv:70 +msgid "Character string" +msgstr "Chaîne de caractères" + +#: ../PLCOpenEditor.py:1031 +#: ../PLCOpenEditor.py:1082 +#: ../PLCOpenEditor.py:1118 +msgid "Choose a file" +msgstr "Choisissez un fichier" + +#: ../PLCOpenEditor.py:3848 +#: ../PLCOpenEditor.py:3849 +msgid "Class" +msgstr "Classe" + +#: ../PLCOpenEditor.py:4236 +msgid "Class Filter:" +msgstr "Filtre de classe :" + +#: ../Dialogs.py:508 +msgid "Class:" +msgstr "Classe :" + +#: ../PLCOpenEditor.py:423 +msgid "Clear Errors\tCTRL+K" +msgstr "Effacer les erreurs\tCTRL+K" + +#: ../Viewer.py:407 +msgid "Clear Execution Order" +msgstr "Effacer l'ordre d'exécution" + +#: ../PLCOpenEditor.py:346 +msgid "Close\tCTRL+Q" +msgstr "Fermer\tCTRL+Q" + +#: ../PLCOpenEditor.py:961 +msgid "Close Application" +msgstr "Fermer l'application" + +#: ../PLCOpenEditor.py:319 +msgid "Close Project" +msgstr "Fermer le projet" + +#: ../PLCOpenEditor.py:316 +msgid "Close Tab\tCTRL+W" +msgstr "Fermer l'onglet\tCTRL+W" + +#: ../LDViewer.py:478 +msgid "Comment" +msgstr "Commentaire" + +#: ../PLCOpenEditor.py:2910 +msgid "Company Name (required):" +msgstr "Nom de l'entreprise (obligatoire) :" + +#: ../PLCOpenEditor.py:2918 +msgid "Company URL (optional):" +msgstr "URL de l'entreprise (optionel) :" + +#: ../plcopen/iec_std.csv:64 +msgid "Comparison" +msgstr "Comparaison" + +#: ../plcopen/iec_std.csv:74 +msgid "Concatenation" +msgstr "Concaténation" + +#: ../PLCOpenEditor.py:394 +msgid "Configuration" +msgstr "Configuration" + +#: ../PLCControler.py:84 +msgid "Configurations" +msgstr "Configurations" + +#: ../Dialogs.py:1737 +msgid "Connection" +msgstr "Connexion" + +#: ../Dialogs.py:784 +msgid "Connection Properties" +msgstr "Propriétés de la connexion" + +#: ../Dialogs.py:800 +msgid "Connector" +msgstr "Connecteur" + +#: ../Dialogs.py:1459 +msgid "Connectors:" +msgstr "Connecteurs :" + +#: ../PLCOpenEditor.py:3848 +#: ../PLCOpenEditor.py:3849 +msgid "Constant" +msgstr "Constante" + +#: ../PLCOpenEditor.py:3000 +msgid "Content Description (optional):" +msgstr "Description du contenu (optionel) :" + +#: ../Dialogs.py:806 +msgid "Continuation" +msgstr "Prolongement" + +#: ../plcopen/iec_std.csv:18 +msgid "Conversion from BCD" +msgstr "Conversion d'un BCD" + +#: ../plcopen/iec_std.csv:19 +msgid "Conversion to BCD" +msgstr "Conversion en BCD" + +#: ../plcopen/iec_std.csv:21 +msgid "Conversion to date" +msgstr "Conversion en date" + +#: ../plcopen/iec_std.csv:20 +msgid "Conversion to time-of-day" +msgstr "Conversion en heure de la journée" + +#: ../PLCOpenEditor.py:379 +msgid "Copy\tCTRL+C" +msgstr "Copier\tCtrl+C" + +#: ../plcopen/iec_std.csv:28 +msgid "Cosine" +msgstr "Cosinus" + +#: ../PLCOpenEditor.py:3223 +msgid "Create a new POU" +msgstr "Créer un nouveau POU" + +#: ../PLCOpenEditor.py:1804 +#: ../PLCOpenEditor.py:2461 +msgid "Create a new POU from" +msgstr "Créer un nouveau POU à partir de" + +#: ../PLCOpenEditor.py:3544 +msgid "Create a new action" +msgstr "Créer une nouvelle action" + +#: ../PLCOpenEditor.py:214 +msgid "Create a new action block" +msgstr "Créer un nouveau bloc d'actions" + +#: ../PLCOpenEditor.py:169 +#: ../PLCOpenEditor.py:196 +#: ../PLCOpenEditor.py:226 +msgid "Create a new block" +msgstr "Créer un nouveau bloc" + +#: ../PLCOpenEditor.py:190 +msgid "Create a new branch" +msgstr "Créer une nouvelle branche" + +#: ../PLCOpenEditor.py:184 +msgid "Create a new coil" +msgstr "Créer un nouveau relai" + +#: ../PLCOpenEditor.py:163 +#: ../PLCOpenEditor.py:175 +#: ../PLCOpenEditor.py:202 +msgid "Create a new comment" +msgstr "Créer un nouveau copmmentaire" + +#: ../PLCOpenEditor.py:172 +#: ../PLCOpenEditor.py:199 +#: ../PLCOpenEditor.py:229 +msgid "Create a new connection" +msgstr "Créer une nouvelle connexion" + +#: ../PLCOpenEditor.py:187 +#: ../PLCOpenEditor.py:235 +msgid "Create a new contact" +msgstr "Créer un nouveau contact" + +#: ../PLCOpenEditor.py:217 +msgid "Create a new divergence" +msgstr "Créer une nouvelle divergence" + +#: ../Dialogs.py:1976 +msgid "Create a new divergence or convergence" +msgstr "Créer une nouvelle divergence ou convergence" + +#: ../PLCOpenEditor.py:205 +msgid "Create a new initial step" +msgstr "Créer une nouvelle étape initiale" + +#: ../PLCOpenEditor.py:220 +msgid "Create a new jump" +msgstr "Créer un nouveau renvoi" + +#: ../PLCOpenEditor.py:178 +#: ../PLCOpenEditor.py:232 +msgid "Create a new power rail" +msgstr "Créer une nouvelle barre d'alimentation" + +#: ../PLCOpenEditor.py:181 +msgid "Create a new rung" +msgstr "Créer un nouvel échelon" + +#: ../PLCOpenEditor.py:208 +msgid "Create a new step" +msgstr "Créer une nouvelle étape" + +#: ../PLCOpenEditor.py:211 +#: ../PLCOpenEditor.py:3400 +msgid "Create a new transition" +msgstr "Créer une nouvelle transition" + +#: ../PLCOpenEditor.py:166 +#: ../PLCOpenEditor.py:193 +#: ../PLCOpenEditor.py:223 +msgid "Create a new variable" +msgstr "Créer une nouvelle variable" + +#: ../PLCOpenEditor.py:377 +msgid "Cut\tCTRL+X" +msgstr "Couper\tCTRL+X" + +#: ../PLCOpenEditor.py:386 +msgid "Data Type" +msgstr "Type de donnée" + +#: ../PLCControler.py:83 +msgid "Data Types" +msgstr "Types de données" + +#: ../plcopen/iec_std.csv:16 +msgid "Data type conversion" +msgstr "Conversion entre types de donnée" + +#: ../plcopen/iec_std.csv:36 +msgid "Date addition" +msgstr "Addition de dates" + +#: ../plcopen/iec_std.csv:44 +#: ../plcopen/iec_std.csv:45 +msgid "Date and time subtraction" +msgstr "Soustraction entre horodatage" + +#: ../plcopen/iec_std.csv:41 +msgid "Date subtraction" +msgstr "Soustraction de date" + +#: ../PLCOpenEditor.py:398 +#: ../PLCOpenEditor.py:1821 +#: ../PLCOpenEditor.py:1830 +#: ../PLCOpenEditor.py:1836 +#: ../PLCOpenEditor.py:4249 +#: ../PLCOpenEditor.py:4862 +#: ../Viewer.py:416 +#: ../Dialogs.py:2351 +#: ../DataTypeEditor.py:544 +msgid "Delete" +msgstr "Supprimer" + +#: ../Viewer.py:404 +msgid "Delete Divergence Branch" +msgstr "Supprimer une branche de divergence" + +#: ../RessourceEditor.py:414 +msgid "Delete Instance" +msgstr "Supprimer une instance" + +#: ../RessourceEditor.py:378 +msgid "Delete Task" +msgstr "Supprimer une tâche" + +#: ../Viewer.py:399 +msgid "Delete Wire Segment" +msgstr "Supprimer un segment de fil" + +#: ../DataTypeEditor.py:453 +#: ../DataTypeEditor.py:495 +msgid "Delete item" +msgstr "Supprimer un élément" + +#: ../plcopen/iec_std.csv:77 +msgid "Deletion (within)" +msgstr "Suppression (au milieu)" + +#: ../DataTypeEditor.py:364 +msgid "Derivation Type:" +msgstr "Type de dérivation :" + +#: ../plcopen/structures.py:236 +msgid "" +"Derivative\n" +"The derivative function block produces an output XOUT proportional to the rate of change of the input XIN." +msgstr "" +"Dérivée\n" +"Le Function Block derivative produit une sortie XOUT proportionnelle au rapport de changement de l'entrée XIN." + +#: ../DataTypeEditor.py:487 +msgid "Dimensions:" +msgstr "Dimensions :" + +#: ../DataTypeEditor.py:236 +msgid "Directly" +msgstr "Direct" + +#: ../PLCOpenEditor.py:306 +msgid "Display" +msgstr "Affichage" + +#: ../plcopen/iec_std.csv:46 +msgid "Division" +msgstr "Division" + +#: ../PLCOpenEditor.py:1086 +msgid "Done" +msgstr "Terminé" + +#: ../plcopen/structures.py:199 +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 "" +"Compteur décrémental\n" +"Le compteur décrémental peut être utilisé pour signaler lorsque le compteur atteint zéro en partant d'une valeur prédéfinie." + +#: ../Dialogs.py:2105 +msgid "Duration" +msgstr "Durée" + +#: ../PLCOpenEditor.py:305 +msgid "Edit" +msgstr "Editer" + +#: ../Viewer.py:414 +msgid "Edit Block" +msgstr "Editer le block" + +#: ../Dialogs.py:1098 +msgid "Edit Coil Values" +msgstr "Editer les valeurs du relai" + +#: ../Dialogs.py:1093 +msgid "Edit Contact Values" +msgstr "Editer les valeurs du contact" + +#: ../Dialogs.py:1451 +msgid "Edit Step" +msgstr "Editer l'étape" + +#: ../Dialogs.py:2328 +msgid "Edit action block properties" +msgstr "Editer les propriétés du block d'actions" + +#: ../Viewer.py:1796 +#: ../Viewer.py:1798 +#: ../Viewer.py:2297 +#: ../Viewer.py:2299 +msgid "Edit comment" +msgstr "Editer le commentaire" + +#: ../DataTypeEditor.py:448 +#: ../DataTypeEditor.py:490 +msgid "Edit item" +msgstr "Editer l'élément" + +#: ../Viewer.py:2262 +msgid "Edit jump target" +msgstr "Editer la cible du renvoi" + +#: ../SFCViewer.py:726 +msgid "Edit step name" +msgstr "Editer le nom de l'étape" + +#: ../Dialogs.py:1698 +msgid "Edit transition" +msgstr "Editer la transition" + +#: ../DataTypeEditor.py:520 +msgid "Elements :" +msgstr "Eléments :" + +#: ../DataTypeEditor.py:236 +msgid "Enumerated" +msgstr "Enumération" + +#: ../plcopen/iec_std.csv:66 +msgid "Equal to" +msgstr "Egal à" + +#: ../PLCOpenEditor.py:953 +#: ../PLCOpenEditor.py:1093 +#: ../PLCOpenEditor.py:1098 +#: ../PLCOpenEditor.py:1583 +#: ../PLCOpenEditor.py:1620 +#: ../PLCOpenEditor.py:1625 +#: ../PLCOpenEditor.py:1640 +#: ../PLCOpenEditor.py:1645 +#: ../PLCOpenEditor.py:2491 +#: ../PLCOpenEditor.py:2520 +#: ../PLCOpenEditor.py:3041 +#: ../PLCOpenEditor.py:3133 +#: ../PLCOpenEditor.py:3137 +#: ../PLCOpenEditor.py:3141 +#: ../PLCOpenEditor.py:3145 +#: ../PLCOpenEditor.py:3286 +#: ../PLCOpenEditor.py:3290 +#: ../PLCOpenEditor.py:3294 +#: ../PLCOpenEditor.py:3298 +#: ../PLCOpenEditor.py:3449 +#: ../PLCOpenEditor.py:3453 +#: ../PLCOpenEditor.py:3457 +#: ../PLCOpenEditor.py:3461 +#: ../PLCOpenEditor.py:3465 +#: ../PLCOpenEditor.py:3593 +#: ../PLCOpenEditor.py:3597 +#: ../PLCOpenEditor.py:3601 +#: ../PLCOpenEditor.py:3605 +#: ../PLCOpenEditor.py:3609 +#: ../PLCOpenEditor.py:3664 +#: ../PLCOpenEditor.py:3668 +#: ../PLCOpenEditor.py:3672 +#: ../PLCOpenEditor.py:3676 +#: ../PLCOpenEditor.py:3727 +#: ../PLCOpenEditor.py:3731 +#: ../PLCOpenEditor.py:3735 +#: ../PLCOpenEditor.py:3739 +#: ../PLCOpenEditor.py:4119 +#: ../PLCOpenEditor.py:4444 +#: ../PLCOpenEditor.py:4449 +#: ../PLCOpenEditor.py:4454 +#: ../PLCOpenEditor.py:4459 +#: ../PLCOpenEditor.py:4795 +#: ../PLCOpenEditor.py:5057 +#: ../PLCOpenEditor.py:5067 +#: ../Viewer.py:335 +#: ../TextViewer.py:224 +#: ../LDViewer.py:628 +#: ../LDViewer.py:850 +#: ../LDViewer.py:854 +#: ../Dialogs.py:241 +#: ../Dialogs.py:245 +#: ../Dialogs.py:249 +#: ../Dialogs.py:253 +#: ../Dialogs.py:257 +#: ../Dialogs.py:261 +#: ../Dialogs.py:648 +#: ../Dialogs.py:652 +#: ../Dialogs.py:882 +#: ../Dialogs.py:886 +#: ../Dialogs.py:890 +#: ../Dialogs.py:894 +#: ../Dialogs.py:898 +#: ../Dialogs.py:1525 +#: ../Dialogs.py:1529 +#: ../Dialogs.py:1533 +#: ../Dialogs.py:1537 +#: ../Dialogs.py:1541 +#: ../Dialogs.py:1545 +#: ../Dialogs.py:1803 +#: ../Dialogs.py:2508 +#: ../Dialogs.py:2512 +#: ../Dialogs.py:2516 +#: ../Dialogs.py:2520 +#: ../Dialogs.py:2524 +#: ../Dialogs.py:2528 +#: ../Dialogs.py:2575 +#: ../Dialogs.py:2579 +#: ../Dialogs.py:2583 +#: ../Dialogs.py:2587 +#: ../DataTypeEditor.py:697 +#: ../DataTypeEditor.py:702 +#: ../DataTypeEditor.py:757 +#: ../DataTypeEditor.py:762 +#: ../DataTypeEditor.py:772 +#: ../DataTypeEditor.py:899 +#: ../DataTypeEditor.py:906 +msgid "Error" +msgstr "Erreur" + +#: ../Dialogs.py:134 +msgid "Execution Control:" +msgstr "Contrôle d'exécution :" + +#: ../Dialogs.py:130 +#: ../Dialogs.py:516 +msgid "Execution Order:" +msgstr "Ordre d'exécution :" + +#: ../plcopen/iec_std.csv:49 +msgid "Exponent" +msgstr "Exposant" + +#: ../plcopen/iec_std.csv:26 +msgid "Exponentiation" +msgstr "Exponentiel" + +#: ../Dialogs.py:512 +msgid "Expression:" +msgstr "Expression :" + +#: ../PLCOpenEditor.py:3860 +msgid "External" +msgstr "Externe" + +#: ../PLCOpenEditor.py:2978 +#: ../PLCOpenEditor.py:3168 +#: ../PLCOpenEditor.py:3178 +#: ../PLCOpenEditor.py:3357 +#: ../PLCOpenEditor.py:3501 +msgid "FBD" +msgstr "FBD" + +#: ../Viewer.py:394 +#: ../Dialogs.py:1060 +msgid "Falling Edge" +msgstr "Front descendant" + +#: ../plcopen/structures.py:189 +msgid "" +"Falling edge detector\n" +"The output produces a single pulse when a falling edge is detected." +msgstr "" +"Détecteur de front descendant\n" +"La sortie produit une impulsion unique lorsqu'un front descendant est détecté." + +#: ../PLCOpenEditor.py:303 +msgid "File" +msgstr "Fichier" + +#: ../plcopen/iec_std.csv:79 +msgid "Find position" +msgstr "Trouver la position" + +#: ../PLCOpenEditor.py:3041 +#: ../PLCOpenEditor.py:3286 +#: ../PLCOpenEditor.py:3449 +#: ../PLCOpenEditor.py:3593 +#: ../Dialogs.py:1803 +#, python-format +msgid "Form isn't complete. %s must be filled!" +msgstr "Le formulaire est incomplet. %s doit être complété !" + +#: ../Dialogs.py:245 +#: ../Dialogs.py:882 +msgid "Form isn't complete. Name must be filled!" +msgstr "Le formulaire est incomplet. Le nom doit être complété !" + +#: ../Dialogs.py:241 +msgid "Form isn't complete. Valid block type must be selected!" +msgstr "Le formulaire est incomplet. Un type de bloc valide doit être sélectionné !" + +#: ../PLCOpenEditor.py:388 +msgid "Function" +msgstr "Fonction" + +#: ../PLCOpenEditor.py:390 +#: ../PLCOpenEditor.py:1811 +msgid "Function Block" +msgstr "Bloc fonctionnel" + +#: ../PLCOpenEditor.py:4506 +msgid "Function Block Types" +msgstr "Types de blocs fonctionnels" + +#: ../PLCControler.py:82 +msgid "Function Blocks" +msgstr "Blocs fonctionnels" + +#: ../Viewer.py:227 +msgid "Function Blocks can't be used in Functions!" +msgstr "Les blocs fonctionnels ne peuvent être utilisés dans des functions !" + +#: ../Viewer.py:229 +msgid "Function Blocks can't be used in Transitions!" +msgstr "Les blocs fonctionnels ne peuvent être utilisés dans des transitions" + +#: ../PLCControler.py:1673 +#, python-format +msgid "FunctionBlock \"%s\" can't be paste in a Function!!!" +msgstr "Le bloc fonctionnel \"%s\" ne peuvent être collés dans une function !" + +#: ../PLCControler.py:82 +msgid "Functions" +msgstr "Fonctions" + +#: ../PLCOpenEditor.py:328 +msgid "Generate Program\tCTRL+G" +msgstr "Générer le program\tCTRL+G" + +#: ../PLCOpenEditor.py:3861 +msgid "Global" +msgstr "Globale" + +#: ../PLCOpenEditor.py:2028 +msgid "Graphic Panel" +msgstr "Graphique" + +#: ../PLCOpenEditor.py:2983 +msgid "Graphics" +msgstr "Graphiques" + +#: ../plcopen/iec_std.csv:64 +msgid "Greater than" +msgstr "Supérieur à" + +#: ../plcopen/iec_std.csv:65 +msgid "Greater than or equal to" +msgstr "Supérieur ou égal à" + +#: ../PLCOpenEditor.py:2962 +msgid "Height:" +msgstr "Hauteur :" + +#: ../PLCOpenEditor.py:307 +msgid "Help" +msgstr "Aide" + +#: ../plcopen/structures.py:251 +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 "" + +#: ../PLCOpenEditor.py:3168 +#: ../PLCOpenEditor.py:3178 +#: ../PLCOpenEditor.py:3357 +#: ../PLCOpenEditor.py:3501 +msgid "IL" +msgstr "IL" + +#: ../PLCOpenEditor.py:3859 +#: ../Dialogs.py:426 +msgid "InOut" +msgstr "Entrée-Sortie" + +#: ../PLCOpenEditor.py:4089 +#, python-format +msgid "Incompatible data types between \"%s\" and \"%s\"" +msgstr "Types de donnée imcompatible entre \"%s\" et \"%s\"" + +#: ../PLCOpenEditor.py:4100 +#, python-format +msgid "Incompatible size of data between \"%s\" and \"%s\"" +msgstr "Taille de donnée incompatible entre \"%s\" et \"%s\"" + +#: ../PLCOpenEditor.py:4096 +#, python-format +msgid "Incompatible size of data between \"%s\" and \"BOOL\"" +msgstr "Taille de donnée incompatible entre \"%s\" et \"BOOL\"" + +#: ../Dialogs.py:2105 +msgid "Indicator" +msgstr "Indicateur" + +#: ../PLCOpenEditor.py:3848 +#: ../PLCOpenEditor.py:3849 +#: ../DataTypeEditor.py:46 +msgid "Initial Value" +msgstr "Valeur initiale" + +#: ../DataTypeEditor.py:388 +#: ../DataTypeEditor.py:412 +#: ../DataTypeEditor.py:463 +#: ../DataTypeEditor.py:505 +msgid "Initial Value:" +msgstr "Valeur initiale :" + +#: ../Dialogs.py:1725 +#: ../Dialogs.py:1793 +#: ../Dialogs.py:2109 +msgid "Inline" +msgstr "Inline" + +#: ../PLCOpenEditor.py:3859 +#: ../Dialogs.py:425 +#: ../Dialogs.py:1472 +msgid "Input" +msgstr "Entrée" + +#: ../Dialogs.py:126 +msgid "Inputs:" +msgstr "Entrées :" + +#: ../plcopen/iec_std.csv:76 +msgid "Insertion (into)" +msgstr "Insertion (au milieu)" + +#: ../plcopen/plcopen.py:1329 +#, python-format +msgid "Instance with id %d doesn't exists!" +msgstr "L'instance dont l'id est %d n'existe pas !" + +#: ../PLCOpenEditor.py:559 +#: ../PLCOpenEditor.py:597 +msgid "Instances" +msgstr "Instances" + +#: ../RessourceEditor.py:394 +msgid "Instances:" +msgstr "Instances :" + +#: ../plcopen/structures.py:231 +msgid "" +"Integral\n" +"The integral function block integrates the value of input XIN over time." +msgstr "" +"Intégrale\n" +"Le bloc fonctionnel INTEGRAL intègre les valeurs de l'entrée XIN en fonction du temps." + +#: ../PLCOpenEditor.py:3858 +msgid "Interface" +msgstr "Interface" + +#: ../RessourceEditor.py:79 +msgid "Interval" +msgstr "Interval" + +#: ../PLCControler.py:1654 +#: ../PLCControler.py:1688 +msgid "Invalid plcopen element(s)!!!" +msgstr "Les éléments plcopen ne sont pas valides !!! " + +#: ../PLCOpenEditor.py:4784 +#: ../PLCOpenEditor.py:4787 +#, python-format +msgid "Invalid value \"%s\" for debug variable" +msgstr "Chemin de variable à déboguer \"%s\" invalide" + +#: ../PLCOpenEditor.py:4077 +#: ../PLCOpenEditor.py:4080 +#, python-format +msgid "Invalid value \"%s\" for location" +msgstr "Adresse \"%s\" invalide " + +#: ../Viewer.py:211 +#: ../Viewer.py:214 +#, python-format +msgid "Invalid value \"%s\" for viewer block" +msgstr "Valeur \"%s\" invalide pour un élément graphique" + +#: ../PLCOpenEditor.py:2978 +#: ../PLCOpenEditor.py:3168 +#: ../PLCOpenEditor.py:3178 +#: ../PLCOpenEditor.py:3357 +#: ../PLCOpenEditor.py:3501 +msgid "LD" +msgstr "LD" + +#: ../LDViewer.py:213 +#: ../LDViewer.py:228 +#, python-format +msgid "Ladder element with id %d is on more than one rung." +msgstr "L'élément de LD dont l'id est %d apparait dans plusieurs échelons. " + +#: ../PLCOpenEditor.py:3276 +#: ../PLCOpenEditor.py:3439 +#: ../PLCOpenEditor.py:3583 +msgid "Language" +msgstr "Langue" + +#: ../PLCOpenEditor.py:2992 +msgid "Language (optional):" +msgstr "Langue (optionnel) :" + +#: ../PLCOpenEditor.py:3244 +#: ../PLCOpenEditor.py:3412 +#: ../PLCOpenEditor.py:3556 +msgid "Language:" +msgstr "Langue :" + +#: ../Viewer.py:358 +msgid "Left" +msgstr "Gauche" + +#: ../Dialogs.py:1287 +msgid "Left PowerRail" +msgstr "Barre d'alimentation à gauche" + +#: ../plcopen/iec_std.csv:70 +msgid "Length of string" +msgstr "Longueur de la chaîne" + +#: ../plcopen/iec_std.csv:67 +msgid "Less than" +msgstr "Inférieur à" + +#: ../plcopen/iec_std.csv:68 +msgid "Less than or equal to" +msgstr "Inférieur ou égal à" + +#: ../PLCOpenEditor.py:638 +msgid "Library" +msgstr "Librairie" + +#: ../plcopen/iec_std.csv:62 +msgid "Limitation" +msgstr "Limitation" + +#: ../PLCOpenEditor.py:3860 +msgid "Local" +msgstr "Locale" + +#: ../PLCOpenEditor.py:3848 +msgid "Location" +msgstr "Adresse" + +#: ../plcopen/iec_std.csv:25 +msgid "Logarithm to base 10" +msgstr "Logarithme de base 10" + +#: ../plcopen/iec_std.csv:60 +msgid "Maximum" +msgstr "Maximum" + +#: ../DataTypeEditor.py:430 +msgid "Maximum:" +msgstr "Maximum :" + +#: ../Viewer.py:367 +msgid "Middle" +msgstr "Milieu" + +#: ../plcopen/iec_std.csv:61 +msgid "Minimum" +msgstr "Minimum" + +#: ../DataTypeEditor.py:421 +msgid "Minimum:" +msgstr "Minimum :" + +#: ../PLCOpenEditor.py:3007 +msgid "Miscellaneous" +msgstr "Divers" + +#: ../Dialogs.py:1022 +msgid "Modifier:" +msgstr "Modificateur :" + +#: ../PLCGenerator.py:672 +#: ../PLCGenerator.py:876 +#, python-format +msgid "More than one connector found corresponding to \"%s\" continuation in \"%s\" POU" +msgstr "Plusieurs connecteurs trouvés pour le prolongement \"%s\" dans le POU \"%s\"" + +#: ../DataTypeEditor.py:459 +#: ../DataTypeEditor.py:501 +msgid "Move down" +msgstr "Déplcer vers le haut" + +#: ../DataTypeEditor.py:456 +#: ../DataTypeEditor.py:498 +msgid "Move up" +msgstr "Déplacer vers le bas" + +#: ../plcopen/iec_std.csv:63 +msgid "Multiplexer (select 1 of N)" +msgstr "Multipléxeur (sélection 1 sur N)" + +#: ../plcopen/iec_std.csv:37 +msgid "Multiplication" +msgstr "Multiplication" + +#: ../PLCOpenEditor.py:3848 +#: ../PLCOpenEditor.py:3849 +#: ../RessourceEditor.py:79 +#: ../RessourceEditor.py:83 +#: ../DataTypeEditor.py:46 +msgid "Name" +msgstr "Nom" + +#: ../Dialogs.py:122 +#: ../Dialogs.py:520 +#: ../Dialogs.py:792 +#: ../Dialogs.py:1026 +#: ../Dialogs.py:1455 +msgid "Name:" +msgstr "Nom :" + +#: ../plcopen/iec_std.csv:24 +msgid "Natural logarithm" +msgstr "Logarithme népérien" + +#: ../Viewer.py:390 +#: ../Dialogs.py:1040 +msgid "Negated" +msgstr "Inversé" + +#: ../PLCOpenEditor.py:312 +msgid "New\tCTRL+N" +msgstr "Nouveau\tCTRL+N" + +#: ../DataTypeEditor.py:450 +#: ../DataTypeEditor.py:492 +msgid "New item" +msgstr "Nouvel élément" + +#: ../PLCOpenEditor.py:3853 +msgid "No" +msgstr "Non" + +#: ../Viewer.py:388 +msgid "No Modifier" +msgstr "Pas de modificateur" + +#: ../PLCControler.py:2535 +msgid "No PLC project found" +msgstr "Pas de projet d'automate trouvé" + +#: ../PLCGenerator.py:1257 +#, python-format +msgid "No body defined in \"%s\" POU" +msgstr "Pas de code défini dans le POU \"%s\"" + +#: ../PLCGenerator.py:691 +#: ../PLCGenerator.py:885 +#, python-format +msgid "No connector found corresponding to \"%s\" continuation in \"%s\" POU" +msgstr "Pas de connecteur trouvé pour le prolongement \"%s\" dans le POU \"%s\"" + +#: ../PLCOpenEditor.py:2606 +msgid "" +"No documentation available.\n" +"Coming soon." +msgstr "" +"Pas de documentation.\n" +"Bientôt disponible." + +#: ../PLCGenerator.py:743 +#, python-format +msgid "No informations found for \"%s\" block" +msgstr "" + +#: ../plcopen/structures.py:139 +msgid "No output variable found" +msgstr "Pas de variable de sortie trouvée." + +#: ../PLCGenerator.py:1255 +#, python-format +msgid "No variable defined in \"%s\" POU" +msgstr "Pas de varaibles définies dans le POU \"%s\"" + +#: ../Dialogs.py:1034 +msgid "Normal" +msgstr "Normal" + +#: ../plcopen/iec_std.csv:69 +msgid "Not equal to" +msgstr "Non égal à" + +#: ../Dialogs.py:2008 +msgid "Number of sequences:" +msgstr "Nombre de branches :" + +#: ../plcopen/iec_std.csv:22 +msgid "Numerical" +msgstr "Numérique" + +#: ../plcopen/structures.py:219 +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/structures.py:214 +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 "" + +#: ../PLCOpenEditor.py:314 +msgid "Open\tCTRL+O" +msgstr "Ouvrir\tCTRL+O" + +#: ../PLCOpenEditor.py:2934 +msgid "Organization (optional):" +msgstr "Groupe (optionnel) :" + +#: ../PLCOpenEditor.py:3859 +#: ../Dialogs.py:427 +#: ../Dialogs.py:1477 +msgid "Output" +msgstr "Sortie" + +#: ../plcopen/structures.py:241 +msgid "" +"PID\n" +"The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control." +msgstr "" +"PID\n" +"Le bloc fonctionnel PID (Proportionnel, Intégrale, Dérivée) fournit un controller de boucle fermé classique à trois paramètres." + +#: ../PLCOpenEditor.py:1031 +#: ../PLCOpenEditor.py:1118 +msgid "PLCOpen files (*.xml)|*.xml|All files|*.*" +msgstr "Fichiers PLCOpen (*.xml)|*.xml|Tous les fichiers|*.*" + +#: ../PLCOpenEditor.py:485 +#: ../PLCOpenEditor.py:838 +msgid "PLCOpenEditor" +msgstr "PLCOpenEditor" + +#: ../PLCOpenEditor.py:438 +msgid "PLCOpenEditor\tF1" +msgstr "PLCOpenEditor\tF1" + +#: ../PLCOpenEditor.py:3272 +msgid "POU Name" +msgstr "Nom du POU" + +#: ../PLCOpenEditor.py:3227 +msgid "POU Name:" +msgstr "Nom du POU :" + +#: ../PLCOpenEditor.py:3274 +msgid "POU Type" +msgstr "Type du POU" + +#: ../PLCOpenEditor.py:3235 +msgid "POU Type:" +msgstr "Type du POU :" + +#: ../PLCOpenEditor.py:331 +msgid "Page Setup" +msgstr "Mise en page..." + +#: ../PLCOpenEditor.py:2950 +msgid "Page Size (optional):" +msgstr "Taille de la page (optionnel) :" + +#: ../PLCOpenEditor.py:5000 +#, python-format +msgid "Page: %d" +msgstr "Page: %d" + +#: ../PLCOpenEditor.py:381 +msgid "Paste\tCTRL+V" +msgstr "Coller\tCTRL+V" + +#: ../Dialogs.py:1279 +msgid "Pin number:" +msgstr "Nombre de pattes :" + +#: ../Viewer.py:1971 +#: ../Viewer.py:2262 +#: ../SFCViewer.py:698 +msgid "Please choose a target" +msgstr "Choisissez une cible" + +#: ../PLCOpenEditor.py:2461 +msgid "Please enter POU name" +msgstr "Saisissez le nom du POU" + +#: ../Viewer.py:1796 +#: ../Viewer.py:1798 +#: ../Viewer.py:2297 +#: ../Viewer.py:2299 +msgid "Please enter comment text" +msgstr "Saisissez le texte du commentaire" + +#: ../PLCOpenEditor.py:2416 +#: ../PLCOpenEditor.py:3647 +msgid "Please enter configuration name" +msgstr "Saisissez le nom de la configuration" + +#: ../PLCOpenEditor.py:2359 +msgid "Please enter data type name" +msgstr "Saisissez le nom du type de donnée" + +#: ../PLCOpenEditor.py:2431 +#: ../PLCOpenEditor.py:3710 +msgid "Please enter resource name" +msgstr "Saisissez le nom de la ressource" + +#: ../SFCViewer.py:362 +#: ../SFCViewer.py:384 +#: ../SFCViewer.py:726 +msgid "Please enter step name" +msgstr "Saisissez le nom de l'étape" + +#: ../PLCOpenEditor.py:3118 +msgid "Please enter text" +msgstr "Saisissez le texte" + +#: ../GraphicViewer.py:117 +msgid "Position:" +msgstr "Position :" + +#: ../Dialogs.py:1271 +msgid "Power Rail Properties" +msgstr "Propriétés de la barre d'alimentation" + +#: ../PLCOpenEditor.py:333 +msgid "Preview" +msgstr "Aperçu avant impression" + +#: ../Dialogs.py:138 +#: ../Dialogs.py:524 +#: ../Dialogs.py:796 +#: ../Dialogs.py:1030 +#: ../Dialogs.py:1283 +#: ../Dialogs.py:1463 +#: ../Dialogs.py:1706 +#: ../Dialogs.py:2017 +msgid "Preview:" +msgstr "Aperçu :" + +#: ../PLCOpenEditor.py:335 +msgid "Print" +msgstr "Imprimer" + +#: ../PLCOpenEditor.py:1150 +msgid "Print preview" +msgstr "Aperçu avant impression" + +#: ../RessourceEditor.py:79 +msgid "Priority" +msgstr "Priorité" + +#: ../Dialogs.py:1710 +msgid "Priority:" +msgstr "Priorité :" + +#: ../PLCOpenEditor.py:2878 +msgid "Product Name (required):" +msgstr "Nom du produit (obligatoire) :" + +#: ../PLCOpenEditor.py:2894 +msgid "Product Release (optional):" +msgstr "Publication du produit (optionnel) :" + +#: ../PLCOpenEditor.py:2886 +msgid "Product Version (required):" +msgstr "Version du produit (obligatoire) :" + +#: ../PLCOpenEditor.py:392 +#: ../PLCOpenEditor.py:1814 +msgid "Program" +msgstr "Programme" + +#: ../PLCOpenEditor.py:1095 +msgid "Program was successfully generated!" +msgstr "Le programme a été généré avec succès !" + +#: ../PLCControler.py:83 +msgid "Programs" +msgstr "Programmes" + +#: ../Viewer.py:220 +msgid "Programs can't be used by other POUs!" +msgstr "Les programmes ne peuvent être utilisés par les autres POUs !" + +#: ../PLCOpenEditor.py:497 +#: ../PLCOpenEditor.py:2901 +msgid "Project" +msgstr "Projet" + +#: ../PLCOpenEditor.py:2862 +msgid "Project Name (required):" +msgstr "Nom du projet (obligatoire) :" + +#: ../PLCOpenEditor.py:2870 +msgid "Project Version (optional):" +msgstr "Version du projet (optionnel) :" + +#: ../PLCOpenEditor.py:2848 +msgid "Project properties" +msgstr "Propriétés du projet" + +#: ../PLCOpenEditor.py:339 +#: ../PLCControler.py:84 +msgid "Properties" +msgstr "Propriétés" + +#: ../plcopen/structures.py:209 +msgid "" +"Pulse timer\n" +"The pulse timer can be used to generate output pulses of a given time duration." +msgstr "" + +#: ../Dialogs.py:2105 +msgid "Qualifier" +msgstr "Qualificatif" + +#: ../PLCOpenEditor.py:343 +msgid "Quit\tCTRL+Q" +msgstr "Quitter\tCTRL+Q" + +#: ../plcopen/structures.py:174 +msgid "" +"RS bistable\n" +"The RS bistable is a latch where the Reset dominates." +msgstr "" +"Bascule RS\n" +"La bascule RS est une bascule où le Reset est dominant." + +#: ../plcopen/structures.py:246 +msgid "" +"Ramp\n" +"The RAMP function block is modelled on example given in the standard but with the addition of a 'Holdback' feature." +msgstr "" +"Rampe\n" +"Le bloc fonctionnel RAMP est basé sur l'exemple du standard mais avec en supplément un paramètre 'Holdback'." + +#: ../GraphicViewer.py:106 +msgid "Range:" +msgstr "Echelle :" + +#: ../PLCOpenEditor.py:374 +msgid "Redo\tCTRL+Y" +msgstr "Refaire\tCTRL+Y" + +#: ../Dialogs.py:1714 +#: ../Dialogs.py:1791 +msgid "Reference" +msgstr "Référence" + +#: ../PLCOpenEditor.py:420 +msgid "Refresh\tF5" +msgstr "Actualiser\tF5" + +#: ../plcopen/iec_std.csv:48 +msgid "Remainder (modulo)" +msgstr "Modulo" + +#: ../PLCOpenEditor.py:1818 +msgid "Rename" +msgstr "Renommer" + +#: ../plcopen/iec_std.csv:78 +msgid "Replacement (within)" +msgstr "Remplacement (au milieu)" + +#: ../Dialogs.py:1050 +msgid "Reset" +msgstr "Mise à zéro" + +#: ../Viewer.py:409 +msgid "Reset Execution Order" +msgstr "Réinitialiser l'order d'exécution" + +#: ../PLCControler.py:84 +msgid "Resources" +msgstr "Ressources" + +#: ../PLCOpenEditor.py:3848 +#: ../PLCOpenEditor.py:3849 +msgid "Retain" +msgstr "Persistante" + +#: ../PLCOpenEditor.py:4227 +msgid "Return Type:" +msgstr "Type de retour :" + +#: ../Viewer.py:362 +msgid "Right" +msgstr "Droite" + +#: ../Dialogs.py:1293 +msgid "Right PowerRail" +msgstr "Barre d'alimentation à droite" + +#: ../Viewer.py:392 +#: ../Dialogs.py:1055 +msgid "Rising Edge" +msgstr "Front montant" + +#: ../plcopen/structures.py:184 +msgid "" +"Rising edge detector\n" +"The output produces a single pulse when a rising edge is detected." +msgstr "" +"Détecteur de front montant\n" +"La sortie produit une impulsion unique lorsqu'un front montant est détecté." + +#: ../plcopen/iec_std.csv:54 +msgid "Rotate left" +msgstr "Rotation à gauche" + +#: ../plcopen/iec_std.csv:53 +msgid "Rotate right" +msgstr "Rotation à droite" + +#: ../plcopen/iec_std.csv:17 +msgid "Rounding up/down" +msgstr "Arrondi" + +#: ../PLCOpenEditor.py:2978 +#: ../PLCOpenEditor.py:3178 +msgid "SFC" +msgstr "SFC" + +#: ../plcopen/structures.py:169 +msgid "" +"SR bistable\n" +"The SR bistable is a latch where the Set dominates." +msgstr "" +"Bascule SR\n" +"La bascule SR est une bascule où le Set est dominant." + +#: ../PLCOpenEditor.py:3168 +#: ../PLCOpenEditor.py:3178 +#: ../PLCOpenEditor.py:3357 +#: ../PLCOpenEditor.py:3501 +msgid "ST" +msgstr "ST" + +#: ../PLCOpenEditor.py:1082 +msgid "ST files (*.st)|*.st|All files|*.*" +msgstr "Fichiers ST (*.st)|*.st|Tous les fichiers|*.*" + +#: ../PLCOpenEditor.py:323 +msgid "Save\tCTRL+S" +msgstr "Enregistrer\tCTRL+S" + +#: ../PLCOpenEditor.py:326 +msgid "Save As...\tCTRL+SHIFT+S" +msgstr "Enregistrer sous...\tCTRL+SHIFT+S" + +#: ../PLCOpenEditor.py:2970 +msgid "Scaling:" +msgstr "Echelle :" + +#: ../PLCOpenEditor.py:396 +msgid "Select All\tCTRL+A" +msgstr "Tout sélectionner\tCTRL+A" + +#: ../PLCOpenEditor.py:4102 +msgid "Select a variable class:" +msgstr "Sélectionner une direction pour la variable :" + +#: ../PLCOpenEditor.py:604 +#: ../PLCOpenEditor.py:616 +msgid "Select an object" +msgstr "Sélectionner un objet" + +#: ../plcopen/iec_std.csv:59 +msgid "Selection" +msgstr "Sélection" + +#: ../Dialogs.py:1990 +msgid "Selection Convergence" +msgstr "Convergence simple" + +#: ../Dialogs.py:1984 +msgid "Selection Divergence" +msgstr "Divergence simple" + +#: ../plcopen/structures.py:179 +msgid "" +"Semaphore\n" +"The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources." +msgstr "" +"Sémaphore\n" +"La sémaphore fournit un mécanisme permettant à des éléments du programme d'accéder de façon exclusive à certaines resources." + +#: ../Dialogs.py:1045 +msgid "Set" +msgstr "Mise à 1" + +#: ../plcopen/iec_std.csv:51 +msgid "Shift left" +msgstr "Décalage à gauche" + +#: ../plcopen/iec_std.csv:52 +msgid "Shift right" +msgstr "Décalage à droite" + +#: ../Dialogs.py:2002 +msgid "Simultaneous Convergence" +msgstr "Convergence double" + +#: ../Dialogs.py:1996 +msgid "Simultaneous Divergence" +msgstr "Divergence double" + +#: ../plcopen/iec_std.csv:27 +msgid "Sine" +msgstr "Sinus" + +#: ../RessourceEditor.py:79 +msgid "Single" +msgstr "Evènement" + +#: ../plcopen/iec_std.csv:23 +msgid "Square root (base 2)" +msgstr "Racine carré (base 2)" + +#: ../plcopen/structures.py:165 +msgid "Standard function blocks" +msgstr "Blocs fonctionnels standards" + +#: ../DataTypeEditor.py:236 +msgid "Structure" +msgstr "Structure" + +#: ../DataTypeEditor.py:236 +msgid "Subrange" +msgstr "Sous-ensemble" + +#: ../plcopen/iec_std.csv:39 +msgid "Subtraction" +msgstr "Soustraction" + +#: ../plcopen/iec_std.csv:29 +msgid "Tangent" +msgstr "Tangente" + +#: ../RessourceEditor.py:83 +msgid "Task" +msgstr "Tâche" + +#: ../RessourceEditor.py:358 +msgid "Tasks:" +msgstr "Tâches :" + +#: ../PLCOpenEditor.py:3861 +msgid "Temp" +msgstr "Temporaire" + +#: ../LDViewer.py:850 +msgid "The group of block must be coherent!" +msgstr "Le groupe de blocs doit être cohérent !" + +#: ../PLCOpenEditor.py:961 +msgid "There are changes, do you want to save?" +msgstr "Le projet a été modifié. Voulez-vous l'enregistrer ?" + +#: ../PLCOpenEditor.py:1169 +msgid "" +"There was a problem printing.\n" +"Perhaps your current printer is not set correctly?" +msgstr "" +"Un problème est apparu lors de l'impression.\n" +"Peut-être que votre imprimante n'est pas correctement configurée ?" + +#: ../LDViewer.py:859 +msgid "This option isn't available yet!" +msgstr "Cette option n'a pas encore disponible" + +#: ../GraphicViewer.py:181 +msgid "Tick" +msgstr "Tick" + +#: ../plcopen/iec_std.csv:34 +msgid "Time addition" +msgstr "Addition de durée" + +#: ../plcopen/iec_std.csv:75 +msgid "Time concatenation" +msgstr "Concaténation de date et de durée" + +#: ../plcopen/iec_std.csv:47 +msgid "Time division" +msgstr "Division de durée" + +#: ../plcopen/iec_std.csv:38 +msgid "Time multiplication" +msgstr "Multiplication de durée" + +#: ../plcopen/iec_std.csv:40 +msgid "Time subtraction" +msgstr "Soustraction de durée" + +#: ../plcopen/iec_std.csv:35 +msgid "Time-of-day addition" +msgstr "Addition d'horodatage" + +#: ../plcopen/iec_std.csv:42 +#: ../plcopen/iec_std.csv:43 +msgid "Time-of-day subtraction" +msgstr "Soustraction d'horodatage" + +#: ../PLCOpenEditor.py:608 +msgid "Toolbar" +msgstr "Barre d'outils" + +#: ../Viewer.py:365 +msgid "Top" +msgstr "Haut" + +#: ../PLCOpenEditor.py:3437 +msgid "Transition Name" +msgstr "Nom de la transition" + +#: ../PLCOpenEditor.py:3404 +msgid "Transition Name:" +msgstr "Nom de la transition :" + +#: ../PLCGenerator.py:1237 +#, python-format +msgid "Transition with content \"%s\" not connected to a next step in \"%s\" POU" +msgstr "La transition contenant \"%s\" n'est pas connectée à une étape en sortie dans le POU \"%s\" !" + +#: ../PLCGenerator.py:1228 +#, python-format +msgid "Transition with content \"%s\" not connected to a previous step in \"%s\" POU" +msgstr "La transition contenant \"%s\" n'est pas connectée à une étape en entrée dans le POU \"%s\" !" + +#: ../plcopen/plcopen.py:1035 +#, python-format +msgid "Transition with name %s doesn't exists!" +msgstr "La transition nommée %s n'existe pas !" + +#: ../PLCControler.py:83 +msgid "Transitions" +msgstr "Transitions" + +#: ../PLCOpenEditor.py:3848 +#: ../PLCOpenEditor.py:3849 +#: ../RessourceEditor.py:83 +#: ../Dialogs.py:2105 +#: ../DataTypeEditor.py:46 +msgid "Type" +msgstr "Type" + +#: ../plcopen/iec_std.csv:16 +msgid "Type conversion" +msgstr "Conversion de type" + +#: ../DataTypeEditor.py:360 +msgid "Type infos:" +msgstr "Propriétés du type :" + +#: ../Dialogs.py:118 +#: ../Dialogs.py:788 +#: ../Dialogs.py:1275 +#: ../Dialogs.py:1702 +#: ../Dialogs.py:1980 +msgid "Type:" +msgstr "Type :" + +#: ../PLCOpenEditor.py:560 +#: ../PLCOpenEditor.py:596 +msgid "Types" +msgstr "Types" + +#: ../PLCGenerator.py:232 +#, python-format +msgid "Undefined pou type \"%s\"" +msgstr "Type de POU \"%s\" indéterminé !" + +#: ../PLCOpenEditor.py:372 +msgid "Undo\tCTRL+Z" +msgstr "Défaire\tCTRL+Z" + +#: ../Viewer.py:286 +#, python-format +msgid "Unknown variable \"%s\" for this POU!" +msgstr "Variable \"%s\" inconnue dans ce POU !" + +#: ../PLCControler.py:293 +#, python-format +msgid "Unnamed%d" +msgstr "Sansnom%d" + +#: ../PLCOpenEditor.py:4098 +#, python-format +msgid "Unrecognized data size \"%s\"" +msgstr "Taille de donnée \"%s\" non identifié !" + +#: ../plcopen/structures.py:194 +msgid "" +"Up-counter\n" +"The up-counter can be used to signal when a count has reached a maximum value." +msgstr "" +"Compteur incrémental\n" +"Le compteur incrémental peut être utilisé pour signaler lorsque le compteur a atteint la valeur maximale." + +#: ../plcopen/structures.py:204 +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 "" +"Compteur bidirectionnel\n" +"Le compteur bidirectionnel a deux entrées CU et CD. Il peut être utilisé pour compter de façon incrémentale ou décrémentale sur l'une ou l'autre des entrées." + +#: ../PLCOpenEditor.py:4497 +#: ../DataTypeEditor.py:804 +msgid "User Data Types" +msgstr "Types de donnée du projet" + +#: ../PLCControler.py:82 +msgid "User-defined POUs" +msgstr "POUs du projet" + +#: ../PLCOpenEditor.py:4614 +#: ../Dialogs.py:2105 +msgid "Value" +msgstr "Valeur" + +#: ../GraphicViewer.py:181 +msgid "Values" +msgstr "Valeurs" + +#: ../DataTypeEditor.py:445 +msgid "Values:" +msgstr "Valeurs" + +#: ../PLCOpenEditor.py:4614 +#: ../Dialogs.py:2109 +msgid "Variable" +msgstr "Variable" + +#: ../Dialogs.py:504 +msgid "Variable Properties" +msgstr "Propriétés de la variable" + +#: ../PLCOpenEditor.py:4102 +msgid "Variable class" +msgstr "Direction de la variable" + +#: ../Viewer.py:288 +#: ../TextViewer.py:224 +msgid "Variable don't belong to this POU!" +msgstr "La variable n'appartient pas à ce POU !" + +#: ../PLCOpenEditor.py:573 +#: ../PLCOpenEditor.py:624 +#: ../PLCOpenEditor.py:3860 +msgid "Variables" +msgstr "Variables" + +#: ../PLCOpenEditor.py:3302 +#: ../PLCOpenEditor.py:3680 +#: ../PLCOpenEditor.py:3743 +#: ../LDViewer.py:859 +msgid "Warning" +msgstr "Attention" + +#: ../PLCOpenEditor.py:2954 +msgid "Width:" +msgstr "Longueur :" + +#: ../PLCOpenEditor.py:2697 +msgid "X Scale:" +msgstr "Echelle X :" + +#: ../PLCOpenEditor.py:2705 +msgid "Y Scale:" +msgstr "Echelle Y :" + +#: ../PLCOpenEditor.py:3853 +msgid "Yes" +msgstr "Oui" + +#: ../LDViewer.py:854 +msgid "You must select the block or group of blocks around which a branch should be added!" +msgstr "Vous devez sélectionné le bloc ou le group autour duquel un ebranche doit être ajoutée !" + +#: ../LDViewer.py:628 +msgid "You must select the wire where a contact should be added!" +msgstr "Vous devez sélectionner le fil sur lequel le contact doit être ajouté !" + +#: ../PLCOpenEditor.py:3133 +#: ../PLCOpenEditor.py:3664 +#: ../PLCOpenEditor.py:3727 +#: ../Dialogs.py:1525 +#: ../Dialogs.py:2508 +#: ../Dialogs.py:2575 +msgid "You must type a name!" +msgstr "Vous devez saisir un nom !" + +#: ../PLCOpenEditor.py:426 +msgid "Zoom" +msgstr "Zoom" + +#: ../PLCOpenEditor.py:1091 +#, python-format +msgid "error: %s\n" +msgstr "erreur: %s\n" + +#: ../PLCOpenEditor.py:5032 +#: ../PLCOpenEditor.py:5034 +msgid "file : " +msgstr "fichier :" + +#: ../PLCOpenEditor.py:3173 +msgid "function" +msgstr "fonction" + +#: ../PLCOpenEditor.py:5035 +msgid "function : " +msgstr "fonction :" + +#: ../PLCOpenEditor.py:3173 +msgid "functionBlock" +msgstr "Bloc fonctionnel" + +#: ../PLCOpenEditor.py:5035 +msgid "line : " +msgstr "ligne :" + +#: ../PLCOpenEditor.py:3173 +msgid "program" +msgstr "programme" + +#: ../plcopen/iec_std.csv:73 +msgid "string from the middle" +msgstr "Caractères du milieu" + +#: ../plcopen/iec_std.csv:71 +msgid "string left of" +msgstr "Caractères à gauche de" + +#: ../plcopen/iec_std.csv:72 +msgid "string right of" +msgstr "Caractères à droite de" + +#: ../PLCOpenEditor.py:1089 +#, python-format +msgid "warning: %s\n" +msgstr "attention: %s\n" + +#~ msgid "" +#~ "A variable is defined with \"%s\" as name. It can generate a conflict. Do " +#~ "you wish to continue?" +#~ msgstr "Une variable" +#~ msgid "A pou with \"%s\" for name exists!" +#~ msgstr "Un POU nommé \"%s\" existe déjà !" +#~ msgid "Create A New POU From" +#~ msgstr "Créer un nouveau POU à partir de" + diff -r 020420ad8914 -r 07447ee3538e i18n/PLCOpenEditor_zh_CN.po --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i18n/PLCOpenEditor_zh_CN.po Fri Jul 24 17:12:59 2009 +0200 @@ -0,0 +1,2334 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-06-24 18:43+0200\n" +"PO-Revision-Date: 2009-06-25 11:55+0100\n" +"Last-Translator: \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: PLCOpenEditor.py:5108 +msgid "" +"\n" +"An error happens.\n" +"\n" +"Click on OK for saving an error report.\n" +"\n" +"Please contact LOLITech at:\n" +"+33 (0)3 29 57 60 42\n" +"bugs_PLCOpenEditor@lolitech.fr\n" +"\n" +"\n" +"Error:\n" +msgstr "" +"\n" +"一个错误发生了。\n" +"\n" +"点击确定以保存一个错误报告。\n" +"\n" +"请用以下方式联系LOLITech:\n" +"+33 (0)3 29 57 60 42\n" +"bugs_PLCOpenEditor@lolitech.fr\n" +"\n" +"\n" +"错误:\n" + +#: PLCOpenEditor.py:3923 +msgid " External" +msgstr " 外部" + +#: PLCOpenEditor.py:3922 +msgid " InOut" +msgstr " 输入" + +#: PLCOpenEditor.py:3922 +msgid " Input" +msgstr " 输入" + +#: PLCOpenEditor.py:3923 +msgid " Local" +msgstr " 本地" + +#: PLCOpenEditor.py:3922 +msgid " Output" +msgstr " 输出" + +#: PLCOpenEditor.py:3924 +msgid " Temp" +msgstr " 缓冲" + +#: PLCOpenEditor.py:841 +msgid " (Debug)" +msgstr " (调试)" + +#: PLCOpenEditor.py:5120 +msgid " : " +msgstr ":" + +#: PLCOpenEditor.py:3346 +#: PLCOpenEditor.py:3509 +#: PLCOpenEditor.py:3653 +#: Dialogs.py:1796 +#, python-format +msgid " and %s" +msgstr "和 %s" + +#: plcopen/plcopen.py:754 +#, python-format +msgid "\"%s\" Data Type doesn't exist !!!" +msgstr "\"%s\" 数据类型尚不存在!!!" + +#: plcopen/plcopen.py:772 +#, python-format +msgid "\"%s\" POU already exists !!!" +msgstr "\"%s\"编程组织单元已经存在!!!" + +#: plcopen/plcopen.py:793 +#, python-format +msgid "\"%s\" POU doesn't exist !!!" +msgstr "\"%s\" POU不存在!!!" + +#: Viewer.py:228 +#, python-format +msgid "\"%s\" can't use itself!" +msgstr "\"%s\" 不能自己使用!" + +#: PLCOpenEditor.py:1644 +#: PLCOpenEditor.py:1669 +#, python-format +msgid "\"%s\" config already exists!" +msgstr "\"%s\" 配置已存在!" + +#: plcopen/plcopen.py:257 +#, python-format +msgid "\"%s\" configuration already exists !!!" +msgstr "\"%s\" 配置已存在!!!" + +#: PLCOpenEditor.py:1588 +#: PLCOpenEditor.py:3207 +#, python-format +msgid "\"%s\" data type already exists!" +msgstr "\"%s\" 数据类型已存在!" + +#: PLCControler.py:1648 +#, python-format +msgid "\"%s\" element can't be paste here!!!" +msgstr "\"%s\" 元素不能粘贴在这里!!!" + +#: PLCOpenEditor.py:3528 +#: PLCOpenEditor.py:3672 +#: Viewer.py:251 +#: Dialogs.py:257 +#: Dialogs.py:894 +#, python-format +msgid "\"%s\" element for this pou already exists!" +msgstr "\"%s\" " + +#: plcopen/structures.py:97 +#, python-format +msgid "\"%s\" function cancelled in \"%s\" POU: No input connected" +msgstr "\"%s\" 功能被取消 \"%s\" 在POU中:没有输入连接" + +#: PLCOpenEditor.py:1579 +#: PLCOpenEditor.py:3203 +#: PLCOpenEditor.py:3357 +#: PLCOpenEditor.py:3520 +#: PLCOpenEditor.py:3664 +#: PLCOpenEditor.py:3735 +#: PLCOpenEditor.py:3798 +#: PLCOpenEditor.py:4513 +#: Dialogs.py:249 +#: Dialogs.py:648 +#: Dialogs.py:886 +#: Dialogs.py:1529 +#: Dialogs.py:2513 +#: Dialogs.py:2580 +#: DataTypeEditor.py:698 +#: DataTypeEditor.py:758 +#, python-format +msgid "\"%s\" is a keyword. It can't be used!" +msgstr "\"%s\" 是一个关键词。它不能被使用!" + +#: Viewer.py:234 +#, python-format +msgid "\"%s\" is already used by \"%s\"!" +msgstr "\"%s\" 已被 \"%s\" 使用!" + +#: plcopen/plcopen.py:2056 +#, python-format +msgid "\"%s\" is an invalid value!" +msgstr "\"%s\"不是有效值!" + +#: PLCOpenEditor.py:1098 +#: PLCOpenEditor.py:1127 +#, python-format +msgid "\"%s\" is not a valid folder!" +msgstr "\"%s\"不是有效文件夹!" + +#: PLCOpenEditor.py:1577 +#: PLCOpenEditor.py:3199 +#: PLCOpenEditor.py:3353 +#: PLCOpenEditor.py:3516 +#: PLCOpenEditor.py:3660 +#: PLCOpenEditor.py:3731 +#: PLCOpenEditor.py:3794 +#: PLCOpenEditor.py:4508 +#: Dialogs.py:245 +#: Dialogs.py:882 +#: Dialogs.py:1525 +#: Dialogs.py:2509 +#: Dialogs.py:2576 +#: DataTypeEditor.py:753 +#, python-format +msgid "\"%s\" is not a valid identifier!" +msgstr "\"%s\"不是有效标识符!" + +#: PLCOpenEditor.py:283 +#: PLCOpenEditor.py:2553 +#: PLCOpenEditor.py:2582 +#, python-format +msgid "\"%s\" is used by one or more POUs. It can't be removed!" +msgstr "%s 正在被一个或多个POU使用。不能被删除!" + +#: PLCOpenEditor.py:1597 +#: PLCOpenEditor.py:3361 +#: Viewer.py:249 +#: Dialogs.py:253 +#: Dialogs.py:890 +#, python-format +msgid "\"%s\" pou already exists!" +msgstr "\"%s\"编程组织单元已经存在!" + +#: plcopen/plcopen.py:288 +#, python-format +msgid "\"%s\" resource already exists in \"%s\" configuration !!!" +msgstr "\"%s\" 资源已经存在于 \"%s\" 配置中!!!" + +#: plcopen/plcopen.py:304 +#, python-format +msgid "\"%s\" resource doesn't exist in \"%s\" configuration !!!" +msgstr "\"%s\" 资源不存在于 \"%s\" 配置之内!!!" + +#: Dialogs.py:1541 +#: Dialogs.py:2525 +#, python-format +msgid "\"%s\" step already exists!" +msgstr "\"%s\"步骤已经存在!" + +#: DataTypeEditor.py:693 +#, python-format +msgid "\"%s\" value already defined!" +msgstr "\"%s\" 值已经被定义!" + +#: DataTypeEditor.py:895 +#, python-format +msgid "\"%s\" value isn't a valid array dimension!" +msgstr "\"%s\" 值不是有效数组维数!" + +#: DataTypeEditor.py:902 +#, python-format +msgid "" +"\"%s\" value isn't a valid array dimension!\n" +"Right value must be greater than left value." +msgstr "" +"\"%s\" 不是一个有效的数组维数值!\n" +"右边的数值必须大于左边的数值。" + +#: GraphicViewer.py:181 +#, python-format +msgid "%s Graphics" +msgstr "%s 图形" + +#: plcopen/plcopen.py:1181 +#: plcopen/plcopen.py:1191 +#: plcopen/plcopen.py:1201 +#: plcopen/plcopen.py:1211 +#: plcopen/plcopen.py:1220 +#, python-format +msgid "%s body don't have instances!" +msgstr "%s 未包含实例!" + +#: plcopen/plcopen.py:1243 +#: plcopen/plcopen.py:1250 +#, python-format +msgid "%s body don't have text!" +msgstr "%s 未包含文本!" + +#: PLCOpenEditor.py:5096 +#: PLCOpenEditor.py:5098 +#: PLCOpenEditor.py:5099 +msgid ", " +msgstr "," + +#: PLCOpenEditor.py:3348 +#: PLCOpenEditor.py:3511 +#: PLCOpenEditor.py:3655 +#: Dialogs.py:1798 +#, python-format +msgid ", %s" +msgstr ", %s" + +#: PLCOpenEditor.py:5094 +msgid ". " +msgstr "。" + +#: DataTypeEditor.py:768 +#, python-format +msgid "A element with \"%s\" as name exists in this structure!" +msgstr "一个以\"%s\"命名的元素已经在这个结构中存在!" + +#: PLCOpenEditor.py:1600 +#: PLCOpenEditor.py:1652 +#: PLCOpenEditor.py:1677 +#: PLCOpenEditor.py:3365 +#: PLCOpenEditor.py:3743 +#: PLCOpenEditor.py:3806 +#, python-format +msgid "A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?" +msgstr "一个编程组织单元的成员被命名为\"%s\"。这可能会产生冲突。你希望继续吗?" + +#: PLCOpenEditor.py:1647 +#: PLCOpenEditor.py:1672 +#, python-format +msgid "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?" +msgstr "一个编程组织单元被命名为\"%s\"。这可能会产生冲突。你希望继续吗?" + +#: PLCOpenEditor.py:1618 +#: PLCOpenEditor.py:1634 +#: PLCOpenEditor.py:3524 +#: PLCOpenEditor.py:3668 +#: PLCOpenEditor.py:3739 +#: PLCOpenEditor.py:3802 +#: PLCOpenEditor.py:4518 +#: Dialogs.py:1533 +#: Dialogs.py:2517 +#: Dialogs.py:2584 +#, python-format +msgid "A pou with \"%s\" as name exists!" +msgstr "一个以\"%s\"命名的的编程组织单元已经存在!" + +#: PLCOpenEditor.py:1620 +#: PLCOpenEditor.py:1636 +#: PLCOpenEditor.py:4523 +#: Dialogs.py:1537 +#: Dialogs.py:2521 +#, python-format +msgid "A variable with \"%s\" as name already exists in this pou!" +msgstr "一个以\"%s\"命名的变量在这个编程组织单元中已经存在!" + +#: PLCOpenEditor.py:445 +msgid "About" +msgstr "关于" + +#: PLCOpenEditor.py:2676 +msgid "About PLCOpenEditor" +msgstr "关于PLCOpen编辑器" + +#: plcopen/iec_std.csv:22 +msgid "Absolute number" +msgstr "绝对值" + +#: Dialogs.py:1478 +#: Dialogs.py:2105 +msgid "Action" +msgstr "行动" + +#: PLCOpenEditor.py:3644 +msgid "Action Name" +msgstr "行动名字" + +#: PLCOpenEditor.py:3611 +msgid "Action Name:" +msgstr "行动名字:" + +#: plcopen/plcopen.py:1028 +#, python-format +msgid "Action with name %s doesn't exists!" +msgstr "一个以\"%s\"命名的的行动不存在!" + +#: PLCControler.py:83 +msgid "Actions" +msgstr "行动" + +#: Dialogs.py:2336 +msgid "Actions:" +msgstr "行动:" + +#: PLCOpenEditor.py:4309 +#: Dialogs.py:2350 +#: DataTypeEditor.py:536 +msgid "Add" +msgstr "添加" + +#: PLCOpenEditor.py:1860 +#: PLCOpenEditor.py:1933 +msgid "Add Action" +msgstr "添加行动" + +#: PLCOpenEditor.py:1916 +msgid "Add Configuration" +msgstr "添加配置" + +#: PLCOpenEditor.py:1904 +msgid "Add DataType" +msgstr "添加数据类型" + +#: Viewer.py:405 +msgid "Add Divergence Branch" +msgstr "添加发散分支" + +#: PLCOpenEditor.py:384 +msgid "Add Element" +msgstr "插入" + +#: RessourceEditor.py:409 +msgid "Add Instance" +msgstr "添加实例" + +#: PLCOpenEditor.py:1910 +msgid "Add Pou" +msgstr "添加Pou" + +#: PLCOpenEditor.py:1887 +#: PLCOpenEditor.py:1944 +msgid "Add Resource" +msgstr "添加源" + +#: RessourceEditor.py:373 +msgid "Add Task" +msgstr "添加任务" + +#: PLCOpenEditor.py:1857 +#: PLCOpenEditor.py:1922 +msgid "Add Transition" +msgstr "添加跃迁" + +#: Viewer.py:400 +msgid "Add Wire Segment" +msgstr "添加布线段" + +#: PLCOpenEditor.py:2421 +msgid "Add a new data type" +msgstr "添加一个新的数据类型" + +#: SFCViewer.py:362 +msgid "Add a new initial step" +msgstr "新建一个初始步骤" + +#: Viewer.py:1977 +#: SFCViewer.py:698 +msgid "Add a new jump" +msgstr "新建一个跳跃" + +#: SFCViewer.py:384 +msgid "Add a new step" +msgstr "添加一个新步骤" + +#: PLCOpenEditor.py:2478 +msgid "Add new configuration" +msgstr "添加新配置" + +#: PLCOpenEditor.py:2493 +msgid "Add new resource" +msgstr "添加新源" + +#: plcopen/iec_std.csv:33 +msgid "Addition" +msgstr "加法" + +#: plcopen/structures.py:222 +msgid "Additionnal function blocks" +msgstr "附加功能类型" + +#: Viewer.py:414 +msgid "Alignment" +msgstr "对准" + +#: PLCOpenEditor.py:3921 +msgid "All" +msgstr "所有" + +#: plcopen/iec_std.csv:31 +msgid "Arc cosine" +msgstr "反余弦" + +#: plcopen/iec_std.csv:30 +msgid "Arc sine" +msgstr "反正弦" + +#: plcopen/iec_std.csv:32 +msgid "Arc tangent" +msgstr "反正切" + +#: plcopen/iec_std.csv:33 +msgid "Arithmetic" +msgstr "运算" + +#: DataTypeEditor.py:238 +msgid "Array" +msgstr "阵列的" + +#: plcopen/iec_std.csv:50 +msgid "Assignment" +msgstr "分配" + +#: Dialogs.py:644 +msgid "At least a variable or an expression must be selected!" +msgstr "至少选择一个变量或者表达式!" + +#: PLCOpenEditor.py:3003 +msgid "Author" +msgstr "作者" + +#: PLCOpenEditor.py:2988 +msgid "Author Name (optional):" +msgstr "作者姓名(选填):" + +#: DataTypeEditor.py:376 +#: DataTypeEditor.py:400 +#: DataTypeEditor.py:475 +msgid "Base Type:" +msgstr "基类型:" + +#: PLCOpenEditor.py:4555 +#: DataTypeEditor.py:794 +msgid "Base Types" +msgstr "基类型" + +#: plcopen/iec_std.csv:59 +msgid "Binary selection (1 of 2)" +msgstr "二进制选取(二选一)" + +#: plcopen/iec_std.csv:51 +msgid "Bit-shift" +msgstr "位移" + +#: plcopen/iec_std.csv:55 +msgid "Bitwise" +msgstr "位操作" + +#: plcopen/iec_std.csv:55 +msgid "Bitwise AND" +msgstr "按位”与“" + +#: plcopen/iec_std.csv:56 +msgid "Bitwise OR" +msgstr "按位”或“" + +#: plcopen/iec_std.csv:57 +msgid "Bitwise XOR" +msgstr "按位”异或“" + +#: plcopen/iec_std.csv:58 +msgid "Bitwise inverting" +msgstr "按位“反向”" + +#: Dialogs.py:110 +msgid "Block Properties" +msgstr "块属性" + +#: PLCOpenEditor.py:2139 +#: Dialogs.py:265 +msgid "Block Types" +msgstr "块类型" + +#: Viewer.py:372 +msgid "Bottom" +msgstr "底部" + +#: PLCOpenEditor.py:2093 +msgid "CSV Log" +msgstr "逗号分隔值文件日志" + +#: PLCOpenEditor.py:4137 +msgid "Can affect a location only to local or global variables" +msgstr "只能影响本地或全局变量的位置" + +#: plcopen/plcopen.py:1123 +#: plcopen/plcopen.py:1137 +#: plcopen/plcopen.py:1158 +#: plcopen/plcopen.py:1174 +msgid "Can only generate execution order on FBD networks!" +msgstr "在功能块网络,只能生成执行命令!" + +#: PLCOpenEditor.py:4135 +msgid "Can't affect a location to a function block instance" +msgstr "不能影响功能块实例的位置" + +#: PLCOpenEditor.py:1093 +#, python-format +msgid "Can't generate program to file %s!" +msgstr "这个编程生成文件失败 %s!" + +#: PLCOpenEditor.py:1125 +#, python-format +msgid "Can't save project to file %s!" +msgstr "这个项目保存为文件失败 %s!" + +#: Viewer.py:363 +msgid "Center" +msgstr "中" + +#: PLCOpenEditor.py:1876 +msgid "Change POU Type To" +msgstr "将POU类型转换为" + +#: plcopen/iec_std.csv:70 +msgid "Character string" +msgstr "字符串" + +#: PLCOpenEditor.py:1032 +#: PLCOpenEditor.py:1083 +#: PLCOpenEditor.py:1119 +msgid "Choose a file" +msgstr "选择一个文件" + +#: PLCOpenEditor.py:3911 +#: PLCOpenEditor.py:3912 +msgid "Class" +msgstr "分类" + +#: PLCOpenEditor.py:4301 +msgid "Class Filter:" +msgstr "类过滤器:" + +#: Dialogs.py:504 +msgid "Class:" +msgstr "分类:" + +#: PLCOpenEditor.py:423 +msgid "Clear Errors\tCTRL+K" +msgstr "清除错误\tCTRL+K" + +#: Viewer.py:410 +msgid "Clear Execution Order" +msgstr "清空执行命令" + +#: PLCOpenEditor.py:346 +msgid "Close\tCTRL+Q" +msgstr "关闭\tCTRL+Q" + +#: PLCOpenEditor.py:962 +msgid "Close Application" +msgstr "关闭应用程序" + +#: PLCOpenEditor.py:319 +msgid "Close Project" +msgstr "关闭程序" + +#: PLCOpenEditor.py:316 +msgid "Close Tab\tCTRL+W" +msgstr "关闭当前" + +#: LDViewer.py:478 +msgid "Comment" +msgstr "注释" + +#: PLCOpenEditor.py:2972 +msgid "Company Name (required):" +msgstr "公司名字(必须):" + +#: PLCOpenEditor.py:2980 +msgid "Company URL (optional):" +msgstr "公司网址(选填):" + +#: plcopen/iec_std.csv:64 +msgid "Comparison" +msgstr "比较" + +#: plcopen/iec_std.csv:74 +msgid "Concatenation" +msgstr "级联" + +#: PLCOpenEditor.py:394 +msgid "Configuration" +msgstr "配置" + +#: PLCControler.py:84 +msgid "Configurations" +msgstr "配置" + +#: Dialogs.py:1733 +msgid "Connection" +msgstr "连接" + +#: Dialogs.py:780 +msgid "Connection Properties" +msgstr "连接属性" + +#: Dialogs.py:796 +msgid "Connector" +msgstr "连接" + +#: Dialogs.py:1455 +msgid "Connectors:" +msgstr "连接:" + +#: PLCOpenEditor.py:3911 +#: PLCOpenEditor.py:3912 +msgid "Constant" +msgstr "常量" + +#: PLCOpenEditor.py:3062 +msgid "Content Description (optional):" +msgstr "内容描述(选填):" + +#: Dialogs.py:802 +msgid "Continuation" +msgstr "连续" + +#: plcopen/iec_std.csv:18 +msgid "Conversion from BCD" +msgstr "由BCD码转换" + +#: plcopen/iec_std.csv:19 +msgid "Conversion to BCD" +msgstr "转换为BCD码" + +#: plcopen/iec_std.csv:21 +msgid "Conversion to date" +msgstr "转换为日期" + +#: plcopen/iec_std.csv:20 +msgid "Conversion to time-of-day" +msgstr "转换为日期时间" + +#: PLCOpenEditor.py:379 +msgid "Copy\tCTRL+C" +msgstr "复制\tCTRL+C" + +#: plcopen/iec_std.csv:28 +msgid "Cosine" +msgstr "余弦" + +#: PLCOpenEditor.py:3286 +msgid "Create a new POU" +msgstr "新建一个POU" + +#: PLCOpenEditor.py:1864 +#: PLCOpenEditor.py:2523 +msgid "Create a new POU from" +msgstr "新建一个POU从" + +#: PLCOpenEditor.py:3607 +msgid "Create a new action" +msgstr "新建一个行动" + +#: PLCOpenEditor.py:214 +msgid "Create a new action block" +msgstr "新建一个作用块" + +#: PLCOpenEditor.py:169 +#: PLCOpenEditor.py:196 +#: PLCOpenEditor.py:226 +msgid "Create a new block" +msgstr "新建一个块" + +#: PLCOpenEditor.py:190 +msgid "Create a new branch" +msgstr "新建一个支流" + +#: PLCOpenEditor.py:184 +msgid "Create a new coil" +msgstr "新建一个线圈" + +#: PLCOpenEditor.py:163 +#: PLCOpenEditor.py:175 +#: PLCOpenEditor.py:202 +msgid "Create a new comment" +msgstr "新建一个备注" + +#: PLCOpenEditor.py:172 +#: PLCOpenEditor.py:199 +#: PLCOpenEditor.py:229 +msgid "Create a new connection" +msgstr "新建一个连接" + +#: PLCOpenEditor.py:187 +#: PLCOpenEditor.py:235 +msgid "Create a new contact" +msgstr "新建一个接触点" + +#: PLCOpenEditor.py:217 +msgid "Create a new divergence" +msgstr "新建一个发散" + +#: Dialogs.py:1972 +msgid "Create a new divergence or convergence" +msgstr "新建一个发散或者收敛" + +#: PLCOpenEditor.py:205 +msgid "Create a new initial step" +msgstr "新建一个初始步骤" + +#: PLCOpenEditor.py:220 +msgid "Create a new jump" +msgstr "新建一个跳跃" + +#: PLCOpenEditor.py:178 +#: PLCOpenEditor.py:232 +msgid "Create a new power rail" +msgstr "新建一个电源导轨" + +#: PLCOpenEditor.py:181 +msgid "Create a new rung" +msgstr "新建一个梯级" + +#: PLCOpenEditor.py:208 +msgid "Create a new step" +msgstr "新建一个步骤" + +#: PLCOpenEditor.py:211 +#: PLCOpenEditor.py:3463 +msgid "Create a new transition" +msgstr "新建一个跃迁" + +#: PLCOpenEditor.py:166 +#: PLCOpenEditor.py:193 +#: PLCOpenEditor.py:223 +msgid "Create a new variable" +msgstr "新建一个变量" + +#: PLCOpenEditor.py:377 +msgid "Cut\tCTRL+X" +msgstr "剪切\tCTRL+X" + +#: PLCOpenEditor.py:386 +msgid "Data Type" +msgstr "数据类型" + +#: PLCControler.py:83 +msgid "Data Types" +msgstr "数据类型 " + +#: plcopen/iec_std.csv:16 +msgid "Data type conversion" +msgstr "日期类型转换" + +#: plcopen/iec_std.csv:36 +msgid "Date addition" +msgstr "日期加法" + +#: plcopen/iec_std.csv:44 +#: plcopen/iec_std.csv:45 +msgid "Date and time subtraction" +msgstr "日期和时间减法" + +#: plcopen/iec_std.csv:41 +msgid "Date subtraction" +msgstr "日期减法" + +#: PLCOpenEditor.py:398 +#: PLCOpenEditor.py:1881 +#: PLCOpenEditor.py:1890 +#: PLCOpenEditor.py:1896 +#: PLCOpenEditor.py:4314 +#: PLCOpenEditor.py:4926 +#: Viewer.py:419 +#: Dialogs.py:2355 +#: DataTypeEditor.py:541 +msgid "Delete" +msgstr "删除" + +#: Viewer.py:407 +msgid "Delete Divergence Branch" +msgstr "删除发散分支" + +#: RessourceEditor.py:414 +msgid "Delete Instance" +msgstr "删除实例" + +#: RessourceEditor.py:378 +msgid "Delete Task" +msgstr "删除任务" + +#: Viewer.py:402 +msgid "Delete Wire Segment" +msgstr "删除布线段" + +#: DataTypeEditor.py:450 +#: DataTypeEditor.py:492 +msgid "Delete item" +msgstr "删除项目" + +#: plcopen/iec_std.csv:77 +msgid "Deletion (within)" +msgstr "删除" + +#: DataTypeEditor.py:361 +msgid "Derivation Type:" +msgstr "推导类型:" + +#: plcopen/structures.py:236 +msgid "" +"Derivative\n" +"The derivative function block produces an output XOUT proportional to the rate of change of the input XIN." +msgstr "" +"导数\n" +"导数功能块根据输入XIN的速率的变化而按比例的生产输出XOUT。" + +#: DataTypeEditor.py:484 +msgid "Dimensions:" +msgstr "维数:" + +#: DataTypeEditor.py:238 +msgid "Directly" +msgstr "直接的" + +#: PLCOpenEditor.py:306 +msgid "Display" +msgstr "显示" + +#: plcopen/iec_std.csv:46 +msgid "Division" +msgstr "除法" + +#: PLCOpenEditor.py:1087 +msgid "Done" +msgstr "完成" + +#: plcopen/structures.py:199 +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" +"倒计时器用于当计数到达 0的时候,从当前值开始倒计时。" + +#: Dialogs.py:2101 +msgid "Duration" +msgstr "时间" + +#: PLCOpenEditor.py:305 +msgid "Edit" +msgstr "编辑" + +#: Viewer.py:417 +msgid "Edit Block" +msgstr "编辑块" + +#: Dialogs.py:1094 +msgid "Edit Coil Values" +msgstr "编辑线圈值" + +#: Dialogs.py:1089 +msgid "Edit Contact Values" +msgstr "编辑接触点值" + +#: Dialogs.py:1447 +msgid "Edit Step" +msgstr "编辑步骤" + +#: Dialogs.py:2332 +msgid "Edit action block properties" +msgstr "编辑行动块属性" + +#: Viewer.py:1802 +#: Viewer.py:1804 +#: Viewer.py:2303 +#: Viewer.py:2305 +msgid "Edit comment" +msgstr "编辑注释" + +#: DataTypeEditor.py:445 +#: DataTypeEditor.py:487 +msgid "Edit item" +msgstr "编辑项目" + +#: Viewer.py:2268 +msgid "Edit jump target" +msgstr "编辑跳跃目标" + +#: SFCViewer.py:726 +msgid "Edit step name" +msgstr "编辑步骤名称" + +#: Dialogs.py:1694 +msgid "Edit transition" +msgstr "编辑跃迁" + +#: DataTypeEditor.py:517 +msgid "Elements :" +msgstr "元素:" + +#: DataTypeEditor.py:238 +msgid "Enumerated" +msgstr "列举的" + +#: plcopen/iec_std.csv:66 +msgid "Equal to" +msgstr "等于" + +#: PLCOpenEditor.py:954 +#: PLCOpenEditor.py:1094 +#: PLCOpenEditor.py:1099 +#: PLCOpenEditor.py:1600 +#: PLCOpenEditor.py:1647 +#: PLCOpenEditor.py:1652 +#: PLCOpenEditor.py:1672 +#: PLCOpenEditor.py:1677 +#: PLCOpenEditor.py:2553 +#: PLCOpenEditor.py:2582 +#: PLCOpenEditor.py:3103 +#: PLCOpenEditor.py:3195 +#: PLCOpenEditor.py:3199 +#: PLCOpenEditor.py:3203 +#: PLCOpenEditor.py:3207 +#: PLCOpenEditor.py:3349 +#: PLCOpenEditor.py:3353 +#: PLCOpenEditor.py:3357 +#: PLCOpenEditor.py:3361 +#: PLCOpenEditor.py:3512 +#: PLCOpenEditor.py:3516 +#: PLCOpenEditor.py:3520 +#: PLCOpenEditor.py:3524 +#: PLCOpenEditor.py:3528 +#: PLCOpenEditor.py:3656 +#: PLCOpenEditor.py:3660 +#: PLCOpenEditor.py:3664 +#: PLCOpenEditor.py:3668 +#: PLCOpenEditor.py:3672 +#: PLCOpenEditor.py:3727 +#: PLCOpenEditor.py:3731 +#: PLCOpenEditor.py:3735 +#: PLCOpenEditor.py:3739 +#: PLCOpenEditor.py:3790 +#: PLCOpenEditor.py:3794 +#: PLCOpenEditor.py:3798 +#: PLCOpenEditor.py:3802 +#: PLCOpenEditor.py:4184 +#: PLCOpenEditor.py:4508 +#: PLCOpenEditor.py:4513 +#: PLCOpenEditor.py:4518 +#: PLCOpenEditor.py:4523 +#: PLCOpenEditor.py:4859 +#: PLCOpenEditor.py:5121 +#: PLCOpenEditor.py:5131 +#: Viewer.py:338 +#: TextViewer.py:224 +#: LDViewer.py:628 +#: LDViewer.py:850 +#: LDViewer.py:854 +#: Dialogs.py:237 +#: Dialogs.py:241 +#: Dialogs.py:245 +#: Dialogs.py:249 +#: Dialogs.py:253 +#: Dialogs.py:257 +#: Dialogs.py:644 +#: Dialogs.py:648 +#: Dialogs.py:878 +#: Dialogs.py:882 +#: Dialogs.py:886 +#: Dialogs.py:890 +#: Dialogs.py:894 +#: Dialogs.py:1521 +#: Dialogs.py:1525 +#: Dialogs.py:1529 +#: Dialogs.py:1533 +#: Dialogs.py:1537 +#: Dialogs.py:1541 +#: Dialogs.py:1799 +#: Dialogs.py:2505 +#: Dialogs.py:2509 +#: Dialogs.py:2513 +#: Dialogs.py:2517 +#: Dialogs.py:2521 +#: Dialogs.py:2525 +#: Dialogs.py:2572 +#: Dialogs.py:2576 +#: Dialogs.py:2580 +#: Dialogs.py:2584 +#: DataTypeEditor.py:693 +#: DataTypeEditor.py:698 +#: DataTypeEditor.py:753 +#: DataTypeEditor.py:758 +#: DataTypeEditor.py:768 +#: DataTypeEditor.py:895 +#: DataTypeEditor.py:902 +msgid "Error" +msgstr "错误" + +#: Dialogs.py:130 +msgid "Execution Control:" +msgstr "执行控制:" + +#: Dialogs.py:126 +#: Dialogs.py:512 +msgid "Execution Order:" +msgstr "执行命令:" + +#: plcopen/iec_std.csv:49 +msgid "Exponent" +msgstr "指数" + +#: plcopen/iec_std.csv:26 +msgid "Exponentiation" +msgstr "幂" + +#: Dialogs.py:508 +msgid "Expression:" +msgstr "表达式:" + +#: PLCOpenEditor.py:3923 +msgid "External" +msgstr "外部的" + +#: PLCOpenEditor.py:3040 +#: PLCOpenEditor.py:3230 +#: PLCOpenEditor.py:3241 +#: PLCOpenEditor.py:3420 +#: PLCOpenEditor.py:3564 +msgid "FBD" +msgstr "功能区块图" + +#: Viewer.py:397 +#: Dialogs.py:1056 +msgid "Falling Edge" +msgstr "下降沿" + +#: plcopen/structures.py:189 +msgid "" +"Falling edge detector\n" +"The output produces a single pulse when a falling edge is detected." +msgstr "" +"下降沿检测\n" +"当下降沿被检测到时,输出便产生一个单脉冲。" + +#: PLCOpenEditor.py:303 +msgid "File" +msgstr "文件" + +#: plcopen/iec_std.csv:79 +msgid "Find position" +msgstr "定位" + +#: PLCOpenEditor.py:3103 +#: PLCOpenEditor.py:3349 +#: PLCOpenEditor.py:3512 +#: PLCOpenEditor.py:3656 +#: Dialogs.py:1799 +#, python-format +msgid "Form isn't complete. %s must be filled!" +msgstr "形式不完整。%s 必须被填补完整!" + +#: Dialogs.py:241 +#: Dialogs.py:878 +msgid "Form isn't complete. Name must be filled!" +msgstr "形式不完整。%s 名字必须填!" + +#: Dialogs.py:237 +msgid "Form isn't complete. Valid block type must be selected!" +msgstr "形式不完整。%s 有效的块类型必须被选择!" + +#: PLCOpenEditor.py:388 +msgid "Function" +msgstr "功能" + +#: PLCOpenEditor.py:390 +#: PLCOpenEditor.py:1871 +msgid "Function Block" +msgstr "功能块" + +#: PLCOpenEditor.py:4570 +msgid "Function Block Types" +msgstr "功能块类型" + +#: PLCControler.py:82 +msgid "Function Blocks" +msgstr "功能块" + +#: Viewer.py:230 +msgid "Function Blocks can't be used in Functions!" +msgstr "功能块不能用于功能中!" + +#: Viewer.py:232 +msgid "Function Blocks can't be used in Transitions!" +msgstr "功能块不能用于跃迁中" + +#: PLCControler.py:1658 +#, python-format +msgid "FunctionBlock \"%s\" can't be paste in a Function!!!" +msgstr "功能块 \"%s\" 不能用于功能中!" + +#: PLCControler.py:82 +msgid "Functions" +msgstr "功能" + +#: PLCOpenEditor.py:328 +msgid "Generate Program\tCTRL+G" +msgstr "生成程序\tCTRL+G" + +#: PLCOpenEditor.py:3924 +msgid "Global" +msgstr "全球的" + +#: PLCOpenEditor.py:2090 +msgid "Graphic Panel" +msgstr "图形面板" + +#: PLCOpenEditor.py:3045 +msgid "Graphics" +msgstr "图形" + +#: plcopen/iec_std.csv:64 +msgid "Greater than" +msgstr "大于" + +#: plcopen/iec_std.csv:65 +msgid "Greater than or equal to" +msgstr "大于或等于" + +#: PLCOpenEditor.py:3024 +msgid "Height:" +msgstr "高度:" + +#: PLCOpenEditor.py:307 +msgid "Help" +msgstr "帮助" + +#: plcopen/structures.py:251 +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" +"滞后功能块提供一个被2个浮点(REAL)的差异所驱动的布尔型滞后输出,2个浮点即输入的XIN1和XIN2。" + +#: PLCOpenEditor.py:3230 +#: PLCOpenEditor.py:3241 +#: PLCOpenEditor.py:3420 +#: PLCOpenEditor.py:3564 +msgid "IL" +msgstr "指令集" + +#: PLCOpenEditor.py:3922 +#: Dialogs.py:422 +msgid "InOut" +msgstr "输入输出" + +#: PLCOpenEditor.py:4154 +#, python-format +msgid "Incompatible data types between \"%s\" and \"%s\"" +msgstr " \"%s\" 和 \"%s\" 数据类型不相容" + +#: PLCOpenEditor.py:4165 +#, python-format +msgid "Incompatible size of data between \"%s\" and \"%s\"" +msgstr " \"%s\" 和 \"%s\" 数据大小不相容" + +#: PLCOpenEditor.py:4161 +#, python-format +msgid "Incompatible size of data between \"%s\" and \"BOOL\"" +msgstr " \"%s\" 和 \"BOOL\" 数据类型不相容" + +#: Dialogs.py:2101 +msgid "Indicator" +msgstr "指示器" + +#: PLCOpenEditor.py:3911 +#: PLCOpenEditor.py:3912 +#: DataTypeEditor.py:46 +msgid "Initial Value" +msgstr "初始值" + +#: DataTypeEditor.py:385 +#: DataTypeEditor.py:409 +#: DataTypeEditor.py:460 +#: DataTypeEditor.py:502 +msgid "Initial Value:" +msgstr "初始值:" + +#: Dialogs.py:1721 +#: Dialogs.py:1789 +#: Dialogs.py:2105 +msgid "Inline" +msgstr "在线" + +#: PLCOpenEditor.py:3922 +#: Dialogs.py:421 +#: Dialogs.py:1468 +msgid "Input" +msgstr "输入" + +#: Dialogs.py:122 +msgid "Inputs:" +msgstr "输入:" + +#: plcopen/iec_std.csv:76 +msgid "Insertion (into)" +msgstr "插入" + +#: plcopen/plcopen.py:1234 +#, python-format +msgid "Instance with id %d doesn't exists!" +msgstr "有id的实例 %d 尚不存在!" + +#: PLCOpenEditor.py:559 +#: PLCOpenEditor.py:597 +msgid "Instances" +msgstr "实例" + +#: RessourceEditor.py:394 +msgid "Instances:" +msgstr "实例:" + +#: plcopen/structures.py:231 +msgid "" +"Integral\n" +"The integral function block integrates the value of input XIN over time." +msgstr "" +"积分\n" +"积分功能随着时间推移而集成输入的XIN的值。" + +#: PLCOpenEditor.py:3921 +msgid "Interface" +msgstr "界面" + +#: RessourceEditor.py:79 +msgid "Interval" +msgstr "区间" + +#: PLCControler.py:1640 +msgid "Invalid plcopen element(s)!!!" +msgstr "无效的plcopen元素!!!" + +#: PLCOpenEditor.py:4848 +#: PLCOpenEditor.py:4851 +#, python-format +msgid "Invalid value \"%s\" for debug variable" +msgstr "无效值 \"%s\" 为调试变量" + +#: PLCOpenEditor.py:4142 +#: PLCOpenEditor.py:4145 +#, python-format +msgid "Invalid value \"%s\" for location" +msgstr "因地点而无效\"%s\"" + +#: Viewer.py:214 +#: Viewer.py:217 +#, python-format +msgid "Invalid value \"%s\" for viewer block" +msgstr "无效值 \"%s\" 在视窗块" + +#: PLCOpenEditor.py:3040 +#: PLCOpenEditor.py:3230 +#: PLCOpenEditor.py:3241 +#: PLCOpenEditor.py:3420 +#: PLCOpenEditor.py:3564 +msgid "LD" +msgstr "梯级图" + +#: LDViewer.py:213 +#: LDViewer.py:228 +#, python-format +msgid "Ladder element with id %d is on more than one rung." +msgstr "有id的梯形元素 %d 不止在一个梯级上。" + +#: PLCOpenEditor.py:3339 +#: PLCOpenEditor.py:3502 +#: PLCOpenEditor.py:3646 +msgid "Language" +msgstr "语言" + +#: PLCOpenEditor.py:3054 +msgid "Language (optional):" +msgstr "语言(选填):" + +#: PLCOpenEditor.py:3307 +#: PLCOpenEditor.py:3475 +#: PLCOpenEditor.py:3619 +msgid "Language:" +msgstr "语言:" + +#: Viewer.py:361 +msgid "Left" +msgstr "左" + +#: Dialogs.py:1283 +msgid "Left PowerRail" +msgstr "左电源导轨" + +#: plcopen/iec_std.csv:70 +msgid "Length of string" +msgstr "字符串长度" + +#: plcopen/iec_std.csv:67 +msgid "Less than" +msgstr "小于" + +#: plcopen/iec_std.csv:68 +msgid "Less than or equal to" +msgstr "小于或等于" + +#: PLCOpenEditor.py:638 +msgid "Library" +msgstr "图书馆" + +#: plcopen/iec_std.csv:62 +msgid "Limitation" +msgstr "限制" + +#: PLCOpenEditor.py:3923 +msgid "Local" +msgstr "位置" + +#: PLCOpenEditor.py:3911 +msgid "Location" +msgstr "位置" + +#: plcopen/iec_std.csv:25 +msgid "Logarithm to base 10" +msgstr "底数10的对数" + +#: plcopen/iec_std.csv:60 +msgid "Maximum" +msgstr "最大值" + +#: DataTypeEditor.py:427 +msgid "Maximum:" +msgstr "最大值:" + +#: Viewer.py:370 +msgid "Middle" +msgstr "中间" + +#: plcopen/iec_std.csv:61 +msgid "Minimum" +msgstr "最小值" + +#: DataTypeEditor.py:418 +msgid "Minimum:" +msgstr "最小值:" + +#: PLCOpenEditor.py:3069 +msgid "Miscellaneous" +msgstr "其他" + +#: Dialogs.py:1018 +msgid "Modifier:" +msgstr "改动:" + +#: PLCGenerator.py:665 +#: PLCGenerator.py:864 +#, python-format +msgid "More than one connector found corresponding to \"%s\" continuation in \"%s\" POU" +msgstr "发现不止一个连接器符合 \"%s\" 延续在 \"%s\" POU中" + +#: DataTypeEditor.py:456 +#: DataTypeEditor.py:498 +msgid "Move down" +msgstr "下移" + +#: DataTypeEditor.py:453 +#: DataTypeEditor.py:495 +msgid "Move up" +msgstr "上移" + +#: plcopen/iec_std.csv:63 +msgid "Multiplexer (select 1 of N)" +msgstr "多路器(多选一)" + +#: plcopen/iec_std.csv:37 +msgid "Multiplication" +msgstr "乘法" + +#: PLCOpenEditor.py:3911 +#: PLCOpenEditor.py:3912 +#: RessourceEditor.py:79 +#: RessourceEditor.py:83 +#: DataTypeEditor.py:46 +msgid "Name" +msgstr "名字" + +#: Dialogs.py:118 +#: Dialogs.py:516 +#: Dialogs.py:788 +#: Dialogs.py:1022 +#: Dialogs.py:1451 +msgid "Name:" +msgstr "名字:" + +#: plcopen/iec_std.csv:24 +msgid "Natural logarithm" +msgstr "自然对数" + +#: Viewer.py:393 +#: Dialogs.py:1036 +msgid "Negated" +msgstr "否定" + +#: PLCOpenEditor.py:312 +msgid "New\tCTRL+N" +msgstr "新建\tCTRL+N" + +#: DataTypeEditor.py:447 +#: DataTypeEditor.py:489 +msgid "New item" +msgstr "建立项目" + +#: PLCOpenEditor.py:3916 +msgid "No" +msgstr "否" + +#: Viewer.py:391 +msgid "No Modifier" +msgstr "无改动" + +#: PLCControler.py:2507 +msgid "No PLC project found" +msgstr "未找到PLC项目" + +#: PLCGenerator.py:1225 +#, python-format +msgid "No body defined in \"%s\" POU" +msgstr "在 \"%s\" POU 中没有任何东西被定义" + +#: PLCGenerator.py:684 +#: PLCGenerator.py:873 +#, python-format +msgid "No connector found corresponding to \"%s\" continuation in \"%s\" POU" +msgstr "未发现连接器符合 \"%s\" 连续在 \"%s\" POU中" + +#: PLCOpenEditor.py:2668 +msgid "" +"No documentation available.\n" +"Coming soon." +msgstr "" +"没有文件可用。\n" +"稍候" + +#: plcopen/structures.py:139 +msgid "No output variable found" +msgstr "未找到输出值" + +#: PLCGenerator.py:1223 +#, python-format +msgid "No variable defined in \"%s\" POU" +msgstr "无变量被定义在 \"%s\" POU" + +#: Dialogs.py:1030 +msgid "Normal" +msgstr "正常" + +#: plcopen/iec_std.csv:69 +msgid "Not equal to" +msgstr "不等于" + +#: Dialogs.py:2004 +msgid "Number of sequences:" +msgstr "序列号:" + +#: plcopen/iec_std.csv:22 +msgid "Numerical" +msgstr "数学式" + +#: plcopen/structures.py:219 +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" +"关闭延迟计时器可用于延迟设置一个假性输出,固定期限后一个输入变成假。" + +#: plcopen/structures.py:214 +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" +"开启延时计时器可用于延迟设置一个真性输出,固定期限后一个输入成为真。" + +#: PLCOpenEditor.py:314 +msgid "Open\tCTRL+O" +msgstr "打开\tCTRL+O" + +#: PLCOpenEditor.py:2996 +msgid "Organization (optional):" +msgstr "组织(选填):" + +#: PLCOpenEditor.py:3922 +#: Dialogs.py:423 +#: Dialogs.py:1473 +msgid "Output" +msgstr "输出" + +#: plcopen/structures.py:241 +msgid "" +"PID\n" +"The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control." +msgstr "" +"PID\n" +"PID(比例,积分,导数)功能块为闭循环控制提供经典的三阶段控制器。" + +#: PLCOpenEditor.py:1032 +#: PLCOpenEditor.py:1119 +msgid "PLCOpen files (*.xml)|*.xml|All files|*.*" +msgstr "PLCOpen 文件 (*.xml)|*.xml|所有文件|*.*" + +#: PLCOpenEditor.py:485 +#: PLCOpenEditor.py:839 +msgid "PLCOpenEditor" +msgstr "PLCOpen编辑器" + +#: PLCOpenEditor.py:438 +msgid "PLCOpenEditor\tF1" +msgstr "PLCOpen编辑器\tF1" + +#: PLCOpenEditor.py:3335 +msgid "POU Name" +msgstr "POU 名字" + +#: PLCOpenEditor.py:3290 +msgid "POU Name:" +msgstr "POU 名字:" + +#: PLCOpenEditor.py:3337 +msgid "POU Type" +msgstr "POU类型" + +#: PLCOpenEditor.py:3298 +msgid "POU Type:" +msgstr "POU 类型:" + +#: PLCOpenEditor.py:331 +msgid "Page Setup" +msgstr "页面设置" + +#: PLCOpenEditor.py:3012 +msgid "Page Size (optional):" +msgstr "页面大小(选填):" + +#: PLCOpenEditor.py:5064 +#, python-format +msgid "Page: %d" +msgstr "页:%d" + +#: PLCOpenEditor.py:381 +msgid "Paste\tCTRL+V" +msgstr "粘贴\tCTRL+V" + +#: Dialogs.py:1275 +msgid "Pin number:" +msgstr "插脚数:" + +#: Viewer.py:1977 +#: Viewer.py:2268 +#: SFCViewer.py:698 +msgid "Please choose a target" +msgstr "请选择一个目标" + +#: PLCOpenEditor.py:2523 +msgid "Please enter POU name" +msgstr "请输入POU名" + +#: Viewer.py:1802 +#: Viewer.py:1804 +#: Viewer.py:2303 +#: Viewer.py:2305 +msgid "Please enter comment text" +msgstr "请输入注释文本" + +#: PLCOpenEditor.py:2478 +#: PLCOpenEditor.py:3710 +msgid "Please enter configuration name" +msgstr "请输入配置名" + +#: PLCOpenEditor.py:2421 +msgid "Please enter data type name" +msgstr "请输入数据类型名" + +#: PLCOpenEditor.py:2493 +#: PLCOpenEditor.py:3773 +msgid "Please enter resource name" +msgstr "请输入源名" + +#: SFCViewer.py:362 +#: SFCViewer.py:384 +#: SFCViewer.py:726 +msgid "Please enter step name" +msgstr "请输入步骤名称" + +#: PLCOpenEditor.py:3180 +msgid "Please enter text" +msgstr "请输入文本" + +#: GraphicViewer.py:117 +msgid "Position:" +msgstr "定位:" + +#: Dialogs.py:1267 +msgid "Power Rail Properties" +msgstr "电源导轨属性" + +#: PLCOpenEditor.py:333 +msgid "Preview" +msgstr "打印预览" + +#: Dialogs.py:134 +#: Dialogs.py:520 +#: Dialogs.py:792 +#: Dialogs.py:1026 +#: Dialogs.py:1279 +#: Dialogs.py:1459 +#: Dialogs.py:1702 +#: Dialogs.py:2013 +msgid "Preview:" +msgstr "预览:" + +#: PLCOpenEditor.py:335 +msgid "Print" +msgstr "打印" + +#: PLCOpenEditor.py:1151 +msgid "Print preview" +msgstr "打印预览" + +#: RessourceEditor.py:79 +msgid "Priority" +msgstr "优先" + +#: Dialogs.py:1706 +msgid "Priority:" +msgstr "优先:" + +#: PLCOpenEditor.py:2940 +msgid "Product Name (required):" +msgstr "产品名字(必填):" + +#: PLCOpenEditor.py:2956 +msgid "Product Release (optional):" +msgstr "产品发布(选填):" + +#: PLCOpenEditor.py:2948 +msgid "Product Version (required):" +msgstr "产品版本(必填):" + +#: PLCOpenEditor.py:392 +#: PLCOpenEditor.py:1874 +msgid "Program" +msgstr "程序" + +#: PLCOpenEditor.py:1096 +msgid "Program was successfully generated!" +msgstr "该编程成功生成文件!" + +#: PLCControler.py:83 +msgid "Programs" +msgstr "程序" + +#: Viewer.py:223 +msgid "Programs can't be used by other POUs!" +msgstr "程序不能被其它POU使用!" + +#: PLCOpenEditor.py:497 +#: PLCOpenEditor.py:2963 +msgid "Project" +msgstr "项目" + +#: PLCOpenEditor.py:2924 +msgid "Project Name (required):" +msgstr "项目名称(必填):" + +#: PLCOpenEditor.py:2932 +msgid "Project Version (optional):" +msgstr "项目版本(选填):" + +#: PLCOpenEditor.py:2910 +msgid "Project properties" +msgstr "项目属性" + +#: PLCOpenEditor.py:339 +#: PLCControler.py:84 +msgid "Properties" +msgstr "属性" + +#: plcopen/structures.py:209 +msgid "" +"Pulse timer\n" +"The pulse timer can be used to generate output pulses of a given time duration." +msgstr "" +"脉冲计时器\n" +"脉冲计时器可用于产生给定时间限制的输出的脉冲。" + +#: Dialogs.py:2101 +msgid "Qualifier" +msgstr "合格验证" + +#: PLCOpenEditor.py:343 +msgid "Quit\tCTRL+Q" +msgstr "退出\tCTRL+Q" + +#: plcopen/structures.py:174 +msgid "" +"RS bistable\n" +"The RS bistable is a latch where the Reset dominates." +msgstr "" +"RS双稳\n" +"RS双稳是一个重置支配的锁存器。" + +#: plcopen/structures.py:246 +msgid "" +"Ramp\n" +"The RAMP function block is modelled on example given in the standard but with the addition of a 'Holdback' feature." +msgstr "" +"匝道\n" +"匝道功能块模拟给定标准的例子,但增加了一个' 阻碍 '功能。" + +#: GraphicViewer.py:106 +msgid "Range:" +msgstr "范围:" + +#: PLCOpenEditor.py:374 +msgid "Redo\tCTRL+Y" +msgstr "重做\tCTRL+Y" + +#: Dialogs.py:1710 +#: Dialogs.py:1787 +msgid "Reference" +msgstr "参照" + +#: PLCOpenEditor.py:420 +msgid "Refresh\tF5" +msgstr "重新载入\tF5" + +#: plcopen/iec_std.csv:48 +msgid "Remainder (modulo)" +msgstr "余数(模)" + +#: PLCOpenEditor.py:1878 +msgid "Rename" +msgstr "重命名" + +#: plcopen/iec_std.csv:78 +msgid "Replacement (within)" +msgstr "替换" + +#: Dialogs.py:1046 +msgid "Reset" +msgstr "重置" + +#: Viewer.py:412 +msgid "Reset Execution Order" +msgstr "重置执行命令" + +#: PLCControler.py:84 +msgid "Resources" +msgstr "资源" + +#: PLCOpenEditor.py:3911 +#: PLCOpenEditor.py:3912 +msgid "Retain" +msgstr "保持" + +#: PLCOpenEditor.py:4292 +msgid "Return Type:" +msgstr "返回类型:" + +#: Viewer.py:365 +msgid "Right" +msgstr "右" + +#: Dialogs.py:1289 +msgid "Right PowerRail" +msgstr "右电源导轨" + +#: Viewer.py:395 +#: Dialogs.py:1051 +msgid "Rising Edge" +msgstr "上升沿" + +#: plcopen/structures.py:184 +msgid "" +"Rising edge detector\n" +"The output produces a single pulse when a rising edge is detected." +msgstr "" +"上升沿检测\n" +"当上升沿被检测到时,输出便产生一个单脉冲。" + +#: plcopen/iec_std.csv:54 +msgid "Rotate left" +msgstr "循环左移" + +#: plcopen/iec_std.csv:53 +msgid "Rotate right" +msgstr "循环右移" + +#: plcopen/iec_std.csv:17 +msgid "Rounding up/down" +msgstr "四舍五入" + +#: PLCOpenEditor.py:3040 +#: PLCOpenEditor.py:3241 +msgid "SFC" +msgstr "顺序功能流程图" + +#: plcopen/structures.py:169 +msgid "" +"SR bistable\n" +"The SR bistable is a latch where the Set dominates." +msgstr "" +"SR双稳态\n" +"SR双稳态是一个设置支配的锁存器。" + +#: PLCOpenEditor.py:3230 +#: PLCOpenEditor.py:3241 +#: PLCOpenEditor.py:3420 +#: PLCOpenEditor.py:3564 +msgid "ST" +msgstr "结构化文字" + +#: PLCOpenEditor.py:1083 +msgid "ST files (*.st)|*.st|All files|*.*" +msgstr "ST 文件 (*.st)|*.st|所有文件|*.*" + +#: PLCOpenEditor.py:323 +msgid "Save\tCTRL+S" +msgstr "保存\tCTRL+S" + +#: PLCOpenEditor.py:326 +msgid "Save As...\tCTRL+SHIFT+S" +msgstr "另存为...\tCTRL+SHIFT+S" + +#: PLCOpenEditor.py:3032 +msgid "Scaling:" +msgstr "比例:" + +#: PLCOpenEditor.py:396 +msgid "Select All\tCTRL+A" +msgstr "全部选中\tCTRL+A" + +#: PLCOpenEditor.py:4167 +msgid "Select a variable class:" +msgstr "选择一个变量种类:" + +#: PLCOpenEditor.py:604 +#: PLCOpenEditor.py:616 +msgid "Select an object" +msgstr "选择一个对象" + +#: plcopen/iec_std.csv:59 +msgid "Selection" +msgstr "选择" + +#: Dialogs.py:1986 +msgid "Selection Convergence" +msgstr "选择收敛" + +#: Dialogs.py:1980 +msgid "Selection Divergence" +msgstr "选择发散" + +#: plcopen/structures.py:179 +msgid "" +"Semaphore\n" +"The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources." +msgstr "" +"信号\n" +"信号提供一个机制,使软件元素相互排斥的进入一定资源。" + +#: Dialogs.py:1041 +msgid "Set" +msgstr "设置" + +#: plcopen/iec_std.csv:51 +msgid "Shift left" +msgstr "左移" + +#: plcopen/iec_std.csv:52 +msgid "Shift right" +msgstr "右移" + +#: Dialogs.py:1998 +msgid "Simultaneous Convergence" +msgstr "同步收敛" + +#: Dialogs.py:1992 +msgid "Simultaneous Divergence" +msgstr "同步发散" + +#: plcopen/iec_std.csv:27 +msgid "Sine" +msgstr "正弦" + +#: RessourceEditor.py:79 +msgid "Single" +msgstr "单" + +#: plcopen/iec_std.csv:23 +msgid "Square root (base 2)" +msgstr "平方根(底数2)" + +#: plcopen/structures.py:165 +msgid "Standard function blocks" +msgstr "标准功能类型" + +#: DataTypeEditor.py:238 +msgid "Structure" +msgstr "结构的" + +#: DataTypeEditor.py:238 +msgid "Subrange" +msgstr "子集的" + +#: plcopen/iec_std.csv:39 +msgid "Subtraction" +msgstr "减法" + +#: plcopen/iec_std.csv:29 +msgid "Tangent" +msgstr "正切" + +#: RessourceEditor.py:83 +msgid "Task" +msgstr "任务 " + +#: RessourceEditor.py:358 +msgid "Tasks:" +msgstr "任务:" + +#: PLCOpenEditor.py:3924 +msgid "Temp" +msgstr "缓冲" + +#: LDViewer.py:850 +msgid "The group of block must be coherent!" +msgstr "块的组必须是连贯的!" + +#: PLCOpenEditor.py:962 +msgid "There are changes, do you want to save?" +msgstr "文件已被改动。你希望保存吗?" + +#: PLCOpenEditor.py:1170 +msgid "" +"There was a problem printing.\n" +"Perhaps your current printer is not set correctly?" +msgstr "" +"打印出现问题。\n" +"请检查你当前打印机设置。" + +#: LDViewer.py:859 +msgid "This option isn't available yet!" +msgstr "该选项尚未可用!" + +#: GraphicViewer.py:181 +msgid "Tick" +msgstr "" + +#: plcopen/iec_std.csv:34 +msgid "Time addition" +msgstr "时间加法" + +#: plcopen/iec_std.csv:75 +msgid "Time concatenation" +msgstr "时间级联" + +#: plcopen/iec_std.csv:47 +msgid "Time division" +msgstr "时间除法" + +#: plcopen/iec_std.csv:38 +msgid "Time multiplication" +msgstr "时间乘法" + +#: plcopen/iec_std.csv:40 +msgid "Time subtraction" +msgstr "时间减法" + +#: plcopen/iec_std.csv:35 +msgid "Time-of-day addition" +msgstr "日期时间加法" + +#: plcopen/iec_std.csv:42 +#: plcopen/iec_std.csv:43 +msgid "Time-of-day subtraction" +msgstr "日期时间减法" + +#: PLCOpenEditor.py:608 +msgid "Toolbar" +msgstr "工具条" + +#: Viewer.py:368 +msgid "Top" +msgstr "顶部" + +#: PLCOpenEditor.py:3500 +msgid "Transition Name" +msgstr "跃迁名字" + +#: PLCOpenEditor.py:3467 +msgid "Transition Name:" +msgstr "跃迁名字:" + +#: PLCGenerator.py:1205 +#, python-format +msgid "Transition with content \"%s\" not connected to a next step in \"%s\" POU" +msgstr "跃迁的内容 \"%s\" 与后一步骤没有关联在 \"%s\" 中" + +#: PLCGenerator.py:1196 +#, python-format +msgid "Transition with content \"%s\" not connected to a previous step in \"%s\" POU" +msgstr "跃迁的内容 \"%s\" 与前一步骤没有关联在 \"%s\" 中" + +#: plcopen/plcopen.py:990 +#, python-format +msgid "Transition with name %s doesn't exists!" +msgstr "已命名的跃迁 %s 尚不存在!" + +#: PLCControler.py:83 +msgid "Transitions" +msgstr "跃迁" + +#: PLCOpenEditor.py:3911 +#: PLCOpenEditor.py:3912 +#: RessourceEditor.py:83 +#: Dialogs.py:2101 +#: DataTypeEditor.py:46 +msgid "Type" +msgstr "类型" + +#: plcopen/iec_std.csv:16 +msgid "Type conversion" +msgstr "类型转换" + +#: DataTypeEditor.py:357 +msgid "Type infos:" +msgstr "类型信息:" + +#: Dialogs.py:114 +#: Dialogs.py:784 +#: Dialogs.py:1271 +#: Dialogs.py:1698 +#: Dialogs.py:1976 +msgid "Type:" +msgstr "类型:" + +#: PLCOpenEditor.py:560 +#: PLCOpenEditor.py:596 +msgid "Types" +msgstr "类型" + +#: PLCGenerator.py:232 +#, python-format +msgid "Undefined pou type \"%s\"" +msgstr "未定义的pou类型" + +#: PLCOpenEditor.py:372 +msgid "Undo\tCTRL+Z" +msgstr "撤消\tCTRL+Z" + +#: Viewer.py:289 +#, python-format +msgid "Unknown variable \"%s\" for this POU!" +msgstr "未知的变量 \"%s\" 这个POU!" + +#: PLCControler.py:293 +#, python-format +msgid "Unnamed%d" +msgstr "未命名%d" + +#: PLCOpenEditor.py:4163 +#, python-format +msgid "Unrecognized data size \"%s\"" +msgstr "无法识别数据大小 \"%s\"" + +#: plcopen/structures.py:194 +msgid "" +"Up-counter\n" +"The up-counter can be used to signal when a count has reached a maximum value." +msgstr "" +"顺计时器\n" +"当计数到达最大值时,顺计时器给出信号。" + +#: plcopen/structures.py:204 +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。可用于顺计时和倒计时的输入。" + +#: PLCOpenEditor.py:4561 +#: DataTypeEditor.py:800 +msgid "User Data Types" +msgstr "用户数据类型" + +#: PLCControler.py:82 +msgid "User-defined POUs" +msgstr "用户 - 定义POUs" + +#: PLCOpenEditor.py:4678 +#: Dialogs.py:2101 +msgid "Value" +msgstr "值" + +#: GraphicViewer.py:181 +msgid "Values" +msgstr "值" + +#: DataTypeEditor.py:442 +msgid "Values:" +msgstr "值:" + +#: PLCOpenEditor.py:4678 +#: Dialogs.py:2105 +msgid "Variable" +msgstr "变量" + +#: Dialogs.py:500 +msgid "Variable Properties" +msgstr "变量属性" + +#: PLCOpenEditor.py:4167 +msgid "Variable class" +msgstr "变量种类" + +#: Viewer.py:291 +#: TextViewer.py:224 +msgid "Variable don't belong to this POU!" +msgstr "变量不属于这个POU!" + +#: PLCOpenEditor.py:573 +#: PLCOpenEditor.py:624 +#: PLCOpenEditor.py:3923 +msgid "Variables" +msgstr "变量" + +#: PLCOpenEditor.py:3365 +#: PLCOpenEditor.py:3743 +#: PLCOpenEditor.py:3806 +#: LDViewer.py:859 +msgid "Warning" +msgstr "警告" + +#: PLCOpenEditor.py:3016 +msgid "Width:" +msgstr "宽度:" + +#: PLCOpenEditor.py:2759 +msgid "X Scale:" +msgstr "X 坐标:" + +#: PLCOpenEditor.py:2767 +msgid "Y Scale:" +msgstr "Y 坐标:" + +#: PLCOpenEditor.py:3916 +msgid "Yes" +msgstr "是" + +#: LDViewer.py:854 +msgid "You must select the block or group of blocks around which a branch should be added!" +msgstr "你必须选择一个块或块的组围绕着需被添加的分支!" + +#: LDViewer.py:628 +msgid "You must select the wire where a contact should be added!" +msgstr "你必须选择一条线连接需被添加的接触点!" + +#: PLCOpenEditor.py:3195 +#: PLCOpenEditor.py:3727 +#: PLCOpenEditor.py:3790 +#: Dialogs.py:1521 +#: Dialogs.py:2505 +#: Dialogs.py:2572 +msgid "You must type a name!" +msgstr "你必须输入一个名字!" + +#: PLCOpenEditor.py:426 +msgid "Zoom" +msgstr "显示比例" + +#: PLCOpenEditor.py:1092 +#, python-format +msgid "error: %s\n" +msgstr "错误:%s\n" + +#: PLCOpenEditor.py:5096 +#: PLCOpenEditor.py:5098 +msgid "file : " +msgstr "文件:" + +#: PLCOpenEditor.py:3236 +msgid "function" +msgstr "功能" + +#: PLCOpenEditor.py:5099 +msgid "function : " +msgstr "功能:" + +#: PLCOpenEditor.py:3236 +msgid "functionBlock" +msgstr "功能块" + +#: PLCOpenEditor.py:5099 +msgid "line : " +msgstr "在线:" + +#: PLCOpenEditor.py:3236 +msgid "program" +msgstr "程序" + +#: plcopen/iec_std.csv:73 +msgid "string from the middle" +msgstr "从中间取字符串" + +#: plcopen/iec_std.csv:71 +msgid "string left of" +msgstr "从左取字符串" + +#: plcopen/iec_std.csv:72 +msgid "string right of" +msgstr "从右取字符串" + +#: PLCOpenEditor.py:1090 +#, python-format +msgid "warning: %s\n" +msgstr "警告:%s\n" + +#~ msgid "\n" +#~ msgstr "\n" +#~ msgid "A pou with \"%s\" for name exists!" +#~ msgstr "一个以\"%s\"命名的的编程组织单元已经存在!" +#~ msgid "" +#~ "A variable is defined with \"%s\" as name. It can generate a conflict. Do " +#~ "you wish to continue?" +#~ msgstr "一个变量被定义 \"%s\" 为名称。它会导致冲突。你希望继续吗?" +#~ msgid "A variable with \"%s\" as name exists in this pou!" +#~ msgstr "一个以\"%s\"命名的变量在这个编程组织单元中已经存在!" +#~ msgid "A variable with \"%s\" as name exists!" +#~ msgstr "一个以\"%s\"命名的变量已经存在!" +#~ msgid "Create A New POU From" +#~ msgstr "新建一个POU从" +#~ msgid "Create a new project" +#~ msgstr "新建一个项目" +#~ msgid "Printing" +#~ msgstr "打印" +#~ msgid "" +#~ "Ratio monitor\n" +#~ "The ratio_monitor function block checks that one process value PV1 is " +#~ "always a given ratio (defined by input RATIO) of a second process value " +#~ "PV2." +#~ msgstr "" +#~ "比监视器\n" +#~ "比监视器功能块检查一个步骤值PV1总是被比较于(被输入的比定义)第二个步骤" +#~ "值。" +#~ 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 "" +#~ "实时时钟\n" +#~ "实时时钟有很多用途,包括时间冲压,设置日期和批量报告日期时间,报警信息等。" +#~ msgid "ValueError" +#~ msgstr "值错误" +#~ msgid "You can't paste the element in buffer here!" +#~ msgstr "你不能在这缓冲区中粘贴元素!" + diff -r 020420ad8914 -r 07447ee3538e i18n/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i18n/README Fri Jul 24 17:12:59 2009 +0200 @@ -0,0 +1,8 @@ +To generate message.pot file: + + python mki18n.py -p --domain=PLCOpenEditor + +To generate .mo files for all languages: + + python mki18n.py -m --moTarget=../locale --domain=PLCOpenEditor + \ No newline at end of file diff -r 020420ad8914 -r 07447ee3538e i18n/app.fil --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i18n/app.fil Fri Jul 24 17:12:59 2009 +0200 @@ -0,0 +1,14 @@ +../PLCOpenEditor.py +../PLCGenerator.py +../PLCControler.py +../RessourceEditor.py +../Viewer.py +../TextViewer.py +../SFCViewer.py +../LDViewer.py +../GraphicViewer.py +../Dialogs.py +../DataTypeEditor.py +../plcopen/iec_std.csv +../plcopen/plcopen.py +../plcopen/structures.py diff -r 020420ad8914 -r 07447ee3538e i18n/messages.pot --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i18n/messages.pot Fri Jul 24 17:12:59 2009 +0200 @@ -0,0 +1,2000 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-07-24 16:55+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../PLCOpenEditor.py:5044 +msgid "" +"\n" +"An error happens.\n" +"\n" +"Click on OK for saving an error report.\n" +"\n" +"Please contact LOLITech at:\n" +"+33 (0)3 29 57 60 42\n" +"bugs_PLCOpenEditor@lolitech.fr\n" +"\n" +"\n" +"Error:\n" +msgstr "" + +#: ../PLCOpenEditor.py:3860 +msgid " External" +msgstr "" + +#: ../PLCOpenEditor.py:3859 +msgid " InOut" +msgstr "" + +#: ../PLCOpenEditor.py:3859 +msgid " Input" +msgstr "" + +#: ../PLCOpenEditor.py:3860 +msgid " Local" +msgstr "" + +#: ../PLCOpenEditor.py:3859 +msgid " Output" +msgstr "" + +#: ../PLCOpenEditor.py:3861 +msgid " Temp" +msgstr "" + +#: ../PLCOpenEditor.py:840 +msgid " (Debug)" +msgstr "" + +#: ../PLCOpenEditor.py:5056 +msgid " : " +msgstr "" + +#: ../PLCOpenEditor.py:3283 ../PLCOpenEditor.py:3446 ../PLCOpenEditor.py:3590 +#: ../Dialogs.py:1800 +#, python-format +msgid " and %s" +msgstr "" + +#: ../plcopen/plcopen.py:782 +#, python-format +msgid "\"%s\" Data Type doesn't exist !!!" +msgstr "" + +#: ../plcopen/plcopen.py:800 +#, python-format +msgid "\"%s\" POU already exists !!!" +msgstr "" + +#: ../plcopen/plcopen.py:821 +#, python-format +msgid "\"%s\" POU doesn't exist !!!" +msgstr "" + +#: ../Viewer.py:225 +#, python-format +msgid "\"%s\" can't use itself!" +msgstr "" + +#: ../PLCOpenEditor.py:1617 ../PLCOpenEditor.py:1637 +#, python-format +msgid "\"%s\" config already exists!" +msgstr "" + +#: ../plcopen/plcopen.py:256 +#, python-format +msgid "\"%s\" configuration already exists !!!" +msgstr "" + +#: ../PLCOpenEditor.py:1571 ../PLCOpenEditor.py:3145 +#, python-format +msgid "\"%s\" data type already exists!" +msgstr "" + +#: ../PLCControler.py:1663 +#, python-format +msgid "\"%s\" element can't be paste here!!!" +msgstr "" + +#: ../PLCOpenEditor.py:3465 ../PLCOpenEditor.py:3609 ../Viewer.py:248 +#: ../Dialogs.py:261 ../Dialogs.py:898 +#, python-format +msgid "\"%s\" element for this pou already exists!" +msgstr "" + +#: ../plcopen/structures.py:97 +#, python-format +msgid "\"%s\" function cancelled in \"%s\" POU: No input connected" +msgstr "" + +#: ../PLCOpenEditor.py:1562 ../PLCOpenEditor.py:3141 ../PLCOpenEditor.py:3294 +#: ../PLCOpenEditor.py:3457 ../PLCOpenEditor.py:3601 ../PLCOpenEditor.py:3672 +#: ../PLCOpenEditor.py:3735 ../PLCOpenEditor.py:4449 ../Dialogs.py:253 +#: ../Dialogs.py:652 ../Dialogs.py:890 ../Dialogs.py:1533 ../Dialogs.py:2516 +#: ../Dialogs.py:2583 ../DataTypeEditor.py:702 ../DataTypeEditor.py:762 +#, python-format +msgid "\"%s\" is a keyword. It can't be used!" +msgstr "" + +#: ../Viewer.py:231 +#, python-format +msgid "\"%s\" is already used by \"%s\"!" +msgstr "" + +#: ../plcopen/plcopen.py:2120 +#, python-format +msgid "\"%s\" is an invalid value!" +msgstr "" + +#: ../PLCOpenEditor.py:1097 ../PLCOpenEditor.py:1126 +#, python-format +msgid "\"%s\" is not a valid folder!" +msgstr "" + +#: ../PLCOpenEditor.py:1560 ../PLCOpenEditor.py:3137 ../PLCOpenEditor.py:3290 +#: ../PLCOpenEditor.py:3453 ../PLCOpenEditor.py:3597 ../PLCOpenEditor.py:3668 +#: ../PLCOpenEditor.py:3731 ../PLCOpenEditor.py:4444 ../Dialogs.py:249 +#: ../Dialogs.py:886 ../Dialogs.py:1529 ../Dialogs.py:2512 ../Dialogs.py:2579 +#: ../DataTypeEditor.py:757 +#, python-format +msgid "\"%s\" is not a valid identifier!" +msgstr "" + +#: ../PLCOpenEditor.py:283 ../PLCOpenEditor.py:2491 ../PLCOpenEditor.py:2520 +#, python-format +msgid "\"%s\" is used by one or more POUs. It can't be removed!" +msgstr "" + +#: ../PLCOpenEditor.py:1580 ../PLCOpenEditor.py:3298 ../Viewer.py:246 +#: ../Dialogs.py:257 ../Dialogs.py:894 +#, python-format +msgid "\"%s\" pou already exists!" +msgstr "" + +#: ../plcopen/plcopen.py:287 +#, python-format +msgid "\"%s\" resource already exists in \"%s\" configuration !!!" +msgstr "" + +#: ../plcopen/plcopen.py:303 +#, python-format +msgid "\"%s\" resource doesn't exist in \"%s\" configuration !!!" +msgstr "" + +#: ../Dialogs.py:1545 ../Dialogs.py:2528 +#, python-format +msgid "\"%s\" step already exists!" +msgstr "" + +#: ../DataTypeEditor.py:697 +#, python-format +msgid "\"%s\" value already defined!" +msgstr "" + +#: ../DataTypeEditor.py:899 +#, python-format +msgid "\"%s\" value isn't a valid array dimension!" +msgstr "" + +#: ../DataTypeEditor.py:906 +#, python-format +msgid "" +"\"%s\" value isn't a valid array dimension!\n" +"Right value must be greater than left value." +msgstr "" + +#: ../GraphicViewer.py:181 +#, python-format +msgid "%s Graphics" +msgstr "" + +#: ../plcopen/plcopen.py:1276 ../plcopen/plcopen.py:1286 +#: ../plcopen/plcopen.py:1296 ../plcopen/plcopen.py:1306 +#: ../plcopen/plcopen.py:1315 +#, python-format +msgid "%s body don't have instances!" +msgstr "" + +#: ../plcopen/plcopen.py:1338 ../plcopen/plcopen.py:1345 +#, python-format +msgid "%s body don't have text!" +msgstr "" + +#: ../PLCOpenEditor.py:5032 ../PLCOpenEditor.py:5034 ../PLCOpenEditor.py:5035 +msgid ", " +msgstr "" + +#: ../PLCOpenEditor.py:3285 ../PLCOpenEditor.py:3448 ../PLCOpenEditor.py:3592 +#: ../Dialogs.py:1802 +#, python-format +msgid ", %s" +msgstr "" + +#: ../PLCOpenEditor.py:5030 +msgid ". " +msgstr "" + +#: ../DataTypeEditor.py:772 +#, python-format +msgid "A element with \"%s\" as name exists in this structure!" +msgstr "" + +#: ../PLCOpenEditor.py:1583 ../PLCOpenEditor.py:1625 ../PLCOpenEditor.py:1645 +#: ../PLCOpenEditor.py:3302 ../PLCOpenEditor.py:3680 ../PLCOpenEditor.py:3743 +#, python-format +msgid "A pou has an element with \"%s\" as name. It can generate a conflict. Do you wish to continue?" +msgstr "" + +#: ../PLCOpenEditor.py:1620 ../PLCOpenEditor.py:1640 +#, python-format +msgid "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?" +msgstr "" + +#: ../PLCOpenEditor.py:1596 ../PLCOpenEditor.py:1607 ../PLCOpenEditor.py:3461 +#: ../PLCOpenEditor.py:3605 ../PLCOpenEditor.py:3676 ../PLCOpenEditor.py:3739 +#: ../PLCOpenEditor.py:4454 ../Dialogs.py:1537 ../Dialogs.py:2520 +#: ../Dialogs.py:2587 +#, python-format +msgid "A pou with \"%s\" as name exists!" +msgstr "" + +#: ../PLCOpenEditor.py:1598 ../PLCOpenEditor.py:1609 ../PLCOpenEditor.py:4459 +#: ../Dialogs.py:1541 ../Dialogs.py:2524 +#, python-format +msgid "A variable with \"%s\" as name already exists in this pou!" +msgstr "" + +#: ../PLCOpenEditor.py:445 +msgid "About" +msgstr "" + +#: ../PLCOpenEditor.py:2614 +msgid "About PLCOpenEditor" +msgstr "" + +#: ../plcopen/iec_std.csv:22 +msgid "Absolute number" +msgstr "" + +#: ../Dialogs.py:1482 ../Dialogs.py:2109 +msgid "Action" +msgstr "" + +#: ../PLCOpenEditor.py:3581 +msgid "Action Name" +msgstr "" + +#: ../PLCOpenEditor.py:3548 +msgid "Action Name:" +msgstr "" + +#: ../plcopen/plcopen.py:1073 +#, python-format +msgid "Action with name %s doesn't exists!" +msgstr "" + +#: ../PLCControler.py:83 +msgid "Actions" +msgstr "" + +#: ../Dialogs.py:2332 +msgid "Actions:" +msgstr "" + +#: ../PLCOpenEditor.py:4244 ../Dialogs.py:2346 ../DataTypeEditor.py:539 +msgid "Add" +msgstr "" + +#: ../PLCOpenEditor.py:1800 ../PLCOpenEditor.py:1873 +msgid "Add Action" +msgstr "" + +#: ../PLCOpenEditor.py:1856 +msgid "Add Configuration" +msgstr "" + +#: ../PLCOpenEditor.py:1844 +msgid "Add DataType" +msgstr "" + +#: ../Viewer.py:402 +msgid "Add Divergence Branch" +msgstr "" + +#: ../PLCOpenEditor.py:384 +msgid "Add Element" +msgstr "" + +#: ../RessourceEditor.py:409 +msgid "Add Instance" +msgstr "" + +#: ../PLCOpenEditor.py:1850 +msgid "Add Pou" +msgstr "" + +#: ../PLCOpenEditor.py:1827 ../PLCOpenEditor.py:1884 +msgid "Add Resource" +msgstr "" + +#: ../RessourceEditor.py:373 +msgid "Add Task" +msgstr "" + +#: ../PLCOpenEditor.py:1797 ../PLCOpenEditor.py:1862 +msgid "Add Transition" +msgstr "" + +#: ../Viewer.py:397 +msgid "Add Wire Segment" +msgstr "" + +#: ../PLCOpenEditor.py:2359 +msgid "Add a new data type" +msgstr "" + +#: ../SFCViewer.py:362 +msgid "Add a new initial step" +msgstr "" + +#: ../Viewer.py:1971 ../SFCViewer.py:698 +msgid "Add a new jump" +msgstr "" + +#: ../SFCViewer.py:384 +msgid "Add a new step" +msgstr "" + +#: ../PLCOpenEditor.py:2416 +msgid "Add new configuration" +msgstr "" + +#: ../PLCOpenEditor.py:2431 +msgid "Add new resource" +msgstr "" + +#: ../plcopen/iec_std.csv:33 +msgid "Addition" +msgstr "" + +#: ../plcopen/structures.py:222 +msgid "Additionnal function blocks" +msgstr "" + +#: ../Viewer.py:411 +msgid "Alignment" +msgstr "" + +#: ../PLCOpenEditor.py:3858 +msgid "All" +msgstr "" + +#: ../plcopen/iec_std.csv:31 +msgid "Arc cosine" +msgstr "" + +#: ../plcopen/iec_std.csv:30 +msgid "Arc sine" +msgstr "" + +#: ../plcopen/iec_std.csv:32 +msgid "Arc tangent" +msgstr "" + +#: ../plcopen/iec_std.csv:33 +msgid "Arithmetic" +msgstr "" + +#: ../DataTypeEditor.py:236 +msgid "Array" +msgstr "" + +#: ../plcopen/iec_std.csv:50 +msgid "Assignment" +msgstr "" + +#: ../Dialogs.py:648 +msgid "At least a variable or an expression must be selected!" +msgstr "" + +#: ../PLCOpenEditor.py:2941 +msgid "Author" +msgstr "" + +#: ../PLCOpenEditor.py:2926 +msgid "Author Name (optional):" +msgstr "" + +#: ../DataTypeEditor.py:379 ../DataTypeEditor.py:403 ../DataTypeEditor.py:478 +msgid "Base Type:" +msgstr "" + +#: ../PLCOpenEditor.py:4491 ../DataTypeEditor.py:798 +msgid "Base Types" +msgstr "" + +#: ../plcopen/iec_std.csv:59 +msgid "Binary selection (1 of 2)" +msgstr "" + +#: ../plcopen/iec_std.csv:51 +msgid "Bit-shift" +msgstr "" + +#: ../plcopen/iec_std.csv:55 +msgid "Bitwise" +msgstr "" + +#: ../plcopen/iec_std.csv:55 +msgid "Bitwise AND" +msgstr "" + +#: ../plcopen/iec_std.csv:56 +msgid "Bitwise OR" +msgstr "" + +#: ../plcopen/iec_std.csv:57 +msgid "Bitwise XOR" +msgstr "" + +#: ../plcopen/iec_std.csv:58 +msgid "Bitwise inverting" +msgstr "" + +#: ../Dialogs.py:114 +msgid "Block Properties" +msgstr "" + +#: ../PLCOpenEditor.py:2077 ../Dialogs.py:269 +msgid "Block Types" +msgstr "" + +#: ../Viewer.py:369 +msgid "Bottom" +msgstr "" + +#: ../PLCOpenEditor.py:2031 +msgid "CSV Log" +msgstr "" + +#: ../PLCOpenEditor.py:4072 +msgid "Can affect a location only to local or global variables" +msgstr "" + +#: ../plcopen/plcopen.py:1218 ../plcopen/plcopen.py:1232 +#: ../plcopen/plcopen.py:1253 ../plcopen/plcopen.py:1269 +msgid "Can only generate execution order on FBD networks!" +msgstr "" + +#: ../PLCOpenEditor.py:4070 +msgid "Can't affect a location to a function block instance" +msgstr "" + +#: ../PLCOpenEditor.py:1092 +#, python-format +msgid "Can't generate program to file %s!" +msgstr "" + +#: ../PLCOpenEditor.py:1124 +#, python-format +msgid "Can't save project to file %s!" +msgstr "" + +#: ../Viewer.py:360 +msgid "Center" +msgstr "" + +#: ../PLCOpenEditor.py:1816 +msgid "Change POU Type To" +msgstr "" + +#: ../plcopen/iec_std.csv:70 +msgid "Character string" +msgstr "" + +#: ../PLCOpenEditor.py:1031 ../PLCOpenEditor.py:1082 ../PLCOpenEditor.py:1118 +msgid "Choose a file" +msgstr "" + +#: ../PLCOpenEditor.py:3848 ../PLCOpenEditor.py:3849 +msgid "Class" +msgstr "" + +#: ../PLCOpenEditor.py:4236 +msgid "Class Filter:" +msgstr "" + +#: ../Dialogs.py:508 +msgid "Class:" +msgstr "" + +#: ../PLCOpenEditor.py:423 +msgid "Clear Errors\tCTRL+K" +msgstr "" + +#: ../Viewer.py:407 +msgid "Clear Execution Order" +msgstr "" + +#: ../PLCOpenEditor.py:346 +msgid "Close\tCTRL+Q" +msgstr "" + +#: ../PLCOpenEditor.py:961 +msgid "Close Application" +msgstr "" + +#: ../PLCOpenEditor.py:319 +msgid "Close Project" +msgstr "" + +#: ../PLCOpenEditor.py:316 +msgid "Close Tab\tCTRL+W" +msgstr "" + +#: ../LDViewer.py:478 +msgid "Comment" +msgstr "" + +#: ../PLCOpenEditor.py:2910 +msgid "Company Name (required):" +msgstr "" + +#: ../PLCOpenEditor.py:2918 +msgid "Company URL (optional):" +msgstr "" + +#: ../plcopen/iec_std.csv:64 +msgid "Comparison" +msgstr "" + +#: ../plcopen/iec_std.csv:74 +msgid "Concatenation" +msgstr "" + +#: ../PLCOpenEditor.py:394 +msgid "Configuration" +msgstr "" + +#: ../PLCControler.py:84 +msgid "Configurations" +msgstr "" + +#: ../Dialogs.py:1737 +msgid "Connection" +msgstr "" + +#: ../Dialogs.py:784 +msgid "Connection Properties" +msgstr "" + +#: ../Dialogs.py:800 +msgid "Connector" +msgstr "" + +#: ../Dialogs.py:1459 +msgid "Connectors:" +msgstr "" + +#: ../PLCOpenEditor.py:3848 ../PLCOpenEditor.py:3849 +msgid "Constant" +msgstr "" + +#: ../PLCOpenEditor.py:3000 +msgid "Content Description (optional):" +msgstr "" + +#: ../Dialogs.py:806 +msgid "Continuation" +msgstr "" + +#: ../plcopen/iec_std.csv:18 +msgid "Conversion from BCD" +msgstr "" + +#: ../plcopen/iec_std.csv:19 +msgid "Conversion to BCD" +msgstr "" + +#: ../plcopen/iec_std.csv:21 +msgid "Conversion to date" +msgstr "" + +#: ../plcopen/iec_std.csv:20 +msgid "Conversion to time-of-day" +msgstr "" + +#: ../PLCOpenEditor.py:379 +msgid "Copy\tCTRL+C" +msgstr "" + +#: ../plcopen/iec_std.csv:28 +msgid "Cosine" +msgstr "" + +#: ../PLCOpenEditor.py:3223 +msgid "Create a new POU" +msgstr "" + +#: ../PLCOpenEditor.py:1804 ../PLCOpenEditor.py:2461 +msgid "Create a new POU from" +msgstr "" + +#: ../PLCOpenEditor.py:3544 +msgid "Create a new action" +msgstr "" + +#: ../PLCOpenEditor.py:214 +msgid "Create a new action block" +msgstr "" + +#: ../PLCOpenEditor.py:169 ../PLCOpenEditor.py:196 ../PLCOpenEditor.py:226 +msgid "Create a new block" +msgstr "" + +#: ../PLCOpenEditor.py:190 +msgid "Create a new branch" +msgstr "" + +#: ../PLCOpenEditor.py:184 +msgid "Create a new coil" +msgstr "" + +#: ../PLCOpenEditor.py:163 ../PLCOpenEditor.py:175 ../PLCOpenEditor.py:202 +msgid "Create a new comment" +msgstr "" + +#: ../PLCOpenEditor.py:172 ../PLCOpenEditor.py:199 ../PLCOpenEditor.py:229 +msgid "Create a new connection" +msgstr "" + +#: ../PLCOpenEditor.py:187 ../PLCOpenEditor.py:235 +msgid "Create a new contact" +msgstr "" + +#: ../PLCOpenEditor.py:217 +msgid "Create a new divergence" +msgstr "" + +#: ../Dialogs.py:1976 +msgid "Create a new divergence or convergence" +msgstr "" + +#: ../PLCOpenEditor.py:205 +msgid "Create a new initial step" +msgstr "" + +#: ../PLCOpenEditor.py:220 +msgid "Create a new jump" +msgstr "" + +#: ../PLCOpenEditor.py:178 ../PLCOpenEditor.py:232 +msgid "Create a new power rail" +msgstr "" + +#: ../PLCOpenEditor.py:181 +msgid "Create a new rung" +msgstr "" + +#: ../PLCOpenEditor.py:208 +msgid "Create a new step" +msgstr "" + +#: ../PLCOpenEditor.py:211 ../PLCOpenEditor.py:3400 +msgid "Create a new transition" +msgstr "" + +#: ../PLCOpenEditor.py:166 ../PLCOpenEditor.py:193 ../PLCOpenEditor.py:223 +msgid "Create a new variable" +msgstr "" + +#: ../PLCOpenEditor.py:377 +msgid "Cut\tCTRL+X" +msgstr "" + +#: ../PLCOpenEditor.py:386 +msgid "Data Type" +msgstr "" + +#: ../PLCControler.py:83 +msgid "Data Types" +msgstr "" + +#: ../plcopen/iec_std.csv:16 +msgid "Data type conversion" +msgstr "" + +#: ../plcopen/iec_std.csv:36 +msgid "Date addition" +msgstr "" + +#: ../plcopen/iec_std.csv:44 ../plcopen/iec_std.csv:45 +msgid "Date and time subtraction" +msgstr "" + +#: ../plcopen/iec_std.csv:41 +msgid "Date subtraction" +msgstr "" + +#: ../PLCOpenEditor.py:398 ../PLCOpenEditor.py:1821 ../PLCOpenEditor.py:1830 +#: ../PLCOpenEditor.py:1836 ../PLCOpenEditor.py:4249 ../PLCOpenEditor.py:4862 +#: ../Viewer.py:416 ../Dialogs.py:2351 ../DataTypeEditor.py:544 +msgid "Delete" +msgstr "" + +#: ../Viewer.py:404 +msgid "Delete Divergence Branch" +msgstr "" + +#: ../RessourceEditor.py:414 +msgid "Delete Instance" +msgstr "" + +#: ../RessourceEditor.py:378 +msgid "Delete Task" +msgstr "" + +#: ../Viewer.py:399 +msgid "Delete Wire Segment" +msgstr "" + +#: ../DataTypeEditor.py:453 ../DataTypeEditor.py:495 +msgid "Delete item" +msgstr "" + +#: ../plcopen/iec_std.csv:77 +msgid "Deletion (within)" +msgstr "" + +#: ../DataTypeEditor.py:364 +msgid "Derivation Type:" +msgstr "" + +#: ../plcopen/structures.py:236 +msgid "" +"Derivative\n" +"The derivative function block produces an output XOUT proportional to the rate of change of the input XIN." +msgstr "" + +#: ../DataTypeEditor.py:487 +msgid "Dimensions:" +msgstr "" + +#: ../DataTypeEditor.py:236 +msgid "Directly" +msgstr "" + +#: ../PLCOpenEditor.py:306 +msgid "Display" +msgstr "" + +#: ../plcopen/iec_std.csv:46 +msgid "Division" +msgstr "" + +#: ../PLCOpenEditor.py:1086 +msgid "Done" +msgstr "" + +#: ../plcopen/structures.py:199 +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.py:2105 +msgid "Duration" +msgstr "" + +#: ../PLCOpenEditor.py:305 +msgid "Edit" +msgstr "" + +#: ../Viewer.py:414 +msgid "Edit Block" +msgstr "" + +#: ../Dialogs.py:1098 +msgid "Edit Coil Values" +msgstr "" + +#: ../Dialogs.py:1093 +msgid "Edit Contact Values" +msgstr "" + +#: ../Dialogs.py:1451 +msgid "Edit Step" +msgstr "" + +#: ../Dialogs.py:2328 +msgid "Edit action block properties" +msgstr "" + +#: ../Viewer.py:1796 ../Viewer.py:1798 ../Viewer.py:2297 ../Viewer.py:2299 +msgid "Edit comment" +msgstr "" + +#: ../DataTypeEditor.py:448 ../DataTypeEditor.py:490 +msgid "Edit item" +msgstr "" + +#: ../Viewer.py:2262 +msgid "Edit jump target" +msgstr "" + +#: ../SFCViewer.py:726 +msgid "Edit step name" +msgstr "" + +#: ../Dialogs.py:1698 +msgid "Edit transition" +msgstr "" + +#: ../DataTypeEditor.py:520 +msgid "Elements :" +msgstr "" + +#: ../DataTypeEditor.py:236 +msgid "Enumerated" +msgstr "" + +#: ../plcopen/iec_std.csv:66 +msgid "Equal to" +msgstr "" + +#: ../PLCOpenEditor.py:953 ../PLCOpenEditor.py:1093 ../PLCOpenEditor.py:1098 +#: ../PLCOpenEditor.py:1583 ../PLCOpenEditor.py:1620 ../PLCOpenEditor.py:1625 +#: ../PLCOpenEditor.py:1640 ../PLCOpenEditor.py:1645 ../PLCOpenEditor.py:2491 +#: ../PLCOpenEditor.py:2520 ../PLCOpenEditor.py:3041 ../PLCOpenEditor.py:3133 +#: ../PLCOpenEditor.py:3137 ../PLCOpenEditor.py:3141 ../PLCOpenEditor.py:3145 +#: ../PLCOpenEditor.py:3286 ../PLCOpenEditor.py:3290 ../PLCOpenEditor.py:3294 +#: ../PLCOpenEditor.py:3298 ../PLCOpenEditor.py:3449 ../PLCOpenEditor.py:3453 +#: ../PLCOpenEditor.py:3457 ../PLCOpenEditor.py:3461 ../PLCOpenEditor.py:3465 +#: ../PLCOpenEditor.py:3593 ../PLCOpenEditor.py:3597 ../PLCOpenEditor.py:3601 +#: ../PLCOpenEditor.py:3605 ../PLCOpenEditor.py:3609 ../PLCOpenEditor.py:3664 +#: ../PLCOpenEditor.py:3668 ../PLCOpenEditor.py:3672 ../PLCOpenEditor.py:3676 +#: ../PLCOpenEditor.py:3727 ../PLCOpenEditor.py:3731 ../PLCOpenEditor.py:3735 +#: ../PLCOpenEditor.py:3739 ../PLCOpenEditor.py:4119 ../PLCOpenEditor.py:4444 +#: ../PLCOpenEditor.py:4449 ../PLCOpenEditor.py:4454 ../PLCOpenEditor.py:4459 +#: ../PLCOpenEditor.py:4795 ../PLCOpenEditor.py:5057 ../PLCOpenEditor.py:5067 +#: ../Viewer.py:335 ../TextViewer.py:224 ../LDViewer.py:628 ../LDViewer.py:850 +#: ../LDViewer.py:854 ../Dialogs.py:241 ../Dialogs.py:245 ../Dialogs.py:249 +#: ../Dialogs.py:253 ../Dialogs.py:257 ../Dialogs.py:261 ../Dialogs.py:648 +#: ../Dialogs.py:652 ../Dialogs.py:882 ../Dialogs.py:886 ../Dialogs.py:890 +#: ../Dialogs.py:894 ../Dialogs.py:898 ../Dialogs.py:1525 ../Dialogs.py:1529 +#: ../Dialogs.py:1533 ../Dialogs.py:1537 ../Dialogs.py:1541 ../Dialogs.py:1545 +#: ../Dialogs.py:1803 ../Dialogs.py:2508 ../Dialogs.py:2512 ../Dialogs.py:2516 +#: ../Dialogs.py:2520 ../Dialogs.py:2524 ../Dialogs.py:2528 ../Dialogs.py:2575 +#: ../Dialogs.py:2579 ../Dialogs.py:2583 ../Dialogs.py:2587 +#: ../DataTypeEditor.py:697 ../DataTypeEditor.py:702 ../DataTypeEditor.py:757 +#: ../DataTypeEditor.py:762 ../DataTypeEditor.py:772 ../DataTypeEditor.py:899 +#: ../DataTypeEditor.py:906 +msgid "Error" +msgstr "" + +#: ../Dialogs.py:134 +msgid "Execution Control:" +msgstr "" + +#: ../Dialogs.py:130 ../Dialogs.py:516 +msgid "Execution Order:" +msgstr "" + +#: ../plcopen/iec_std.csv:49 +msgid "Exponent" +msgstr "" + +#: ../plcopen/iec_std.csv:26 +msgid "Exponentiation" +msgstr "" + +#: ../Dialogs.py:512 +msgid "Expression:" +msgstr "" + +#: ../PLCOpenEditor.py:3860 +msgid "External" +msgstr "" + +#: ../PLCOpenEditor.py:2978 ../PLCOpenEditor.py:3168 ../PLCOpenEditor.py:3178 +#: ../PLCOpenEditor.py:3357 ../PLCOpenEditor.py:3501 +msgid "FBD" +msgstr "" + +#: ../Viewer.py:394 ../Dialogs.py:1060 +msgid "Falling Edge" +msgstr "" + +#: ../plcopen/structures.py:189 +msgid "" +"Falling edge detector\n" +"The output produces a single pulse when a falling edge is detected." +msgstr "" + +#: ../PLCOpenEditor.py:303 +msgid "File" +msgstr "" + +#: ../plcopen/iec_std.csv:79 +msgid "Find position" +msgstr "" + +#: ../PLCOpenEditor.py:3041 ../PLCOpenEditor.py:3286 ../PLCOpenEditor.py:3449 +#: ../PLCOpenEditor.py:3593 ../Dialogs.py:1803 +#, python-format +msgid "Form isn't complete. %s must be filled!" +msgstr "" + +#: ../Dialogs.py:245 ../Dialogs.py:882 +msgid "Form isn't complete. Name must be filled!" +msgstr "" + +#: ../Dialogs.py:241 +msgid "Form isn't complete. Valid block type must be selected!" +msgstr "" + +#: ../PLCOpenEditor.py:388 +msgid "Function" +msgstr "" + +#: ../PLCOpenEditor.py:390 ../PLCOpenEditor.py:1811 +msgid "Function Block" +msgstr "" + +#: ../PLCOpenEditor.py:4506 +msgid "Function Block Types" +msgstr "" + +#: ../PLCControler.py:82 +msgid "Function Blocks" +msgstr "" + +#: ../Viewer.py:227 +msgid "Function Blocks can't be used in Functions!" +msgstr "" + +#: ../Viewer.py:229 +msgid "Function Blocks can't be used in Transitions!" +msgstr "" + +#: ../PLCControler.py:1673 +#, python-format +msgid "FunctionBlock \"%s\" can't be paste in a Function!!!" +msgstr "" + +#: ../PLCControler.py:82 +msgid "Functions" +msgstr "" + +#: ../PLCOpenEditor.py:328 +msgid "Generate Program\tCTRL+G" +msgstr "" + +#: ../PLCOpenEditor.py:3861 +msgid "Global" +msgstr "" + +#: ../PLCOpenEditor.py:2028 +msgid "Graphic Panel" +msgstr "" + +#: ../PLCOpenEditor.py:2983 +msgid "Graphics" +msgstr "" + +#: ../plcopen/iec_std.csv:64 +msgid "Greater than" +msgstr "" + +#: ../plcopen/iec_std.csv:65 +msgid "Greater than or equal to" +msgstr "" + +#: ../PLCOpenEditor.py:2962 +msgid "Height:" +msgstr "" + +#: ../PLCOpenEditor.py:307 +msgid "Help" +msgstr "" + +#: ../plcopen/structures.py:251 +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 "" + +#: ../PLCOpenEditor.py:3168 ../PLCOpenEditor.py:3178 ../PLCOpenEditor.py:3357 +#: ../PLCOpenEditor.py:3501 +msgid "IL" +msgstr "" + +#: ../PLCOpenEditor.py:3859 ../Dialogs.py:426 +msgid "InOut" +msgstr "" + +#: ../PLCOpenEditor.py:4089 +#, python-format +msgid "Incompatible data types between \"%s\" and \"%s\"" +msgstr "" + +#: ../PLCOpenEditor.py:4100 +#, python-format +msgid "Incompatible size of data between \"%s\" and \"%s\"" +msgstr "" + +#: ../PLCOpenEditor.py:4096 +#, python-format +msgid "Incompatible size of data between \"%s\" and \"BOOL\"" +msgstr "" + +#: ../Dialogs.py:2105 +msgid "Indicator" +msgstr "" + +#: ../PLCOpenEditor.py:3848 ../PLCOpenEditor.py:3849 ../DataTypeEditor.py:46 +msgid "Initial Value" +msgstr "" + +#: ../DataTypeEditor.py:388 ../DataTypeEditor.py:412 ../DataTypeEditor.py:463 +#: ../DataTypeEditor.py:505 +msgid "Initial Value:" +msgstr "" + +#: ../Dialogs.py:1725 ../Dialogs.py:1793 ../Dialogs.py:2109 +msgid "Inline" +msgstr "" + +#: ../PLCOpenEditor.py:3859 ../Dialogs.py:425 ../Dialogs.py:1472 +msgid "Input" +msgstr "" + +#: ../Dialogs.py:126 +msgid "Inputs:" +msgstr "" + +#: ../plcopen/iec_std.csv:76 +msgid "Insertion (into)" +msgstr "" + +#: ../plcopen/plcopen.py:1329 +#, python-format +msgid "Instance with id %d doesn't exists!" +msgstr "" + +#: ../PLCOpenEditor.py:559 ../PLCOpenEditor.py:597 +msgid "Instances" +msgstr "" + +#: ../RessourceEditor.py:394 +msgid "Instances:" +msgstr "" + +#: ../plcopen/structures.py:231 +msgid "" +"Integral\n" +"The integral function block integrates the value of input XIN over time." +msgstr "" + +#: ../PLCOpenEditor.py:3858 +msgid "Interface" +msgstr "" + +#: ../RessourceEditor.py:79 +msgid "Interval" +msgstr "" + +#: ../PLCControler.py:1654 ../PLCControler.py:1688 +msgid "Invalid plcopen element(s)!!!" +msgstr "" + +#: ../PLCOpenEditor.py:4784 ../PLCOpenEditor.py:4787 +#, python-format +msgid "Invalid value \"%s\" for debug variable" +msgstr "" + +#: ../PLCOpenEditor.py:4077 ../PLCOpenEditor.py:4080 +#, python-format +msgid "Invalid value \"%s\" for location" +msgstr "" + +#: ../Viewer.py:211 ../Viewer.py:214 +#, python-format +msgid "Invalid value \"%s\" for viewer block" +msgstr "" + +#: ../PLCOpenEditor.py:2978 ../PLCOpenEditor.py:3168 ../PLCOpenEditor.py:3178 +#: ../PLCOpenEditor.py:3357 ../PLCOpenEditor.py:3501 +msgid "LD" +msgstr "" + +#: ../LDViewer.py:213 ../LDViewer.py:228 +#, python-format +msgid "Ladder element with id %d is on more than one rung." +msgstr "" + +#: ../PLCOpenEditor.py:3276 ../PLCOpenEditor.py:3439 ../PLCOpenEditor.py:3583 +msgid "Language" +msgstr "" + +#: ../PLCOpenEditor.py:2992 +msgid "Language (optional):" +msgstr "" + +#: ../PLCOpenEditor.py:3244 ../PLCOpenEditor.py:3412 ../PLCOpenEditor.py:3556 +msgid "Language:" +msgstr "" + +#: ../Viewer.py:358 +msgid "Left" +msgstr "" + +#: ../Dialogs.py:1287 +msgid "Left PowerRail" +msgstr "" + +#: ../plcopen/iec_std.csv:70 +msgid "Length of string" +msgstr "" + +#: ../plcopen/iec_std.csv:67 +msgid "Less than" +msgstr "" + +#: ../plcopen/iec_std.csv:68 +msgid "Less than or equal to" +msgstr "" + +#: ../PLCOpenEditor.py:638 +msgid "Library" +msgstr "" + +#: ../plcopen/iec_std.csv:62 +msgid "Limitation" +msgstr "" + +#: ../PLCOpenEditor.py:3860 +msgid "Local" +msgstr "" + +#: ../PLCOpenEditor.py:3848 +msgid "Location" +msgstr "" + +#: ../plcopen/iec_std.csv:25 +msgid "Logarithm to base 10" +msgstr "" + +#: ../plcopen/iec_std.csv:60 +msgid "Maximum" +msgstr "" + +#: ../DataTypeEditor.py:430 +msgid "Maximum:" +msgstr "" + +#: ../Viewer.py:367 +msgid "Middle" +msgstr "" + +#: ../plcopen/iec_std.csv:61 +msgid "Minimum" +msgstr "" + +#: ../DataTypeEditor.py:421 +msgid "Minimum:" +msgstr "" + +#: ../PLCOpenEditor.py:3007 +msgid "Miscellaneous" +msgstr "" + +#: ../Dialogs.py:1022 +msgid "Modifier:" +msgstr "" + +#: ../PLCGenerator.py:672 ../PLCGenerator.py:876 +#, python-format +msgid "More than one connector found corresponding to \"%s\" continuation in \"%s\" POU" +msgstr "" + +#: ../DataTypeEditor.py:459 ../DataTypeEditor.py:501 +msgid "Move down" +msgstr "" + +#: ../DataTypeEditor.py:456 ../DataTypeEditor.py:498 +msgid "Move up" +msgstr "" + +#: ../plcopen/iec_std.csv:63 +msgid "Multiplexer (select 1 of N)" +msgstr "" + +#: ../plcopen/iec_std.csv:37 +msgid "Multiplication" +msgstr "" + +#: ../PLCOpenEditor.py:3848 ../PLCOpenEditor.py:3849 ../RessourceEditor.py:79 +#: ../RessourceEditor.py:83 ../DataTypeEditor.py:46 +msgid "Name" +msgstr "" + +#: ../Dialogs.py:122 ../Dialogs.py:520 ../Dialogs.py:792 ../Dialogs.py:1026 +#: ../Dialogs.py:1455 +msgid "Name:" +msgstr "" + +#: ../plcopen/iec_std.csv:24 +msgid "Natural logarithm" +msgstr "" + +#: ../Viewer.py:390 ../Dialogs.py:1040 +msgid "Negated" +msgstr "" + +#: ../PLCOpenEditor.py:312 +msgid "New\tCTRL+N" +msgstr "" + +#: ../DataTypeEditor.py:450 ../DataTypeEditor.py:492 +msgid "New item" +msgstr "" + +#: ../PLCOpenEditor.py:3853 +msgid "No" +msgstr "" + +#: ../Viewer.py:388 +msgid "No Modifier" +msgstr "" + +#: ../PLCControler.py:2535 +msgid "No PLC project found" +msgstr "" + +#: ../PLCGenerator.py:1257 +#, python-format +msgid "No body defined in \"%s\" POU" +msgstr "" + +#: ../PLCGenerator.py:691 ../PLCGenerator.py:885 +#, python-format +msgid "No connector found corresponding to \"%s\" continuation in \"%s\" POU" +msgstr "" + +#: ../PLCOpenEditor.py:2606 +msgid "" +"No documentation available.\n" +"Coming soon." +msgstr "" + +#: ../PLCGenerator.py:743 +#, python-format +msgid "No informations found for \"%s\" block" +msgstr "" + +#: ../plcopen/structures.py:139 +msgid "No output variable found" +msgstr "" + +#: ../PLCGenerator.py:1255 +#, python-format +msgid "No variable defined in \"%s\" POU" +msgstr "" + +#: ../Dialogs.py:1034 +msgid "Normal" +msgstr "" + +#: ../plcopen/iec_std.csv:69 +msgid "Not equal to" +msgstr "" + +#: ../Dialogs.py:2008 +msgid "Number of sequences:" +msgstr "" + +#: ../plcopen/iec_std.csv:22 +msgid "Numerical" +msgstr "" + +#: ../plcopen/structures.py:219 +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/structures.py:214 +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 "" + +#: ../PLCOpenEditor.py:314 +msgid "Open\tCTRL+O" +msgstr "" + +#: ../PLCOpenEditor.py:2934 +msgid "Organization (optional):" +msgstr "" + +#: ../PLCOpenEditor.py:3859 ../Dialogs.py:427 ../Dialogs.py:1477 +msgid "Output" +msgstr "" + +#: ../plcopen/structures.py:241 +msgid "" +"PID\n" +"The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control." +msgstr "" + +#: ../PLCOpenEditor.py:1031 ../PLCOpenEditor.py:1118 +msgid "PLCOpen files (*.xml)|*.xml|All files|*.*" +msgstr "" + +#: ../PLCOpenEditor.py:485 ../PLCOpenEditor.py:838 +msgid "PLCOpenEditor" +msgstr "" + +#: ../PLCOpenEditor.py:438 +msgid "PLCOpenEditor\tF1" +msgstr "" + +#: ../PLCOpenEditor.py:3272 +msgid "POU Name" +msgstr "" + +#: ../PLCOpenEditor.py:3227 +msgid "POU Name:" +msgstr "" + +#: ../PLCOpenEditor.py:3274 +msgid "POU Type" +msgstr "" + +#: ../PLCOpenEditor.py:3235 +msgid "POU Type:" +msgstr "" + +#: ../PLCOpenEditor.py:331 +msgid "Page Setup" +msgstr "" + +#: ../PLCOpenEditor.py:2950 +msgid "Page Size (optional):" +msgstr "" + +#: ../PLCOpenEditor.py:5000 +#, python-format +msgid "Page: %d" +msgstr "" + +#: ../PLCOpenEditor.py:381 +msgid "Paste\tCTRL+V" +msgstr "" + +#: ../Dialogs.py:1279 +msgid "Pin number:" +msgstr "" + +#: ../Viewer.py:1971 ../Viewer.py:2262 ../SFCViewer.py:698 +msgid "Please choose a target" +msgstr "" + +#: ../PLCOpenEditor.py:2461 +msgid "Please enter POU name" +msgstr "" + +#: ../Viewer.py:1796 ../Viewer.py:1798 ../Viewer.py:2297 ../Viewer.py:2299 +msgid "Please enter comment text" +msgstr "" + +#: ../PLCOpenEditor.py:2416 ../PLCOpenEditor.py:3647 +msgid "Please enter configuration name" +msgstr "" + +#: ../PLCOpenEditor.py:2359 +msgid "Please enter data type name" +msgstr "" + +#: ../PLCOpenEditor.py:2431 ../PLCOpenEditor.py:3710 +msgid "Please enter resource name" +msgstr "" + +#: ../SFCViewer.py:362 ../SFCViewer.py:384 ../SFCViewer.py:726 +msgid "Please enter step name" +msgstr "" + +#: ../PLCOpenEditor.py:3118 +msgid "Please enter text" +msgstr "" + +#: ../GraphicViewer.py:117 +msgid "Position:" +msgstr "" + +#: ../Dialogs.py:1271 +msgid "Power Rail Properties" +msgstr "" + +#: ../PLCOpenEditor.py:333 +msgid "Preview" +msgstr "" + +#: ../Dialogs.py:138 ../Dialogs.py:524 ../Dialogs.py:796 ../Dialogs.py:1030 +#: ../Dialogs.py:1283 ../Dialogs.py:1463 ../Dialogs.py:1706 ../Dialogs.py:2017 +msgid "Preview:" +msgstr "" + +#: ../PLCOpenEditor.py:335 +msgid "Print" +msgstr "" + +#: ../PLCOpenEditor.py:1150 +msgid "Print preview" +msgstr "" + +#: ../RessourceEditor.py:79 +msgid "Priority" +msgstr "" + +#: ../Dialogs.py:1710 +msgid "Priority:" +msgstr "" + +#: ../PLCOpenEditor.py:2878 +msgid "Product Name (required):" +msgstr "" + +#: ../PLCOpenEditor.py:2894 +msgid "Product Release (optional):" +msgstr "" + +#: ../PLCOpenEditor.py:2886 +msgid "Product Version (required):" +msgstr "" + +#: ../PLCOpenEditor.py:392 ../PLCOpenEditor.py:1814 +msgid "Program" +msgstr "" + +#: ../PLCOpenEditor.py:1095 +msgid "Program was successfully generated!" +msgstr "" + +#: ../PLCControler.py:83 +msgid "Programs" +msgstr "" + +#: ../Viewer.py:220 +msgid "Programs can't be used by other POUs!" +msgstr "" + +#: ../PLCOpenEditor.py:497 ../PLCOpenEditor.py:2901 +msgid "Project" +msgstr "" + +#: ../PLCOpenEditor.py:2862 +msgid "Project Name (required):" +msgstr "" + +#: ../PLCOpenEditor.py:2870 +msgid "Project Version (optional):" +msgstr "" + +#: ../PLCOpenEditor.py:2848 +msgid "Project properties" +msgstr "" + +#: ../PLCOpenEditor.py:339 ../PLCControler.py:84 +msgid "Properties" +msgstr "" + +#: ../plcopen/structures.py:209 +msgid "" +"Pulse timer\n" +"The pulse timer can be used to generate output pulses of a given time duration." +msgstr "" + +#: ../Dialogs.py:2105 +msgid "Qualifier" +msgstr "" + +#: ../PLCOpenEditor.py:343 +msgid "Quit\tCTRL+Q" +msgstr "" + +#: ../plcopen/structures.py:174 +msgid "" +"RS bistable\n" +"The RS bistable is a latch where the Reset dominates." +msgstr "" + +#: ../plcopen/structures.py:246 +msgid "" +"Ramp\n" +"The RAMP function block is modelled on example given in the standard but with the addition of a 'Holdback' feature." +msgstr "" + +#: ../GraphicViewer.py:106 +msgid "Range:" +msgstr "" + +#: ../PLCOpenEditor.py:374 +msgid "Redo\tCTRL+Y" +msgstr "" + +#: ../Dialogs.py:1714 ../Dialogs.py:1791 +msgid "Reference" +msgstr "" + +#: ../PLCOpenEditor.py:420 +msgid "Refresh\tF5" +msgstr "" + +#: ../plcopen/iec_std.csv:48 +msgid "Remainder (modulo)" +msgstr "" + +#: ../PLCOpenEditor.py:1818 +msgid "Rename" +msgstr "" + +#: ../plcopen/iec_std.csv:78 +msgid "Replacement (within)" +msgstr "" + +#: ../Dialogs.py:1050 +msgid "Reset" +msgstr "" + +#: ../Viewer.py:409 +msgid "Reset Execution Order" +msgstr "" + +#: ../PLCControler.py:84 +msgid "Resources" +msgstr "" + +#: ../PLCOpenEditor.py:3848 ../PLCOpenEditor.py:3849 +msgid "Retain" +msgstr "" + +#: ../PLCOpenEditor.py:4227 +msgid "Return Type:" +msgstr "" + +#: ../Viewer.py:362 +msgid "Right" +msgstr "" + +#: ../Dialogs.py:1293 +msgid "Right PowerRail" +msgstr "" + +#: ../Viewer.py:392 ../Dialogs.py:1055 +msgid "Rising Edge" +msgstr "" + +#: ../plcopen/structures.py:184 +msgid "" +"Rising edge detector\n" +"The output produces a single pulse when a rising edge is detected." +msgstr "" + +#: ../plcopen/iec_std.csv:54 +msgid "Rotate left" +msgstr "" + +#: ../plcopen/iec_std.csv:53 +msgid "Rotate right" +msgstr "" + +#: ../plcopen/iec_std.csv:17 +msgid "Rounding up/down" +msgstr "" + +#: ../PLCOpenEditor.py:2978 ../PLCOpenEditor.py:3178 +msgid "SFC" +msgstr "" + +#: ../plcopen/structures.py:169 +msgid "" +"SR bistable\n" +"The SR bistable is a latch where the Set dominates." +msgstr "" + +#: ../PLCOpenEditor.py:3168 ../PLCOpenEditor.py:3178 ../PLCOpenEditor.py:3357 +#: ../PLCOpenEditor.py:3501 +msgid "ST" +msgstr "" + +#: ../PLCOpenEditor.py:1082 +msgid "ST files (*.st)|*.st|All files|*.*" +msgstr "" + +#: ../PLCOpenEditor.py:323 +msgid "Save\tCTRL+S" +msgstr "" + +#: ../PLCOpenEditor.py:326 +msgid "Save As...\tCTRL+SHIFT+S" +msgstr "" + +#: ../PLCOpenEditor.py:2970 +msgid "Scaling:" +msgstr "" + +#: ../PLCOpenEditor.py:396 +msgid "Select All\tCTRL+A" +msgstr "" + +#: ../PLCOpenEditor.py:4102 +msgid "Select a variable class:" +msgstr "" + +#: ../PLCOpenEditor.py:604 ../PLCOpenEditor.py:616 +msgid "Select an object" +msgstr "" + +#: ../plcopen/iec_std.csv:59 +msgid "Selection" +msgstr "" + +#: ../Dialogs.py:1990 +msgid "Selection Convergence" +msgstr "" + +#: ../Dialogs.py:1984 +msgid "Selection Divergence" +msgstr "" + +#: ../plcopen/structures.py:179 +msgid "" +"Semaphore\n" +"The semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources." +msgstr "" + +#: ../Dialogs.py:1045 +msgid "Set" +msgstr "" + +#: ../plcopen/iec_std.csv:51 +msgid "Shift left" +msgstr "" + +#: ../plcopen/iec_std.csv:52 +msgid "Shift right" +msgstr "" + +#: ../Dialogs.py:2002 +msgid "Simultaneous Convergence" +msgstr "" + +#: ../Dialogs.py:1996 +msgid "Simultaneous Divergence" +msgstr "" + +#: ../plcopen/iec_std.csv:27 +msgid "Sine" +msgstr "" + +#: ../RessourceEditor.py:79 +msgid "Single" +msgstr "" + +#: ../plcopen/iec_std.csv:23 +msgid "Square root (base 2)" +msgstr "" + +#: ../plcopen/structures.py:165 +msgid "Standard function blocks" +msgstr "" + +#: ../DataTypeEditor.py:236 +msgid "Structure" +msgstr "" + +#: ../DataTypeEditor.py:236 +msgid "Subrange" +msgstr "" + +#: ../plcopen/iec_std.csv:39 +msgid "Subtraction" +msgstr "" + +#: ../plcopen/iec_std.csv:29 +msgid "Tangent" +msgstr "" + +#: ../RessourceEditor.py:83 +msgid "Task" +msgstr "" + +#: ../RessourceEditor.py:358 +msgid "Tasks:" +msgstr "" + +#: ../PLCOpenEditor.py:3861 +msgid "Temp" +msgstr "" + +#: ../LDViewer.py:850 +msgid "The group of block must be coherent!" +msgstr "" + +#: ../PLCOpenEditor.py:961 +msgid "There are changes, do you want to save?" +msgstr "" + +#: ../PLCOpenEditor.py:1169 +msgid "" +"There was a problem printing.\n" +"Perhaps your current printer is not set correctly?" +msgstr "" + +#: ../LDViewer.py:859 +msgid "This option isn't available yet!" +msgstr "" + +#: ../GraphicViewer.py:181 +msgid "Tick" +msgstr "" + +#: ../plcopen/iec_std.csv:34 +msgid "Time addition" +msgstr "" + +#: ../plcopen/iec_std.csv:75 +msgid "Time concatenation" +msgstr "" + +#: ../plcopen/iec_std.csv:47 +msgid "Time division" +msgstr "" + +#: ../plcopen/iec_std.csv:38 +msgid "Time multiplication" +msgstr "" + +#: ../plcopen/iec_std.csv:40 +msgid "Time subtraction" +msgstr "" + +#: ../plcopen/iec_std.csv:35 +msgid "Time-of-day addition" +msgstr "" + +#: ../plcopen/iec_std.csv:42 ../plcopen/iec_std.csv:43 +msgid "Time-of-day subtraction" +msgstr "" + +#: ../PLCOpenEditor.py:608 +msgid "Toolbar" +msgstr "" + +#: ../Viewer.py:365 +msgid "Top" +msgstr "" + +#: ../PLCOpenEditor.py:3437 +msgid "Transition Name" +msgstr "" + +#: ../PLCOpenEditor.py:3404 +msgid "Transition Name:" +msgstr "" + +#: ../PLCGenerator.py:1237 +#, python-format +msgid "Transition with content \"%s\" not connected to a next step in \"%s\" POU" +msgstr "" + +#: ../PLCGenerator.py:1228 +#, python-format +msgid "Transition with content \"%s\" not connected to a previous step in \"%s\" POU" +msgstr "" + +#: ../plcopen/plcopen.py:1035 +#, python-format +msgid "Transition with name %s doesn't exists!" +msgstr "" + +#: ../PLCControler.py:83 +msgid "Transitions" +msgstr "" + +#: ../PLCOpenEditor.py:3848 ../PLCOpenEditor.py:3849 ../RessourceEditor.py:83 +#: ../Dialogs.py:2105 ../DataTypeEditor.py:46 +msgid "Type" +msgstr "" + +#: ../plcopen/iec_std.csv:16 +msgid "Type conversion" +msgstr "" + +#: ../DataTypeEditor.py:360 +msgid "Type infos:" +msgstr "" + +#: ../Dialogs.py:118 ../Dialogs.py:788 ../Dialogs.py:1275 ../Dialogs.py:1702 +#: ../Dialogs.py:1980 +msgid "Type:" +msgstr "" + +#: ../PLCOpenEditor.py:560 ../PLCOpenEditor.py:596 +msgid "Types" +msgstr "" + +#: ../PLCGenerator.py:232 +#, python-format +msgid "Undefined pou type \"%s\"" +msgstr "" + +#: ../PLCOpenEditor.py:372 +msgid "Undo\tCTRL+Z" +msgstr "" + +#: ../Viewer.py:286 +#, python-format +msgid "Unknown variable \"%s\" for this POU!" +msgstr "" + +#: ../PLCControler.py:293 +#, python-format +msgid "Unnamed%d" +msgstr "" + +#: ../PLCOpenEditor.py:4098 +#, python-format +msgid "Unrecognized data size \"%s\"" +msgstr "" + +#: ../plcopen/structures.py:194 +msgid "" +"Up-counter\n" +"The up-counter can be used to signal when a count has reached a maximum value." +msgstr "" + +#: ../plcopen/structures.py:204 +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 "" + +#: ../PLCOpenEditor.py:4497 ../DataTypeEditor.py:804 +msgid "User Data Types" +msgstr "" + +#: ../PLCControler.py:82 +msgid "User-defined POUs" +msgstr "" + +#: ../PLCOpenEditor.py:4614 ../Dialogs.py:2105 +msgid "Value" +msgstr "" + +#: ../GraphicViewer.py:181 +msgid "Values" +msgstr "" + +#: ../DataTypeEditor.py:445 +msgid "Values:" +msgstr "" + +#: ../PLCOpenEditor.py:4614 ../Dialogs.py:2109 +msgid "Variable" +msgstr "" + +#: ../Dialogs.py:504 +msgid "Variable Properties" +msgstr "" + +#: ../PLCOpenEditor.py:4102 +msgid "Variable class" +msgstr "" + +#: ../Viewer.py:288 ../TextViewer.py:224 +msgid "Variable don't belong to this POU!" +msgstr "" + +#: ../PLCOpenEditor.py:573 ../PLCOpenEditor.py:624 ../PLCOpenEditor.py:3860 +msgid "Variables" +msgstr "" + +#: ../PLCOpenEditor.py:3302 ../PLCOpenEditor.py:3680 ../PLCOpenEditor.py:3743 +#: ../LDViewer.py:859 +msgid "Warning" +msgstr "" + +#: ../PLCOpenEditor.py:2954 +msgid "Width:" +msgstr "" + +#: ../PLCOpenEditor.py:2697 +msgid "X Scale:" +msgstr "" + +#: ../PLCOpenEditor.py:2705 +msgid "Y Scale:" +msgstr "" + +#: ../PLCOpenEditor.py:3853 +msgid "Yes" +msgstr "" + +#: ../LDViewer.py:854 +msgid "You must select the block or group of blocks around which a branch should be added!" +msgstr "" + +#: ../LDViewer.py:628 +msgid "You must select the wire where a contact should be added!" +msgstr "" + +#: ../PLCOpenEditor.py:3133 ../PLCOpenEditor.py:3664 ../PLCOpenEditor.py:3727 +#: ../Dialogs.py:1525 ../Dialogs.py:2508 ../Dialogs.py:2575 +msgid "You must type a name!" +msgstr "" + +#: ../PLCOpenEditor.py:426 +msgid "Zoom" +msgstr "" + +#: ../PLCOpenEditor.py:1091 +#, python-format +msgid "error: %s\n" +msgstr "" + +#: ../PLCOpenEditor.py:5032 ../PLCOpenEditor.py:5034 +msgid "file : " +msgstr "" + +#: ../PLCOpenEditor.py:3173 +msgid "function" +msgstr "" + +#: ../PLCOpenEditor.py:5035 +msgid "function : " +msgstr "" + +#: ../PLCOpenEditor.py:3173 +msgid "functionBlock" +msgstr "" + +#: ../PLCOpenEditor.py:5035 +msgid "line : " +msgstr "" + +#: ../PLCOpenEditor.py:3173 +msgid "program" +msgstr "" + +#: ../plcopen/iec_std.csv:73 +msgid "string from the middle" +msgstr "" + +#: ../plcopen/iec_std.csv:71 +msgid "string left of" +msgstr "" + +#: ../plcopen/iec_std.csv:72 +msgid "string right of" +msgstr "" + +#: ../PLCOpenEditor.py:1089 +#, python-format +msgid "warning: %s\n" +msgstr "" diff -r 020420ad8914 -r 07447ee3538e i18n/mki18n.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i18n/mki18n.py Fri Jul 24 17:12:59 2009 +0200 @@ -0,0 +1,455 @@ +#! /usr/bin/env python +# -*- coding: iso-8859-1 -*- +# +# PYTHON MODULE: MKI18N.PY +# ========= +# +# Abstract: Make Internationalization (i18n) files for an application. +# +# Copyright Pierre Rouleau. 2003. Released to public domain. +# +# Last update: Saturday, November 8, 2003. @ 15:55:18. +# +# File: ROUP2003N01::C:/dev/python/mki18n.py +# +# RCS $Header: //software/official/MKS/MKS_SI/TV_NT/dev/Python/rcs/mki18n.py 1.5 2003/11/05 19:40:04 PRouleau Exp $ +# +# Update history: +# +# - File created: Saturday, June 7, 2003. by Pierre Rouleau +# - 10/06/03 rcs : RCS Revision 1.1 2003/06/10 10:06:12 PRouleau +# - 10/06/03 rcs : RCS Initial revision +# - 23/08/03 rcs : RCS Revision 1.2 2003/06/10 10:54:27 PRouleau +# - 23/08/03 P.R.: [code:fix] : The strings encoded in this file are encode in iso-8859-1 format. Added the encoding +# notification to Python to comply with Python's 2.3 PEP 263. +# - 23/08/03 P.R.: [feature:new] : Added the '-e' switch which is used to force the creation of the empty English .mo file. +# - 22/10/03 P.R.: [code] : incorporated utility functions in here to make script self sufficient. +# - 05/11/03 rcs : RCS Revision 1.4 2003/10/22 06:39:31 PRouleau +# - 05/11/03 P.R.: [code:fix] : included the unixpath() in this file. +# - 08/11/03 rcs : RCS Revision 1.5 2003/11/05 19:40:04 PRouleau +# +# RCS $Log: $ +# +# +# ----------------------------------------------------------------------------- +""" +mki18n allows you to internationalize your software. You can use it to +create the GNU .po files (Portable Object) and the compiled .mo files +(Machine Object). + +mki18n module can be used from the command line or from within a script (see +the Usage at the end of this page). + + Table of Contents + ----------------- + + makePO() -- Build the Portable Object file for the application -- + catPO() -- Concatenate one or several PO files with the application domain files. -- + makeMO() -- Compile the Portable Object files into the Machine Object stored in the right location. -- + printUsage -- Displays how to use this script from the command line -- + + Scriptexecution -- Runs when invoked from the command line -- + + +NOTE: this module uses GNU gettext utilities. + +You can get the gettext tools from the following sites: + + - `GNU FTP site for gettetx`_ where several versions (0.10.40, 0.11.2, 0.11.5 and 0.12.1) are available. + Note that you need to use `GNU libiconv`_ to use this. Get it from the `GNU + libiconv ftp site`_ and get version 1.9.1 or later. Get the Windows .ZIP + files and install the packages inside c:/gnu. All binaries will be stored + inside c:/gnu/bin. Just put c:/gnu/bin inside your PATH. You will need + the following files: + + - `gettext-runtime-0.12.1.bin.woe32.zip`_ + - `gettext-tools-0.12.1.bin.woe32.zip`_ + - `libiconv-1.9.1.bin.woe32.zip`_ + + +.. _GNU libiconv: http://www.gnu.org/software/libiconv/ +.. _GNU libiconv ftp site: http://www.ibiblio.org/pub/gnu/libiconv/ +.. _gettext-runtime-0.12.1.bin.woe32.zip: ftp://ftp.gnu.org/gnu/gettext/gettext-runtime-0.12.1.bin.woe32.zip +.. _gettext-tools-0.12.1.bin.woe32.zip: ftp://ftp.gnu.org/gnu/gettext/gettext-tools-0.12.1.bin.woe32.zip +.. _libiconv-1.9.1.bin.woe32.zip: http://www.ibiblio.org/pub/gnu/libiconv/libiconv-1.9.1.bin.woe32.zip + +""" +# ----------------------------------------------------------------------------- +# Module Import +# ------------- +# +import os +import sys +import wx +# ----------------------------------------------------------------------------- +# Global variables +# ---------------- +# + +__author__ = "Pierre Rouleau" +__version__= "$Revision: 1.5 $" + +# ----------------------------------------------------------------------------- + +def getlanguageDict(): + languageDict = {} + + for lang in [x for x in dir(wx) if x.startswith("LANGUAGE")]: + i = wx.Locale(wx.LANGUAGE_DEFAULT).GetLanguageInfo(getattr(wx, lang)) + if i: + languageDict[i.CanonicalName] = i.Description + + return languageDict + +# ----------------------------------------------------------------------------- +# m a k e P O ( ) -- Build the Portable Object file for the application -- +# ^^^^^^^^^^^^^^^ +# +def makePO(applicationDirectoryPath, applicationDomain=None, verbose=0) : + """Build the Portable Object Template file for the application. + + makePO builds the .pot file for the application stored inside + a specified directory by running xgettext for all application source + files. It finds the name of all files by looking for a file called 'app.fil'. + If this file does not exists, makePo raises an IOError exception. + By default the application domain (the application + name) is the same as the directory name but it can be overridden by the + 'applicationDomain' argument. + + makePO always creates a new file called messages.pot. If it finds files + of the form app_xx.po where 'app' is the application name and 'xx' is one + of the ISO 639 two-letter language codes, makePO resynchronizes those + files with the latest extracted strings (now contained in messages.pot). + This process updates all line location number in the language-specific + .po files and may also create new entries for translation (or comment out + some). The .po file is not changed, instead a new file is created with + the .new extension appended to the name of the .po file. + + By default the function does not display what it is doing. Set the + verbose argument to 1 to force it to print its commands. + """ + + if applicationDomain is None: + applicationName = fileBaseOf(applicationDirectoryPath,withPath=0) + else: + applicationName = applicationDomain + currentDir = os.getcwd() + os.chdir(applicationDirectoryPath) + if not os.path.exists('app.fil'): + raise IOError(2,'No module file: app.fil') + + # Steps: + # Use xgettext to parse all application modules + # The following switches are used: + # + # -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' + if verbose: print cmd + os.system(cmd) + + languageDict = getlanguageDict() + + for langCode in languageDict.keys(): + if langCode == 'en': + pass + else: + langPOfileName = "%s_%s.po" % (applicationName , langCode) + if os.path.exists(langPOfileName): + cmd = 'msgmerge -s --no-wrap "%s" messages.pot > "%s.new"' % (langPOfileName, langPOfileName) + if verbose: print cmd + os.system(cmd) + os.chdir(currentDir) + +# ----------------------------------------------------------------------------- +# c a t P O ( ) -- Concatenate one or several PO files with the application domain files. -- +# ^^^^^^^^^^^^^ +# +def catPO(applicationDirectoryPath, listOf_extraPo, applicationDomain=None, targetDir=None, verbose=0) : + """Concatenate one or several PO files with the application domain files. + """ + + if applicationDomain is None: + applicationName = fileBaseOf(applicationDirectoryPath,withPath=0) + else: + applicationName = applicationDomain + currentDir = os.getcwd() + os.chdir(applicationDirectoryPath) + + languageDict = getlanguageDict() + + for langCode in languageDict.keys(): + if langCode == 'en': + pass + else: + langPOfileName = "%s_%s.po" % (applicationName , langCode) + if os.path.exists(langPOfileName): + fileList = '' + for fileName in listOf_extraPo: + fileList += ("%s_%s.po " % (fileName,langCode)) + cmd = "msgcat -s --no-wrap %s %s > %s.cat" % (langPOfileName, fileList, langPOfileName) + if verbose: print cmd + os.system(cmd) + if targetDir is None: + pass + else: + mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir,langCode) + cmd = "msgfmt --output-file=%s/%s.mo %s_%s.po.cat" % (mo_targetDir,applicationName,applicationName,langCode) + if verbose: print cmd + os.system(cmd) + os.chdir(currentDir) + +# ----------------------------------------------------------------------------- +# m a k e M O ( ) -- Compile the Portable Object files into the Machine Object stored in the right location. -- +# ^^^^^^^^^^^^^^^ +# +def makeMO(applicationDirectoryPath,targetDir='./locale',applicationDomain=None, verbose=0, forceEnglish=0) : + """Compile the Portable Object files into the Machine Object stored in the right location. + + makeMO converts all translated language-specific PO files located inside + the application directory into the binary .MO files stored inside the + LC_MESSAGES sub-directory for the found locale files. + + makeMO searches for all files that have a name of the form 'app_xx.po' + inside the application directory specified by the first argument. The + 'app' is the application domain name (that can be specified by the + applicationDomain argument or is taken from the directory name). The 'xx' + corresponds to one of the ISO 639 two-letter language codes. + + makeMo stores the resulting files inside a sub-directory of `targetDir` + called xx/LC_MESSAGES where 'xx' corresponds to the 2-letter language + code. + """ + if targetDir is None: + targetDir = './locale' + if verbose: + print "Target directory for .mo files is: %s" % targetDir + + if applicationDomain is None: + applicationName = fileBaseOf(applicationDirectoryPath,withPath=0) + else: + applicationName = applicationDomain + currentDir = os.getcwd() + os.chdir(applicationDirectoryPath) + + languageDict = getlanguageDict() + + for langCode in languageDict.keys(): + if (langCode == 'en') and (forceEnglish==0): + pass + else: + langPOfileName = "%s_%s.po" % (applicationName , langCode) + if os.path.exists(langPOfileName): + mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir,langCode) + if not os.path.exists(mo_targetDir): + mkdir(mo_targetDir) + cmd = 'msgfmt --output-file="%s/%s.mo" "%s_%s.po"' % (mo_targetDir,applicationName,applicationName,langCode) + if verbose: print cmd + os.system(cmd) + os.chdir(currentDir) + +# ----------------------------------------------------------------------------- +# p r i n t U s a g e -- Displays how to use this script from the command line -- +# ^^^^^^^^^^^^^^^^^^^ +# +def printUsage(errorMsg=None) : + """Displays how to use this script from the command line.""" + print """ + ################################################################################## + # mki18n : Make internationalization files. # + # Uses the GNU gettext system to create PO (Portable Object) files # + # from source code, coimpile PO into MO (Machine Object) files. # + # Supports C,C++,Python source files. # + # # + # Usage: mki18n {OPTION} [appDirPath] # + # # + # Options: # + # -e : When -m is used, forces English .mo file creation # + # -h : prints this help # + # -m : make MO from existing PO files # + # -p : make PO, update PO files: Creates a new messages.pot # + # file. Creates a dom_xx.po.new for every existing # + # language specific .po file. ('xx' stands for the ISO639 # + # two-letter language code and 'dom' stands for the # + # application domain name). mki18n requires that you # + # write a 'app.fil' file which contains the list of all # + # source code to parse. # + # -v : verbose (prints comments while running) # + # --domain=appName : specifies the application domain name. By default # + # the directory name is used. # + # --moTarget=dir : specifies the directory where .mo files are stored. # + # If not specified, the target is './locale' # + # # + # You must specify one of the -p or -m option to perform the work. You can # + # specify the path of the target application. If you leave it out mki18n # + # will use the current directory as the application main directory. # + # # + ##################################################################################""" + if errorMsg: + print "\n ERROR: %s" % errorMsg + +# ----------------------------------------------------------------------------- +# f i l e B a s e O f ( ) -- Return base name of filename -- +# ^^^^^^^^^^^^^^^^^^^^^^^ +# +def fileBaseOf(filename,withPath=0) : + """fileBaseOf(filename,withPath) ---> string + + Return base name of filename. The returned string never includes the extension. + Use os.path.basename() to return the basename with the extension. The + second argument is optional. If specified and if set to 'true' (non zero) + the string returned contains the full path of the file name. Otherwise the + path is excluded. + + [Example] + >>> fn = 'd:/dev/telepath/tvapp/code/test.html' + >>> fileBaseOf(fn) + 'test' + >>> fileBaseOf(fn) + 'test' + >>> fileBaseOf(fn,1) + 'd:/dev/telepath/tvapp/code/test' + >>> fileBaseOf(fn,0) + 'test' + >>> fn = 'abcdef' + >>> fileBaseOf(fn) + 'abcdef' + >>> fileBaseOf(fn,1) + 'abcdef' + >>> fn = "abcdef." + >>> fileBaseOf(fn) + 'abcdef' + >>> fileBaseOf(fn,1) + 'abcdef' + """ + pos = filename.rfind('.') + if pos > 0: + filename = filename[:pos] + if withPath: + return filename + else: + return os.path.basename(filename) +# ----------------------------------------------------------------------------- +# m k d i r ( ) -- Create a directory (and possibly the entire tree) -- +# ^^^^^^^^^^^^^ +# +def mkdir(directory) : + """Create a directory (and possibly the entire tree). + + The os.mkdir() will fail to create a directory if one of the + directory in the specified path does not exist. mkdir() + solves this problem. It creates every intermediate directory + required to create the final path. Under Unix, the function + only supports forward slash separator, but under Windows and MacOS + the function supports the forward slash and the OS separator (backslash + under windows). + """ + + # translate the path separators + directory = unixpath(directory) + # build a list of all directory elements + aList = filter(lambda x: len(x)>0, directory.split('/')) + theLen = len(aList) + # if the first element is a Windows-style disk drive + # concatenate it with the first directory + if aList[0].endswith(':'): + if theLen > 1: + aList[1] = aList[0] + '/' + aList[1] + del aList[0] + theLen -= 1 + # if the original directory starts at root, + # make sure the first element of the list + # starts at root too + if directory[0] == '/': + aList[0] = '/' + aList[0] + # Now iterate through the list, check if the + # directory exists and if not create it + theDir = '' + for i in range(theLen): + theDir += aList[i] + if not os.path.exists(theDir): + os.mkdir(theDir) + theDir += '/' + +# ----------------------------------------------------------------------------- +# u n i x p a t h ( ) -- Return a path name that contains Unix separator. -- +# ^^^^^^^^^^^^^^^^^^^ +# +def unixpath(thePath) : + r"""Return a path name that contains Unix separator. + + [Example] + >>> unixpath(r"d:\test") + 'd:/test' + >>> unixpath("d:/test/file.txt") + 'd:/test/file.txt' + >>> + """ + thePath = os.path.normpath(thePath) + if os.sep == '/': + return thePath + else: + return thePath.replace(os.sep,'/') + +# ----------------------------------------------------------------------------- + +# S c r i p t e x e c u t i o n -- Runs when invoked from the command line -- +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +if __name__ == "__main__": + import getopt # command line parsing + argc = len(sys.argv) + if argc == 1: + printUsage('Missing argument: specify at least one of -m or -p (or both).') + sys.exit(1) + # If there is some arguments, parse the command line + validOptions = "ehmpv" + validLongOptions = ['domain=', 'moTarget='] + option = {} + option['forceEnglish'] = 0 + option['mo'] = 0 + option['po'] = 0 + option['verbose'] = 0 + option['domain'] = None + option['moTarget'] = None + try: + optionList,pargs = getopt.getopt(sys.argv[1:],validOptions,validLongOptions) + except getopt.GetoptError, e: + printUsage(e[0]) + sys.exit(1) + for (opt,val) in optionList: + if (opt == '-h'): + printUsage() + sys.exit(0) + elif (opt == '-e'): option['forceEnglish'] = 1 + elif (opt == '-m'): option['mo'] = 1 + elif (opt == '-p'): option['po'] = 1 + elif (opt == '-v'): option['verbose'] = 1 + elif (opt == '--domain'): option['domain'] = val + elif (opt == '--moTarget'): option['moTarget'] = val + if len(pargs) == 0: + appDirPath = os.getcwd() + if option['verbose']: + print "No project directory given. Using current one: %s" % appDirPath + elif len(pargs) == 1: + appDirPath = pargs[0] + else: + printUsage('Too many arguments (%u). Use double quotes if you have space in directory name' % len(pargs)) + sys.exit(1) + if option['domain'] is None: + # If no domain specified, use the name of the target directory + option['domain'] = fileBaseOf(appDirPath) + if option['verbose']: + print "Application domain used is: '%s'" % option['domain'] + if option['po']: + try: + makePO(appDirPath,option['domain'],option['verbose']) + except IOError, e: + printUsage(e[1] + '\n You must write a file app.fil that contains the list of all files to parse.') + if option['mo']: + makeMO(appDirPath,option['moTarget'],option['domain'],option['verbose'],option['forceEnglish']) + sys.exit(1) + + +# ----------------------------------------------------------------------------- diff -r 020420ad8914 -r 07447ee3538e locale/fr_FR/LC_MESSAGES/PLCOpenEditor.mo Binary file locale/fr_FR/LC_MESSAGES/PLCOpenEditor.mo has changed diff -r 020420ad8914 -r 07447ee3538e locale/zh_CN/LC_MESSAGES/PLCOpenEditor.mo Binary file locale/zh_CN/LC_MESSAGES/PLCOpenEditor.mo has changed diff -r 020420ad8914 -r 07447ee3538e plcopen/iec_std.csv --- a/plcopen/iec_std.csv Fri Jul 24 12:49:57 2009 +0200 +++ b/plcopen/iec_std.csv Fri Jul 24 17:12:59 2009 +0200 @@ -13,67 +13,67 @@ ;;;;;;;; ;;;;;;;; Standard_functions_type;name;baseinputnumber;inputs;outputs;comment;extensible;python_eval_c_code_format;return_type_rule -Type conversion;*_TO_**;1;(ANY);ANY;Data type conversion;no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_ANY_LIST,fdecl);defined -;TRUNC;1;(ANY_REAL);ANY_INT;Rounding up/down;no;("int", None, None);&search_constant_type_c::constant_int_type_name -;BCD_TO_**;1;(ANY_BIT);ANY_INT;Conversion from BCD;no;ANY_TO_ANY_FORMAT_GEN(BCD_TO_ANY_LIST,fdecl);defined -;*_TO_BCD;1;(ANY_INT);ANY_BIT;Conversion to BCD;no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_BCD_LIST,fdecl);&search_constant_type_c::constant_int_type_name -;DATE_AND_TIME_TO_TIME_OF_DAY;1;(DT);TOD;Conversion to time-of-day;no;(None, "__date_and_time_to_time_of_day", None);defined -;DATE_AND_TIME_TO_DATE;1;(DT);DATE;Conversion to date;no;(None, "__date_and_time_to_date", None);defined -Numerical;ABS;1;(ANY_NUM);ANY_NUM;Absolute number;no;(None, "__abs_", "IN_type");IN_type_symbol -;SQRT;1;(ANY_REAL);ANY_REAL;Square root (base 2);no;(None, "__sqrt_", "IN_type");IN_type_symbol -;LN;1;(ANY_REAL);ANY_REAL;Natural logarithm;no;(None, "__ln_", "IN_type");IN_type_symbol -;LOG;1;(ANY_REAL);ANY_REAL;Logarithm to base 10;no;(None, "__log_", "IN_type");IN_type_symbol -;EXP;1;(ANY_REAL);ANY_REAL;Exponentiation;no;(None, "__exp_", "IN_type");IN_type_symbol -;SIN;1;(ANY_REAL);ANY_REAL;Sine;no;(None, "__sin_", "IN_type");IN_type_symbol -;COS;1;(ANY_REAL);ANY_REAL;Cosine;no;(None, "__cos_", "IN_type");IN_type_symbol -;TAN;1;(ANY_REAL);ANY_REAL;Tangent;no;(None, "__tan_", "IN_type");IN_type_symbol -;ASIN;1;(ANY_REAL);ANY_REAL;Arc sine;no;(None, "__asin_", "IN_type");IN_type_symbol -;ACOS;1;(ANY_REAL);ANY_REAL;Arc cosine;no;(None, "__acos_", "IN_type");IN_type_symbol -;ATAN;1;(ANY_REAL);ANY_REAL;Arc tangent;no;(None, "__atan_", "IN_type");IN_type_symbol -Arithmetic;ADD;1;(ANY_NUM, ANY_NUM);ANY_NUM;Addition;yes;(None, "__add_", "return_type");copy_input -;ADD;1;(TIME, TIME);TIME;Time addition;no;(None, "__time_add", None);defined -;ADD;1;(TOD, TIME);TOD;Time-of-day addition;no;(None, "__time_add", None);defined -;ADD;1;(DT, TIME);DT;Date addition;no;(None, "__time_add", None);defined -;MUL;1;(ANY_NUM, ANY_NUM);ANY_NUM;Multiplication;yes;(None, "__mul_", "return_type");copy_input -;MUL;1;(TIME, ANY_NUM);TIME;Time multiplication;no;(None, "__time_mul", None);defined -;SUB;1;(ANY_NUM, ANY_NUM);ANY_NUM;Subtraction;no;(None, "__sub_", "return_type");copy_input -;SUB;1;(TIME, TIME);TIME;Time subtraction;no;(None, "__time_sub", None);defined -;SUB;1;(DATE, DATE);TIME;Date subtraction;no;(None, "__time_sub", None);defined -;SUB;1;(TOD, TIME);TOD;Time-of-day subtraction;no;(None, "__time_sub", None);defined -;SUB;1;(TOD, TOD);TIME;Time-of-day subtraction;no;(None, "__time_sub", None);defined -;SUB;1;(DT, TIME);DT;Date and time subtraction;no;(None, "__time_sub", None);defined -;SUB;1;(DT, DT);TIME;Date and time subtraction;no;(None, "__time_sub", None);defined -;DIV;1;(ANY_NUM, ANY_NUM);ANY_NUM;Division;no;(None, "__div_", "return_type");copy_input -;DIV;1;(TIME, ANY_NUM);TIME;Time division;no;(None, "__time_div", None);defined -;MOD;1;(ANY_NUM, ANY_NUM);ANY_NUM;Remainder (modulo);no;(None, "__mod_", "return_type");copy_input -;EXPT;1;(ANY_REAL, ANY_NUM);ANY_REAL;Exponent;no;(None, "__expt_", "IN1_type");copy_input -;MOVE;1;(ANY);ANY;Assignment;no;(None, "__move_", "return_type");copy_input -Bit-shift;SHL;1;(ANY_BIT, N);ANY_BIT;Shift left;no;(None, "__shl_", "IN_type");IN_type_symbol -;SHR;1;(ANY_BIT, N);ANY_BIT;Shift right;no;(None, "__shr_", "IN_type");IN_type_symbol -;ROR;1;(ANY_NBIT, N);ANY_NBIT;Rotate right;no;(None, "__ror_", "IN_type");IN_type_symbol -;ROL;1;(ANY_NBIT, N);ANY_NBIT;Rotate left;no;(None, "__rol_", "IN_type");IN_type_symbol -Bitwise;AND;1;(ANY_BIT, ANY_BIT);ANY_BIT;Bitwise AND;yes;(None, "__and_", "return_type");copy_input -;OR;1;(ANY_BIT, ANY_BIT);ANY_BIT;Bitwise OR;yes;(None, "__or_", "return_type");copy_input -;XOR;1;(ANY_BIT, ANY_BIT);ANY_BIT;Bitwise EXOR;yes;(None, "__xor_", "return_type");copy_input -;NOT;1;(ANY_BIT);ANY_BIT;Bitwise inverting;no;(None, "__not_", "return_type");IN_type_symbol -Selection;SEL;0;(G, ANY, ANY);ANY;Binary selection (1 of 2);no;(None, "__sel_", "IN0_type");copy_input -;MAX;1;(ANY, ANY);ANY;Maximum;yes;(None, "__max_", "return_type");copy_input -;MIN;1;(ANY, ANY);ANY;Minimum;yes;(None, "__min_", "return_type");copy_input -;LIMIT;1;(MN, ANY, MX);ANY;Limitation;no;(None, "__limit_", "IN_type");IN_type_symbol -;MUX;0;(K, ANY, ANY);ANY;Multiplexer (select 1 of N);yes;(None, "__mux_", "return_type");copy_input -Comparison;GT;1;(ANY, ANY);BOOL;Greater than;yes;(None, "__gt_", "common_type");defined -;GE;1;(ANY, ANY);BOOL;Greater than or equal to;yes;(None, "__ge_", "common_type");defined -;EQ;1;(ANY, ANY);BOOL;Equal to;yes;(None, "__eq_", "common_type");defined -;LT;1;(ANY, ANY);BOOL;Less than;yes;(None, "__lt_", "common_type");defined -;LE;1;(ANY, ANY);BOOL;Less than or equal to;yes;(None, "__le_", "common_type");defined -;NE;1;(ANY, ANY);BOOL;Not equal to;yes;(None, "__ne_", "common_type");defined -Character string;LEN;1;(STRING);INT;Length of string;no;(None, "__len", None);defined -;LEFT;1;(STRING, L);STRING;string left of;no;(None, "__left", None);defined -;RIGHT;1;(STRING, L);STRING;string right of;no;(None, "__right", None);defined -;MID;1;(STRING, L, P);STRING;string from the middle;no;(None, "__mid", None);defined -;CONCAT;1;(STRING, STRING);STRING;Concatenation;yes;(None, "__concat", None);defined -;CONCAT;1;(DATE, TOD);DT;Time concatenation;no;(None, "__time_add", None);defined -;INSERT;1;(STRING, STRING, P);STRING;Insertion (into);no;(None, "__insert", None);defined -;DELETE;1;(STRING, L, P);STRING;Deletion (within);no;(None, "__delete", None);defined -;REPLACE;1;(STRING, STRING, L, P);STRING;Replacement (within);no;(None, "__replace", None);defined -;FIND;1;(STRING, STRING);INT;Find position;no;(None, "__find", None);defined +_("Type conversion");*_TO_**;1;(ANY);ANY;_("Data type conversion");no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_ANY_LIST,fdecl);defined +;TRUNC;1;(ANY_REAL);ANY_INT;_("Rounding up/down");no;("int", None, None);&search_constant_type_c::constant_int_type_name +;BCD_TO_**;1;(ANY_BIT);ANY_INT;_("Conversion from BCD");no;ANY_TO_ANY_FORMAT_GEN(BCD_TO_ANY_LIST,fdecl);defined +;*_TO_BCD;1;(ANY_INT);ANY_BIT;_("Conversion to BCD");no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_BCD_LIST,fdecl);&search_constant_type_c::constant_int_type_name +;DATE_AND_TIME_TO_TIME_OF_DAY;1;(DT);TOD;_("Conversion to time-of-day");no;(None, "__date_and_time_to_time_of_day", None);defined +;DATE_AND_TIME_TO_DATE;1;(DT);DATE;_("Conversion to date");no;(None, "__date_and_time_to_date", None);defined +_("Numerical");ABS;1;(ANY_NUM);ANY_NUM;_("Absolute number");no;(None, "__abs_", "IN_type");IN_type_symbol +;SQRT;1;(ANY_REAL);ANY_REAL;_("Square root (base 2)");no;(None, "__sqrt_", "IN_type");IN_type_symbol +;LN;1;(ANY_REAL);ANY_REAL;_("Natural logarithm");no;(None, "__ln_", "IN_type");IN_type_symbol +;LOG;1;(ANY_REAL);ANY_REAL;_("Logarithm to base 10");no;(None, "__log_", "IN_type");IN_type_symbol +;EXP;1;(ANY_REAL);ANY_REAL;_("Exponentiation");no;(None, "__exp_", "IN_type");IN_type_symbol +;SIN;1;(ANY_REAL);ANY_REAL;_("Sine");no;(None, "__sin_", "IN_type");IN_type_symbol +;COS;1;(ANY_REAL);ANY_REAL;_("Cosine");no;(None, "__cos_", "IN_type");IN_type_symbol +;TAN;1;(ANY_REAL);ANY_REAL;_("Tangent");no;(None, "__tan_", "IN_type");IN_type_symbol +;ASIN;1;(ANY_REAL);ANY_REAL;_("Arc sine");no;(None, "__asin_", "IN_type");IN_type_symbol +;ACOS;1;(ANY_REAL);ANY_REAL;_("Arc cosine");no;(None, "__acos_", "IN_type");IN_type_symbol +;ATAN;1;(ANY_REAL);ANY_REAL;_("Arc tangent");no;(None, "__atan_", "IN_type");IN_type_symbol +_("Arithmetic");ADD;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Addition");yes;(None, "__add_", "return_type");copy_input +;ADD;1;(TIME, TIME);TIME;_("Time addition");no;(None, "__time_add", None);defined +;ADD;1;(TOD, TIME);TOD;_("Time-of-day addition");no;(None, "__time_add", None);defined +;ADD;1;(DT, TIME);DT;_("Date addition");no;(None, "__time_add", None);defined +;MUL;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Multiplication");yes;(None, "__mul_", "return_type");copy_input +;MUL;1;(TIME, ANY_NUM);TIME;_("Time multiplication");no;(None, "__time_mul", None);defined +;SUB;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Subtraction");no;(None, "__sub_", "return_type");copy_input +;SUB;1;(TIME, TIME);TIME;_("Time subtraction");no;(None, "__time_sub", None);defined +;SUB;1;(DATE, DATE);TIME;_("Date subtraction");no;(None, "__time_sub", None);defined +;SUB;1;(TOD, TIME);TOD;_("Time-of-day subtraction");no;(None, "__time_sub", None);defined +;SUB;1;(TOD, TOD);TIME;_("Time-of-day subtraction");no;(None, "__time_sub", None);defined +;SUB;1;(DT, TIME);DT;_("Date and time subtraction");no;(None, "__time_sub", None);defined +;SUB;1;(DT, DT);TIME;_("Date and time subtraction");no;(None, "__time_sub", None);defined +;DIV;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Division");no;(None, "__div_", "return_type");copy_input +;DIV;1;(TIME, ANY_NUM);TIME;_("Time division");no;(None, "__time_div", None);defined +;MOD;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Remainder (modulo)");no;(None, "__mod_", "return_type");copy_input +;EXPT;1;(ANY_REAL, ANY_NUM);ANY_REAL;_("Exponent");no;(None, "__expt_", "IN1_type");copy_input +;MOVE;1;(ANY);ANY;_("Assignment");no;(None, "__move_", "return_type");copy_input +_("Bit-shift");SHL;1;(ANY_BIT, N);ANY_BIT;_("Shift left");no;(None, "__shl_", "IN_type");IN_type_symbol +;SHR;1;(ANY_BIT, N);ANY_BIT;_("Shift right");no;(None, "__shr_", "IN_type");IN_type_symbol +;ROR;1;(ANY_NBIT, N);ANY_NBIT;_("Rotate right");no;(None, "__ror_", "IN_type");IN_type_symbol +;ROL;1;(ANY_NBIT, N);ANY_NBIT;_("Rotate left");no;(None, "__rol_", "IN_type");IN_type_symbol +_("Bitwise");AND;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise AND");yes;(None, "__and_", "return_type");copy_input +;OR;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise OR");yes;(None, "__or_", "return_type");copy_input +;XOR;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise XOR");yes;(None, "__xor_", "return_type");copy_input +;NOT;1;(ANY_BIT);ANY_BIT;_("Bitwise inverting");no;(None, "__not_", "return_type");IN_type_symbol +_("Selection");SEL;0;(G, ANY, ANY);ANY;_("Binary selection (1 of 2)");no;(None, "__sel_", "IN0_type");copy_input +;MAX;1;(ANY, ANY);ANY;_("Maximum");yes;(None, "__max_", "return_type");copy_input +;MIN;1;(ANY, ANY);ANY;_("Minimum");yes;(None, "__min_", "return_type");copy_input +;LIMIT;1;(MN, ANY, MX);ANY;_("Limitation");no;(None, "__limit_", "IN_type");IN_type_symbol +;MUX;0;(K, ANY, ANY);ANY;_("Multiplexer (select 1 of N)");yes;(None, "__mux_", "return_type");copy_input +_("Comparison");GT;1;(ANY, ANY);BOOL;_("Greater than");yes;(None, "__gt_", "common_type");defined +;GE;1;(ANY, ANY);BOOL;_("Greater than or equal to");yes;(None, "__ge_", "common_type");defined +;EQ;1;(ANY, ANY);BOOL;_("Equal to");yes;(None, "__eq_", "common_type");defined +;LT;1;(ANY, ANY);BOOL;_("Less than");yes;(None, "__lt_", "common_type");defined +;LE;1;(ANY, ANY);BOOL;_("Less than or equal to");yes;(None, "__le_", "common_type");defined +;NE;1;(ANY, ANY);BOOL;_("Not equal to");yes;(None, "__ne_", "common_type");defined +_("Character string");LEN;1;(STRING);INT;_("Length of string");no;(None, "__len", None);defined +;LEFT;1;(STRING, L);STRING;_("string left of");no;(None, "__left", None);defined +;RIGHT;1;(STRING, L);STRING;_("string right of");no;(None, "__right", None);defined +;MID;1;(STRING, L, P);STRING;_("string from the middle");no;(None, "__mid", None);defined +;CONCAT;1;(STRING, STRING);STRING;_("Concatenation");yes;(None, "__concat", None);defined +;CONCAT;1;(DATE, TOD);DT;_("Time concatenation");no;(None, "__time_add", None);defined +;INSERT;1;(STRING, STRING, P);STRING;_("Insertion (into)");no;(None, "__insert", None);defined +;DELETE;1;(STRING, L, P);STRING;_("Deletion (within)");no;(None, "__delete", None);defined +;REPLACE;1;(STRING, STRING, L, P);STRING;_("Replacement (within)");no;(None, "__replace", None);defined +;FIND;1;(STRING, STRING);INT;_("Find position");no;(None, "__find", None);defined diff -r 020420ad8914 -r 07447ee3538e plcopen/plcopen.py --- a/plcopen/plcopen.py Fri Jul 24 12:49:57 2009 +0200 +++ b/plcopen/plcopen.py Fri Jul 24 17:12:59 2009 +0200 @@ -253,7 +253,7 @@ def addconfiguration(self, name): for configuration in self.instances.configurations.getconfiguration(): if configuration.getname() == name: - raise ValueError, "\"%s\" configuration already exists !!!"%name + raise ValueError, _("\"%s\" configuration already exists !!!")%name new_configuration = PLCOpenClasses["configurations_configuration"]() new_configuration.setname(name) self.instances.configurations.appendconfiguration(new_configuration) @@ -267,7 +267,7 @@ found = True break if not found: - raise ValueError, "\"%s\" configuration doesn't exist !!!"%name + raise ValueError, ("\"%s\" configuration doesn't exist !!!")%name setattr(cls, "removeconfiguration", removeconfiguration) def getconfigurationResource(self, config_name, name): @@ -284,7 +284,7 @@ if configuration: for resource in configuration.getresource(): if resource.getname() == name: - raise ValueError, "\"%s\" resource already exists in \"%s\" configuration !!!"%(name, config_name) + raise ValueError, _("\"%s\" resource already exists in \"%s\" configuration !!!")%(name, config_name) new_resource = PLCOpenClasses["configuration_resource"]() new_resource.setname(name) configuration.appendresource(new_resource) @@ -300,7 +300,7 @@ found = True break if not found: - raise ValueError, "\"%s\" resource doesn't exist in \"%s\" configuration !!!"%(name, config_name) + raise ValueError, _("\"%s\" resource doesn't exist in \"%s\" configuration !!!")%(name, config_name) setattr(cls, "removeconfigurationResource", removeconfigurationResource) def updateElementName(self, old_name, new_name): @@ -779,7 +779,7 @@ found = True break if not found: - raise ValueError, "\"%s\" Data Type doesn't exist !!!"%name + raise ValueError, _("\"%s\" Data Type doesn't exist !!!")%name setattr(cls, "removedataTypeElement", removedataTypeElement) def getpouElements(self): @@ -797,7 +797,7 @@ def appendpouElement(self, name, pou_type, body_type): for element in self.pous.getpou(): if element.getname() == name: - raise ValueError, "\"%s\" POU already exists !!!"%name + raise ValueError, _("\"%s\" POU already exists !!!")%name new_pou = PLCOpenClasses["pous_pou"]() new_pou.setname(name) new_pou.setpouType(pou_type) @@ -818,7 +818,7 @@ found = True break if not found: - raise ValueError, "\"%s\" POU doesn't exist !!!"%name + raise ValueError, _("\"%s\" POU doesn't exist !!!")%name setattr(cls, "removepouElement", removepouElement) cls = PLCOpenClasses.get("pous_pou", None) @@ -1032,7 +1032,7 @@ removed = True i += 1 if not removed: - raise ValueError, "Transition with name %s doesn't exists!"%name + raise ValueError, _("Transition with name %s doesn't exists!")%name setattr(cls, "removetransition", removetransition) def addaction(self, name, type): @@ -1070,7 +1070,7 @@ removed = True i += 1 if not removed: - raise ValueError, "Action with name %s doesn't exists!"%name + raise ValueError, _("Action with name %s doesn't exists!")%name setattr(cls, "removeaction", removeaction) def updateElementName(self, old_name, new_name): @@ -1215,7 +1215,7 @@ PLCOpenClasses.get("commonObjects_continuation", None))): element["value"].setexecutionOrderId(0) else: - raise TypeError, "Can only generate execution order on FBD networks!" + raise TypeError, _("Can only generate execution order on FBD networks!") setattr(cls, "resetexecutionOrder", resetexecutionOrder) def compileexecutionOrder(self): @@ -1229,7 +1229,7 @@ self.compileelementExecutionOrder(connections[0]) element["value"].setexecutionOrderId(self.getnewExecutionOrderId()) else: - raise TypeError, "Can only generate execution order on FBD networks!" + raise TypeError, _("Can only generate execution order on FBD networks!") setattr(cls, "compileexecutionOrder", compileexecutionOrder) def compileelementExecutionOrder(self, link): @@ -1250,7 +1250,7 @@ if connections and len(connections) == 1: self.compileelementExecutionOrder(connections[0]) else: - raise TypeError, "Can only generate execution order on FBD networks!" + raise TypeError, _("Can only generate execution order on FBD networks!") setattr(cls, "compileelementExecutionOrder", compileelementExecutionOrder) def setelementExecutionOrder(self, instance, new_executionOrder): @@ -1266,14 +1266,14 @@ element["value"].setexecutionOrderId(element_executionOrder + 1) instance.setexecutionOrderId(new_executionOrder) else: - raise TypeError, "Can only generate execution order on FBD networks!" + raise TypeError, _("Can only generate execution order on FBD networks!") setattr(cls, "setelementExecutionOrder", setelementExecutionOrder) def appendcontentInstance(self, name, instance): if self.content["name"] in ["LD","FBD","SFC"]: self.content["value"].appendcontent({"name" : name, "value" : instance}) else: - raise TypeError, "%s body don't have instances!"%self.content["name"] + raise TypeError, _("%s body don't have instances!")%self.content["name"] setattr(cls, "appendcontentInstance", appendcontentInstance) def getcontentInstances(self): @@ -1283,7 +1283,7 @@ instances.append(element["value"]) return instances else: - raise TypeError, "%s body don't have instances!"%self.content["name"] + raise TypeError, _("%s body don't have instances!")%self.content["name"] setattr(cls, "getcontentInstances", getcontentInstances) def getcontentInstance(self, id): @@ -1293,7 +1293,7 @@ return element["value"] return None else: - raise TypeError, "%s body don't have instances!"%self.content["name"] + raise TypeError, _("%s body don't have instances!")%self.content["name"] setattr(cls, "getcontentInstance", getcontentInstance) def getcontentRandomInstance(self, exclude): @@ -1303,7 +1303,7 @@ return element["value"] return None else: - raise TypeError, "%s body don't have instances!"%self.content["name"] + raise TypeError, _("%s body don't have instances!")%self.content["name"] setattr(cls, "getcontentRandomInstance", getcontentRandomInstance) def getcontentInstanceByName(self, name): @@ -1312,7 +1312,7 @@ if isinstance(element["value"], PLCOpenClasses.get("fbdObjects_block", None)) and element["value"].getinstanceName() == name: return element["value"] else: - raise TypeError, "%s body don't have instances!"%self.content["name"] + raise TypeError, _("%s body don't have instances!")%self.content["name"] setattr(cls, "getcontentInstanceByName", getcontentInstanceByName) def removecontentInstance(self, id): @@ -1326,7 +1326,7 @@ removed = True i += 1 if not removed: - raise ValueError, "Instance with id %d doesn't exists!"%id + raise ValueError, _("Instance with id %d doesn't exists!")%id else: raise TypeError, "%s body don't have instances!"%self.content["name"] setattr(cls, "removecontentInstance", removecontentInstance) @@ -1335,14 +1335,14 @@ if self.content["name"] in ["IL","ST"]: self.content["value"].settext(text) else: - raise TypeError, "%s body don't have text!"%self.content["name"] + raise TypeError, _("%s body don't have text!")%self.content["name"] setattr(cls, "settext", settext) def gettext(self): if self.content["name"] in ["IL","ST"]: return self.content["value"].gettext() else: - raise TypeError, "%s body don't have text!"%self.content["name"] + raise TypeError, _("%s body don't have text!")%self.content["name"] setattr(cls, "gettext", gettext) def updateElementName(self, old_name, new_name): @@ -2117,7 +2117,7 @@ elif opened == closed: i += 1 else: - raise ValueError, "\"%s\" is an invalid value!"%value + raise ValueError, _("\"%s\" is an invalid value!")%value return items cls = PLCOpenClasses.get("value_arrayValue", None) diff -r 020420ad8914 -r 07447ee3538e plcopen/structures.py --- a/plcopen/structures.py Fri Jul 24 12:49:57 2009 +0200 +++ b/plcopen/structures.py Fri Jul 24 17:12:59 2009 +0200 @@ -33,6 +33,8 @@ "D" : ["DINT", "UDINT", "REAL", "DWORD"], "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} +_ = lambda x:x + # Helper for emulate join on element list def JoinList(separator, mylist): if len(mylist) > 0 : @@ -92,7 +94,7 @@ generator.Program += JoinList([(", ", ())], vars) generator.Program += [(");\n", ())] else: - generator.Warnings.append("\"%s\" function cancelled in \"%s\" POU: No input connected"%(type, generator.TagName.split("::")[-1])) + generator.Warnings.append(_("\"%s\" function cancelled in \"%s\" POU: No input connected")%(type, generator.TagName.split("::")[-1])) if link: connectionPoint = link.getposition()[-1] else: @@ -134,7 +136,7 @@ output_info = (generator.TagName, "block", block.getlocalId(), "output", i) return generator.ExtractModifier(variable, [("%s.%s"%(name, variable.getformalParameter()), output_info)], output_info) if link is not None: - raise ValueError, "No output variable found" + raise ValueError, _("No output variable found") def initialise_block(type, name, block = None): return [(type, name, None, None)] @@ -160,98 +162,98 @@ - The default modifier which can be "none", "negated", "rising" or "falling" """ -BlockTypes = [{"name" : "Standard function blocks", "list": +BlockTypes = [{"name" : _("Standard function blocks"), "list": [{"name" : "SR", "type" : "functionBlock", "extensible" : False, "inputs" : [("S1","BOOL","none"),("R","BOOL","none")], "outputs" : [("Q1","BOOL","none")], - "comment" : "SR bistable\nThe SR bistable is a latch where the Set dominates.", + "comment" : _("SR bistable\nThe SR bistable is a latch where the Set dominates."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "RS", "type" : "functionBlock", "extensible" : False, "inputs" : [("S","BOOL","none"),("R1","BOOL","none")], "outputs" : [("Q1","BOOL","none")], - "comment" : "RS bistable\nThe RS bistable is a latch where the Reset dominates.", + "comment" : _("RS bistable\nThe RS bistable is a latch where the Reset dominates."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "SEMA", "type" : "functionBlock", "extensible" : False, "inputs" : [("CLAIM","BOOL","none"),("RELEASE","BOOL","none")], "outputs" : [("BUSY","BOOL","none")], - "comment" : "Semaphore\nThe semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources.", + "comment" : _("Semaphore\nThe semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "R_TRIG", "type" : "functionBlock", "extensible" : False, "inputs" : [("CLK","BOOL","none")], "outputs" : [("Q","BOOL","none")], - "comment" : "Rising edge detector\nThe output produces a single pulse when a rising edge is detected.", + "comment" : _("Rising edge detector\nThe output produces a single pulse when a rising edge is detected."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "F_TRIG", "type" : "functionBlock", "extensible" : False, "inputs" : [("CLK","BOOL","none")], "outputs" : [("Q","BOOL","none")], - "comment" : "Falling edge detector\nThe output produces a single pulse when a falling edge is detected.", + "comment" : _("Falling edge detector\nThe output produces a single pulse when a falling edge is detected."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "CTU", "type" : "functionBlock", "extensible" : False, "inputs" : [("CU","BOOL","rising"),("R","BOOL","none"),("PV","INT","none")], "outputs" : [("Q","BOOL","none"),("CV","INT","none")], - "comment" : "Up-counter\nThe up-counter can be used to signal when a count has reached a maximum value.", + "comment" : _("Up-counter\nThe up-counter can be used to signal when a count has reached a maximum value."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "CTD", "type" : "functionBlock", "extensible" : False, "inputs" : [("CD","BOOL","rising"),("LD","BOOL","none"),("PV","INT","none")], "outputs" : [("Q","BOOL","none"),("CV","INT","none")], - "comment" : "Down-counter\nThe down-counter can be used to signal when a count has reached zero, on counting down from a preset value.", + "comment" : _("Down-counter\nThe down-counter can be used to signal when a count has reached zero, on counting down from a preset value."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "CTUD", "type" : "functionBlock", "extensible" : False, "inputs" : [("CU","BOOL","rising"),("CD","BOOL","rising"),("R","BOOL","none"),("LD","BOOL","none"),("PV","INT","none")], "outputs" : [("QU","BOOL","none"),("QD","BOOL","none"),("CV","INT","none")], - "comment" : "Up-down counter\nThe up-down counter has two inputs CU and CD. It can be used to both count up on one input ans down on the other.", + "comment" : _("Up-down counter\nThe 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."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "TP", "type" : "functionBlock", "extensible" : False, "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], "outputs" : [("Q","BOOL","none"),("ET","TIME","none")], - "comment" : "Pulse timer\nThe pulse timer can be used to generate output pulses of a given time duration.", + "comment" : _("Pulse timer\nThe pulse timer can be used to generate output pulses of a given time duration."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "TON", "type" : "functionBlock", "extensible" : False, "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], "outputs" : [("Q","BOOL","none"),("ET","TIME","none")], - "comment" : "On-delay timer\nThe on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true.", + "comment" : _("On-delay timer\nThe on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "TOF", "type" : "functionBlock", "extensible" : False, "inputs" : [("IN","BOOL","none"),("PT","TIME","none")], "outputs" : [("Q","BOOL","none"),("ET","TIME","none")], - "comment" : "Off-delay timer\nThe off-delay timer can be used to delay setting an output false, for fixed period after input goes false.", + "comment" : _("Off-delay timer\nThe off-delay timer can be used to delay setting an output false, for fixed period after input goes false."), "generate" : generate_block, "initialise" : initialise_block}, ]}, - {"name" : "Additionnal function blocks", "list": + {"name" : _("Additionnal function blocks"), "list": ## {"name" : "RTC", "type" : "functionBlock", "extensible" : False, ## "inputs" : [("EN","BOOL","none"),("PDT","DATE_AND_TIME","none")], ## "outputs" : [("Q","BOOL","none"),("CDT","DATE_AND_TIME","none")], -## "comment" : "Real time clock\nThe real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on.", +## "comment" : _("Real time clock\nThe real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on."), ## "generate" : generate_block, "initialise" : initialise_block}, [{"name" : "INTEGRAL", "type" : "functionBlock", "extensible" : False, "inputs" : [("RUN","BOOL","none"),("R1","BOOL","none"),("XIN","REAL","none"),("X0","REAL","none"),("CYCLE","TIME","none")], "outputs" : [("Q","BOOL","none"),("XOUT","REAL","none")], - "comment" : "Integral\nThe integral function block integrates the value of input XIN over time.", + "comment" : _("Integral\nThe integral function block integrates the value of input XIN over time."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "DERIVATIVE", "type" : "functionBlock", "extensible" : False, "inputs" : [("RUN","BOOL","none"),("XIN","REAL","none"),("CYCLE","TIME","none")], "outputs" : [("XOUT","REAL","none")], - "comment" : "Derivative\nThe derivative function block produces an output XOUT proportional to the rate of change of the input XIN.", + "comment" : _("Derivative\nThe derivative function block produces an output XOUT proportional to the rate of change of the input XIN."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "PID", "type" : "functionBlock", "extensible" : False, "inputs" : [("AUTO","BOOL","none"),("PV","REAL","none"),("SP","REAL","none"),("X0","REAL","none"),("KP","REAL","none"),("TR","REAL","none"),("TD","REAL","none"),("CYCLE","TIME","none")], "outputs" : [("XOUT","REAL","none")], - "comment" : "PID\nThe PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control.", + "comment" : _("PID\nThe PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "RAMP", "type" : "functionBlock", "extensible" : False, "inputs" : [("RUN","BOOL","none"),("X0","REAL","none"),("X1","REAL","none"),("TR","TIME","none"),("CYCLE","TIME","none"),("HOLDBACK","BOOL","none"),("ERROR","REAL","none"),("PV","REAL","none")], "outputs" : [("RAMP","BOOL","none"),("XOUT","REAL","none")], - "comment" : "Ramp\nThe RAMP function block is modelled on example given in the standard but with the addition of a 'Holdback' feature.", + "comment" : _("Ramp\nThe RAMP function block is modelled on example given in the standard but with the addition of a 'Holdback' feature."), "generate" : generate_block, "initialise" : initialise_block}, {"name" : "HYSTERESIS", "type" : "functionBlock", "extensible" : False, "inputs" : [("XIN1","REAL","none"),("XIN2","REAL","none"),("EPS","REAL","none")], "outputs" : [("Q","BOOL","none")], - "comment" : "Hysteresis\nThe hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2.", + "comment" : _("Hysteresis\nThe hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2."), "generate" : generate_block, "initialise" : initialise_block}, ## {"name" : "RATIO_MONITOR", "type" : "functionBlock", "extensible" : False, ## "inputs" : [("PV1","REAL","none"),("PV2","REAL","none"),("RATIO","REAL","none"),("TIMON","TIME","none"),("TIMOFF","TIME","none"),("TOLERANCE","BOOL","none"),("RESET","BOOL","none"),("CYCLE","TIME","none")], ## "outputs" : [("ALARM","BOOL","none"),("TOTAL_ERR","BOOL","none")], -## "comment" : "Ratio monitor\nThe ratio_monitor function block checks that one process value PV1 is always a given ratio (defined by input RATIO) of a second process value PV2.", +## "comment" : _("Ratio monitor\nThe ratio_monitor function block checks that one process value PV1 is always a given ratio (defined by input RATIO) of a second process value PV2."), ## "generate" : generate_block, "initialise" : initialise_block} ]}, ] @@ -503,7 +505,12 @@ if fields[1]: # If function section name given if fields[0]: - Current_section = {"name" : fields[0], "list" : []} + words = fields[0].split('"') + if len(words) > 1: + section_name = words[1] + else: + section_name = fields[0] + Current_section = {"name" : section_name, "list" : []} Standard_Functions_Decl.append(Current_section) Function_decl_list = [] if Current_section: @@ -563,7 +570,10 @@ # create the copy of decl dict to be appended to section Function_decl_copy = Function_decl.copy() # Have to generate type description in comment with freshly redefined types - Function_decl_copy["comment"] += ( + words = Function_decl_copy["comment"].split('"') + if len(words) > 1: + Function_decl_copy["comment"] = words[1] + Function_decl_copy["usage"] = ( "\n (" + str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in Function_decl["inputs"]]).strip("[]").replace("'",'') + " ) => (" +