Beispiel #1
0
	def handle_active(self):
		print "Jukebox thread activating"
		thread.start_new_thread(self.ticker, ())
		self.lastKeyTime = time()
		self.idleCount = 0
		self.confirmExit = False
		self.isScreenSaverActive = False
		self.msgbox = None
		
		self.myimages = Images(self)
		self.myfonts = Fonts(self)
		
		self.stack = []

		self.root.set_resource(self.myimages.Background)
		self.TitleView = View(self, height=30, width=screenWidth, ypos=titleYPos, parent=self.root)
		self.SubTitleView= View(self, height=20, width=screenWidth, ypos=subTitleYPos, parent=self.root)
		self.MessageView= View(self, height=40, width=screenWidth, ypos=messageYPos, parent=self.root)
		
		self.menuTitle = "Main Menu"

		self.TitleView.set_text(TITLE, font=self.myfonts.fnt30, colornum=0xffffff, flags=RSRC_VALIGN_BOTTOM)
		self.setSubTitle(self.menuTitle)

		self.menuMode = MODE_MAIN_MENU
		self.mm = MenuMgr(self)
		self.detMgr = DetailMgr(self)
		self.NPPlaylist = PlayList("Now Playing")

		self.plMgr = PlaylistMgr(self, skin=opts['skin'])
		self.iterMode = ITER_MODE_ALBUM
		
		self.setPrefs = SetPrefs(self, config)
		
		self.nowPlaying = NowPlaying(self)
		
		self.lyricView = LyricView(self)

		self.DJ = DJ(self, opts)

		nSong, nAlbum, nAlbumArtist, nTrackArtist = self.sdb.count()
		mainMenu.setCount(CHOICE_ALBUM_ARTIST, nAlbumArtist)		
		mainMenu.setCount(CHOICE_TRACK_ARTIST, nTrackArtist)		
		mainMenu.setCount(CHOICE_ALBUM, nAlbum)		
		mainMenu.setCount(CHOICE_TRACK, nSong)	
		
		self.updateMenus(False)	
		
		self.currentArtist = None
		self.currentAlbum = None
		self.currentTrack = None
		
		self.currentMenu, self.currentItem = self.mm.Descend(mainMenu)
		
		# screen saver needs to be last so it is on top
		self.vwScreenSaver = View(self, visible=True, transparency=1, colornum=0, parent=self.root)
		self.vwScreenSaverArt1 = View(self.app, height=artHeight, width=artWidth, ypos=0, xpos=0, parent=self.vwScreenSaver)
		self.vwScreenSaverArt1.set_transparency(1)
		self.vwScreenSaverArt2 = View(self.app, height=artHeight, width=artWidth, ypos=0, xpos=0, parent=self.vwScreenSaver)
		self.vwScreenSaverArt2.set_transparency(1)
		self.ssActiveFrame = 1
		self.vwScreenSaverText = View(self.app, height=40, width=screenWidth, ypos=screenHeight/2, xpos=0, parent=self.vwScreenSaver)
		self.vwScreenSaverText.set_transparency(1)
		self.setScreenSaverArt(None)
Beispiel #2
0
    def __init__(self):

        # the current mode
        self.__mode = _MODE_NORMAL

        # list of available dialog windows
        self.__dialogs = []

        self.__widgets = []

        # the file that is currently playing
        self.__current_file = None

        # list of files for playing
        self.__play_folder = None
        self.__play_files = []

        # list for choosing random files from when in shuffle mode
        self.__random_files = []

        # current window size (for detecting resizing)
        self.__window_size = (0, 0)

        self.__is_searching = False
        self.__filter_term = ""

        self.__key_hold_down_timestamp = 0
        self.__skip_letter = False

        # scheduler for creating thumbnails one by one
        self.__tn_scheduler = ItemScheduler()

        # whether we are shutting down
        self.__is_shutdown = False

        Component.__init__(self)
        Window.__init__(self, Window.TYPE_TOPLEVEL)
        self.set_flag(windowflags.CATCH_VOLUME_KEYS, True)
        self.connect_key_pressed(self.__on_key_press)
        self.connect_closed(self.__on_close_window)

        # [Now Playing] button
        self.__now_playing = NowPlaying()
        #self.__now_playing.set_visible(False)

        # file browser
        self.__browser = StorageBrowser()
        #self.__browser.set_root_device(self.__root_dev)
        self.__browser.connect_folder_begin(self.__on_begin_folder)
        self.__browser.connect_folder_progress(self.__on_progress_folder)
        self.__browser.connect_folder_complete(self.__on_complete_folder)
        self.__browser.connect_file_opened(self.__on_open_file)
        self.__browser.connect_item_shifted(self.__on_shift_item)

        # toolbar
        self.__toolbar = Toolbar()

        self.__btn_home = ToolbarButton(theme.mb_btn_home_1)
        self.__btn_home.connect_clicked(self.__on_btn_home)

        self.__btn_history = ToolbarButton(theme.mb_btn_history_1)
        self.__btn_history.connect_clicked(self.__on_btn_history)

        self.__btn_bookmarks = ToolbarButton(theme.mb_btn_bookmark_1)
        self.__btn_bookmarks.connect_clicked(self.__on_btn_bookmarks)

        self.__btn_back = ToolbarButton(theme.mb_btn_dir_up_1)
        self.__btn_back.connect_clicked(self.__on_btn_back)

        self.__btn_select_all = ToolbarButton(theme.mb_btn_select_all_1)
        self.__btn_select_all.connect_clicked(self.__on_btn_select_all)

        self.__btn_select_none = ToolbarButton(theme.mb_btn_select_none_1)
        self.__btn_select_none.connect_clicked(self.__on_btn_select_none)

        self.__btn_select_done = ToolbarButton(theme.mb_btn_select_done_1)
        self.__btn_select_done.connect_clicked(self.__on_btn_select_done)

        # arrangement
        self.__arr = Arrangement()
        self.__arr.connect_resized(self.__update_layout)
        self.__arr.add(self.__now_playing, "now-playing")
        self.__arr.add(self.__browser, "browser")
        self.__arr.add(self.__toolbar, "toolbar")
        self.add(self.__arr)
        self.__arr.set_visible(False)

        # we have to fill the menu with content before showing the window on
        # Maemo5 or the window will show no menu at all
        self.__update_menu()

        self.set_visible(True)
