1 /****************************************************************************************
2  * Copyright (c) 2007 Ian Monroe <ian@monroe.nu>                                        *
3  * Copyright (c) 2008 Seb Ruiz <ruiz@kde.org>                                           *
4  * Copyright (c) 2008 Soren Harward <stharward@gmail.com>                               *
5  *                                                                                      *
6  * This program is free software; you can redistribute it and/or modify it under        *
7  * the terms of the GNU General Public License as published by the Free Software        *
8  * Foundation; either version 2 of the License, or (at your option) version 3 or        *
9  * any later version accepted by the membership of KDE e.V. (or its successor approved  *
10  * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of  *
11  * version 3 of the license.                                                            *
12  *                                                                                      *
13  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
15  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
16  *                                                                                      *
17  * You should have received a copy of the GNU General Public License along with         *
18  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
19  ****************************************************************************************/
20 
21 #ifndef AMAROK_PLAYLISTACTIONS_H
22 #define AMAROK_PLAYLISTACTIONS_H
23 
24 #include "amarok_export.h"
25 #include "core/support/Debug.h"
26 #include "core/playlists/Playlist.h"
27 
28 #include <QQueue>
29 #include <QModelIndex>
30 #include <QUrl>
31 
32 #include <phonon/Global>
33 
34 namespace Playlist
35 {
36     class Actions;
37 }
38 
39 namespace The
40 {
41     AMAROK_EXPORT Playlist::Actions* playlistActions();
42 }
43 
44 namespace Playlist
45 {
46 class TrackNavigator;
47 
48 /**
49  * This class is a central hub between the playlist model stack, the playlist navigators,
50  * and the track playback engine. It ties them together to provide simple "Play", "Play
51  * Next", etc. commands to the GUI code.
52  */
53 
54 class AMAROK_EXPORT Actions : public QObject
55 {
56     Q_OBJECT
57 
58 public:
59 
60     static Actions* instance();
61     static void destroy();
62 
63 
64     Meta::TrackPtr likelyNextTrack();
65     Meta::TrackPtr likelyPrevTrack();
66 
67     /**
68      * This is called by the engine before the current track ends. It
69      * will figure out the next track and enqueue it. This won't
70      * actually change the track. That happens in the engine when the
71      * current track ends.
72      */
73     void requestNextTrack();
74 
75     /**
76      * Figure out the next track, and start playing it immediately.
77      */
78     void requestUserNextTrack();
79 
80     /**
81      * Figure out the previous track and start playing it immediately.
82      */
83     void requestPrevTrack();
84 
85     /**
86      * Set next track from track id, but don't start playing immediately
87      */
88     void requestTrack( quint64 id );
89 
90     /**
91      * Request that Amarok stops playback after playing certain track.
92      * @param id playlist id of a track to stop playing after or 0 to disable
93      *           stopping after some track. If not specified, enable stopping
94      *           after currently playing track.
95      */
96     void stopAfterPlayingTrack( quint64 id = -1 );
97 
98     bool willStopAfterTrack( const quint64 id ) const;
99 
100     // This shouldn't be in Actions, it doesn't make sense
101     int queuePosition( quint64 id );
102 
103     // nor should this, ideally this and queuePosition
104     // should be in TrackNavigator and TrackNavigator
105     // should be publicly accessible
106     QQueue<quint64> queue();
107 
108     bool queueMoveUp( quint64 id );
109     bool queueMoveDown( quint64 id );
110     void dequeue( quint64 id );
111 
112 public Q_SLOTS:
113     void play();
114     void play( const int row );
115     void play( const QModelIndex& index );
116     void play( const quint64 id, bool now = true );
117     void next();
118     void back();
119     void enableDynamicMode( bool enable );
120 
121     /** Changes the tracknavigator depending on the current configuration */
122     void playlistModeChanged();
123 
124     void repopulateDynamicPlaylist();
125 
126     /**
127       * Shuffles tracks (that are visible in the top model) at the bottom model level
128       */
129     void shuffle();
130 
131     /**
132      * Adds a list of top playlist model rows to the queue.
133      */
134     void queue( const QList<int> &rows );
135 
136     /**
137      * Adds a list of playlist item unique ids to the queue.
138      */
139     void queue( const QList<quint64> &ids );
140 
141     void dequeue( const QList<int> &rows );
142     void restoreDefaultPlaylist();
143 
144     /**
145      * Make sure that there are enough tracks in the current playlist
146      * if it is dynamic and the user removed tracks.
147      */
148     void normalizeDynamicPlaylist();
149 
150 
151     /**
152     * Repaint the playlist.
153     * Useful when triggering a change that will modify the visual appearance of one or more items in the playlist
154     */
155     void repaintPlaylist();
156 
157 Q_SIGNALS:
158     void navigatorChanged();
159 
160 private Q_SLOTS:
161     void slotTrackPlaying( Meta::TrackPtr engineTrack );
162     void slotPlayingStopped( qint64 finalPosition, qint64 trackLength );
163 
164 private:
165     Actions();
166     ~Actions() override;
167 
168     void init();
169 
170     quint64 m_nextTrackCandidate;
171     /**
172      * Playlist id if a track where the playback should be stopped or 0 if playback
173      * shouldn't be stopped after certain track
174      */
175     quint64 m_stopAfterPlayingTrackId;
176     TrackNavigator* m_navigator;                //!< the strategy of what to do when a track finishes playing
177     bool m_waitingForNextTrack;
178 
179     static Actions* s_instance; //!< instance variable
180 };
181 } // namespace Playlist
182 
183 #endif
184