diff -r 000000000000 -r c2295d311402 etherlab/ConfigEditor.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etherlab/ConfigEditor.py Sun Dec 18 19:42:13 2011 +0100 @@ -0,0 +1,568 @@ +import wx + +from controls import CustomGrid, CustomTable, EditorPanel + +[ETHERCAT_VENDOR, ETHERCAT_GROUP, ETHERCAT_DEVICE] = range(3) + +def AppendMenu(parent, help, id, kind, text): + if wx.VERSION >= (2, 6, 0): + parent.Append(help=help, id=id, kind=kind, text=text) + else: + parent.Append(helpString=help, id=id, kind=kind, item=text) + +[ID_SLAVETYPECHOICEDIALOG, ID_SLAVETYPECHOICEDIALOGSTATICTEXT1, + ID_SLAVETYPECHOICEDIALOGSLAVETYPESLIBRARY +] = [wx.NewId() for _init_ctrls in range(3)] + +class SlaveTypeChoiceDialog(wx.Dialog): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_flexGridSizer1_Items(self, parent): + parent.AddWindow(self.staticText1, 0, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddWindow(self.SlaveTypesLibrary, 0, border=20, flag=wx.GROW|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.ButtonSizer, 0, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_flexGridSizer1_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_sizers(self): + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt): + wx.Dialog.__init__(self, id=ID_SLAVETYPECHOICEDIALOG, + name='SlaveTypeChoiceDialog', parent=prnt, + size=wx.Size(600, 400), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER, + title=_('Browse slave types library')) + self.SetClientSize(wx.Size(600, 400)) + + self.staticText1 = wx.StaticText(id=ID_SLAVETYPECHOICEDIALOGSTATICTEXT1, + label=_('Choose a slave type:'), name='staticText1', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.SlaveTypesLibrary = wx.TreeCtrl(id=ID_SLAVETYPECHOICEDIALOGSLAVETYPESLIBRARY, + name='TypeTree', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_HIDE_ROOT|wx.TR_LINES_AT_ROOT) + + self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) + if wx.VERSION >= (2, 5, 0): + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId()) + else: + self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) + + self._init_sizers() + + def __init__(self, parent, controler, default=None): + self._init_ctrls(parent) + + slaves_types = controler.GetSlaveTypesLibrary() + + root = self.SlaveTypesLibrary.AddRoot("") + self.GenerateSlaveTypesLibraryTreeBranch(root, slaves_types, default) + + def GenerateSlaveTypesLibraryTreeBranch(self, root, children, default): + for infos in children: + item = self.SlaveTypesLibrary.AppendItem(root, infos["name"]) + if infos["type"] == ETHERCAT_DEVICE: + self.SlaveTypesLibrary.SetPyData(item, infos["infos"]) + if infos["infos"] == default: + self.SlaveTypesLibrary.SelectItem(item) + self.SlaveTypesLibrary.EnsureVisible(item) + else: + self.GenerateSlaveTypesLibraryTreeBranch(item, infos["children"], default) + + def GetType(self): + selected = self.SlaveTypesLibrary.GetSelection() + return self.SlaveTypesLibrary.GetPyData(selected) + + def OnOK(self, event): + selected = self.SlaveTypesLibrary.GetSelection() + if not selected.IsOk() or self.SlaveTypesLibrary.GetPyData(selected) is None: + message = wx.MessageDialog(self, _("No valid slave type selected!"), _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + self.EndModal(wx.ID_OK) + + +def GetPDOsTableColnames(): + _ = lambda x : x + return ["#", _("Index"), _("Name"), _("Type")] + +def GetVariablesTableColnames(): + _ = lambda x : x + return ["#", _("Index"), _("SubIndex"), _("Name"), _("Type"), _("PDO")] + +class PDOsTable(CustomTable): + + def GetValue(self, row, col): + if row < self.GetNumberRows(): + if col == 0: + return row + 1 + colname = self.GetColLabelValue(col, False) + value = self.data[row].get(colname, "") + if colname == "Type": + value = _(value) + return value + +class VariablesTable(CustomTable): + + def GetValue(self, row, col): + if row < self.GetNumberRows(): + if col == 0: + return row + 1 + return self.data[row].get(self.GetColLabelValue(col, False), "") + +[ID_SLAVEPANEL, ID_SLAVEPANELTYPELABEL, + ID_SLAVEPANELTYPE, ID_SLAVEPANELTYPEBROWSE, + ID_SLAVEPANELALIASLABEL, ID_SLAVEPANELALIAS, + ID_SLAVEPANELPOSLABEL, ID_SLAVEPANELPOS, + ID_SLAVEPANELSLAVEINFOSSTATICBOX, ID_SLAVEPANELVENDORLABEL, + ID_SLAVEPANELVENDOR, ID_SLAVEPANELPRODUCTCODELABEL, + ID_SLAVEPANELPRODUCTCODE, ID_SLAVEPANELREVISIONNUMBERLABEL, + ID_SLAVEPANELREVISIONNUMBER, ID_SLAVEPANELPHYSICSLABEL, + ID_SLAVEPANELPHYSICS, ID_SLAVEPANELPDOSLABEL, + ID_SLAVEPANELPDOSGRID, ID_SLAVEPANELVARIABLESLABEL, + ID_SLAVEPANELVARIABLESGRID, +] = [wx.NewId() for _init_ctrls in range(21)] + +class SlavePanel(wx.Panel): + + if wx.VERSION < (2, 6, 0): + def Bind(self, event, function, id = None): + if id is not None: + event(self, id, function) + else: + event(self, function) + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.PositionSizer, 0, border=5, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddSizer(self.SlaveInfosBoxSizer, 0, border=5, flag=wx.GROW|wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT) + + def _init_coll_MainSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_coll_PositionSizer_Items(self, parent): + parent.AddWindow(self.TypeLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) + parent.AddSizer(self.TypeSizer, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.AliasLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) + parent.AddWindow(self.Alias, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.PosLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) + parent.AddWindow(self.Pos, 0, border=0, flag=wx.GROW) + + def _init_coll_PositionSizer_Growables(self, parent): + parent.AddGrowableCol(1) + parent.AddGrowableCol(3) + parent.AddGrowableCol(5) + parent.AddGrowableRow(0) + + def _init_coll_TypeSizer_Items(self, parent): + parent.AddWindow(self.Type, 1, border=0, flag=0) + parent.AddWindow(self.TypeBrowse, 0, border=0, flag=0) + + def _init_coll_SlaveInfosBoxSizer_Items(self, parent): + parent.AddSizer(self.SlaveInfosSizer, 1, border=5, flag=wx.GROW|wx.ALL) + + def _init_coll_SlaveInfosSizer_Items(self, parent): + parent.AddSizer(self.SlaveInfosDetailsSizer, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.PDOsLabel, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.PDOsGrid, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.VariablesLabel, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wx.GROW) + + def _init_coll_SlaveInfosSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(2) + parent.AddGrowableRow(4) + + def _init_coll_SlaveInfosDetailsSizer_Items(self, parent): + parent.AddWindow(self.VendorLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW) + parent.AddWindow(self.Vendor, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.ProductCodeLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW) + parent.AddWindow(self.ProductCode, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.RevisionNumberLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW) + parent.AddWindow(self.RevisionNumber, 0, border=0, flag=wx.GROW) + parent.AddWindow(self.PhysicsLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW) + parent.AddWindow(self.Physics, 0, border=0, flag=wx.GROW) + + def _init_coll_SlaveInfosDetailsSizer_Growables(self, parent): + parent.AddGrowableCol(1) + parent.AddGrowableCol(3) + + def _init_sizers(self): + self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) + self.PositionSizer = wx.FlexGridSizer(cols=6, hgap=5, rows=1, vgap=0) + self.TypeSizer = wx.BoxSizer(wx.HORIZONTAL) + self.SlaveInfosBoxSizer = wx.StaticBoxSizer(self.SlaveInfosStaticBox, wx.VERTICAL) + self.SlaveInfosSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5) + self.SlaveInfosDetailsSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=2, vgap=5) + + self._init_coll_MainSizer_Growables(self.MainSizer) + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_PositionSizer_Growables(self.PositionSizer) + self._init_coll_PositionSizer_Items(self.PositionSizer) + self._init_coll_TypeSizer_Items(self.TypeSizer) + self._init_coll_SlaveInfosBoxSizer_Items(self.SlaveInfosBoxSizer) + self._init_coll_SlaveInfosSizer_Growables(self.SlaveInfosSizer) + self._init_coll_SlaveInfosSizer_Items(self.SlaveInfosSizer) + self._init_coll_SlaveInfosDetailsSizer_Growables(self.SlaveInfosDetailsSizer) + self._init_coll_SlaveInfosDetailsSizer_Items(self.SlaveInfosDetailsSizer) + + self.SetSizer(self.MainSizer) + + def _init_ctrls(self, prnt): + wx.Panel.__init__(self, id=ID_SLAVEPANEL, name='SlavePanel', parent=prnt, + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.TypeLabel = wx.StaticText(id=ID_SLAVEPANELTYPELABEL, + label=_('Type:'), name='TypeLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.Type = wx.TextCtrl(id=ID_SLAVEPANELTYPE, value='', + name='Type', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.TE_READONLY) + + self.TypeBrowse = wx.Button(id=ID_SLAVEPANELTYPEBROWSE, label='...', + name='TypeBrowse', parent=self, pos=wx.Point(0, 0), + size=wx.Size(30, 24), style=0) + self.Bind(wx.EVT_BUTTON, self.OnTypeBrowseClick, id=ID_SLAVEPANELTYPEBROWSE) + + self.AliasLabel = wx.StaticText(id=ID_SLAVEPANELALIASLABEL, + label=_('Alias:'), name='AliasLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.Alias = wx.SpinCtrl(id=ID_SLAVEPANELALIAS, + name='Alias', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) + self.Bind(wx.EVT_SPINCTRL, self.OnAliasChanged, id=ID_SLAVEPANELALIAS) + + self.PosLabel = wx.StaticText(id=ID_SLAVEPANELPOSLABEL, + label=_('Position:'), name='PositionLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.Pos = wx.SpinCtrl(id=ID_SLAVEPANELPOS, + name='Pos', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0, max=0xffff) + self.Bind(wx.EVT_SPINCTRL, self.OnPositionChanged, id=ID_SLAVEPANELPOS) + + self.SlaveInfosStaticBox = wx.StaticBox(id=ID_SLAVEPANELSLAVEINFOSSTATICBOX, + label=_('Slave infos:'), name='SlaveInfosStaticBox', parent=self, + pos=wx.Point(0, 0), size=wx.Size(0, 0), style=0) + + self.VendorLabel = wx.StaticText(id=ID_SLAVEPANELVENDORLABEL, + label=_('Vendor:'), name='VendorLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.Vendor = wx.TextCtrl(id=ID_SLAVEPANELVENDOR, value='', + name='Vendor', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.TE_READONLY) + + self.ProductCodeLabel = wx.StaticText(id=ID_SLAVEPANELPRODUCTCODELABEL, + label=_('Product code:'), name='ProductCodeLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.ProductCode = wx.TextCtrl(id=ID_SLAVEPANELPRODUCTCODE, value='', + name='ProductCode', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.TE_READONLY) + + self.RevisionNumberLabel = wx.StaticText(id=ID_SLAVEPANELREVISIONNUMBERLABEL, + label=_('Revision number:'), name='RevisionNumberLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.RevisionNumber = wx.TextCtrl(id=ID_SLAVEPANELREVISIONNUMBER, value='', + name='RevisionNumber', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.TE_READONLY) + + self.PhysicsLabel = wx.StaticText(id=ID_SLAVEPANELPHYSICSLABEL, + label=_('Physics:'), name='PhysicsLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.Physics = wx.TextCtrl(id=ID_SLAVEPANELPHYSICS, value='', + name='Physics', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 24), style=wx.TE_READONLY) + + self.PDOsLabel = wx.StaticText(id=ID_SLAVEPANELPDOSLABEL, + label=_('PDO entries:'), name='PDOsLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.PDOsGrid = CustomGrid(id=ID_SLAVEPANELPDOSGRID, + name='PDOsGrid', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.VSCROLL) + + self.VariablesLabel = wx.StaticText(id=ID_SLAVEPANELVARIABLESLABEL, + label=_('Variable entries:'), name='VariablesLabel', parent=self, + pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) + + self.VariablesGrid = CustomGrid(id=ID_SLAVEPANELPDOSGRID, + name='PDOsGrid', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.VSCROLL) + if wx.VERSION >= (2, 5, 0): + self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick) + else: + wx.grid.EVT_GRID_CELL_LEFT_CLICK(self.VariablesGrid, self.OnVariablesGridCellLeftClick) + + self._init_sizers() + + def __init__(self, parent, controler, window, slave): + self._init_ctrls(parent) + + self.Controler = controler + self.ParentWindow = window + self.Slave = slave + + self.PDOsTable = PDOsTable(self, [], GetPDOsTableColnames()) + self.PDOsGrid.SetTable(self.PDOsTable) + self.PDOsGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_LEFT] + self.PDOsGridColSizes = [40, 100, 150, 150] + self.PDOsGrid.SetRowLabelSize(0) + for col in range(self.PDOsTable.GetNumberCols()): + attr = wx.grid.GridCellAttr() + attr.SetAlignment(self.PDOsGridColAlignements[col], wx.ALIGN_CENTRE) + self.PDOsGrid.SetColAttr(col, attr) + self.PDOsGrid.SetColMinimalWidth(col, self.PDOsGridColSizes[col]) + self.PDOsGrid.AutoSizeColumn(col, False) + + self.VariablesTable = VariablesTable(self, [], GetVariablesTableColnames()) + self.VariablesGrid.SetTable(self.VariablesTable) + self.VariablesGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT] + self.VariablesGridColSizes = [40, 100, 100, 150, 150, 100] + self.VariablesGrid.SetRowLabelSize(0) + for col in range(self.VariablesTable.GetNumberCols()): + attr = wx.grid.GridCellAttr() + attr.SetAlignment(self.VariablesGridColAlignements[col], wx.ALIGN_CENTRE) + self.VariablesGrid.SetColAttr(col, attr) + self.VariablesGrid.SetColMinimalWidth(col, self.VariablesGridColSizes[col]) + self.VariablesGrid.AutoSizeColumn(col, False) + + self.RefreshView() + + def GetSlaveTitle(self): + type_infos = self.Controler.GetSlaveType(self.Slave) + return "%s (%d:%d)" % (type_infos["device_type"], self.Slave[0], self.Slave[1]) + + def GetSlave(self): + return self.Slave + + def SetSlave(self, slave): + if self.Slave != slave: + self.Slave = slave + self.RefreshView() + + def RefreshView(self): + self.Alias.SetValue(self.Slave[0]) + self.Pos.SetValue(self.Slave[1]) + slave_infos = self.Controler.GetSlaveInfos(self.Slave) + if slave_infos is not None: + self.Type.SetValue(slave_infos["device_type"]) + self.Vendor.SetValue(slave_infos["vendor"]) + self.ProductCode.SetValue(slave_infos["product_code"]) + self.RevisionNumber.SetValue(slave_infos["revision_number"]) + self.Physics.SetValue(slave_infos["physics"]) + self.PDOsTable.SetData(slave_infos["pdos"]) + self.PDOsTable.ResetView(self.PDOsGrid) + self.VariablesTable.SetData(slave_infos["variables"]) + self.VariablesTable.ResetView(self.VariablesGrid) + else: + type_infos = self.Controler.GetSlaveType(self.Slave) + self.Type.SetValue(type_infos["device_type"]) + + def OnAliasChanged(self, event): + alias = self.Alias.GetValue() + if alias != self.Slave[0]: + result = self.Controler.SetSlavePos(self.Slave[:2], alias = alias) + if result is not None: + message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + wx.CallAfter(self.ParentWindow.RefreshView, (alias, self.Slave[1])) + wx.CallAfter(self.ParentWindow.RefreshParentWindow) + event.Skip() + + def OnPositionChanged(self, event): + position = self.Pos.GetValue() + if position != self.Slave[1]: + result = self.Controler.SetSlavePos(self.Slave, position = position) + if result is not None: + message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + wx.CallAfter(self.ParentWindow.RefreshView, (self.Slave[0], position)) + wx.CallAfter(self.ParentWindow.RefreshParentWindow) + event.Skip() + + def OnTypeBrowseClick(self, event): + dialog = SlaveTypeChoiceDialog(self, self.Controler, self.Controler.GetSlaveType(self.Slave)) + if dialog.ShowModal() == wx.ID_OK: + result = self.Controler.SetSlaveType(self.Slave, dialog.GetType()) + if result is not None: + message = wx.MessageDialog(self, result, _("Error"), wx.OK|wx.ICON_ERROR) + message.ShowModal() + message.Destroy() + else: + wx.CallAfter(self.RefreshView) + wx.CallAfter(self.ParentWindow.RefreshSlaveNodesTitles) + wx.CallAfter(self.ParentWindow.RefreshParentWindow) + dialog.Destroy() + event.Skip() + + def OnVariablesGridCellLeftClick(self, event): + if event.GetCol() == 0: + row = event.GetRow() + data_type = self.VariablesTable.GetValueByName(row, "Type") + var_name = self.VariablesTable.GetValueByName(row, "Name") + entry_index = self.Controler.ExtractHexDecValue(self.VariablesTable.GetValueByName(row, "Index")) + entry_subindex = self.VariablesTable.GetValueByName(row, "SubIndex") + pdo_index = self.VariablesTable.GetValueByName(row, "PDO") + for pdo_row in xrange(self.PDOsTable.GetNumberRows()): + if self.PDOsTable.GetValueByName(row, "Index") == pdo_index: + if self.PDOsTable.GetValueByName(row, "Type") == "Transmit": + dir = "%I" + else: + dir = "%Q" + break + location = "%s%s" % (dir, self.Controler.GetSizeOfType(data_type)) + \ + ".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + self.Slave + (entry_index, entry_subindex))) + data = wx.TextDataObject(str((location, "location", data_type, var_name, ""))) + dragSource = wx.DropSource(self.VariablesGrid) + dragSource.SetData(data) + dragSource.DoDragDrop() + event.Skip() + +[ID_CONFIGEDITOR, ID_CONFIGEDITORADDSLAVEBUTTON, + ID_CONFIGEDITORDELETESLAVEBUTTON, ID_CONFIGEDITORSLAVENODES, +] = [wx.NewId() for _init_ctrls in range(4)] + +class ConfigEditor(EditorPanel): + + ID = ID_CONFIGEDITOR + + def _init_coll_MainSizer_Items(self, parent): + parent.AddSizer(self.ButtonSizer, 0, border=5, flag=wx.ALIGN_RIGHT|wx.TOP|wx.LEFT|wx.RIGHT) + parent.AddWindow(self.SlaveNodes, 0, border=5, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT) + + def _init_coll_MainSizer_Growables(self, parent): + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_coll_ButtonSizer_Items(self, parent): + parent.AddWindow(self.AddSlaveButton, 0, border=5, flag=wx.RIGHT) + parent.AddWindow(self.DeleteSlaveButton, 0, border=5, flag=0) + + def _init_sizers(self): + self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) + self.ButtonSizer = wx.BoxSizer(wx.HORIZONTAL) + + self._init_coll_MainSizer_Items(self.MainSizer) + self._init_coll_MainSizer_Growables(self.MainSizer) + self._init_coll_ButtonSizer_Items(self.ButtonSizer) + + self.Editor.SetSizer(self.MainSizer) + + def _init_Editor(self, prnt): + self.Editor = wx.Panel(id=-1, parent=prnt, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL) + + self.AddSlaveButton = wx.Button(id=ID_CONFIGEDITORADDSLAVEBUTTON, label=_('Add slave'), + name='AddSlaveButton', parent=self.Editor, pos=wx.Point(0, 0), + size=wx.DefaultSize, style=0) + self.Bind(wx.EVT_BUTTON, self.OnAddSlaveButtonClick, id=ID_CONFIGEDITORADDSLAVEBUTTON) + + self.DeleteSlaveButton = wx.Button(id=ID_CONFIGEDITORDELETESLAVEBUTTON, label=_('Delete slave'), + name='DeleteSlaveButton', parent=self.Editor, pos=wx.Point(0, 0), + size=wx.DefaultSize, style=0) + self.Bind(wx.EVT_BUTTON, self.OnDeleteSlaveButtonClick, id=ID_CONFIGEDITORDELETESLAVEBUTTON) + + self.SlaveNodes = wx.Notebook(id=ID_CONFIGEDITORSLAVENODES, + name='SlaveNodes', parent=self.Editor, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=wx.NB_LEFT) + + self._init_sizers() + + def __init__(self, parent, controler, window): + EditorPanel.__init__(self, parent, "", window, controler) + + img = wx.Bitmap(self.Controler.GetIconPath("Cfile.png"), wx.BITMAP_TYPE_PNG).ConvertToImage() + self.SetIcon(wx.BitmapFromImage(img.Rescale(16, 16))) + + def GetTitle(self): + filename = self.Controler.GetFilename() + if not self.Controler.ConfigIsSaved(): + return "~%s~" % filename + return filename + + def GetBufferState(self): + return self.Controler.GetBufferState() + + def Undo(self): + self.Controler.LoadPrevious() + self.RefreshView() + + def Redo(self): + self.Controler.LoadNext() + self.RefreshView() + + def RefreshView(self, slave_pos=None): + slaves = self.Controler.GetSlaves() + for i, slave in enumerate(slaves): + if i < self.SlaveNodes.GetPageCount(): + panel = self.SlaveNodes.GetPage(i) + panel.SetSlave(slave) + else: + panel = SlavePanel(self.SlaveNodes, self.Controler, self, slave) + self.SlaveNodes.AddPage(panel, "") + while self.SlaveNodes.GetPageCount() > len(slaves): + self.SlaveNodes.RemovePage(len(slaves)) + self.RefreshSlaveNodesTitles() + self.RefreshButtons() + if slave_pos is not None: + self.SelectSlave(slave_pos) + + def RefreshParentWindow(self): + self.ParentWindow.RefreshTitle() + self.ParentWindow.RefreshFileMenu() + self.ParentWindow.RefreshEditMenu() + self.ParentWindow.RefreshPageTitles() + + def RefreshSlaveNodesTitles(self): + for idx in xrange(self.SlaveNodes.GetPageCount()): + panel = self.SlaveNodes.GetPage(idx) + self.SlaveNodes.SetPageText(idx, panel.GetSlaveTitle()) + + def RefreshButtons(self): + self.DeleteSlaveButton.Enable(self.SlaveNodes.GetPageCount() > 0) + + def SelectSlave(self, slave): + for idx in xrange(self.SlaveNodes.GetPageCount()): + panel = self.SlaveNodes.GetPage(idx) + if panel.GetSlave() == slave: + self.SlaveNodes.SetSelection(idx) + return + + def OnAddSlaveButtonClick(self, event): + slave = self.Controler.AddSlave() + self.RefreshParentWindow() + wx.CallAfter(self.RefreshView, slave) + event.Skip() + + def OnDeleteSlaveButtonClick(self, event): + selected = self.SlaveNodes.GetSelection() + if selected != -1: + panel = self.SlaveNodes.GetPage(selected) + if self.Controler.RemoveSlave(panel.GetSlave()[:2]): + self.RefreshParentWindow() + wx.CallAfter(self.RefreshView) + \ No newline at end of file