File indexing completed on 2024-05-05 04:48:44

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) 2008 Nikolaj Hald Nielsen <nhn@kde.org>                                *
0006  * Copyright (c) 2010 Nanno Langstraat <langstr@gmail.com>                              *
0007  *                                                                                      *
0008  * This program is free software; you can redistribute it and/or modify it under        *
0009  * the terms of the GNU General Public License as published by the Free Software        *
0010  * Foundation; either version 2 of the License, or (at your option) version 3 or        *
0011  * any later version accepted by the membership of KDE e.V. (or its successor approved  *
0012  * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of  *
0013  * version 3 of the license.                                                            *
0014  *                                                                                      *
0015  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0016  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0017  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0018  *                                                                                      *
0019  * You should have received a copy of the GNU General Public License along with         *
0020  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0021  ****************************************************************************************/
0022 
0023 #ifndef AMAROK_PLAYLISTMODEL_H
0024 #define AMAROK_PLAYLISTMODEL_H
0025 
0026 #include "UndoCommands.h"
0027 #include "amarok_export.h"
0028 #include "core/meta/Observer.h"
0029 #include "core/support/Amarok.h"
0030 #include "playlist/proxymodels/AbstractModel.h"
0031 
0032 #include <QAbstractListModel>
0033 #include <QHash>
0034 #include <QTimer>
0035 
0036 #include <QtGlobal>
0037 
0038 class QMimeData;
0039 class QModelIndex;
0040 class TestPlaylistModels;
0041 
0042 namespace Playlist
0043 {
0044 
0045 class AMAROK_EXPORT Model : public QAbstractListModel, public Meta::Observer, public Playlist::AbstractModel
0046 {
0047     friend class InsertTracksCmd;
0048     friend class RemoveTracksCmd;
0049     friend class MoveTracksCmd;
0050     friend class ::TestPlaylistModels; //this test really needs access to the private functions.
0051 
0052     Q_OBJECT
0053 
0054     public:
0055         explicit Model( QObject *parent = nullptr );
0056         ~Model() override;
0057 
0058         // Inherited from QAbstractItemModel  (via QAbstractListModel)
0059         int columnCount( const QModelIndex& parent = QModelIndex() ) const override { Q_UNUSED( parent ); return NUM_COLUMNS; }
0060         QVariant data( const QModelIndex& index, int role ) const override;
0061         bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent ) override;
0062         Qt::ItemFlags flags( const QModelIndex &index ) const override;
0063         QVariant headerData( int section, Qt::Orientation orientation, int role ) const override;
0064         QMimeData* mimeData( const QModelIndexList &indexes ) const override;
0065         QStringList mimeTypes() const override;
0066         int rowCount( const QModelIndex& parent = QModelIndex() ) const override { Q_UNUSED( parent ); return m_items.size(); }
0067         Qt::DropActions supportedDropActions() const override;
0068 
0069         // Inherited from Playlist::AbstractModel
0070         QAbstractItemModel* qaim() const override { return const_cast<Model*>( this ); }
0071 
0072         quint64 activeId() const override;
0073         Meta::TrackPtr activeTrack() const override;
0074         int activeRow() const override { return m_activeRow; } // returns -1 if there is no active row
0075 
0076         bool containsTrack( const Meta::TrackPtr& track ) const override;
0077         int firstRowForTrack( const Meta::TrackPtr& track ) const override;
0078         QSet<int> allRowsForTrack( const Meta::TrackPtr& track ) const override;
0079 
0080         quint64 idAt( const int row ) const override;
0081         bool rowExists( int row ) const override { return (( row >= 0 ) && ( row < m_items.size() ) ); }
0082         int rowForId( const quint64 id ) const override; // returns -1 if the id is invalid
0083         int rowFromBottomModel( const int row ) override { return row; }
0084         int rowToBottomModel( const int row ) override { return row; }
0085         void setActiveId( const quint64 id ) override { setActiveRow( rowForId( id ) ); }
0086         void setActiveRow( int row ) override;
0087         void setAllNewlyAddedToUnplayed();
0088         void setAllUnplayed() override;
0089         void emitQueueChanged() override;
0090         int queuePositionOfRow( int row ) override;
0091         Item::State stateOfId( quint64 id ) const override;
0092         Item::State stateOfRow( int row ) const override;
0093         qint64 totalLength() const override { return m_totalLength; }
0094         quint64 totalSize() const override { return m_totalSize; }
0095         Meta::TrackPtr trackAt( int row ) const override;
0096         Meta::TrackPtr trackForId( const quint64 id ) const override;
0097 
0098         bool exportPlaylist( const QString &path, bool relative = false ) override;
0099         Meta::TrackList tracks() override;
0100 
0101         // Inherited from Meta::Observer
0102         using Observer::metadataChanged;
0103         void metadataChanged( const Meta::TrackPtr &track ) override;
0104         void metadataChanged( const Meta::AlbumPtr &album ) override;
0105 
0106         // static member functions
0107         static QString prettyColumnName( Column index ); //!< takes a Column enum and returns its string name
0108 
0109         /** Set the columns that are displayed in the tooltip */
0110         static void setTooltipColumns( bool columns[] );
0111 
0112         static void enableToolTip( bool enable );
0113 
0114     Q_SIGNALS:
0115         void activeTrackChanged( quint64 );
0116         void queueChanged();
0117 
0118     protected:
0119         int rowForItem( Item *item ) const { return m_items.indexOf( item ); }
0120 
0121     private Q_SLOTS:
0122         void saveState();
0123         void queueSaveState();
0124         void insertTracksFromTrackLoader( const Meta::TrackList &tracks );
0125 
0126     private:
0127         QString tooltipFor( Meta::TrackPtr track ) const;
0128 
0129         // Inherited from QAbstractItemModel. Make them private so that nobody is tempted to use them.
0130         bool insertRow( int, const QModelIndex& parent = QModelIndex() ) { Q_UNUSED( parent ); return false; }
0131         bool insertRows( int, int, const QModelIndex& parent = QModelIndex() ) override { Q_UNUSED( parent ); return false; }
0132         bool removeRow( int, const QModelIndex& parent = QModelIndex() ) { Q_UNUSED( parent ); return false; }
0133         bool removeRows( int, int, const QModelIndex& parent = QModelIndex() ) override { Q_UNUSED( parent ); return false; }
0134 
0135         // These functions do the real work of modifying the playlist, and should be called ONLY by UndoCommands
0136         void insertTracksCommand( const InsertCmdList& );
0137         void removeTracksCommand( const RemoveCmdList& );
0138         void moveTracksCommand( const MoveCmdList&, bool reverse = false );
0139         void clearCommand();
0140 
0141         // Always alter the state of a row via one of the following functions.
0142         void setStateOfItem_batchStart();
0143         void setStateOfItem_batchEnd();
0144         void setStateOfItem( Item *item, int row, Item::State state );    // 'item' must equal 'm_items.at( row )'
0145         void setStateOfItem( Item *item, Item::State state ) { setStateOfItem( item, rowForItem( item ), state ); }
0146         void setStateOfRow( int row, Item::State state )     { setStateOfItem( m_items.at( row ), row, state ); }
0147 
0148         // Variables
0149         QList<Item*> m_items;               //!< list of playlist items, in their "natural" (unsorted) order.
0150         QHash<quint64, Item*> m_itemIds;    //!< maps playlist item ID to Item pointer.
0151 
0152         int m_activeRow;    //!< the row being played
0153 
0154         qint64 m_totalLength;
0155         quint64 m_totalSize;
0156 
0157         QString m_playlistName;
0158         bool m_proposeOverwriting;
0159 
0160         int m_setStateOfItem_batchMinRow;    //!< For 'setStateOfItem_batch*()'
0161         int m_setStateOfItem_batchMaxRow;
0162 
0163         static bool s_tooltipColumns[NUM_COLUMNS];
0164         static bool s_showToolTip;
0165 
0166         QTimer *m_saveStateTimer;
0167 };
0168 
0169 } // namespace Playlist
0170 
0171 #endif