def __init__(self, app, debugname=None, doeslogging=0, stop_osd=2, callback_use_rc=True): """ Initialise ChildApp2 """ logger.debug('ChildApp2.__init__(app=%r, debugname=%r, doeslogging=%r, stop_osd=%r)', app, debugname, doeslogging, stop_osd) self.timer = kaa.Timer(self.poll) self.timer.start(0.1) rc.register(self.stop, True, rc.SHUTDOWN) self.is_video = 0 # Be more explicit if stop_osd == 2: self.is_video = 1 rc.post_event(Event(VIDEO_START)) stop_osd = config.OSD_STOP_WHEN_PLAYING self.stop_osd = stop_osd if self.stop_osd: osd.stop() if hasattr(self, 'item'): rc.post_event(Event(PLAY_START, arg=self.item)) # return status of the child self.status = 0 # start the child ChildApp.__init__(self, app, debugname, doeslogging, callback_use_rc)
def add_animation(self, anim_object): """ Add an animation to our list """ self.animations.append(anim_object) if len(self.animations) == 1: # first animation, register ourself to the main loop: rc.register(self.update, True, 0)
def show(self): """ used when showing for the first time """ self.player = audio.player.get() rc.register(self.update, True, 10) self.getInfo() self.status = BAR_SHOW
def show(self): """ used when showing for the first time """ _debug_('show(self)', 2) self.player = audio.player.get() if not self.update_registered: rc.register(self.update, True, 10) self.update_registered = True self.getInfo() self.status = BAR_SHOW
def update_wait(self): """ This is used while starting freevo """ if osd._singleton == None: return if self.osd == None: self.osd = osd.get_singleton() rc.unregister(self.update) self.update = self.update_enabled rc.register(self.update, True, 0)
def __init__(self, app, debugname=None, doeslogging=0, stop_osd=2): rc.register(self.poll, True, 10) rc.register(self.stop, True, rc.SHUTDOWN) self.is_video = 0 # Be more explicit if stop_osd == 2: self.is_video = 1 rc.post_event(Event(VIDEO_START)) stop_osd = config.OSD_STOP_WHEN_PLAYING self.stop_osd = stop_osd if self.stop_osd: osd.stop() if hasattr(self, 'item'): rc.post_event(Event(PLAY_START, arg=self.item)) # return status of the child self.status = 0 # start the child ChildApp.__init__(self, app, debugname, doeslogging)
def _handle_input(self): saved = '' while 1: data = self.fp.readline(300) if not data: _debug_( '%s: No data, stopping (pid %s)!' % (self.name, os.getpid()), 2) self.fp.close() if self.logger: self.logger.close() break else: data = data.replace('\r', '\n') lines = data.split('\n') # Only one partial line? if len(lines) == 1: saved += data else: # Combine saved data and first line, send to app if self.logger: self.logger.write(saved + lines[0] + '\n') rc.register(self.callback, False, 0, saved + lines[0]) saved = '' # There's one or more lines + possibly a partial line if lines[-1] != '': # The last line is partial, save it for the next time saved = lines[-1] # Send all lines except the last partial line to the app for line in lines[1:-1]: if self.logger: self.logger.write(line + '\n') rc.register(self.callback, False, 0, line) else: # Send all lines to the app for line in lines[1:]: if self.logger: self.logger.write(line + '\n') rc.register(self.callback, False, 0, line)
print print 'Warning: Freevo cache helper/information updated.' print 'Please rerun \'freevo cache\' to speed up Freevo' print del_cache() elif kaa.metadata.version.VERSION > mmchanged: print print 'Warning: kaa metadata as changed.' print 'Please rerun \'freevo cache\' to get the latest updates' print del_cache() elif (int(time.time()) - part_update) / (3600 * 24) > 7: print print 'Warning: cache is older than 7 days' print 'Running \'freevo cache\' is recommended.' print except: print print 'Error: unable to read kaa metadata version information' print 'Please update kaa.metadata to the latest release or if you use' print 'Freevo svn versions, please also use kaa.metadata svn.' print print 'Some functions in Freevo may not work or even crash!' print print import rc rc.register(check_cache_status, True, 100)
def __load_plugin__(name, type, level, args, number): """ load the plugin and add it to the lists """ import rc global __plugin_type_list__ global __named_plugins__ global __plugin_basedir__ # fallback module = name object = '%s.PluginInterface' % module special = None # locate the plugin: files = [] if not isinstance(name, Plugin): module, special = __find_plugin_file__(name.replace('.', '/')) if module: object = module + '.PluginInterface' elif name.find('.') > 0: module, special = __find_plugin_file__(name[:name.rfind('.')].replace('.', '/')) if module: object = module + '.%s' % name[name.rfind('.')+1:] else: print 'can\'t locate plugin %s' % name print 'start \'freevo plugins -l\' to get a list of plugins' return else: print 'can\'t locate plugin %s' % name print 'start \'freevo plugins -l\' to get a list of plugins' return try: if not isinstance(name, Plugin): if DEBUG: print 'loading %s as plugin %s' % (module, object) exec('import %s' % module) if not args: p = eval(object)() elif isinstance(args, list) or isinstance(args, tuple): paramlist = 'args[0]' for i in range(1, len(args)): paramlist += ',args[%s]' % i p = eval('%s(%s)' % (object, paramlist)) else: p = eval(object)(args) if not hasattr(p, '_type'): if hasattr(p, 'reason'): reason = p.reason else: reason = 'unknown\nThe plugin neither called __init__ nor set a '\ 'reason why\nPlease contact the plugin author or the freevo list' print 'plugin %s deactivated, reason: %s' % (name, reason) return else: p = name p._number = number p._level = level if type: special = type if special == 'main': special = '' elif special: special = '_%s' % special else: special = '' # special plugin type (e.g. idlebar) if p._type: __add_to_ptl__(p._type, p) else: if isinstance(p, DaemonPlugin): __add_to_ptl__('daemon', p) for type in ('poll', 'draw', 'eventhandler', 'shutdown' ): if hasattr(p, type): __add_to_ptl__('daemon_%s' % type, p) if hasattr(p, 'poll'): if p.poll_menu_only: # replace poll with the poll wrapper to handle # poll_menu_only p.real_poll = p.poll p.poll = p.poll_wrapper rc.register(p.poll, True, p.poll_interval) if isinstance(p, MainMenuPlugin): __add_to_ptl__('mainmenu%s' % special, p) if hasattr(p, 'eventhandler'): __add_to_ptl__('daemon_eventhandler', p) if isinstance(p, ItemPlugin): __add_to_ptl__('item%s' % special, p) if isinstance(p, MimetypePlugin): __add_to_ptl__('mimetype', p) if hasattr(p, 'shutdown'): # register shutdown handler rc.register(p.shutdown, True, rc.SHUTDOWN) if p.plugin_name: __named_plugins__[p.plugin_name] = p except: print 'failed to load plugin %s' % name print 'start \'freevo plugins -l\' to get a list of plugins' traceback.print_exc()
def view(self, item, zoom=0, rotation=0): #print 'view(self, item, zoom=%s, rotation=%s)' % (zoom, rotation) if zoom: self.app_mode = 'image_zoom' else: self.app_mode = 'image' filename = item.filename self.fileitem = item self.parent = item.menuw if not self.free_cache in item.menuw.show_callbacks: item.menuw.show_callbacks.append(self.free_cache) self.filename = filename self.rotation = rotation if filename and len(filename) > 0: image = self.osd.loadbitmap(filename, cache=self.bitmapcache) else: # Using Container-Image image = item.loadimage() rc.app(self) if not image: self.osd.clearscreen(color=self.osd.COL_BLACK) self.osd.drawstringframed( _('Can\'t Open Image\n\'%s\'') % Unicode(filename), config.OSD_OVERSCAN_X + 20, config.OSD_OVERSCAN_Y + 20, self.osd.width - 2 * config.OSD_OVERSCAN_X - 40, self.osd.height - 2 * config.OSD_OVERSCAN_Y - 40, self.osd.getfont(config.OSD_DEFAULT_FONTNAME, config.OSD_DEFAULT_FONTSIZE), fgcolor=self.osd.COL_ORANGE, align_h='center', align_v='center', mode='soft') self.osd.update() return width, height = image.get_size() # Bounding box default values bbx = bby = bbw = bbh = 0 if zoom: # Translate the 9-element grid to bounding boxes if self.rotation == 90: bb = { 1: (2, 0), 2: (2, 1), 3: (2, 2), 4: (1, 0), 5: (1, 1), 6: (1, 2), 7: (0, 0), 8: (0, 1), 9: (0, 2) } elif self.rotation == 180: bb = { 1: (2, 2), 2: (1, 2), 3: (0, 2), 4: (2, 1), 5: (1, 1), 6: (0, 1), 7: (2, 0), 8: (1, 0), 9: (0, 0) } elif self.rotation == 270: bb = { 1: (0, 2), 2: (0, 1), 3: (0, 0), 4: (1, 2), 5: (1, 1), 6: (1, 0), 7: (2, 2), 8: (2, 1), 9: (2, 0) } else: bb = { 1: (0, 0), 2: (1, 0), 3: (2, 0), 4: (0, 1), 5: (1, 1), 6: (2, 1), 7: (0, 2), 8: (1, 2), 9: (2, 2) } if isinstance(zoom, int): h, v = bb[zoom] else: h, v = bb[zoom[0]] # Bounding box center bbcx = ([1, 3, 5][h]) * width / 6 bbcy = ([1, 3, 5][v]) * height / 6 if self.rotation % 180: # different calculations because image width is screen height scale_x = float(self.osd.width) / (height / 3) scale_y = float(self.osd.height) / (width / 3) scale = min(scale_x, scale_y) # read comment for the bbw and bbh calculations below bbw = min(max( (width / 3) * scale, self.osd.height), width) / scale bbh = min(max( (height / 3) * scale, self.osd.width), height) / scale else: scale_x = float(self.osd.width) / (width / 3) scale_y = float(self.osd.height) / (height / 3) scale = min(scale_x, scale_y) # the bb width is the width / 3 * scale, to avoid black bars left # and right exapand it to the osd.width but not if this is more than the # image width (same for height) bbw = min(max( (width / 3) * scale, self.osd.width), width) / scale bbh = min(max( (height / 3) * scale, self.osd.height), height) / scale # calculate the beginning of the bounding box bbx = max(0, bbcx - bbw / 2) bby = max(0, bbcy - bbh / 2) if bbx + bbw > width: bbx = width - bbw if bby + bbh > height: bby = height - bbh if self.rotation % 180: new_h, new_w = bbw * scale, bbh * scale else: new_w, new_h = bbw * scale, bbh * scale else: if self.rotation % 180: height, width = width, height # scale_x = scale_y = 1.0 # if width > osd.width: scale_x = float(osd.width) / width # if height > osd.height: scale_y = float(osd.height) / height scale_x = float(self.osd.width) / width scale_y = float(self.osd.height) / height scale = min(scale_x, scale_y) new_w, new_h = int(scale * width), int(scale * height) # Now we have all necessary informations about zoom yes/no and # the kind of rotation x = (self.osd.width - new_w) / 2 y = (self.osd.height - new_h) / 2 last_image = self.last_image[1] if not isinstance(zoom, int): # change zoom based on rotation if self.rotation == 90: zoom = zoom[0], -zoom[2], zoom[1] if self.rotation == 180: zoom = zoom[0], -zoom[1], -zoom[2] if self.rotation == 270: zoom = zoom[0], zoom[2], -zoom[1] # don't move outside the image if bbx + zoom[1] < 0: zoom = zoom[0], -bbx, zoom[2] if bbx + zoom[1] > width - bbw: zoom = zoom[0], width - (bbw + bbx), zoom[2] if bby + zoom[2] < 0: zoom = zoom[0], zoom[1], -bby if bby + zoom[2] > height - bbh: zoom = zoom[0], zoom[1], height - (bbh + bby) # change bbx bbx += zoom[1] bby += zoom[2] if (last_image and self.last_image[0] != item and config.IMAGEVIEWER_BLEND_MODE != None): screen = self.osd.screen.convert() screen.fill((0, 0, 0, 0)) screen.blit( self.osd.zoomsurface(image, scale, bbx, bby, bbw, bbh, rotation=self.rotation).convert(), (x, y)) # update the OSD self.drawosd(layer=screen) blend = Transition(self.osd.screen, screen, config.IMAGEVIEWER_BLEND_MODE) blend.start() while not blend.finished: rc.poll() blend.remove() else: self.osd.clearscreen(color=self.osd.COL_BLACK) self.osd.drawsurface(image, x, y, scale, bbx, bby, bbw, bbh, rotation=self.rotation) # update the OSD self.drawosd() if plugin.getbyname('osd'): plugin.getbyname('osd').draw(('osd', None), self.osd) # draw self.osd.update() # start timer if self.fileitem.duration and self.slideshow and not self.signal_registered: rc.register(self.signalhandler, False, self.fileitem.duration * 100) self.signal_registered = True self.last_image = (item, (image, x, y, scale, bbx, bby, bbw, bbh, self.rotation)) # XXX Hack to move the selected item to the current showing image # XXX TODO: find a way to add it to directory.py or playlist.py if item.parent and hasattr(item.parent, 'menu') and item.parent.menu and \ item in item.parent.menu.choices: item.parent.menu.selected = item item.menuw.force_page_rebuild = True # save zoom, but revert the rotation mix up if not isinstance(zoom, int) and self.rotation: if self.rotation == 90: zoom = zoom[0], zoom[2], -zoom[1] if self.rotation == 180: zoom = zoom[0], -zoom[1], -zoom[2] if self.rotation == 270: zoom = zoom[0], -zoom[2], zoom[1] self.zoom = zoom return None
def eventhandler(self, event, menuw=None): #print 'eventhandler(self, event=%s, menuw=%s)' % (event, menuw) if event == PAUSE or event == PLAY: if self.slideshow: rc.post_event(Event(OSD_MESSAGE, arg=_('pause'))) self.slideshow = False rc.unregister(self.signalhandler) self.signal_registered = False else: rc.post_event(Event(OSD_MESSAGE, arg=_('play'))) self.slideshow = True rc.register(self.signalhandler, False, 100) self.signal_registered = True return True elif event == STOP: self.last_image = None, None self.signal_registered = False rc.unregister(self.signalhandler) rc.app(None) self.fileitem.eventhandler(event) return True # up and down will stop the slideshow and pass the # event to the playlist elif event == PLAYLIST_NEXT or event == PLAYLIST_PREV: self.signal_registered = False rc.unregister(self.signalhandler) self.fileitem.eventhandler(event) return True # rotate image elif event == IMAGE_ROTATE: if event.arg == 'left': self.rotation = (self.rotation + 270) % 360 else: self.rotation = (self.rotation + 90) % 360 self.fileitem['rotation'] = self.rotation self.view(self.fileitem, zoom=self.zoom, rotation=self.rotation) return True # print image information elif event == TOGGLE_OSD: self.osd_mode = (self.osd_mode + 1) % (len(config.IMAGEVIEWER_OSD) + 1) # Redraw self.view(self.fileitem, zoom=self.zoom, rotation=self.rotation) return True # zoom to one third of the image # 1 is upper left, 9 is lower right, 0 zoom off elif str(event) in self.zoom_btns: self.zoom = self.zoom_btns[str(event)] if self.zoom: # Zoom one third of the image, don't load the next # image in the list self.view(self.fileitem, zoom=self.zoom, rotation=self.rotation) else: # Display entire picture, don't load next image in case # the user wants to zoom around some more. self.view(self.fileitem, zoom=0, rotation=self.rotation) return True elif event == IMAGE_MOVE: coord = event.arg if isinstance(self.zoom, int): self.zoom = self.zoom, coord[0], coord[1] else: self.zoom = self.zoom[ 0], self.zoom[1] + coord[0], self.zoom[2] + coord[1] self.view(self.fileitem, zoom=self.zoom, rotation=self.rotation) return True # save the image with the current rotation elif event == IMAGE_SAVE: if self.rotation and os.path.splitext(self.filename)[1] == ".jpg": cmd = 'jpegtran -copy all -rotate %s -outfile /tmp/freevo-iview %s' \ % ((self.rotation + 180) % 360, self.filename) os.system(cmd) os.system('mv /tmp/freevo-iview %s' % self.filename) self.rotation = 0 self.osd.bitmapcache.__delitem__(self.filename) return True else: return self.fileitem.eventhandler(event)