aboutsummaryrefslogtreecommitdiff
path: root/src/qmmpui/playlisttask.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/playlisttask.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/playlisttask.cpp')
-rw-r--r--src/qmmpui/playlisttask.cpp371
1 files changed, 369 insertions, 2 deletions
diff --git a/src/qmmpui/playlisttask.cpp b/src/qmmpui/playlisttask.cpp
index fc23618e5..f1859135e 100644
--- a/src/qmmpui/playlisttask.cpp
+++ b/src/qmmpui/playlisttask.cpp
@@ -18,14 +18,381 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
+#include <QFileInfo>
+#include <QDateTime>
+#include <QTime>
+#include <qmmp/metadatamanager.h>
+#include "qmmpuisettings.h"
+#include "playlisttrack.h"
#include "playlisttask_p.h"
-PlayListTask::PlayListTask(QObject *parent) :
- QRunnable(parent)
+struct TrackField
{
+ PlayListTrack *track;
+ QString value;
+ QString groupName;
+};
+
+struct GroupdField
+{
+ QList <TrackField *> fields;
+ QString groupName;
+};
+
+////===============THE BEGINNING OF SORT IMPLEMENTATION =======================////
+
+// First we'll implement bundle of static compare procedures
+// to sort items in different ways
+
+//by string
+static bool _stringLessComparator(TrackField* s1, TrackField* s2)
+{
+ return QString::localeAwareCompare (s1->value, s2->value) < 0;
+}
+
+static bool _stringGreaterComparator(TrackField* s1, TrackField* s2)
+{
+ return QString::localeAwareCompare (s1->value, s2->value) > 0;
+}
+//by number
+static bool _numberLessComparator(TrackField* s1, TrackField* s2)
+{
+ return s1->value.toInt() < s2->value.toInt();
+}
+
+static bool _numberGreaterComparator(TrackField* s1, TrackField* s2)
+{
+ return s1->value.toInt() > s2->value.toInt();
+}
+//by file creation date
+static bool _fileCreationDateLessComparator(TrackField* s1, TrackField* s2)
+{
+ return QFileInfo(s1->value).created() < QFileInfo(s2->value).created();
+}
+
+static bool _fileCreationDateGreaterComparator(TrackField* s1, TrackField* s2)
+{
+ return QFileInfo(s1->value).created() > QFileInfo(s2->value).created();
+}
+//by file modification date
+static bool _fileModificationDateLessComparator(TrackField* s1, TrackField* s2)
+{
+ return QFileInfo(s1->value).lastModified() < QFileInfo(s2->value).lastModified();
+}
+
+static bool _fileModificationDateGreaterComparator(TrackField* s1, TrackField* s2)
+{
+ return QFileInfo(s1->value).lastModified() > QFileInfo(s2->value).lastModified();
+}
+//by file name
+static bool _filenameLessComparator(TrackField* s1, TrackField* s2)
+{
+ QFileInfo i_s1(s1->value);
+ QFileInfo i_s2(s2->value);
+ return QString::localeAwareCompare (i_s1.baseName(), i_s2.baseName()) < 0;
+}
+
+static bool _filenameGreaterComparator(TrackField* s1, TrackField* s2)
+{
+ QFileInfo i_s1(s1->value);
+ QFileInfo i_s2(s2->value);
+ return QString::localeAwareCompare (i_s1.baseName(), i_s2.baseName()) > 0;
+}
+////=============== THE END OF SORT IMPLEMENTATION =======================////
+
+PlayListTask::PlayListTask(QObject *parent) : QThread(parent)
+{
+ m_reverted = true;
+ m_align_groups = false;
+ m_current_track = 0;
+ m_task = EMPTY;
+
+ m_sort_keys.insert(PlayListModel::TITLE, Qmmp::TITLE);
+ m_sort_keys.insert(PlayListModel::DISCNUMBER, Qmmp::DISCNUMBER);
+ m_sort_keys.insert(PlayListModel::ALBUM, Qmmp::ALBUM);
+ m_sort_keys.insert(PlayListModel::ARTIST, Qmmp::ARTIST);
+ m_sort_keys.insert(PlayListModel::ALBUMARTIST, Qmmp::ALBUMARTIST);
+ m_sort_keys.insert(PlayListModel::FILENAME, Qmmp::URL);
+ m_sort_keys.insert(PlayListModel::PATH_AND_FILENAME, Qmmp::URL);
+ m_sort_keys.insert(PlayListModel::DATE, Qmmp::YEAR);
+ m_sort_keys.insert(PlayListModel::TRACK, Qmmp::TRACK);
+ m_sort_keys.insert(PlayListModel::FILE_CREATION_DATE, Qmmp::URL);
+ m_sort_keys.insert(PlayListModel::FILE_MODIFICATION_DATE, Qmmp::URL);
+}
+
+PlayListTask::~PlayListTask()
+{}
+
+void PlayListTask::sort(QList<PlayListTrack *> tracks, int mode)
+{
+ if(isRunning())
+ return;
+ clear();
+ m_reverted = !m_reverted;
+ m_sort_mode = mode;
+ m_task = SORT;
+ m_input_tracks = tracks;
+ Qmmp::MetaData key = m_sort_keys.value(mode);
+
+ m_align_groups = QmmpUiSettings::instance()->isGroupsEnabled() && (mode != PlayListModel::GROUP);
+
+ foreach (PlayListTrack *t, tracks)
+ {
+ TrackField *f = new TrackField;
+ f->track = t;
+ f->value = (mode == PlayListModel::GROUP) ? t->groupName() : t->value(key);
+ if(m_align_groups)
+ f->groupName = t->groupName();
+ m_fields.append(f);
+ }
+
+ start();
+}
+
+void PlayListTask::sortSelection(QList<PlayListTrack *> tracks, int mode)
+{
+ if(isRunning())
+ return;
+ clear();
+ m_reverted = !m_reverted;
+ m_sort_mode = mode;
+ m_task = SORT_SELECTION;
+ m_tracks = tracks;
+ m_input_tracks = tracks;
+ Qmmp::MetaData key = m_sort_keys.value(mode);
+
+ for(int i = 0; i < tracks.count(); ++i)
+ {
+ if(!tracks[i]->isSelected())
+ continue;
+
+ TrackField *f = new TrackField;
+ f->track = tracks[i];
+ f->value = (mode == PlayListModel::GROUP) ? f->track->groupName() : f->track->value(key);
+ m_fields.append(f);
+ m_indexes.append(i);
+ }
+
+ start();
+}
+
+void PlayListTask::removeInvalidTracks(QList<PlayListTrack *> tracks, PlayListTrack *current_track)
+{
+ if(isRunning())
+ return;
+ clear();
+ m_task = REMOVE_INVALID;
+ m_input_tracks = tracks;
+ m_tracks = tracks;
+ m_current_track = current_track;
+
+ for(int i = 0; i < tracks.count(); ++i)
+ {
+ TrackField *f = new TrackField;
+ f->track = tracks[i];
+ f->value = f->track->value(Qmmp::URL);
+ m_fields.append(f);
+ }
+ MetaDataManager::instance()->prepareForAnotherThread();
+ start();
+}
+
+void PlayListTask::removeDuplicates(QList<PlayListTrack *> tracks, PlayListTrack *current_track)
+{
+ if(isRunning())
+ return;
+ clear();
+ m_task = REMOVE_DUPLICATES;
+ m_input_tracks = tracks;
+ m_tracks = tracks;
+ m_current_track = current_track;
+
+ for(int i = 0; i < tracks.count(); ++i)
+ {
+ TrackField *f = new TrackField;
+ f->track = tracks[i];
+ f->value = f->track->value(Qmmp::URL);
+ m_fields.append(f);
+ }
+ MetaDataManager::instance()->prepareForAnotherThread();
+ start();
}
void PlayListTask::run()
{
+ qDebug("PlayListTask: started");
+
+ if(m_task == SORT || m_task == SORT_SELECTION)
+ {
+ bool(*compareLessFunc)(TrackField*, TrackField*) = 0;
+ bool(*compareGreaterFunc)(TrackField*, TrackField*) = 0;
+
+ QList<TrackField*>::iterator begin = m_fields.begin();
+ QList<TrackField*>::iterator end = m_fields.end();
+
+ if(m_sort_mode == PlayListModel::FILE_CREATION_DATE)
+ {
+ compareLessFunc = _fileCreationDateLessComparator;
+ compareGreaterFunc = _fileCreationDateGreaterComparator;
+ }
+ else if(m_sort_mode == PlayListModel::FILE_MODIFICATION_DATE)
+ {
+ compareLessFunc = _fileModificationDateLessComparator;
+ compareGreaterFunc = _fileModificationDateGreaterComparator;
+ }
+ else if(m_sort_mode == PlayListModel::TRACK || m_sort_mode == PlayListModel::DATE)
+ {
+ compareLessFunc = _numberLessComparator;
+ compareGreaterFunc = _numberGreaterComparator;
+ }
+ else if(m_sort_mode == PlayListModel::FILENAME)
+ {
+ compareLessFunc = _filenameLessComparator;
+ compareGreaterFunc = _filenameGreaterComparator;
+ }
+ else
+ {
+ compareLessFunc = _stringLessComparator;
+ compareGreaterFunc = _stringGreaterComparator;
+ }
+
+ if(m_reverted)
+ qStableSort(begin,end,compareGreaterFunc);
+ else
+ qStableSort(begin,end,compareLessFunc);
+
+ //align track list by group name (optimization)
+ if(m_align_groups)
+ {
+ QList<GroupdField *> groups;
+ bool found = false;
+ for(int i = 0; i < m_fields.count(); ++i)
+ {
+ found = false;
+ for(int j = groups.count() - 1; j >= 0; j--)
+ {
+ if(groups[j]->groupName == m_fields[i]->groupName)
+ {
+ groups[j]->fields.append(m_fields[i]);
+ found = true;
+ break;
+ }
+ }
+
+ if(!found)
+ {
+ groups << new GroupdField;
+ groups.last()->fields.append(m_fields[i]);
+ groups.last()->groupName = m_fields[i]->groupName;
+ }
+ }
+
+ m_fields.clear();
+ for(int j = 0; j < groups.count(); ++j)
+ {
+ m_fields.append(groups[j]->fields);
+ }
+ qDeleteAll(groups);
+ groups.clear();
+ }
+ }
+ else if(m_task == REMOVE_INVALID)
+ {
+ TrackField *f = 0;
+ bool ok = false;
+ for(int i = 0; i < m_fields.count(); ++i)
+ {
+ f = m_fields.at(i);
+
+ if(f->value.contains("://"))
+ ok = MetaDataManager::instance()->protocols().contains(f->value.section("://",0,0)); //url
+ else
+ ok = MetaDataManager::instance()->supports(f->value); //local file
+
+ if(!ok)
+ m_indexes << i;
+ }
+ }
+ else if(m_task == REMOVE_DUPLICATES)
+ {
+ QStringList urls;
+ TrackField *f = 0;
+ for(int i = 0; i < m_fields.count(); ++i)
+ {
+ f = m_fields.at(i);
+
+ if(urls.contains(f->value))
+ {
+ m_indexes.append(i);
+ }
+ else
+ {
+ urls.append(f->value);
+ }
+ }
+ }
+ qDebug("PlayListTask: finished");
+}
+
+PlayListTask::TaskType PlayListTask::type() const
+{
+ return m_task;
+}
+
+bool PlayListTask::isChanged(PlayListContainer *container)
+{
+ if(m_input_tracks.count() != container->trackCount())
+ return true;
+
+ return m_input_tracks != container->tracks();
+}
+QList<PlayListTrack *> PlayListTask::takeResults(PlayListTrack **current_track)
+{
+ if(m_task == SORT)
+ {
+ foreach (TrackField *f, m_fields)
+ m_tracks.append(f->track);
+ }
+ else if(m_task == SORT_SELECTION)
+ {
+ for (int i = 0; i < m_indexes.count(); i++)
+ m_tracks.replace(m_indexes[i], m_fields[i]->track);
+ }
+ else if(m_task == REMOVE_INVALID || m_task == REMOVE_DUPLICATES)
+ {
+ int index = 0;
+ PlayListTrack *t = 0;
+ for (int i = m_indexes.count() - 1; i >= 0; i--)
+ {
+ index = m_indexes.at(i);
+ t = m_tracks.takeAt(index);
+ if(t == m_current_track)
+ {
+ if(m_tracks.isEmpty())
+ m_current_track = 0;
+ else if(index > 0 && index <= m_tracks.count())
+ m_current_track = m_tracks[index - 1];
+ else
+ m_current_track = m_tracks[0];
+ *current_track = m_current_track;
+ }
+ if(t->isUsed())
+ t->deleteLater();
+ else
+ delete t;
+ }
+ }
+ return m_tracks;
+}
+
+void PlayListTask::clear()
+{
+ qDeleteAll(m_fields);
+ m_fields.clear();
+ m_align_groups = false;
+ m_indexes.clear();
+ m_input_tracks.clear();
+ m_tracks.clear();
+ m_current_track = 0;
}