diff options
Diffstat (limited to 'src')
61 files changed, 1192 insertions, 566 deletions
diff --git a/src/app/builtincommandlineoption.cpp b/src/app/builtincommandlineoption.cpp index 372d63cc9..ee10835a5 100644 --- a/src/app/builtincommandlineoption.cpp +++ b/src/app/builtincommandlineoption.cpp @@ -125,7 +125,7 @@ void BuiltinCommandLineOption::executeCommand(const QString &option_string, m_model->clear(); if(!full_path_list.isEmpty()) { - connect(m_model, SIGNAL(itemAdded(PlayListItem*)), player, SLOT(play())); + connect(m_model, SIGNAL(itemAdded(PlayListTrack*)), player, SLOT(play())); connect(core, SIGNAL(stateChanged(Qmmp::State)), SLOT(disconnectPl())); connect(m_model, SIGNAL(loaderFinished()), SLOT(disconnectPl())); } @@ -219,7 +219,7 @@ void BuiltinCommandLineOption::disconnectPl() { if(m_model) { - disconnect(m_model, SIGNAL(itemAdded(PlayListItem*)), MediaPlayer::instance(), SLOT(play())); + disconnect(m_model, SIGNAL(itemAdded(PlayListTrack*)), MediaPlayer::instance(), SLOT(play())); disconnect(m_model, SIGNAL(loaderFinished()), this, SLOT(disconnectPl())); disconnect(SoundCore::instance(), SIGNAL(stateChanged(Qmmp::State)), this, SLOT(disconnectPl())); m_model = 0; diff --git a/src/plugins/CommandLineOptions/PlayListOption/playlistoption.cpp b/src/plugins/CommandLineOptions/PlayListOption/playlistoption.cpp index 8e8f12c7e..f8b36c29d 100644 --- a/src/plugins/CommandLineOptions/PlayListOption/playlistoption.cpp +++ b/src/plugins/CommandLineOptions/PlayListOption/playlistoption.cpp @@ -99,7 +99,7 @@ QString PlayListOption::executeCommand(const QString& opt_str, const QStringList PlayListModel *model = pl_manager->playListAt(pl_id); if(!model) return tr("Invalid playlist ID") + "\n"; - PlayListItem *item = model->item(track_id); + PlayListTrack *item = model->item(track_id); if(!item) return tr("Invalid track ID") + "\n"; player->stop(); diff --git a/src/plugins/General/converter/converterdialog.cpp b/src/plugins/General/converter/converterdialog.cpp index 2cf238441..2c83e5416 100644 --- a/src/plugins/General/converter/converterdialog.cpp +++ b/src/plugins/General/converter/converterdialog.cpp @@ -29,11 +29,11 @@ #include "preseteditor.h" #include "converterdialog.h" -ConverterDialog::ConverterDialog(QList <PlayListItem *> items, QWidget *parent) : QDialog(parent) +ConverterDialog::ConverterDialog(QList <PlayListTrack *> items, QWidget *parent) : QDialog(parent) { ui.setupUi(this); MetaDataFormatter formatter("%p%if(%p&%t, - ,)%t - %l"); - foreach(PlayListItem *item , items) + foreach(PlayListTrack *item , items) { if(item->length() == 0) continue; diff --git a/src/plugins/General/converter/converterdialog.h b/src/plugins/General/converter/converterdialog.h index a7f531b55..981a726fc 100644 --- a/src/plugins/General/converter/converterdialog.h +++ b/src/plugins/General/converter/converterdialog.h @@ -26,7 +26,7 @@ #include "ui_converterdialog.h" class QAction; -class PlayListItem; +class PlayListTrack; class ConverterPreset; /** @@ -36,7 +36,7 @@ class ConverterDialog : public QDialog { Q_OBJECT public: - explicit ConverterDialog(QList <PlayListItem *> items, QWidget *parent = 0); + explicit ConverterDialog(QList <PlayListTrack *> items, QWidget *parent = 0); virtual ~ConverterDialog(); QStringList selectedUrls() const; diff --git a/src/plugins/General/converter/converterhelper.cpp b/src/plugins/General/converter/converterhelper.cpp index 96ccf72a2..0a93990c6 100644 --- a/src/plugins/General/converter/converterhelper.cpp +++ b/src/plugins/General/converter/converterhelper.cpp @@ -55,7 +55,7 @@ ConverterHelper::~ConverterHelper() void ConverterHelper::openConverter() { PlayListManager *pl_manager = MediaPlayer::instance()->playListManager(); - QList <PlayListItem *> items = pl_manager->selectedPlayList()->selectedItems(); + QList <PlayListTrack *> items = pl_manager->selectedPlayList()->selectedItems(); if (items.isEmpty()) return; diff --git a/src/plugins/General/copypaste/copypaste.cpp b/src/plugins/General/copypaste/copypaste.cpp index 87fc8a275..2d9576187 100644 --- a/src/plugins/General/copypaste/copypaste.cpp +++ b/src/plugins/General/copypaste/copypaste.cpp @@ -66,9 +66,9 @@ void CopyPaste::cut() qDebug("%s", Q_FUNC_INFO); qDeleteAll(m_buffer); m_buffer.clear(); - foreach(PlayListItem *item, m_pl_manager->selectedPlayList()->selectedItems()) + foreach(PlayListTrack *item, m_pl_manager->selectedPlayList()->selectedItems()) { - m_buffer.append(new PlayListItem(*item)); + m_buffer.append(new PlayListTrack(*item)); } m_pl_manager->selectedPlayList()->removeSelected(); } @@ -78,17 +78,17 @@ void CopyPaste::copy() qDebug("%s", Q_FUNC_INFO); qDeleteAll(m_buffer); m_buffer.clear(); - foreach(PlayListItem *item, m_pl_manager->selectedPlayList()->selectedItems()) + foreach(PlayListTrack *item, m_pl_manager->selectedPlayList()->selectedItems()) { - m_buffer.append(new PlayListItem(*item)); + m_buffer.append(new PlayListTrack(*item)); } } void CopyPaste::paste() { qDebug("%s", Q_FUNC_INFO); - foreach(PlayListItem *item, m_buffer) + foreach(PlayListTrack *item, m_buffer) { - m_pl_manager->selectedPlayList()->add(new PlayListItem(*item)); + m_pl_manager->selectedPlayList()->add(new PlayListTrack(*item)); } } diff --git a/src/plugins/General/copypaste/copypaste.h b/src/plugins/General/copypaste/copypaste.h index 9a444f26c..3b550122c 100644 --- a/src/plugins/General/copypaste/copypaste.h +++ b/src/plugins/General/copypaste/copypaste.h @@ -26,7 +26,7 @@ class QAction; class SoundCore; -class PlayListItem; +class PlayListTrack; class PlayListManager; /** @@ -47,7 +47,7 @@ private slots: private: PlayListManager *m_pl_manager; - QList<PlayListItem *> m_buffer; + QList<PlayListTrack *> m_buffer; }; #endif //COPYPASTE_H diff --git a/src/plugins/General/covermanager/covermanager.cpp b/src/plugins/General/covermanager/covermanager.cpp index 7ab4c82dc..a01bffa60 100644 --- a/src/plugins/General/covermanager/covermanager.cpp +++ b/src/plugins/General/covermanager/covermanager.cpp @@ -40,7 +40,7 @@ CoverManager::CoverManager(QObject *parent) : QObject(parent) void CoverManager::showWindow() { - QList <PlayListItem *> items = MediaPlayer::instance()->playListManager()->selectedPlayList()->selectedItems(); + QList <PlayListTrack *> items = MediaPlayer::instance()->playListManager()->selectedPlayList()->selectedItems(); if (!items.isEmpty()) { CoverWidget *w = new CoverWidget(qApp->activeWindow ()); diff --git a/src/plugins/General/fileops/fileops.cpp b/src/plugins/General/fileops/fileops.cpp index 245c4fe20..4283bb187 100644 --- a/src/plugins/General/fileops/fileops.cpp +++ b/src/plugins/General/fileops/fileops.cpp @@ -85,7 +85,7 @@ void FileOps::execAction(int n) QString destination = m_destinations.at(n); PlayListModel *model = MediaPlayer::instance()->playListManager()->selectedPlayList(); - QList<PlayListItem*> items = model->selectedItems(); + QList<PlayListTrack*> items = model->selectedItems(); switch (type) { @@ -105,7 +105,7 @@ void FileOps::execAction(int n) progress.show(); progress.setAutoClose (false); int i = 0; - foreach(PlayListItem *item, items) + foreach(PlayListTrack *item, items) { if (!QFile::exists(item->url())) continue; @@ -158,7 +158,7 @@ void FileOps::execAction(int n) } case RENAME: qDebug("FileOps: rename"); - foreach(PlayListItem *item, items) + foreach(PlayListTrack *item, items) { if (!QFile::exists(item->url())) continue; @@ -191,7 +191,7 @@ void FileOps::execAction(int n) QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) break; - foreach(PlayListItem *item, items) + foreach(PlayListTrack *item, items) { if (QFile::exists(item->url()) && QFile::remove(item->url())) model->removeAt (model->indexOf(item)); diff --git a/src/plugins/General/fileops/fileops.h b/src/plugins/General/fileops/fileops.h index 23c35c6de..fdd87182f 100644 --- a/src/plugins/General/fileops/fileops.h +++ b/src/plugins/General/fileops/fileops.h @@ -25,7 +25,7 @@ class QAction; class SoundCore; -class PlayListItem; +class PlayListTrack; /** @author Ilya Kotov <forkotov02@hotmail.ru> diff --git a/src/plugins/General/hal/halplugin.cpp b/src/plugins/General/hal/halplugin.cpp index 51db4d894..2f1dfd067 100644 --- a/src/plugins/General/hal/halplugin.cpp +++ b/src/plugins/General/hal/halplugin.cpp @@ -237,7 +237,7 @@ HalDevice *HalPlugin::findDevice(QAction *action) void HalPlugin::addPath(const QString &path) { - foreach(PlayListItem *item, MediaPlayer::instance()->playListManager()->selectedPlayList()->items()) // Is it already exist? + foreach(PlayListTrack *item, MediaPlayer::instance()->playListManager()->selectedPlayList()->items()) // Is it already exist? { if (item->url().startsWith(path)) return; diff --git a/src/plugins/General/lyrics/lyrics.cpp b/src/plugins/General/lyrics/lyrics.cpp index 415e04647..fef704801 100644 --- a/src/plugins/General/lyrics/lyrics.cpp +++ b/src/plugins/General/lyrics/lyrics.cpp @@ -42,7 +42,7 @@ Lyrics::~Lyrics() void Lyrics::showLyrics() { PlayListManager *pl_manager = MediaPlayer::instance()->playListManager(); - QList <PlayListItem *> items = pl_manager->selectedPlayList()->selectedItems(); + QList <PlayListTrack *> items = pl_manager->selectedPlayList()->selectedItems(); if (!items.isEmpty()) { if (items.at(0)->value(Qmmp::ARTIST).isEmpty() || items.at(0)->value(Qmmp::TITLE).isEmpty()) diff --git a/src/plugins/General/mpris/mpris1/tracklistobject.cpp b/src/plugins/General/mpris/mpris1/tracklistobject.cpp index 9576a902a..e75900439 100644 --- a/src/plugins/General/mpris/mpris1/tracklistobject.cpp +++ b/src/plugins/General/mpris/mpris1/tracklistobject.cpp @@ -82,7 +82,7 @@ int TrackListObject::GetLength() QVariantMap TrackListObject::GetMetadata(int in0) { QVariantMap map; - PlayListItem *item = m_model->item(in0); + PlayListTrack *item = m_model->item(in0); if (item) { if (QFile::exists(item->url())) diff --git a/src/plugins/General/mpris/mpris2/player2object.cpp b/src/plugins/General/mpris/mpris2/player2object.cpp index 1aeb4b2ac..af22d1eb7 100644 --- a/src/plugins/General/mpris/mpris2/player2object.cpp +++ b/src/plugins/General/mpris/mpris2/player2object.cpp @@ -119,7 +119,7 @@ double Player2Object::maximumRate() const QVariantMap Player2Object::metadata() const { - PlayListItem *item = m_pl_manager->currentPlayList()->currentItem(); + PlayListTrack *item = m_pl_manager->currentPlayList()->currentItem(); if(!item || m_core->metaData(Qmmp::URL).isEmpty()) return QVariantMap(); QVariantMap map; @@ -222,8 +222,8 @@ void Player2Object::OpenUri(const QString &in0) if(!m_pl_manager->currentPlayList()->isLoaderRunning()) { m_pl_manager->selectPlayList(m_pl_manager->currentPlayList()); - connect(m_pl_manager->currentPlayList(), SIGNAL(itemAdded(PlayListItem*)), - SLOT(playItem(PlayListItem*))); + connect(m_pl_manager->currentPlayList(), SIGNAL(itemAdded(PlayListTrack*)), + SLOT(playItem(PlayListTrack*))); connect(m_pl_manager->currentPlayList(), SIGNAL(loaderFinished()), this, SLOT(disconnectPl())); } m_pl_manager->currentPlayList()->add(path); @@ -343,11 +343,11 @@ void Player2Object::checkSeeking(qint64 elapsed) m_previous_pos = elapsed; } -void Player2Object::playItem(PlayListItem *item) +void Player2Object::playItem(PlayListTrack *item) { m_pl_manager->selectPlayList((PlayListModel*)sender()); m_pl_manager->activatePlayList((PlayListModel*)sender()); - disconnect(sender(), SIGNAL(itemAddded(itemAdded(PlayListItem*))), this, SLOT(playItem(PlayListItem*))); + disconnect(sender(), SIGNAL(itemAddded(itemAdded(PlayListTrack*))), this, SLOT(playItem(PlayListTrack*))); if(!m_pl_manager->currentPlayList()->setCurrent(item)) return; m_core->stop(); @@ -356,8 +356,8 @@ void Player2Object::playItem(PlayListItem *item) void Player2Object::disconnectPl() { - disconnect(sender(), SIGNAL(itemAddded(itemAdded(PlayListItem*))), - this, SLOT(playItem(PlayListItem*))); + disconnect(sender(), SIGNAL(itemAddded(itemAdded(PlayListTrack*))), + this, SLOT(playItem(PlayListTrack*))); } void Player2Object::setModel(PlayListModel *selected, PlayListModel *previous) diff --git a/src/plugins/General/mpris/mpris2/player2object.h b/src/plugins/General/mpris/mpris2/player2object.h index 37d332cf2..b808f83e5 100644 --- a/src/plugins/General/mpris/mpris2/player2object.h +++ b/src/plugins/General/mpris/mpris2/player2object.h @@ -30,7 +30,7 @@ class SoundCore; class MediaPlayer; class PlayListManager; -class PlayListItem; +class PlayListTrack; class PlayListModel; /** @@ -97,7 +97,7 @@ private slots: void updateId(); void checkState(Qmmp::State state); void checkSeeking(qint64 elapsed); - void playItem(PlayListItem *item); + void playItem(PlayListTrack *item); void disconnectPl(); void setModel(PlayListModel *selected, PlayListModel *previous); @@ -109,7 +109,7 @@ private: PlayListManager *m_pl_manager; QMap<QString, QVariant> m_props; QDBusObjectPath m_trackID; - PlayListItem *m_prev_item; + PlayListTrack *m_prev_item; qint64 m_previous_pos; }; diff --git a/src/plugins/General/trackchange/trackchange.h b/src/plugins/General/trackchange/trackchange.h index 372964551..727f2e2d5 100644 --- a/src/plugins/General/trackchange/trackchange.h +++ b/src/plugins/General/trackchange/trackchange.h @@ -26,7 +26,7 @@ class QAction; class SoundCore; -class PlayListItem; +class PlayListTrack; class PlayListManager; /** diff --git a/src/plugins/General/udisks/udisksplugin.cpp b/src/plugins/General/udisks/udisksplugin.cpp index ae342165d..220bf2c03 100644 --- a/src/plugins/General/udisks/udisksplugin.cpp +++ b/src/plugins/General/udisks/udisksplugin.cpp @@ -231,7 +231,7 @@ UDisksDevice *UDisksPlugin::findDevice(QAction *action) void UDisksPlugin::addPath(const QString &path) { - foreach(PlayListItem *item, MediaPlayer::instance()->playListManager()->selectedPlayList()->items()) // Is it already exist? + foreach(PlayListTrack *item, MediaPlayer::instance()->playListManager()->selectedPlayList()->items()) // Is it already exist? { if (item->url().startsWith(path)) return; diff --git a/src/plugins/General/udisks2/udisks2plugin.cpp b/src/plugins/General/udisks2/udisks2plugin.cpp index 39c8c6af7..bfee228d8 100644 --- a/src/plugins/General/udisks2/udisks2plugin.cpp +++ b/src/plugins/General/udisks2/udisks2plugin.cpp @@ -211,7 +211,7 @@ UDisks2Device *UDisks2Plugin::findDevice(QAction *action) void UDisks2Plugin::addPath(const QString &path) { - foreach(PlayListItem *item, PlayListManager::instance()->selectedPlayList()->items()) // Is it already exist? + foreach(PlayListTrack *item, PlayListManager::instance()->selectedPlayList()->items()) // Is it already exist? { if (item->url().startsWith(path)) return; diff --git a/src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp b/src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp index 7f916dda1..d426fe1ff 100644 --- a/src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp +++ b/src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp @@ -51,11 +51,11 @@ QStringList M3UPlaylistFormat::decode(const QString & contents) return out; } -QString M3UPlaylistFormat::encode(const QList<PlayListItem*> & contents) +QString M3UPlaylistFormat::encode(const QList<PlayListTrack*> & contents) { QStringList out; out << QString("#EXTM3U"); - foreach(PlayListItem* f,contents) + foreach(PlayListTrack* f,contents) { QString info = "#EXTINF:" + QString::number(f->length()) + "," + f->value(Qmmp::TITLE); out.append(info); diff --git a/src/plugins/PlayListFormats/m3u/m3uplaylistformat.h b/src/plugins/PlayListFormats/m3u/m3uplaylistformat.h index 4c2405abf..6e9397f0c 100644 --- a/src/plugins/PlayListFormats/m3u/m3uplaylistformat.h +++ b/src/plugins/PlayListFormats/m3u/m3uplaylistformat.h @@ -37,7 +37,7 @@ class M3UPlaylistFormat : public QObject, public PlayListFormat public: const PlayListFormatProperties properties() const; QStringList decode(const QString& contents); - QString encode(const QList<PlayListItem*>& contents); + QString encode(const QList<PlayListTrack*>& contents); }; diff --git a/src/plugins/PlayListFormats/pls/plsplaylistformat.cpp b/src/plugins/PlayListFormats/pls/plsplaylistformat.cpp index f73d7cc87..76073a7c6 100644 --- a/src/plugins/PlayListFormats/pls/plsplaylistformat.cpp +++ b/src/plugins/PlayListFormats/pls/plsplaylistformat.cpp @@ -64,12 +64,12 @@ QStringList PLSPlaylistFormat::decode(const QString & contents) return QStringList(); } -QString PLSPlaylistFormat::encode(const QList<PlayListItem *> & contents) +QString PLSPlaylistFormat::encode(const QList<PlayListTrack *> & contents) { QStringList out; out << QString("[playlist]"); int counter = 1; - foreach(PlayListItem* f,contents) + foreach(PlayListTrack* f,contents) { QString begin = "File" + QString::number(counter) + "="; out.append(begin + f->url()); diff --git a/src/plugins/PlayListFormats/pls/plsplaylistformat.h b/src/plugins/PlayListFormats/pls/plsplaylistformat.h index 42fbb48f6..28b5b724e 100644 --- a/src/plugins/PlayListFormats/pls/plsplaylistformat.h +++ b/src/plugins/PlayListFormats/pls/plsplaylistformat.h @@ -37,7 +37,7 @@ class PLSPlaylistFormat : public QObject, public PlayListFormat public: const PlayListFormatProperties properties() const; QStringList decode(const QString& contents); - QString encode(const QList<PlayListItem*>& contents); + QString encode(const QList<PlayListTrack*>& contents); }; diff --git a/src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp b/src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp index 9d37610de..08b840177 100644 --- a/src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp +++ b/src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp @@ -75,7 +75,7 @@ QStringList XSPFPlaylistFormat::decode(const QString & contents) // Needs more work - it's better use libSpiff there and put it as plugin. -QString XSPFPlaylistFormat::encode(const QList<PlayListItem*> & files) +QString XSPFPlaylistFormat::encode(const QList<PlayListTrack*> & files) { QDomDocument doc; QDomElement root = doc.createElement("playlist"); @@ -90,7 +90,7 @@ QString XSPFPlaylistFormat::encode(const QList<PlayListItem*> & files) QDomElement tracklist = doc.createElement("trackList"); int counter = 1; - foreach(PlayListItem* f,files) + foreach(PlayListTrack* f,files) { QDomElement track = doc.createElement("track"); diff --git a/src/plugins/PlayListFormats/xspf/xspfplaylistformat.h b/src/plugins/PlayListFormats/xspf/xspfplaylistformat.h index 4570c041d..d7f705c55 100644 --- a/src/plugins/PlayListFormats/xspf/xspfplaylistformat.h +++ b/src/plugins/PlayListFormats/xspf/xspfplaylistformat.h @@ -37,7 +37,7 @@ class XSPFPlaylistFormat : public QObject, public PlayListFormat public: const PlayListFormatProperties properties() const; QStringList decode(const QString& contents); - QString encode(const QList<PlayListItem*>& contents); + QString encode(const QList<PlayListTrack*>& contents); }; #endif diff --git a/src/plugins/Ui/skinned/eqwidget.cpp b/src/plugins/Ui/skinned/eqwidget.cpp index 5068e0861..54450b705 100644 --- a/src/plugins/Ui/skinned/eqwidget.cpp +++ b/src/plugins/Ui/skinned/eqwidget.cpp @@ -323,22 +323,22 @@ void EqWidget::savePreset() void EqWidget::saveAutoPreset() { - PlayList* playlist = qobject_cast<MainWindow*>(parent())->playlist(); - if (!playlist->currentItem()) - return; + PlayList* playlist;// = qobject_cast<MainWindow*>(parent())->playlist(); + /*if (!playlist->currentItem()) + return;*/ //delete preset if it already exists - EQPreset* preset = findPreset(playlist->currentItem()->url().section("/",-1)); - if (preset) - deletePreset(preset); + //EQPreset* preset = findPreset(playlist->currentItem()->url().section("/",-1)); + //if (preset) + // deletePreset(preset); //create new preset - preset = new EQPreset(); - preset->setText(playlist->currentItem()->url().section("/",-1)); - preset->setPreamp(m_preamp->value()); + //preset = new EQPreset(); + //preset->setText(playlist->currentItem()->url().section("/",-1)); + /*preset->setPreamp(m_preamp->value()); for (int i = 0; i<10; ++i) { preset->setGain(i, m_sliders.at (i)->value()); } - m_autoPresets.append(preset); + m_autoPresets.append(preset);*/ } void EqWidget::setPreset(EQPreset* preset) diff --git a/src/plugins/Ui/skinned/eqwidget.h b/src/plugins/Ui/skinned/eqwidget.h index 1f96d1310..8ed690e94 100644 --- a/src/plugins/Ui/skinned/eqwidget.h +++ b/src/plugins/Ui/skinned/eqwidget.h @@ -35,7 +35,7 @@ class ToggleButton; class EQGraph; class Button; class EQPreset; -class PlayListItem; +class PlayListTrack; class SoundCore; class EqWidget : public PixmapWidget diff --git a/src/plugins/Ui/skinned/listwidget.cpp b/src/plugins/Ui/skinned/listwidget.cpp index f4e9c1c2f..64fb4f770 100644 --- a/src/plugins/Ui/skinned/listwidget.cpp +++ b/src/plugins/Ui/skinned/listwidget.cpp @@ -168,50 +168,80 @@ void ListWidget::paintEvent(QPaintEvent *) for (int i = 0; i < m_rows.size(); ++i ) { + sy = (i + 1) * (2 + m_metrics->lineSpacing()) - 2 - m_metrics->descent(); + + if(m_rows[i]->separator) + { + painter.setPen(m_normal); + if(m_number_width) + { + sx = 10 + m_number_width + m_metrics->width("9"); + if(rtl) + { + sx = width() - sx - m_metrics->width(m_rows[i]->title); + } + } + else + { + sx = rtl ? width() - 10 - m_metrics->width(m_rows[i]->title) : 10; + } + painter.drawLine(sx, sy - m_metrics->lineSpacing()/2 + 2, + sx + 30, sy - m_metrics->lineSpacing()/2 + 2); + + painter.drawLine(sx + 35 + m_metrics->width(m_rows[i]->title) + 5, + sy - m_metrics->lineSpacing()/2 + 2, + width() - 10, + sy - m_metrics->lineSpacing()/2 + 2); + + painter.drawText(sx + 35, sy, m_rows[i]->title); + continue; + } + if (m_show_anchor && i == m_anchor_row - m_first) { - painter.setBrush(m_rows[i]->item->isSelected() ? m_selected_bg : m_normal_bg); + painter.setBrush(m_rows[i]->selected ? m_selected_bg : m_normal_bg); painter.setPen(m_normal); painter.drawRect (6, i * (m_metrics->lineSpacing() + 2), - width() - 10, m_metrics->lineSpacing() + 1); + width() - 10, m_metrics->lineSpacing() + 1); } else { - if (m_rows[i]->item->isSelected()) + if (m_rows[i]->selected) { painter.setBrush(QBrush(m_selected_bg)); painter.setPen(m_selected_bg); painter.drawRect (6, i * (m_metrics->lineSpacing() + 2), - width() - 10, m_metrics->lineSpacing() + 1); + width() - 10, m_metrics->lineSpacing() + 1); } } - if (m_model->currentIndex() == m_rows[i]->index) + + if (m_model->currentIndex() == m_first + i) painter.setPen(m_current); else painter.setPen(m_normal); //243,58 - sy = (i + 1) * (2 + m_metrics->lineSpacing()) - 2 - m_metrics->descent(); if(m_number_width) { - QString number = QString("%1").arg(m_first+i+1); + QString number = QString("%1").arg(m_rows[i]->number); sx = 10 + m_number_width - m_metrics->width(number); if(rtl) sx = width() - sx - m_metrics->width(number); - painter.drawText(sx, sy, number); + if(!m_rows[i]->separator) + painter.drawText(sx, sy, number); sx = 10 + m_number_width + m_metrics->width("9"); if(rtl) sx = width() - sx - m_metrics->width(m_rows[i]->title); - painter.drawText(sx, sy, m_rows[i]->title); } else { sx = rtl ? width() - 10 - m_metrics->width(m_rows[i]->title) : 10; - painter.drawText(sx, sy, m_rows[i]->title); } + painter.drawText(sx, sy, m_rows[i]->title); + QString extra_string = m_rows[i]->extraString; if(!extra_string.isEmpty()) @@ -349,7 +379,7 @@ void ListWidget::wheelEvent (QWheelEvent *e) bool ListWidget::event (QEvent *e) { - if(m_popupWidget) + /*if(m_popupWidget) { if(e->type() == QEvent::ToolTip) { @@ -366,7 +396,7 @@ bool ListWidget::event (QEvent *e) } else if(e->type() == QEvent::Leave) m_popupWidget->deactivate(); - } + }*/ return QWidget::event(e); } @@ -391,34 +421,51 @@ void ListWidget::updateList() //song numbers width if(m_show_number && m_align_numbres && m_model->count()) { - m_number_width = m_metrics->width("9") * QString::number(m_model->count()).size(); + m_number_width = m_metrics->width("9") * QString::number(m_model->trackCount()).size(); } else m_number_width = 0; - qDeleteAll(m_rows); //TODO do not delete all row objects + qDeleteAll(m_rows); m_rows.clear(); QList<PlayListItem *> items = m_model->mid(m_first, m_row_count); + + while(m_rows.count() < qMin(m_row_count, items.count())) + m_rows << new ListWidgetRow; + while(m_rows.count() > qMin(m_row_count, items.count())) + delete m_rows.takeFirst(); + for(int i = 0; i < items.count(); ++i) { - ListWidgetRow *row = new ListWidgetRow; - row->item = items[i]; - row->title = items[i]->formattedTitle(); - row->length = items[i]->formattedLength(); - row->index = m_first + i; - //add numbers - if(m_show_number && !m_align_numbres) - row->title.prepend(QString("%1").arg(m_first+i+1)+". "); - //elide titles - row->extraString = getExtraString(m_first + i); - int extra_string_width = row->extraString.isEmpty() ? 0 : m_metrics->width(row->extraString); - if(m_number_width) - extra_string_width += m_number_width + m_metrics->width("9"); - row->title = m_metrics->elidedText (row->title, Qt::ElideRight, - width() - m_metrics->width(row->length) - 22 - extra_string_width); - - m_rows.append(row); + ListWidgetRow *row = m_rows[i]; + if(items[i]->isGroup()) + { + row->separator = true; + row->number = 0; + row->title = items[i]->formattedTitle(); + row->length.clear(); + row->selected = false; + row->title = m_metrics->elidedText (row->title, Qt::ElideRight, + width() - m_number_width - 22 - 70); + } + else + { + row->separator = false; + row->number = m_model->numberOfTrack(m_first+i) + 1; + row->title = items[i]->formattedTitle(); + row->length = items[i]->formattedLength(); + row->selected = items[i]->isSelected(); + if(m_show_number && !m_align_numbres) + row->title.prepend(QString("%1").arg(row->number)+". "); + row->extraString = getExtraString(m_first + i); + //elide titles + int extra_string_width = row->extraString.isEmpty() ? 0 : m_metrics->width(row->extraString); + if(m_number_width) + extra_string_width += m_number_width + m_metrics->width("9"); + row->title = m_metrics->elidedText (row->title, Qt::ElideRight, + width() - m_metrics->width(row->length) - 22 - extra_string_width); + } } m_scroll = false; update(); @@ -504,18 +551,22 @@ const QString ListWidget::getExtraString(int i) { QString extra_string; - if (m_show_protocol && m_model->item(i)->url().contains("://")) - extra_string = "[" + m_model->item(i)->url().split("://").at(0) + "]"; + PlayListTrack *track = m_model->track(i); + if(!track) + return extra_string; - if (m_model->isQueued(m_model->item(i))) + if (m_show_protocol && track->url().contains("://")) + extra_string = "[" + track->url().split("://").at(0) + "]"; + + if (m_model->isQueued(track)) { - int index = m_model->queuedIndex(m_model->item(i)); + int index = m_model->queuedIndex(track); extra_string += "|"+QString::number(index + 1)+"|"; } if(m_model->currentIndex() == i && m_player->isRepeatable()) extra_string += "|R|"; - else if(m_model->isStopAfter(m_model->item(i))) + else if(m_model->isStopAfter(track)) extra_string += "|S|"; extra_string = extra_string.trimmed(); //remove white space @@ -570,8 +621,8 @@ void ListWidget::mouseMoveEvent(QMouseEvent *e) else if(m_popupWidget) { int row = rowAt(e->y()); - if(row < 0 || m_popupWidget->url() != m_model->item(row)->url()) - m_popupWidget->deactivate(); + /*if(row < 0 || m_popupWidget->url() != m_model->item(row)->url()) + m_popupWidget->deactivate();*/ } } diff --git a/src/plugins/Ui/skinned/listwidget.h b/src/plugins/Ui/skinned/listwidget.h index 75dd12427..b7e902203 100644 --- a/src/plugins/Ui/skinned/listwidget.h +++ b/src/plugins/Ui/skinned/listwidget.h @@ -46,8 +46,9 @@ struct ListWidgetRow QString title; QString length; QString extraString; - int index; - PlayListItem *item; + int number; + bool separator; + bool selected; }; /** diff --git a/src/plugins/Ui/skinned/mainwindow.cpp b/src/plugins/Ui/skinned/mainwindow.cpp index c042e757b..d46e8e315 100644 --- a/src/plugins/Ui/skinned/mainwindow.cpp +++ b/src/plugins/Ui/skinned/mainwindow.cpp @@ -174,8 +174,8 @@ void MainWindow::showState(Qmmp::State state) switch ((int) state) { case Qmmp::Playing: - if (m_pl_manager->currentPlayList()->currentItem()) - m_equalizer->loadPreset(m_pl_manager->currentPlayList()->currentItem()->url().section("/",-1)); + //if (m_pl_manager->currentPlayList()->currentItem()) + // m_equalizer->loadPreset(m_pl_manager->currentPlayList()->currentItem()->url().section("/",-1)); break; case Qmmp::Paused: break; @@ -191,11 +191,11 @@ void MainWindow::showState(Qmmp::State state) void MainWindow::showMetaData() { - if (m_playlist->currentItem() && + /*if (m_playlist->currentItem() && m_playlist->currentItem()->url() == m_core->metaData().value(Qmmp::URL)) { setWindowTitle(m_playlist->currentItem()->formattedTitle()); - } + }*/ } void MainWindow::closeEvent (QCloseEvent *) diff --git a/src/plugins/Ui/skinned/playlist.cpp b/src/plugins/Ui/skinned/playlist.cpp index c72802606..57ca57550 100644 --- a/src/plugins/Ui/skinned/playlist.cpp +++ b/src/plugins/Ui/skinned/playlist.cpp @@ -522,7 +522,7 @@ void PlayList::updateList() PlayListItem *PlayList::currentItem() { - return m_pl_manager->currentPlayList()->currentItem(); + return m_pl_manager->currentPlayList()->currentTrack(); } void PlayList::showPlaylistMenu() @@ -582,7 +582,7 @@ void PlayList::generateCopySelectedMenu() void PlayList::copySelectedMenuActionTriggered(QAction *action) { - PlayListModel *targetPlayList = 0; + /*PlayListModel *targetPlayList = 0; QString actionText=action->text(); if(action == m_copySelectedMenu->actions().at(0))//actionText == tr ("&New PlayList")) { @@ -606,13 +606,13 @@ void PlayList::copySelectedMenuActionTriggered(QAction *action) qWarning("Error: Cannot find target playlist '%s'",qPrintable(actionText)); return; } - QList <PlayListItem *> theCopy; + QList <PlayListTrack *> theCopy; foreach(PlayListItem *item, m_pl_manager->selectedPlayList()->selectedItems()) { - PlayListItem *newItem = new PlayListItem(*item); + PlayListTrack *newItem = new PlayListTrack(*item); theCopy << newItem; } - targetPlayList->add(theCopy); + targetPlayList->add(theCopy);*/ } void PlayList::setMinimalMode(bool b) diff --git a/src/plugins/Ui/skinned/playlist.h b/src/plugins/Ui/skinned/playlist.h index 80adaf3c7..fc1bd3959 100644 --- a/src/plugins/Ui/skinned/playlist.h +++ b/src/plugins/Ui/skinned/playlist.h @@ -51,7 +51,6 @@ class PlayList : public QWidget PlayList (PlayListManager *manager, QWidget *parent = 0); virtual ~PlayList(); - void load (PlayListItem *); void readSettings(); PlayListItem *currentItem(); ListWidget* listWidget() const diff --git a/src/plugins/Ui/skinned/playlisttitlebar.cpp b/src/plugins/Ui/skinned/playlisttitlebar.cpp index 3c5e5d55e..017bed82c 100644 --- a/src/plugins/Ui/skinned/playlisttitlebar.cpp +++ b/src/plugins/Ui/skinned/playlisttitlebar.cpp @@ -260,9 +260,9 @@ void PlayListTitleBar::mouseDoubleClickEvent (QMouseEvent *) void PlayListTitleBar::showCurrent() { - if (m_model) + /*if (m_model) { - PlayListItem* info = m_model->currentItem(); + PlayListTrack* info = m_model->currentItem(); if (info) { m_text = QString("%1. %2").arg(m_model->currentIndex()+1) @@ -278,5 +278,5 @@ void PlayListTitleBar::showCurrent() } QFontMetrics metrics(m_font); m_truncatedText = metrics.elidedText (m_text, Qt::ElideRight, width() - 35*m_ratio); - updatePixmap(); + updatePixmap();*/ } diff --git a/src/plugins/Ui/skinned/popupwidget.cpp b/src/plugins/Ui/skinned/popupwidget.cpp index 640a4fddb..8714f966d 100644 --- a/src/plugins/Ui/skinned/popupwidget.cpp +++ b/src/plugins/Ui/skinned/popupwidget.cpp @@ -81,7 +81,7 @@ void PopupWidget::mouseMoveEvent (QMouseEvent *) hide(); } -void PopupWidget::prepare(PlayListItem *item, QPoint pos) +void PopupWidget::prepare(PlayListTrack *item, QPoint pos) { pos += QPoint(15,10); diff --git a/src/plugins/Ui/skinned/popupwidget.h b/src/plugins/Ui/skinned/popupwidget.h index 87c3bed2b..806165851 100644 --- a/src/plugins/Ui/skinned/popupwidget.h +++ b/src/plugins/Ui/skinned/popupwidget.h @@ -26,7 +26,7 @@ class QTimer; class QLabel; -class PlayListItem; +class PlayListTrack; namespace PlayListPopup { /** @@ -40,7 +40,7 @@ public: ~PopupWidget(); - void prepare(PlayListItem *item, QPoint pos); + void prepare(PlayListTrack *item, QPoint pos); void deactivate(); const QString url() const; diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index facdc240c..58a47ba9b 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,14 +1,14 @@ SUBDIRS += Input \ Output \ - General \ + #General \ Visual \ Transports \ Effect \ - PlayListFormats \ + #PlayListFormats \ FileDialogs \ Ui -unix:SUBDIRS += CommandLineOptions \ - Engines +#unix:SUBDIRS += CommandLineOptions \ +# Engines TEMPLATE = subdirs 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(); |
