summaryrefslogtreecommitdiff
path: root/plugins/PlayControl.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/PlayControl.py')
-rw-r--r--plugins/PlayControl.py125
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!"