File indexing completed on 2024-05-19 04:48:42
0001 /**************************************************************************************** 0002 * Copyright (c) 2008 Nikolaj Hald Nielsen <nhn@kde.org> * 0003 * Copyright (c) 2008 Ian Monroe <imonroe@kde.org> * 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 #include "UserPlaylistModel.h" 0019 #include "playlistmanager/PlaylistManager.h" 0020 #include "core/playlists/PlaylistProvider.h" 0021 0022 #include "AmarokMimeData.h" 0023 #include "core-impl/collections/support/CollectionManager.h" 0024 #include "core/support/Debug.h" 0025 #include "SvgHandler.h" 0026 0027 #include <QIcon> 0028 0029 #include <QAbstractListModel> 0030 0031 #include <typeinfo> 0032 0033 //Playlist & Track index differentiator macros 0034 //QModelIndex::intenalId() is a qint64 to support 64-bit pointers in a union with the ID 0035 #define TRACK_MASK (0x1<<31) 0036 #define IS_TRACK(x) ((x.internalId()) & (TRACK_MASK))?true:false 0037 #define SET_TRACK_MASK(x) ((x) | (TRACK_MASK)) 0038 #define REMOVE_TRACK_MASK(x) ((x) & ~(TRACK_MASK)) 0039 0040 namespace The 0041 { 0042 PlaylistBrowserNS::UserModel* userPlaylistModel() 0043 { 0044 return PlaylistBrowserNS::UserModel::instance(); 0045 } 0046 } 0047 0048 PlaylistBrowserNS::UserModel *PlaylistBrowserNS::UserModel::s_instance = nullptr; 0049 0050 PlaylistBrowserNS::UserModel *PlaylistBrowserNS::UserModel::instance() 0051 { 0052 if( s_instance == nullptr ) 0053 s_instance = new UserModel(); 0054 0055 return s_instance; 0056 } 0057 0058 void 0059 PlaylistBrowserNS::UserModel::destroy() 0060 { 0061 if( s_instance ) 0062 { 0063 delete s_instance; 0064 s_instance = nullptr; 0065 } 0066 } 0067 0068 PlaylistBrowserNS::UserModel::UserModel() 0069 : PlaylistBrowserModel( PlaylistManager::UserPlaylist ) 0070 { 0071 s_instance = this; 0072 } 0073 0074 PlaylistBrowserNS::UserModel::~UserModel() 0075 { 0076 } 0077 0078 bool 0079 PlaylistBrowserNS::UserModel::setData( const QModelIndex &idx, const QVariant &value, int role ) 0080 { 0081 Q_UNUSED( role ) 0082 0083 switch( idx.column() ) 0084 { 0085 case PlaylistBrowserModel::PlaylistItemColumn: 0086 { 0087 QString newName = value.toString().trimmed(); 0088 if( newName.isEmpty() ) 0089 return false; 0090 Playlists::PlaylistPtr playlist = m_playlists.value( idx.internalId() ); 0091 // we Q_EMIT dataChanged signals later 0092 return The::playlistManager()->rename( playlist, newName ); 0093 } 0094 case PlaylistBrowserModel::LabelColumn: 0095 { 0096 debug() << "changing group of item " << idx.internalId() << " to " << value.toString(); 0097 Playlists::PlaylistPtr item = m_playlists.value( idx.internalId() ); 0098 item->setGroups( value.toStringList() ); 0099 // we Q_EMIT dataChanged signals later 0100 return true; 0101 } 0102 default: 0103 return false; 0104 } 0105 0106 return true; 0107 } 0108 0109 bool 0110 PlaylistBrowserNS::UserModel::removeRows( int row, int count, const QModelIndex &parent ) 0111 { 0112 if( row < 0 || row > rowCount( parent ) ) 0113 return false; 0114 0115 if( !parent.isValid() ) 0116 { 0117 Playlists::PlaylistList playlistToRemove; 0118 for( int i = row; i < row + count; i++ ) 0119 { 0120 if( m_playlists.count() > i ) 0121 { 0122 Playlists::PlaylistPtr playlist = m_playlists[i]; 0123 debug() << "Removing " << playlist->name(); 0124 playlistToRemove << playlist; 0125 } 0126 } 0127 if( playlistToRemove.isEmpty() ) 0128 return false; 0129 0130 return The::playlistManager()->deletePlaylists( playlistToRemove ); 0131 } 0132 int playlistRow = REMOVE_TRACK_MASK(parent.internalId()); 0133 0134 //don't try to get a playlist beyond the last item in the list 0135 if( playlistRow >= m_playlists.count() ) 0136 { 0137 error() << "Tried to remove from non existing playlist:"; 0138 error() << playlistRow << " while there are only " << m_playlists.count(); 0139 return false; 0140 } 0141 0142 Playlists::PlaylistPtr playlist = m_playlists.value( playlistRow ); 0143 0144 //if we are trying to delete more tracks then what the playlist has, return. 0145 //count will be at least 1 to delete one track 0146 if( row + count - 1 >= playlist->tracks().count() ) 0147 { 0148 error() << "Tried to remove a track using an index that is not there:"; 0149 error() << "row: " << row << " count: " << count << " number of tracks: " 0150 << playlist->tracks().count(); 0151 return false; 0152 } 0153 0154 beginRemoveRows( parent, row, row + count - 1 ); 0155 //ignore notifications while removing tracks 0156 unsubscribeFrom( playlist ); 0157 for( int i = row; i < row + count; i++ ) 0158 //deleting a track moves the next track up, so use the same row number each time 0159 playlist->removeTrack( row ); 0160 subscribeTo( playlist ); 0161 endRemoveRows(); 0162 0163 return true; 0164 } 0165 0166 bool 0167 PlaylistBrowserNS::UserModel::dropMimeData ( const QMimeData *data, Qt::DropAction action, int row, 0168 int column, const QModelIndex &parent ) //reimplemented 0169 { 0170 Q_UNUSED( column ) 0171 0172 //let the base class handle the regular actions. 0173 if( PlaylistBrowserModel::dropMimeData( data, action, row, column, parent ) ) 0174 return true; 0175 0176 if( data->hasUrls() ) 0177 { 0178 foreach( const QUrl &url, data->urls() ) 0179 The::playlistManager()->import( url ); 0180 } 0181 0182 return false; 0183 } 0184