Commit c0204770 authored by Michael Pyne's avatar Michael Pyne

Decouple PlayerManager from JuK so that it isn't a singleton.

The major reason for this change is to allow for a saner destruct sequence
(instead of the unordered global static destruct sequence) which will hopefully
help reduce crash-on-shutdown bugs.

This will not be in the upcoming KDE 4.4 beta but will be in the 4.4 release (assuming no
bugs are found in it ;)

CCMAIL:nlecureuil@mandriva.com


svn path=/trunk/KDE/kdemultimedia/juk/; revision=1054429
parent b932c048
......@@ -29,12 +29,12 @@
////////////////////////////////////////////////////////////////////////////////
HistoryPlaylist::HistoryPlaylist(PlaylistCollection *collection) :
Playlist(collection, true), m_timer(0)
Playlist(collection, true),
m_timer(new QTimer(this))
{
setAllowDuplicates(true);
m_timer = new QTimer(this);
connect(PlayerManager::instance(), SIGNAL(signalPlay()), this, SLOT(slotAddPlaying()));
m_timer->setSingleShot(true);
connect(m_timer, SIGNAL(timeout()), this, SLOT(slotCreateNewItem()));
}
......@@ -71,22 +71,20 @@ void HistoryPlaylist::polish()
// private slots
////////////////////////////////////////////////////////////////////////////////
void HistoryPlaylist::slotAddPlaying()
void HistoryPlaylist::appendProposedItem(const FileHandle &file)
{
m_file = PlayerManager::instance()->playingFile();
m_timer->stop();
m_timer->setSingleShot(true);
m_timer->start(delay());
m_file = file;
if(!m_file.isNull())
m_timer->start(delay());
else
m_timer->stop();
}
void HistoryPlaylist::slotCreateNewItem()
{
PlayerManager *player = PlayerManager::instance();
if(player->playing() && m_file == player->playingFile()) {
createItem(m_file);
m_file = FileHandle::null();
}
createItem(m_file);
m_file = FileHandle::null();
}
////////////////////////////////////////////////////////////////////////////////
......
......@@ -54,12 +54,12 @@ public:
public slots:
void cut() {}
void clear() {}
void appendProposedItem(const FileHandle &file);
protected:
virtual void polish();
private slots:
void slotAddPlaying();
void slotCreateNewItem();
private:
......
......@@ -4,7 +4,7 @@
email : wheeler@kde.org
copyright : (C) 2008, 2009 by Michael Pyne
email : michael.pyne@kdemail.net
email : mpyne@kde.org
***************************************************************************/
/***************************************************************************
......@@ -59,14 +59,23 @@ using namespace ActionCollection;
JuK* JuK::m_instance;
template<class T>
void deleteAndClear(T *&ptr)
{
delete ptr;
ptr = 0;
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
JuK::JuK(QWidget *parent) :
KXmlGuiWindow(parent, Qt::WDestructiveClose),
m_splitter(0),
m_statusLabel(0),
m_systemTray(0),
m_player(PlayerManager::instance()),
m_player(new PlayerManager),
m_shuttingDown(false)
{
// Expect segfaults if you change this order.
......@@ -94,6 +103,8 @@ JuK::JuK(QWidget *parent) :
readConfig();
setupGlobalAccels();
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(slotAboutToQuit()));
// slotCheckCache loads the cached entries first to populate the collection list
QTimer::singleShot(0, CollectionList::instance(), SLOT(slotCheckCache()));
......@@ -116,6 +127,11 @@ JuK* JuK::JuKInstance()
return m_instance;
}
PlayerManager *JuK::playerManager() const
{
return m_player;
}
void JuK::coverDownloaded(const QPixmap &cover)
{
QString event(cover.isNull() ? "coverFailed" : "coverDownloaded");
......@@ -139,14 +155,14 @@ void JuK::setupLayout()
{
new TagTransactionManager(this);
m_splitter = new PlaylistSplitter(this, "playlistSplitter");
m_splitter = new PlaylistSplitter(m_player, this);
setCentralWidget(m_splitter);
m_statusLabel = new StatusLabel(m_splitter->playlist(), statusBar());
connect(CollectionList::instance(), SIGNAL(signalCollectionChanged()),
m_statusLabel, SLOT(updateData()));
statusBar()->addWidget(m_statusLabel, 1);
PlayerManager::instance()->setStatusLabel(m_statusLabel);
m_player->setStatusLabel(m_statusLabel);
m_splitter->setFocus();
resize(750, 500);
......@@ -300,13 +316,11 @@ void JuK::setupActions()
void JuK::slotSetupSystemTray()
{
if(m_toggleSystemTrayAction && m_toggleSystemTrayAction->isChecked()) {
m_systemTray = new SystemTray(this);
m_systemTray = new SystemTray(m_player, this);
m_systemTray->setObjectName("systemTray");
m_toggleDockOnCloseAction->setEnabled(true);
m_togglePopupsAction->setEnabled(true);
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(slotAboutToQuit()));
}
else {
m_systemTray = 0;
......@@ -488,11 +502,10 @@ void JuK::slotAboutToQuit()
{
m_shuttingDown = true;
delete m_systemTray;
m_systemTray = 0;
delete m_splitter;
m_splitter = 0;
deleteAndClear(m_systemTray);
deleteAndClear(m_splitter);
deleteAndClear(m_player);
deleteAndClear(m_statusLabel);
// Playlists depend on CoverManager, so CoverManager should shutdown as
// late as possible
......
......@@ -42,6 +42,8 @@ public:
static JuK* JuKInstance();
PlayerManager *playerManager() const;
// Use a null cover for failure
void coverDownloaded(const QPixmap &cover);
......
......@@ -85,11 +85,11 @@ int main(int argc, char *argv[])
// Create the main window and such
JuK *juk = new JuK;
JuK juk;
KConfigGroup config(KGlobal::config(), "Settings");
if(!config.readEntry("StartDocked", false))
juk->show();
juk.show();
return a.exec();
}
......
......@@ -2,6 +2,9 @@
begin : Tue Nov 9 2004
copyright : (C) 2004 by Scott Wheeler
email : wheeler@kde.org
copyright : (C) 2009 by Michael Pyne
email : mpyne@kde.org
***************************************************************************/
/***************************************************************************
......@@ -40,7 +43,6 @@
#include "playlistcollection.h"
#include "playlistitem.h"
#include "playermanager.h"
#include "coverinfo.h"
#include "covermanager.h"
#include "tag.h"
......@@ -80,9 +82,6 @@ NowPlaying::NowPlaying(QWidget *parent, PlaylistCollection *collection) :
layout->addWidget(new Line(this), 0);
layout->addWidget(new HistoryItem(this), 1);
connect(PlayerManager::instance(), SIGNAL(signalPlay()), this, SLOT(slotUpdate()));
connect(PlayerManager::instance(), SIGNAL(signalStop()), this, SLOT(slotUpdate()));
hide();
}
......@@ -96,10 +95,9 @@ PlaylistCollection *NowPlaying::collection() const
return m_collection;
}
void NowPlaying::slotUpdate()
void NowPlaying::slotUpdate(const FileHandle &file)
{
FileHandle file = PlayerManager::instance()->playingFile();
m_file = file;
if(file.isNull()) {
hide();
return;
......@@ -111,6 +109,12 @@ void NowPlaying::slotUpdate()
item->update(file);
}
void NowPlaying::slotReloadCurrentItem()
{
foreach(NowPlayingItem *item, m_items)
item->update(m_file);
}
////////////////////////////////////////////////////////////////////////////////
// CoverItem
////////////////////////////////////////////////////////////////////////////////
......@@ -129,11 +133,11 @@ void CoverItem::update(const FileHandle &file)
{
m_file = file;
if(file.coverInfo()->hasCover()) {
if(!file.isNull() && file.coverInfo()->hasCover()) {
show();
setPixmap(
file.coverInfo()->pixmap(CoverInfo::Thumbnail)
.scaled(imageSize, imageSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
file.coverInfo()->pixmap(CoverInfo::Thumbnail)
.scaled(imageSize, imageSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
else
hide();
......@@ -247,11 +251,6 @@ TrackItem::TrackItem(NowPlaying *parent) :
m_label->setTextInteractionFlags(Qt::LinksAccessibleByMouse|Qt::LinksAccessibleByKeyboard);
#ifdef __GNUC__
#warning We should potentially check on URL underlining.
#endif
/* m_label->setLinkUnderline(false); */
layout->addStretch();
layout->addWidget(m_label);
layout->addStretch();
......@@ -282,6 +281,11 @@ void TrackItem::slotOpenLink(const QString &link)
void TrackItem::slotUpdate()
{
if(m_file.isNull()) {
m_label->setText(QString());
return;
}
QString title = Qt::escape(m_file.tag()->title());
QString artist = Qt::escape(m_file.tag()->artist());
QString album = Qt::escape(m_file.tag()->album());
......@@ -315,14 +319,14 @@ void TrackItem::slotUpdate()
HistoryItem::HistoryItem(NowPlaying *parent) :
QLabel(parent),
NowPlayingItem(parent)
NowPlayingItem(parent),
m_timer(new QTimer(this))
{
setFixedHeight(parent->height() - parent->layout()->margin() * 2);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
/* setLinkUnderline(false); */
setText(QString("<b>%1</b>").arg(i18n("History")));
m_timer = new QTimer(this);
m_timer->setSingleShot(true);
connect(m_timer, SIGNAL(timeout()), this, SLOT(slotAddPlaying()));
}
......@@ -349,8 +353,6 @@ void HistoryItem::update(const FileHandle &file)
}
m_file = file;
m_timer->stop();
m_timer->setSingleShot(true);
m_timer->start(HistoryPlaylist::delay());
}
......@@ -376,14 +378,10 @@ void HistoryItem::slotAddPlaying()
{
// More or less copied from the HistoryPlaylist
PlayerManager *manager = PlayerManager::instance();
if(manager->playing() && manager->playingFile() == m_file) {
if(!m_file.isNull()) {
m_history.prepend(Item(KRandom::randomString(20),
m_file, Playlist::playingItem()->playlist()));
}
m_file = FileHandle::null();
}
#include "nowplaying.moc"
......
......@@ -45,8 +45,9 @@ public:
void addItem(NowPlayingItem *item);
PlaylistCollection *collection() const;
private slots:
void slotUpdate();
public slots:
void slotUpdate(const FileHandle &file);
void slotReloadCurrentItem();
private:
struct Observer : public PlaylistObserver
......@@ -55,7 +56,7 @@ private:
PlaylistObserver(playlist),
m_parent(parent) {}
virtual void updateCurrent() {}
virtual void updateData() { m_parent->slotUpdate(); }
virtual void updateData() { m_parent->slotReloadCurrentItem(); }
NowPlaying *m_parent;
};
friend struct Observer;
......@@ -64,6 +65,7 @@ private:
Observer m_collectionListObserver;
PlaylistCollection *m_collection;
QList<NowPlayingItem *> m_items;
FileHandle m_file;
};
/**
......
......@@ -75,18 +75,14 @@ PlayerManager::PlayerManager() :
PlayerManager::~PlayerManager()
{
delete m_sliderAction;
m_sliderAction = 0;
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
PlayerManager *PlayerManager::instance() // static
{
static PlayerManager manager;
return &manager;
}
bool PlayerManager::playing() const
{
if(!m_setup)
......@@ -175,14 +171,10 @@ FileHandle PlayerManager::playingFile() const
QString PlayerManager::playingString() const
{
if(!playing())
if(!playing() || m_file.isNull())
return QString();
QString str = m_file.tag()->artist() + " - " + m_file.tag()->title();
if(m_file.tag()->artist().isEmpty())
str = m_file.tag()->title();
return str;
return m_file.tag()->playingString();
}
void PlayerManager::setPlaylistInterface(PlaylistInterface *interface)
......@@ -226,14 +218,19 @@ void PlayerManager::play(const FileHandle &file)
{
mediaObject->setCurrentSource(KUrl::fromPath(m_file.absFilePath()));
mediaObject->play();
emit signalItemChanged(m_file);
}
}
}
else {
m_file = file;
mediaObject->setCurrentSource(KUrl::fromPath(m_file.absFilePath()));
mediaObject->setCurrentSource(KUrl::fromPath(file.absFilePath()));
mediaObject->play();
if(m_file != file)
emit signalItemChanged(file);
m_file = file;
}
// Our state changed handler will perform the follow up actions necessary
......@@ -286,6 +283,11 @@ void PlayerManager::stop()
stopCrossfade();
m_media[0]->stop();
m_media[1]->stop();
if(!m_file.isNull()) {
m_file = FileHandle::null();
emit signalItemChanged(m_file);
}
}
void PlayerManager::setVolume(float volume)
......@@ -417,6 +419,7 @@ void PlayerManager::slotFinished()
stop();
}
else {
emit signalItemChanged(m_file);
m_media[m_curOutputPath]->setCurrentSource(m_file.absFilePath());
m_media[m_curOutputPath]->play();
}
......@@ -594,6 +597,7 @@ void PlayerManager::crossfadeToFile(const FileHandle &newFile)
m_fader[nextOutputPath]->setVolume(0.0f);
emit signalItemChanged(newFile);
m_media[nextOutputPath]->setCurrentSource(newFile.absFilePath());
m_media[nextOutputPath]->play();
......
......@@ -51,13 +51,10 @@ class PlayerManager : public QObject
{
Q_OBJECT
protected:
public:
PlayerManager();
virtual ~PlayerManager();
public:
static PlayerManager *instance();
bool playing() const;
bool paused() const;
float volume() const;
......@@ -106,6 +103,7 @@ signals:
void signalPlay();
void signalPause();
void signalStop();
void signalItemChanged(const FileHandle &file);
private:
void setup();
......
......@@ -158,6 +158,12 @@ PlaylistBox::PlaylistBox(QWidget *parent, QStackedWidget *playlistStack) :
m_savePlaylistTimer = 0;
KToggleAction *historyAction =
new KToggleAction(KIcon("view-history"), i18n("Show &History"), ActionCollection::actions());
ActionCollection::actions()->addAction("showHistory", historyAction);
connect(historyAction, SIGNAL(triggered(bool)),
this, SLOT(slotSetHistoryPlaylistEnabled(bool)));
m_showTimer = new QTimer(this);
connect(m_showTimer, SIGNAL(timeout()), SLOT(slotShowDropTarget()));
......@@ -244,6 +250,15 @@ void PlaylistBox::slotPlaylistDataChanged()
m_savePlaylistTimer->start(); // Restarts the timer if it's already running.
}
void PlaylistBox::slotSetHistoryPlaylistEnabled(bool enable)
{
setHistoryPlaylistEnabled(enable);
if(enable) {
connect(this, SIGNAL(playingItemChanged(FileHandle)),
historyPlaylist(), SLOT(appendProposedItem(FileHandle)));
}
}
void PlaylistBox::setupPlaylist(Playlist *playlist, const QString &iconName)
{
setupPlaylist(playlist, iconName, 0);
......@@ -675,7 +690,7 @@ void PlaylistBox::slotDoubleClicked(Q3ListViewItem *item)
PlaylistItem *next = manager->nextItem(); // Allow manager to choose
if(next) {
PlayerManager::instance()->play(next->file());
emit startFilePlayback(next->file());
playlistItem->playlist()->setPlaying(next);
}
else
......
......@@ -72,6 +72,7 @@ public slots:
void slotFreezePlaylists();
void slotUnfreezePlaylists();
void slotPlaylistDataChanged();
void slotSetHistoryPlaylistEnabled(bool enable);
protected:
virtual void setupPlaylist(Playlist *playlist, const QString &iconName);
......@@ -80,6 +81,7 @@ protected:
signals:
void signalPlaylistDestroyed(Playlist *);
void startupComplete(); ///< Emitted after playlists are loaded.
void startFilePlayback(const FileHandle &file);
private:
void readConfig();
......
......@@ -86,7 +86,6 @@ PlaylistCollection::PlaylistCollection(QStackedWidget *playlistStack) :
m_instance = this;
m_actionHandler = new ActionHandler(this);
PlayerManager::instance()->setPlaylistInterface(this);
// KDirLister's auto error handling seems to crash JuK during startup in
// readConfig().
......@@ -99,7 +98,6 @@ PlaylistCollection::~PlaylistCollection()
{
saveConfig();
delete m_actionHandler;
PlayerManager::instance()->setPlaylistInterface(0);
Playlist::setShuttingDown();
}
......@@ -906,16 +904,10 @@ PlaylistCollection::ActionHandler::ActionHandler(PlaylistCollection *collection)
menu->addAction(createAction(i18n("Show Cover &Manager"),
SLOT(slotShowCoverManager()), "showCoverManager"));
KToggleAction *historyAction =
new KToggleAction(KIcon("view-history"), i18n("Show &History"), actions());
actions()->addAction("showHistory", historyAction);
KToggleAction *upcomingAction =
new KToggleAction(KIcon("go-jump-today"), i18n("Show &Play Queue"), actions());
actions()->addAction("showUpcoming", upcomingAction);
connect(historyAction, SIGNAL(triggered(bool)),
this, SLOT(slotSetHistoryPlaylistEnabled(bool)));
connect(upcomingAction, SIGNAL(triggered(bool)),
this, SLOT(slotSetUpcomingPlaylistEnabled(bool)));
}
......
......@@ -256,7 +256,6 @@ private slots:
void slotGuessTagFromInternet() { m_collection->guessTagFromInternet(); }
void slotSetSearchEnabled(bool enable) { m_collection->setSearchEnabled(enable); }
void slotSetHistoryPlaylistEnabled(bool enable) { m_collection->setHistoryPlaylistEnabled(enable); }
void slotSetUpcomingPlaylistEnabled(bool enable) { m_collection->setUpcomingPlaylistEnabled(enable); }
void slotShowCoverManager() { m_collection->showCoverManager(); }
void slotEnableDirWatch(bool enable) { m_collection->enableDirWatch(enable); }
......
......@@ -28,6 +28,7 @@
#include <QEvent>
#include <QVBoxLayout>
#include <QLatin1String>
#include <QList>
#include <QStackedWidget>
#include <QSizePolicy>
......@@ -45,16 +46,17 @@
// public methods
////////////////////////////////////////////////////////////////////////////////
PlaylistSplitter::PlaylistSplitter(QWidget *parent, const char *name) :
PlaylistSplitter::PlaylistSplitter(PlayerManager *player, QWidget *parent) :
QSplitter(Qt::Horizontal, parent),
m_newVisible(0),
m_playlistBox(0),
m_searchWidget(0),
m_playlistStack(0),
m_editor(0),
m_nowPlaying(0)
m_nowPlaying(0),
m_player(player)
{
setObjectName(name);
setObjectName(QLatin1String("playlistSplitter"));
setupActions();
setupLayout();
......@@ -62,6 +64,9 @@ PlaylistSplitter::PlaylistSplitter(QWidget *parent, const char *name) :
m_editor->slotUpdateCollection();
m_editor->setupObservers();
connect(m_player, SIGNAL(signalItemChanged(FileHandle)),
this, SIGNAL(playingItemChanged(FileHandle)));
}
PlaylistSplitter::~PlaylistSplitter()
......@@ -197,6 +202,10 @@ void PlaylistSplitter::setupLayout()
connect(m_playlistBox, SIGNAL(signalPlaylistDestroyed(Playlist *)),
m_editor, SLOT(slotPlaylistDestroyed(Playlist *)));
connect(m_playlistBox, SIGNAL(startupComplete()), SLOT(slotEnable()));
connect(m_playlistBox, SIGNAL(startFilePlayback(FileHandle)),
m_player, SLOT(play(FileHandle)));
m_player->setPlaylistInterface(m_playlistBox);
// Let interested parties know we're ready
connect(m_playlistBox, SIGNAL(startupComplete()), SIGNAL(guiReady()));
......@@ -204,6 +213,8 @@ void PlaylistSplitter::setupLayout()
insertWidget(0, m_playlistBox);
m_nowPlaying = new NowPlaying(top, m_playlistBox);
connect(m_player, SIGNAL(signalItemChanged(FileHandle)),
m_nowPlaying, SLOT(slotUpdate(FileHandle)));
// Create the search widget -- this must be done after the CollectionList is created.
......
......@@ -26,6 +26,8 @@ class PlaylistInterface;
class TagEditor;
class PlaylistBox;
class NowPlaying;
class PlayerManager;
class FileHandle;
/**
* This is the main layout class of JuK. It should contain a PlaylistBox and
......@@ -41,7 +43,7 @@ class PlaylistSplitter : public QSplitter
Q_OBJECT
public:
explicit PlaylistSplitter(QWidget *parent, const char *name = 0);
PlaylistSplitter(PlayerManager *player, QWidget *parent);
virtual ~PlaylistSplitter();
PlaylistInterface *playlist() const;
......@@ -56,6 +58,8 @@ signals:
*/
void guiReady();
void playingItemChanged(const FileHandle &file);
public slots:
virtual void setFocus();
virtual void slotFocusCurrentPlaylist();
......@@ -91,6 +95,7 @@ private:
QStackedWidget *m_playlistStack;
TagEditor *m_editor;
NowPlaying *m_nowPlaying;
PlayerManager *m_player;
};
#endif
......
......@@ -136,12 +136,13 @@ void PassiveInfo::positionSelf()
// public methods
////////////////////////////////////////////////////////////////////////////////
SystemTray::SystemTray(QWidget *parent) : KStatusNotifierItem(parent),
m_popup(0),
m_fadeTimer(0),
m_fade(true),
m_hasCompositionManager(false)
SystemTray::SystemTray(PlayerManager *player, QWidget *parent) :
KStatusNotifierItem(parent),
m_popup(0),
m_player(player),
m_fadeTimer(0),
m_fade(true),
m_hasCompositionManager(false)
{
// This should be initialized to the number of labels that are used.
m_labels.fill(0, 3);
......@@ -162,9 +163,9 @@ SystemTray::SystemTray(QWidget *parent) : KStatusNotifierItem(parent),
KMenu *cm = contextMenu();
connect(PlayerManager::instance(), SIGNAL(signalPlay()), this, SLOT(slotPlay()));
connect(PlayerManager::instance(), SIGNAL(signalPause()), this, SLOT(slotPause()));
connect(PlayerManager::instance(), SIGNAL(signalStop()), this, SLOT(slotStop()));
connect(m_player, SIGNAL(signalPlay()), this, SLOT(slotPlay()));
connect(m_player, SIGNAL(signalPause()), this, SLOT(slotPause()));
connect(m_player, SIGNAL(signalStop()), this, SLOT(slotStop()));
cm->addAction( action("play") );
cm->addAction( action("pause") );
......@@ -196,9 +197,9 @@ SystemTray::SystemTray(QWidget *parent) : KStatusNotifierItem(parent),
connect(this, SIGNAL(secondaryActivateRequested(const QPoint &)),
action("playPause"), SLOT(trigger()));
if(PlayerManager::instance()->playing())
if(m_player->playing())
slotPlay();
else if(PlayerManager::instance()->paused())
else if(m_player->paused())
slotPause();
}
......@@ -208,13 +209,13 @@ SystemTray::SystemTray(QWidget *parent) : KStatusNotifierItem(parent),
void SystemTray::slotPlay()
{
if(!PlayerManager::instance()->playing())
if(!m_player->playing())
return;
QPixmap cover = PlayerManager::instance()->playingFile().coverInfo()->pixmap(CoverInfo::Thumbnail);
QPixmap cover = m_player->playingFile().coverInfo()->pixmap(CoverInfo::Thumbnail);
setOverlayIconByName("media-playback-start");
setToolTip(PlayerManager::instance()->playingString(), cover);
setToolTip(m_player->playingString(), cover);
createPopup();
}
......@@ -233,10 +234,10 @@ void SystemTray::slotTogglePopup()
void SystemTray::slotPopupLargeCover()
{
if(!PlayerManager::instance()->playing())
if(!m_player->playing())
return;
FileHandle playingFile = PlayerManager::instance()->playingFile();
FileHandle playingFile = m_player->playingFile();
playingFile.coverInfo()->popup();
}
......@@ -343,7 +344,7 @@ KVBox *SystemTray::createPopupLayout(QWidget *parent, const FileHandle &file)
void SystemTray::createPopup()
{
FileHandle playingFile = PlayerManager::instance()->playingFile();
FileHandle playingFile = m_player->playingFile();
Tag *playingInfo = playingFile.tag();
// If the action exists and it's checked, do our stuff
......
......@@ -30,6 +30,7 @@
#include <QFrame>
class SystemTray;
class PlayerManager;
class QLabel;
class QTimer;
class KVBox;
......@@ -90,7 +91,7 @@ class SystemTray : public KStatusNotifierItem
Q_OBJECT
public:
SystemTray(QWidget *parent = 0);
SystemTray(PlayerManager