diff options
Diffstat (limited to 'plugins/PlayControl.py')
-rw-r--r-- | plugins/PlayControl.py | 125 |
1 files changed, 122 insertions, 3 deletions
diff --git a/plugins/PlayControl.py b/plugins/PlayControl.py index 06952e6..abe4547 100644 --- a/plugins/PlayControl.py +++ b/plugins/PlayControl.py @@ -3,6 +3,22 @@ from PyQt4 import QtGui, QtSvg, QtCore from misc import * from clMonty import monty from clPlugin import * +from thread import start_new_thread +from random import randint + +# Some predefined constants. +# Note that REPEAT precedes RANDOM. E.g. if repeat +# is ALBUM, and random is SONG, then it'll take a random song +# from the current album ... +PC_RANDOM_NO=0 # no randomness +PC_RANDOM_SONG=1 # choose a song random from the playlist +PC_RANDOM_ALBUM=2 # choose a random album, and play that fully + +PC_REPEAT_NO=0 # no repeat +PC_REPEAT_SONG=1 # repeat current song +PC_REPEAT_ALBUM=2 # repeat current album +PC_REPEAT_PLAYLIST=3 # repeat playlist + class wgPlayControl(QtGui.QWidget): """Displays controls for interacting with playing, like play, volume ...""" @@ -20,6 +36,12 @@ class wgPlayControl(QtGui.QWidget): " all objects in this widget" objects=None + cmbRepeat=None + cmbShuffle=None + + " contains the songs of the album the current song is playing. None, if the album is not set" + curAlbumSongs=None + def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) @@ -56,11 +78,28 @@ class wgPlayControl(QtGui.QWidget): self.btnPrevious=Button("prev", self.onBtnPreviousClick, 'gfx/media-skip-backward.svg', True) self.btnNext=Button("next", self.onBtnNextClick, 'gfx/media-skip-forward.svg', True) + self.cmbShuffle=QtGui.QComboBox(self) + self.cmbShuffle.addItem('Don\'t play dices') + self.cmbShuffle.addItem('Random song') + self.cmbShuffle.addItem('Random album') + self.cmbShuffle.setCurrentIndex(int(settings.get('playcontrol.shuffle', PC_RANDOM_SONG))) + + self.cmbRepeat=QtGui.QComboBox(self) + self.cmbRepeat.addItem('No repeat') + self.cmbRepeat.addItem('Repeat current song') + self.cmbRepeat.addItem('Repeat album') + self.cmbRepeat.addItem('Playlist') + self.cmbRepeat.setCurrentIndex(int(settings.get('playcontrol.repeat', PC_REPEAT_PLAYLIST))) + self.objects=[self.slrVolume, self.slrTime, self.btnStop, self.btnNext, self.btnPrevious] layout=QtGui.QHBoxLayout(parent) - self.setLayout(layout) + layout2=QtGui.QHBoxLayout(parent) + layoutWidget=QtGui.QVBoxLayout(parent) + layoutWidget.addLayout(layout) + layoutWidget.addLayout(layout2) + self.setLayout(layoutWidget) layout.addWidget(self.btnPrevious) layout.addWidget(self.btnPlayPause) @@ -69,12 +108,18 @@ class wgPlayControl(QtGui.QWidget): layout.addWidget(self.slrTime) layout.addWidget(self.slrVolume) layout.addWidget(self.svgVolume) + + layout2.addWidget(self.cmbRepeat) + layout2.addWidget(self.cmbShuffle) self.connect(self.slrVolume, QtCore.SIGNAL('valueChanged(int)'),self.onVolumeSliderChange) self.connect(self.slrTime, QtCore.SIGNAL('sliderReleased()'),self.onTimeSliderChange) + self.connect(self.cmbRepeat, QtCore.SIGNAL('currentIndexChanged(int)'),self.onCmbRepeatChanged) + self.connect(self.cmbShuffle, QtCore.SIGNAL('currentIndexChanged(int)'),self.onCmbShuffleChanged) + monty.addListener('onStateChange', self.onStateChange) - monty.addListener('onSongChange', self.onSongChange) + monty.addListener('beforeSongChange', self.beforeSongChange) monty.addListener('onSongChange', self.onSongChange) monty.addListener('onVolumeChange', self.onVolumeChange) monty.addListener('onReady', self.onStateChange) @@ -105,7 +150,68 @@ class wgPlayControl(QtGui.QWidget): self.slrTime.setEnabled(True) except: pass + # look in another thread for the songs in the current album! + params=() + start_new_thread(self.findAlbumSongs, params) + def beforeSongChange(self, params): + nextID=None + song=monty.getCurrentSong() + # decide here what next song to play! + repeat=self.cmbRepeat.currentIndex() + random=self.cmbShuffle.currentIndex() + # is the current song the last of the album? + eofAlbum=int(song.getTrack())==int(self.curAlbumSongs[-1].getTrack()) + if repeat==PC_REPEAT_NO: + # no repeat, nothing to see here! Pass on! + pass + elif repeat==PC_REPEAT_SONG: + # we must repeat the previous song! + nextID=params['curSongID'] + elif repeat==PC_REPEAT_ALBUM: + # check if we are at the last track, if it is, we must start a new! + if eofAlbum: + nextID=self.curAlbumSongs[0].getID() + elif repeat==PC_REPEAT_PLAYLIST: + # repeating the playlist is handled by monty itself; + # it is set in onCmbRepeatChanged. + pass + + if random==PC_RANDOM_NO: + # just follow our leader Monty. + pass + elif random==PC_RANDOM_SONG: + # pick a random song! This depends on what repeat-mode we're in. + if repeat==PC_REPEAT_NO or repeat==PC_REPEAT_PLAYLIST: + # we don't repeat anything, so we can just let monty pick the + # next random one! + pass + elif repeat==PC_REPEAT_SONG: + # song repeat; don't choose the next one! + nextID=params['curSongID'] + elif repeat==PC_REPEAT_ALBUM and self.curAlbumSongs: + # pick random song from current album + nextID=self.curAlbumSongs[randint(0,len(self.curAlbumSongs)-1)].getID() + elif random==PC_RANDOM_ALBUM: + # pick a random album! This means, we pick the first song of a random + # album. + if eofAlbum and (repeat==PC_REPEAT_PLAYLIST or repeat==PC_REPEAT_NO): + # all first songs of an album + albums=filter(lambda s: s.getAlbum() and s.getTrack()==1, monty.listPlaylist()) + nextID=albums[randint(0,len(albums)-1)].getID() + + if nextID!=None: + monty.play(nextID) + + def findAlbumSongs(self): + """This method looks for the songs in the album of current playing song.""" + song=monty.getCurrentSong() + self.curAlbumSongs=None + if not song or not song.getAlbum(): + return + self.curAlbumSongs=filter(lambda s: s.getArtist()==song.getArtist() + and s.getAlbum()==song.getAlbum(), monty.listPlaylist()) + self.curAlbumSongs.sort(numeric_compare) def onBtnPlayPauseClick(self): status=monty.getStatus() @@ -135,13 +241,26 @@ class wgPlayControl(QtGui.QWidget): else: mode=('0', 'min', 'med', 'max')[int(3*v/100)] self.svgVolume.load('gfx/stock_volume-%s.svg'%(mode)) - + + def onCmbRepeatChanged(self, newval): + settings.set('playcontrol.repeat', newval) + if newval==PC_REPEAT_PLAYLIST: + monty.repeat(1) + else: + monty.repeat(0) + def onCmbShuffleChanged(self, newval): + settings.set('playcontrol.shuffle', newval) + if newval==PC_RANDOM_SONG: + monty.random(1) + else: + monty.random(0) class pluginPlayControl(Plugin): o=None def __init__(self, winMain): Plugin.__init__(self, winMain, 'PlayControl') + def _load(self): self.o=wgPlayControl(None) def getInfo(self): return "Have total control over the playing!" |