213 message = wx.MessageDialog(self, message%texts, "Error", wx.OK|wx.ICON_ERROR) |
213 message = wx.MessageDialog(self, message%texts, "Error", wx.OK|wx.ICON_ERROR) |
214 message.ShowModal() |
214 message.ShowModal() |
215 message.Destroy() |
215 message.Destroy() |
216 return |
216 return |
217 self.EndModal(wx.ID_OK) |
217 self.EndModal(wx.ID_OK) |
|
218 event.Skip() |
218 |
219 |
219 def GetValue(self): |
220 def GetValue(self): |
220 return self.GetSizer().GetItem(1).GetWindow().GetValue() |
221 return self.GetSizer().GetItem(1).GetWindow().GetValue() |
221 |
222 |
222 def SetTests(self, tests): |
223 def SetTests(self, tests): |
223 self.Tests = tests |
224 self.Tests = tests |
224 |
225 |
225 class DemoTaskBarIcon(wx.TaskBarIcon): |
226 class BeremizTaskBarIcon(wx.TaskBarIcon): |
226 TBMENU_CHANGE_NAME = wx.NewId() |
227 TBMENU_CHANGE_NAME = wx.NewId() |
227 TBMENU_CHANGE_PORT = wx.NewId() |
228 TBMENU_CHANGE_PORT = wx.NewId() |
228 TBMENU_CHANGE_INTERFACE = wx.NewId() |
229 TBMENU_CHANGE_INTERFACE = wx.NewId() |
|
230 TBMENU_LIVE_SHELL = wx.NewId() |
229 TBMENU_CHANGE_WD = wx.NewId() |
231 TBMENU_CHANGE_WD = wx.NewId() |
230 TBMENU_QUIT = wx.NewId() |
232 TBMENU_QUIT = wx.NewId() |
231 |
233 |
232 def __init__(self, pyroserver): |
234 def __init__(self, pyroserver): |
233 wx.TaskBarIcon.__init__(self) |
235 wx.TaskBarIcon.__init__(self) |
|
236 self.pyroserver = pyroserver |
234 # Set the image |
237 # Set the image |
235 self.UpdateIcon(None) |
238 self.UpdateIcon(None) |
236 |
239 |
237 # bind some events |
240 # bind some events |
238 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeName, id=self.TBMENU_CHANGE_NAME) |
241 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeName, id=self.TBMENU_CHANGE_NAME) |
239 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeInterface, id=self.TBMENU_CHANGE_INTERFACE) |
242 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeInterface, id=self.TBMENU_CHANGE_INTERFACE) |
|
243 self.Bind(wx.EVT_MENU, self.OnTaskBarLiveShell, id=self.TBMENU_LIVE_SHELL) |
240 self.Bind(wx.EVT_MENU, self.OnTaskBarChangePort, id=self.TBMENU_CHANGE_PORT) |
244 self.Bind(wx.EVT_MENU, self.OnTaskBarChangePort, id=self.TBMENU_CHANGE_PORT) |
241 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeWorkingDir, id=self.TBMENU_CHANGE_WD) |
245 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeWorkingDir, id=self.TBMENU_CHANGE_WD) |
242 self.Bind(wx.EVT_MENU, self.OnTaskBarQuit, id=self.TBMENU_QUIT) |
246 self.Bind(wx.EVT_MENU, self.OnTaskBarQuit, id=self.TBMENU_QUIT) |
243 |
247 |
244 def CreatePopupMenu(self): |
248 def CreatePopupMenu(self): |
249 the base class takes care of the rest. |
253 the base class takes care of the rest. |
250 """ |
254 """ |
251 menu = wx.Menu() |
255 menu = wx.Menu() |
252 menu.Append(self.TBMENU_CHANGE_NAME, "Change Name") |
256 menu.Append(self.TBMENU_CHANGE_NAME, "Change Name") |
253 menu.Append(self.TBMENU_CHANGE_INTERFACE, "Change IP of interface to bind") |
257 menu.Append(self.TBMENU_CHANGE_INTERFACE, "Change IP of interface to bind") |
|
258 menu.Append(self.TBMENU_LIVE_SHELL, "Launch a live Python shell") |
254 menu.Append(self.TBMENU_CHANGE_PORT, "Change Port Number") |
259 menu.Append(self.TBMENU_CHANGE_PORT, "Change Port Number") |
255 menu.AppendSeparator() |
260 menu.AppendSeparator() |
256 menu.Append(self.TBMENU_CHANGE_WD, "Change working directory") |
261 menu.Append(self.TBMENU_CHANGE_WD, "Change working directory") |
257 menu.Append(self.TBMENU_QUIT, "Quit") |
262 menu.Append(self.TBMENU_QUIT, "Quit") |
258 return menu |
263 return menu |
274 dlg = ParamsEntryDialog(None, "Enter the ip of the interface to bind", defaultValue=pyroserver.ip) |
279 dlg = ParamsEntryDialog(None, "Enter the ip of the interface to bind", defaultValue=pyroserver.ip) |
275 dlg.SetTests([(re.compile('\d{1,3}(?:\.\d{1,3}){3}$').match, "Ip is not valid!"), |
280 dlg.SetTests([(re.compile('\d{1,3}(?:\.\d{1,3}){3}$').match, "Ip is not valid!"), |
276 ( lambda ip :len([x for x in ip.split(".") if 0 <= int(x) <= 255]) == 4, "Ip is not valid!") |
281 ( lambda ip :len([x for x in ip.split(".") if 0 <= int(x) <= 255]) == 4, "Ip is not valid!") |
277 ]) |
282 ]) |
278 if dlg.ShowModal() == wx.ID_OK: |
283 if dlg.ShowModal() == wx.ID_OK: |
279 pyroserver.ip = dlg.GetValue() |
284 self.pyroserver.ip = dlg.GetValue() |
280 pyroserver.Stop() |
285 self.pyroserver.Stop() |
|
286 evt.Skip() |
281 |
287 |
282 def OnTaskBarChangePort(self,evt): |
288 def OnTaskBarChangePort(self,evt): |
283 dlg = ParamsEntryDialog(None, "Enter a port number ", defaultValue=str(pyroserver.port)) |
289 dlg = ParamsEntryDialog(None, "Enter a port number ", defaultValue=str(pyroserver.port)) |
284 dlg.SetTests([(UnicodeType.isdigit, "Port number must be an integer!"), (lambda port : 0 <= int(port) <= 65535 , "Port number must be 0 <= port <= 65535!")]) |
290 dlg.SetTests([(UnicodeType.isdigit, "Port number must be an integer!"), (lambda port : 0 <= int(port) <= 65535 , "Port number must be 0 <= port <= 65535!")]) |
285 if dlg.ShowModal() == wx.ID_OK: |
291 if dlg.ShowModal() == wx.ID_OK: |
286 pyroserver.port = int(dlg.GetValue()) |
292 self.pyroserver.port = int(dlg.GetValue()) |
287 pyroserver.Stop() |
293 self.pyroserver.Stop() |
288 |
294 evt.Skip() |
289 |
295 |
290 def OnTaskBarChangeWorkingDir(self,evt): |
296 def OnTaskBarChangeWorkingDir(self,evt): |
291 dlg = wx.DirDialog(None, "Choose a working directory ", pyroserver.workdir, wx.DD_NEW_DIR_BUTTON) |
297 dlg = wx.DirDialog(None, "Choose a working directory ", pyroserver.workdir, wx.DD_NEW_DIR_BUTTON) |
292 if dlg.ShowModal() == wx.ID_OK: |
298 if dlg.ShowModal() == wx.ID_OK: |
293 pyroserver.workdir = dlg.GetPath() |
299 self.pyroserver.workdir = dlg.GetPath() |
294 pyroserver.Stop() |
300 self.pyroserver.Stop() |
|
301 evt.Skip() |
295 |
302 |
296 def OnTaskBarChangeName(self,evt): |
303 def OnTaskBarChangeName(self,evt): |
297 dlg = ParamsEntryDialog(None, "Enter a name ", defaultValue=pyroserver.name) |
304 dlg = ParamsEntryDialog(None, "Enter a name ", defaultValue=pyroserver.name) |
298 dlg.SetTests([(lambda name : len(name) is not 0 , "Name must not be null!")]) |
305 dlg.SetTests([(lambda name : len(name) is not 0 , "Name must not be null!")]) |
299 if dlg.ShowModal() == wx.ID_OK: |
306 if dlg.ShowModal() == wx.ID_OK: |
300 pyroserver.name = dlg.GetValue() |
307 self.pyroserver.name = dlg.GetValue() |
301 pyroserver.Restart() |
308 self.pyroserver.Restart() |
302 |
309 evt.Skip() |
|
310 |
|
311 def OnTaskBarLiveShell(self,evt): |
|
312 if self.pyroserver.plcobj is not None and self.pyroserver.plcobj.python_threads_vars is not None: |
|
313 from wx import py |
|
314 frame = py.shell.ShellFrame(locals=self.pyroserver.plcobj.python_threads_vars) |
|
315 frame.Show() |
|
316 else: |
|
317 wx.MessageBox("No runnning PLC","Error") |
|
318 evt.Skip() |
|
319 |
303 def OnTaskBarQuit(self,evt): |
320 def OnTaskBarQuit(self,evt): |
304 pyroserver.Quit() |
321 pyroserver.Quit() |
305 self.RemoveIcon() |
322 self.RemoveIcon() |
306 wx.GetApp().ExitMainLoop() |
323 wx.GetApp().ExitMainLoop() |
|
324 evt.Skip() |
307 |
325 |
308 def UpdateIcon(self, plcstatus): |
326 def UpdateIcon(self, plcstatus): |
309 if plcstatus is "Started" : |
327 if plcstatus is "Started" : |
310 currenticon = self.MakeIcon(starticon.GetImage()) |
328 currenticon = self.MakeIcon(starticon.GetImage()) |
311 elif plcstatus is "Stopped": |
329 elif plcstatus is "Stopped": |
374 |
392 |
375 pyroserver = Server(name, ip, port, WorkingDir, args) |
393 pyroserver = Server(name, ip, port, WorkingDir, args) |
376 |
394 |
377 if havewx: |
395 if havewx: |
378 app=wx.App(redirect=False) |
396 app=wx.App(redirect=False) |
379 taskbar_instance = DemoTaskBarIcon(pyroserver) |
397 taskbar_instance = BeremizTaskBarIcon(pyroserver) |
380 def statuschange(status): |
398 def statuschange(status): |
381 wx.CallAfter(taskbar_instance.UpdateIcon,status) |
399 wx.CallAfter(taskbar_instance.UpdateIcon,status) |
382 pyro_thread=Thread(target=pyroserver.Loop, args=[statuschange]) |
400 pyro_thread=Thread(target=pyroserver.Loop, args=[statuschange]) |
383 pyro_thread.start() |
401 pyro_thread.start() |
384 app.MainLoop() |
402 app.MainLoop() |