23 # along with this program; if not, write to the Free Software |
23 # along with this program; if not, write to the Free Software |
24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
25 |
25 |
26 import socket |
26 import socket |
27 import wx |
27 import wx |
28 import wx.lib.mixins.listctrl as listmix |
28 import wx.lib.mixins.listctrl as listmix |
29 from util.Zeroconf import * |
29 from util.Zeroconf import * |
30 |
30 |
31 import connectors |
31 import connectors |
32 |
32 |
33 service_type = '_PYRO._tcp.local.' |
33 service_type = '_PYRO._tcp.local.' |
|
34 |
34 |
35 |
35 class AutoWidthListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): |
36 class AutoWidthListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): |
36 def __init__(self, parent, id, name, pos=wx.DefaultPosition, |
37 def __init__(self, parent, id, name, pos=wx.DefaultPosition, |
37 size=wx.DefaultSize, style=0): |
38 size=wx.DefaultSize, style=0): |
38 wx.ListCtrl.__init__(self, parent, id, pos, size, style, name=name) |
39 wx.ListCtrl.__init__(self, parent, id, pos, size, style, name=name) |
39 listmix.ListCtrlAutoWidthMixin.__init__(self) |
40 listmix.ListCtrlAutoWidthMixin.__init__(self) |
40 |
41 |
41 [ID_DISCOVERYDIALOG, ID_DISCOVERYDIALOGSTATICTEXT1, |
42 |
42 ID_DISCOVERYDIALOGSERVICESLIST, ID_DISCOVERYDIALOGREFRESHBUTTON, |
43 [ |
43 ID_DISCOVERYDIALOGLOCALBUTTON, ID_DISCOVERYDIALOGIPBUTTON, |
44 ID_DISCOVERYDIALOG, ID_DISCOVERYDIALOGSTATICTEXT1, |
|
45 ID_DISCOVERYDIALOGSERVICESLIST, ID_DISCOVERYDIALOGREFRESHBUTTON, |
|
46 ID_DISCOVERYDIALOGLOCALBUTTON, ID_DISCOVERYDIALOGIPBUTTON, |
44 ] = [wx.NewId() for _init_ctrls in range(6)] |
47 ] = [wx.NewId() for _init_ctrls in range(6)] |
45 |
48 |
|
49 |
46 class DiscoveryDialog(wx.Dialog, listmix.ColumnSorterMixin): |
50 class DiscoveryDialog(wx.Dialog, listmix.ColumnSorterMixin): |
47 |
51 |
48 def _init_coll_MainSizer_Items(self, parent): |
52 def _init_coll_MainSizer_Items(self, parent): |
49 parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP|wx.LEFT|wx.RIGHT|wx.GROW) |
53 parent.AddWindow(self.staticText1, 0, border=20, flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.GROW) |
50 parent.AddWindow(self.ServicesList, 0, border=20, flag=wx.LEFT|wx.RIGHT|wx.GROW) |
54 parent.AddWindow(self.ServicesList, 0, border=20, flag=wx.LEFT | wx.RIGHT | wx.GROW) |
51 parent.AddSizer(self.ButtonGridSizer, 0, border=20, flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW) |
55 parent.AddSizer(self.ButtonGridSizer, 0, border=20, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.GROW) |
52 |
56 |
53 def _init_coll_MainSizer_Growables(self, parent): |
57 def _init_coll_MainSizer_Growables(self, parent): |
54 parent.AddGrowableCol(0) |
58 parent.AddGrowableCol(0) |
55 parent.AddGrowableRow(1) |
59 parent.AddGrowableRow(1) |
56 |
60 |
57 def _init_coll_ButtonGridSizer_Items(self, parent): |
61 def _init_coll_ButtonGridSizer_Items(self, parent): |
58 parent.AddWindow(self.RefreshButton, 0, border=0, flag=0) |
62 parent.AddWindow(self.RefreshButton, 0, border=0, flag=0) |
59 parent.AddWindow(self.LocalButton, 0, border=0, flag=0) |
63 parent.AddWindow(self.LocalButton, 0, border=0, flag=0) |
60 parent.AddWindow(self.IpButton, 0, border=0, flag=0) |
64 parent.AddWindow(self.IpButton, 0, border=0, flag=0) |
61 parent.AddSizer(self.ButtonSizer, 0, border=0, flag=0) |
65 parent.AddSizer(self.ButtonSizer, 0, border=0, flag=0) |
62 |
66 |
63 def _init_coll_ButtonGridSizer_Growables(self, parent): |
67 def _init_coll_ButtonGridSizer_Growables(self, parent): |
64 parent.AddGrowableCol(0) |
68 parent.AddGrowableCol(0) |
65 parent.AddGrowableCol(1) |
69 parent.AddGrowableCol(1) |
66 parent.AddGrowableRow(0) |
70 parent.AddGrowableRow(0) |
67 |
71 |
68 def _init_sizers(self): |
72 def _init_sizers(self): |
69 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) |
73 self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=10) |
70 self.ButtonGridSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=1, vgap=0) |
74 self.ButtonGridSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=1, vgap=0) |
71 |
75 |
72 self._init_coll_MainSizer_Items(self.MainSizer) |
76 self._init_coll_MainSizer_Items(self.MainSizer) |
73 self._init_coll_MainSizer_Growables(self.MainSizer) |
77 self._init_coll_MainSizer_Growables(self.MainSizer) |
74 self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer) |
78 self._init_coll_ButtonGridSizer_Items(self.ButtonGridSizer) |
75 self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer) |
79 self._init_coll_ButtonGridSizer_Growables(self.ButtonGridSizer) |
76 |
80 |
77 self.SetSizer(self.MainSizer) |
81 self.SetSizer(self.MainSizer) |
78 |
82 |
79 def _init_ctrls(self, prnt): |
83 def _init_ctrls(self, prnt): |
80 wx.Dialog.__init__(self, id=ID_DISCOVERYDIALOG, |
84 wx.Dialog.__init__( |
81 name='DiscoveryDialog', parent=prnt, style=wx.DEFAULT_DIALOG_STYLE, |
85 self, id=ID_DISCOVERYDIALOG, |
82 title=_('Service Discovery')) |
86 name='DiscoveryDialog', parent=prnt, style=wx.DEFAULT_DIALOG_STYLE, |
83 |
87 title=_('Service Discovery')) |
84 self.staticText1 = wx.StaticText(id=ID_DISCOVERYDIALOGSTATICTEXT1, |
88 |
85 label=_('Services available:'), name='staticText1', parent=self, |
89 self.staticText1 = wx.StaticText( |
86 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
90 id=ID_DISCOVERYDIALOGSTATICTEXT1, |
87 |
91 label=_('Services available:'), name='staticText1', parent=self, |
|
92 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
|
93 |
88 # Set up list control |
94 # Set up list control |
89 self.ServicesList = AutoWidthListCtrl(id=ID_DISCOVERYDIALOGSERVICESLIST, |
95 self.ServicesList = AutoWidthListCtrl( |
90 name='ServicesList', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), |
96 id=ID_DISCOVERYDIALOGSERVICESLIST, |
91 style=wx.LC_REPORT|wx.LC_EDIT_LABELS|wx.LC_SORT_ASCENDING|wx.LC_SINGLE_SEL) |
97 name='ServicesList', parent=self, pos=wx.Point(0, 0), size=wx.Size(0, 0), |
|
98 style=wx.LC_REPORT | wx.LC_EDIT_LABELS | wx.LC_SORT_ASCENDING | wx.LC_SINGLE_SEL) |
92 self.ServicesList.InsertColumn(0, _('NAME')) |
99 self.ServicesList.InsertColumn(0, _('NAME')) |
93 self.ServicesList.InsertColumn(1, _('TYPE')) |
100 self.ServicesList.InsertColumn(1, _('TYPE')) |
94 self.ServicesList.InsertColumn(2, _('IP')) |
101 self.ServicesList.InsertColumn(2, _('IP')) |
95 self.ServicesList.InsertColumn(3, _('PORT')) |
102 self.ServicesList.InsertColumn(3, _('PORT')) |
96 self.ServicesList.SetColumnWidth(0, 150) |
103 self.ServicesList.SetColumnWidth(0, 150) |
98 self.ServicesList.SetColumnWidth(2, 150) |
105 self.ServicesList.SetColumnWidth(2, 150) |
99 self.ServicesList.SetColumnWidth(3, 150) |
106 self.ServicesList.SetColumnWidth(3, 150) |
100 self.ServicesList.SetInitialSize(wx.Size(-1, 300)) |
107 self.ServicesList.SetInitialSize(wx.Size(-1, 300)) |
101 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, id=ID_DISCOVERYDIALOGSERVICESLIST) |
108 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, id=ID_DISCOVERYDIALOGSERVICESLIST) |
102 self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, id=ID_DISCOVERYDIALOGSERVICESLIST) |
109 self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, id=ID_DISCOVERYDIALOGSERVICESLIST) |
103 |
110 |
104 listmix.ColumnSorterMixin.__init__(self, 4) |
111 listmix.ColumnSorterMixin.__init__(self, 4) |
105 |
112 |
106 self.RefreshButton = wx.Button(id=ID_DISCOVERYDIALOGREFRESHBUTTON, |
113 self.RefreshButton = wx.Button( |
107 label=_('Refresh'), name='RefreshButton', parent=self, |
114 id=ID_DISCOVERYDIALOGREFRESHBUTTON, |
108 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
115 label=_('Refresh'), name='RefreshButton', parent=self, |
|
116 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
109 self.Bind(wx.EVT_BUTTON, self.OnRefreshButton, id=ID_DISCOVERYDIALOGREFRESHBUTTON) |
117 self.Bind(wx.EVT_BUTTON, self.OnRefreshButton, id=ID_DISCOVERYDIALOGREFRESHBUTTON) |
110 |
118 |
111 self.LocalButton = wx.Button(id=ID_DISCOVERYDIALOGLOCALBUTTON, |
119 self.LocalButton = wx.Button( |
112 label=_('Local'), name='LocalButton', parent=self, |
120 id=ID_DISCOVERYDIALOGLOCALBUTTON, |
113 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
121 label=_('Local'), name='LocalButton', parent=self, |
|
122 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
114 self.Bind(wx.EVT_BUTTON, self.OnLocalButton, id=ID_DISCOVERYDIALOGLOCALBUTTON) |
123 self.Bind(wx.EVT_BUTTON, self.OnLocalButton, id=ID_DISCOVERYDIALOGLOCALBUTTON) |
115 |
124 |
116 self.IpButton = wx.Button(id=ID_DISCOVERYDIALOGIPBUTTON, |
125 self.IpButton = wx.Button( |
117 label=_('Add IP'), name='IpButton', parent=self, |
126 id=ID_DISCOVERYDIALOGIPBUTTON, |
118 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
127 label=_('Add IP'), name='IpButton', parent=self, |
|
128 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
119 self.Bind(wx.EVT_BUTTON, self.OnIpButton, id=ID_DISCOVERYDIALOGIPBUTTON) |
129 self.Bind(wx.EVT_BUTTON, self.OnIpButton, id=ID_DISCOVERYDIALOGIPBUTTON) |
120 |
130 |
121 self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTER) |
131 self.ButtonSizer = self.CreateButtonSizer(wx.OK | wx.CANCEL | wx.CENTER) |
122 |
132 |
123 self._init_sizers() |
133 self._init_sizers() |
124 self.Fit() |
134 self.Fit() |
125 |
135 |
126 def __init__(self, parent): |
136 def __init__(self, parent): |
127 self._init_ctrls(parent) |
137 self._init_ctrls(parent) |
128 |
138 |
129 self.itemDataMap = {} |
139 self.itemDataMap = {} |
130 self.nextItemId = 0 |
140 self.nextItemId = 0 |
131 |
141 |
132 self.URI = None |
142 self.URI = None |
133 self.Browser = None |
143 self.Browser = None |
134 |
144 |
135 self.ZeroConfInstance = Zeroconf() |
145 self.ZeroConfInstance = Zeroconf() |
136 self.RefreshList() |
146 self.RefreshList() |
137 self.LatestSelection=None |
147 self.LatestSelection = None |
138 |
148 |
139 def __del__(self): |
149 def __del__(self): |
140 if self.Browser is not None : self.Browser.cancel() |
150 if self.Browser is not None: |
|
151 self.Browser.cancel() |
141 self.ZeroConfInstance.close() |
152 self.ZeroConfInstance.close() |
142 |
153 |
143 def RefreshList(self): |
154 def RefreshList(self): |
144 if self.Browser is not None : self.Browser.cancel() |
155 if self.Browser is not None: |
|
156 self.Browser.cancel() |
145 self.Browser = ServiceBrowser(self.ZeroConfInstance, service_type, self) |
157 self.Browser = ServiceBrowser(self.ZeroConfInstance, service_type, self) |
146 |
158 |
147 def OnRefreshButton(self, event): |
159 def OnRefreshButton(self, event): |
148 self.ServicesList.DeleteAllItems() |
160 self.ServicesList.DeleteAllItems() |
149 self.RefreshList() |
161 self.RefreshList() |
179 |
193 |
180 # def SetURI(self, idx): |
194 # def SetURI(self, idx): |
181 # connect_type = self.getColumnText(idx, 1) |
195 # connect_type = self.getColumnText(idx, 1) |
182 # connect_address = self.getColumnText(idx, 2) |
196 # connect_address = self.getColumnText(idx, 2) |
183 # connect_port = self.getColumnText(idx, 3) |
197 # connect_port = self.getColumnText(idx, 3) |
184 # |
198 # |
185 # self.URI = "%s://%s:%s"%(connect_type, connect_address, connect_port) |
199 # self.URI = "%s://%s:%s"%(connect_type, connect_address, connect_port) |
186 |
200 |
187 def SetURI(self, idx): |
201 def SetURI(self, idx): |
188 self.LatestSelection = idx |
202 self.LatestSelection = idx |
189 svcname = self.getColumnText(idx, 0) |
203 svcname = self.getColumnText(idx, 0) |
190 connect_type = self.getColumnText(idx, 1) |
204 connect_type = self.getColumnText(idx, 1) |
191 self.URI = "%s://%s"%(connect_type, svcname + '.' + service_type) |
205 self.URI = "%s://%s" % (connect_type, svcname + '.' + service_type) |
192 |
206 |
193 def GetURI(self): |
207 def GetURI(self): |
194 return self.URI |
208 return self.URI |
195 |
209 |
196 def removeService(self, zeroconf, _type, name): |
210 def removeService(self, zeroconf, _type, name): |
197 wx.CallAfter(self._removeService, name) |
211 wx.CallAfter(self._removeService, name) |
198 |
212 |
199 |
|
200 def _removeService(self, name): |
213 def _removeService(self, name): |
201 ''' |
214 ''' |
202 called when a service with the desired type goes offline. |
215 called when a service with the desired type goes offline. |
203 ''' |
216 ''' |
204 |
217 |
205 # loop through the list items looking for the service that went offline |
218 # loop through the list items looking for the service that went offline |
206 for idx in xrange(self.ServicesList.GetItemCount()): |
219 for idx in xrange(self.ServicesList.GetItemCount()): |
207 # this is the unique identifier assigned to the item |
220 # this is the unique identifier assigned to the item |
208 item_id = self.ServicesList.GetItemData(idx) |
221 item_id = self.ServicesList.GetItemData(idx) |
209 |
222 |