📄 uibackenddelegate.py
字号:
import osimport timeimport stringimport signalimport threadingfrom objc import YES, NO, nil, signaturefrom AppKit import *from Foundation import *from PyObjCTools import NibClassBuilder, Conversionimport appimport feedimport prefsimport configimport dialogsimport eventloopimport platformutilsfrom StartupPanel import StartupPanelControllerimport GrowlNotifier###############################################################################NibClassBuilder.extractClasses("PasswordWindow")NibClassBuilder.extractClasses("TextEntryWindow")NibClassBuilder.extractClasses('SearchChannelWindow')NibClassBuilder.extractClasses("ExceptionReporterPanel")dlTask = None################################################################################### Helper methods used to display alert dialog of various types ###################################################################################def showInformationalDialog(summary, message, buttons=None): return showDialog(summary, message, buttons, NSInformationalAlertStyle)def showWarningDialog(summary, message, buttons=None): return showDialog(summary, message, buttons, NSWarningAlertStyle)def showCriticalDialog(summary, message, buttons=None): return showDialog(summary, message, buttons, NSCriticalAlertStyle)@platformutils.onMainThreadWithReturndef showDialog(summary, message, buttons, style): alert = NSAlert.alloc().init() alert.setAlertStyle_(style) alert.setMessageText_(summary) alert.setInformativeText_(message) if buttons is not None: for title in buttons: alert.addButtonWithTitle_(title) result = platformutils.callOnMainThreadAndWaitReturnValue(alert.runModal) result -= NSAlertFirstButtonReturn del alert return result###############################################################################class UIBackendDelegate: # This lock is used by the HTTPAuthDialog to serialize HTTP authentication # requests and prevent multiple authentication dialogs to pop up at once. httpAuthLock = threading.Lock() def __init__(self): self.contextItemHandler = ContextItemHandler.alloc().init() def performStartupTasks(self, terminationCallback): NSApplication.sharedApplication().delegate().checkQuicktimeVersion(True) startupController = StartupPanelController.alloc().init() startupController.run(terminationCallback) @platformutils.onMainThread def runDialog(self, dialog): if isinstance(dialog, dialogs.TextEntryDialog): dlog = TextEntryController.alloc().initWithDialog_(dialog) dlog.run() call = lambda:dialog.runCallback(dlog.result, dlog.value) name = "TextEntryDialog" elif isinstance(dialog, dialogs.HTTPAuthDialog): self.httpAuthLock.acquire() try: authDlog = PasswordController.alloc().initWithDialog_(dialog) result = authDlog.getAnswer() name = "HTTPAuthDialog" if result is not None: call = lambda:dialog.runCallback(dialogs.BUTTON_OK, *result) else: call = lambda:dialog.runCallback(None) finally: self.httpAuthLock.release() elif isinstance(dialog, dialogs.SearchChannelDialog): dlog = SearchChannelController.alloc().initWithDialog_(dialog) dlog.run() call = lambda:dialog.runCallback(dlog.result) name = "SearchChannelDialog" else: buttons = map(lambda x:x.text, dialog.buttons) result = showWarningDialog(dialog.title, dialog.description, buttons) call = lambda:dialog.runCallback(dialog.buttons[result]) name = "Dialog" eventloop.addUrgentCall(call, "Calling back from %s" % name) def openExternalURL(self, url): # We could use Python's webbrowser.open() here, but # unfortunately, it doesn't have the same semantics under UNIX # as under other OSes. Sometimes it blocks, sometimes it doesn't. NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_(url)) def revealFile(self, filename): NSWorkspace.sharedWorkspace().selectFile_inFileViewerRootedAtPath_(filename, nil) def updateAvailableItemsCountFeedback(self, count): try: appIcon = NSImage.imageNamed_('NSApplicationIcon') badgedIcon = NSImage.alloc().initWithSize_(appIcon.size()) badgedIcon.lockFocus() except: pass else: try: appIcon.compositeToPoint_operation_((0,0), NSCompositeSourceOver) if count > 0: digits = len(str(count)) badge = nil if digits <= 2: badge = NSImage.imageNamed_('dock_badge_1_2.png') elif digits <= 5: badge = NSImage.imageNamed_('dock_badge_%d.png' % digits) else: print "DTV: Wow, that's a whole lot of new items!" if badge is not nil: appIconSize = appIcon.size() badgeSize = badge.size() badgeLoc = (appIconSize.width - badgeSize.width, appIconSize.height - badgeSize.height) badge.compositeToPoint_operation_(badgeLoc, NSCompositeSourceOver) badgeLabel = NSString.stringWithString_(u'%d' % count) badgeLabelFont = NSFont.boldSystemFontOfSize_(24) badgeLabelColor = NSColor.whiteColor() badgeParagraphStyle = NSMutableParagraphStyle.alloc().init() badgeParagraphStyle.setAlignment_(NSCenterTextAlignment) badgeLabelAttributes = {NSFontAttributeName: badgeLabelFont, NSForegroundColorAttributeName: badgeLabelColor, NSParagraphStyleAttributeName: badgeParagraphStyle} badgeLabelLoc = (badgeLoc[0], badgeLoc[1]-10) badgeLabel.drawInRect_withAttributes_((badgeLabelLoc, badgeSize), badgeLabelAttributes) finally: badgedIcon.unlockFocus() appl = NSApplication.sharedApplication() platformutils.callOnMainThreadAndWaitUntilDone(appl.setApplicationIconImage_, badgedIcon) def notifyDownloadCompleted(self, item): GrowlNotifier.notifyDownloadComplete(item.getTitle()) def notifyDownloadFailed(self, item): GrowlNotifier.notifyDownloadFailed(item.getTitle()) @platformutils.onMainThread def notifyUnkownErrorOccurence(self, when, log = ''): controller = ExceptionReporterController.alloc().initWithMoment_log_(when, log) controller.showPanel() return True def copyTextToClipboard(self, text): pb = NSPasteboard.generalPasteboard() pb.declareTypes_owner_([NSStringPboardType], self) pb.setString_forType_(text, NSStringPboardType) def ensureDownloadDaemonIsTerminated(self): # Calling dlTask.waitUntilExit() here could cause problems since we # cannot specify a timeout, so if the daemon fails to shutdown we could # wait here indefinitely. We therefore manually poll for a specific # amount of time beyond which we force quit the daemon. global dlTask if dlTask is not None and dlTask.isRunning(): print "DTV: Waiting for the downloader daemon to terminate..." timeout = 5.0 sleepTime = 0.2 loopCount = int(timeout / sleepTime) for i in range(loopCount): if dlTask.isRunning(): time.sleep(sleepTime) else: break else: # If the daemon is still alive at this point, it's likely to be # in a bad state, so nuke it. print "DTV: Timeout expired - Killing downloader daemon!" dlTask.terminate() dlTask.waitUntilExit() dlTask = None def waitUntilDownloadDaemonExit(self): global dlTask if dlTask is not None: dlTask.waitUntilExit() dlTask = None def killDownloadDaemon(self, oldpid=None): if oldpid is not None: try: os.kill(oldpid, signal.SIGTERM) sleep(1) os.kill(oldpid, signal.SIGKILL) except: pass def launchDownloadDaemon(self, oldpid, env): self.killDownloadDaemon(oldpid) env['DEMOCRACY_DOWNLOADER_LOG'] = config.get(prefs.DOWNLOADER_LOG_PATHNAME) env.update(os.environ) bundle = NSBundle.mainBundle() bundleExe = bundle.executablePath() exe = "%s/Downloader" % os.path.dirname(bundleExe) global dlTask dlTask = NSTask.alloc().init() dlTask.setLaunchPath_(exe) dlTask.setArguments_(['download_daemon']) dlTask.setEnvironment_(env) controller = NSApplication.sharedApplication().delegate() nc = NSNotificationCenter.defaultCenter() nc.addObserver_selector_name_object_(controller, 'downloaderDaemonDidTerminate:', NSTaskDidTerminateNotification, dlTask) print "DTV: Launching Download Daemon" dlTask.launch() def makeDemocracyRunAtStartup(self, run): defaults = NSUserDefaults.standardUserDefaults() lwdomain = defaults.persistentDomainForName_('loginwindow') lwdomain = Conversion.pythonCollectionFromPropertyList(lwdomain) if 'AutoLaunchedApplicationDictionary' not in lwdomain: lwdomain['AutoLaunchedApplicationDictionary'] = list() launchedApps = lwdomain['AutoLaunchedApplicationDictionary'] ourPath = NSBundle.mainBundle().bundlePath() ourEntry = None for entry in launchedApps: if entry.get('Path') == ourPath: ourEntry = entry break if run and ourEntry is None: launchInfo = dict(Path=ourPath, Hide=NO)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -