diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2015-01-09 12:01:22 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2015-01-09 12:01:22 +0000 |
| commit | ebd7f9bc697973366de8a6bf7265051e825e0680 (patch) | |
| tree | 1feb9df1c5fe3493e9aa1dd8f5d6233a38ae9d3c /src/qmmpui/playlisttask.cpp | |
| parent | bc7ad688c646afd2a89e5c5ff58696f2df2c8605 (diff) | |
| download | qmmp-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.cpp | 371 |
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; } |
