The branch, build-59a18b6e3b5d3f1dd8f07f26433d37fe5984a57d has been updated via 2ab7ddf42913b5abb4e8ed11401d4abe30bece3d (commit) from 4d5862b911b74d8897c068370f224fc2ee70df18 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: pyhoca/wxgui/frontend.py | 6 ++- pyhoca/wxgui/notify.py | 131 ++++++++++------------------------------------ pyhoca/wxgui/taskbar.py | 75 +++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 104 deletions(-) The diff of changes is: diff --git a/pyhoca/wxgui/frontend.py b/pyhoca/wxgui/frontend.py index 2848ad1..b8bcd67 100644 --- a/pyhoca/wxgui/frontend.py +++ b/pyhoca/wxgui/frontend.py @@ -181,7 +181,11 @@ class PyHocaGUI(wx.App, x2go.X2goClient): #self._chooser_selected_profile_name = None self.taskbar = taskbar.PyHocaGUI_TaskBarIcon(self) self.taskbar.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.taskbar.CreateSessionManagerPopupMenu) - self.notifier = notify.libnotify_NotifierPopup(self) + + if x2go.X2GOCLIENT_OS in ('Linux', 'Mac'): + self.notifier = notify.libnotify_NotifierPopup(self) + if x2go.X2GOCLIENT_OS in ('Windows'): + self.notifier = notify.win32gui_NotifierPopup(self) self._sub_windows = [] self._eventid_profilenames_map = {} diff --git a/pyhoca/wxgui/notify.py b/pyhoca/wxgui/notify.py index 7f7e838..f8eb545 100644 --- a/pyhoca/wxgui/notify.py +++ b/pyhoca/wxgui/notify.py @@ -67,109 +67,36 @@ class libnotify_NotifierPopup(object): def Close(self): pass -class wx_NotifierPopup(wx.Frame): - """notifier's popup window""" - def __init__(self, _PyHocaGUI): +class win32gui_NotifierPopup(object): + + title = {} + text = {} + def __init__(self, _PyHocaGUI): self._PyHocaGUI = _PyHocaGUI - wx.Frame.__init__(self, None, -1, style=wx.NO_BORDER|wx.FRAME_NO_TASKBAR) - self.padding = 12 # padding between edge, icon and text - self.popped = 0 # the time popup was opened - self.delay = 4 # time to leave the popup opened - - # platform specific hacks - lines = 2 - lineHeight = wx.MemoryDC().GetTextExtent(" ")[1] - if wx.Platform == "__WXGTK__": - # use the popup window widget on gtk as the - # frame widget can't animate outside the screen - self.popup = wx.PopupWindow(self, -1) - elif wx.Platform == "__WXMSW__": - # decrement line height on windows as the text calc below is off otherwise - self.popup = self - lineHeight -= 3 - elif wx.Platform == "__WXMAC__": - # untested - self.popup = self - - self.popup.SetSize((250, (lineHeight * (lines + 1)) + (self.padding * 2))) - self.panel = wx.Panel(self.popup, -1, size=self.popup.GetSize()) - - # popup's click handler - self.panel.Bind(wx.EVT_LEFT_DOWN, self.click) - - # popup's logo - self.logo = wx.BitmapFromImage(images.getx2goclientImage()) - wx.StaticBitmap(self.panel, -1, pos=(self.padding, self.padding)).SetBitmap(self.logo) - - # main timer routine - self.timer = wx.Timer(self, -1) - self.Bind(wx.EVT_TIMER, self.main, self.timer) - self.timer.Start(700) - - def main(self, event): - - if self.focused(): - # maintain opened state if focused - self.popped = time.time() - elif self.opened() and self.popped + self.delay < time.time(): - # hide the popup once delay is reached - self.hide() - - def click(self, event): - """handles popup click""" - - self.popped = 0 - self.hide() - - def send(self, title, text): - """shows the popup""" - - # create new text - if hasattr(self, "text"): - self.text.Destroy() - popupSize = self.popup.GetSize() - logoSize = self.logo.GetSize() - self.text = wx.StaticText(self.panel, -1, title) - self.text = wx.StaticText(self.panel, -1, text) - self.text.Bind(wx.EVT_LEFT_DOWN, self.click) - #self.text.Move((logoSize.width + (self.padding * 2), self.padding)) - self.text.SetSize(( - popupSize.width - logoSize.width - (self.padding * 3), - popupSize.height - (self.padding * 2) - )) - - # animate the popup - screen = wx.GetClientDisplayRect() - self.popup.Show() - for i in range(1, popupSize.height + 1): - self.popup.Move((screen.width - popupSize.width, screen.height - i)) - self.popup.SetTransparent(int(float(240) / popupSize.height * i)) - self.popup.Update() - self.popup.Refresh() - time.sleep(0.01) - self.popped = time.time() - - def hide(self): - """hides the popup""" - - self.popup.Hide() - self.popped = 0 - - def focused(self): - """returns true if popup has mouse focus""" - - mouse = wx.GetMousePosition() - popup = self.popup.GetScreenRect() - return ( - self.popped and - mouse.x in range(popup.x, popup.x + popup.width) - and mouse.y in range(popup.y, popup.y + popup.height) - ) - - def opened(self): - """returns true if popup is open""" - - return self.popped != 0 + self.taskbar = self._PyhocaGUI.taskbar + + def prepare(self, context, title=None, text=None): + if title is not None: + self.title[context] = title + if text is not None: + self.text[context] = text + def send(self, title=None, text=None, context=None, timeout=8000): + if context is not None: + try: + title = self.title[context] + del self.title[context] + except KeyError: + pass + try: + text = self.text[context] + del self.text[context] + except KeyError: + pass + + self.taskbar.ShowBalloon(title, text, msec=timeout) + + def Close(self): + pass diff --git a/pyhoca/wxgui/taskbar.py b/pyhoca/wxgui/taskbar.py index 3e1af8a..20dad7f 100644 --- a/pyhoca/wxgui/taskbar.py +++ b/pyhoca/wxgui/taskbar.py @@ -79,6 +79,7 @@ class PyHocaGUI_TaskBarIcon(wx.TaskBarIcon): icon = self.MakeIcon(images.getx2goclientImage()) self.SetIcon(icon, "PyHoca-GUI (Python X2go Client)") self.imgidx = 1 + self.tooltip = "" def CreateSessionManagerPopupMenu(self, evt): """\ @@ -113,4 +114,76 @@ class PyHocaGUI_TaskBarIcon(wx.TaskBarIcon): return icon def Close(self): - self.Destroy() \ No newline at end of file + self.Destroy() + + def ShowBalloon(self, title, text, msec=0, flags=0): + """ + Show Balloon tooltip + + @param title - Title for balloon tooltip + @param msg - Balloon tooltip text + @param msec - Timeout for balloon tooltip, in milliseconds + @param flags - one of wx.ICON_INFORMATION, wx.ICON_WARNING, wx.ICON_ERROR + """ + if WIN32 and self.IsIconInstalled(): + try: + self.__SetBalloonTip(self.icon.GetHandle(), title, text, msec, flags) + except Exception, e: + self._PyHocaGUI._pyhoca_logger(str(e)) + + def __SetBalloonTip(self, hicon, title, msg, msec, flags): + + # translate flags + infoFlags = 0 + if flags & wx.ICON_INFORMATION: + infoFlags |= win32gui.NIIF_INFO + elif flags & wx.ICON_WARNING: + infoFlags |= win32gui.NIIF_WARNING + elif flags & wx.ICON_ERROR: + infoFlags |= win32gui.NIIF_ERROR + + # Show balloon + lpdata = (self.__GetIconHandle(), # hWnd + 99, # ID + win32gui.NIF_MESSAGE|win32gui.NIF_INFO|win32gui.NIF_ICON, # flags: Combination of NIF_* flags + 0, # CallbackMessage: Message id to be pass to hWnd when processing messages + hicon, # hIcon: Handle to the icon to be displayed + '', # Tip: Tooltip text + msg, # Info: Balloon tooltip text + msec, # Timeout: Timeout for balloon tooltip, in milliseconds + title, # InfoTitle: Title for balloon tooltip + infoFlags # InfoFlags: Combination of NIIF_* flags + ) + win32gui.Shell_NotifyIcon(win32gui.NIM_MODIFY, lpdata) + self.SetIcon(self.icon, self.tooltip) # Hack: because we have no access to the real CallbackMessage value + + def __GetIconHandle(self): + """ + Find the icon window. + This is ugly but for now there is no way to find this window directly from wx + """ + if not hasattr(self, "_chwnd"): + try: + for handle in wx.GetTopLevelWindows(): + if handle.GetWindowStyle(): + continue + handle = handle.GetHandle() + if len(win32gui.GetWindowText(handle)) == 0 and \ + win32gui.GetWindowRect(handle) == (0,0,400,250): + self._chwnd = handle + break + if not hasattr(self, "_chwnd"): + raise Exception + except: + raise Exception, "Icon window not found" + return self._chwnd + + def SetIcon(self, icon, tooltip=""): + self.icon = icon + self.tooltip = tooltip + wx.TaskBarIcon.SetIcon(self, icon, tooltip) + + def RemoveIcon(self): + self.icon = None + self.tooltip = "" + wx.TaskBarIcon.RemoveIcon(self) \ No newline at end of file hooks/post-receive -- pyhoca-gui.git (Python X2Go Client (wxPython GUI)) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "pyhoca-gui.git" (Python X2Go Client (wxPython GUI)).