File indexing completed on 2024-05-05 04:48:42
0001 /**************************************************************************************** 0002 * Copyright (c) 2007 Ian Monroe <ian@monroe.nu> * 0003 * Copyright (c) 2008 Seb Ruiz <ruiz@kde.org> * 0004 * Copyright (c) 2008 Soren Harward <stharward@gmail.com> * 0005 * Copyright (c) 2009,2010 Téo Mrnjavac <teo@kde.org> * 0006 * * 0007 * This program is free software; you can redistribute it and/or modify it under * 0008 * the terms of the GNU General Public License as published by the Free Software * 0009 * Foundation; either version 2 of the License, or (at your option) version 3 or * 0010 * any later version accepted by the membership of KDE e.V. (or its successor approved * 0011 * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of * 0012 * version 3 of the license. * 0013 * * 0014 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0015 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0016 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0017 * * 0018 * You should have received a copy of the GNU General Public License along with * 0019 * this program. If not, see <http://www.gnu.org/licenses/>. * 0020 ****************************************************************************************/ 0021 0022 #ifndef AMAROK_PLAYLISTCONTROLLER_H 0023 #define AMAROK_PLAYLISTCONTROLLER_H 0024 0025 #include "UndoCommands.h" 0026 #include "amarok_export.h" 0027 #include "core/meta/forward_declarations.h" 0028 #include "core/playlists/Playlist.h" 0029 0030 #include <QObject> 0031 0032 class QUndoStack; 0033 0034 namespace Playlist 0035 { 0036 class AbstractModel; 0037 0038 /** 0039 * No options means: append at the end of the playlist (without touching playing 0040 * state) 0041 */ 0042 enum AddOption 0043 { 0044 Replace = 1, ///< replaces the playlist instead of default appending (or queueing) 0045 Queue = 2, ///< inserts media into the queue after the currentTrack instead of default 0046 /// appending to the end of the playlist 0047 PrependToQueue = Queue | 4, ///< prepends media to the queue (after current track), implies Queue 0048 DirectPlay = PrependToQueue | 8, ///< start playback of the first item in the list, implies PrependToQueue 0049 RemotePlaylistsAreStreams = 16, ///< treat remote urls pointing to playlists as streams. 0050 /// only has sense for methods that accept urls or playlists 0051 StartPlayIfConfigured = 32, ///< start playing the first added track if Amarok is 0052 /// configured so and nothing else is already playing 0053 0054 // following are "consistency convenience enums" so that it is easy for us to make the 0055 // bahaviour of similarly-looking UI elements the same. These enums are the preferred 0056 // ones on calling sites. Feel free to add a new one if you find another UI element 0057 // that appears on multiple places. Prefix these with On*. 0058 OnDoubleClickOnSelectedItems = StartPlayIfConfigured, 0059 OnMiddleClickOnSelectedItems = DirectPlay, 0060 OnReturnPressedOnSelectedItems = StartPlayIfConfigured, // append, should be kept same as double-click 0061 0062 OnPlayMediaAction = DirectPlay, 0063 OnAppendToPlaylistAction = 0, // double-click is always available, so don't add StartPlayIfConfigured here 0064 OnReplacePlaylistAction = Replace | StartPlayIfConfigured, 0065 OnQueueToPlaylistAction = Queue | StartPlayIfConfigured, 0066 }; 0067 Q_DECLARE_FLAGS( AddOptions, AddOption ) 0068 0069 /** The Playlist::Controller allows to add, remove or otherwise change tracks to the playlist. 0070 Instead of directly talking to The::Playlist or PlaylistModelStack this object 0071 should be used. It will take care of correctly placing the tracks (even 0072 if the playlist is sorted) and will handle undo and redo operations. 0073 */ 0074 class AMAROK_EXPORT Controller : public QObject 0075 { 0076 Q_OBJECT 0077 0078 public: 0079 /** 0080 * Accessor for the singleton pattern. 0081 * @return a pointer to the only instance of Playlist::Controller. 0082 */ 0083 static Controller *instance(); 0084 0085 /** 0086 * Singleton destructor. 0087 */ 0088 static void destroy(); 0089 0090 public Q_SLOTS: 0091 /** 0092 * Handles the insertion of one single track into the playlist, considering a set of 0093 * options that handle the specifics of the operation. 0094 * @param track the track to be inserted. 0095 * @param options the set of options to be applied to the operation. 0096 * @see enum AddOptions. 0097 */ 0098 void insertOptioned( Meta::TrackPtr track, AddOptions options = {} ); 0099 0100 /** 0101 * Handles the insertion of one or more tracks into the playlist, considering a set of 0102 * options that handle the specifics of the operation. 0103 * @param list the list of tracks to be inserted. 0104 * @param options the set of options to be applied to the operation. 0105 * @see enum AddOptions. 0106 */ 0107 void insertOptioned( Meta::TrackList list, AddOptions options = {} ); 0108 void insertOptioned( Playlists::PlaylistPtr playlist, AddOptions options = {} ); 0109 void insertOptioned( Playlists::PlaylistList list, AddOptions options = {} ); 0110 void insertOptioned( const QUrl &url, AddOptions options = {} ); 0111 void insertOptioned( QList<QUrl> &urls, AddOptions options = {} ); 0112 0113 /** 0114 * Handles the insertion of one or more tracks into the playlist on a specific row. 0115 * The rows are always considered as topmost playlist model rows. 0116 * @param topModelRow the insertion row in the topmost model. 0117 * @param track the track to be inserted. 0118 */ 0119 void insertTrack( int topModelRow, Meta::TrackPtr track ); 0120 void insertTracks( int topModelRow, Meta::TrackList list ); 0121 void insertPlaylist( int topModelRow, Playlists::PlaylistPtr playlist ); 0122 void insertPlaylists( int topModelRow, Playlists::PlaylistList playlists ); 0123 void insertUrls( int topModelRow, QList<QUrl> &urls ); 0124 0125 /** 0126 * Handles the removal of a single track from the playlist. 0127 * The rows are considered as topmost playlist model rows. 0128 * @param topModelRow the row to remove in the topmost model. 0129 */ 0130 void removeRow( int topModelRow ); 0131 0132 /** 0133 * Handles the removal of tracks from the playlist. 0134 * The rows are considered as topmost playlist model rows. 0135 * @param topModelRow the row to remove in the topmost model. 0136 * @param count the number of rows to remove. 0137 */ 0138 void removeRows( int topModelRow, int count ); 0139 0140 /** 0141 * Handles the removal of a list of tracks from the playlist. 0142 * The rows are considered as topmost playlist model rows. 0143 * @param topModelRows the list of row numbers to remove. 0144 */ 0145 void removeRows( QList<int>& topModelRows ); 0146 0147 /** 0148 * Removes unplayable and duplicate entries in the topmost playlist model, i.e. 0149 * respects playlist filters. 0150 */ 0151 void removeDeadAndDuplicates(); 0152 0153 /** 0154 * Moves a track from one row to another in the playlist. 0155 * @param topModelFrom the row containing the track that is about to be moved. 0156 * @param topModelTo the target row where the track should be moved. 0157 */ 0158 void moveRow( int topModelFrom, int topModelTo ); 0159 0160 /** 0161 * Moves a list of tracks to a specified row in the playlist. 0162 * This function returns the real starting location where the rows ended up. 0163 * For example, if you start with the following playlist: 0164 * 0 Alpha 0165 * 1 Bravo 0166 * 2 Charlie 0167 * 3 Delta 0168 * 4 Echo 0169 * 5 Foxtrot 0170 * and you call moveRows( [0,1,2], 4 ) then the playlist will end up with 0171 * 0 Delta 0172 * 1 Echo 0173 * 2 Alpha 0174 * 3 Bravo 0175 * 4 Charlie 0176 * 5 Foxtrot 0177 * and the function will return 2, because that's where the rows really ended up. 0178 * @param topModelFrom the list of rows containing the tracks that are about to be moved. 0179 * @param topModelTo the target row where the tracks should be moved. 0180 * @return the first row where the tracks ended up in the new list. 0181 */ 0182 int moveRows( QList<int>& topModelFrom, int topModelTo ); 0183 0184 /** 0185 * Reorders tracks in the playlist. For each i, track at position 0186 * topModelFrom[i] is moved to the position topModelTo[i]. Note that when track 0187 * on position A is moved to the position B, the track from position B needs to 0188 * be moved as well. As a consequence, every track position appearing 0189 * in topModelFrom needs to appear in topModelTo. 0190 * @param topModelFrom the list containing positions of tracks to be moved 0191 * @param topModelTo the list containing positions the tracks should be moved to 0192 */ 0193 void reorderRows( const QList<int> &topModelFrom, const QList<int> &topModelTo ); 0194 0195 void undo(); 0196 void redo(); 0197 void clear(); 0198 0199 Q_SIGNALS: 0200 void canRedoChanged( bool ); 0201 void canUndoChanged( bool ); 0202 0203 void changed(); 0204 0205 void replacingPlaylist(); 0206 0207 private Q_SLOTS: 0208 void slotLoaderWithOptionsFinished( const Meta::TrackList &tracks ); 0209 void slotLoaderWithRowFinished( const Meta::TrackList &tracks ); 0210 0211 private: 0212 Controller(); 0213 0214 ~Controller() override; 0215 0216 static Controller *s_instance; //!< Instance member. 0217 0218 /** 0219 * Converts a row number in 'm_topModel' to a row in 'm_bottomModel', for purposes of 0220 * insert. This is not useful for remove/move. 0221 */ 0222 int insertionTopRowToBottom( int topModelRow ); 0223 0224 /** 0225 * Handles the insertion of a list of tracks into the playlist on a specific row. 0226 * The row number is always in the *bottom* playlist model, in contrast to most other 0227 * functions in this class. 0228 * @param bottomModelRow the insertion row in the bottom model. 0229 * @param tl the Meta::TrackList to be inserted. 0230 */ 0231 void insertionHelper( int bottomModelRow, Meta::TrackList& tl ); 0232 0233 AbstractModel* m_topModel; 0234 AbstractModel* m_bottomModel; 0235 0236 QUndoStack* m_undoStack; 0237 }; 0238 } 0239 0240 Q_DECLARE_OPERATORS_FOR_FLAGS( Playlist::AddOptions ) 0241 Q_DECLARE_METATYPE( Playlist::AddOptions ) 0242 0243 namespace The 0244 { 0245 AMAROK_EXPORT Playlist::Controller* playlistController(); 0246 } 0247 0248 #endif