aboutsummaryrefslogtreecommitdiff
path: root/src/qmmpui/playlistmodel.cpp
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2015-01-09 12:01:22 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2015-01-09 12:01:22 +0000
commitebd7f9bc697973366de8a6bf7265051e825e0680 (patch)
tree1feb9df1c5fe3493e9aa1dd8f5d6233a38ae9d3c /src/qmmpui/playlistmodel.cpp
parentbc7ad688c646afd2a89e5c5ff58696f2df2c8605 (diff)
downloadqmmp-ebd7f9bc697973366de8a6bf7265051e825e0680.tar.gz
qmmp-ebd7f9bc697973366de8a6bf7265051e825e0680.tar.bz2
qmmp-ebd7f9bc697973366de8a6bf7265051e825e0680.zip
renaming experimental branch
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@4675 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/qmmpui/playlistmodel.cpp')
-rw-r--r--src/qmmpui/playlistmodel.cpp351
1 files changed, 185 insertions, 166 deletions
diff --git a/src/qmmpui/playlistmodel.cpp b/src/qmmpui/playlistmodel.cpp
index c41bd11c1..52392ed64 100644
--- a/src/qmmpui/playlistmodel.cpp
+++ b/src/qmmpui/playlistmodel.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright(C) 2006-2014 by Ilya Kotov *
+ * Copyright(C) 2006-2015 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -27,6 +27,7 @@
#include "playlistcontainer_p.h"
#include "groupedcontainer_p.h"
#include "normalcontainer_p.h"
+#include "playlisttask_p.h"
#include "fileloader_p.h"
#include "playstate_p.h"
#include "detailsdialog.h"
@@ -46,6 +47,7 @@ PlayListModel::PlayListModel(const QString &name, QObject *parent)
m_stop_track = 0;
m_name = name;
m_loader = new FileLoader(this);
+ m_task = new PlayListTask(this);
if(m_ui_settings->isGroupsEnabled())
m_container = new GroupedContainer;
else
@@ -62,6 +64,7 @@ PlayListModel::PlayListModel(const QString &name, QObject *parent)
SLOT(insert(PlayListItem*, PlayListTrack*)), Qt::QueuedConnection);
connect(m_loader, SIGNAL(finished()), SLOT(preparePlayState()));
connect(m_loader, SIGNAL(finished()), SIGNAL(loaderFinished()));
+ connect(m_task, SIGNAL(finished()), SLOT(onTaskFinished()));
}
PlayListModel::~PlayListModel()
@@ -91,21 +94,21 @@ void PlayListModel::add(PlayListTrack *track)
{
m_container->addTrack(track);
m_total_length += track->length();
+ int flags = 0;
if(m_container->trackCount() == 1)
{
m_current_track = track;
m_current = m_container->indexOf(track);
- emit currentChanged();
+ flags |= CURRENT;
}
else if(m_ui_settings->isGroupsEnabled())
{
//update current index for grouped container only
m_current = m_container->indexOf(m_current_track);
}
- emit trackAdded(track);
- emit listChanged();
- emit countChanged();
+ flags |= STRUCTURE;
+ emit listChanged(flags);
}
void PlayListModel::add(QList<PlayListTrack *> tracks)
@@ -113,13 +116,15 @@ void PlayListModel::add(QList<PlayListTrack *> tracks)
if(tracks.isEmpty())
return;
+ int flags = 0;
+
m_container->addTracks(tracks);
if(m_container->trackCount() == tracks.count())
{
m_current_track = tracks.first();
m_current = m_container->indexOf(m_current_track);
- emit currentChanged();
+ flags |= CURRENT;
}
else if(m_ui_settings->isGroupsEnabled())
{
@@ -133,23 +138,32 @@ void PlayListModel::add(QList<PlayListTrack *> tracks)
emit trackAdded(track);
}
preparePlayState();
- emit listChanged();
- emit countChanged();
+ flags |= STRUCTURE;
+ emit listChanged(flags);
}
void PlayListModel::add(const QString &path)
{
- m_loader->add(path);
- loadPlaylist(path);
+ QStringList paths = PlayListParser::loadPlaylist(path);
+ if(paths.isEmpty())
+ m_loader->add(path);
+ else
+ m_loader->add(paths);
}
void PlayListModel::add(const QStringList &paths)
{
- m_loader->add(paths);
- foreach(QString str, paths)
+ QStringList urls, pl_urls;
+ foreach(QString path, paths)
{
- loadPlaylist(str);
+ pl_urls = PlayListParser::loadPlaylist(path); //is it playlist?
+ if(pl_urls.isEmpty())
+ urls.append(path);
+ else
+ urls.append(pl_urls);
+
}
+ m_loader->add(urls);
}
void PlayListModel::insert(int index, PlayListTrack *track)
@@ -157,11 +171,13 @@ void PlayListModel::insert(int index, PlayListTrack *track)
m_container->insertTrack(index, track);
m_total_length += track->length();
+ int flags = 0;
+
if(m_container->trackCount() == 1)
{
m_current_track = track;
m_current = m_container->indexOf(track);
- emit currentChanged();
+ flags |= CURRENT;
}
else
{
@@ -169,8 +185,8 @@ void PlayListModel::insert(int index, PlayListTrack *track)
m_current = m_container->indexOf(m_current_track);
}
emit trackAdded(track);
- emit listChanged();
- emit countChanged();
+ flags |= STRUCTURE;
+ emit listChanged(flags);
}
void PlayListModel::insert(PlayListItem *before, PlayListTrack *track)
@@ -183,6 +199,8 @@ void PlayListModel::insert(int index, QList<PlayListTrack *> tracks)
if(tracks.isEmpty())
return;
+ int flags = 0;
+
PlayListItem *prevItem = m_container->item(index);
foreach(PlayListTrack *track, tracks)
{
@@ -194,15 +212,15 @@ void PlayListModel::insert(int index, QList<PlayListTrack *> tracks)
{
m_current_track = track;
m_current = m_container->indexOf(track);
- emit currentChanged();
+ flags |= CURRENT;
}
emit trackAdded(track);
}
//update current index
m_current = m_container->indexOf(m_current_track);
preparePlayState();
- emit listChanged();
- emit countChanged();
+ flags |= STRUCTURE;
+ emit listChanged(flags);
}
void PlayListModel::insert(int index, const QString &path)
@@ -304,8 +322,7 @@ bool PlayListModel::setCurrent(int index)
}
m_current = index;
m_current_track = dynamic_cast<PlayListTrack*> (item);
- emit currentChanged();
- emit listChanged();
+ emit listChanged(CURRENT);
return true;
}
@@ -335,12 +352,14 @@ bool PlayListModel::next()
if(m_stop_track == currentTrack())
{
m_stop_track = 0;
- emit listChanged();
+ emit listChanged(STOP_AFTER);
return false;
}
- if (!isEmptyQueue())
+ if (!m_queued_songs.isEmpty())
{
- setCurrentToQueued();
+ m_current_track = m_queued_songs.dequeue();
+ m_current = m_container->indexOf(m_current_track);
+ emit listChanged(CURRENT | QUEUE);
return true;
}
@@ -365,14 +384,13 @@ void PlayListModel::clear()
m_queued_songs.clear();
m_total_length = 0;
m_play_state->resetState();
- emit listChanged();
- emit countChanged();
+ emit listChanged(STRUCTURE | QUEUE | STOP_AFTER | CURRENT | SELECTION);
}
void PlayListModel::clearSelection()
{
m_container->clearSelection();
- emit listChanged();
+ emit listChanged(SELECTION);
}
QList<PlayListItem *> PlayListModel::mid(int pos, int count) const
@@ -411,21 +429,21 @@ PlayListTrack *PlayListModel::findTrack(int number) const
void PlayListModel::setSelected(int index, bool selected)
{
m_container->setSelected(index, selected);
- emit listChanged();
+ emit listChanged(SELECTION);
}
void PlayListModel::setSelected(QList<PlayListTrack *> tracks, bool selected)
{
foreach(PlayListTrack *t, tracks)
t->setSelected(selected);
- emit listChanged();
+ emit listChanged(SELECTION);
}
void PlayListModel::setSelected(QList<PlayListItem *> items, bool selected)
{
foreach(PlayListItem *i, items)
i->setSelected(selected);
- emit listChanged();
+ emit listChanged(SELECTION);
}
void PlayListModel::setSelected(int first, int last, bool selected)
@@ -442,7 +460,7 @@ void PlayListModel::setSelected(int first, int last, bool selected)
continue;
i->setSelected(selected);
}
- emit listChanged();
+ emit listChanged(SELECTION);
}
void PlayListModel::removeSelected()
@@ -457,55 +475,9 @@ void PlayListModel::removeUnselected()
void PlayListModel::removeTrack (int i)
{
- bool current_changed = false;
- if ((i < count()) && (i >= 0))
- {
- PlayListTrack* track = m_container->track(i);
- if(!track)
- return;
- m_queued_songs.removeAll(track);
- m_container->removeTrack(track);
- if(m_stop_track == track)
- m_stop_track = 0;
- m_total_length -= track->length();
- m_total_length = qMax(0, m_total_length);
-
- if(m_current_track == track)
- {
- if(m_container->isEmpty())
- m_current_track = 0;
- else
- {
- current_changed = true;
- int current = qMin(i - 1, m_container->count() - 1);
- current = qMax(current, 0);
- m_current_track = m_container->track(current);
- if(!m_current_track)
- {
- m_current_track = current > 0 ? m_container->track(current-1) :
- m_container->track(1);
- }
- }
- }
-
- if (track->flag() == PlayListTrack::FREE)
- {
- delete track;
- track = NULL;
- }
- else if (track->flag() == PlayListTrack::EDITING)
- track->setFlag(PlayListTrack::SCHEDULED_FOR_DELETION);
-
-
- m_current = m_current_track ? m_container->indexOf(m_current_track) : -1;
- m_play_state->prepare();
-
- if(current_changed)
- emit currentChanged();
-
- emit listChanged();
- emit countChanged();
- }
+ int flags = removeTrackInternal(i);
+ if(flags)
+ emit listChanged(flags);
}
void PlayListModel::removeTrack (PlayListItem *track)
@@ -518,16 +490,14 @@ void PlayListModel::removeSelection(bool inverted)
{
int i = 0;
int select_after_delete = -1;
- PlayListTrack *prev_current_track = m_current_track;
+ int flags = 0;
while (!m_container->isEmpty() && i < m_container->count())
{
PlayListItem *item = m_container->item(i);
if (!item->isGroup() && item->isSelected() ^ inverted)
{
- blockSignals(true);
- removeTrack(i);
- blockSignals(false);
+ flags |= removeTrackInternal(i);
if(m_container->isEmpty())
continue;
@@ -538,33 +508,83 @@ void PlayListModel::removeSelection(bool inverted)
i++;
}
- if (select_after_delete >= m_container->count())
- select_after_delete = m_container->count() - 1;
+ select_after_delete = qMin(select_after_delete, m_container->count() - 1);
- if(select_after_delete != -1)
+ if(select_after_delete >= 0)
+ {
m_container->setSelected(select_after_delete, true);
+ flags |= SELECTION;
+ }
m_play_state->prepare();
- if(prev_current_track != m_current_track)
- emit currentChanged();
+ if(flags)
+ emit listChanged(flags);
+}
- emit listChanged();
- emit countChanged();
+int PlayListModel::removeTrackInternal(int i)
+{
+ if((i < 0) || (i >= count()))
+ return 0;
+
+ int flags = 0;
+ PlayListTrack* track = m_container->track(i);
+ if(!track)
+ return flags;
+ if(m_queued_songs.removeAll(track) > 0)
+ flags |= QUEUE;
+ m_container->removeTrack(track);
+ if(m_stop_track == track)
+ {
+ flags |= STOP_AFTER;
+ m_stop_track = 0;
+ }
+ if(track->isSelected())
+ flags |= SELECTION;
+
+ m_total_length -= track->length();
+ m_total_length = qMax(0, m_total_length);
+
+ if(m_current_track == track)
+ {
+ flags |= CURRENT;
+ if(m_container->isEmpty())
+ m_current_track = 0;
+ else
+ {
+ m_current = i > 0 ? qMin(i - 1, m_container->count() - 1) : 0;
+ if(!(m_current_track = m_container->track(m_current)))
+ {
+ m_current_track = m_current > 0 ? m_container->track(m_current - 1) :
+ m_container->track(1);
+ }
+ }
+ }
+
+ if (track->isUsed())
+ track->deleteLater();
+ else
+ delete track;
+
+ m_current = m_current_track ? m_container->indexOf(m_current_track) : -1;
+ m_play_state->prepare();
+
+ flags |= STRUCTURE;
+ return flags;
}
void PlayListModel::invertSelection()
{
for (int i = 0; i < m_container->count(); ++i)
m_container->setSelected(i, !m_container->isSelected(i));
- emit listChanged();
+ emit listChanged(SELECTION);
}
void PlayListModel::selectAll()
{
for (int i = 0; i < m_container->count(); ++i)
m_container->setSelected(i, true);
- emit listChanged();
+ emit listChanged(SELECTION);
}
void PlayListModel::showDetails(QWidget *parent)
@@ -576,9 +596,8 @@ void PlayListModel::showDetails(QWidget *parent)
if(!m_container->isSelected(i))
continue;
PlayListTrack *track = m_container->track(i);
- if(!track || track->flag() != PlayListTrack::FREE)
- continue;
- selected_tracks.append(track);
+ if(track)
+ selected_tracks.append(track);
}
if(!selected_tracks.isEmpty())
@@ -640,7 +659,7 @@ void PlayListModel::moveItems(int from, int to)
if(m_container->move(selected_indexes, from, to))
{
m_current = m_container->indexOf(m_current_track);
- emit listChanged();
+ emit listChanged(STRUCTURE);
}
}
@@ -714,9 +733,11 @@ QList<PlayListItem *> PlayListModel::items() const
void PlayListModel::addToQueue()
{
QList<PlayListTrack*> selected_tracks = selectedTracks();
+ blockSignals(true);
foreach(PlayListTrack* track, selected_tracks)
setQueued(track);
- emit listChanged();
+ blockSignals(false);
+ emit listChanged(QUEUE);
}
void PlayListModel::setQueued(PlayListTrack *item)
@@ -725,7 +746,7 @@ void PlayListModel::setQueued(PlayListTrack *item)
m_queued_songs.removeAll(item);
else
m_queued_songs.enqueue(item);
- emit listChanged();
+ emit listChanged(QUEUE);
}
bool PlayListModel::isQueued(PlayListTrack *f) const
@@ -733,11 +754,6 @@ bool PlayListModel::isQueued(PlayListTrack *f) const
return m_queued_songs.contains(f);
}
-void PlayListModel::setCurrentToQueued()
-{
- setCurrent(indexOf(m_queued_songs.dequeue()));
-}
-
bool PlayListModel::isEmptyQueue() const
{
return m_queued_songs.isEmpty();
@@ -764,7 +780,7 @@ void PlayListModel::randomizeList()
return;
m_container->randomizeList();
m_current = m_container->indexOf(m_current_track);
- emit listChanged();
+ emit listChanged(STRUCTURE);
}
void PlayListModel::reverseList()
@@ -773,25 +789,23 @@ void PlayListModel::reverseList()
return;
m_container->reverseList();
m_current = m_container->indexOf(m_current_track);
- emit listChanged();
+ emit listChanged(STRUCTURE);
}
void PlayListModel::sortSelection(int mode)
{
if(m_container->isEmpty())
return;
- m_container->sortSelection(mode);
- m_current = m_container->indexOf(m_current_track);
- emit listChanged();
+
+ m_task->sortSelection(m_container->tracks(), (PlayListModel::SortMode) mode);
}
void PlayListModel::sort(int mode)
{
if(m_container->isEmpty())
return;
- m_container->sort(mode);
- m_current = m_container->indexOf(m_current_track);
- emit listChanged();
+
+ m_task->sort(m_container->tracks(), (PlayListModel::SortMode) mode);
}
void PlayListModel::prepareForShufflePlaying(bool val)
@@ -817,13 +831,60 @@ void PlayListModel::prepareGroups(bool enabled)
m_container = container;
if(!m_container->isEmpty())
m_current = m_container->indexOf(m_current_track);
- emit listChanged();
+ emit listChanged(STRUCTURE);
+}
+
+void PlayListModel::onTaskFinished()
+{
+ if(m_task->isChanged(m_container)) //update unchanged container only
+ return;
+
+ if(m_task->type() == PlayListTask::SORT || m_task->type() == PlayListTask::SORT_SELECTION)
+ {
+ m_container->replaceTracks(m_task->takeResults(&m_current_track));
+ m_current = m_container->indexOf(m_current_track);
+ emit listChanged(STRUCTURE);
+ }
+ else if(m_task->type() == PlayListTask::REMOVE_INVALID
+ || m_task->type() == PlayListTask::REMOVE_DUPLICATES)
+ {
+ PlayListTrack *prev_current_track = m_current_track;
+ bool prev_count = m_container->count();
+
+ m_container->replaceTracks(m_task->takeResults(&m_current_track));
+
+ if(prev_count != m_container->count())
+ {
+ int flags = STRUCTURE;
+ m_current = m_container->indexOf(m_current_track);
+ if(prev_current_track != m_current_track)
+ flags |= CURRENT;
+
+ if(m_stop_track && !m_container->contains(m_stop_track))
+ {
+ m_stop_track = 0;
+ flags |= STOP_AFTER;
+ }
+
+ foreach (PlayListTrack *t, m_queued_songs)
+ {
+ if(!m_container->contains(t))
+ {
+ flags |= QUEUE;
+ m_queued_songs.removeAll(t);
+ }
+ }
+
+ emit listChanged(flags);
+ }
+ }
}
void PlayListModel::doCurrentVisibleRequest()
{
- emit currentChanged();
- emit listChanged();
+ //TODO check these signals
+ //emit currentChanged();
+ //emit listChanged();
}
void PlayListModel::loadPlaylist(const QString &f_name)
@@ -855,70 +916,25 @@ void PlayListModel::preparePlayState()
void PlayListModel::removeInvalidTracks()
{
- bool ok = false;
-
- for(int i = m_container->count() - 1; i >= 0; i--)
- {
- if(i >= m_container->count() || !isTrack(i))
- continue;
-
- PlayListTrack *track = m_container->track(i);
-
- if(track->url().contains("://"))
- ok = MetaDataManager::instance()->protocols().contains(track->url().section("://",0,0));
- else
- ok = MetaDataManager::instance()->supports(track->url());
- if(!ok)
- removeTrack(i);
-
- }
+ m_task->removeInvalidTracks(m_container->tracks(), m_current_track);
}
void PlayListModel::removeDuplicates()
{
- QStringList urls;
- bool modified = false;
- PlayListTrack *prev_current = m_current_track;
-
- for(int i = 0; i < m_container->count(); ++i)
- {
- if(!isTrack(i))
- continue;
-
- if(urls.contains(track(i)->url()))
- {
- blockSignals(true);
- removeTrack(i);
- blockSignals(false);
- modified = true;
- i--;
- }
- else
- {
- urls.append(track(i)->url());
- }
- }
-
- if(modified)
- {
- if(m_current_track != prev_current)
- emit currentChanged();
-
- emit listChanged();
- emit countChanged();
- }
+ m_task->removeDuplicates(m_container->tracks(), m_current_track);
}
void PlayListModel::clearQueue()
{
m_queued_songs.clear();
m_stop_track = 0;
- emit listChanged();
+ emit listChanged(QUEUE);
}
void PlayListModel::stopAfterSelected()
{
QList<PlayListTrack*> selected_tracks = selectedTracks();
+ int flags = STOP_AFTER;
if(!m_queued_songs.isEmpty())
{
m_stop_track = m_stop_track != m_queued_songs.last() ? m_queued_songs.last() : 0;
@@ -929,15 +945,18 @@ void PlayListModel::stopAfterSelected()
}
else if(selected_tracks.count() > 1)
{
+ blockSignals(true);
addToQueue();
+ blockSignals(false);
+ flags |= QUEUE;
m_stop_track = m_queued_songs.last();
}
else
return;
- emit listChanged();
+ emit listChanged(flags);
}
-void PlayListModel::updateGroups()
+void PlayListModel::rebuildGroups()
{
if(m_ui_settings->isGroupsEnabled())
prepareGroups(true);