Work on playlist editing
This commit is contained in:
@@ -90,7 +90,7 @@ PlaylistsPage::PlaylistsPage(MainWindow *p)
|
||||
connect(this, SIGNAL(removePlaylist(const QString &)), MPDConnection::self(), SLOT(removePlaylist(const QString &)));
|
||||
connect(this, SIGNAL(savePlaylist(const QString &)), MPDConnection::self(), SLOT(savePlaylist(const QString &)));
|
||||
connect(this, SIGNAL(renamePlaylist(const QString &, const QString &)), MPDConnection::self(), SLOT(renamePlaylist(const QString &, const QString &)));
|
||||
connect(this, SIGNAL(removeFromPlaylist(const QString &, const QList<int> &)), MPDConnection::self(), SLOT(removeFromPlaylist(const QString &, const QList<int> &)));
|
||||
connect(this, SIGNAL(removeFromPlaylist(const QString &, const QList<quint32> &)), MPDConnection::self(), SLOT(removeFromPlaylist(const QString &, const QList<quint32> &)));
|
||||
connect(p->savePlaylistAction, SIGNAL(activated()), this, SLOT(savePlaylist()));
|
||||
connect(renamePlaylistAction, SIGNAL(triggered()), this, SLOT(renamePlaylist()));
|
||||
connect(PlaylistsModel::self(), SIGNAL(updated(const QModelIndex &)), this, SLOT(updated(const QModelIndex &)));
|
||||
@@ -159,7 +159,7 @@ void PlaylistsPage::addSelectionToPlaylist()
|
||||
void PlaylistsPage::removeItems()
|
||||
{
|
||||
QSet<QString> remPlaylists;
|
||||
QMap<QString, QList<int> > remSongs;
|
||||
QMap<QString, QList<quint32> > remSongs;
|
||||
QModelIndexList selected = view->selectedIndexes();
|
||||
|
||||
foreach(const QModelIndex &index, selected) {
|
||||
@@ -201,8 +201,8 @@ void PlaylistsPage::removeItems()
|
||||
foreach (const QString &pl, remPlaylists) {
|
||||
emit removePlaylist(pl);
|
||||
}
|
||||
QMap<QString, QList<int> >::ConstIterator it=remSongs.constBegin();
|
||||
QMap<QString, QList<int> >::ConstIterator end=remSongs.constEnd();
|
||||
QMap<QString, QList<quint32> >::ConstIterator it=remSongs.constBegin();
|
||||
QMap<QString, QList<quint32> >::ConstIterator end=remSongs.constEnd();
|
||||
for (; it!=end; ++it) {
|
||||
emit removeFromPlaylist(it.key(), it.value());
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ Q_SIGNALS:
|
||||
void removePlaylist(const QString &name);
|
||||
void savePlaylist(const QString &name);
|
||||
void renamePlaylist(const QString &oldname, const QString &newname);
|
||||
void removeFromPlaylist(const QString &name, const QList<int> &positions);
|
||||
void removeFromPlaylist(const QString &name, const QList<quint32> &positions);
|
||||
|
||||
void add(const QStringList &files);
|
||||
|
||||
|
||||
@@ -60,13 +60,13 @@ PlaylistsModel::PlaylistsModel(QObject *parent)
|
||||
{
|
||||
connect(MPDConnection::self(), SIGNAL(playlistsRetrieved(const QList<Playlist> &)), this, SLOT(setPlaylists(const QList<Playlist> &)));
|
||||
connect(MPDConnection::self(), SIGNAL(playlistInfoRetrieved(const QString &, const QList<Song> &)), this, SLOT(playlistInfoRetrieved(const QString &, const QList<Song> &)));
|
||||
connect(MPDConnection::self(), SIGNAL(removedFromPlaylist(const QString &, const QList<int> &)), this, SLOT(removedFromPlaylist(const QString &, const QList<int> &)));
|
||||
// connect(MPDConnection::self(), SIGNAL(removedFromPlaylist(const QString &, const QList<int> &)), this, SLOT(removedFromPlaylist(const QString &, const QList<int> &)));
|
||||
connect(MPDConnection::self(), SIGNAL(playlistRenamed(const QString &, const QString &)), this, SLOT(playlistRenamed(const QString &, const QString &)));
|
||||
connect(this, SIGNAL(listPlaylists()), MPDConnection::self(), SLOT(listPlaylists()));
|
||||
connect(this, SIGNAL(playlistInfo(const QString &)), MPDConnection::self(), SLOT(playlistInfo(const QString &)));
|
||||
connect(this, SIGNAL(addToPlaylist(const QString &, const QStringList &)), MPDConnection::self(), SLOT(addToPlaylist(const QString &, const QStringList &)));
|
||||
connect(this, SIGNAL(moveInPlaylist(const QString &, int, int)), MPDConnection::self(), SLOT(moveInPlaylist(const QString &, int, int)));
|
||||
connect(MPDConnection::self(), SIGNAL(movedInPlaylist(const QString &, int, int)), this, SLOT(movedInPlaylist(const QString &, int, int)));
|
||||
connect(this, SIGNAL(addToPlaylist(const QString &, const QStringList, quint32, quint32)), MPDConnection::self(), SLOT(addToPlaylist(const QString &, const QStringList, quint32, quint32)));
|
||||
connect(this, SIGNAL(moveInPlaylist(const QString &, const QList<quint32> &, quint32, quint32)), MPDConnection::self(), SLOT(moveInPlaylist(const QString &, const QList<quint32> &, quint32, quint32)));
|
||||
// connect(MPDConnection::self(), SIGNAL(movedInPlaylist(const QString &, int, int)), this, SLOT(movedInPlaylist(const QString &, int, int)));
|
||||
updateItemMenu();
|
||||
}
|
||||
|
||||
@@ -388,12 +388,9 @@ bool PlaylistsModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
|
||||
QStringList filenames=PlayQueueModel::decode(*data, PlayQueueModel::constFileNameMimeType);
|
||||
|
||||
if (data->hasFormat(PlayQueueModel::constMoveMimeType)) {
|
||||
emit addToPlaylist(pl->name, filenames);
|
||||
if (!item->isPlaylist()) {
|
||||
for (int i=0; i<filenames.count(); ++i) {
|
||||
emit moveInPlaylist(pl->name, pl->songs.count(), parent.row());
|
||||
}
|
||||
}
|
||||
emit addToPlaylist(pl->name, filenames,
|
||||
parent.row() < 0 || item->isPlaylist() ? 0 : parent.row(),
|
||||
parent.row() < 0 || item->isPlaylist() ? 0 : pl->songs.size());
|
||||
return true;
|
||||
} else if (data->hasFormat(constPlaylistNameMimeType)) {
|
||||
QStringList playlists=PlayQueueModel::decode(*data, constPlaylistNameMimeType);
|
||||
@@ -414,31 +411,29 @@ bool PlaylistsModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
|
||||
if (fromThis) {
|
||||
if (!item->isPlaylist()) {
|
||||
QStringList list=PlayQueueModel::decode(*data, constPositionsMimeType);
|
||||
QList<int> pos;
|
||||
QList<quint32> pos;
|
||||
|
||||
foreach (const QString &s, list) {
|
||||
pos.append(s.toUInt());
|
||||
}
|
||||
qSort(pos);
|
||||
int offset=0;
|
||||
foreach (int p, pos) {
|
||||
int dest=parent.row();
|
||||
int source=p;
|
||||
|
||||
if (dest>source) {
|
||||
source-=offset++;
|
||||
}
|
||||
emit moveInPlaylist(pl->name, source, dest);
|
||||
}
|
||||
// qSort(pos);
|
||||
// int offset=0;
|
||||
// foreach (int p, pos) {
|
||||
// int dest=parent.row();
|
||||
// int source=p;
|
||||
//
|
||||
// if (dest>source) {
|
||||
// source-=offset++;
|
||||
// }
|
||||
emit moveInPlaylist(pl->name, pos, parent.row() < 0 ? pl->songs.size() : parent.row(), pl->songs.size());
|
||||
// emit moveInPlaylist(pl->name, source, dest);
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
emit addToPlaylist(pl->name, filenames);
|
||||
if (!item->isPlaylist()) {
|
||||
for (int i=0; i<filenames.count(); ++i) {
|
||||
emit moveInPlaylist(pl->name, pl->songs.count(), parent.row());
|
||||
}
|
||||
}
|
||||
emit addToPlaylist(pl->name, filenames,
|
||||
parent.row() < 0 || item->isPlaylist() ? 0 : parent.row(),
|
||||
parent.row() < 0 || item->isPlaylist() ? 0 : pl->songs.size());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -593,63 +588,63 @@ void PlaylistsModel::playlistInfoRetrieved(const QString &name, const QList<Song
|
||||
updateGenreList();
|
||||
}
|
||||
|
||||
void PlaylistsModel::removedFromPlaylist(const QString &name, const QList<int> &positions)
|
||||
{
|
||||
PlaylistItem *pl=0;
|
||||
if (0==positions.count() || !(pl=getPlaylist(name))) {
|
||||
emit listPlaylists();
|
||||
return;
|
||||
}
|
||||
// void PlaylistsModel::removedFromPlaylist(const QString &name, const QList<int> &positions)
|
||||
// {
|
||||
// PlaylistItem *pl=0;
|
||||
// if (0==positions.count() || !(pl=getPlaylist(name))) {
|
||||
// emit listPlaylists();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int adjust=0;
|
||||
// QModelIndex parent=createIndex(items.indexOf(pl), 0, pl);
|
||||
// QList<int>::ConstIterator it=positions.constBegin();
|
||||
// QList<int>::ConstIterator end=positions.constEnd();
|
||||
// while(it!=end) {
|
||||
// int rowBegin=*it;
|
||||
// int rowEnd=*it;
|
||||
// QList<int>::ConstIterator next=it+1;
|
||||
// while(next!=end) {
|
||||
// if (*next!=(rowEnd+1)) {
|
||||
// break;
|
||||
// } else {
|
||||
// it=next;
|
||||
// rowEnd=*next;
|
||||
// next++;
|
||||
// }
|
||||
// }
|
||||
// beginRemoveRows(parent, rowBegin-adjust, rowEnd-adjust);
|
||||
// for (int i=rowBegin; i<=rowEnd; ++i) {
|
||||
// delete pl->songs.takeAt(rowBegin-adjust);
|
||||
// }
|
||||
// adjust+=(rowEnd-rowBegin)+1;
|
||||
// endRemoveRows();
|
||||
// it++;
|
||||
// pl->updateGenres();
|
||||
// }
|
||||
// updateGenreList();
|
||||
// }
|
||||
|
||||
int adjust=0;
|
||||
QModelIndex parent=createIndex(items.indexOf(pl), 0, pl);
|
||||
QList<int>::ConstIterator it=positions.constBegin();
|
||||
QList<int>::ConstIterator end=positions.constEnd();
|
||||
while(it!=end) {
|
||||
int rowBegin=*it;
|
||||
int rowEnd=*it;
|
||||
QList<int>::ConstIterator next=it+1;
|
||||
while(next!=end) {
|
||||
if (*next!=(rowEnd+1)) {
|
||||
break;
|
||||
} else {
|
||||
it=next;
|
||||
rowEnd=*next;
|
||||
next++;
|
||||
}
|
||||
}
|
||||
beginRemoveRows(parent, rowBegin-adjust, rowEnd-adjust);
|
||||
for (int i=rowBegin; i<=rowEnd; ++i) {
|
||||
delete pl->songs.takeAt(rowBegin-adjust);
|
||||
}
|
||||
adjust+=(rowEnd-rowBegin)+1;
|
||||
endRemoveRows();
|
||||
it++;
|
||||
pl->updateGenres();
|
||||
}
|
||||
updateGenreList();
|
||||
}
|
||||
|
||||
void PlaylistsModel::movedInPlaylist(const QString &name, int from, int to)
|
||||
{
|
||||
PlaylistItem *pl=0;
|
||||
if (!(pl=getPlaylist(name)) || from>pl->songs.count()) {
|
||||
emit listPlaylists();
|
||||
return;
|
||||
}
|
||||
QModelIndex parent=createIndex(items.indexOf(pl), 0, pl);
|
||||
|
||||
beginMoveRows(parent, from, from, parent, to>from ? to+1 : to);
|
||||
SongItem *si=pl->songs.takeAt(from);
|
||||
pl->songs.insert(to, si);
|
||||
endMoveRows();
|
||||
// beginRemoveRows(parent, from, from);
|
||||
// void PlaylistsModel::movedInPlaylist(const QString &name, int from, int to)
|
||||
// {
|
||||
// PlaylistItem *pl=0;
|
||||
// if (!(pl=getPlaylist(name)) || from>pl->songs.count()) {
|
||||
// emit listPlaylists();
|
||||
// return;
|
||||
// }
|
||||
// QModelIndex parent=createIndex(items.indexOf(pl), 0, pl);
|
||||
//
|
||||
// beginMoveRows(parent, from, from, parent, to>from ? to+1 : to);
|
||||
// SongItem *si=pl->songs.takeAt(from);
|
||||
// endRemoveRows();
|
||||
// beginInsertRows(parent, to<from ? to : to-1, to<from ? to : to-1);
|
||||
// pl->songs.insert(to, si);
|
||||
// endInsertRows();
|
||||
}
|
||||
// endMoveRows();
|
||||
// // beginRemoveRows(parent, from, from);
|
||||
// // SongItem *si=pl->songs.takeAt(from);
|
||||
// // endRemoveRows();
|
||||
// // beginInsertRows(parent, to<from ? to : to-1, to<from ? to : to-1);
|
||||
// // pl->songs.insert(to, si);
|
||||
// // endInsertRows();
|
||||
// }
|
||||
|
||||
static QString qt_strippedText(QString s)
|
||||
{
|
||||
|
||||
@@ -103,8 +103,8 @@ Q_SIGNALS:
|
||||
void add(const QStringList &files);
|
||||
void listPlaylists();
|
||||
void playlistInfo(const QString &name) const;
|
||||
void addToPlaylist(const QString &name, const QStringList &songs);
|
||||
void moveInPlaylist(const QString &name, int from, int to);
|
||||
void addToPlaylist(const QString &name, const QStringList &songs, quint32 pos, quint32 size);
|
||||
void moveInPlaylist(const QString &name, const QList<quint32> &items, quint32 pos, quint32 size);
|
||||
|
||||
void addToNew();
|
||||
void addToExisting(const QString &name);
|
||||
@@ -115,8 +115,8 @@ Q_SIGNALS:
|
||||
private Q_SLOTS:
|
||||
void setPlaylists(const QList<Playlist> &playlists);
|
||||
void playlistInfoRetrieved(const QString &name, const QList<Song> &songs);
|
||||
void removedFromPlaylist(const QString &name, const QList<int> &positions);
|
||||
void movedInPlaylist(const QString &name, int from, int to);
|
||||
// void removedFromPlaylist(const QString &name, const QList<int> &positions);
|
||||
// void movedInPlaylist(const QString &name, int from, int to);
|
||||
void emitAddToExisting();
|
||||
void playlistRenamed(const QString &from, const QString &to);
|
||||
|
||||
|
||||
@@ -372,6 +372,8 @@ void MPDConnection::move(quint32 from, quint32 to)
|
||||
|
||||
void MPDConnection::move(const QList<quint32> &items, quint32 pos, quint32 size)
|
||||
{
|
||||
doMoveInPlaylist(QString(), items, pos, size);
|
||||
#if 0
|
||||
QByteArray send = "command_list_begin\n";
|
||||
QList<quint32> moveItems;
|
||||
|
||||
@@ -403,6 +405,7 @@ void MPDConnection::move(const QList<quint32> &items, quint32 pos, quint32 size)
|
||||
|
||||
send += "command_list_end";
|
||||
sendCommand(send);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MPDConnection::shuffle()
|
||||
@@ -788,7 +791,7 @@ void MPDConnection::savePlaylist(QString name)
|
||||
}
|
||||
}
|
||||
|
||||
void MPDConnection::addToPlaylist(const QString &name, const QStringList &songs)
|
||||
void MPDConnection::addToPlaylist(const QString &name, const QStringList &songs, quint32 pos, quint32 size)
|
||||
{
|
||||
if (songs.isEmpty()) {
|
||||
return;
|
||||
@@ -810,55 +813,84 @@ void MPDConnection::addToPlaylist(const QString &name, const QStringList &songs)
|
||||
}
|
||||
|
||||
if (!added.isEmpty()) {
|
||||
playlistInfo(name);
|
||||
if (size>0) {
|
||||
QList<quint32> items;
|
||||
for(int i=0; i<added.count(); ++i) {
|
||||
items.append(size+i);
|
||||
}
|
||||
doMoveInPlaylist(name, items, pos, size+added.count());
|
||||
}
|
||||
}
|
||||
playlistInfo(name);
|
||||
}
|
||||
|
||||
void MPDConnection::removeFromPlaylist(const QString &name, const QList<int> &positions)
|
||||
void MPDConnection::removeFromPlaylist(const QString &name, const QList<quint32> &positions)
|
||||
{
|
||||
if (positions.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray encodedName=encodeName(name);
|
||||
QList<int> sorted=positions;
|
||||
QList<quint32> sorted=positions;
|
||||
|
||||
qSort(sorted);
|
||||
QList<int> fixedPositions;
|
||||
QMap<int, int> map;
|
||||
QList<quint32> fixedPositions;
|
||||
QMap<quint32, quint32> map;
|
||||
|
||||
for (int i=0; i<sorted.count(); ++i) {
|
||||
fixedPositions << (sorted.at(i)-i);
|
||||
}
|
||||
QList<int> removed;
|
||||
for (int i=0; i<fixedPositions.count(); ++i) {
|
||||
QByteArray data = "playlistdelete ";
|
||||
data += encodedName;
|
||||
data += " ";
|
||||
data += QByteArray::number(fixedPositions.at(i));
|
||||
if (sendCommand(data).ok) {
|
||||
removed << sorted.at(i);
|
||||
} else {
|
||||
if (!sendCommand(data).ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!removed.isEmpty()) {
|
||||
emit removedFromPlaylist(name, removed);
|
||||
}
|
||||
playlistInfo(name);
|
||||
}
|
||||
|
||||
void MPDConnection::moveInPlaylist(const QString &name, int from, int to)
|
||||
void MPDConnection::moveInPlaylist(const QString &name, const QList<quint32> &items, quint32 pos, quint32 size)
|
||||
{
|
||||
QByteArray data = "playlistmove ";
|
||||
data += encodeName(name);
|
||||
data += " ";
|
||||
data += QByteArray::number(from);
|
||||
data += " ";
|
||||
data += QByteArray::number(to);
|
||||
if (sendCommand(data).ok) {
|
||||
emit movedInPlaylist(name, from, to);
|
||||
doMoveInPlaylist(name, items, pos, size);
|
||||
playlistInfo(name);
|
||||
}
|
||||
|
||||
bool MPDConnection::doMoveInPlaylist(const QString &name, const QList<quint32> &items, quint32 pos, quint32 size)
|
||||
{
|
||||
QByteArray cmd = name.isEmpty() ? "move " : ("playlistmove "+encodeName(name)+" ");
|
||||
QByteArray send = "command_list_begin\n";
|
||||
QList<quint32> moveItems=items;
|
||||
int posOffset = 0;
|
||||
|
||||
qSort(moveItems);
|
||||
|
||||
//first move all items (starting with the biggest) to the end so we don't have to deal with changing rownums
|
||||
for (int i = moveItems.size() - 1; i >= 0; i--) {
|
||||
if (moveItems.at(i) < pos && moveItems.at(i) != size - 1) {
|
||||
// we are moving away an item that resides before the destinatino row, manipulate destination row
|
||||
posOffset++;
|
||||
}
|
||||
send += cmd;
|
||||
send += QByteArray::number(moveItems.at(i));
|
||||
send += " ";
|
||||
send += QByteArray::number(size - 1);
|
||||
send += "\n";
|
||||
}
|
||||
//now move all of them to the destination position
|
||||
for (int i = moveItems.size() - 1; i >= 0; i--) {
|
||||
send += cmd;
|
||||
send += QByteArray::number(size - 1 - i);
|
||||
send += " ";
|
||||
send += QByteArray::number(pos - posOffset);
|
||||
send += "\n";
|
||||
}
|
||||
|
||||
send += "command_list_end";
|
||||
return sendCommand(send).ok;
|
||||
}
|
||||
|
||||
MpdSocket::MpdSocket(QObject *parent)
|
||||
|
||||
@@ -202,9 +202,10 @@ public Q_SLOTS:
|
||||
void renamePlaylist(const QString oldName, const QString newName);
|
||||
void removePlaylist(QString name);
|
||||
void savePlaylist(QString name);
|
||||
void addToPlaylist(const QString &name, const QStringList &songs);
|
||||
void removeFromPlaylist(const QString &name, const QList<int> &positions);
|
||||
void moveInPlaylist(const QString &name, int id, int pos);
|
||||
void addToPlaylist(const QString &name, const QStringList &songs) { addToPlaylist(name, songs, 0, 0); }
|
||||
void addToPlaylist(const QString &name, const QStringList &songs, quint32 pos, quint32 size);
|
||||
void removeFromPlaylist(const QString &name, const QList<quint32> &positions);
|
||||
void moveInPlaylist(const QString &name, const QList<quint32> &items, quint32 row, quint32 size);
|
||||
|
||||
Q_SIGNALS:
|
||||
void stateChanged(bool connected);
|
||||
@@ -219,8 +220,8 @@ Q_SIGNALS:
|
||||
void playlistsRetrieved(const QList<Playlist> &data);
|
||||
void playlistInfoRetrieved(const QString &name, const QList<Song> &songs);
|
||||
void playlistRenamed(const QString &from, const QString &to);
|
||||
void removedFromPlaylist(const QString &name, const QList<int> &positions);
|
||||
void movedInPlaylist(const QString &name, int from, int to);
|
||||
// void removedFromPlaylist(const QString &name, const QList<int> &positions);
|
||||
// void movedInPlaylist(const QString &name, int from, int to);
|
||||
void databaseUpdated();
|
||||
void playlistLoaded(const QString &playlist);
|
||||
void added(const QStringList &files);
|
||||
@@ -244,6 +245,7 @@ private:
|
||||
Response sendCommand(const QByteArray &command, bool emitErrors=true);
|
||||
void initialize();
|
||||
void parseIdleReturn(const QByteArray &data);
|
||||
bool doMoveInPlaylist(const QString &name, const QList<quint32> &items, quint32 pos, quint32 size);
|
||||
|
||||
private:
|
||||
long ver;
|
||||
|
||||
Reference in New Issue
Block a user