Commit eb7bff72 authored by Scott Wheeler's avatar Scott Wheeler

Added forward and back buttons to the player.

svn path=/trunk/kdemultimedia/juk/; revision=189613
parent 73a1755f
......@@ -93,9 +93,11 @@ void JuK::setupActions()
// play menu
randomPlayAction = new KToggleAction(i18n("Random Play"), 0, actionCollection(), "randomPlay");
playAction = new KAction(i18n("&Play"), "1rightarrow", 0, this, SLOT(playFile()), actionCollection(), "playFile");
playAction = new KAction(i18n("&Play"), "player_play", 0, this, SLOT(playFile()), actionCollection(), "playFile");
pauseAction = new KAction(i18n("P&ause"), "player_pause", 0, this, SLOT(pauseFile()), actionCollection(), "pauseFile");
stopAction = new KAction(i18n("&Stop"), "player_stop", 0, this, SLOT(stopFile()), actionCollection(), "stopFile");
backAction = new KAction(i18n("Skip &Back"), "player_start", 0, this, SLOT(backFile()), actionCollection(), "backFile");
forwardAction = new KAction(i18n("Skip &Forward"), "player_end", 0, this, SLOT(forwardFile()), actionCollection(), "forwardFile");
// playlist menu
new KAction(i18n("New..."), "filenew", 0, splitter, SLOT(createPlaylist()), actionCollection(), "createPlaylist");
......@@ -129,10 +131,14 @@ void JuK::setupActions()
void JuK::setupPlayer()
{
playingItem = 0;
trackPositionDragging = false;
noSeek = false;
pauseAction->setEnabled(false);
stopAction->setEnabled(false);
backAction->setEnabled(false);
forwardAction->setEnabled(false);
playTimer = new QTimer(this);
connect(playTimer, SIGNAL(timeout()), this, SLOT(pollPlay()));
......@@ -295,6 +301,10 @@ void JuK::playFile()
{
if(player.paused()) {
player.play();
// Here, before doing anything, we want to make sure that the player did
// in fact start.
if(player.playing()) {
pauseAction->setEnabled(true);
stopAction->setEnabled(true);
......@@ -325,6 +335,8 @@ void JuK::stopFile()
player.stop();
pauseAction->setEnabled(false);
stopAction->setEnabled(false);
backAction->setEnabled(false);
forwardAction->setEnabled(false);
sliderAction->getTrackPositionSlider()->setValue(0);
sliderAction->getTrackPositionSlider()->setEnabled(false);
if(playingItem)
......@@ -334,6 +346,20 @@ void JuK::stopFile()
statusLabel->clear();
}
void JuK::backFile()
{
PlaylistItem *i = Playlist::previousItem(playingItem, randomPlayAction->isChecked());
if(i)
playItem(i);
}
void JuK::forwardFile()
{
PlaylistItem *i = Playlist::nextItem(playingItem, randomPlayAction->isChecked());
playItem(i);
}
////////////////////////////////////////////////////////////////////////////////
// additional player slots
////////////////////////////////////////////////////////////////////////////////
......@@ -371,6 +397,9 @@ void JuK::pollPlay()
if(next) {
playingItem = next;
backAction->setEnabled(true);
sliderAction->getTrackPositionSlider()->setValue(0);
player.play(playingItem->absFilePath(), player.getVolume());
if(player.playing()) {
......@@ -404,9 +433,7 @@ void JuK::setVolume(int volume)
void JuK::playItem(QListViewItem *item)
{
PlaylistItem *fileListItem = dynamic_cast<PlaylistItem *>(item);
if(fileListItem)
playItem(fileListItem);
playItem(dynamic_cast<PlaylistItem *>(item));
}
void JuK::playItem(PlaylistItem *item)
......@@ -415,17 +442,25 @@ void JuK::playItem(PlaylistItem *item)
stopFile();
if(item) {
playingItem = item;
float volume = float(sliderAction->getVolumeSlider()->value()) / float(sliderAction->getVolumeSlider()->maxValue());
player.play(playingItem->absFilePath(), volume);
player.play(item->absFilePath(), volume);
// Make sure that the player actually starts before doing anything.
if(player.playing()) {
pauseAction->setEnabled(true);
stopAction->setEnabled(true);
backAction->setEnabled(true);
forwardAction->setEnabled(true);
playingItem = item;
sliderAction->getTrackPositionSlider()->setEnabled(true);
playingItem->setPixmap(0, QPixmap(UserIcon("playing")));
item->setPixmap(0, QPixmap(UserIcon("playing")));
playTimer->start(pollInterval);
statusLabel->setPlayingItem(playingItem);
statusLabel->setPlayingItem(item);
}
}
}
......
......@@ -72,9 +72,12 @@ private:
KToggleAction *restoreOnLoadAction;
SliderAction *sliderAction;
KToggleAction *randomPlayAction;
KAction *playAction;
KAction *pauseAction;
KAction *stopAction;
KAction *backAction;
KAction *forwardAction;
KAction *savePlaylistAction;
KAction *saveAsPlaylistAction;
......@@ -84,6 +87,7 @@ private:
QTimer *playTimer;
Player player;
PlaylistItem *playingItem;
bool trackPositionDragging;
bool noSeek;
bool restore;
......@@ -106,6 +110,8 @@ private slots:
void playFile();
void pauseFile();
void stopFile();
void backFile();
void forwardFile();
// additional player slots
void trackPositionSliderClick();
......@@ -113,7 +119,14 @@ private slots:
void trackPositionSliderUpdate(int position);
void pollPlay();
void setVolume(int volume);
/**
* This is just a wrapper around the below method to take a QListViewItem.
*/
void playItem(QListViewItem *item);
/**
* This is the main method to play stuff. All of the other play related
* members in this class ultimately call this method.
*/
void playItem(PlaylistItem *item);
};
......
......@@ -22,6 +22,8 @@
<Action name="playFile"/>
<Action name="pauseFile"/>
<Action name="stopFile"/>
<Action name="backFile"/>
<Action name="forwardFile"/>
</Menu>
<Menu name="playlist"><text>Play&amp;list</text>
<Action name="createPlaylist"/>
......@@ -52,5 +54,8 @@
<Action name="playFile"/>
<Action name="pauseFile"/>
<Action name="stopFile"/>
<Separator lineSeparator="false"/>
<Action name="backFile"/>
<Action name="forwardFile"/>
<Action name="trackPositionAction"/>
</kpartgui>
......@@ -244,12 +244,14 @@ PlaylistItem *Playlist::nextItem(PlaylistItem *current, bool random)
return(0);
PlaylistItem *i;
Playlist *list = static_cast<Playlist *>(current->listView());
if(random) {
Playlist *list = static_cast<Playlist *>(current->listView());
PlaylistItemList items = list->items();
if(items.count() > 1) {
list->history.push(current);
srand(time(0));
i = current;
while(i == current)
......@@ -264,6 +266,19 @@ PlaylistItem *Playlist::nextItem(PlaylistItem *current, bool random)
return(i);
}
PlaylistItem *Playlist::previousItem(PlaylistItem *current, bool random)
{
if(!current)
return(0);
Playlist *list = static_cast<Playlist *>(current->listView());
if(random && !list->history.isEmpty())
return(list->history.pop());
else
return(static_cast<PlaylistItem *>(current->itemAbove()));
}
bool Playlist::isInternalFile() const
{
return(internalFile);
......
......@@ -21,6 +21,7 @@
#include <klistview.h>
#include <qstringlist.h>
#include <qptrstack.h>
#include "playlistitem.h"
......@@ -97,9 +98,11 @@ public:
// static methods
/**
* This gets the next item to be played in the specified playlist.
* This gets the next item to be played. This is static because often we
* know about the playing item, but not to which list it belongs.
*/
static PlaylistItem *nextItem(PlaylistItem *current, bool random = false);
static PlaylistItem *previousItem(PlaylistItem *current, bool random = false);
protected:
virtual QDragObject *dragObject();
......@@ -125,6 +128,8 @@ private:
QString playlistName;
PlaylistSplitter *splitter;
PlaylistBoxItem *boxItem;
QPtrStack<PlaylistItem> history;
private slots:
void emitSelected();
......
......@@ -43,26 +43,34 @@ public:
GenreColumn = 4, YearColumn = 5, LengthColumn = 6, FileNameColumn = 7 };
// The constructors are in the protected secion. See the note there.
virtual ~PlaylistItem();
// These can't be const members because they fetch the data "on demand".
Tag *tag() const;
AudioData *getAudioData();
void setFile(const QString &file);
// QFileInfo-ish methods
// These are just forwarding methods to PlaylistItem::Data, a QFileInfo
// subclass.
QString fileName() const;
QString filePath() const;
QString absFilePath() const;
QString dirPath(bool absPath = false) const;
bool isWritable() const;
inline QString fileName() const;
inline QString filePath() const;
inline QString absFilePath() const;
inline QString dirPath(bool absPath = false) const;
inline bool isWritable() const;
public slots:
/**
* This just refreshes from the in memory data. This may seem pointless at
* first, but this data is shared between all of the list view items that are
* based on the same file, so if another one of those items changes its data
* it is important to refresh the others.
*/
virtual void refresh();
/**
* This rereads the tag from disk. This affects all PlaylistItems based on
* the same file.
*/
virtual void refreshFromDisk();
protected:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment