def start_file_search(self, search_directory): self.searching = True self.finder = util.gather_media_files(search_directory) self.progress_bar.start_pulsing() threads.call_on_ui_thread(self.make_progress)
def make_progress(self): if not self.searching: self.finder = None self.progress_label.set_text("") return try: num_parsed, found = self.finder.next() self.gathered_media_files = found self.parsed_files = num_parsed num_found = len(found) self.progress_label.set_text( self._build_progress_label(num_found, num_parsed)) threads.call_on_ui_thread(self.make_progress) except StopIteration: self.end_file_search() self.finder = None num_found = len(self.gathered_media_files) num_parsed = self.parsed_files self.results_label.set_text( self._build_progress_label(num_found, num_parsed)) self.next_page()
def movie_load_state_changed(self, disconnect=True): callback = self.callback errback = self.errback force_subtitles = self.force_subtitles if not self.movie: logging.error('self.movie is not set') # We can only get here via the callback notification so no need # to check disconnect. self.movie_notifications.disconnect( QTMovieLoadStateDidChangeNotification) return load_state = self.movie.attributeForKey_( QTMovieLoadStateAttribute).longValue() if load_state == QTMovieLoadStateError: threads.call_on_ui_thread(errback) elif load_state == QTMovieLoadStateLoading: # Huh? Shouldn't we start of as loading? If so then what's # changed? pass elif load_state == QTMovieLoadStateLoaded: # We really want to be able to play it not just query properties. pass elif load_state in (QTMovieLoadStatePlayable, QTMovieLoadStatePlaythroughOK, QTMovieLoadStateComplete): # call the callback in an idle call, the rest of the Player code # expects it if disconnect: self.movie_notifications.disconnect( QTMovieLoadStateDidChangeNotification) self.setup_subtitles(force_subtitles) tracks = self.movie.tracks() threads.call_on_ui_thread(callback) else: raise ValueError('Unknown QTMovieLoadStateAttribute value')
def make_progress(): if self.cancelled: self.gathered_media_files = [] self.finder = None progress_label.set_text("") return try: num_parsed, found = self.finder.next() self.gathered_media_files = found num_found = len(found) num_files = ngettext("parsed %(count)s file", "parsed %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) progress_label.set_text(u"%s - %s" % (num_files, num_media_files)) threads.call_on_ui_thread(make_progress) except StopIteration: handle_cancel_clicked(None) self.finder = None
def __init__(self): self.donate_ask_thresholds = [app.config.get(prefs.DONATE_ASK1), app.config.get(prefs.DONATE_ASK2), app.config.get(prefs.DONATE_ASK3)] self.donate_url_template = app.config.get(prefs.DONATE_URL_TEMPLATE) self.payment_url_template = app.config.get( prefs.DONATE_PAYMENT_URL_TEMPLATE) self.donate_nothanks = app.config.get(prefs.DONATE_NOTHANKS) self.donate_counter = app.config.get(prefs.DONATE_COUNTER) self.last_donate_time = app.config.get(prefs.LAST_DONATE_TIME) app.backend_config_watcher.connect('changed', self.on_config_changed) signals.system.connect('download-complete', self.on_download_complete) self.donate_window = self.powertoys = None self.donate_ratelimit = False self.ratelimit_dc = None # Tri-state: None/False/True: the close callback gets called # anyway even if the window's not shown! self.donate_response = None call_on_ui_thread(self.create_windows) # Reset counters if not shown for more than 1/2 year. Only do this on # startup is fine. We have already waited half a year, we can wait # some more. # # The other part to this is in shutdown, if the last_donate_time # is still zero at the point in shutdown() set the current time. # # At reset, if the timer is zero, it will fail the half year nag # test. So anyone who is upgrading or somehow had a screwed # last donate time will get the dialog reshown. HALF_YEAR = 60 * 60 * 24 * 180 if time.time() - self.last_donate_time > HALF_YEAR: self.reset()
def movie_load_state_changed(self, disconnect=True): callback = self.callback errback = self.errback force_subtitles = self.force_subtitles if not self.movie: logging.error('self.movie is not set') # We can only get here via the callback notification so no need # to check disconnect. self.movie_notifications.disconnect( QTMovieLoadStateDidChangeNotification) return load_state = self.movie.attributeForKey_( QTMovieLoadStateAttribute).longValue() if load_state == QTMovieLoadStateError: threads.call_on_ui_thread(errback) elif load_state == QTMovieLoadStateLoading: # Huh? Shouldn't we start of as loading? If so then what's # changed? pass elif load_state == QTMovieLoadStateLoaded: # We really want to be able to play it not just query properties. pass elif load_state in (QTMovieLoadStatePlayable, QTMovieLoadStatePlaythroughOK, QTMovieLoadStateComplete): # call the callback in an idle call, the rest of the Player code # expects it if disconnect: self.movie_notifications.disconnect( QTMovieLoadStateDidChangeNotification) self.setup_subtitles(force_subtitles) threads.call_on_ui_thread(callback) else: raise ValueError('Unknown QTMovieLoadStateAttribute value')
def set_item(self, item_info, callback, errback, force_subtitles=False): threads.warn_if_not_on_main_thread('quicktime.Player.set_item') self.reset() qtmovie = self.get_movie_from_file(item_info.video_path) self.callback = callback self.errback = errback self.force_subtitles = force_subtitles if qtmovie is not None: self.item_info = item_info self.movie = qtmovie self.movie_notifications = NotificationForwarder.create(self.movie) self.movie_notifications.connect(self.handle_movie_notification, QTMovieDidEndNotification) load_state = qtmovie.attributeForKey_( QTMovieLoadStateAttribute).longValue() # Only setup a deferred notification if we are unsure of status # anything else in movie_load_state_changed(). if load_state in (QTMovieLoadStateLoading, QTMovieLoadStateLoaded): self.movie_notifications.connect( self.handle_movie_notification, QTMovieLoadStateDidChangeNotification) else: # Playable right away or error - just call and don't disconnect # notification because it wasn't connected in the first place. self.movie_load_state_changed(disconnect=False) else: threads.call_on_ui_thread(errback)
def set_item(self, item_info, callback, errback, force_subtitles=False): threads.warn_if_not_on_main_thread('quicktime.Player.set_item') self.reset() qtmovie = self.get_movie_from_file(item_info.filename) self.callback = callback self.errback = errback self.force_subtitles = force_subtitles if qtmovie is not None: self.item_info = item_info self.movie = qtmovie self.movie_notifications = NotificationForwarder.create(self.movie) self.movie_notifications.connect(self.handle_movie_notification, QTMovieDidEndNotification) load_state = qtmovie.attributeForKey_( QTMovieLoadStateAttribute).longValue() # Only setup a deferred notification if we are unsure of status # anything else in movie_load_state_changed(). if load_state in (QTMovieLoadStateLoading, QTMovieLoadStateLoaded): self.movie_notifications.connect( self.handle_movie_notification, QTMovieLoadStateDidChangeNotification) else: # Playable right away or error - just call and don't disconnect # notification because it wasn't connected in the first place. self.movie_load_state_changed(disconnect=False) else: threads.call_on_ui_thread(errback)
def _on_browser_error(self, widget): # XXX Linux/GTK can't directly issue a self.navigate() here on error. # Don't know why. :-( logging.debug("Donate: _on_browser_error") # only need to nav to fallback if the window was requested to be # shown if self.was_shown_invoked: fallback_path = resources.url("donate.html") call_on_ui_thread(lambda: self.browser.navigate(fallback_path)) self.was_shown_invoked = False
def on_activate(self, is_push): app.item_list_controller_manager.controller_displayed(self.controller) if not is_push: # Focus the item list when we pop the video display from being on # top of us. # # FIXME: call_on_ui_thread is a bit weird here. It's needed # because on OS X we can't call focus() yet on our tableview. call_on_ui_thread(self.controller.focus_view) super(ItemListDisplayMixin, self).on_activate(is_push)
def _on_browser_error(self, widget): # XXX Linux/GTK can't directly issue a self.navigate() here on error. # Don't know why. :-( logging.debug('Donate: _on_browser_error') # only need to nav to fallback if the window was requested to be # shown if self.was_shown_invoked: fallback_path = resources.url('donate.html') call_on_ui_thread(lambda: self.browser.navigate(fallback_path)) self.was_shown_invoked = False
def do_size_allocated(self, width, height): if width != self.renderer.total_width: self.renderer.total_width = width # We want to resize the rows with show_details set to # True, because they may have gotten taller/shorter based # on the description getting less/more width. However, if # the user is quickly resizing the window, we don't want # to flood the system. Use call_on_ui_thread, which # amounts to waiting until the widget system is idle. if not self._recalculate_heights_queued: self._recalculate_heights_queued = True call_on_ui_thread(self._recalculate_show_details_heights)
def handle_search_clicked(widget): self.cancelled = False search_button.disable() cancel_button.enable() prev_button.disable() finish_button.disable() search_directory = FilenameType(self.search_directory) self.finder = util.gather_media_files(search_directory) progress_bar.start_pulsing() threads.call_on_ui_thread(make_progress)
def show_donate(self, url=None, payment_url=None): if not url: args = [1, 2, 3] try: url = self.donate_url_template % args[self.donate_nothanks] except IndexError: url = self.donate_url_template % args[-1] if not payment_url: payment_url = self.payment_url if self.donate_window: self.last_donate_time = time.time() app.config.set(prefs.LAST_DONATE_TIME, self.last_donate_time) call_on_ui_thread(lambda: self.donate_window.show(url, payment_url))
def handle_unwatched_count_changed(self): try: appIcon = NSImage.imageNamed_(u'NSApplicationIcon') badgedIcon = NSImage.alloc().initWithSize_(appIcon.size()) badgedIcon.lockFocus() except: pass else: try: appIcon.compositeToPoint_operation_((0, 0), NSCompositeSourceOver) if self.unwatched_count > 0: digits = len(str(self.unwatched_count)) badge = nil if digits <= 2: badge = NSImage.imageNamed_(u'dock_badge_1_2.png') elif digits <= 5: badge = NSImage.imageNamed_(u'dock_badge_%d.png' % digits) else: logging.warn("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' % self.unwatched_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() threads.call_on_ui_thread(appl.setApplicationIconImage_, badgedIcon)
def start_search(self): # only start a search if we haven't gathered anything, yet. if self.gathered_media_files is not None: return # this starts the search as soon as the dialog is built self.cancelled = False self.cancel_search_button.enable() self.search_prev_button.disable() self.search_next_button.disable() search_directory = FilenameType(self.search_directory) self.finder = util.gather_media_files(search_directory) self.progress_bar.start_pulsing() threads.call_on_ui_thread(self.make_search_progress)
def make_search_progress(self): if self.cancelled: self.finder = None return try: num_parsed, found = self.finder.next() self.gathered_media_files = found num_found = len(found) num_files = ngettext("parsed %(count)s file", "parsed %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) self.progress_label.set_text(u"%s - %s" % ( num_files, num_media_files)) threads.call_on_ui_thread(self.make_search_progress) except StopIteration: num_found = len(self.gathered_media_files) self.search_complete( ngettext( "found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None except Exception: # this is here to get more data for bug #17422 logging.exception("exception thrown in make_search_progress") # we want to clean up after this exception, too. num_found = len(self.gathered_media_files) self.search_complete( ngettext( "found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None
def handle_unwatched_count_changed(self): try: appIcon = NSImage.imageNamed_(u'NSApplicationIcon') badgedIcon = NSImage.alloc().initWithSize_(appIcon.size()) badgedIcon.lockFocus() except: pass else: try: appIcon.drawAtPoint_fromRect_operation_fraction_( (0, 0), NSZeroRect, NSCompositeSourceOver, 1.0) if self.unwatched_count > 0: digits = len(str(self.unwatched_count)) badge = nil if digits <= 2: badge = NSImage.imageNamed_(u'dock_badge_1_2.png') elif digits <= 5: badge = NSImage.imageNamed_(u'dock_badge_%d.png' % digits) else: logging.warn("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.drawAtPoint_fromRect_operation_fraction_( badgeLoc, NSZeroRect, NSCompositeSourceOver, 1.0) badgeLabel = NSString.stringWithString_(u'%d' % self.unwatched_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() threads.call_on_ui_thread(appl.setApplicationIconImage_, badgedIcon)
def show_donate(self, url=None, payment_url=None): if not url: args = [1, 2, 3] try: url = self.donate_url_template % args[self.donate_nothanks] except IndexError: url = self.donate_url_template % args[-1] if not payment_url: args = [7, 8, 9] try: payment_url = (self.payment_url_template % args[self.donate_nothanks]) except IndexError: payment_url = self.payment_url_template % args[-1] if self.donate_window: logging.debug('donate window: callout to frontend') call_on_ui_thread(lambda: self.donate_window.show(url, payment_url))
def make_search_progress(self): if self.cancelled: self.finder = None return try: num_parsed, found = self.finder.next() self.gathered_media_files = found num_found = len(found) num_files = ngettext("parsed %(count)s file", "parsed %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) self.progress_label.set_text(u"%s - %s" % (num_files, num_media_files)) threads.call_on_ui_thread(self.make_search_progress) except StopIteration: num_found = len(self.gathered_media_files) self.search_complete( ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None except Exception: # this is here to get more data for bug #17422 logging.exception("exception thrown in make_search_progress") # we want to clean up after this exception, too. num_found = len(self.gathered_media_files) self.search_complete( ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None
def startup_ui(self): sys.excepthook = self.exception_handler Application.startup_ui(self) call_on_ui_thread(migrateappname.migrateVideos, 'Democracy', 'Miro') call_on_ui_thread(flash.check_flash_install) call_on_ui_thread(bonjour.check_bonjour_install) timer.add(15, self._init_autoupdate)
def change_non_video_displays(self, display): # If the dc exists, cancel it. If the cancel failed because lost # the race to cancel it, then the display will load and some # some redundant code will be scheduled onto the main thread, but # that's okay, since at the next invocation of the delayed call # we shall get the correct display. We use a miro.timer here # rather than tacking onto the UI loop using call_on_ui_thread() # since we can't cancel it. if self.change_non_video_displays_dc: timer.cancel(self.change_non_video_displays_dc) self.change_non_video_displays_dc = None self.change_non_video_displays_dc = timer.add(0.1, lambda: call_on_ui_thread( lambda: self.do_change_non_video_displays(display)))
def _result(): self.done.wait(1) if self.success: # -1 if None, 0 if yes current_video = self.playbin.get_property("current-video") current_audio = self.playbin.get_property("current-audio") if current_video == 0: call_on_ui_thread(success_callback, "video") elif current_audio == 0: call_on_ui_thread(success_callback, "audio") else: call_on_ui_thread(success_callback, "unplayable") else: call_on_ui_thread(error_callback) self.disconnect()
def make_search_progress(self): if self.cancelled: self.finder = None return try: num_parsed, found = self.finder.next() self.gathered_media_files = found num_found = len(found) num_files = ngettext("parsed %(count)s file", "parsed %(count)s files", num_parsed, {"count": num_parsed}) num_media_files = ngettext("found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found}) self.progress_label.set_text(u"%s - %s" % ( num_files, num_media_files)) threads.call_on_ui_thread(self.make_search_progress) except StopIteration: if self.gathered_media_files: num_found = len(self.gathered_media_files) else: num_found = 0 self.search_complete( ngettext( "found %(count)s media file", "found %(count)s media files", num_found, {"count": num_found})) self.finder = None
def startup_ui(self): sys.excepthook = self.exception_handler Application.startup_ui(self) call_on_ui_thread(migrateappname.migrateVideos, 'Democracy', 'Miro') call_on_ui_thread(flash.check_flash_install) call_on_ui_thread(bonjour.check_bonjour_install) if app.config.get(prefs.APP_FINAL_RELEASE) == u"0": # if this is not a final release, look at the beta # channel url = app.config.get(prefs.AUTOUPDATE_BETA_URL) logging.info("Using beta channel") else: # if this is a final release, look at the final # channel url = app.config.get(prefs.AUTOUPDATE_URL) logging.info("Using the final channel") ctypes.cdll.winsparkle.win_sparkle_set_appcast_url( url.encode('ascii', 'ignore')) ctypes.cdll.winsparkle.win_sparkle_set_app_details( unicode(app.config.get(prefs.PUBLISHER)), unicode(app.config.get(prefs.SHORT_APP_NAME)), unicode(app.config.get(prefs.APP_VERSION))) ctypes.cdll.winsparkle.win_sparkle_init()
def __del__(self): call_on_ui_thread( lambda: app.sharing_manager.unregister_interest(self)) widgetset.VBox.__del__(self)
def startup(): threads.call_on_ui_thread(_startup)
def startup_ui(self): sys.excepthook = self.exception_handler Application.startup_ui(self) call_on_ui_thread(bonjour.check_bonjour_install)
def handle_update_available(self, obj, item): call_on_ui_thread(self.show_update_available, item)
def _schedule_indexing(self): if not self._index_pass_scheduled: call_on_ui_thread(self._do_index_pass) self._index_pass_scheduled = True
def unknown_callback(url): call_on_ui_thread(self.handle_unknown_url, url)
def startup_ui(self): Application.startup_ui(self) call_on_ui_thread(migrateappname.migrateVideos, 'Democracy', 'Miro') call_on_ui_thread(flash.check_flash_install)
def unknown_callback(self, url): """ callback to use for unknown URLs""" call_on_ui_thread(self.handle_unknown_url, url)