etisserant@203: #!/usr/bin/env python etisserant@203: # -*- coding: utf-8 -*- etisserant@203: etisserant@203: #This file is part of Beremiz, a Integrated Development Environment for etisserant@203: #programming IEC 61131-3 automates supporting plcopen standard and CanFestival. etisserant@203: # etisserant@203: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD etisserant@203: # etisserant@203: #See COPYING file for copyrights details. etisserant@203: # etisserant@203: #This library is free software; you can redistribute it and/or etisserant@203: #modify it under the terms of the GNU General Public etisserant@203: #License as published by the Free Software Foundation; either etisserant@203: #version 2.1 of the License, or (at your option) any later version. etisserant@203: # etisserant@203: #This library is distributed in the hope that it will be useful, etisserant@203: #but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@203: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@203: #General Public License for more details. etisserant@203: # etisserant@203: #You should have received a copy of the GNU General Public etisserant@203: #License along with this library; if not, write to the Free Software etisserant@203: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@203: etisserant@203: import wx btaylor@357: from Zeroconf import * etisserant@203: import socket etisserant@203: import wx.lib.mixins.listctrl as listmix etisserant@203: etisserant@203: class TestListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): etisserant@203: def __init__(self, parent, ID, pos=wx.DefaultPosition, etisserant@203: size=wx.DefaultSize, style=0): etisserant@203: wx.ListCtrl.__init__(self, parent, ID, pos, size, style) etisserant@203: listmix.ListCtrlAutoWidthMixin.__init__(self) etisserant@203: etisserant@203: class DiscoveryDialog(wx.Dialog, listmix.ColumnSorterMixin): etisserant@203: def __init__(self, parent, id=-1, title='Service Discovery'): etisserant@203: self.my_result=None etisserant@203: wx.Dialog.__init__(self, parent, id, title, size=(600,600), style=wx.DEFAULT_DIALOG_STYLE) etisserant@203: etisserant@221: sizer = wx.FlexGridSizer(2, 1, 2, 2) # rows, cols, vgap, hgap etisserant@221: sizer.AddGrowableRow(0) etisserant@221: sizer.AddGrowableCol(0) etisserant@221: etisserant@203: self.list = TestListCtrl(self, -1, etisserant@221: #pos=(50,20), etisserant@221: #size=(500,300), etisserant@203: style=wx.LC_REPORT etisserant@203: | wx.LC_EDIT_LABELS etisserant@203: | wx.LC_SORT_ASCENDING etisserant@203: ) etisserant@221: sizer.Add(self.list, 1, wx.EXPAND) etisserant@221: etisserant@221: btsizer = wx.FlexGridSizer(1, 6, 2, 2) # rows, cols, vgap, hgap etisserant@221: etisserant@221: sizer.Add(btsizer, 1, wx.EXPAND) etisserant@221: etisserant@203: self.PopulateList() etisserant@203: etisserant@203: self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) etisserant@203: self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.list) etisserant@203: etisserant@221: local_id = wx.NewId() etisserant@221: b = wx.Button(self, local_id, "Refresh") etisserant@221: self.Bind(wx.EVT_BUTTON, self.OnRefreshButton, b) etisserant@221: btsizer.Add(b) etisserant@203: etisserant@221: btsizer.AddSpacer(0) etisserant@221: btsizer.AddGrowableCol(1) etisserant@203: etisserant@221: local_id = wx.NewId() etisserant@221: b = wx.Button(self, local_id, "Local") etisserant@221: self.Bind(wx.EVT_BUTTON, self.ChooseLocalID, b) etisserant@221: btsizer.Add(b) etisserant@221: etisserant@221: btsizer.AddSpacer(0) etisserant@221: btsizer.AddGrowableCol(3) etisserant@221: etisserant@221: b = wx.Button(self, wx.ID_CANCEL, "Cancel") btaylor@357: self.Bind(wx.EVT_BUTTON, self.OnCancel, b) etisserant@221: btsizer.Add(b) etisserant@221: etisserant@221: b = wx.Button(self, wx.ID_OK, "OK") btaylor@357: self.Bind(wx.EVT_BUTTON, self.OnOk, b) etisserant@221: b.SetDefault() etisserant@221: btsizer.Add(b) etisserant@221: etisserant@221: self.SetSizer(sizer) etisserant@203: etisserant@203: listmix.ColumnSorterMixin.__init__(self, 4) etisserant@221: etisserant@221: #type = "_http._tcp.local." greg@262: self.browser = None etisserant@221: self.zConfInstance = Zeroconf() etisserant@221: self.RefreshList() etisserant@221: btaylor@357: self.Bind(wx.EVT_CLOSE, self.OnClose) btaylor@357: etisserant@221: def RefreshList(self): etisserant@221: type = "_PYRO._tcp.local." greg@262: self.browser = ServiceBrowser(self.zConfInstance, type, self) etisserant@221: etisserant@221: def OnRefreshButton(self, event): etisserant@221: self.list.DeleteAllItems() greg@262: self.browser.cancel() etisserant@221: self.RefreshList() etisserant@221: btaylor@357: def OnClose(self, event): btaylor@357: self.zConfInstance.close() btaylor@357: event.Skip() btaylor@357: btaylor@357: def OnCancel(self, event): btaylor@357: self.zConfInstance.close() btaylor@357: event.Skip() btaylor@357: btaylor@357: def OnOk(self, event): btaylor@357: self.zConfInstance.close() btaylor@357: event.Skip() btaylor@357: etisserant@203: # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py etisserant@203: def GetListCtrl(self): etisserant@203: return self.list etisserant@203: etisserant@203: def PopulateList(self): etisserant@221: self.list.InsertColumn(0, 'NAME') etisserant@203: self.list.InsertColumn(1, 'TYPE') etisserant@203: self.list.InsertColumn(2, 'IP') etisserant@203: self.list.InsertColumn(3, 'PORT') etisserant@203: self.list.SetColumnWidth(0, 150) etisserant@203: self.list.SetColumnWidth(1, 150) etisserant@203: self.list.SetColumnWidth(2, 150) etisserant@203: self.list.SetColumnWidth(3, 150) etisserant@203: etisserant@203: def getColumnText(self, index, col): etisserant@203: item = self.list.GetItem(index, col) etisserant@203: return item.GetText() etisserant@203: etisserant@203: def OnItemSelected(self, event): etisserant@203: self.currentItem = event.m_itemIndex etisserant@221: self.setresult() etisserant@203: event.Skip() etisserant@203: etisserant@203: def OnItemActivated(self, event): etisserant@203: self.currentItem = event.m_itemIndex etisserant@221: self.setresult() etisserant@221: self.Close() etisserant@203: event.Skip() etisserant@203: etisserant@221: def setresult(self): etisserant@203: connect_type = self.getColumnText(self.currentItem, 1) etisserant@203: connect_address = self.getColumnText(self.currentItem, 2) etisserant@203: connect_port = self.getColumnText(self.currentItem, 3) etisserant@203: etisserant@203: uri = self.CreateURI(connect_type, connect_address, connect_port) etisserant@203: self.my_result=uri etisserant@203: etisserant@203: def GetResult(self): etisserant@203: return self.my_result etisserant@203: btaylor@357: def removeService(self, zeroconf, type, name): etisserant@221: pass btaylor@357: greg@262: def addService(self, zeroconf, type, name): btaylor@357: info = self.zConfInstance.getServiceInfo(type, name) etisserant@203: typename = type.split(".")[0][1:] etisserant@203: num_items = self.list.GetItemCount() etisserant@203: self.list.InsertStringItem(num_items, name.split(".")[0]) etisserant@203: self.list.SetStringItem(num_items, 1, "%s"%typename) etisserant@203: self.list.SetStringItem(num_items, 2, "%s"%str(socket.inet_ntoa(info.getAddress()))) etisserant@203: self.list.SetStringItem(num_items, 3, "%s"%info.getPort()) etisserant@203: etisserant@203: def CreateURI(self, connect_type, connect_address, connect_port): etisserant@203: uri = "%s://%s:%s"%(connect_type, connect_address, connect_port) etisserant@203: return uri etisserant@203: etisserant@221: def ChooseLocalID(self, event): etisserant@277: self.my_result = "LOCAL://" etisserant@203: self.Close()