Work on playlist editing

This commit is contained in:
craig
2012-03-21 19:04:10 +00:00
parent b00860ca65
commit ea932bda1c
6 changed files with 147 additions and 118 deletions

View File

@@ -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());
}

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;