25 import wx |
25 import wx |
26 import wx.lib.mixins.listctrl as listmix |
26 import wx.lib.mixins.listctrl as listmix |
27 from util.Zeroconf import * |
27 from util.Zeroconf import * |
28 |
28 |
29 import connectors |
29 import connectors |
|
30 |
|
31 service_type = '_PYRO._tcp.local.' |
30 |
32 |
31 class AutoWidthListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): |
33 class AutoWidthListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): |
32 def __init__(self, parent, id, name, pos=wx.DefaultPosition, |
34 def __init__(self, parent, id, name, pos=wx.DefaultPosition, |
33 size=wx.DefaultSize, style=0): |
35 size=wx.DefaultSize, style=0): |
34 wx.ListCtrl.__init__(self, parent, id, pos, size, style, name=name) |
36 wx.ListCtrl.__init__(self, parent, id, pos, size, style, name=name) |
35 listmix.ListCtrlAutoWidthMixin.__init__(self) |
37 listmix.ListCtrlAutoWidthMixin.__init__(self) |
36 |
38 |
37 [ID_DISCOVERYDIALOG, ID_DISCOVERYDIALOGSTATICTEXT1, |
39 [ID_DISCOVERYDIALOG, ID_DISCOVERYDIALOGSTATICTEXT1, |
38 ID_DISCOVERYDIALOGSERVICESLIST, ID_DISCOVERYDIALOGREFRESHBUTTON, |
40 ID_DISCOVERYDIALOGSERVICESLIST, ID_DISCOVERYDIALOGREFRESHBUTTON, |
39 ID_DISCOVERYDIALOGLOCALBUTTON, |
41 ID_DISCOVERYDIALOGLOCALBUTTON, ID_DISCOVERYDIALOGIPBUTTON, |
40 ] = [wx.NewId() for _init_ctrls in range(5)] |
42 ] = [wx.NewId() for _init_ctrls in range(6)] |
41 |
43 |
42 class DiscoveryDialog(wx.Dialog, listmix.ColumnSorterMixin): |
44 class DiscoveryDialog(wx.Dialog, listmix.ColumnSorterMixin): |
43 |
45 |
44 def _init_coll_MainSizer_Items(self, parent): |
46 def _init_coll_MainSizer_Items(self, parent): |
45 parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW) |
47 parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW) |
51 parent.AddGrowableRow(1) |
53 parent.AddGrowableRow(1) |
52 |
54 |
53 def _init_coll_ButtonGridSizer_Items(self, parent): |
55 def _init_coll_ButtonGridSizer_Items(self, parent): |
54 parent.AddWindow(self.RefreshButton, 0, border=0, flag=0) |
56 parent.AddWindow(self.RefreshButton, 0, border=0, flag=0) |
55 parent.AddWindow(self.LocalButton, 0, border=0, flag=0) |
57 parent.AddWindow(self.LocalButton, 0, border=0, flag=0) |
|
58 parent.AddWindow(self.IpButton, 0, border=0, flag=0) |
56 parent.AddSizer(self.ButtonSizer, 0, border=0, flag=0) |
59 parent.AddSizer(self.ButtonSizer, 0, border=0, flag=0) |
57 |
60 |
58 def _init_coll_ButtonGridSizer_Growables(self, parent): |
61 def _init_coll_ButtonGridSizer_Growables(self, parent): |
59 parent.AddGrowableCol(0) |
62 parent.AddGrowableCol(0) |
60 parent.AddGrowableCol(1) |
63 parent.AddGrowableCol(1) |
61 parent.AddGrowableRow(1) |
64 parent.AddGrowableRow(1) |
62 |
65 |
63 def _init_sizers(self): |
66 def _init_sizers(self): |
64 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) |
67 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) |
65 self.ButtonGridSizer = wx.FlexGridSizer(cols=3, hgap=5, rows=1, vgap=0) |
68 self.ButtonGridSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=1, vgap=0) |
66 |
69 |
67 self._init_coll_MainSizer_Items(self.MainSizer) |
70 self._init_coll_MainSizer_Items(self.MainSizer) |
68 self._init_coll_MainSizer_Growables(self.MainSizer) |
71 self._init_coll_MainSizer_Growables(self.MainSizer) |
69 self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer) |
72 self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer) |
70 self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer) |
73 self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer) |
105 |
108 |
106 self.LocalButton = wx.Button(id=ID_DISCOVERYDIALOGLOCALBUTTON, |
109 self.LocalButton = wx.Button(id=ID_DISCOVERYDIALOGLOCALBUTTON, |
107 label=_('Local'), name='LocalButton', parent=self, |
110 label=_('Local'), name='LocalButton', parent=self, |
108 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
111 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
109 self.Bind(wx.EVT_BUTTON, self.OnLocalButton, id=ID_DISCOVERYDIALOGLOCALBUTTON) |
112 self.Bind(wx.EVT_BUTTON, self.OnLocalButton, id=ID_DISCOVERYDIALOGLOCALBUTTON) |
|
113 |
|
114 self.IpButton = wx.Button(id=ID_DISCOVERYDIALOGIPBUTTON, |
|
115 label=_('Add IP'), name='IpButton', parent=self, |
|
116 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
117 self.Bind(wx.EVT_BUTTON, self.OnIpButton, id=ID_DISCOVERYDIALOGIPBUTTON) |
110 |
118 |
111 self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTER) |
119 self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTER) |
112 |
120 |
113 self._init_sizers() |
121 self._init_sizers() |
114 |
122 |
117 |
125 |
118 self.itemDataMap = {} |
126 self.itemDataMap = {} |
119 self.nextItemId = 0 |
127 self.nextItemId = 0 |
120 |
128 |
121 self.URI = None |
129 self.URI = None |
122 self.Browsers = [] |
130 self.Browser = None |
123 |
131 |
124 self.ZeroConfInstance = Zeroconf() |
132 self.ZeroConfInstance = Zeroconf() |
125 self.RefreshList() |
133 self.RefreshList() |
|
134 self.LatestSelection=None |
126 |
135 |
127 def __del__(self): |
136 def __del__(self): |
128 for browser in self.Browsers: |
137 if self.Browser is not None : self.Browser.cancel() |
129 browser.cancel() |
|
130 self.ZeroConfInstance.close() |
138 self.ZeroConfInstance.close() |
131 |
139 |
132 def RefreshList(self): |
140 def RefreshList(self): |
133 for browser in self.Browsers: |
141 if self.Browser is not None : self.Browser.cancel() |
134 browser.cancel() |
142 self.Browser = ServiceBrowser(self.ZeroConfInstance, service_type, self) |
135 |
|
136 self.Browsers = [] |
|
137 for t in connectors.dnssd_connectors.keys(): |
|
138 self.Browsers.append(ServiceBrowser(self.ZeroConfInstance, t, self)) |
|
139 |
143 |
140 def OnRefreshButton(self, event): |
144 def OnRefreshButton(self, event): |
141 self.ServicesList.DeleteAllItems() |
145 self.ServicesList.DeleteAllItems() |
142 self.RefreshList() |
146 self.RefreshList() |
143 |
147 |
144 def OnLocalButton(self, event): |
148 def OnLocalButton(self, event): |
145 self.URI = "LOCAL://" |
149 self.URI = "LOCAL://" |
146 self.EndModal(wx.ID_OK) |
150 self.EndModal(wx.ID_OK) |
147 event.Skip() |
151 event.Skip() |
148 |
152 |
|
153 def OnIpButton(self, event): |
|
154 if self.LatestSelection is not None: |
|
155 l = lambda col : self.getColumnText(self.LatestSelection,col) |
|
156 self.URI = "%s://%s:%s"%tuple(map(l,(1,2,3))) |
|
157 self.EndModal(wx.ID_OK) |
|
158 event.Skip() |
|
159 |
149 # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py |
160 # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py |
150 def GetListCtrl(self): |
161 def GetListCtrl(self): |
151 return self.ServicesList |
162 return self.ServicesList |
152 |
163 |
153 def getColumnText(self, index, col): |
164 def getColumnText(self, index, col): |
161 def OnItemActivated(self, event): |
172 def OnItemActivated(self, event): |
162 self.SetURI(event.m_itemIndex) |
173 self.SetURI(event.m_itemIndex) |
163 self.EndModal(wx.ID_OK) |
174 self.EndModal(wx.ID_OK) |
164 event.Skip() |
175 event.Skip() |
165 |
176 |
|
177 # def SetURI(self, idx): |
|
178 # connect_type = self.getColumnText(idx, 1) |
|
179 # connect_address = self.getColumnText(idx, 2) |
|
180 # connect_port = self.getColumnText(idx, 3) |
|
181 # |
|
182 # self.URI = "%s://%s:%s"%(connect_type, connect_address, connect_port) |
|
183 |
166 def SetURI(self, idx): |
184 def SetURI(self, idx): |
|
185 self.LatestSelection = idx |
|
186 svcname = self.getColumnText(idx, 0) |
167 connect_type = self.getColumnText(idx, 1) |
187 connect_type = self.getColumnText(idx, 1) |
168 connect_address = self.getColumnText(idx, 2) |
188 self.URI = "%s://%s"%(connect_type, svcname + '.' + service_type) |
169 connect_port = self.getColumnText(idx, 3) |
189 |
170 |
|
171 self.URI = "%s://%s:%s"%(connect_type, connect_address, connect_port) |
|
172 |
|
173 def GetURI(self): |
190 def GetURI(self): |
174 return self.URI |
191 return self.URI |
175 |
192 |
176 def removeService(self, zeroconf, type, name): |
193 def removeService(self, zeroconf, _type, name): |
177 wx.CallAfter(self._removeService, name) |
194 wx.CallAfter(self._removeService, name) |
178 |
195 |
179 |
196 |
180 def _removeService(self, name): |
197 def _removeService(self, name): |
181 ''' |
198 ''' |
192 |
209 |
193 if item_name == name: |
210 if item_name == name: |
194 self.ServicesList.DeleteItem(idx) |
211 self.ServicesList.DeleteItem(idx) |
195 break |
212 break |
196 |
213 |
197 def addService(self, zeroconf, type, name): |
214 def addService(self, zeroconf, _type, name): |
198 wx.CallAfter(self._addService, type, name) |
215 wx.CallAfter(self._addService, _type, name) |
199 |
216 |
200 def _addService(self, type, name): |
217 def _addService(self, _type, name): |
201 ''' |
218 ''' |
202 called when a service with the desired type is discovered. |
219 called when a service with the desired type is discovered. |
203 ''' |
220 ''' |
204 info = self.ZeroConfInstance.getServiceInfo(type, name) |
221 info = self.ZeroConfInstance.getServiceInfo(_type, name) |
205 |
222 |
206 svcname = name.split(".")[0] |
223 svcname = name.split(".")[0] |
207 typename = type.split(".")[0][1:] |
224 typename = _type.split(".")[0][1:] |
208 ip = str(socket.inet_ntoa(info.getAddress())) |
225 ip = str(socket.inet_ntoa(info.getAddress())) |
209 port = info.getPort() |
226 port = info.getPort() |
210 |
227 |
211 num_items = self.ServicesList.GetItemCount() |
228 num_items = self.ServicesList.GetItemCount() |
212 |
229 |