def OnInit(self): if operating_system.isWindows(): self.Bind(wx.EVT_QUERY_END_SESSION, self.onQueryEndSession) try: isatty = sys.stdout.isatty() except AttributeError: isatty = False if (operating_system.isWindows() and hasattr(sys, 'frozen') and not isatty) or not isatty: sys.stdout = sys.stderr = RedirectedOutput() return True
def __create_mutex(): ''' On Windows, create a mutex so that InnoSetup can check whether the application is running. ''' if operating_system.isWindows(): import ctypes from taskcoachlib import meta ctypes.windll.kernel32.CreateMutexA(None, False, meta.filename)
def getSimple(klass): """ Returns a notifier suitable for simple notifications. This defaults to Growl/Snarl/libnotify depending on their availability. """ if klass._enabled: if operating_system.isMac(): return klass.get('Growl') or klass.get('Task Coach') elif operating_system.isWindows(): return klass.get('Snarl') or klass.get('Task Coach') else: return klass.get('libnotify') or klass.get('Task Coach') else: class DummyNotifier(AbstractNotifier): def getName(self): return u'Dummy' def isAvailable(self): return True def notify(self, title, summary, bitmap, **kwargs): pass return DummyNotifier()
def getSimple(klass): """ Returns a notifier suitable for simple notifications. This defaults to Growl/Snarl/libnotify depending on their availability. """ if klass._enabled: if operating_system.isMac(): return klass.get("Growl") or klass.get("Task Coach") elif operating_system.isWindows(): return klass.get("Snarl") or klass.get("Task Coach") else: return klass.get("libnotify") or klass.get("Task Coach") else: class DummyNotifier(AbstractNotifier): def getName(self): return u"Dummy" def isAvailable(self): return True def notify(self, title, summary, bitmap, **kwargs): pass return DummyNotifier()
def init(): if operating_system.isWindows() and wx.DisplayDepth() >= 32: wx.SystemOptions_SetOption("msw.remap", "0") # pragma: no cover try: wx.ArtProvider_PushProvider(ArtProvider()) # pylint: disable=E1101 except AttributeError: wx.ArtProvider.Push(ArtProvider())
def __is_scrollbar_included_in_client_size(self): # NOTE: on GTK, the scrollbar is included in the client size, but on # Windows it is not included if operating_system.isWindows(): return isinstance(self, hypertreelist.HyperTreeList) else: return True
def __register_signal_handlers(self): if operating_system.isWindows(): import win32api # pylint: disable=F0401 def quit_adapter(*args): # The handler is called from something that is not the main thread, so we can't do # much wx-related event = threading.Event() def quit(): try: self.quitApplication() finally: event.set() wx.CallAfter(quit) event.wait() return True win32api.SetConsoleCtrlHandler(quit_adapter, True) else: import signal def quit_adapter(*args): return self.quitApplication() signal.signal(signal.SIGTERM, quit_adapter) if hasattr(signal, 'SIGHUP'): forced_quit = lambda *args: self.quitApplication(force=True) signal.signal(signal.SIGHUP, forced_quit) # pylint: disable=E1101
def pathToDocumentsDir(): if operating_system.isWindows(): from win32com.shell import shell, shellcon try: return shell.SHGetSpecialFolderPath(None, shellcon.CSIDL_PERSONAL) except: # Yes, one of the documented ways to get this sometimes fail with "Unspecified error". Not sure # this will work either. # Update: There are cases when it doesn't work either; see support request #410... try: return shell.SHGetFolderPath(None, shellcon.CSIDL_PERSONAL, None, 0) # SHGFP_TYPE_CURRENT not in shellcon except: return os.getcwd() # F**k this elif operating_system.isMac(): import Carbon.Folder, Carbon.Folders, Carbon.File pathRef = Carbon.Folder.FSFindFolder(Carbon.Folders.kUserDomain, Carbon.Folders.kDocumentsFolderType, True) return Carbon.File.pathname(pathRef) elif operating_system.isGTK(): try: from PyKDE4.kdeui import KGlobalSettings except ImportError: pass else: return unicode(KGlobalSettings.documentPath()) # Assuming Unix-like return os.path.expanduser('~')
def migrateConfigurationFiles(self): # Templates. Extra care for Windows shortcut. oldPath = self.pathToTemplatesDir_deprecated(doCreate=False) newPath, exists = self._pathToTemplatesDir() if self.__iniFileSpecifiedOnCommandLine: globalPath = os.path.join(self.pathToDataDir(forceGlobal=True), 'templates') if os.path.exists(globalPath) and not os.path.exists(oldPath): # Upgrade from fresh installation of 1.3.24 Portable oldPath = globalPath if exists and not os.path.exists(newPath + '-old'): # WTF? os.rename(newPath, newPath + '-old') exists = False if exists: return if oldPath != newPath: if operating_system.isWindows() and os.path.exists(oldPath + '.lnk'): shutil.move(oldPath + '.lnk', newPath + '.lnk') elif os.path.exists(oldPath): # pathToTemplatesDir() has created the directory try: os.rmdir(newPath) except: pass shutil.move(oldPath, newPath) # Ini file oldPath = os.path.join(self.pathToConfigDir_deprecated(environ=os.environ), '%s.ini' % meta.filename) newPath = os.path.join(self.pathToConfigDir(environ=os.environ), '%s.ini' % meta.filename) if newPath != oldPath and os.path.exists(oldPath): shutil.move(oldPath, newPath) # Cleanup try: os.rmdir(self.pathToConfigDir_deprecated(environ=os.environ)) except: pass
def summary(self): if self.__handle is not None: self.close() if operating_system.isWindows(): wx.MessageBox(_('Errors have occured. Please see "taskcoachlog.txt" in your "My Documents" folder.'), _('Error'), wx.OK) else: wx.MessageBox(_('Errors have occured. Please see "%s"') % self.__path, _('Error'), wx.OK)
def OnBeginColumnDrag(self, event): # pylint: disable=W0201 if event.Column == self.ResizeColumn: self.__oldResizeColumnWidth = self.GetColumnWidth(self.ResizeColumn) # Temporarily unbind the EVT_SIZE to prevent resizing during dragging self.Unbind(wx.EVT_SIZE) if operating_system.isWindows(): event.Skip()
def testWindowSizeShouldnotChangeWhenReceivingChangeSizeEvent(self): event = wx.SizeEvent((100, 20)) process = self.mainwindow.ProcessEvent if operating_system.isWindows(): process(event) # pragma: no cover else: wx.CallAfter(process, event) # pragma: no cover self.assertEqual((900, self.expectedHeight()), eval(self.settings.get("window", "size")))
def setUp(self): super(WindowDimensionsTrackerTest, self).setUp() self.settings = config.Settings(load=False) self.section = "window" self.settings.setvalue(self.section, "position", (50, 50)) self.settings.setvalue(self.section, "starticonized", "Never") if operating_system.isWindows(): self.frame.Show() self.tracker = gui.windowdimensionstracker.WindowDimensionsTracker(self.frame, self.settings)
def testMaximize(self): # pragma: no cover # Skipping this test under wxGTK. I don't know how it managed # to pass before but according to # http://trac.wxwidgets.org/ticket/9167 and to my own tests, # EVT_MAXIMIZE is a noop under this platform. self.mainwindow.Maximize() if operating_system.isWindows(): wx.Yield() self.failUnless(self.settings.getboolean('window', 'maximized'))
def __init__(self, *args, **kwargs): super(IPhoneBonjourDialog, self).__init__(*args, **kwargs) vsizer = wx.BoxSizer(wx.VERTICAL) vsizer.Add( wx.StaticText( self, wx.ID_ANY, _('You have enabled the iPhone synchronization feature, which\n' 'needs Bonjour. Bonjour does not seem to be installed on\n' 'your system.')), 0, wx.ALL, 3) if operating_system.isWindows(): # pragma: no cover vsizer.Add( wx.StaticText( self, wx.ID_ANY, _('Please download and install Bonjour for Windows from\n') ), 0, wx.ALL, 3) vsizer.Add( hl.HyperLinkCtrl( self, wx.ID_ANY, _('Apple\'s web site'), URL='http://support.apple.com/downloads/Bonjour_for_Windows' ), 0, wx.ALL, 3) else: # pragma: no cover # MacOS does support Bonjour in all cases, so we're probably running Linux. vsizer.Add( wx.StaticText( self, wx.ID_ANY, _('Bonjour support for Linux is generally provided by\n' 'Avahi.')), 0, wx.ALL, 3) vsizer.Add( hl.HyperLinkCtrl( self, wx.ID_ANY, _('You may find details for your distribution here'), URL='http://avahi.org/wiki/AboutAvahi#Distributions'), 0, wx.ALL, 3) vsizer.Add( wx.StaticText( self, wx.ID_ANY, _('Note that under some systems (Fedora), you may have to\n' 'install the avahi-compat-libdns_sd package as well as Avahi in order\n' 'for this to work.')), 0, wx.ALL, 3) vsizer.Add( wx.StaticText( self, wx.ID_ANY, _('In addition, if you have a firewall, check that ports 4096-4100 are open.' ))) btnOK = wx.Button(self, wx.ID_ANY, _('OK')) vsizer.Add(btnOK, 0, wx.ALIGN_CENTRE | wx.ALL, 3) self.SetSizer(vsizer) self.Fit() self.CentreOnScreen() wx.EVT_BUTTON(btnOK, wx.ID_ANY, self.OnDismiss)
def testWindowSizeShouldnotChangeWhenReceivingChangeSizeEvent(self): event = wx.SizeEvent((100, 20)) process = self.mainwindow.ProcessEvent if operating_system.isWindows(): process(event) # pragma: no cover else: wx.CallAfter(process, event) # pragma: no cover self.assertEqual((900, self.expectedHeight()), eval(self.settings.get('window', 'size')))
def OnInit(self): if operating_system.isWindows(): self.Bind(wx.EVT_QUERY_END_SESSION, self.onQueryEndSession) if (operating_system.isMac() and hasattr(sys, 'frozen')) or \ (operating_system.isGTK() and not sys.stdout.isatty()): sys.stdout = sys.stderr = RedirectedOutput() return True
def setUp(self): super(WindowDimensionsTrackerTest, self).setUp() self.settings = config.Settings(load=False) self.section = 'window' self.settings.setvalue(self.section, 'position', (50, 50)) self.settings.setvalue(self.section, 'starticonized', 'Never') if operating_system.isWindows(): self.frame.Show() self.tracker = gui.windowdimensionstracker.WindowDimensionsTracker( \ self.frame, self.settings)
def __register_signal_handlers(self): quit_adapter = lambda *args: self.quitApplication() if operating_system.isWindows(): import win32api # pylint: disable=F0401 win32api.SetConsoleCtrlHandler(quit_adapter, True) else: import signal signal.signal(signal.SIGTERM, quit_adapter) if hasattr(signal, 'SIGHUP'): forced_quit = lambda *args: self.quitApplication(force=True) signal.signal(signal.SIGHUP, forced_quit) # pylint: disable=E1101
def _pathToDataDir(self, *args, **kwargs): forceGlobal = kwargs.pop('forceGlobal', False) if operating_system.isGTK(): from taskcoachlib.thirdparty.xdg import BaseDirectory path = BaseDirectory.save_data_path(meta.name) elif operating_system.isMac(): import Carbon.Folder, Carbon.Folders, Carbon.File pathRef = Carbon.Folder.FSFindFolder( Carbon.Folders.kUserDomain, Carbon.Folders.kApplicationSupportFolderType, True) path = Carbon.File.pathname(pathRef) # XXXFIXME: should we release pathRef ? Doesn't seem so since I get a SIGSEGV if I try. path = os.path.join(path, meta.name) elif operating_system.isWindows(): if self.__iniFileSpecifiedOnCommandLine and not forceGlobal: path = self.pathToIniFileSpecifiedOnCommandLine() else: from win32com.shell import shell, shellcon path = os.path.join( shell.SHGetSpecialFolderPath(None, shellcon.CSIDL_APPDATA, True), meta.name) else: # Errr... path = self.path() if operating_system.isWindows(): # Follow shortcuts. from win32com.client import Dispatch shell = Dispatch('WScript.Shell') for component in args: path = os.path.join(path, component) if os.path.exists(path + '.lnk'): shortcut = shell.CreateShortcut(path + '.lnk') path = shortcut.TargetPath else: path = os.path.join(path, *args) exists = os.path.exists(path) if not exists: os.makedirs(path) return path, exists
def __init__(self, *args, **kwargs): super(AuiManagedFrameWithDynamicCenterPane, self).__init__(*args, **kwargs) agwStyle = aui.AUI_MGR_DEFAULT | aui.AUI_MGR_ALLOW_ACTIVE_PANE if not operating_system.isWindows(): # With this style on Windows, you can't dock back floating frames agwStyle |= aui.AUI_MGR_USE_NATIVE_MINIFRAMES self.manager = aui.AuiManager(self, agwStyle) self.manager.SetAutoNotebookStyle(aui.AUI_NB_TOP | \ aui.AUI_NB_CLOSE_BUTTON | \ aui.AUI_NB_SUB_NOTEBOOK | \ aui.AUI_NB_SCROLL_BUTTONS) self.bindEvents()
def getSimple(klass): """ Returns a notifier suitable for simple notifications. This defaults to Growl/Snarl/libnotify depending on their availability. """ if operating_system.isMac(): return klass.get('Growl') or klass.get('Task Coach') elif operating_system.isWindows(): return klass.get('Snarl') or klass.get('Task Coach') else: return klass.get('libnotify') or klass.get('Task Coach')
def _pathToDataDir(self, *args, **kwargs): forceGlobal = kwargs.pop('forceGlobal', False) if operating_system.isGTK(): from taskcoachlib.thirdparty.xdg import BaseDirectory path = BaseDirectory.save_data_path(meta.name) elif operating_system.isMac(): import Carbon.Folder, Carbon.Folders, Carbon.File pathRef = Carbon.Folder.FSFindFolder(Carbon.Folders.kUserDomain, Carbon.Folders.kApplicationSupportFolderType, True) path = Carbon.File.pathname(pathRef) # XXXFIXME: should we release pathRef ? Doesn't seem so since I get a SIGSEGV if I try. path = os.path.join(path, meta.name) elif operating_system.isWindows(): if self.__iniFileSpecifiedOnCommandLine and not forceGlobal: path = self.pathToIniFileSpecifiedOnCommandLine() else: from win32com.shell import shell, shellcon path = os.path.join(shell.SHGetSpecialFolderPath(None, shellcon.CSIDL_APPDATA, True), meta.name) else: # Errr... path = self.path() if operating_system.isWindows(): # Follow shortcuts. from win32com.client import Dispatch shell = Dispatch('WScript.Shell') for component in args: path = os.path.join(path, component) if os.path.exists(path + '.lnk'): shortcut = shell.CreateShortcut(path + '.lnk') path = shortcut.TargetPath else: path = os.path.join(path, *args) exists = os.path.exists(path) if not exists: os.makedirs(path) return path, exists
def updateMenuText(self, menuText): self.menuText = menuText if operating_system.isWindows(): for menuItem in self.menuItems[:]: menu = menuItem.GetMenu() pos = menu.GetMenuItems().index(menuItem) newMenuItem = wx.MenuItem(menu, self.id, menuText, self.helpText, self.kind) self.addBitmapToMenuItem(newMenuItem) menu.DeleteItem(menuItem) self.menuItems.remove(menuItem) self.menuItems.append(newMenuItem) menu.InsertItem(pos, newMenuItem) else: for menuItem in self.menuItems: menuItem.SetItemLabel(menuText)
def __init__(self, mainwindow, taskList, settings, defaultBitmap='taskcoach', tickBitmap='clock_icon', tackBitmap='clock_stopwatch_icon', *args, **kwargs): super(TaskBarIcon, self).__init__(*args, **kwargs) self.__window = mainwindow self.__taskList = taskList self.__settings = settings self.__bitmap = self.__defaultBitmap = defaultBitmap self.__tooltipText = '' self.__tickBitmap = tickBitmap self.__tackBitmap = tackBitmap self.registerObserver(self.onTaskListChanged, eventType=taskList.addItemEventType(), eventSource=taskList) self.registerObserver(self.onTaskListChanged, eventType=taskList.removeItemEventType(), eventSource=taskList) pub.subscribe(self.onTrackingChanged, task.Task.trackingChangedEventType()) pub.subscribe(self.onChangeDueDateTime, task.Task.dueDateTimeChangedEventType()) # When the user chances the due soon hours preferences it may cause # a task to change appearance. That also means the number of due soon # tasks has changed, so we need to change the tool tip text. # Note that directly subscribing to the setting (behavior.duesoonhours) # is not reliable. The TaskBarIcon may get the event before the tasks # do. When that happens the tasks haven't changed their status yet and # we would use the wrong status count. self.registerObserver(self.onChangeDueDateTime_Deprecated, eventType=task.Task.appearanceChangedEventType()) if operating_system.isGTK(): events = [wx.EVT_TASKBAR_LEFT_DOWN] elif operating_system.isWindows(): # See http://msdn.microsoft.com/en-us/library/windows/desktop/aa511448.aspx#interaction events = [wx.EVT_TASKBAR_LEFT_DOWN, wx.EVT_TASKBAR_LEFT_DCLICK] else: events = [wx.EVT_TASKBAR_LEFT_DCLICK] for event in events: self.Bind(event, self.onTaskbarClick) self.__setTooltipText() self.__setIcon()
def pathToConfigDir(self, environ): try: if operating_system.isGTK(): from taskcoachlib.thirdparty.xdg import BaseDirectory path = BaseDirectory.save_config_path(meta.name) elif operating_system.isMac(): import Carbon.Folder, Carbon.Folders, Carbon.File pathRef = Carbon.Folder.FSFindFolder(Carbon.Folders.kUserDomain, Carbon.Folders.kPreferencesFolderType, True) path = Carbon.File.pathname(pathRef) # XXXFIXME: should we release pathRef ? Doesn't seem so since I get a SIGSEGV if I try. elif operating_system.isWindows(): from win32com.shell import shell, shellcon path = os.path.join(shell.SHGetSpecialFolderPath(None, shellcon.CSIDL_APPDATA, True), meta.name) else: path = self.pathToConfigDir_deprecated(environ=environ) except: # Fallback to old dir path = self.pathToConfigDir_deprecated(environ=environ) return path
def pathToTemplatesDir_deprecated(self, doCreate=True): path = os.path.join(self.path(), 'taskcoach-templates') if operating_system.isWindows(): # Under Windows, check for a shortcut and follow it if it # exists. if os.path.exists(path + '.lnk'): from win32com.client import Dispatch # pylint: disable=F0401 shell = Dispatch('WScript.Shell') shortcut = shell.CreateShortcut(path + '.lnk') return shortcut.TargetPath if doCreate: try: os.makedirs(path) except OSError: pass return operating_system.decodeSystemString(path)
def __init__(self, mainwindow, taskList, settings, defaultBitmap='taskcoach', tickBitmap='clock_icon', tackBitmap='clock_stopwatch_icon', *args, **kwargs): super(TaskBarIcon, self).__init__(*args, **kwargs) self.__window = mainwindow self.__taskList = taskList self.__settings = settings self.__bitmap = self.__defaultBitmap = defaultBitmap self.__currentBitmap = self.__bitmap self.__tooltipText = '' self.__currentText = self.__tooltipText self.__tickBitmap = tickBitmap self.__tackBitmap = tackBitmap self.registerObserver(self.onTaskListChanged, eventType=taskList.addItemEventType(), eventSource=taskList) self.registerObserver(self.onTaskListChanged, eventType=taskList.removeItemEventType(), eventSource=taskList) pub.subscribe(self.onTrackingChanged, task.Task.trackingChangedEventType()) pub.subscribe(self.onChangeDueDateTime, task.Task.dueDateTimeChangedEventType()) # When the user chances the due soon hours preferences it may cause # a task to change appearance. That also means the number of due soon # tasks has changed, so we need to change the tool tip text. # Note that directly subscribing to the setting (behavior.duesoonhours) # is not reliable. The TaskBarIcon may get the event before the tasks # do. When that happens the tasks haven't changed their status yet and # we would use the wrong status count. self.registerObserver(self.onChangeDueDateTime_Deprecated, eventType=task.Task.appearanceChangedEventType()) if operating_system.isGTK(): events = [wx.EVT_TASKBAR_LEFT_DOWN] elif operating_system.isWindows(): # See http://msdn.microsoft.com/en-us/library/windows/desktop/aa511448.aspx#interaction events = [wx.EVT_TASKBAR_LEFT_DOWN, wx.EVT_TASKBAR_LEFT_DCLICK] else: events = [wx.EVT_TASKBAR_LEFT_DCLICK] for event in events: self.Bind(event, self.onTaskbarClick) self.__setTooltipText() mainwindow.Bind(wx.EVT_IDLE, self.onIdle)
def __init__(self, *args, **kwargs): super(IPhoneBonjourDialog, self).__init__(*args, **kwargs) vsizer = wx.BoxSizer(wx.VERTICAL) vsizer.Add(wx.StaticText(self, wx.ID_ANY, _('You have enabled the iPhone synchronization feature, which\n' 'needs Bonjour. Bonjour does not seem to be installed on\n' 'your system.')), 0, wx.ALL, 3) if operating_system.isWindows(): # pragma: no cover vsizer.Add(wx.StaticText(self, wx.ID_ANY, _('Please download and install Bonjour for Windows from\n')), 0, wx.ALL, 3) vsizer.Add(hl.HyperLinkCtrl(self, wx.ID_ANY, _('Apple\'s web site'), URL='http://support.apple.com/downloads/Bonjour_for_Windows'), 0, wx.ALL, 3) else: # pragma: no cover # MacOS does support Bonjour in all cases, so we're probably running Linux. vsizer.Add(wx.StaticText(self, wx.ID_ANY, _('Bonjour support for Linux is generally provided by\n' 'Avahi.')), 0, wx.ALL, 3) vsizer.Add(hl.HyperLinkCtrl(self, wx.ID_ANY, _('You may find details for your distribution here'), URL='http://avahi.org/wiki/AboutAvahi#Distributions'), 0, wx.ALL, 3) vsizer.Add(wx.StaticText(self, wx.ID_ANY, _('Note that under some systems (Fedora), you may have to\n' 'install the avahi-compat-libdns_sd package as well as Avahi in order\n' 'for this to work.')), 0, wx.ALL, 3) vsizer.Add(wx.StaticText(self, wx.ID_ANY, _('In addition, if you have a firewall, check that ports 4096-4100 are open.'))) btnOK = wx.Button(self, wx.ID_ANY, _('OK')) vsizer.Add(btnOK, 0, wx.ALIGN_CENTRE|wx.ALL, 3) self.SetSizer(vsizer) self.Fit() self.CentreOnScreen() wx.EVT_BUTTON(btnOK, wx.ID_ANY, self.OnDismiss)
def tearDown(self): # pragma: no cover if operating_system.isWindows(): self.icon.Destroy() else: self.icon.RemoveIcon() super(TaskBarIconTestCase, self).tearDown()
c_int, c_ulong, c_ulong, POINTER(XScreenSaverInfo))( ('XScreenSaverQueryInfo', _xss)) self.info = self.XScreenSaverAllocInfo() def __del__(self): self.XCloseDisplay(self.dpy) def getIdleSeconds(self): self.XScreenSaverQueryInfo(self.dpy, self.XRootWindow(self.dpy, 0), self.info) return 1.0 * self.info.contents.idle / 1000 IdleQuery = LinuxIdleQuery elif operating_system.isWindows(): class LASTINPUTINFO(Structure): _fields_ = [('cbSize', c_uint), ('dwTime', c_uint)] class WindowsIdleQuery(object): def __init__(self): self.GetTickCount = windll.kernel32.GetTickCount self.GetLastInputInfo = windll.user32.GetLastInputInfo self.lastInputInfo = LASTINPUTINFO() self.lastInputInfo.cbSize = sizeof(self.lastInputInfo) def getIdleSeconds(self): self.GetLastInputInfo(byref(self.lastInputInfo)) return (1.0 * self.GetTickCount() -
def OnResize(self, event): event.Skip() if operating_system.isWindows(): wx.CallAfter(self.DoResize) else: self.DoResize()
def __createLockFile(self, filename): if operating_system.isWindows() and self.__isCloud(filename): return DummyLockFile() if self.__isFuse(filename): return lockfile.MkdirFileLock(filename) return lockfile.FileLock(filename)
curY = int(y0 + (y1 - y0) * 1.0 * self.__step / 10) self.__frame.SetPosition(wx.Point(curX, curY)) if self.__step == 10: self.Stop() def __OnClose(self, event): self.Stop() event.Skip() #============================================================================== # Notifications if operating_system.isWindows(): class _NotifyBase(wx.MiniFrame): pass elif operating_system.isGTK(): class _NotifyBase(wx.PopupWindow): def __init__(self, parent, id_, title, style=0): # pylint: disable=W0613,E1003 super(_NotifyBase, self).__init__(parent, id_) # No style def Close(self): # pylint: disable=W0221,E1003 # Strange... super(_NotifyBase, self).Close() self.Destroy() else: class _NotifyBase(wx.Frame): """FIXME: steals focus..."""