Beispiel #3
0
class Jukebox(Application):
	def handle_resolution(self):
		for (hres, vres, x, y) in self.resolutions:
			if (hres == 1280):
				return (hres, vres, x, y)
			
		print "NO HD resolutions found!!!"
		self.active = False
		return self.resolutions[0]
	
	def handle_error(self, code, text):
		print "Got an error event, text = (%s)" % text
		print "Error code = ", code

	def startup(self):
		print "Jukebox thread entering startup"
		self.opts = opts
		self.idleCount = 0
		if opts['preloadcache']:
			self.sdb = sdb
		else:
			self.sdb = SongDB(CACHEFILE, opts).getDBHandler()
		
	def ticker(self):
		while self.active:
			self.sleep(TICKER_INTERVAL)
			self.send_key(KEY_TIVO, TIMER)
			
	def sound(self, id=None):
		if not self.nowPlaying.isPlaying():
			Application.sound(self, id)
			
	def cleanup(self):
		if not self.opts['preloadcache']:
			self.sdb.release()
			self.sdb = None
			
		if self.nowPlaying.isActive():
			self.nowPlaying.cleanup()
			
	def handle_idle(self, flag):
		if self.nowPlaying.isActive() or self.opts['ignoreidle']:
			self.idleCount = 0
			return True
		else:
			self.idleCount += 1
			if self.idleCount >= 2:
				return False
			else:
				return True
		
	def handle_active(self):
		print "Jukebox thread activating"
		thread.start_new_thread(self.ticker, ())
		self.lastKeyTime = time()
		self.idleCount = 0
		self.confirmExit = False
		self.isScreenSaverActive = False
		self.msgbox = None
		
		self.myimages = Images(self)
		self.myfonts = Fonts(self)
		
		self.stack = []

		self.root.set_resource(self.myimages.Background)
		self.TitleView = View(self, height=30, width=screenWidth, ypos=titleYPos, parent=self.root)
		self.SubTitleView= View(self, height=20, width=screenWidth, ypos=subTitleYPos, parent=self.root)
		self.MessageView= View(self, height=40, width=screenWidth, ypos=messageYPos, parent=self.root)
		
		self.menuTitle = "Main Menu"

		self.TitleView.set_text(TITLE, font=self.myfonts.fnt30, colornum=0xffffff, flags=RSRC_VALIGN_BOTTOM)
		self.setSubTitle(self.menuTitle)

		self.menuMode = MODE_MAIN_MENU
		self.mm = MenuMgr(self)
		self.detMgr = DetailMgr(self)
		self.NPPlaylist = PlayList("Now Playing")

		self.plMgr = PlaylistMgr(self, skin=opts['skin'])
		self.iterMode = ITER_MODE_ALBUM
		
		self.setPrefs = SetPrefs(self, config)
		
		self.nowPlaying = NowPlaying(self)
		
		self.lyricView = LyricView(self)

		self.DJ = DJ(self, opts)

		nSong, nAlbum, nAlbumArtist, nTrackArtist = self.sdb.count()
		mainMenu.setCount(CHOICE_ALBUM_ARTIST, nAlbumArtist)		
		mainMenu.setCount(CHOICE_TRACK_ARTIST, nTrackArtist)		
		mainMenu.setCount(CHOICE_ALBUM, nAlbum)		
		mainMenu.setCount(CHOICE_TRACK, nSong)	
		
		self.updateMenus(False)	
		
		self.currentArtist = None
		self.currentAlbum = None
		self.currentTrack = None
		
		self.currentMenu, self.currentItem = self.mm.Descend(mainMenu)
		
		# screen saver needs to be last so it is on top
		self.vwScreenSaver = View(self, visible=True, transparency=1, colornum=0, parent=self.root)
		self.vwScreenSaverArt1 = View(self.app, height=artHeight, width=artWidth, ypos=0, xpos=0, parent=self.vwScreenSaver)
		self.vwScreenSaverArt1.set_transparency(1)
		self.vwScreenSaverArt2 = View(self.app, height=artHeight, width=artWidth, ypos=0, xpos=0, parent=self.vwScreenSaver)
		self.vwScreenSaverArt2.set_transparency(1)
		self.ssActiveFrame = 1
		self.vwScreenSaverText = View(self.app, height=40, width=screenWidth, ypos=screenHeight/2, xpos=0, parent=self.vwScreenSaver)
		self.vwScreenSaverText.set_transparency(1)
		self.setScreenSaverArt(None)
		
	def setScreenSaverArt(self, art, track=None, album=None):
		if art == None:
			art = self.myimages.Icon
		else:
			text = ""
			if track != None:
				text += track.getTitle()
				
			if album:
				text += " / " + album.getAlbumName() + " / " + album.getArtistName()
				
			self.vwScreenSaverText.set_text(text, font=self.myfonts.fnt30, colornum=0xffffff)
			self.vwScreenSaverText.set_transparency(0)
			self.vwScreenSaverText.set_transparency(1, animation=Animation(self, 8.0))
			
		if self.ssActiveFrame == 1:
			self.vwScreenSaverArt2.set_resource(art, flags=RSRC_VALIGN_TOP+RSRC_HALIGN_LEFT)
			self.vwScreenSaverArt2.set_transparency(0, animation=Animation(self, 2.0))
			self.vwScreenSaverArt1.set_transparency(1, animation=Animation(self, 2.0))
			self.ssActiveFrame = 2
		else:
			self.vwScreenSaverArt1.set_resource(art, flags=RSRC_VALIGN_TOP+RSRC_HALIGN_LEFT)
			self.vwScreenSaverArt1.set_transparency(0, animation=Animation(self, 2.0))
			self.vwScreenSaverArt2.set_transparency(1, animation=Animation(self, 2.0))
			self.ssActiveFrame = 1
		
	def activateScreenSaver(self, flag):
		if flag:
			if self.isScreenSaverActive: return
			self.isScreenSaverActive = True
			self.vwScreenSaverArt1.set_bounds(xpos = 0, ypos = 0)
			self.vwScreenSaverArt2.set_bounds(xpos = 0, ypos = 0)
			self.ssDirection = 1
			self.vwScreenSaver.set_transparency(0, animation=Animation(self, 0.75))
			y = int(random.choice(range(screenHeight-artHeight)))
			self.vwScreenSaverArt1.set_bounds(xpos = (screenWidth - artWidth), ypos = y, animtime = TICKER_INTERVAL)
			self.vwScreenSaverArt2.set_bounds(xpos = (screenWidth - artWidth), ypos = y, animtime = TICKER_INTERVAL)
			
		else:
			if not self.isScreenSaverActive: return
			self.isScreenSaverActive = False
			self.vwScreenSaver.set_transparency(1, animation=Animation(self, 0.75))

	def screenSaverSwitch(self):
		y = int(random.choice(range(screenHeight-artHeight)))
		if self.ssDirection == -1:
			self.ssDirection = 1
			self.vwScreenSaverArt1.set_bounds(xpos = (screenWidth - artWidth), ypos = y, animtime = TICKER_INTERVAL)
			self.vwScreenSaverArt2.set_bounds(xpos = (screenWidth - artWidth), ypos = y, animtime = TICKER_INTERVAL)
		else:
			self.ssDirection = -1
			self.vwScreenSaverArt1.set_bounds(xpos = 0, ypos = y, animtime = TICKER_INTERVAL)
			self.vwScreenSaverArt2.set_bounds(xpos = 0, ypos = y, animtime = TICKER_INTERVAL)

	def setSubTitle(self, text):
		self.SubTitleView.set_text(text, font=self.myfonts.fnt20, colornum=0xffffff, flags=RSRC_VALIGN_BOTTOM)
		
	def setMessage(self, text):
		self.MessageView.set_text(text, font=self.myfonts.fnt20, colornum=0xffffff, flags=RSRC_VALIGN_BOTTOM + RSRC_HALIGN_CENTER)
		
	def updateMenus(self, flag):
		# nowplaying status has changed - update the menus accordingly
		mainMenu.setActive(CHOICE_NOWPLAYING, flag)
		self.mm.RefreshMenu(mainMenu)
		
	def addToNowPlaying(self, clear=False, album=None, artist=None, song=None, playlist=None):
		if clear:
			self.NPPlaylist.clear()
			
		if song:
			self.NPPlaylist.addSong(song)
			
		if album:
			for s in album:
				self.NPPlaylist.addSong(s)
			
		if playlist:
			for s in playlist:
				self.NPPlaylist.addSong(s)
				
		if artist:
			for s in artist:
				self.NPPlaylist.addSong(s)
		
		self.nowPlaying.addToNowPlaying(album=album, artist=artist, song=song, playlist=playlist)
		
	def showLyrics(self, song):
		self.lyricView.loadLyrics(song)
			
	def handle_key_press(self, keynum, rawcode):
		if keynum in ignoreKeys:
			return
		
		if keynum != KEY_TIVO:
			self.lastKeyTime = time()
			
		if keynum != KEY_THUMBSUP and self.confirmExit:
			self.setMessage('')
			self.confirmExit = False
			
		if keynum == KEY_TIVO and rawcode == TIMER:
			if self.isScreenSaverActive:
				self.screenSaverSwitch()

			now = time()
			idleTime = now - self.lastKeyTime
			
			if opts['autoswitchnp'] != 0 and idleTime > opts['autoswitchnp']:
				if self.nowPlaying.isActive() and not self.nowPlaying.isShowing():
					self.nowPlaying.show()
					
			if opts['screensaver'] != 0 and idleTime > opts['screensaver']:
				if not self.isScreenSaverActive:
					self.activateScreenSaver(True)
				
			return
				
		if keynum != KEY_TIVO and self.isScreenSaverActive:
			self.activateScreenSaver(False)
			return
		
		if self.msgbox:
			self.msgbox.handle_key_press(keynum, rawcode)
		
		elif keynum == KEY_TIVO and self.DJ.isActive():
			self.DJ.handle_key_press(keynum, rawcode)
			
		elif self.lyricView.isShowing():
			self.lyricView.handle_key_press(keynum, rawcode)
			
		elif self.nowPlaying.isShowing():
			self.nowPlaying.handle_key_press(keynum, rawcode)
			
		elif self.plMgr.isActive():
			self.plMgr.handle_key_press(keynum, rawcode)
		
		elif self.DJ.isActive():
			self.DJ.handle_key_press(keynum, rawcode)
		
		elif self.setPrefs.isActive():
			self.setPrefs.handle_key_press(keynum, rawcode)
		
		elif self.mm.isNavKey(keynum, rawcode):
			self.currentMenu, self.currentItem = self.mm.Navigate(keynum, rawcode)
			
		elif keynum == KEY_TIVO:
			if rawcode == PLM_DONE:
				self.setSubTitle(self.menuTitle)
				self.mm.RefreshMenu(None)
				self.sdb.setIterMode(self.iterMode)
			elif rawcode == DJ_DONE:
				self.setSubTitle(self.menuTitle)
				self.mm.RefreshMenu(None)
				self.sdb.setIterMode(self.iterMode)
			
		elif keynum in [ KEY_LEFT, KEY_THUMBSUP ]:
			if keynum == KEY_LEFT and self.mm.atRoot() and self.nowPlaying.isActive():
				self.setMessage('Press THUMBS-UP to confirm exit while music is playing')
				self.sound('alert')
				self.confirmExit = True
				return
			
			if keynum == KEY_THUMBSUP and not self.confirmExit:
				self.sound('bonk')
				return
			
			self.currentMenu, self.currentItem = self.mm.Ascend()
			if self.currentMenu == None:
				self.active = False
				return
			self.menuMode, self.menuTitle, self.iterMode = self.stack.pop()
			self.setSubTitle(self.menuTitle)
			self.sdb.setIterMode(self.iterMode)
			self.sound('updown')
			
		else:
			if self.menuMode == MODE_MAIN_MENU:
				self.handleKeyMainMenu(keynum, rawcode)
			
			elif self.menuMode == MODE_ALBUM_ARTIST:
				self.handleKeyAlbumArtist(keynum, rawcode)
				
			elif self.menuMode == MODE_ALBUM_ARTIST_ALBUM:
				self.handleKeyAlbumArtistAlbum(keynum, rawcode)
				
			elif self.menuMode == MODE_ALBUM_ARTIST_ALBUM_TRACK:
				self.handleKeyAlbumArtistAlbumTrack(keynum, rawcode)
				
			elif self.menuMode == MODE_ALBUM_ARTIST_ALBUM_TRACK_CHOICES:
				self.handleKeyAlbumArtistAlbumTrackChoices(keynum, rawcode)
				
			elif self.menuMode == MODE_ALBUM:
				self.handleKeyAlbum(keynum, rawcode)
			
			elif self.menuMode == MODE_ALBUM_TRACK:
				self.handleKeyAlbumTrack(keynum, rawcode)
				
			elif self.menuMode == MODE_ALBUM_TRACK_CHOICES:
				self.handleKeyAlbumTrackChoices(keynum, rawcode)
				
			elif self.menuMode == MODE_TRACK_ARTIST:
				self.handleKeyTrackArtist(keynum, rawcode)
				
			elif self.menuMode == MODE_TRACK_ARTIST_TRACK:
				self.handleKeyTrackArtistTrack(keynum, rawcode)
				
			elif self.menuMode == MODE_TRACK_ARTIST_TRACK_CHOICES:
				self.handleKeyTrackArtistTrackChoices(keynum, rawcode)
				
			elif self.menuMode == MODE_TRACK:
				self.handleKeyTrack(keynum, rawcode)
				
			elif self.menuMode == MODE_TRACK_CHOICES:
				self.handleKeyTrackChoices(keynum, rawcode)
				
			else:
				self.sound('bonk')
				return
			
		self.setCurrentInfo()
		self.showDetails()
			
	def handleKeyMainMenu(self, keynum, rawcode):
		value = self.currentMenu.getMenuValue(self.currentItem)
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			if value == CHOICE_ALBUM_ARTIST:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				menu = self.sdb.getAlbumArtistList()
				self.menuMode = MODE_ALBUM_ARTIST
				self.iterMode = ITER_MODE_ALBUM
				self.sdb.setIterMode(self.iterMode)
				self.menuTitle = "Album Artists"
				self.setSubTitle(self.menuTitle)
				self.currentMenu, self.currentItem = self.mm.Descend(menu)
	
			elif value == CHOICE_ALBUM:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				menu = self.sdb.getAlbumList()
				self.menuMode = MODE_ALBUM
				self.iterMode = ITER_MODE_ALBUM
				self.sdb.setIterMode(self.iterMode)
				self.menuTitle = "All Albums"
				self.setSubTitle(self.menuTitle)
				self.currentMenu, self.currentItem = self.mm.Descend(menu, offset=8)
	
			elif value == CHOICE_TRACK_ARTIST:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				menu = self.sdb.getTrackArtistList()
				self.menuMode = MODE_TRACK_ARTIST
				self.iterMode = ITER_MODE_SONG
				self.sdb.setIterMode(self.iterMode)
				self.menuTitle = "Track Artists"
				self.setSubTitle(self.menuTitle)
				self.currentMenu, self.currentItem = self.mm.Descend(menu)
	
			elif value == CHOICE_TRACK:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				menu = self.sdb
				self.menuMode = MODE_TRACK
				self.iterMode = ITER_MODE_SONG
				self.sdb.setIterMode(self.iterMode)
				self.menuTitle = "Tracks"
				self.setSubTitle(self.menuTitle)
				self.currentMenu, self.currentItem = self.mm.Descend(menu, offset=8)
	
			elif value == CHOICE_PLAYLIST:
				self.setSubTitle("Choose Playlist")
				self.plMgr.activate(done = PLM_DONE)
				
			elif value == CHOICE_PREFS:
				self.setPrefs.show()
			
			elif value == CHOICE_DJ:
				self.DJ.show(done = DJ_DONE)
			
			elif value == CHOICE_NOWPLAYING:
				if self.nowPlaying.isActive():
					self.nowPlaying.show()
			
			else:
				print "Received an unknown menu choice:", value
				self.sound('bonk')
				return
			self.sound('updown')
		
		elif keynum == KEY_ENTER:
			if value == CHOICE_NOWPLAYING:
				t = "Choose Playlist - adding %d Tracks from Now Playing list" % len(self.NPPlaylist)
				self.setSubTitle(t)	
				self.plMgr.activate(done = PLM_DONE, selectonly = True, playlist = self.NPPlaylist)
				self.sound('updown')
			
			else:
				self.sound('bonk')
				
		elif keynum == KEY_PLAY:
			if value != CHOICE_TRACK:
				self.sound('bonk')
			else:
				self.NPPlaylist.clear()
				for s in self.sdb:
					self.NPPlaylist.addSong(s)
					
				self.nowPlaying.Play(self.NPPlaylist,
									shuffle=opts['trackshuffle'],
									loop=opts['trackloop'])
				
		else:
			self.sound('bonk')
			
	def handleKeyAlbumArtist(self, keynum, rawcode):
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			self.currentArtist = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentArtist == None:
				self.sound('bonk')
			else:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				self.menuMode = MODE_ALBUM_ARTIST_ALBUM
				self.menuTitle = "Albums by " + self.currentArtist.getArtistName()
				self.setSubTitle(self.menuTitle)
				self.iterMode = ITER_MODE_ALBUM
				self.sdb.setIterMode(self.iterMode)
				self.currentMenu, self.currentItem = self.mm.Descend(self.currentArtist, offset=8)
				self.sound('updown')
			
		else:
			self.sound('bonk')
			
	def handleKeyAlbumArtistAlbum(self, keynum, rawcode):
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			self.currentAlbum = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentAlbum == None:
				self.sound('bonk')
			else:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				self.menuMode = MODE_ALBUM_ARTIST_ALBUM_TRACK
				self.menuTitle = ("Tracks on " + self.currentAlbum.getArtist().getArtistName() +
							" / " + self.currentAlbum.getAlbumName())
				self.setSubTitle(self.menuTitle)
				self.iterMode = ITER_MODE_ALBUM
				self.sdb.setIterMode(self.iterMode)
				self.currentMenu, self.currentItem = self.mm.Descend(self.currentAlbum, offset=8)
				self.sound('updown')
			
		elif keynum == KEY_ENTER:
			self.currentAlbum = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentAlbum == None:
				self.sound('bonk')
			else:	
				t = "Choose Playlist - adding %d Tracks on from %s / %s" % (len(self.currentAlbum),
					self.currentAlbum.getArtist().getArtistName(),
					self.currentAlbum.getAlbumName())
				self.setSubTitle(t)	
				self.plMgr.activate(done = PLM_DONE, album = self.currentAlbum)
				self.sound('updown')
			
		elif keynum == KEY_PLAY:
			self.currentAlbum = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentAlbum == None:
				self.sound('bonk')
			else:
				self.NPPlaylist.clear()
				for s in self.currentAlbum:
					self.NPPlaylist.addSong(s)
					
				self.nowPlaying.Play(self.NPPlaylist,
									shuffle=opts['albumshuffle'],
									loop=opts['albumloop'])
			
		else:
			self.sound('bonk')
	
	def handleKeyAlbumArtistAlbumTrack(self, keynum, rawcode):
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			else:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				self.menuMode = MODE_ALBUM_ARTIST_ALBUM_TRACK_CHOICES
				self.menuTitle = ""
				self.setSubTitle(self.menuTitle)
				self.iterMode = ITER_MODE_ALBUM
				self.sdb.setIterMode(self.iterMode)
				self.currentMenu, self.currentItem = self.mm.Descend(albumTrackMenu, offset=8)
				self.sound('updown')
			
		elif keynum == KEY_INFO:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.app.sound('bonk')
			else:
				self.app.showLyrics(self.currentTrack)
				self.app.sound('updown')
				
		elif keynum == KEY_PLAY:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			else:
				self.NPPlaylist.clear()
				self.NPPlaylist.addSong(self.currentTrack)
				self.nowPlaying.Play(self.NPPlaylist)

				self.sound('updown')
			
		elif keynum == KEY_ENTER:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentArtist == None or self.currentTrack == None:
				self.sound('bonk')
			else:
				t = ("Choose Playlist - adding Track %s / %s" 
					% (self.currentArtist.getArtistName(), self.currentTrack.getTitle()))
				self.setSubTitle(t)	
				self.plMgr.activate(done = PLM_DONE, song = self.currentTrack)
				self.sound('updown')
			
		else:
			self.sound('bonk')
							
	def handleKeyAlbumArtistAlbumTrackChoices(self, keynum, rawcode):
		value = self.currentMenu.getMenuValue(self.currentItem)
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			if value == CHOICE_PLAY_TRACK:
				if self.currentTrack == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					self.NPPlaylist.addSong(self.currentTrack)
					self.nowPlaying.Play(self.NPPlaylist)

					self.sound('updown')
					
			elif value == CHOICE_PLAY_ALBUM:
				if self.currentAlbum == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					for s in self.currentAlbum:
						self.NPPlaylist.addSong(s)
						
					self.nowPlaying.Play(self.NPPlaylist,
										shuffle=opts['albumshuffle'],
										loop=opts['albumloop'])

					self.sound('updown')

			elif value == CHOICE_PLAY_ALBUM_TRACK:
				if self.currentAlbum == None or self.currentTrack == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					for s in self.currentAlbum:
						self.NPPlaylist.addSong(s)
						
					self.nowPlaying.Play(self.NPPlaylist, first=self.currentTrack,
										shuffle=opts['albumshuffle'],
										loop=opts['albumloop'])

					self.sound('updown')
				
			elif value == CHOICE_SONG_PLAYLIST:
				if self.currentArtist == None or self.currentTrack == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Track %s / %s" 
						% (self.currentArtist.getArtistName(), self.currentTrack.getTitle()))
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, song = self.currentTrack)
					self.sound('updown')
					
			elif value == CHOICE_ALBUM_PLAYLIST:
				if self.currentAlbum == None or self.currentArtist == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Album %s / %s" 
						% (self.currentArtist.getArtistName(), self.currentAlbum.getAlbumName()))
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, album = self.currentAlbum)
					self.sound('updown')
					
					
		elif keynum == KEY_INFO:
			if self.currentTrack == None:
				self.app.sound('bonk')
			else:
				self.app.showLyrics(self.currentTrack)
				self.app.sound('updown')
				
		else:
			self.sound('bonk')
					
	def handleKeyAlbum(self, keynum, rawcode):
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			self.currentAlbum = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentAlbum == None:
				self.sound('bonk')
			else:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				self.menuMode = MODE_ALBUM_TRACK
				self.menuTitle = ("Tracks on " + self.currentAlbum.getArtist().getArtistName() +
							" / " + self.currentAlbum.getAlbumName())
				self.setSubTitle(self.menuTitle)
				self.iterMode = ITER_MODE_ALBUM
				self.sdb.setIterMode(self.iterMode)
				self.currentMenu, self.currentItem = self.mm.Descend(self.currentAlbum, offset=8)
				self.sound('updown')
			
		elif keynum == KEY_ENTER:
			self.currentAlbum = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentAlbum == None:
				self.sound('bonk')
			else:	
				t = "Choose Playlist - adding %d Tracks on from %s / %s" % (len(self.currentAlbum),
					self.currentAlbum.getArtist().getArtistName(),
					self.currentAlbum.getAlbumName())
				self.setSubTitle(t)	
				self.plMgr.activate(done = PLM_DONE, album = self.currentAlbum)
				self.sound('updown')
			
		elif keynum == KEY_PLAY:
			self.currentAlbum = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentAlbum == None:
				self.sound('bonk')
			else:
				self.NPPlaylist.clear()
				for s in self.currentAlbum:
					self.NPPlaylist.addSong(s)
					
				self.nowPlaying.Play(self.NPPlaylist,
										shuffle=opts['albumshuffle'],
										loop=opts['albumloop'])
			
		else:
			self.sound('bonk')

	def handleKeyAlbumTrack(self, keynum, rawcode):
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			else:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				self.menuMode = MODE_ALBUM_TRACK_CHOICES
				self.menuTitle = ""
				self.setSubTitle(self.menuTitle)
				self.iterMode = ITER_MODE_ALBUM
				self.sdb.setIterMode(self.iterMode)
				self.currentMenu, self.currentItem = self.mm.Descend(albumTrackMenu, offset=8)
				self.sound('updown')
			
		elif keynum == KEY_PLAY:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			else:
				self.NPPlaylist.clear()
				self.NPPlaylist.addSong(self.currentTrack)
				self.nowPlaying.Play(self.NPPlaylist)

				self.sound('updown')
					
		elif keynum == KEY_INFO:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.app.sound('bonk')
			else:
				self.app.showLyrics(self.currentTrack)
				self.app.sound('updown')

		elif keynum == KEY_ENTER:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			self.currentArtist = self.currentTrack.getArtist()
			if self.currentArtist == None or self.currentTrack == None:
				self.sound('bonk')
			else:
				t = ("Choose Playlist - adding Track %s / %s" 
					% (self.currentArtist.getArtistName(), self.currentTrack.getTitle()))
				self.setSubTitle(t)	
				self.plMgr.activate(done = PLM_DONE, song = self.currentTrack)
				self.sound('updown')
			
		else:
			self.sound('bonk')
			
	def handleKeyAlbumTrackChoices(self, keynum, rawcode):
		value = self.currentMenu.getMenuValue(self.currentItem)
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			if value == CHOICE_PLAY_TRACK:
				if self.currentTrack == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					self.NPPlaylist.addSong(self.currentTrack)
					self.nowPlaying.Play(self.NPPlaylist)

					self.sound('updown')

			elif value == CHOICE_PLAY_ALBUM:
				if self.currentAlbum == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					for s in self.currentAlbum:
						self.NPPlaylist.addSong(s)
						
					self.nowPlaying.Play(self.NPPlaylist,
										shuffle=opts['albumshuffle'],
										loop=opts['albumloop'])

					self.sound('updown')

			elif value == CHOICE_PLAY_ALBUM_TRACK:
				if self.currentAlbum == None or self.currentTrack == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					for s in self.currentAlbum:
						self.NPPlaylist.addSong(s)
						
					self.nowPlaying.Play(self.NPPlaylist, first=self.currentTrack,
										shuffle=opts['albumshuffle'],
										loop=opts['albumloop'])

					self.sound('updown')
				
			elif value == CHOICE_SONG_PLAYLIST:
				self.currentArtist = self.currentTrack.getArtist()
				if self.currentArtist == None or self.currentTrack == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Track %s / %s" 
						% (self.currentArtist.getArtistName(), self.currentTrack.getTitle()))
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, song = self.currentTrack)
					self.sound('updown')
					
			elif value == CHOICE_ALBUM_PLAYLIST:
				if self.currentAlbum == None or self.currentArtist == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Album %s / %s" 
						% (self.currentArtist.getArtistName(), self.currentAlbum.getAlbumName()))
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, album = self.currentAlbum)
					self.sound('updown')
			
		elif keynum == KEY_INFO:
			if self.currentTrack == None:
				self.app.sound('bonk')
			else:
				self.app.showLyrics(self.currentTrack)
				self.app.sound('updown')

		else:
			self.sound('bonk')
		
	def handleKeyTrackArtist(self, keynum, rawcode):
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			self.currentArtist = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentArtist == None:
				self.sound('bonk')
			else:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				self.menuMode = MODE_TRACK_ARTIST_TRACK
				self.menuTitle = "Individual Songs by " + self.currentArtist.getArtistName()
				self.setSubTitle(self.menuTitle)
				self.iterMode = ITER_MODE_SONG
				self.sdb.setIterMode(self.iterMode)
				self.currentMenu, self.currentItem = self.mm.Descend(self.currentArtist, offset=8)
				self.sound('updown')
			
		elif keynum == KEY_ENTER:
			self.currentArtist = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentArtist == None:
				self.sound('bonk')
			else:
				t = "Choose Playlist - adding %d songs by %s" %(len(self.currentArtist),
						self.currentArtist.getArtistName())				
				self.setSubTitle(t)	
				self.plMgr.activate(done = PLM_DONE, artist = self.currentArtist)
				self.sound('updown')
			
		elif keynum == KEY_PLAY:
			self.currentArtist = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentArtist == None:
				self.sound('bonk')
			else:
				self.NPPlaylist.clear()
				for s in self.currentArtist:
					self.NPPlaylist.addSong(s)
				self.nowPlaying.Play(self.NPPlaylist,
										shuffle=opts['artistshuffle'],
										loop=opts['artistloop'])
			
		else:
			self.sound('bonk')
			
	def handleKeyTrackArtistTrack(self, keynum, rawcode):
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			else:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				self.menuMode = MODE_TRACK_ARTIST_TRACK_CHOICES
				self.menuTitle = ""
				self.setSubTitle(self.menuTitle)
				self.iterMode = ITER_MODE_SONG
				self.sdb.setIterMode(self.iterMode)
				self.currentMenu, self.currentItem = self.mm.Descend(artistTrackMenu, offset=8)
				self.sound('updown')
			
		elif keynum == KEY_PLAY:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			else:
				self.NPPlaylist.clear()
				self.NPPlaylist.addSong(self.currentTrack)
				self.nowPlaying.Play(self.NPPlaylist)
			
		elif keynum == KEY_INFO:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.app.sound('bonk')
			else:
				self.app.showLyrics(self.currentTrack)
				self.app.sound('updown')

		elif keynum == KEY_ENTER:
			if self.currentArtist == None or self.currentTrack == None:
				self.sound('bonk')
			else:
				t = ("Choose Playlist - adding Track %s / %s" 
					% (self.currentArtist.getArtistName(), self.currentTrack.getTitle()))
				self.setSubTitle(t)	
				self.plMgr.activate(done = PLM_DONE, song = self.currentTrack)
				self.sound('updown')
		
		else:
			self.sound('bonk')
		
	def handleKeyTrackArtistTrackChoices(self, keynum, rawcode):
		value = self.currentMenu.getMenuValue(self.currentItem)
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			if value == CHOICE_PLAY_TRACK:
				if self.currentTrack == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					self.NPPlaylist.addSong(self.currentTrack)
					self.nowPlaying.Play(self.NPPlaylist)

					self.sound('updown')
					
			elif value == CHOICE_PLAY_ARTIST:
				if self.currentArtist == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					for s in self.currentArtist:
						self.NPPlaylist.addSong(s)
					self.nowPlaying.Play(self.NPPlaylist,
										shuffle=opts['artistshuffle'],
										loop=opts['artistloop'])

					self.sound('updown')

			elif value == CHOICE_PLAY_ARTIST_TRACK:
				if self.currentArtist == None or self.currentTrack == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					for s in self.currentArtist:
						self.NPPlaylist.addSong(s)
					self.nowPlaying.Play(self.NPPlaylist, first=self.currentTrack,
										shuffle=opts['artistshuffle'],
										loop=opts['artistloop'])
					self.sound('updown')

			elif value == CHOICE_SONG_PLAYLIST:
				if self.currentArtist == None or self.currentTrack == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Track %s / %s" 
						% (self.currentArtist.getArtistName(), self.currentTrack.getTitle()))
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, song = self.currentTrack)
					self.sound('updown')
					
			elif value == CHOICE_ARTIST_PLAYLIST:
				if self.currentArtist == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Track Artist %s" 
						% self.currentArtist.getArtistName())
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, artist = self.currentArtist)
					self.sound('updown')
			
		elif keynum == KEY_INFO:
			if self.currentTrack == None:
				self.app.sound('bonk')
			else:
				self.app.showLyrics(self.currentTrack)
				self.app.sound('updown')
					
		else:
			self.sound('bonk')
			
	def handleKeyTrack(self, keynum, rawcode):
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			else:
				self.stack.append([self.menuMode, self.menuTitle, self.iterMode])
				self.menuMode = MODE_TRACK_CHOICES
				self.menuTitle = ""
				self.setSubTitle(self.menuTitle)
				self.iterMode = ITER_MODE_SONG
				self.sdb.setIterMode(self.iterMode)
				self.currentMenu, self.currentItem = self.mm.Descend(trackMenu, offset=8)
				self.sound('updown')
				
		elif keynum in [KEY_ENTER]:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			else:
				self.currentArtist = self.currentTrack.getArtist()
				t = ("Choose Playlist - adding Track %s / %s" 
					% (self.currentArtist.getArtistName(), self.currentTrack.getTitle()))
				self.setSubTitle(t)	
				self.plMgr.activate(done = PLM_DONE, song = self.currentTrack)
				self.sound('updown')
			
		elif keynum == KEY_INFO:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.app.sound('bonk')
			else:
				self.app.showLyrics(self.currentTrack)
				self.app.sound('updown')
			
		elif keynum == KEY_PLAY:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			if self.currentTrack == None:
				self.sound('bonk')
			
			self.NPPlaylist.clear()
			self.NPPlaylist.addSong(self.currentTrack)
			self.nowPlaying.Play(self.NPPlaylist)
		
		else:
			self.sound('bonk')
			
	def handleKeyTrackChoices(self, keynum, rawcode):
		value = self.currentMenu.getMenuValue(self.currentItem)
		if keynum in [KEY_RIGHT, KEY_SELECT]:
			if value == CHOICE_PLAY_TRACK:
				if self.currentTrack == None:
					self.sound('bonk')
				else:
					self.NPPlaylist.clear()
					self.NPPlaylist.addSong(self.currentTrack)
					self.nowPlaying.Play(self.NPPlaylist)

					self.sound('updown')
					
			elif value == CHOICE_SONG_PLAYLIST:
				if self.currentArtist == None or self.currentTrack == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Track %s / %s" 
						% (self.currentArtist.getArtistName(), self.currentTrack.getTitle()))
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, song = self.currentTrack)
					self.sound('updown')
					
			elif value == CHOICE_ARTIST_PLAYLIST:
				if self.currentArtist == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Track Artist %s" 
						% self.currentArtist.getArtistName())
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, artist = self.currentArtist)
					self.sound('updown')
					
			elif value == CHOICE_ALBUM_PLAYLIST:
				if self.currentAlbum == None or self.currentArtist == None:
					self.sound('bonk')
				else:
					t = ("Choose Playlist - adding Album %s / %s" 
						% (self.currentArtist.getArtistName(), self.currentAlbum.getAlbumName()))
					self.setSubTitle(t)	
					self.plMgr.activate(done = PLM_DONE, album = self.currentAlbum)
					self.sound('updown')

		elif keynum == KEY_INFO:
			if self.currentTrack == None:
				self.app.sound('bonk')
			else:
				self.app.showLyrics(self.currentTrack)
				self.app.sound('updown')
					
		else:
			self.sound('bonk')
			
	def setCurrentInfo(self):
		if self.menuMode in [ MODE_ALBUM_ARTIST, MODE_TRACK_ARTIST ]:
			self.currentArtist = self.currentMenu.getMenuValue(self.currentItem)
			
		elif self.menuMode in [ MODE_ALBUM, MODE_ALBUM_ARTIST_ALBUM ]:
			self.currentAlbum = self.currentMenu.getMenuValue(self.currentItem)
			self.currentArtist = self.currentAlbum.getArtist()
			
		elif self.menuMode in [ MODE_ALBUM_ARTIST_ALBUM_TRACK, MODE_ALBUM_TRACK, MODE_TRACK_ARTIST_TRACK, MODE_TRACK ]:
			self.currentTrack = self.currentMenu.getMenuValue(self.currentItem)
			self.currentAlbum = self.currentTrack.getAlbum()
			self.currentArtist = self.currentTrack.getArtist()
			
	def showDetails(self):
		if self.plMgr.isActive():
			self.detMgr.hide()
			
		elif self.menuMode in [ MODE_MAIN_MENU, MODE_ALBUM_ARTIST, MODE_TRACK_ARTIST, MODE_PREFS ]:
			self.detMgr.hide()
			return
		elif self.menuMode in [ MODE_ALBUM, MODE_ALBUM_ARTIST_ALBUM ]:
			self.detMgr.setAlbumDetail(self.currentAlbum)
			self.detMgr.show()
			return
		elif self.menuMode in [ MODE_PLAYLIST, MODE_ALBUM_ARTIST_ALBUM_TRACK, MODE_ALBUM_TRACK, MODE_TRACK_ARTIST_TRACK,
							MODE_ALBUM_ARTIST_ALBUM_TRACK_CHOICES, MODE_ALBUM_TRACK_CHOICES, MODE_TRACK_ARTIST_TRACK_CHOICES, MODE_TRACK, MODE_TRACK_CHOICES ]:
			self.detMgr.setTrackDetail(self.currentTrack)
			self.detMgr.show()
			return
		else:
			# this should never happen
			self.detMgr.hide()
			
	def handle_resource_info(self, resource, status, info):
		if self.nowPlaying.isActive():
			self.nowPlaying.handle_resource(resource, status, info)
