diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2013-08-05 11:50:37 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2013-08-05 11:50:37 +0000 |
| commit | 245d0ac0cdb729c94ca71dc035342154d70aa8e5 (patch) | |
| tree | f908567eb29ddba73c36e82511605d3635a897e8 /src/qmmpui | |
| parent | d04ab1bfe9a70049e0c9ee753835c95a6ccf2086 (diff) | |
| download | qmmp-245d0ac0cdb729c94ca71dc035342154d70aa8e5.tar.gz qmmp-245d0ac0cdb729c94ca71dc035342154d70aa8e5.tar.bz2 qmmp-245d0ac0cdb729c94ca71dc035342154d70aa8e5.zip | |
added playlist groups, disabled broken plugins
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@3564 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/qmmpui')
26 files changed, 1023 insertions, 448 deletions
diff --git a/src/qmmpui/detailsdialog.cpp b/src/qmmpui/detailsdialog.cpp index 5be918ebe..0ade03e9e 100644 --- a/src/qmmpui/detailsdialog.cpp +++ b/src/qmmpui/detailsdialog.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2009-2012 by Ilya Kotov * + * Copyright (C) 2009-2013 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -28,11 +28,11 @@ #include <qmmp/tagmodel.h> #include <qmmp/soundcore.h> #include "ui_detailsdialog.h" -#include "playlistitem.h" +#include "playlisttrack.h" #include "tageditor_p.h" #include "detailsdialog.h" -DetailsDialog::DetailsDialog(PlayListItem *item, QWidget *parent) +DetailsDialog::DetailsDialog(PlayListTrack *item, QWidget *parent) : QDialog(parent) { m_ui = new Ui::DetailsDialog; diff --git a/src/qmmpui/detailsdialog.h b/src/qmmpui/detailsdialog.h index a8bcad25d..570235a71 100644 --- a/src/qmmpui/detailsdialog.h +++ b/src/qmmpui/detailsdialog.h @@ -27,7 +27,7 @@ class QTextCodec; class QAbstractButton; -class PlayListItem; +class PlayListTrack; class MetaDataModel; namespace Ui { @@ -46,7 +46,7 @@ public: * @param item Playlist item which should be used. * @param parent Parent widget. */ - DetailsDialog(PlayListItem *item, QWidget *parent = 0); + DetailsDialog(PlayListTrack *item, QWidget *parent = 0); /*! * Destructor. */ @@ -62,7 +62,7 @@ private: QString m_path; QString formatRow(const QString key, const QString value); MetaDataModel *m_metaDataModel; - PlayListItem *m_item; + PlayListTrack *m_item; }; #endif diff --git a/src/qmmpui/fileloader.cpp b/src/qmmpui/fileloader.cpp index 98e881872..d4ce69002 100644 --- a/src/qmmpui/fileloader.cpp +++ b/src/qmmpui/fileloader.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2006-2012 by Ilya Kotov * + * Copyright (C) 2006-2013 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -22,7 +22,7 @@ #include <QRegExp> #include "fileloader_p.h" #include "qmmpuisettings.h" -#include "playlistitem.h" +#include "playlisttrack.h" FileLoader::FileLoader(QObject *parent) : QThread(parent) { @@ -38,7 +38,7 @@ void FileLoader::addFile(const QString &path) bool use_meta = m_settings->useMetadata(); QList <FileInfo *> playList = MetaDataManager::instance()->createPlayList(path, use_meta); foreach(FileInfo *info, playList) - emit newPlayListItem(new PlayListItem(info)); + emit newPlayListTrack(new PlayListTrack(info)); } void FileLoader::addDirectory(const QString& s) diff --git a/src/qmmpui/fileloader_p.h b/src/qmmpui/fileloader_p.h index a2e2a468f..fc3c798f3 100644 --- a/src/qmmpui/fileloader_p.h +++ b/src/qmmpui/fileloader_p.h @@ -26,7 +26,7 @@ #include <QFileInfo> #include <QThread> -class PlayListItem; +class PlayListTrack; class QmmpUiSettings; /*! @internal @@ -73,7 +73,7 @@ signals: * Emitted when new playlist item is available. * @param item Pointer of the new PlayListItem object. */ - void newPlayListItem(PlayListItem *item); + void newPlayListTrack(PlayListTrack *item); protected: virtual void run(); diff --git a/src/qmmpui/jumptotrackdialog.cpp b/src/qmmpui/jumptotrackdialog.cpp index 132fe7c17..8ecf84a41 100644 --- a/src/qmmpui/jumptotrackdialog.cpp +++ b/src/qmmpui/jumptotrackdialog.cpp @@ -81,16 +81,16 @@ void JumpToTrackDialog::on_refreshPushButton_clicked() void JumpToTrackDialog::on_queuePushButton_clicked() { - QModelIndexList mi_list = songsListView->selectionModel()->selectedRows(); + /*QModelIndexList mi_list = songsListView->selectionModel()->selectedRows(); if (!mi_list.isEmpty()) { int selected = (m_proxyModel->mapToSource(mi_list.at(0))).row(); - m_model->setQueued(m_model->item(selected)); - if (m_model->isQueued(m_model->item(selected))) + m_model->setQueued(m_model->track(selected)); + if (m_model->isQueued(m_model->track(selected))) queuePushButton->setText(tr("Unqueue")); else queuePushButton->setText(tr("Queue")); - } + }*/ } void JumpToTrackDialog::on_jumpToPushButton_clicked() @@ -104,12 +104,12 @@ void JumpToTrackDialog::on_jumpToPushButton_clicked() void JumpToTrackDialog::refresh() { - filterLineEdit->clear(); + /*filterLineEdit->clear(); QStringList titles; - foreach (PlayListItem *item, m_model->items()) + foreach (PlayListTrack *item, m_model->items()) titles.append(item->formattedTitle()); m_listModel->setStringList(titles); - filterLineEdit->setFocus(); + filterLineEdit->setFocus();*/ } void JumpToTrackDialog::on_filterLineEdit_textChanged(const QString &str) @@ -140,9 +140,9 @@ void JumpToTrackDialog::jumpTo(const QModelIndex & index) void JumpToTrackDialog::queueUnqueue(const QModelIndex& curr,const QModelIndex&) { - int row = m_proxyModel->mapToSource(curr).row(); + /*int row = m_proxyModel->mapToSource(curr).row(); if (m_model->isQueued(m_model->item(row))) queuePushButton->setText(tr("Unqueue")); else - queuePushButton->setText(tr("Queue")); + queuePushButton->setText(tr("Queue"));*/ } diff --git a/src/qmmpui/mediaplayer.cpp b/src/qmmpui/mediaplayer.cpp index c251bec0e..fbe61d74e 100644 --- a/src/qmmpui/mediaplayer.cpp +++ b/src/qmmpui/mediaplayer.cpp @@ -89,7 +89,7 @@ void MediaPlayer::play(qint64 offset) if (m_pl_manager->currentPlayList()->count() == 0) return; - QString s = m_pl_manager->currentPlayList()->currentItem()->url(); + QString s = m_pl_manager->currentPlayList()->currentTrack()->url(); if (s.isEmpty()) { m_nextUrl.clear(); @@ -172,18 +172,18 @@ void MediaPlayer::setNoPlaylistAdvance(bool enabled) void MediaPlayer::updateNextUrl() { m_nextUrl.clear(); - PlayListItem *item = 0; + PlayListTrack *track = 0; if(isRepeatable()) - item = m_pl_manager->currentPlayList()->currentItem(); + track = m_pl_manager->currentPlayList()->currentTrack(); else if(!m_noPlaylistAdvance) - item = m_pl_manager->currentPlayList()->nextItem(); + track = m_pl_manager->currentPlayList()->nextTrack(); - if(item) + if(track) { - bool ok = m_core->play(item->url(), true); + bool ok = m_core->play(track->url(), true); if(ok) { - m_nextUrl = item->url(); + m_nextUrl = track->url(); qDebug("MediaPlayer: next track state: received"); } else @@ -231,9 +231,9 @@ void MediaPlayer::updateMetaData() qDebug("== end of metadata =="); PlayListModel *pl = m_pl_manager->currentPlayList(); - if (pl->currentItem() && pl->currentItem()->url() == m_core->metaData().value(Qmmp::URL)) + if (pl->currentTrack() && pl->currentTrack()->url() == m_core->metaData().value(Qmmp::URL)) { - pl->currentItem()->updateMetaData(m_core->metaData()); + pl->currentTrack()->updateMetaData(m_core->metaData()); pl->doCurrentVisibleRequest(); } } diff --git a/src/qmmpui/metadataformatter.cpp b/src/qmmpui/metadataformatter.cpp index 67442e845..a5471dd1a 100644 --- a/src/qmmpui/metadataformatter.cpp +++ b/src/qmmpui/metadataformatter.cpp @@ -47,7 +47,7 @@ MetaDataFormatter::MetaDataFormatter(const QString &format) m_format = format; } -QString MetaDataFormatter::parse(const PlayListItem *item) +QString MetaDataFormatter::parse(const PlayListTrack *item) { return parse(*item, item->length()); } diff --git a/src/qmmpui/metadataformatter.h b/src/qmmpui/metadataformatter.h index 0849a1117..ac33d8282 100644 --- a/src/qmmpui/metadataformatter.h +++ b/src/qmmpui/metadataformatter.h @@ -23,7 +23,7 @@ #include <QString> #include <QMap> -#include <qmmpui/playlistitem.h> +#include <qmmpui/playlisttrack.h> #include <qmmp/qmmp.h> /*! @brief The MetaDataFormatter formats metadata using templates. @@ -55,7 +55,7 @@ public: /*! * Converts metadata of item \b item to one string using template. */ - QString parse(const PlayListItem *item); + QString parse(const PlayListTrack *item); /*! * Converts metadata to one string using template. * @param metaData Metadata array. diff --git a/src/qmmpui/playlistcontainer.cpp b/src/qmmpui/playlistcontainer.cpp new file mode 100644 index 000000000..ea308d41f --- /dev/null +++ b/src/qmmpui/playlistcontainer.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** + * Copyright (C) 2013 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "playlistcontainer.h" + +PlayListContainer::PlayListContainer() +{ + qDebug("%s", Q_FUNC_INFO); +} + +void PlayListContainer::addGroup(PlayListGroup *group) +{ + m_groups.append(group); + m_items.append(group); + foreach (PlayListTrack *item, *group->tracks()) + { + m_items.append(item); + } + updateIndex(); +} + +void PlayListContainer::addTrack(PlayListTrack *track) +{ + foreach(PlayListGroup *group, m_groups) + { + if(track->groupName() == group->formattedTitle()) + { + group->addTrack(track); + m_items.insert(group->lastIndex + 1, track); + updateIndex(); + return; + } + } + + PlayListGroup *group = new PlayListGroup(track->groupName()); + group->addTrack(track); + addGroup(group); +} + +QList<PlayListGroup *> PlayListContainer::groups() +{ + return m_groups; +} + +QList<PlayListItem *> PlayListContainer::items() const +{ + return m_items; +} + +int PlayListContainer::count() const +{ + return m_items.count(); +} + +int PlayListContainer::trackCount() const +{ + return m_items.count() - m_groups.count(); +} + +QList<PlayListItem *> PlayListContainer::mid(int pos, int count) const +{ + return m_items.mid(pos, count); +} + +bool PlayListContainer::isEmpty() const +{ + return m_items.isEmpty(); +} + +bool PlayListContainer::isSelected(int index) const +{ + if (0 <= index && index < m_items.count()) + return m_items.at(index)->isSelected(); + return false; +} + +void PlayListContainer::setSelected(int index, bool selected) +{ + if (0 <= index && index < m_items.count() && !m_items.at(index)->isGroup()) + m_items.at(index)->setSelected(selected); +} + +void PlayListContainer::clearSelection() +{ + foreach (PlayListItem *item, m_items) + { + item->setSelected(false); + } +} + +int PlayListContainer::indexOf(PlayListItem *item) const +{ + return m_items.indexOf(item); +} + +PlayListItem *PlayListContainer::item(int index) const +{ + if(index >= count() || index < 0) + { + qWarning("PlayListItem: index is out of range"); + return 0; + } + return m_items.at(index); +} + +PlayListTrack *PlayListContainer::track(int index) const +{ + PlayListItem *i = item(index); + if(!i || i->isGroup()) + return 0; + return dynamic_cast<PlayListTrack *> (i); +} + +bool PlayListContainer::contains(PlayListItem *track) const +{ + return m_items.contains(track); +} + +int PlayListContainer::numberOfTrack(int index) const +{ + for(int i = 0; i < m_groups.count(); ++i) + { + if(index >= m_groups[i]->firstIndex && index <= m_groups[i]->lastIndex) + { + return index - (i+1); + } + } + return -1; +} + +void PlayListContainer::removeTrack(int index) +{ + PlayListTrack *t = track(index); + if(t) + { + removeTrack(t); + if (t->flag() == PlayListTrack::FREE) + { + delete t; + } + else if (t->flag() == PlayListTrack::EDITING) + { + t->setFlag(PlayListTrack::SCHEDULED_FOR_DELETION); + } + } +} + +void PlayListContainer::removeTrack(PlayListTrack *track) +{ + m_items.removeAll(track); + + foreach(PlayListGroup *group, m_groups) + { + if(group->contains(track)) + { + group->remove(track); + if(group->isEmpty()) + { + m_groups.removeAll(group); + m_items.removeAll(group); + delete group; + } + updateIndex(); + return; + } + } +} + +void PlayListContainer::clear() +{ + while(!m_groups.isEmpty()) + { + delete m_groups.takeFirst(); + } + m_items.clear(); +} + +void PlayListContainer::updateIndex() +{ + for(int i = 0; i < m_groups.count(); ++i) + { + if(i == 0) + { + m_groups[i]->firstIndex = 0; + m_groups[i]->lastIndex = m_groups[i]->count(); + } + else + { + m_groups[i]->firstIndex = m_groups[i-1]->lastIndex + 1; + m_groups[i]->lastIndex = m_groups[i]->firstIndex + m_groups[i]->count(); + } + } +} diff --git a/src/qmmpui/playlistcontainer.h b/src/qmmpui/playlistcontainer.h new file mode 100644 index 000000000..1d400a9f2 --- /dev/null +++ b/src/qmmpui/playlistcontainer.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2013 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef PLAYLISTCONTAINER_H +#define PLAYLISTCONTAINER_H + +#include <QList> +#include "playlistitem.h" +#include "playlisttrack.h" +#include "playlistgroup.h" + + +class PlayListContainer +{ +public: + PlayListContainer(); + + void addGroup(PlayListGroup *group); + void addTrack(PlayListTrack *item); + + QList<PlayListGroup *> groups(); + QList<PlayListItem *> items() const; + int count() const; + int trackCount() const; + QList<PlayListItem *> mid(int pos, int count) const; + bool isEmpty() const; + + bool isSelected(int index) const; + void setSelected(int index, bool selected); + void clearSelection(); + int indexOf(PlayListItem *item) const; + PlayListItem *item(int index) const; + PlayListTrack *track(int index) const; + bool contains(PlayListItem *track) const; + int numberOfTrack(int index) const; + + void removeTrack(int index); + void removeTrack(PlayListTrack *track); + + void clear(); + +private: + void updateIndex(); + QList<PlayListGroup *> m_groups; + QList<PlayListItem *> m_items; + +}; + +#endif // PLAYLISTCONTAINER_H diff --git a/src/qmmpui/playlistformat.h b/src/qmmpui/playlistformat.h index 222425924..ba7ca26f2 100644 --- a/src/qmmpui/playlistformat.h +++ b/src/qmmpui/playlistformat.h @@ -23,7 +23,7 @@ #include <QStringList> -class PlayListItem; +class PlayListTrack; /*! @brief Helper structure to store playlist format properies. * @author Ilya Kotov <forkotov02@hotmail.ru> @@ -58,7 +58,7 @@ public: * Takes the list of AbstractPlaylistItem objects, should return string of * encoded playlist file */ - virtual QString encode(const QList<PlayListItem*>& contents) = 0; + virtual QString encode(const QList<PlayListTrack*>& contents) = 0; }; Q_DECLARE_INTERFACE(PlayListFormat,"PlayListFormat/1.0") diff --git a/src/qmmpui/playlistgroup.cpp b/src/qmmpui/playlistgroup.cpp new file mode 100644 index 000000000..1d33e8ec6 --- /dev/null +++ b/src/qmmpui/playlistgroup.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2013 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "playlistgroup.h" + +PlayListGroup::PlayListGroup(const QString &name) +{ + m_name = name; + firstIndex = 0; + lastIndex = 0; +} + +PlayListGroup::~PlayListGroup() +{ + while(!m_tracks.isEmpty()) + { + PlayListTrack* mf = m_tracks.takeFirst(); + + if (mf->flag() == PlayListTrack::FREE) + { + delete mf; + } + else if (mf->flag() == PlayListTrack::EDITING) + { + mf->setFlag(PlayListTrack::SCHEDULED_FOR_DELETION); + } + } +} + +const QString PlayListGroup::formattedTitle() const +{ + return m_name; +} + +void PlayListGroup::addTrack(PlayListTrack *track) +{ + m_tracks.append(track); +} + +bool PlayListGroup::contains(PlayListTrack *track) const +{ + return m_tracks.contains(track); +} + +bool PlayListGroup::isEmpty() const +{ + return m_tracks.isEmpty(); +} + +void PlayListGroup::remove(PlayListTrack *track) +{ + m_tracks.removeAll(track); +} + +QList<PlayListTrack *> *PlayListGroup::tracks() +{ + return &m_tracks; +} + +int PlayListGroup::count() const +{ + return m_tracks.count(); +} diff --git a/src/qmmpui/playlistgroup.h b/src/qmmpui/playlistgroup.h new file mode 100644 index 000000000..698cf0a6c --- /dev/null +++ b/src/qmmpui/playlistgroup.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2013 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef PLAYLISTGROUP_H +#define PLAYLISTGROUP_H + +#include "playlisttrack.h" +#include "playlistitem.h" + +class PlayListGroup : public PlayListItem +{ +public: + PlayListGroup(const QString &formattedTitle); + + virtual ~PlayListGroup(); + + int firstIndex; + int lastIndex; + + const QString formattedTitle() const; + void addTrack(PlayListTrack *track); + bool contains(PlayListTrack *track) const; + bool isEmpty() const; + void remove(PlayListTrack *track); + + QList<PlayListTrack *> *tracks(); + + int count() const; + + + + /*! + * Returns formatted length of the item. + */ + const QString formattedLength() const { return QString(); } + + virtual bool isGroup() const { return true; } + +private: + QList<PlayListTrack *> m_tracks; + QString m_name; +}; + +#endif // PLAYLISTGROUP_H diff --git a/src/qmmpui/playlistitem.cpp b/src/qmmpui/playlistitem.cpp index 3956a1d1a..eced1e032 100644 --- a/src/qmmpui/playlistitem.cpp +++ b/src/qmmpui/playlistitem.cpp @@ -22,39 +22,13 @@ #include "qmmpuisettings.h" #include "playlistitem.h" -PlayListItem::PlayListItem() : QMap<Qmmp::MetaData, QString>(), m_flag(FREE) +PlayListItem::PlayListItem() { - m_info = 0; - m_length = 0; m_selected = false; } -PlayListItem::PlayListItem(const PlayListItem &other) : QMap<Qmmp::MetaData, QString>(other), - m_flag(other.m_flag) -{ - m_formattedTitle = other.m_formattedTitle; - if (other.m_info) - m_info = new FileInfo(*(other.m_info)); - else - m_info = 0; - m_selected = other.m_selected; - m_length = other.m_length; - m_formattedLength = other.m_formattedLength; -} - -PlayListItem::PlayListItem(FileInfo *info) : QMap<Qmmp::MetaData, QString>(info->metaData()), m_flag(FREE) -{ - setLength(m_length = info->length()); - m_selected = false; - m_info = info; - insert(Qmmp::URL, m_info->path()); -} - PlayListItem::~PlayListItem() -{ - if (m_info) - delete m_info; -} +{} void PlayListItem::setSelected(bool yes) { @@ -66,93 +40,4 @@ bool PlayListItem::isSelected() const return m_selected; } -void PlayListItem::setFlag(FLAGS f) -{ - m_flag = f; -} - -PlayListItem::FLAGS PlayListItem::flag() const -{ - return m_flag; -} - -void PlayListItem::updateMetaData(const QMap <Qmmp::MetaData, QString> &metaData) -{ - QMap <Qmmp::MetaData, QString>::operator =(metaData); - readMetadata(); -} -void PlayListItem::updateTags() -{ - if (m_info) - { - delete m_info; - m_info = 0; - } - QList <FileInfo *> list = MetaDataManager::instance()->createPlayList(value(Qmmp::URL)); - if(!list.isEmpty() && !list.at(0)->path().contains("://")) - { - m_info = list.at(0); - m_length = m_info->length(); - QMap <Qmmp::MetaData, QString>::operator =(m_info->metaData()); - insert(Qmmp::URL, m_info->path()); - readMetadata(); - } - while(list.size() > 1) - delete list.takeLast(); -} - -const QString PlayListItem::groupName() const -{ - MetaDataFormatter f("%p"); - return f.parse(this); -} - -const QString PlayListItem::formattedTitle() -{ - if(m_formattedTitle.isEmpty()) - readMetadata(); - return m_formattedTitle; -} - -const QString PlayListItem::formattedLength() const -{ - return m_formattedLength; -} - -void PlayListItem::setText(const QString &title) -{ - m_formattedTitle = title; -} - -qint64 PlayListItem::length() const -{ - return m_length; -} - -void PlayListItem::setLength(qint64 length) -{ - m_length = length; - MetaDataFormatter f; - m_formattedLength = f.formatLength(m_length); -} - -const QString PlayListItem::url() const -{ - return value(Qmmp::URL); -} - -void PlayListItem::readMetadata() -{ - MetaDataFormatter f(QmmpUiSettings::instance()->format()); - m_formattedTitle = f.parse(this); - if (m_formattedTitle.isEmpty()) - m_formattedTitle = value(Qmmp::URL).section('/',-1); - if (m_info) - delete m_info; - m_info = 0; - if (QmmpUiSettings::instance()->convertUnderscore()) - m_formattedTitle.replace("_", " "); - if (QmmpUiSettings::instance()->convertTwenty()) - m_formattedTitle.replace("%20", " "); -} diff --git a/src/qmmpui/playlistitem.h b/src/qmmpui/playlistitem.h index ab8b4170d..301442e14 100644 --- a/src/qmmpui/playlistitem.h +++ b/src/qmmpui/playlistitem.h @@ -24,42 +24,22 @@ #include <qmmp/fileinfo.h> #include <qmmp/qmmp.h> + /** @brief The PlayListItem class provides an item for use with the PlayListModel class. * @author Ilya Kotov <forkotov02@hotmail.ru> */ -class PlayListItem : public QMap <Qmmp::MetaData, QString> +class PlayListItem { public: - /*! - * Current state of playlist item. - * FREE - instance is free and may be deleted - * EDITING - instance is currently busy in some kind of operation(tags editing etc.) - * and can't be deleted at the moment. Set flag SCHEDULED_FOR_DELETION for it - * instead of delete operator call. - */ - enum FLAGS - { - FREE = 0, /*!< instance is free and may be deleted */ - EDITING, /*!< instance is currently busy */ - SCHEDULED_FOR_DELETION /*!< instance is sheduled for deletion */ - }; + /*! * Constructs an empty plalist item. */ PlayListItem(); /*! - * Constructs a new PlayListItem that is a copy of the given \b item - */ - PlayListItem(const PlayListItem &item); - /*! - * Constructs plalist item with given metadata. - * @param info Media file information. - */ - PlayListItem(FileInfo *info); - /*! * Object destructor. */ - ~PlayListItem(); + virtual ~PlayListItem(); /*! * Sets item selection flag to \b select * @param select State of selection (\b true select, \b false unselect) @@ -70,58 +50,18 @@ public: */ bool isSelected() const; /*! - * Returns current state of the playlist item. - */ - FLAGS flag() const; - /*! - * Sets state of the playlist item. - */ - void setFlag(FLAGS); - /*! * Returns formatted title of the item. */ - const QString formattedTitle(); + virtual const QString formattedTitle() const = 0; /*! * Returns formatted length of the item. */ - const QString formattedLength() const; - /*! - * Direct access to the item short title. - * @param title New short title. - */ - void setText(const QString &title); - /*! - * Returns song length in seconds. - */ - qint64 length() const; - /*! - * Sets length in seconds. - */ - void setLength(qint64 length); - /*! - * Same as url() - */ - const QString url() const; - /*! - * Updates current metadata. - * @param metaData Map with metadata values. - */ - void updateMetaData(const QMap <Qmmp::MetaData, QString> &metaData); - /*! - * Gets new metadata from file (works for local files only). - */ - void updateTags(); + virtual const QString formattedLength() const = 0; - const QString groupName() const; + virtual bool isGroup() const = 0; private: - void readMetadata(); - QString m_formattedTitle; - QString m_formattedLength; - FileInfo *m_info; bool m_selected; - FLAGS m_flag; - qint64 m_length; }; #endif diff --git a/src/qmmpui/playlistmanager.cpp b/src/qmmpui/playlistmanager.cpp index 6e3f73c3b..64ee23261 100644 --- a/src/qmmpui/playlistmanager.cpp +++ b/src/qmmpui/playlistmanager.cpp @@ -279,7 +279,7 @@ void PlayListManager::readPlayLists() { QString line, param, value; int s = 0, row = 0, pl = 0; - QList <PlayListItem *> items; + QList <PlayListTrack *> items; QFile file(QDir::homePath() +"/.qmmp/playlist.txt"); file.open(QIODevice::ReadOnly); QByteArray array = file.readAll(); @@ -287,7 +287,7 @@ void PlayListManager::readPlayLists() QBuffer buffer(&array); buffer.open(QIODevice::ReadOnly); - while (!buffer.atEnd()) + /*while (!buffer.atEnd()) { line = QString::fromUtf8(buffer.readLine()).trimmed(); if ((s = line.indexOf("=")) < 0) @@ -316,7 +316,7 @@ void PlayListManager::readPlayLists() } else if (param == "file") { - items << new PlayListItem(); + items << new PlayListTrack(); items.last()->insert(Qmmp::URL, value); } else if (items.isEmpty()) @@ -341,12 +341,12 @@ void PlayListManager::readPlayLists() items.last()->insert(Qmmp::DISCNUMBER, value); else if (param == "length") items.last()->setLength(value.toInt()); - } + }*/ buffer.close(); if(!m_models.isEmpty()) { - m_models.last()->add(items); - m_models.last()->setCurrent(row); + //m_models.last()->add(items); + //m_models.last()->setCurrent(row); } else m_models << new PlayListModel(tr("Playlist"),this); @@ -360,7 +360,7 @@ void PlayListManager::readPlayLists() void PlayListManager::writePlayLists() { - qDebug("PlayListManager: saving playlists..."); + /*qDebug("PlayListManager: saving playlists..."); QFile file(QDir::homePath() +"/.qmmp/playlist.txt"); if(!file.open(QIODevice::WriteOnly)) { @@ -370,10 +370,10 @@ void PlayListManager::writePlayLists() file.write(QString("current_playlist=%1\n").arg(m_models.indexOf(m_current)).toUtf8()); foreach(PlayListModel *model, m_models) { - QList<PlayListItem *> items = model->items(); + QList<PlayListTrack *> items = model->items(); file.write(QString("playlist=%1\n").arg(model->name()).toUtf8()); file.write(QString("current=%1\n").arg(model->currentIndex()).toUtf8()); - foreach(PlayListItem* m, items) + foreach(PlayListTrack* m, items) { file.write(QString("file=%1\n").arg(m->url()).toUtf8()); file.write(QString("title=%1\n").arg(m->value(Qmmp::TITLE)).toUtf8()); @@ -388,7 +388,7 @@ void PlayListManager::writePlayLists() file.write(QString("length=%1\n").arg(m->length()).toUtf8()); } } - file.close(); + file.close();*/ } void PlayListManager::clear() @@ -413,10 +413,10 @@ void PlayListManager::removeUnselected() void PlayListManager::removeAt (int i) { - m_selected->removeAt(i); + m_selected->removeTrack(i); } -void PlayListManager::removeItem (PlayListItem *item) +void PlayListManager::removeItem (PlayListTrack *item) { m_selected->removeItem(item); } diff --git a/src/qmmpui/playlistmanager.h b/src/qmmpui/playlistmanager.h index 14de512ea..e74e817ee 100644 --- a/src/qmmpui/playlistmanager.h +++ b/src/qmmpui/playlistmanager.h @@ -209,7 +209,7 @@ public slots: /*! * This is a convenience function and is the same as calling \b selectedPlayList()->removeItem(item) */ - void removeItem (PlayListItem *item); + void removeItem (PlayListTrack *item); /*! * This is a convenience function and is the same as calling \b selectedPlayList()->invertSelection() */ diff --git a/src/qmmpui/playlistmodel.cpp b/src/qmmpui/playlistmodel.cpp index da036316d..507bf6252 100644 --- a/src/qmmpui/playlistmodel.cpp +++ b/src/qmmpui/playlistmodel.cpp @@ -50,11 +50,11 @@ PlayListModel::PlayListModel(const QString &name, QObject *parent) m_total_length = 0; m_current = 0; m_is_repeatable_list = false; - m_stop_item = 0; + m_stop_track = 0; m_play_state = new NormalPlayState(this); m_loader = new FileLoader(this); - connect(m_loader, SIGNAL(newPlayListItem(PlayListItem*)), - SLOT(add(PlayListItem*)), Qt::QueuedConnection); + connect(m_loader, SIGNAL(newPlayListTrack(PlayListTrack*)), + SLOT(add(PlayListTrack*)), Qt::QueuedConnection); connect(m_loader, SIGNAL(finished()), SLOT(preparePlayState())); connect(m_loader, SIGNAL(finished()), SIGNAL(loaderFinished())); } @@ -81,33 +81,36 @@ void PlayListModel::setName(const QString &name) } } -void PlayListModel::add(PlayListItem *item) +void PlayListModel::add(PlayListTrack *track) { - if (m_items.isEmpty()) - m_currentItem = item; - - m_total_length += item->length(); - m_items << item; - m_current = m_items.indexOf(m_currentItem); + if (m_container.isEmpty()) + { + m_current_track = track; + m_current = 1; //0 + } + m_container.addTrack(track); + m_total_length += track->length(); - emit itemAdded(item); + emit itemAdded(track); emit listChanged(); emit countChanged(); } -void PlayListModel::add(QList <PlayListItem *> items) +void PlayListModel::add(QList<PlayListTrack *> tracks) { - if(items.isEmpty()) + if(tracks.isEmpty()) return; - if (m_items.isEmpty()) - m_currentItem = items.at(0); + if (m_container.isEmpty()) + { + m_current_track = tracks.at(0); + m_current = 1; //0 + } - m_items << items; - m_current = m_items.indexOf(m_currentItem); - foreach(PlayListItem *item, items) + foreach(PlayListTrack *track, tracks) { - m_total_length += item->length(); - emit itemAdded(item); + m_container.addTrack(track); + m_total_length += track->length(); + emit itemAdded(track); } emit listChanged(); emit countChanged(); @@ -134,41 +137,51 @@ void PlayListModel::add(const QStringList &paths) } } -int PlayListModel::count() +int PlayListModel::count() const { - return m_items.size(); + return m_container.count(); } -PlayListItem* PlayListModel::currentItem() +int PlayListModel::trackCount() const { - return m_items.isEmpty() ? 0 : m_items.at(qMin(m_items.size() - 1, m_current)); + return m_container.trackCount(); } -PlayListItem* PlayListModel::nextItem() +PlayListTrack* PlayListModel::currentTrack() const { - if(m_items.isEmpty() || !m_play_state) + return m_container.isEmpty() ? 0 : m_current_track; +} + +PlayListTrack *PlayListModel::nextTrack() const +{ + if(m_container.isEmpty() || !m_play_state) return 0; - if(m_stop_item && m_stop_item == currentItem()) + if(m_stop_track && m_stop_track == currentTrack()) return 0; if(!isEmptyQueue()) return m_queued_songs.at(0); int index = m_play_state->nextIndex(); - if(index < 0 || (index + 1 > m_items.count())) + if(index < 0 || (index + 1 > m_container.count())) return 0; - return m_items.at(index); + return m_container.track(index); } int PlayListModel::indexOf(PlayListItem* item) const { - return m_items.indexOf(item); + return m_container.indexOf(item); } PlayListItem* PlayListModel::item(int index) const { - return (index < m_items.size() && index >= 0) ? m_items.at(index) : 0; + return m_container.item(index); } -int PlayListModel::currentIndex() +PlayListTrack* PlayListModel::track(int index) const +{ + return m_container.track(index); +} + +int PlayListModel::currentIndex() const { return m_current; } @@ -177,25 +190,28 @@ bool PlayListModel::setCurrent(int index) { if (index > count()-1 || index < 0) return false; + PlayListItem *item = m_container.item(index); + if(item->isGroup()) + return false; m_current = index; - m_currentItem = m_items.at(index); + m_current_track = dynamic_cast<PlayListTrack*> (item); emit currentChanged(); emit listChanged(); return true; } -bool PlayListModel::setCurrent(PlayListItem *item) +bool PlayListModel::setCurrent(PlayListTrack *track) { - if(!m_items.contains(item)) + if(!m_container.contains(track)) return false; - return setCurrent(m_items.indexOf(item)); + return setCurrent(m_container.indexOf(track)); } bool PlayListModel::next() { - if(m_stop_item == currentItem()) + if(m_stop_track == currentTrack()) { - m_stop_item = 0; + m_stop_track = 0; emit listChanged(); return false; } @@ -221,22 +237,9 @@ void PlayListModel::clear() { m_loader->finish(); m_current = 0; - m_stop_item = 0; - while (!m_items.isEmpty()) - { - PlayListItem* mf = m_items.takeFirst(); - - if (mf->flag() == PlayListItem::FREE) - { - delete mf; - } - else if (mf->flag() == PlayListItem::EDITING) - { - mf->setFlag(PlayListItem::SCHEDULED_FOR_DELETION); - } - } + m_stop_track = 0; + m_container.clear(); m_queued_songs.clear(); - m_total_length = 0; m_play_state->resetState(); emit listChanged(); @@ -245,41 +248,39 @@ void PlayListModel::clear() void PlayListModel::clearSelection() { - for (int i = 0; i<m_items.size(); ++i) - m_items.at(i)->setSelected(false); + m_container.clearSelection(); emit listChanged(); } -QList<PlayListItem *> PlayListModel::mid(int pos, int count) +QList<PlayListItem *> PlayListModel::mid(int pos, int count) const { - return m_items.mid(pos, count); + return m_container.mid(pos, count); } -bool PlayListModel::isSelected(int index) +bool PlayListModel::isSelected(int index) const { - if (m_items.count() > index && index >= 0) - return m_items.at(index)->isSelected(); - - return false; + return m_container.isSelected(index); } bool PlayListModel::contains(const QString &url) { - foreach (PlayListItem *item, m_items) + /*foreach (PlayListItem *item, m_items) { if(item->url() == url) return true; - } + }*/ return false; } +int PlayListModel::numberOfTrack(int index) const +{ + return m_container.numberOfTrack(index); +} + void PlayListModel::setSelected(int index, bool selected) { - if (m_items.count() > index && index >= 0) - { - m_items.at(index)->setSelected(selected); - emit listChanged(); - } + m_container.setSelected(index, selected); + emit listChanged(); } void PlayListModel::removeSelected() @@ -292,31 +293,37 @@ void PlayListModel::removeUnselected() removeSelection(true); } -void PlayListModel::removeAt (int i) +void PlayListModel::removeTrack (int i) { if ((i < count()) && (i >= 0)) { - PlayListItem* item = m_items.takeAt(i); - m_queued_songs.removeAll(item); - if(m_stop_item == item) - m_stop_item = 0; - m_total_length -= item->length(); + PlayListTrack* track = m_container.track(i); + if(!track) + return; + m_queued_songs.removeAll(track); + if(m_stop_track == track) + m_stop_track = 0; + m_total_length -= track->length(); if (m_total_length < 0) m_total_length = qMin(0, m_total_length); - if (item->flag() == PlayListItem::FREE) + m_container.removeTrack(i); + + if(m_container.isEmpty()) { - delete item; - item = NULL; + m_current = 0; + m_current_track = 0; } - else if (item->flag() == PlayListItem::EDITING) - item->setFlag(PlayListItem::SCHEDULED_FOR_DELETION); + else + { + if (m_current >= i && m_current > 0) + m_current--; - if (m_current >= i && m_current != 0) - m_current--; + if(m_current > 0 && m_container.item(m_current)->isGroup()) + m_current--; - if (!m_items.isEmpty()) - m_currentItem = m_items.at(m_current); + m_current_track = m_container.track(m_current); + } m_play_state->prepare(); emit listChanged(); @@ -326,8 +333,8 @@ void PlayListModel::removeAt (int i) void PlayListModel::removeItem (PlayListItem *item) { - if(m_items.contains(item)) - removeAt (m_items.indexOf(item)); + /*if(m_items.contains(item)) + removeAt (m_items.indexOf(item));*/ } void PlayListModel::removeSelection(bool inverted) @@ -336,43 +343,58 @@ void PlayListModel::removeSelection(bool inverted) int select_after_delete = -1; - while (!m_items.isEmpty() && i<m_items.size()) + while (!m_container.isEmpty() && i < m_container.count()) { - if (m_items.at(i)->isSelected() ^ inverted) + PlayListItem *item = m_container.item(i); + if (!item->isGroup() && item->isSelected() ^ inverted) { - PlayListItem* item = m_items.takeAt(i); - m_queued_songs.removeAll(item); - if(item == m_stop_item) - m_stop_item = 0; - m_total_length -= item->length(); + PlayListTrack *track = dynamic_cast<PlayListTrack *> (item); + m_container.removeTrack(track); + m_queued_songs.removeAll(track); + if(track == m_stop_track) + m_stop_track = 0; + m_total_length -= track->length(); if (m_total_length < 0) m_total_length = 0; - if (item->flag() == PlayListItem::FREE) + if (track->flag() == PlayListTrack::FREE) { - delete item; - item = NULL; + delete track; + track = NULL; } - else if (item->flag() == PlayListItem::EDITING) - item->setFlag(PlayListItem::SCHEDULED_FOR_DELETION); + else if (track->flag() == PlayListTrack::EDITING) + track->setFlag(PlayListTrack::SCHEDULED_FOR_DELETION); select_after_delete = i; - if (m_current >= i && m_current!=0) - m_current--; + if (m_current >= i && m_current > 0) + { + if(m_current != 1 || !m_container.item(0)->isGroup()) + { + if(!m_container.item(m_current-1)->isGroup()) + m_current--; + else + m_current-=2; + } + } } else i++; } - if (!m_items.isEmpty()) - m_currentItem = m_items.at(m_current); + if (!m_container.isEmpty()) + { + m_current_track = m_container.track(m_current); + } + else + m_current_track = 0; + - if (select_after_delete >= m_items.count()) - select_after_delete = m_items.count() - 1; + if (select_after_delete >= m_container.count()) + select_after_delete = m_container.count() - 1; if(select_after_delete != -1) - m_items.at(select_after_delete)->setSelected(true); + m_container.setSelected(select_after_delete, true); m_play_state->prepare(); @@ -382,27 +404,26 @@ void PlayListModel::removeSelection(bool inverted) void PlayListModel::invertSelection() { - for (int i = 0; i<m_items.size(); ++i) - m_items.at(i)->setSelected(!m_items.at(i)->isSelected()); + for (int i = 0; i < m_container.count(); ++i) + m_container.setSelected(i, !m_container.isSelected(i)); emit listChanged(); } void PlayListModel::selectAll() { - for (int i = 0; i<m_items.size(); ++i) - m_items.at(i)->setSelected(true); + for (int i = 0; i < m_container.count(); ++i) + m_container.setSelected(i, true); emit listChanged(); } void PlayListModel::showDetails(QWidget *parent) { - for (int i = 0; i<m_items.size(); ++i) + for (int i = 0; i < m_container.count(); ++i) { - if (m_items.at(i)->isSelected()) + if (m_container.isSelected(i) && m_container.track(i)) { - QDialog *d = new DetailsDialog(m_items.at(i), parent); - TagUpdater *updater = new TagUpdater(d, m_items.at(i)); - m_editing_items.append(m_items.at(i)); + QDialog *d = new DetailsDialog(m_container.track(i), parent); + TagUpdater *updater = new TagUpdater(d, m_container.track(i)); connect(updater, SIGNAL(destroyed(QObject *)),SIGNAL(listChanged())); d->show(); return; @@ -438,7 +459,7 @@ int PlayListModel::totalLength() const void PlayListModel::moveItems(int from, int to) { // Get rid of useless work - if (from == to) + /*if (from == to) return; QList<int> selected_rows = selectedIndexes(); @@ -464,7 +485,7 @@ void PlayListModel::moveItems(int from, int to) m_current = m_items.indexOf(m_currentItem); emit listChanged(); - } + }*/ } int PlayListModel::topmostInSelection(int row) @@ -484,10 +505,10 @@ int PlayListModel::topmostInSelection(int row) int PlayListModel::bottommostInSelection(int row) { - if (row >= m_items.count() - 1) + if (row >= count() - 1) return row; - for (int i = row + 1;i < count() ;i++) + for (int i = row + 1; i < count(); i++) { if (isSelected(i)) continue; @@ -508,10 +529,10 @@ const SimpleSelection& PlayListModel::getSelection(int row) QList<int> PlayListModel::selectedIndexes() const { - QList<int>selected_rows; - for (int i = 0;i<m_items.count();i++) + QList<int> selected_rows; + for (int i = 0; i < m_container.count(); i++) { - if (m_items[i]->isSelected()) + if (m_container.item(i)->isSelected()) { selected_rows.append(i); } @@ -519,31 +540,31 @@ QList<int> PlayListModel::selectedIndexes() const return selected_rows; } -QList< PlayListItem * > PlayListModel::selectedItems() const +QList<PlayListTrack *> PlayListModel::selectedTracks() { - QList<PlayListItem*> selected_items; - foreach(PlayListItem *item, m_items) + QList<PlayListTrack*> selected_tracks; + foreach(PlayListItem *item, m_container.items()) { - if(item->isSelected()) - selected_items.append(item); + if(!item->isGroup() && item->isSelected()) + selected_tracks.append(dynamic_cast<PlayListTrack *>(item)); } - return selected_items; + return selected_tracks; } QList<PlayListItem *> PlayListModel::items() const { - return m_items; + return m_container.items(); } void PlayListModel::addToQueue() { - QList<PlayListItem*> selected_items = selectedItems(); - foreach(PlayListItem* file,selected_items) - setQueued(file); + QList<PlayListTrack*> selected_tracks = selectedTracks(); + foreach(PlayListTrack* track, selected_tracks) + setQueued(track); emit listChanged(); } -void PlayListModel::setQueued(PlayListItem* item) +void PlayListModel::setQueued(PlayListTrack *item) { if (isQueued(item)) m_queued_songs.removeAll(item); @@ -552,7 +573,7 @@ void PlayListModel::setQueued(PlayListItem* item) emit listChanged(); } -bool PlayListModel::isQueued(PlayListItem* f) const +bool PlayListModel::isQueued(PlayListTrack *f) const { return m_queued_songs.contains(f); } @@ -567,9 +588,9 @@ bool PlayListModel::isEmptyQueue() const return m_queued_songs.isEmpty(); } -int PlayListModel::queuedIndex(PlayListItem* item) const +int PlayListModel::queuedIndex(PlayListTrack *track) const { - return m_queued_songs.indexOf(item); + return m_queued_songs.indexOf(track); } int PlayListModel::queueSize() const @@ -579,27 +600,27 @@ int PlayListModel::queueSize() const bool PlayListModel::isStopAfter(PlayListItem* item) const { - return m_stop_item == item; + return m_stop_track == item; } void PlayListModel::randomizeList() { - for (int i = 0;i < m_items.size();i++) + /*for (int i = 0;i < m_items.size();i++) m_items.swap(qrand()%m_items.size(),qrand()%m_items.size()); m_current = m_items.indexOf(m_currentItem); - emit listChanged(); + emit listChanged();*/ } void PlayListModel::reverseList() { - for (int i = 0;i < m_items.size()/2;i++) + /*for (int i = 0;i < m_items.size()/2;i++) m_items.swap(i,m_items.size() - i - 1); m_current = m_items.indexOf(m_currentItem); - emit listChanged(); + emit listChanged();*/ } - +/* ////===============THE BEGINNING OF SORT IMPLEMENTATION =======================//// // First we'll implement bundle of static compare procedures @@ -709,11 +730,11 @@ static bool _fileModificationDateLessComparator(PlayListItem* s1,PlayListItem* s static bool _fileModificationDateGreaterComparator(PlayListItem* s1,PlayListItem* s2) { return QFileInfo(s1->value(Qmmp::URL)).lastModified() > QFileInfo(s2->value(Qmmp::URL)).lastModified(); -} +}*/ // This is main sort method void PlayListModel::doSort(int sort_mode,QList<PlayListItem*>& list_to_sort) { - QList<PlayListItem*>::iterator begin; + /* QList<PlayListItem*>::iterator begin; QList<PlayListItem*>::iterator end; begin = list_to_sort.begin(); @@ -782,12 +803,12 @@ void PlayListModel::doSort(int sort_mode,QList<PlayListItem*>& list_to_sort) sorted_asc = false; } - m_current = m_items.indexOf(m_currentItem); + m_current = m_items.indexOf(m_currentItem);*/ } void PlayListModel::sortSelection(int mode) { - QList<PlayListItem*>selected_items = selectedItems(); + /*QList<PlayListItem*>selected_items = selectedItems(); QList<int>selected_rows = selectedIndexes(); doSort(mode,selected_items); @@ -796,13 +817,13 @@ void PlayListModel::sortSelection(int mode) m_items.replace(selected_rows[i],selected_items[i]); m_current = m_items.indexOf(m_currentItem); - emit listChanged(); + emit listChanged();*/ } void PlayListModel::sort(int mode) { - doSort(mode,m_items); - emit listChanged(); + /*doSort(mode,m_items); + emit listChanged();*/ } ////=============== THE END OF SORT IMPLEMENTATION =======================//// @@ -864,7 +885,7 @@ void PlayListModel::loadPlaylist(const QString &f_name) void PlayListModel::savePlaylist(const QString & f_name) { - PlayListFormat* prs = PlayListParser::findByPath(f_name); + /*PlayListFormat* prs = PlayListParser::findByPath(f_name); if (prs) { QFile file(f_name); @@ -879,7 +900,7 @@ void PlayListModel::savePlaylist(const QString & f_name) } else qWarning("Error opening %s",f_name.toLocal8Bit().data()); - } + }*/ } bool PlayListModel::isRepeatableList() const @@ -904,7 +925,7 @@ void PlayListModel::preparePlayState() void PlayListModel::removeInvalidItems() { - foreach(PlayListItem *item, m_items) + /*foreach(PlayListItem *item, m_items) { bool ok = false; if(!item->url().contains("://")) @@ -913,12 +934,12 @@ void PlayListModel::removeInvalidItems() ok = MetaDataManager::instance()->protocols().contains(item->url().section("://",0,0)); if(!ok) removeItem(item); - } + }*/ } void PlayListModel::removeDuplicates() { - for(int i = 0; i < m_items.size(); ++i) + /*for(int i = 0; i < m_items.size(); ++i) { int j = m_items.size() - 1; while(j > i) @@ -927,31 +948,31 @@ void PlayListModel::removeDuplicates() removeItem(m_items.at(j)); j--; } - } + }*/ } void PlayListModel::clearQueue() { m_queued_songs.clear(); - m_stop_item = 0; + m_stop_track = 0; emit listChanged(); } void PlayListModel::stopAfterSelected() { - QList<PlayListItem*> selected_items = selectedItems(); + QList<PlayListTrack*> selected_tracks = selectedTracks(); if(!m_queued_songs.isEmpty()) { - m_stop_item = m_stop_item != m_queued_songs.last() ? m_queued_songs.last() : 0; + m_stop_track = m_stop_track != m_queued_songs.last() ? m_queued_songs.last() : 0; } - else if(selected_items.count() == 1) + else if(selected_tracks.count() == 1) { - m_stop_item = m_stop_item != selected_items.at(0) ? selected_items.at(0) : 0; + m_stop_track = m_stop_track != selected_tracks.at(0) ? selected_tracks.at(0) : 0; } - else if(selected_items.count() > 1) + else if(selected_tracks.count() > 1) { addToQueue(); - m_stop_item = m_queued_songs.last(); + m_stop_track = m_queued_songs.last(); } else return; diff --git a/src/qmmpui/playlistmodel.h b/src/qmmpui/playlistmodel.h index 33bff51cb..9689e505b 100644 --- a/src/qmmpui/playlistmodel.h +++ b/src/qmmpui/playlistmodel.h @@ -29,8 +29,10 @@ #include <QVector> #include "playlistitem.h" + +#include "playlistcontainer.h" + class FileLoader; -class PlayListItem; class PlayState; class PlayListFormat; class PlayListModel; @@ -104,15 +106,18 @@ public: /*! * Returns number of items. */ - int count(); + int count() const; + + int trackCount() const; + /*! * Returns the current item. */ - PlayListItem* currentItem(); + PlayListTrack* currentTrack() const; /*! * Returns the next playing item or 0 if next item is unknown. */ - PlayListItem* nextItem(); + PlayListTrack* nextTrack() const; /*! * Returns the row of the \b item */ @@ -121,10 +126,11 @@ public: * Returns the item with the index \b index or 0 if item doesn't exist. */ PlayListItem* item(int index) const; + PlayListTrack* track(int index) const; /*! * Returns index of the current item. */ - int currentIndex(); + int currentIndex() const; /*! * Sets current index. * Returns \b false if item with this index doesn't exist, otherwise returns \b true @@ -135,11 +141,11 @@ public: * Sets current item to \b item. * Returns \b true if success, otherwise returns \b false */ - bool setCurrent(PlayListItem *item); + bool setCurrent(PlayListTrack *item); /*! * Returns \b true if item with \b index is selected, otherwise returns \b false */ - bool isSelected(int index); + bool isSelected(int index) const; /*! * Sets the selected state of the item to \b select * @param index Number of item. @@ -161,7 +167,7 @@ public: * \param pos First item position. * \param count A number of items. If \b count is -1 (the default), all items from pos are returned. */ - QList<PlayListItem *> mid(int pos, int count = -1); + QList<PlayListItem *> mid(int pos, int count = -1) const; /*! * Moves the item at index position \b from to index position \b to. */ @@ -169,7 +175,7 @@ public: /*! * Returns \b true if \b f file is in play queue, otherwise returns \b false. */ - bool isQueued(PlayListItem* item) const; + bool isQueued(PlayListTrack* item) const; /*! * Sets current song to the file that is nex in queue, if queue is empty - does nothing */ @@ -181,7 +187,7 @@ public: /*! * Returns index of \b f file in queue.e */ - int queuedIndex(PlayListItem* item) const; + int queuedIndex(PlayListTrack* track) const; /*! * Returns the number of items in the queue */ @@ -202,7 +208,7 @@ public: /*! * Returns list of \b PlayListItem pointers that are selected. */ - QList<PlayListItem*> selectedItems() const; + QList<PlayListTrack *> selectedTracks(); /*! * Returns list of all \b PlayListItem pointers. */ @@ -260,6 +266,8 @@ public: FILE_MODIFICATION_DATE /*!< by file modification date */ }; + int numberOfTrack(int index) const; + signals: /*! * Emitted when the state of PlayListModel has changed. @@ -292,12 +300,12 @@ public slots: /*! * Adds \b item to the playlist. */ - void add(PlayListItem *item); + void add(PlayListTrack *item); /*! * Adds a list of items to the playlist. * @param items List of items. */ - void add(QList <PlayListItem *> items); + void add(QList <PlayListTrack *> tracks); /*! * Adds a list of files and directories to the playlist * @param path Full path of file or directory. @@ -327,7 +335,7 @@ public slots: /*! * Removes items with \b i index. */ - void removeAt (int i); + void removeTrack (int i); /*! * Removes item \b item from playlist */ @@ -380,7 +388,7 @@ public slots: /*! * Adds/removes item \b f to/from playback queue. */ - void setQueued(PlayListItem* item); + void setQueued(PlayListTrack* item); /*! * Removes invalid items from playlist */ @@ -421,19 +429,18 @@ private slots: void preparePlayState(); private: - QList <PlayListItem*> m_items; - QList <PlayListItem*> m_editing_items; - PlayListItem* m_currentItem; - PlayListItem* m_stop_item; + PlayListTrack* m_current_track; + PlayListTrack* m_stop_track; int m_current; SimpleSelection m_selection; /*!< This flyweight object represents current selection. */ - QQueue <PlayListItem*> m_queued_songs; /*!< Songs in play queue. */ + QQueue <PlayListTrack*> m_queued_songs; /*!< Songs in play queue. */ bool m_is_repeatable_list; /*!< Is playlist repeatable? */ PlayState* m_play_state; /*!< Current playing state (Normal or Shuffle) */ int m_total_length; FileLoader *m_loader; bool m_shuffle; QString m_name; + PlayListContainer m_container; }; #endif diff --git a/src/qmmpui/playlisttrack.cpp b/src/qmmpui/playlisttrack.cpp new file mode 100644 index 000000000..ad84b53b4 --- /dev/null +++ b/src/qmmpui/playlisttrack.cpp @@ -0,0 +1,154 @@ +/*************************************************************************** + * Copyright (C) 2008-2013 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include <qmmp/metadatamanager.h> +#include "metadataformatter.h" +#include "qmmpuisettings.h" +#include "playlisttrack.h" + +PlayListTrack::PlayListTrack() : QMap<Qmmp::MetaData, QString>(), PlayListItem(), m_flag(FREE) +{ + m_info = 0; + m_length = 0; +} + +PlayListTrack::PlayListTrack(const PlayListTrack &other) : QMap<Qmmp::MetaData, QString>(other), + PlayListItem(),m_flag(FREE) +{ + m_formattedTitle = other.m_formattedTitle; + if (other.m_info) + m_info = new FileInfo(*(other.m_info)); + else + m_info = 0; + setSelected(other.isSelected()); + setFlag(other.flag()); + m_length = other.m_length; + m_formattedLength = other.m_formattedLength; +} + +PlayListTrack::PlayListTrack(FileInfo *info) : QMap<Qmmp::MetaData, QString>(info->metaData()), + PlayListItem(), m_flag(FREE) +{ + setLength(m_length = info->length()); + m_info = info; + insert(Qmmp::URL, m_info->path()); + readMetadata(); +} + +PlayListTrack::~PlayListTrack() +{ + if (m_info) + delete m_info; +} + +void PlayListTrack::updateMetaData(const QMap <Qmmp::MetaData, QString> &metaData) +{ + QMap <Qmmp::MetaData, QString>::operator =(metaData); + readMetadata(); +} + +void PlayListTrack::updateTags() +{ + if (m_info) + { + delete m_info; + m_info = 0; + } + QList <FileInfo *> list = MetaDataManager::instance()->createPlayList(value(Qmmp::URL)); + if(!list.isEmpty() && !list.at(0)->path().contains("://")) + { + m_info = list.at(0); + m_length = m_info->length(); + QMap <Qmmp::MetaData, QString>::operator =(m_info->metaData()); + insert(Qmmp::URL, m_info->path()); + readMetadata(); + } + while(list.size() > 1) + delete list.takeLast(); +} + +const QString PlayListTrack::groupName() const +{ + MetaDataFormatter f("%p - %a"); + return f.parse(this); +} + +bool PlayListTrack::isGroup() const +{ + return false; +} + +const QString PlayListTrack::formattedTitle() const +{ + /*if(m_formattedTitle.isEmpty()) + readMetadata();*/ + return m_formattedTitle; +} + +const QString PlayListTrack::formattedLength() const +{ + return m_formattedLength; +} + +void PlayListTrack::setText(const QString &title) +{ + m_formattedTitle = title; +} + +qint64 PlayListTrack::length() const +{ + return m_length; +} + +void PlayListTrack::setLength(qint64 length) +{ + m_length = length; + MetaDataFormatter f; + m_formattedLength = f.formatLength(m_length); +} + +const QString PlayListTrack::url() const +{ + return value(Qmmp::URL); +} + +void PlayListTrack::setFlag(FLAGS f) +{ + m_flag = f; +} + +PlayListTrack::FLAGS PlayListTrack::flag() const +{ + return m_flag; +} + +void PlayListTrack::readMetadata() +{ + MetaDataFormatter f(QmmpUiSettings::instance()->format()); + m_formattedTitle = f.parse(this); + if (m_formattedTitle.isEmpty()) + m_formattedTitle = value(Qmmp::URL).section('/',-1); + if (m_info) + delete m_info; + m_info = 0; + if (QmmpUiSettings::instance()->convertUnderscore()) + m_formattedTitle.replace("_", " "); + if (QmmpUiSettings::instance()->convertTwenty()) + m_formattedTitle.replace("%20", " "); +} diff --git a/src/qmmpui/playlisttrack.h b/src/qmmpui/playlisttrack.h new file mode 100644 index 000000000..1e6948bbd --- /dev/null +++ b/src/qmmpui/playlisttrack.h @@ -0,0 +1,126 @@ +/*************************************************************************** + * Copyright (C) 2013 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., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef PLAYLISTTRACK_H +#define PLAYLISTTRACK_H + +#include <QMap> +#include <qmmp/fileinfo.h> +#include <qmmp/qmmp.h> +#include "playlistitem.h" + + +//PlayListItem +//PlayListTrack +//PlayListGroup + +/** @brief The PlayListTrack class provides an item for use with the PlayListModel class. + * @author Ilya Kotov <forkotov02@hotmail.ru> + */ +class PlayListTrack : public QMap <Qmmp::MetaData, QString>, public PlayListItem +{ +public: + /*! + * Current state of playlist item. + * FREE - instance is free and may be deleted + * EDITING - instance is currently busy in some kind of operation(tags editing etc.) + * and can't be deleted at the moment. Set flag SCHEDULED_FOR_DELETION for it + * instead of delete operator call. + */ + enum FLAGS + { + FREE = 0, /*!< instance is free and may be deleted */ + EDITING, /*!< instance is currently busy */ + SCHEDULED_FOR_DELETION /*!< instance is sheduled for deletion */ + }; + /*! + * Constructs an empty plalist item. + */ + PlayListTrack(); + /*! + * Constructs a new PlayListTrack that is a copy of the given \b item + */ + PlayListTrack(const PlayListTrack &item); + /*! + * Constructs plalist item with given metadata. + * @param info Media file information. + */ + PlayListTrack(FileInfo *info); + /*! + * Object destructor. + */ + ~PlayListTrack(); + /*! + * Returns formatted title of the item. + */ + const QString formattedTitle() const; + /*! + * Returns formatted length of the item. + */ + const QString formattedLength() const; + /*! + * Direct access to the item short title. + * @param title New short title. + */ + void setText(const QString &title); + /*! + * Returns song length in seconds. + */ + qint64 length() const; + /*! + * Sets length in seconds. + */ + void setLength(qint64 length); + /*! + * Same as url() + */ + const QString url() const; + /*! + * Updates current metadata. + * @param metaData Map with metadata values. + */ + void updateMetaData(const QMap <Qmmp::MetaData, QString> &metaData); + /*! + * Gets new metadata from file (works for local files only). + */ + void updateTags(); + + const QString groupName() const; + + bool isGroup() const; + + /*! + * Returns current state of the playlist item. + */ + FLAGS flag() const; + /*! + * Sets state of the playlist item. + */ + void setFlag(FLAGS); + +private: + void readMetadata(); + QString m_formattedTitle; + QString m_formattedLength; + FileInfo *m_info; + qint64 m_length; + FLAGS m_flag; +}; + +#endif diff --git a/src/qmmpui/playstate.cpp b/src/qmmpui/playstate.cpp index e9d4c7aeb..6676bc074 100644 --- a/src/qmmpui/playstate.cpp +++ b/src/qmmpui/playstate.cpp @@ -113,56 +113,75 @@ void ShufflePlayState::resetState() NormalPlayState::NormalPlayState(PlayListModel * model) : PlayState(model) {} - bool NormalPlayState::next() { - int itm_count = m_model->items().count(); + int item_count = m_model->items().count(); - if (itm_count > 0) + if(!item_count) + return false; + + if (m_model->isRepeatableList() && m_model->currentIndex() == item_count - 1) { - if ( m_model->currentIndex() == itm_count - 1) - { - if (m_model->isRepeatableList()) - return m_model->setCurrent(0); - else - return false; - } - return m_model->setCurrent(m_model->currentIndex() + 1); + if(item_count >= 1 && m_model->track(0)) + return m_model->setCurrent(0); + else if(item_count >= 2 && m_model->track(1)) + return m_model->setCurrent(1); } - else + else if(m_model->track((m_model->currentIndex() + 1))) + return m_model->setCurrent(m_model->currentIndex() + 1); + else if(m_model->currentIndex() + 2 >= item_count) return false; + else if(m_model->track(m_model->currentIndex() + 2)) + return m_model->setCurrent(m_model->currentIndex() + 2); + return false; } bool NormalPlayState::previous() { - int itm_count = m_model->items().count(); + int item_count = m_model->items().count(); - if (itm_count > 0) + if(!item_count) + return false; + + if(m_model->isRepeatableList()) { - if ( m_model->currentIndex() < 1 && !m_model->isRepeatableList()) - return false; - else if (m_model->setCurrent(m_model->currentIndex() - 1)) - return true; - else if (m_model->isRepeatableList()) - return m_model->setCurrent(m_model->items().count() - 1); + if(m_model->currentIndex() == 1 && m_model->track(0)) + return m_model->setCurrent(0); + else if(m_model->currentIndex() == 1 && !m_model->track(0)) + return (m_model->setCurrent(m_model->currentIndex() - 1)); + else if(m_model->currentIndex() == 0) + return m_model->setCurrent(m_model->currentIndex() - 1); } + if(m_model->currentIndex() == 0) + return false; + else if(m_model->track(m_model->currentIndex() - 1)) + return m_model->setCurrent(m_model->currentIndex() - 1); + else if(m_model->currentIndex() >= 2 && m_model->track(m_model->currentIndex() - 2)) + return m_model->setCurrent(m_model->currentIndex() - 2); + return false; } int NormalPlayState::nextIndex() { - int itm_count = m_model->items().count(); - if(!itm_count) + int item_count = m_model->items().count(); + if(!item_count) return -1; - if (m_model->currentIndex() == itm_count - 1) + if (m_model->currentIndex() == item_count - 1) { if (m_model->isRepeatableList()) return 0; else return -1; } - return m_model->currentIndex() + 1; + if(m_model->track(m_model->currentIndex() + 1)) + return m_model->currentIndex() + 1; + else if(m_model->currentIndex() + 2 >= m_model->count()) + return -1; + else if(m_model->track(m_model->currentIndex() + 2)) + return m_model->currentIndex() + 2; + return -1; } diff --git a/src/qmmpui/qmmpui.pro b/src/qmmpui/qmmpui.pro index 2ceec6eea..dca536ff7 100644 --- a/src/qmmpui/qmmpui.pro +++ b/src/qmmpui/qmmpui.pro @@ -50,7 +50,10 @@ HEADERS += general.h \ playlistdownloader.h \ addurldialog_p.h \ qmmpuiplugincache_p.h \ - tagupdater_p.h + tagupdater_p.h \ + playlistgroup.h \ + playlistcontainer.h \ + playlisttrack.h SOURCES += general.cpp \ playlistparser.cpp \ commandlinemanager.cpp \ @@ -77,7 +80,10 @@ SOURCES += general.cpp \ playlistdownloader.cpp \ addurldialog.cpp \ qmmpuiplugincache.cpp \ - tagupdater.cpp + tagupdater.cpp \ + playlistgroup.cpp \ + playlistcontainer.cpp \ + playlisttrack.cpp FORMS += forms/detailsdialog.ui \ forms/tageditor.ui \ forms/templateeditor.ui \ diff --git a/src/qmmpui/qmmpuisettings.cpp b/src/qmmpui/qmmpuisettings.cpp index 221bf179d..33dab8fdf 100644 --- a/src/qmmpui/qmmpuisettings.cpp +++ b/src/qmmpui/qmmpuisettings.cpp @@ -81,18 +81,18 @@ void QmmpUiSettings::setConvertTwenty(bool yes) void QmmpUiSettings::setFormat(const QString &format) { - m_format = format; + /*m_format = format; if(format != m_format) { m_format = format; //emit settingsChanged(); foreach(PlayListModel *model, PlayListManager::instance()->playLists()) { - foreach(PlayListItem *item, model->items()) + foreach(PlayListTrack *item, model->items()) item->setText(QString()); model->doCurrentVisibleRequest(); } - } + }*/ } void QmmpUiSettings::setUseMetadata(bool yes) diff --git a/src/qmmpui/tagupdater.cpp b/src/qmmpui/tagupdater.cpp index 5d1d5bae9..261e16cc2 100644 --- a/src/qmmpui/tagupdater.cpp +++ b/src/qmmpui/tagupdater.cpp @@ -20,16 +20,16 @@ #include "tagupdater_p.h" -TagUpdater::TagUpdater(QObject* o, PlayListItem* item) : m_observable(o), m_item(item) +TagUpdater::TagUpdater(QObject* o, PlayListTrack* track) : m_observable(o), m_item(track) { - m_item->setFlag(PlayListItem::EDITING); + m_item->setFlag(PlayListTrack::EDITING); connect(m_observable, SIGNAL(destroyed(QObject *)),SLOT(updateTag())); connect(m_observable, SIGNAL(destroyed(QObject *)),SLOT(deleteLater())); } void TagUpdater::updateTag() { - if (m_item->flag() == PlayListItem::SCHEDULED_FOR_DELETION) + if (m_item->flag() == PlayListTrack::SCHEDULED_FOR_DELETION) { delete m_item; m_item = NULL; @@ -37,6 +37,6 @@ void TagUpdater::updateTag() else { m_item->updateTags(); - m_item->setFlag(PlayListItem::FREE); + m_item->setFlag(PlayListTrack::FREE); } } diff --git a/src/qmmpui/tagupdater_p.h b/src/qmmpui/tagupdater_p.h index d196e538c..e5fa66582 100644 --- a/src/qmmpui/tagupdater_p.h +++ b/src/qmmpui/tagupdater_p.h @@ -22,7 +22,7 @@ #define TAGUPDATER_P_H #include <QObject> -#include "playlistitem.h" +#include "playlisttrack.h" /*! @internal * @brief Helper class used for tags update after details dialog closing. @@ -34,9 +34,9 @@ class TagUpdater : public QObject Q_OBJECT public: - TagUpdater(QObject* o, PlayListItem* item); + TagUpdater(QObject* o, PlayListTrack* track); QObject* m_observable; - PlayListItem* m_item; + PlayListTrack* m_item; public slots: void updateTag(); |
