File indexing completed on 2024-05-19 04:49:51

0001 /****************************************************************************************
0002  * Copyright (c) 2009 Téo Mrnjavac <teo@kde.org>                                        *
0003  * Copyright (c) 2010 Nanno Langstraat <langstr@gmail.com>                              *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) any later           *
0008  * version.                                                                             *
0009  *                                                                                      *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0013  *                                                                                      *
0014  * You should have received a copy of the GNU General Public License along with         *
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0016  ****************************************************************************************/
0017 
0018 #ifndef AMAROK_PLAYLISTABSTRACTMODEL_H
0019 #define AMAROK_PLAYLISTABSTRACTMODEL_H
0020 
0021 #include "core/meta/forward_declarations.h"
0022 #include "playlist/PlaylistDefines.h"
0023 #include "playlist/PlaylistItem.h"
0024 
0025 #include <QAbstractItemModel>
0026 
0027 namespace Playlist
0028 {
0029 
0030 /**
0031  * An abstract base class that defines a common interface of any playlist model.
0032  * Members declared here must be implemented by Playlist::Model and all proxies.
0033  * @author Téo Mrnjavac <teo@kde.org>
0034  */
0035 
0036 //NOTE: While AbstractModel is ideally and logically an abstract base class with all pure
0037 //      virtual methods, there are a few exceptions.
0038 //      Some of the public methods are virtual but not pure. The implementations of those
0039 //      are inline, and are dummies (if they return anything, they return default values).
0040 //      Almost all of them are reimplemented in Playlist::ProxyBase anyway, so the only
0041 //      reason why they are not pure virtual is that this would require the dummies to
0042 //      exist in Playlist::Model, which just looks wrong.
0043 //      These methods are needed because even though they don't do anything in Playlist::
0044 //      Model, they are important parts of the interface that a complete playlist model
0045 //      must implement. Non trivial implementations are handled by the proxies, and they
0046 //      are used in the view(s), Playlist::Controller, Playlist::Actions and probably in
0047 //      many other places.  --Téo 19/7/2009
0048 
0049 class AbstractModel
0050 {
0051 public:
0052 
0053     //! Management of objects and inheritance
0054 
0055     /**
0056      * Virtual destructor
0057      * (Make it OK to delete an instance of a derived class through a pointer to this base class.)
0058      */
0059     virtual ~AbstractModel() { };
0060 
0061     /**
0062      * If you need QAbstractItemModel functions, access them through this pointer.
0063      *
0064      * This is a work-around for Qt's poor support for multiple inheritance and/or templates.
0065      * If Qt supported the full C++ inheritance system well, this class could have inherited
0066      * from QAbstractItemModel, and our descendants could have inherited from more specific
0067      * implementations of QAbstractItemModel, like QSortFilterProxyModel.
0068      * In the current Qt reality, that causes clashes.
0069      */
0070     virtual QAbstractItemModel* qaim() const = 0;
0071 
0072 
0073     //! Playlist-specific API; the functions QAbstractItemModel doesn't already offer.
0074 
0075     /**
0076      * Returns the unique playlist item id of the active track
0077      * (or 0 if no track is active).
0078      * @return The playlist item's id.
0079      */
0080     virtual quint64 activeId() const = 0;
0081 
0082     /**
0083      * Returns the currently active row, translated to proxy rows
0084      * (or -1 if the current row is not represented by this proxy).
0085      * @return The currently active (playing) row in proxy terms.
0086      */
0087     virtual int activeRow() const = 0;
0088 
0089     /**
0090      * Returns a pointer to the currently active track (or a default constructed value if
0091      * no track is active).
0092      * @return A pointer to the track.
0093      */
0094     virtual Meta::TrackPtr activeTrack() const = 0;
0095 
0096     /**
0097      * Returns all rows in the current model which match a given track pointer.
0098      * @see firstRowForTrack
0099      * @param track the track.
0100      * @return collection of rows, empty if the track pointer is invalid.
0101      */
0102     virtual QSet<int> allRowsForTrack( const Meta::TrackPtr& track ) const = 0;
0103 
0104     /**
0105      * Clears the current search term.
0106      *
0107      * Filtering MUST adapt its filter parameters to this call, but SHOULD delay doing
0108      * any work until it gets a 'filterUpdated()' call.
0109      */
0110     virtual void clearSearchTerm() {}    //dummy, needed by Playlist::Model
0111 
0112     /**
0113      * Reports if the current model exposes a given track.
0114      * @param track the track to check for.
0115      * @return true if the track is present, otherwise false.
0116      */
0117     virtual bool containsTrack( const Meta::TrackPtr& track ) const = 0;
0118 
0119     /**
0120      * Get the current search fields bitmask.
0121      * @return The current search fields.
0122      */
0123     virtual int currentSearchFields() { return -1; } //dummy, needed by Playlist::Model
0124 
0125     /**
0126      * Get the current search term.
0127      * @return The current search term.
0128      */
0129     virtual QString currentSearchTerm() { return QString(); }   //dummy, needed by Playlist::Model
0130 
0131     /**
0132      * Saves a playlist to a specified location.
0133      * @param path the path of the playlist file, as chosen by a FileDialog in MainWindow.
0134      * @param relative use relative paths. Defaults to false, uses absolute paths.
0135      */
0136     virtual bool exportPlaylist( const QString &path, bool relative = false ) = 0;
0137 
0138     /**
0139      * Notify FilterProxy that the search term of searched fields has changed. Since this
0140      * call does not use the parent's filter values, this method needs to be called when the
0141      * values change.
0142      */
0143     virtual void filterUpdated() {}
0144 
0145     /**
0146      * Forwards a search down through the stack of ProxyModels.
0147      * Find the first track in the playlist that matches the search term in one of the
0148      * specified search fields. Playlist::Model::find() emits found() or notFound() depending
0149      * on whether a match is found.
0150      *
0151      * Filtering MUST take its filter parameters from this call, but SHOULD delay doing
0152      * any work until it gets a 'filterUpdated()' call.
0153      *
0154      * The first parameter is a term to search for.
0155      * The second parameter is a bitmask specifying the fields to look in.
0156      * @return The row of the first found match, -1 if no match is found.
0157      */
0158     virtual int find( const QString &, int ) { return -1; }
0159 
0160     /**
0161      * Forwards through the stack of ProxyModels a top to bottom search for the next item.
0162      * Find the first track below a given row that matches the search term in one of the
0163      * specified search fields. Playlist::Model::findNext() emits found() or notFound()
0164      * depending on whether a match is found. If no row is found below the current row, the
0165      * function wraps around and returns the first match. If no match is found at all, -1
0166      * is returned.
0167      * The first parameter is a term to search for.
0168      * The second parameter is an offset row.
0169      * The third parameter is a bitmask specifying the fields to look in.
0170      * @return The row of the first found match below the offset, -1 if no match is found.
0171      */
0172     virtual int findNext( const QString &, int, int ) { return -1; }
0173 
0174     /**
0175      * Forwards through the stack of ProxyModels a bottom to top search for the next item.
0176      * Find the first track above a given row that matches the search term in one of the
0177      * specified search fields. Playlist::Model::findPrevious() emits found() or notFound()
0178      * depending on whether a match is found. If no row is found above the current row, the
0179      * function wraps around and returns the last match. If no match is found at all, -1
0180      * is returned.
0181      * The first parameter is a term to search for.
0182      * The second parameter is an offset row.
0183      * The third parameter is a bitmask specifying the fields to look in.
0184      * @return The row of the first found match above the offset, -1 if no match is found.
0185      */
0186     virtual int findPrevious( const QString &, int, int ) {return -1; }
0187 
0188     /**
0189      * Returns the first row in the current model which matches a given track pointer.
0190      * @see allRowsForTrack
0191      * @param track the track.
0192      * @return the row, or -1 if the track pointer is not found.
0193      */
0194     virtual int firstRowForTrack( const Meta::TrackPtr& track ) const = 0;
0195 
0196     /**
0197      * Returns the unique 64-bit id for the given row in the current model.
0198      * @param row the row.
0199      * @return the unique id.
0200      */
0201     virtual quint64 idAt( const int row ) const = 0;
0202 
0203     /**
0204      * Checks if a row exists in the current model or proxy.
0205      * @param row the row in the model or proxy.
0206      * @return true is the row exists, otherwise false.
0207      */
0208     virtual bool rowExists( int row ) const = 0;
0209 
0210     /**
0211      * Returns the row in the current model for a given unique 64-bit id.
0212      * @param id the id.
0213      * @return the row, -1 if the id is invalid.
0214      */
0215     virtual int rowForId( const quint64 id ) const = 0;
0216 
0217     /**
0218      * Returns the row number of a track given the row number in the bottom model.
0219      * @param row the row in the bottom model.
0220      * @return the row in a proxy model
0221      */
0222     virtual int rowFromBottomModel( const int row ) = 0;
0223 
0224     /**
0225      * Returns the row number of a track in terms of the bottom model.
0226      * @param row the row in a proxy model
0227      * @return the row in the bottom model.
0228      */
0229     virtual int rowToBottomModel( const int row ) = 0;
0230 
0231     /**
0232      * Set the currently active track based on the playlist id given.
0233      * @param id the unique playlist id.
0234      */
0235     virtual void setActiveId( const quint64 id ) = 0;
0236 
0237     /**
0238      * Sets the currently active (playing) row, translated for this proxy.
0239      * @param row the row to be set as active.
0240      */
0241     virtual void setActiveRow( int row ) = 0;
0242 
0243     /**
0244      * Sets to uplayed the state of all the tracks exposed by this proxy.
0245      */
0246     virtual void setAllUnplayed() = 0;
0247 
0248     /**
0249      * Emit the queueChanged() signal. Call this after changing the queue in PlaylistActions.
0250      */
0251     virtual void emitQueueChanged() = 0;
0252 
0253     /**
0254      * Return position of @p row in the playlist queue, zero if not queued.
0255      */
0256     virtual int queuePositionOfRow( int row ) = 0;
0257 
0258     /**
0259      * Decides if FilterProxy or SearchProxy should be used.
0260      * The parameter is true if one wants to use SearchProxy, false otherwise.
0261      */
0262     virtual void showOnlyMatches( bool ) {}
0263 
0264     /**
0265      * Get the state of a track by its id.
0266      * @param id The id of the track.
0267      * @return The state of the track.
0268      */
0269     virtual Item::State stateOfId( quint64 id ) const = 0;
0270 
0271     /**
0272      * Get the sate of the track at given row in the proxy model.
0273      * @param row The row in proxy terms.
0274      * @return The state of the track at the row.
0275      */
0276     virtual Item::State stateOfRow( int row ) const = 0;
0277 
0278     /**
0279      * Asks the model sitting below the total length of the playlist.
0280      * @return the total length of the playlist in milliseconds.
0281      */
0282     virtual qint64 totalLength() const = 0;
0283 
0284     /**
0285      * Asks the model sitting below the total size of the playlist.
0286      * @return the total size of the playlist.
0287      */
0288     virtual quint64 totalSize() const = 0;
0289 
0290     /**
0291      * Returns a pointer to the track at a given row.
0292      * @param row the row to return the track pointer for.
0293      * @return a pointer to the track at the given row.
0294      */
0295     virtual Meta::TrackPtr trackAt( int row ) const = 0;
0296 
0297     /**
0298      * Returns a pointer to the track with the given unique id.
0299      * @param id the id to return the track pointer for.
0300      * @return a pointer to the track with the given id.
0301      */
0302     virtual Meta::TrackPtr trackForId( const quint64 id ) const = 0;
0303 
0304     /**
0305      * Returns an ordered list of tracks exposed by the current model.
0306      * @return the tracklist.
0307      */
0308     virtual Meta::TrackList tracks() = 0;
0309 };
0310 
0311 }   //namespace Playlist
0312 
0313 #endif  //AMAROK_PLAYLISTABSTRACTMODEL_H