Beispiel #4
0
class Navigator(Component, Window):
    """
    Navigator dialog for browsing media.
    """
    def __init__(self):

        # the current mode
        self.__mode = _MODE_NORMAL

        # list of available dialog windows
        self.__dialogs = []

        self.__widgets = []

        # the file that is currently playing
        self.__current_file = None

        # list of files for playing
        self.__play_folder = None
        self.__play_files = []

        # list for choosing random files from when in shuffle mode
        self.__random_files = []

        # current window size (for detecting resizing)
        self.__window_size = (0, 0)

        self.__is_searching = False
        self.__filter_term = ""

        self.__key_hold_down_timestamp = 0
        self.__skip_letter = False

        # scheduler for creating thumbnails one by one
        self.__tn_scheduler = ItemScheduler()

        # whether we are shutting down
        self.__is_shutdown = False

        Component.__init__(self)
        Window.__init__(self, Window.TYPE_TOPLEVEL)
        self.set_flag(windowflags.CATCH_VOLUME_KEYS, True)
        self.connect_key_pressed(self.__on_key_press)
        self.connect_closed(self.__on_close_window)

        # [Now Playing] button
        self.__now_playing = NowPlaying()
        #self.__now_playing.set_visible(False)

        # file browser
        self.__browser = StorageBrowser()
        #self.__browser.set_root_device(self.__root_dev)
        self.__browser.connect_folder_begin(self.__on_begin_folder)
        self.__browser.connect_folder_progress(self.__on_progress_folder)
        self.__browser.connect_folder_complete(self.__on_complete_folder)
        self.__browser.connect_file_opened(self.__on_open_file)
        self.__browser.connect_item_shifted(self.__on_shift_item)

        # toolbar
        self.__toolbar = Toolbar()

        self.__btn_home = ToolbarButton(theme.mb_btn_home_1)
        self.__btn_home.connect_clicked(self.__on_btn_home)

        self.__btn_history = ToolbarButton(theme.mb_btn_history_1)
        self.__btn_history.connect_clicked(self.__on_btn_history)

        self.__btn_bookmarks = ToolbarButton(theme.mb_btn_bookmark_1)
        self.__btn_bookmarks.connect_clicked(self.__on_btn_bookmarks)

        self.__btn_back = ToolbarButton(theme.mb_btn_dir_up_1)
        self.__btn_back.connect_clicked(self.__on_btn_back)

        self.__btn_select_all = ToolbarButton(theme.mb_btn_select_all_1)
        self.__btn_select_all.connect_clicked(self.__on_btn_select_all)

        self.__btn_select_none = ToolbarButton(theme.mb_btn_select_none_1)
        self.__btn_select_none.connect_clicked(self.__on_btn_select_none)

        self.__btn_select_done = ToolbarButton(theme.mb_btn_select_done_1)
        self.__btn_select_done.connect_clicked(self.__on_btn_select_done)

        # arrangement
        self.__arr = Arrangement()
        self.__arr.connect_resized(self.__update_layout)
        self.__arr.add(self.__now_playing, "now-playing")
        self.__arr.add(self.__browser, "browser")
        self.__arr.add(self.__toolbar, "toolbar")
        self.add(self.__arr)
        self.__arr.set_visible(False)

        # we have to fill the menu with content before showing the window on
        # Maemo5 or the window will show no menu at all
        self.__update_menu()

        self.set_visible(True)

    def __update_menu(self):

        folder = self.__browser.get_current_folder()

        repeat_selected = [mb_config.REPEAT_MODE_NONE,
                           mb_config.REPEAT_MODE_ALL,
                           mb_config.REPEAT_MODE_ONE] \
                          .index(mb_config.repeat_mode())
        shuffle_selected = [mb_config.SHUFFLE_MODE_NONE,
                            mb_config.SHUFFLE_MODE_ONE] \
                           .index(mb_config.shuffle_mode())

        self.set_menu_choice("repeat", [(theme.mb_repeat_none, "No Repeat"),
                                        (theme.mb_repeat_all, "Repeat All"),
                                        (theme.mb_repeat_one, "Repeat One")],
                             repeat_selected, True, self.__on_menu_repeat)
        self.set_menu_choice("shuffle", [(theme.mb_shuffle_none, "No Shuffle"),
                                         (theme.mb_shuffle_one, "Shuffle")],
                             shuffle_selected, True, self.__on_menu_shuffle)

        if (folder and folder.folder_flags & folder.ITEMS_ADDABLE):
            self.set_menu_item("add", "Add New", True, self.__on_menu_add)
        else:
            self.set_menu_item("add", "Add New", False, self.__on_menu_add)

        self.set_menu_item("openurl", "Open URL...", True,
                           self.__on_menu_open_url)

        self.set_menu_item("downloads", "Active Downloads", True,
                           self.__on_menu_downloads)

        self.set_menu_item("select", "Select Items for Action", True,
                           self.__on_menu_select)

        #self.set_menu_item("rearrange", "Rearrange Items", True,
        #                   self.__on_menu_rearrange)
        #self.set_menu_item("info", "About", True,
        #                   self.__on_menu_info)

    def __update_layout(self):

        w, h = self.get_size()
        if (w < h):
            # portrait mode
            self.__arr.set_xml(_PORTRAIT_ARRANGEMENT)
        else:
            # landscape mode
            self.__arr.set_xml(_LANDSCAPE_ARRANGEMENT)

    def __update_toolbar(self):
        """
        Updates the contents of the toolbar.
        """

        cwd = self.__browser.get_current_folder()
        if (self.__mode == _MODE_NORMAL):
            items = [self.__btn_home, self.__btn_history, self.__btn_back]
        else:
            items = [
                self.__btn_select_all, self.__btn_select_none,
                self.__btn_select_done
            ]

        self.__toolbar.set_toolbar(*items)

    def __update_items_per_row(self, folder):

        w, h = self.get_size()
        if (w > h):
            w -= 180

        if (folder and folder.folder_flags & folder.ITEMS_COMPACT):
            if (w > 0):
                per_row = w / 160
            else:
                per_row = 3
            #if (w < h):
            self.__browser.set_items_per_row(per_row)
            #else:
            #    self.__browser.set_items_per_row(4)
        else:
            self.__browser.set_items_per_row(1)

        #self.__browser.invalidate()
        #self.__browser.render()

    """
    def _visibility_changed(self):
        
        Window._visibility_changed(self)
        if (self.is_visible()):
            self.__tn_scheduler.resume()
            
        else:
            self.__tn_scheduler.halt()
    """

    def __on_key_press(self, keycode):

        w, h = self.get_size()
        if (w < h and mb_config.portrait_swap_volume()
                and keycode in _PORTRAIT_MODE_KEYSWAP):
            keycode = _PORTRAIT_MODE_KEYSWAP[keycode]

        handled = self.call_service(msgs.INPUT_SVC_SEND_KEY, keycode, True)
        if (not handled):
            """
            if (len(keycode) == 1 and ord(keycode) > 31):
                cnt = 0
                for item in self.__browser.get_items():
                    if (item.get_name().upper().startswith(keycode.upper())):
                        self.__browser.scroll_to_item(cnt)
                        break
                    cnt += 1
                #end for
            """
            if (len(keycode) == 1 and ord(keycode) > 31):
                self.__filter_term += keycode
                self.__update_filter()
            elif (keycode == "BackSpace" and self.__filter_term):
                self.__filter_term = self.__filter_term[:len(self.__filter_term
                                                             ) - 1]
                self.__update_filter()

    def __update_filter(self):
        def filter_func(item):
            return self.__filter_term.upper() in item.get_name().upper() + "#" + \
                                                 item.get_file().info.upper()

        if (self.__filter_term):
            self.__browser.set_filter(filter_func)
            self.__browser.set_message("Filter: %s (%d matches)" \
                                       % (self.__filter_term,
                                          self.__browser.count_items()))
        else:
            self.__browser.set_filter()
            self.__browser.set_message("")

        self.__browser.invalidate()
        self.__browser.render()

    def __on_close_window(self):

        self.emit_message(msgs.MEDIA_ACT_STOP)
        self.emit_message(msgs.COM_EV_APP_SHUTDOWN)
        gtk.main_quit()

    def __on_menu_repeat(self, choice):

        if (choice == 0):
            mb_config.set_repeat_mode(mb_config.REPEAT_MODE_NONE)
        elif (choice == 1):
            mb_config.set_repeat_mode(mb_config.REPEAT_MODE_ALL)
        elif (choice == 2):
            mb_config.set_repeat_mode(mb_config.REPEAT_MODE_ONE)

    def __on_menu_shuffle(self, choice):

        if (choice == 0):
            mb_config.set_shuffle_mode(mb_config.SHUFFLE_MODE_NONE)
        elif (choice == 1):
            mb_config.set_shuffle_mode(mb_config.SHUFFLE_MODE_ONE)

    def __on_menu_rearrange(self):
        def on_done():
            for item in self.__browser.get_items():
                item.set_draggable(False)
            self.__browser.invalidate()

            self.__update_toolbar()

        for item in self.__browser.get_items():
            item.set_draggable(True)
        self.__browser.invalidate()

        btn_done = ImageButton(theme.mb_btn_history_1, theme.mb_btn_history_2)
        btn_done.connect_clicked(on_done)
        self.__toolbar.set_toolbar(btn_done)

    def __on_menu_open_url(self):

        dlg = InputDialog("URL to open")
        dlg.add_input("URL", "http://")

        if (dlg.run() == dlg.RETURN_OK):
            url = dlg.get_values()[0]
            self.__load_uri(url, "")
        #end if

    def __on_menu_downloads(self):

        self.emit_message(msgs.UI_ACT_SHOW_DIALOG,
                          "downloader.DownloadManager")

    def __on_menu_fmtx(self):

        import platforms
        platforms.plugin_execute("libcpfmtx.so")

    def __on_menu_select(self):

        if (self.__browser.begin_bulk_action()):
            self.__mode = _MODE_SELECT
            self.__update_toolbar()
        #end if

    def __on_menu_add(self):

        folder = self.__browser.get_current_folder()
        if (folder):
            folder.new_file()

    def __on_menu_info(self):

        self.__show_dialog("core.AboutDialog")

    def __on_open_file(self, f):

        self.__load_file(f, True)

    def __on_begin_folder(self, f):

        self.__tn_scheduler.new_schedule(25, self.__on_load_thumbnail)
        self.__tn_scheduler.halt()

        self.set_flag(windowflags.BUSY, True)

        self.__browser.set_filter()
        self.__filter_term = ""

        self.__update_layout()
        self.__update_menu()

        self.__update_items_per_row(f)
        self.__browser.render()

        # set platform-specific click behavior
        if (platforms.MAEMO4):
            self.__browser.set_click_behavior(
                self.__browser.CLICK_BEHAVIOR_DOUBLE)
        else:
            self.__browser.set_click_behavior(
                self.__browser.CLICK_BEHAVIOR_SINGLE)

    def __on_progress_folder(self, f, c):

        if (not c.icon):
            items = self.__browser.get_items()
            item = items[-1]

            thumbpath, is_final = \
              self.call_service(msgs.THUMBNAIL_SVC_LOOKUP_THUMBNAIL, c)

            item.set_icon(thumbpath)

            if (not is_final):
                self.__tn_scheduler.add(item, c, False)
        #end if

    def __on_complete_folder(self, f):

        self.set_flag(windowflags.BUSY, False)

        names = [p.name for p in self.__browser.get_path()]
        #title = u" \u00bb ".join(names)
        title = names[-1]
        names.reverse()
        acoustic_title = "Entering " + " in ".join(names)
        self.set_title(title)
        self.emit_message(msgs.UI_ACT_TALK, acoustic_title)
        self.emit_message(msgs.CORE_EV_FOLDER_VISITED, f)
        self.__update_toolbar()

        if (self.is_visible()):
            self.__tn_scheduler.resume()

    def __on_shift_item(self, pos, amount):

        if (self.__browser.get_current_folder() == self.__play_folder):
            # force invalidation of play files
            self.__play_files = []

    def __update_thumbnail(self, item, thumbpath):

        item.set_icon(thumbpath)
        try:
            idx = self.__browser.get_items().index(item)
            self.__browser.invalidate_item(idx)
        except:
            pass

    def __on_load_thumbnail(self, item, f, quick):
        """
        Scheduler callback handler for loading the next thumbnail.
        """
        def on_loaded(thumbpath):
            if (thumbpath):
                self.__update_thumbnail(item, thumbpath)

            # priorize visible items
            top_idx = self.__browser.get_item_at(0, 0)
            if (top_idx != -1):
                items = self.__browser.get_items()
                if (top_idx < len(items)):
                    self.__tn_scheduler.priorize(items[top_idx:top_idx + 12])
            #end if
            gobject.idle_add(self.__tn_scheduler.resume)

        # load thumbnail
        self.__tn_scheduler.halt()
        if (quick):
            thumbpath, is_final = \
              self.call_service(msgs.THUMBNAIL_SVC_LOOKUP_THUMBNAIL, f)
            on_loaded(thumbpath)

            if (not is_final):
                #print "SCHEDULING THUMBNAIL", c
                self.__tn_scheduler.add(item, f, False)
            self.__tn_scheduler.resume()

        else:
            self.call_service(msgs.THUMBNAIL_SVC_LOAD_THUMBNAIL, f, on_loaded)

    def __on_btn_home(self):
        """
        Reacts on pressing the [Home] button.
        """

        self.emit_message(msgs.SSDP_ACT_SEARCH_DEVICES)
        self.__browser.go_root()

    def __on_btn_history(self):
        """
        Reacts on pressing the [History] button.
        """

        f = self.call_service(msgs.CORE_SVC_GET_FILE, "history:///")
        if (f):
            self.__browser.load_folder(f, self.__browser.GO_CHILD, True)

    def __on_btn_bookmarks(self):
        """
        Reacts on pressing the [Bookmarks] button.
        """

        f = self.call_service(msgs.CORE_SVC_GET_FILE, "bookmarks://generic/")
        if (f):
            self.__browser.load_folder(f, self.__browser.GO_PARENT, True)

    def __on_btn_back(self):
        """
        Reacts on pressing the [Back] button.
        """

        self.__browser.go_parent()
        #self.__update_items_per_row(self.__browser.get_current_folder())

    def __on_btn_select_all(self):
        """
        Reacts on pressing the [Select All] button.
        """

        self.__browser.select_all()

    def __on_btn_select_none(self):
        """
        Reacts on pressing the [Select None] button.
        """

        self.__browser.unselect_all()

    def __on_btn_select_done(self):
        """
        Reacts on pressing the [Select Done] button.
        """

        self.__mode = _MODE_NORMAL
        self.__update_toolbar()
        self.__browser.perform_bulk_action()

    def __load_uri(self, uri, mimetype):

        if (not mimetype):
            ext = os.path.splitext(uri)[1]
            mimetype = mimetypes.ext_to_mimetype(ext)

        f = self.call_service(msgs.CORE_SVC_GET_FILE,
                              "adhoc://" + File.pack_path("/", uri, mimetype))
        print "Loading URI:", f
        if (f):
            self.__load_file(f, True)

    def __load_file(self, f, is_manual):
        """
        Loads the given file.
        """

        #if (f.mimetype == "application/x-applet"):
        #    applet_id = f.resource
        #    self.call_service(msgs.CORE_SVC_LAUNCH_APPLET, applet_id)

        stopwatch = logging.stopwatch()

        if (f.mimetype == f.CONFIGURATOR):
            cfg_name = f.resource
            self.emit_message(msgs.UI_ACT_SHOW_DIALOG, cfg_name)

        else:
            if (is_manual):
                self.__show_dialog("player.PlayerWindow")

            #if (not f.mimetype in mimetypes.get_image_types()):
            self.emit_message(msgs.MEDIA_ACT_STOP)
            self.emit_message(msgs.MEDIA_ACT_LOAD, f)

            # update set of play files
            self.__current_file = f

            folder = self.__browser.get_current_folder()
            if (is_manual and folder != self.__play_folder):
                self.__play_folder = folder
                self.__random_files = []
                self.__invalidate_play_files()

        logging.profile(stopwatch, "[navigator] loaded file")

    def __go_previous(self):

        now = time.time()
        if (not self.__play_files):
            self.__invalidate_play_files()

        try:
            idx = self.__play_files.index(self.__current_file)
        except ValueError:
            return False

        if (idx > 0):
            next_item = self.__play_files[idx - 1]
            self.__load_file(next_item, False)

        logging.profile(now, "[navigator] loaded previous item")

    def __go_next(self):

        stopwatch = logging.stopwatch()
        if (not self.__play_files):
            self.__invalidate_play_files()

        repeat_mode = mb_config.repeat_mode()
        shuffle_mode = mb_config.shuffle_mode()

        if (repeat_mode == mb_config.REPEAT_MODE_NONE):
            if (shuffle_mode == mb_config.SHUFFLE_MODE_NONE):
                self.__play_next(False)

            elif (shuffle_mode == mb_config.SHUFFLE_MODE_ONE):
                self.__play_shuffled(False)

            elif (shuffle_mode == mb_config.SHUFFLE_MODE_ALL):
                self.__play_shuffled(True)

        elif (repeat_mode == mb_config.REPEAT_MODE_ONE):
            if (self.__current_file):
                self.__play_same()
            else:
                self.__play_next(True)

        elif (repeat_mode == mb_config.REPEAT_MODE_ALL):
            if (shuffle_mode == mb_config.SHUFFLE_MODE_NONE):
                self.__play_next(True)

            elif (shuffle_mode == mb_config.SHUFFLE_MODE_ONE):
                self.__play_shuffled(False)

            elif (shuffle_mode == mb_config.SHUFFLE_MODE_ALL):
                self.__play_shuffled(True)

        logging.profile(stopwatch, "[navigator] loaded next item")

    def __play_same(self):

        self.__load_file(self.__current_file, False)

        return True

    def __play_next(self, wraparound):

        try:
            idx = self.__play_files.index(self.__current_file)
        except:
            idx = -1

        if (idx + 1 < len(self.__play_files)):
            next_item = self.__play_files[idx + 1]
            self.__load_file(next_item, False)
            return True

        elif (wraparound):
            next_item = self.__play_files[0]
            self.__load_file(next_item, False)
            return True

        else:
            return False
            """
            self.__play_folder = self.__browser.get_current_folder()
            self.__invalidate_play_files()
            if (self.__play_files):
                next_item = self.__play_files[0]
                self.__load_file(next_item, False)
                return True
            else:
                return False
            """

    def __play_shuffled(self, from_all):

        if (from_all):
            # TODO...
            pass

        if (not self.__random_files):
            self.__random_files = self.__play_files[:]

        idx = random.randint(0, len(self.__random_files) - 1)
        next_item = self.__random_files.pop(idx)
        logging.debug("[navigator] picking random item %d of %d: %s", idx,
                      len(self.__random_files), str(next_item))

        self.__load_file(next_item, False)

        return True

    def __invalidate_play_files(self):
        """
        Invalidates the play files and random files and rebuilds them.
        """

        profile_now = time.time()

        prev_play_files = self.__play_files
        self.__play_files = [
            f for f in self.__play_folder.get_children()
            if not f.mimetype.endswith("-folder")
        ]

        size = len(self.__play_files)
        img_size = len([
            f for f in self.__play_files
            if f.mimetype in mimetypes.get_image_types()
        ])
        ratio = img_size / float(size)

        if (ratio < 0.5):
            self.__play_files = [
                f for f in self.__play_files
                if not f.mimetype in mimetypes.get_image_types()
            ]

        new_files = [f for f in self.__play_files if not f in prev_play_files]

        self.__random_files = [
            f for f in self.__random_files if f in self.__play_files
        ] + new_files

        logging.profile(profile_now, "[navigator] invalidated list of files " \
                                     "to play")

    def __filter_play_files(self):
        """
        Filters the list of playfiles to see if there's cover art to remove
        from the list.
        """

        if (not self.__play_files): return

        now = time.time()

        size = len(self.__play_files)
        img_size = len([
            f for f in self.__play_files
            if f.mimetype in mimetypes.get_image_types()
        ])
        ratio = img_size / float(size)

        if (ratio < 0.5):
            self.__play_files = [
                f for f in self.__play_files
                if not f.mimetype in mimetypes.get_image_types()
            ]

            self.__random_files = [
                f for f in self.__random_files if f in self.__play_files
            ]

        logging.profile(now, "[navigator] filtered items to play " \
                             "(removed cover art)")

    def __show_dialog(self, name):
        """
        Shows the dialog with the given name.
        """

        #print name, self.__dialogs
        dialogs = [d for d in self.__dialogs if repr(d) == name]
        if (dialogs):
            dlg = dialogs[0]
            dlg.set_visible(True)
        #end if

    def __save_state(self):

        # save state for next start
        path = [f.full_path for f in self.__browser.get_path_stack()]
        play_files = [f.full_path for f in self.__play_files]

        state.save(_STATEFILE, path, play_files,
                   self.__play_folder and self.__play_folder.full_path or "",
                   self.__current_file and self.__current_file.full_path or "")

    def render_this(self):

        w, h = self.get_size()

        if ((w, h) != self.__window_size):
            self.__update_items_per_row(self.__browser.get_current_folder())
            self.__window_size = (w, h)

        if (self.__arr.is_visible()):
            Window.render_this(self)

        elif (self.__is_shutdown):
            x, y = self.get_screen_pos()
            screen = self.get_screen()

            screen.fill_area(x, y, w, h, theme.color_mb_background)
            screen.draw_centered_text(values.NAME + " " + values.VERSION,
                                      theme.font_mb_headline, x, h / 2 - 30, w,
                                      30, theme.color_mb_text)
            screen.draw_centered_text(values.COPYRIGHT, theme.font_mb_plain, x,
                                      h / 2, w, 30, theme.color_mb_text)
            screen.draw_centered_text("Exiting...", theme.font_mb_plain, x,
                                      h - 80, w, 20, theme.color_mb_text)
            screen.fit_pixbuf(theme.mb_logo, w - 120, h - 120, 120, 120)

        else:
            x, y = self.get_screen_pos()
            screen = self.get_screen()

            screen.fill_area(x, y, w, h, theme.color_mb_background)
            screen.draw_centered_text(values.NAME + " " + values.VERSION,
                                      theme.font_mb_headline, x, h / 2 - 30, w,
                                      30, theme.color_mb_text)
            screen.draw_centered_text(values.COPYRIGHT, theme.font_mb_plain, x,
                                      h / 2, w, 30, theme.color_mb_text)
            screen.draw_centered_text("Loading... Please Wait",
                                      theme.font_mb_plain, x, h - 80, w, 20,
                                      theme.color_mb_text)
            screen.fit_pixbuf(theme.mb_logo, w - 120, h - 120, 120, 120)

    def handle_COM_EV_COMPONENT_LOADED(self, component):

        if (isinstance(component, Dialog)):
            if (repr(component) in [repr(d) for d in self.__dialogs]):
                logging.error("a dialog with ID '%s' exists already.",
                              repr(component))
            else:
                self.__dialogs.append(component)
                #component.set_parent_window(self)

        elif (isinstance(component, Widget)):
            if (repr(component) in [repr(d) for d in self.__widgets]):
                pass
            else:
                self.__widgets.append(component)

    def handle_COM_EV_APP_STARTED(self):

        logging.profile(values.START_TIME, "[app] startup complete")

        # load state
        try:
            path, play_files, play_folder, current_file = state.load(
                _STATEFILE)

            path_stack = []
            for p in path:
                f = self.call_service(msgs.CORE_SVC_GET_FILE, p)
                if (f):
                    path_stack.append(f)
                    self.emit_message(msgs.CORE_EV_FOLDER_VISITED, f)
                #end if
            #end for
            self.__browser.set_path_stack(path_stack)

            #self.__play_files = [ self.call_service(msgs.CORE_SVC_GET_FILE, p)
            #                      for p in play_files
            #                      if self.call_service(msgs.CORE_SVC_GET_FILE, p) ]
            self.__play_folder = self.call_service(msgs.CORE_SVC_GET_FILE,
                                                   play_folder)
            self.__current_file = self.call_service(msgs.CORE_SVC_GET_FILE,
                                                    current_file)

        except:
            logging.warning("could not restore navigator state:\n%s",
                            logging.stacktrace())

        self.__arr.set_visible(True)
        self.render()

        if (values.uri and
            (values.uri.startswith("http://") or os.path.exists(values.uri))):
            ext = os.path.splitext(values.uri)[1]
            mimetype = mimetypes.ext_to_mimetype(ext)
            f = self.call_service(
                msgs.CORE_SVC_GET_FILE,
                "adhoc://" + File.pack_path("/", values.uri, mimetype))
            self.__load_file(f, True)
        #end if

    def handle_COM_EV_APP_SHUTDOWN(self):

        self.__is_shutdown = True
        #self.render()

        #while (gtk.events_pending()): gtk.main_iteration(True)
        self.__save_state()

    def handle_CORE_EV_THEME_CHANGED(self):

        self.render()

    def handle_CORE_EV_DEVICE_ADDED(self, ident, device):

        if (repr(device) == "navigator.RootDevice"):
            self.__browser.set_root_device(device)

    def handle_UI_ACT_SHOW_INFO(self, msg):

        dlg = InfoDialog(msg, self)
        dlg.run()

    def handle_UI_ACT_SHOW_DIALOG(self, name):

        self.__show_dialog(name)

    def handle_CORE_EV_FOLDER_INVALIDATED(self, folder):

        logging.debug("[navigator] invalidating folder %s", str(folder))

        if (self.is_visible()):
            self.__browser.invalidate_folder(folder)

        if (folder and folder == self.__play_folder):
            self.__invalidate_play_files()
            """
            prev_play_files = self.__play_files[:]
            self.__play_files = [ fl for fl in folder.get_children()
                                  if not fl.mimetype.endswith("-folder") ]
            # remove from random files what's no longer there and add to random
            # files what's new in play files
            logging.debug("[navigator] updating random items after folder " \
                          "invalidation")
            l = len(self.__random_files)
            self.__random_files = [ f for f in self.__play_files
                                    if f in self.__random_files or
                                       f not in prev_play_files ]
            logging.debug("[navigator] previously %d random items, now %d",
                          l, len(self.__random_files))
            """

    def handle_CORE_EV_DEVICE_REMOVED(self, dev_id):

        folder = self.__browser.get_current_folder()
        if (folder.device_id == dev_id):
            self.__browser.go_root()

    def handle_ASR_ACT_ENABLE(self, value):

        self.set_flag(windowflags.ASR, value)

    def handle_ASR_EV_PORTRAIT(self):

        self.set_flag(windowflags.PORTRAIT, True)
        #self.__update_items_per_row(self.__browser.get_current_folder())

    def handle_ASR_EV_LANDSCAPE(self):

        self.set_flag(windowflags.PORTRAIT, False)
        #self.__update_items_per_row(self.__browser.get_current_folder())

    def handle_MEDIA_EV_LOADED(self, player, f):

        if (not self.__now_playing.is_visible()):
            self.__update_layout()

        self.__browser.hilight_file(f)
        self.__browser.render()

    def handle_MEDIA_ACT_LOAD_URI(self, uri, mimetype):

        self.__load_uri(uri, mimetype)

    def handle_MEDIA_ACT_CHANGE_PLAY_FOLDER(self, folder):

        self.__play_folder = folder
        self.__play_files = [
            fl for fl in self.__browser.get_files()
            if not fl.mimetype.endswith("-folder")
        ]
        logging.debug("[navigator] clearing random items")
        self.__random_files = []

    def handle_MEDIA_ACT_PREVIOUS(self):

        self.__go_previous()

    def handle_MEDIA_ACT_NEXT(self):

        self.__go_next()

    def handle_INPUT_EV_UP(self, pressed):

        if (self.is_visible()):
            self.__browser.move(0, -80)

    def handle_INPUT_EV_DOWN(self, pressed):

        if (self.is_visible()):
            self.__browser.move(0, 80)

    def handle_INPUT_EV_KEY(self, key, pressed):

        if (self.is_visible()):
            print "GOT KEY", key