diff --git a/src/core/mpris1.cpp b/src/core/mpris1.cpp index f6a4be0df..84467ccd1 100644 --- a/src/core/mpris1.cpp +++ b/src/core/mpris1.cpp @@ -31,7 +31,7 @@ namespace mpris { -Mpris1::Mpris1(Player* player, ArtLoader* art_loader, QObject* parent) +Mpris1::Mpris1(PlayerInterface* player, ArtLoader* art_loader, QObject* parent) : QObject(parent) { qDBusRegisterMetaType(); @@ -47,13 +47,13 @@ Mpris1::Mpris1(Player* player, ArtLoader* art_loader, QObject* parent) player_, SLOT(CurrentSongChanged(Song,QString))); } -Mpris1Root::Mpris1Root(Player* player, QObject* parent) +Mpris1Root::Mpris1Root(PlayerInterface* player, QObject* parent) : QObject(parent), player_(player) { new MprisRoot(this); QDBusConnection::sessionBus().registerObject("/", this); } -Mpris1Player::Mpris1Player(Player* player, QObject* parent) +Mpris1Player::Mpris1Player(PlayerInterface* player, QObject* parent) : QObject(parent), player_(player) { new MprisPlayer(this); QDBusConnection::sessionBus().registerObject("/Player", this); @@ -70,7 +70,7 @@ void Mpris1Player::PlaylistManagerInitialized() { SLOT(RepeatModeChanged())); } -Mpris1TrackList::Mpris1TrackList(Player* player, QObject* parent) +Mpris1TrackList::Mpris1TrackList(PlayerInterface* player, QObject* parent) : QObject(parent), player_(player) { new MprisTrackList(this); QDBusConnection::sessionBus().registerObject("/TrackList", this); @@ -192,7 +192,7 @@ int Mpris1Player::VolumeGet() const { } void Mpris1Player::PositionSet(int pos_msec) { - player_->Seek(pos_msec / 1e3); + player_->SeekTo(pos_msec / 1e3); } int Mpris1Player::PositionGet() const { diff --git a/src/core/mpris1.h b/src/core/mpris1.h index ab0af22cf..3a29678d9 100644 --- a/src/core/mpris1.h +++ b/src/core/mpris1.h @@ -24,7 +24,7 @@ #include #include -class Player; +class PlayerInterface; class Playlist; struct DBusStatus { // From Amarok. @@ -79,7 +79,7 @@ class Mpris1 : public QObject { Q_OBJECT public: - Mpris1(Player* player, ArtLoader* art_loader, QObject* parent = 0); + Mpris1(PlayerInterface* player, ArtLoader* art_loader, QObject* parent = 0); static QVariantMap GetMetadata(const Song& song); @@ -98,14 +98,14 @@ class Mpris1Root : public QObject { Q_OBJECT public: - Mpris1Root(Player* player, QObject* parent = 0); + Mpris1Root(PlayerInterface* player, QObject* parent = 0); QString Identity(); void Quit(); Version MprisVersion(); private: - Player* player_; + PlayerInterface* player_; }; @@ -113,7 +113,7 @@ class Mpris1Player : public QObject { Q_OBJECT public: - Mpris1Player(Player* player, QObject* parent = 0); + Mpris1Player(PlayerInterface* player, QObject* parent = 0); void Pause(); void Stop(); @@ -157,7 +157,7 @@ private slots: void RepeatModeChanged(); private: - Player* player_; + PlayerInterface* player_; QVariantMap last_metadata_; }; @@ -167,7 +167,7 @@ class Mpris1TrackList : public QObject { Q_OBJECT public: - Mpris1TrackList(Player* player, QObject* parent = 0); + Mpris1TrackList(PlayerInterface* player, QObject* parent = 0); int AddTrack(const QString&, bool); void DelTrack(int index); @@ -187,7 +187,7 @@ private slots: void PlaylistChanged(Playlist* playlist); private: - Player* player_; + PlayerInterface* player_; }; } // namespace mpris diff --git a/src/core/mpris2.cpp b/src/core/mpris2.cpp index 8ce25384c..36cdc46d5 100644 --- a/src/core/mpris2.cpp +++ b/src/core/mpris2.cpp @@ -43,7 +43,7 @@ const char* Mpris2::kMprisObjectPath = "/org/mpris/MediaPlayer2"; const char* Mpris2::kServiceName = "org.mpris.MediaPlayer2.clementine"; const char* Mpris2::kFreedesktopPath = "org.freedesktop.DBus.Properties"; -Mpris2::Mpris2(Player* player, ArtLoader* art_loader, +Mpris2::Mpris2(PlayerInterface* player, ArtLoader* art_loader, Mpris1* mpris1, QObject* parent) : QObject(parent), player_(player), @@ -400,7 +400,7 @@ void Mpris2::Play() { void Mpris2::Seek(qlonglong offset) { if(CanSeek()) { - player_->Seek(player_->engine()->position_nanosec() / 1e9 + offset / 1e6); + player_->SeekTo(player_->engine()->position_nanosec() / 1e9 + offset / 1e6); } } @@ -409,7 +409,7 @@ void Mpris2::SetPosition(const QDBusObjectPath& trackId, qlonglong offset) { offset *= 1e3; if(offset < player_->GetCurrentItem()->Metadata().length_nanosec()) { - player_->Seek(offset / 1e9); + player_->SeekTo(offset / 1e9); } } } diff --git a/src/core/mpris2.h b/src/core/mpris2.h index 760f6d663..d4a2bf77d 100644 --- a/src/core/mpris2.h +++ b/src/core/mpris2.h @@ -27,7 +27,7 @@ #include class MainWindow; -class Player; +class PlayerInterface; typedef QList TrackMetadata; typedef QList TrackIds; @@ -72,7 +72,8 @@ class Mpris2 : public QObject { Q_PROPERTY( bool CanEditTracks READ CanEditTracks ) public: - Mpris2(Player* player, ArtLoader* art_loader, Mpris1* mpris1, QObject* parent = 0); + Mpris2(PlayerInterface* player, ArtLoader* art_loader, Mpris1* mpris1, + QObject* parent = 0); void InitLibIndicate(); @@ -170,7 +171,7 @@ private: QVariantMap last_metadata_; - Player* player_; + PlayerInterface* player_; Mpris1* mpris1_; }; diff --git a/src/core/player.cpp b/src/core/player.cpp index b02f4acf3..1605bba4e 100644 --- a/src/core/player.cpp +++ b/src/core/player.cpp @@ -36,16 +36,10 @@ using boost::shared_ptr; -Player::Player(PlaylistManager* playlists, -#ifdef HAVE_LIBLASTFM - LastFMService* lastfm, -#endif - QObject* parent) - : QObject(parent), +Player::Player(PlaylistManager* playlists, LastFMService* lastfm, QObject* parent) + : PlayerInterface(parent), playlists_(playlists), -#ifdef HAVE_LIBLASTFM lastfm_(lastfm), -#endif engine_(new GstEngine), stream_change_type_(Engine::First), last_state_(Engine::Empty), @@ -282,7 +276,7 @@ void Player::CurrentMetadataChanged(const Song& metadata) { #endif } -void Player::Seek(int seconds) { +void Player::SeekTo(int seconds) { qint64 nanosec = qBound(0ll, qint64(seconds) * qint64(1e9), engine_->length_nanosec()); engine_->Seek(nanosec); @@ -294,11 +288,11 @@ void Player::Seek(int seconds) { } void Player::SeekForward() { - Seek(engine()->position_nanosec() / 1e9 + 5); + SeekTo(engine()->position_nanosec() / 1e9 + 5); } void Player::SeekBackward() { - Seek(engine()->position_nanosec() / 1e9 - 5); + SeekTo(engine()->position_nanosec() / 1e9 - 5); } void Player::EngineMetadataReceived(const Engine::SimpleMetaBundle& bundle) { @@ -365,7 +359,7 @@ void Player::Pause() { void Player::Play() { switch (GetState()) { case Engine::Playing: - Seek(0); + SeekTo(0); break; case Engine::Paused: engine_->Unpause(); diff --git a/src/core/player.h b/src/core/player.h index d5a8e8079..dfd91d61f 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -29,23 +29,77 @@ #include "engines/engine_fwd.h" #include "playlist/playlistitem.h" +class LastFMService; class PlaylistManager; class Settings; class MainWindow; -#ifdef HAVE_LIBLASTFM - class LastFMService; -#endif -class Player : public QObject { +class PlayerInterface : public QObject { Q_OBJECT - public: - Player(PlaylistManager* playlists, -#ifdef HAVE_LIBLASTFM - LastFMService* lastfm, -#endif - QObject* parent = 0); +public: + PlayerInterface(QObject* parent = 0) : QObject(parent) {} + + virtual EngineBase* engine() const = 0; + virtual Engine::State GetState() const = 0; + virtual int GetVolume() const = 0; + + virtual PlaylistItemPtr GetCurrentItem() const = 0; + virtual PlaylistItemPtr GetItemAt(int pos) const = 0; + virtual PlaylistManager* playlists() const = 0; + +public slots: + virtual void ReloadSettings() = 0; + + // Manual track change to the specified track + virtual void PlayAt(int i, Engine::TrackChangeType change, bool reshuffle) = 0; + + // If there's currently a song playing, pause it, otherwise play the track + // that was playing last, or the first one on the playlist + virtual void PlayPause() = 0; + + // Skips this track. Might load more of the current radio station. + virtual void Next() = 0; + + virtual void Previous() = 0; + virtual void SetVolume(int value) = 0; + virtual void VolumeUp() = 0; + virtual void VolumeDown() = 0; + virtual void SeekTo(int seconds) = 0; + // Moves the position of the currently playing song five seconds forward. + virtual void SeekForward() = 0; + // Moves the position of the currently playing song five seconds backwards. + virtual void SeekBackward() = 0; + + virtual void HandleSpecialLoad(const PlaylistItem::SpecialLoadResult& result) = 0; + virtual void CurrentMetadataChanged(const Song& metadata) = 0; + + virtual void Mute() = 0; + virtual void Pause() = 0; + virtual void Stop() = 0; + virtual void Play() = 0; + virtual void ShowOSD() = 0; + +signals: + void Playing(); + void Paused(); + void Stopped(); + void PlaylistFinished(); + void VolumeChanged(int volume); + void Error(const QString& message); + void TrackSkipped(PlaylistItemPtr old_track); + // Emitted when there's a manual change to the current's track position. + void Seeked(qlonglong microseconds); + + void ForceShowOSD(Song); +}; + +class Player : public PlayerInterface { + Q_OBJECT + +public: + Player(PlaylistManager* playlists, LastFMService* lastfm, QObject* parent = 0); ~Player(); void Init(); @@ -58,27 +112,18 @@ class Player : public QObject { PlaylistItemPtr GetItemAt(int pos) const; PlaylistManager* playlists() const { return playlists_; } - public slots: +public slots: void ReloadSettings(); - // Manual track change to the specified track void PlayAt(int i, Engine::TrackChangeType change, bool reshuffle); - - // If there's currently a song playing, pause it, otherwise play the track - // that was playing last, or the first one on the playlist void PlayPause(); - - // Skips this track. Might load more of the current radio station. void Next(); - void Previous(); void SetVolume(int value); void VolumeUp() { SetVolume(GetVolume() + 5); } void VolumeDown() { SetVolume(GetVolume() - 5); } - void Seek(int seconds); - // Moves the position of the currently playing song five seconds forward. + void SeekTo(int seconds); void SeekForward(); - // Moves the position of the currently playing song five seconds backwards. void SeekBackward(); void HandleSpecialLoad(const PlaylistItem::SpecialLoadResult& result); @@ -90,19 +135,6 @@ class Player : public QObject { void Play(); void ShowOSD(); - signals: - void Playing(); - void Paused(); - void Stopped(); - void PlaylistFinished(); - void VolumeChanged(int volume); - void Error(const QString& message); - void TrackSkipped(PlaylistItemPtr old_track); - // Emitted when there's a manual change to the current's track position. - void Seeked(qlonglong microseconds); - - void ForceShowOSD(Song); - private slots: void EngineStateChanged(Engine::State); void EngineMetadataReceived(const Engine::SimpleMetaBundle& bundle); @@ -116,9 +148,7 @@ class Player : public QObject { private: PlaylistManager* playlists_; -#ifdef HAVE_LIBLASTFM LastFMService* lastfm_; -#endif QSettings settings_; PlaylistItemPtr current_item_; diff --git a/src/main.cpp b/src/main.cpp index 9202989e3..773b2a8cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,6 +75,8 @@ using boost::scoped_ptr; #ifdef HAVE_LIBLASTFM #include "radio/lastfmservice.h" +#else + class LastFMService; #endif #ifdef HAVE_DBUS @@ -292,19 +294,24 @@ int main(int argc, char *argv[]) { // Seed the random number generator srand(time(NULL)); + // Create some key objects scoped_ptr > database( new BackgroundThreadImplementation(NULL)); database->Start(true); TaskManager task_manager; PlaylistManager playlists(&task_manager, NULL); - RadioModel radio_model(database.get(), &task_manager, NULL); - Player player(&playlists -#ifdef HAVE_LIBLASTFM - ,RadioModel::Service() -#endif - ); + // Get the last.fm service if it's available + LastFMService* lastfm_service = NULL; +#ifdef HAVE_LIBLASTFM + lastfm_service = RadioModel::Service(); +#endif + + // Create the player + Player player(&playlists, lastfm_service); + + // Create the tray icon and OSD scoped_ptr tray_icon(SystemTrayIcon::CreateSystemTrayIcon()); OSD osd(tray_icon.get()); diff --git a/src/scripting/python/player.sip b/src/scripting/python/player.sip index cf567824e..571ece8ab 100644 --- a/src/scripting/python/player.sip +++ b/src/scripting/python/player.sip @@ -1,4 +1,4 @@ -class Player : QObject { +class PlayerInterface : QObject { %TypeHeaderCode #include "core/player.h" @@ -29,7 +29,7 @@ public slots: void VolumeDown(); void Mute(); - void Seek(int seconds); + void SeekTo(int seconds); void SeekForward(); void SeekBackward(); @@ -50,5 +50,5 @@ signals: void ForceShowOSD(Song); private: - Player(); + PlayerInterface(); }; diff --git a/src/scripting/python/pythonengine.cpp b/src/scripting/python/pythonengine.cpp index e6ddd268c..a484f23d7 100644 --- a/src/scripting/python/pythonengine.cpp +++ b/src/scripting/python/pythonengine.cpp @@ -132,7 +132,7 @@ Script* PythonEngine::CreateScript(const ScriptInfo& info) { if (manager()->data().valid_) { AddObject(manager()->data().library_->backend(), sipType_LibraryBackend, "library"); AddObject(manager()->data().library_view_, sipType_LibraryView, "library_view"); - AddObject(manager()->data().player_, sipType_Player, "player"); + AddObject(manager()->data().player_, sipType_PlayerInterface, "player"); AddObject(manager()->data().playlists_, sipType_PlaylistManager, "playlists"); AddObject(manager()->data().radio_model_, sipType_RadioModel, "radio_model"); AddObject(manager()->data().settings_dialog_, sipType_SettingsDialog, "settings_dialog"); diff --git a/src/scripting/python/scriptinterface.sip b/src/scripting/python/scriptinterface.sip index bab9379d0..14280921b 100644 --- a/src/scripting/python/scriptinterface.sip +++ b/src/scripting/python/scriptinterface.sip @@ -16,7 +16,7 @@ class ScriptInterface : QObject { CLASS(MergedProxyModel), CLASS(NetworkAccessManager), CLASS(ParserBase), - CLASS(Player), + CLASS(PlayerInterface), CLASS(Playlist), CLASS(PlaylistManager), CLASS(PlaylistParser), diff --git a/src/scripting/scriptmanager.h b/src/scripting/scriptmanager.h index 1fff7fe66..6f88ed095 100644 --- a/src/scripting/scriptmanager.h +++ b/src/scripting/scriptmanager.h @@ -28,7 +28,7 @@ class LanguageEngine; class Library; class LibraryView; -class Player; +class PlayerInterface; class PlaylistManager; class RadioModel; class Script; @@ -58,9 +58,10 @@ public: struct GlobalData { GlobalData() : valid_(false) {} - GlobalData(Library* library, LibraryView* library_view, Player* player, - PlaylistManager* playlists, TaskManager* task_manager, - SettingsDialog* settings_dialog, RadioModel* radio_model) + GlobalData(Library* library, LibraryView* library_view, + PlayerInterface* player, PlaylistManager* playlists, + TaskManager* task_manager, SettingsDialog* settings_dialog, + RadioModel* radio_model) : valid_(true), library_(library), library_view_(library_view), @@ -74,7 +75,7 @@ public: bool valid_; Library* library_; LibraryView* library_view_; - Player* player_; + PlayerInterface* player_; PlaylistManager* playlists_; TaskManager* task_manager_; SettingsDialog* settings_dialog_; diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 86d3fad1f..29b6ebc1c 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -401,7 +401,7 @@ MainWindow::MainWindow( connect(ui_->playlist->view(), SIGNAL(RightClicked(QPoint,QModelIndex)), SLOT(PlaylistRightClick(QPoint,QModelIndex))); connect(ui_->playlist->view(), SIGNAL(SeekTrack(int)), ui_->track_slider, SLOT(Seek(int))); - connect(ui_->track_slider, SIGNAL(ValueChanged(int)), player_, SLOT(Seek(int))); + connect(ui_->track_slider, SIGNAL(ValueChanged(int)), player_, SLOT(SeekTo(int))); // Database connections connect(database_->Worker().get(), SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString))); @@ -1400,9 +1400,9 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) { player_->SetVolume(player_->GetVolume() + options.volume_modifier()); if (options.seek_to() != -1) - player_->Seek(options.seek_to() * 1e9); + player_->SeekTo(options.seek_to() * 1e9); else if (options.seek_by() != 0) - player_->Seek(player_->engine()->position_nanosec() + options.seek_by() * 1e9); + player_->SeekTo(player_->engine()->position_nanosec() + options.seek_by() * 1e9); if (options.play_track_at() != -1) player_->PlayAt(options.play_track_at(), Engine::Manual, true);