diff options
| author | vovanec <vovanec@90c681e8-e032-0410-971d-27865f9a5e38> | 2008-02-07 13:36:34 +0000 |
|---|---|---|
| committer | vovanec <vovanec@90c681e8-e032-0410-971d-27865f9a5e38> | 2008-02-07 13:36:34 +0000 |
| commit | 06d1877811fa6aa97dddc0e03bcde4e766928c87 (patch) | |
| tree | c25462d0e58c3d58c728664440412bf4f16a49ec /src/playlistmodel.cpp | |
| parent | 3f6b60f23c44a8ba8dd97ca6f41a16e2af7ef2f7 (diff) | |
| download | qmmp-06d1877811fa6aa97dddc0e03bcde4e766928c87.tar.gz qmmp-06d1877811fa6aa97dddc0e03bcde4e766928c87.tar.bz2 qmmp-06d1877811fa6aa97dddc0e03bcde4e766928c87.zip | |
new directory structure
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@232 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/playlistmodel.cpp')
| -rw-r--r-- | src/playlistmodel.cpp | 899 |
1 files changed, 0 insertions, 899 deletions
diff --git a/src/playlistmodel.cpp b/src/playlistmodel.cpp deleted file mode 100644 index 196608438..000000000 --- a/src/playlistmodel.cpp +++ /dev/null @@ -1,899 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Ilya Kotov * - * forkotov02@hotmail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include <QWidget> -#include <QFile> -#include <QDir> -#include <QtAlgorithms> -#include <QFileInfo> -#include <QTextStream> -#include <QPluginLoader> -#include <QApplication> -#include <QTimer> -#include <QSettings> - -#include <time.h> - -#include <decoder.h> -#include <decoderfactory.h> - -#include "fileloader.h" -#include "playlistmodel.h" -#include "mediafile.h" -#include "playlistformat.h" -#include "playstate.h" - -#include <QMetaType> - -#define INVALID_ROW -1 - -TagUpdater::TagUpdater(QObject* o,MediaFile* f):m_observable(o),m_file(f) -{ - m_file->setFlag(MediaFile::EDITING); - connect (m_observable, SIGNAL(destroyed (QObject * )),SLOT(updateTag())); - connect (m_observable, SIGNAL(destroyed (QObject * )),SLOT(deleteLater())); -} - -void TagUpdater::updateTag() -{ - if(m_file->flag() == MediaFile::SCHEDULED_FOR_DELETION) - { - delete m_file; - m_file = NULL; - } - else - { - m_file->updateTags(); - m_file->setFlag(MediaFile::FREE); - } -} - - -PlayListModel::PlayListModel ( QObject *parent ) - : QObject ( parent ) , m_selection() -{ - qsrand(time(0)); - m_total_length = 0; - m_current = 0; - m_block_update_signals = false; - is_repeatable_list = false; - m_play_state = new NormalPlayState(this); - //readSettings(); - - registerPlaylistFormat( new PLSPlaylistFormat); - registerPlaylistFormat( new M3UPlaylistFormat); -#ifndef XSPF_PLUGIN - registerPlaylistFormat( new XSPFPlaylistFormat); -#endif - loadExternalPlaylistFormats(); -} - -PlayListModel::~PlayListModel() -{ - writeSettings(); - clear(); - delete m_play_state; - qDeleteAll(m_registered_pl_formats); - - foreach(GuardedFileLoader l,m_running_loaders) - { - if (!l.isNull()) - { - l->finish(); - l->wait(); - } - } -} - -void PlayListModel::load ( MediaFile *file ) -{ - if (m_files.isEmpty()) - m_currentItem = file; - - m_total_length += file->length(); - m_files << file; - - //if (!m_block_update_signals) - emit listChanged(); -} - -int PlayListModel::count() -{ - return m_files.size(); -} - -MediaFile* PlayListModel::currentItem() -{ - if ( m_files.isEmpty() ) - return 0; - else - return m_files.at ( qMin(m_files.size() - 1, m_current)); -} - -int PlayListModel::currentRow() -{ - return m_current; -} - -bool PlayListModel::setCurrent ( int c ) -{ - if ( c > count()-1 || c < 0) - return FALSE; - m_current = c; - m_currentItem = m_files.at(c); - emit currentChanged(); - emit listChanged(); - return TRUE; -} - - -bool PlayListModel::next() -{ - if (isFileLoaderRunning()) - m_play_state->prepare(); - - return m_play_state->next(); -} - -bool PlayListModel::previous() -{ - if (isFileLoaderRunning()) - m_play_state->prepare(); - - return m_play_state->previous();//) -} - -void PlayListModel::clear() -{ - foreach(GuardedFileLoader l,m_running_loaders) - { - if (!l.isNull()) - { - l->finish(); - l->wait(); - } - } - - m_running_loaders.clear(); - - m_current = 0; - while ( !m_files.isEmpty() ) - { - MediaFile* mf = m_files.takeFirst(); - - if(mf->flag() == MediaFile::FREE) - { - delete mf; - } - else if(mf->flag() == MediaFile::EDITING) - { - mf->setFlag(MediaFile::SCHEDULED_FOR_DELETION); - } - } - - m_total_length = 0; - m_play_state->resetState(); - emit listChanged(); -} - -void PlayListModel::clearSelection() -{ - for ( int i = 0; i<m_files.size(); ++i ) - m_files.at ( i )->setSelected ( FALSE ); - emit listChanged(); -} - -QList <QString> PlayListModel::getTitles ( int b,int l ) -{ - QList <QString> m_titles; - for ( int i = b; ( i < b + l ) && ( i < m_files.size() ); ++i ) - m_titles << m_files.at ( i )->title(); - return m_titles; -} - -QList <QString> PlayListModel::getTimes ( int b,int l ) -{ - QList <QString> m_times; - for ( int i = b; ( i < b + l ) && ( i < m_files.size() ); ++i ) - m_times << QString ( "%1" ).arg ( m_files.at ( i )->length() /60 ) +":" - +QString ( "%1" ).arg ( m_files.at ( i )->length() %60/10 ) + - QString ( "%1" ).arg ( m_files.at ( i )->length() %60%10 ); - return m_times; -} - -bool PlayListModel::isSelected ( int row ) -{ - if (m_files.count() > row && row >= 0) - return m_files.at ( row )->isSelected(); - - return false; -} - -void PlayListModel::setSelected ( int row, bool yes ) -{ - if (m_files.count() > row && row >= 0) - m_files.at ( row )->setSelected ( yes ); -} - -void PlayListModel::removeSelected() -{ - removeSelection(false); -} - -void PlayListModel::removeUnselected() -{ - removeSelection(true); -} - -void PlayListModel::removeSelection(bool inverted) -{ - int i = 0; - - int select_after_delete = -1; - - while ( !m_files.isEmpty() && i<m_files.size() ) - { - if ( m_files.at ( i )->isSelected() ^ inverted ) - { - MediaFile* f = m_files.takeAt ( i ); - m_total_length -= f->length(); - if (m_total_length < 0) - m_total_length = 0; - - if(f->flag() == MediaFile::FREE) - { - delete f; - f = NULL; - } - else if(f->flag() == MediaFile::EDITING) - f->setFlag(MediaFile::SCHEDULED_FOR_DELETION); - - select_after_delete = i; - - if ( m_current >= i && m_current!=0 ) - m_current--; - } - else - i++; - } - - if (!m_files.isEmpty()) - m_currentItem = m_files.at(m_current); - - if (select_after_delete >= m_files.count()) - select_after_delete = m_files.count() - 1; - - setSelected(select_after_delete,true); - - m_play_state->prepare(); - - emit listChanged(); -} - -void PlayListModel::invertSelection() -{ - for ( int i = 0; i<m_files.size(); ++i ) - m_files.at ( i )->setSelected ( !m_files.at ( i )->isSelected() ); - emit listChanged(); -} - -void PlayListModel::selectAll() -{ - for ( int i = 0; i<m_files.size(); ++i ) - m_files.at ( i )->setSelected ( TRUE ); - emit listChanged(); -} - -void PlayListModel::showDetails() -{ - for ( int i = 0; i<m_files.size(); ++i ) - { - if ( m_files.at ( i )->isSelected() ) - { - DecoderFactory *fact = Decoder::findByPath ( m_files.at ( i )->path() ); - if ( fact ) - { - QObject* o = fact->showDetails ( 0, m_files.at ( i )->path() ); - if(o) - { - TagUpdater *updater = new TagUpdater(o,m_files.at(i)); - m_editing_files.append(m_files.at(i)); - connect (updater, SIGNAL(destroyed (QObject * )),SIGNAL(listChanged())); - } - } - - return; - } - } - -} - - -void PlayListModel::readSettings() -{ - QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat); - m_current = settings.value("Playlist/current",0).toInt(); - - QFile file ( QDir::homePath() +"/.qmmp/playlist.txt" ); - file.open ( QIODevice::ReadOnly ); - - QStringList files; - QByteArray line; - m_files.clear(); - - while (!file.atEnd ()) - { - line = file.readLine(); - files << QString::fromUtf8 ( line ).trimmed (); - } - - file.close (); - - if(m_current > files.count() - 1) - m_current = 0; - - int preload = (files.count() < 100) ? files.count() : 100; - - for (int i = 0;i < preload;i++) - { - load(new MediaFile(files.takeAt(0))); - } - - if (files.isEmpty()) - { - doCurrentVisibleRequest (); - return; - } - - FileLoader* f_loader = createFileLoader(); - connect(f_loader, SIGNAL(finished ()), SLOT(doCurrentVisibleRequest ())); - - f_loader->setFilesToLoad(files); - //f_loader->start(QThread::IdlePriority); - QTimer::singleShot(1000,f_loader,SLOT(start())); - //m_play_state->prepare(); -} - -void PlayListModel::writeSettings() -{ - QFile file ( QDir::homePath() +"/.qmmp/playlist.txt" ); - file.open ( QIODevice::WriteOnly ); - foreach ( MediaFile* m, m_files ) - file.write ( m->path().toUtf8 () +"\n" ); - file.close (); - QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat); - settings.setValue("Playlist/current", m_current); -} - -void PlayListModel::addFile(const QString& path) -{ - if (path.isEmpty ()) - return; - if (path.startsWith("http://")) - load(new MediaFile(path)); - else if (Decoder::supports(path)) - load(new MediaFile(path)); - - m_play_state->prepare(); -} - -FileLoader * PlayListModel::createFileLoader() -{ - FileLoader* f_loader = new FileLoader(this); -// f_loader->setStackSize(20 * 1024 * 1024); - m_running_loaders << f_loader; - connect(f_loader,SIGNAL(newMediaFile(MediaFile*)),this,SLOT(load(MediaFile*)),Qt::QueuedConnection); - connect(f_loader,SIGNAL(finished()),this,SLOT(preparePlayState())); - connect(f_loader,SIGNAL(finished()),f_loader,SLOT(deleteLater())); - return f_loader; -} - -void PlayListModel::addFiles(const QStringList &files) -{ - FileLoader* f_loader = createFileLoader(); - f_loader->setFilesToLoad(files); - f_loader->start(QThread::IdlePriority); -} - -void PlayListModel::addDirectory(const QString& s) -{ - FileLoader* f_loader = createFileLoader(); - f_loader->setDirectoryToLoad(s); - f_loader->start(QThread::IdlePriority); -} - -void PlayListModel::addFileList(const QStringList &l) -{ -// qWarning("void// PlayListModel::addFileList(const QStringList &l)"); - foreach(QString str,l) - { - QFileInfo f_info(str); - if (f_info.exists()) - { - if (f_info.isDir()) - addDirectory(str); - else - addFile(str); - } - // Do processing the rest of events to avoid GUI freezing - QApplication::processEvents(QEventLoop::AllEvents,10); - } -} - -bool PlayListModel::setFileList(const QStringList & l) -{ - bool model_cleared = FALSE; - foreach(QString str,l) - { - QFileInfo f_info(str); - if (f_info.exists()) - { - if (!model_cleared) - { - clear(); - model_cleared = TRUE; - } - if (f_info.isDir()) - addDirectory(str); - else - addFile(str); - } - // Do processing the rest of events to avoid GUI freezing - QApplication::processEvents(QEventLoop::AllEvents,10); - } - - return model_cleared; -} - -int PlayListModel::firstSelectedUpper(int row) -{ - for (int i = row - 1;i >= 0;i--) - { - if (isSelected(i)) - return i; - } - return -1; -} - -int PlayListModel::firstSelectedLower(int row) -{ - for (int i = row + 1;i < count() ;i++) - { - if (isSelected(i)) - return i; - } - return -1; -} - -void PlayListModel::moveItems( int from, int to ) -{ - // Get rid of useless work - if (from == to) - return; - - QList<int> selected_rows = getSelectedRows(); - - if (! (bottommostInSelection(from) == INVALID_ROW || - from == INVALID_ROW || - topmostInSelection(from) == INVALID_ROW) - ) - { - if (from > to) - foreach(int i, selected_rows) - if (i + to - from < 0) - break; - else - m_files.move(i,i + to - from); - else - for (int i = selected_rows.count() - 1; i >= 0; i--) - if (selected_rows[i] + to -from >= m_files.count()) - break; - else - m_files.move(selected_rows[i],selected_rows[i] + to - from); - - m_current = m_files.indexOf(m_currentItem); - - emit listChanged(); - } -} - - - -int PlayListModel::topmostInSelection( int row) -{ - if ( row == 0) - return 0; - - for (int i = row - 1;i >= 0;i--) - { - if (isSelected(i)) - continue; - else - return i + 1; - } - return 0; -} - -int PlayListModel::bottommostInSelection( int row ) -{ - if (row >= m_files.count() - 1) - return row; - - for (int i = row + 1;i < count() ;i++) - { - if (isSelected(i)) - continue; - else - return i - 1; - } - return count() - 1; -} - -const SimpleSelection& PlayListModel::getSelection(int row ) -{ - m_selection.m_top = topmostInSelection( row ); - m_selection.m_anchor = row; - m_selection.m_bottom = bottommostInSelection( row ); - m_selection.m_selected_rows = getSelectedRows(); - return m_selection; -} - -QList<int> PlayListModel::getSelectedRows() const -{ - QList<int>selected_rows; - for (int i = 0;i<m_files.count();i++) - { - if (m_files[i]->isSelected()) - { - selected_rows.append(i); - } - } - return selected_rows; -} - -QList< MediaFile * > PlayListModel::getSelectedItems() const -{ - QList<MediaFile*>selected_items; - for (int i = 0;i<m_files.count();i++) - { - if (m_files[i]->isSelected()) - { - selected_items.append(m_files[i]); - } - } - return selected_items; -} - -void PlayListModel::addToQueue() -{ - QList<MediaFile*> selected_items = getSelectedItems(); - foreach(MediaFile* file,selected_items) - {/* - if (isQueued(file)) - m_queued_songs.removeAt(m_queued_songs.indexOf(file)); - else - m_queued_songs.append(file); - */ - setQueued(file); - } - emit listChanged(); -} - -void PlayListModel::setQueued(MediaFile* file) -{ - if (isQueued(file)) - m_queued_songs.removeAt(m_queued_songs.indexOf(file)); - else - m_queued_songs.append(file); - - emit listChanged(); -} - -bool PlayListModel::isQueued(MediaFile* f) const -{ - return m_queued_songs.contains(f); -} - -void PlayListModel::setCurrentToQueued() -{ - setCurrent(row(m_queued_songs.at(0))); - m_queued_songs.pop_front(); -} - -bool PlayListModel::isEmptyQueue() const -{ - return m_queued_songs.isEmpty(); -} - -void PlayListModel::randomizeList() -{ - for (int i = 0;i < m_files.size();i++) - m_files.swap(qrand()%m_files.size(),qrand()%m_files.size()); - - m_current = m_files.indexOf(m_currentItem); - emit listChanged(); -} - -void PlayListModel::reverseList() -{ - for (int i = 0;i < m_files.size()/2;i++) - m_files.swap(i,m_files.size() - i - 1); - - m_current = m_files.indexOf(m_currentItem); - emit listChanged(); -} - -////===============THE BEGINNING OF SORT IMPLEMENTATION =======================//// - -// First we'll implement bundle of static compare procedures -// to sort items in different ways -static bool _titleLessComparator(MediaFile* s1,MediaFile* s2) -{ - return s1->title() < s2->title(); -} - -static bool _titleGreaterComparator(MediaFile* s1,MediaFile* s2) -{ - return s1->title() > s2->title(); -} - -static bool _pathAndFilenameLessComparator(MediaFile* s1,MediaFile* s2) -{ - return s1->path() < s2->path(); -} - -static bool _pathAndFilenameGreaterComparator(MediaFile* s1,MediaFile* s2) -{ - return s1->path() > s2->path(); -} - -static bool _filenameLessComparator(MediaFile* s1,MediaFile* s2) -{ - QFileInfo i_s1(s1->path()); - QFileInfo i_s2(s2->path()); - return i_s1.baseName() < i_s2.baseName(); -} - -static bool _filenameGreaterComparator(MediaFile* s1,MediaFile* s2) -{ - QFileInfo i_s1(s1->path()); - QFileInfo i_s2(s2->path()); - return i_s1.baseName() > i_s2.baseName(); -} - -static bool _dateLessComparator(MediaFile* s1,MediaFile* s2) -{ - return s1->year() < s2->year(); -} - -static bool _dateGreaterComparator(MediaFile* s1,MediaFile* s2) -{ - return s1->year() > s2->year(); -} - -// This is main sort method -void PlayListModel::doSort(int sort_mode,QList<MediaFile*>& list_to_sort) -{ - QList<MediaFile*>::iterator begin; - QList<MediaFile*>::iterator end; - - begin = list_to_sort.begin(); - end = list_to_sort.end(); - - bool (*compareLessFunc)(MediaFile*,MediaFile*) = 0; - bool (*compareGreaterFunc)(MediaFile*,MediaFile*) = 0; - - switch (sort_mode) - { - case TITLE: - compareLessFunc = _titleLessComparator; - compareGreaterFunc = _titleGreaterComparator; - break; - case FILENAME: - compareLessFunc = _filenameLessComparator; - compareGreaterFunc = _filenameGreaterComparator; - break; - case PATH_AND_FILENAME: - compareLessFunc = _pathAndFilenameLessComparator; - compareGreaterFunc = _pathAndFilenameGreaterComparator; - break; - case DATE: - compareLessFunc = _dateLessComparator; - compareGreaterFunc = _dateGreaterComparator; - break; - //qWarning("TODO Sort by Date: %s\t%d",__FILE__,__LINE__); - default: - compareLessFunc = _titleLessComparator; - compareGreaterFunc = _titleGreaterComparator; - } - - static bool sorted_asc = false; - if (!sorted_asc) - { - qSort(begin,end,compareLessFunc); - sorted_asc = true; - } - else - { - qSort(begin,end,compareGreaterFunc); - sorted_asc = false; - } - - m_current = m_files.indexOf(m_currentItem); -} - -void PlayListModel::sortSelection(int mode) -{ - QList<MediaFile*>selected_items = getSelectedItems(); - QList<int>selected_rows = getSelectedRows(); - - doSort(mode,selected_items); - - for (int i = 0;i < selected_rows.count();i++) - m_files.replace(selected_rows[i],selected_items[i]); - - m_current = m_files.indexOf(m_currentItem); - emit listChanged(); -} - -void PlayListModel::sort(int mode) -{ - doSort(mode,m_files); - emit listChanged(); -} - -////=============== THE END OF SORT IMPLEMENTATION =======================//// - -void PlayListModel::prepareForShufflePlaying(bool val) -{ - if (m_play_state) - delete m_play_state; - - if (val) - m_play_state = new ShufflePlayState(this); - else - m_play_state = new NormalPlayState(this); - -} - -void PlayListModel::prepareForRepeatablePlaying(bool val) -{ - is_repeatable_list = val; -} - -void PlayListModel::doCurrentVisibleRequest() -{ - emit currentChanged(); - emit listChanged(); -} - -void PlayListModel::setUpdatesEnabled(bool yes) -{ - if (yes) - { - m_block_update_signals = false; - emit listChanged(); - } - else - { - m_block_update_signals = true; - } -} - -void PlayListModel::loadPlaylist(const QString & f_name) -{ - - foreach(PlaylistFormat* prs,m_registered_pl_formats.values()) - { - if (prs->hasFormat(QFileInfo(f_name).completeSuffix().toLower())) - { - QFile file(f_name); - if (file.open(QIODevice::ReadOnly)) - { - clear(); - addFiles(prs->decode(QTextStream(&file).readAll())); - file.close(); - } - else - qWarning("Error opening %s",f_name.toLocal8Bit().data()); - } - } -} - -void PlayListModel::savePlaylist(const QString & f_name) -{ - foreach(PlaylistFormat* prs,m_registered_pl_formats.values()) - { - if (prs->hasFormat(QFileInfo(f_name).completeSuffix().toLower())) - { - QFile file(f_name); - if (file.open(QIODevice::WriteOnly)) - { - QTextStream ts(&file); - ts << prs->encode(m_files); - file.close(); - } - else - qWarning("Error opening %s",f_name.toLocal8Bit().data()); - } - } -} - - -void PlayListModel::loadExternalPlaylistFormats() -{ - QDir pluginsDir (QDir::homePath()+"/.qmmp/plugins/PlaylistFormats"); - //pluginsDir.cdUp(); - //pluginsDir.cd("plugins/PlaylistFormats"); - foreach (QString fileName, pluginsDir.entryList(QDir::Files)) - { - QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); - QObject *plugin = loader.instance(); - if (loader.isLoaded()) - qDebug("PlaylistFormat: plugin loaded - %s", qPrintable(fileName)); - - PlaylistFormat *fmt = 0; - if (plugin) - fmt = qobject_cast<PlaylistFormat *>(plugin); - - if (fmt) - if (!registerPlaylistFormat(fmt)) - qDebug("Warning: Plugin with name %s is already registered...", - qPrintable(fmt->name())); - } -} - -bool PlayListModel::registerPlaylistFormat(PlaylistFormat* p) -{ - QString name = p->name(); - if (!m_registered_pl_formats.contains(name)) - { - m_registered_pl_formats.insert(name,p); - return true; - } - return false; -} - -bool PlayListModel::isFileLoaderRunning() const -{ - foreach(FileLoader* l,m_running_loaders) - if (l && l->isRunning()) - return TRUE; - - return FALSE; -} - -void PlayListModel::preparePlayState() -{ - m_play_state->prepare(); -} - - - - - - - - - - - - - - |
