prepare for polymorph playlist

Jean-Francois Dockes Jean-Francois Dockes 2014-09-11

added playlist/PlaylistAVT.h
changed HelperStructs/MetaData.h
changed playlist/Playlist.cpp
changed playlist/Playlist.h
changed .gitignore
changed application.cpp
changed cdbrowser.h
changed upplay.pro
copied playlist/Playlist_GUI_slots.cpp -> playlist/PlaylistAVT.cpp
playlist/PlaylistAVT.h Diff Switch to unified view
Loading...
HelperStructs/MetaData.h Diff Switch to unified view
Loading...
playlist/Playlist.cpp Diff Switch to unified view
Loading...
playlist/Playlist.h Diff Switch to unified view
Loading...
.gitignore Diff Switch to unified view
Loading...
application.cpp Diff Switch to unified view
Loading...
cdbrowser.h Diff Switch to unified view
Loading...
upplay.pro Diff Switch to unified view
Loading...
playlist/Playlist_GUI_slots.cpp to playlist/PlaylistAVT.cpp
--- a/playlist/Playlist_GUI_slots.cpp
+++ b/playlist/PlaylistAVT.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013  Lucio Carreras
+/* Copyright (C) 2011  Lucio Carreras
  *
  * This file is part of sayonara player
  *
@@ -14,154 +14,255 @@
 
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
  */
 
-#include <QString>
-
-#include "HelperStructs/globals.h"
-#include "HelperStructs/MetaData.h"
-#include "playlist/Playlist.h"
+#include <ctime>
+
+using namespace std;
+#include <QFile>
+#include <QList>
+#include <QObject>
+#include <QDate>
+#include <QTime>
+#include <QDebug>
+#include <QDir>
+
+#include <libupnpp/control/avtransport.hxx>
+
+#include "PlaylistAVT.h"
+
+void PlaylistAVT::set_for_playing(int row)
+{
+    if (row < 0 || row >= int(_v_meta_data.size())) {
+        _cur_play_idx = -1;
+        _v_meta_data.setCurPlayTrack(-1);
+        return;
+    }
+
+    if(!checkTrack(_v_meta_data[row]))
+        return;
+
+    emit sig_playing_track_changed(row);
+    emit sig_play_now(_v_meta_data[row]);
+    emit sig_track_metadata(_v_meta_data[row]);
+
+    _cur_play_idx = row;
+    _v_meta_data.setCurPlayTrack(row);
+}
+
+// Player switched tracks under us. Hopefully the uri matches a further track
+void PlaylistAVT::psl_ext_track_change(const QString& uri)
+{
+    if (!valid_row(_cur_play_idx))
+        return;
+
+    for (unsigned int i = _cur_play_idx + 1; i < _v_meta_data.size(); i++) {
+        if (!uri.compare(_v_meta_data[i].filepath)) {
+            qDebug() << "PlaylistAVT::psl_ext_track_change: index now " << i;
+            _cur_play_idx = i;
+            _v_meta_data.setCurPlayTrack(i);
+            emit sig_playing_track_changed(i);
+            emit sig_track_metadata(_v_meta_data[i]);
+            break;
+        }
+    }
+}
+
+void PlaylistAVT::send_next_playing_signal()
+{
+    // Only if there is a track behind the current one
+    if (_cur_play_idx >= 0 && _cur_play_idx < int(_v_meta_data.size()) - 1)
+        emit sig_next_track_to_play(_v_meta_data[_cur_play_idx + 1]);
+}
+
+void PlaylistAVT::psl_prepare_for_end_of_track()
+{
+    if (!valid_row(_cur_play_idx))
+        return;
+    send_next_playing_signal();
+}
+
+void PlaylistAVT::psl_new_transport_state(int tps)
+{
+    string s;
+    switch (tps) {
+    case UPnPClient::AVTransport::Stopped: s = "Stopped"; break;
+    case UPnPClient::AVTransport::Playing: s = "Playing"; break;
+    case UPnPClient::AVTransport::Transitioning: s = "Transitioning"; break;
+    case UPnPClient::AVTransport::PausedPlayback: s = "PausedPlayback"; break;
+    case UPnPClient::AVTransport::PausedRecording: s = "PausedRecording"; break;
+    case UPnPClient::AVTransport::Recording: s = "Recording"; break;
+    case UPnPClient::AVTransport::NoMediaPresent: s = "NoMediaPresent"; break;
+    case UPnPClient::AVTransport::Unknown: 
+    default:
+        s = "Unknown"; break;
+    }
+    qDebug() << "psl_new_transport_state: " << s.c_str();
+}
+
+void PlaylistAVT::psl_next_track()
+{
+    qDebug() << "PlaylistAVT::psl_next_track()";
+
+    int track_num = -1;
+    if(_v_meta_data.empty()) {
+        qDebug() << "PlaylistAVT::psl_next_track(): empty playlist";
+        goto out;
+    }
+
+    if (_playlist_mode.shuffle) {
+        // shuffle mode
+        track_num = rand() % _v_meta_data.size();
+        if (track_num == _cur_play_idx) {
+            track_num = (_cur_play_idx + 1) % _v_meta_data.size();
+        }
+    } else {
+        if (_cur_play_idx >= int(_v_meta_data.size()) -1) {
+            // last track
+            qDebug() << "PlaylistAVT::psl_next_track(): was last, stop or loop";
+            if(_playlist_mode.repAll) {
+                track_num = 0;
+            }
+        } else {
+            track_num = _cur_play_idx + 1;
+            qDebug() << "PlaylistAVT::psl_next_track(): new tnum " << track_num;
+        }
+    }
+
+out:
+    if (track_num >= 0) {
+        // valid next track
+        if(checkTrack(_v_meta_data[track_num])){
+            set_for_playing(track_num);
+        } else {
+            remove_row(track_num);
+            psl_next_track();
+        }
+    } else {
+        set_for_playing(-1);
+        emit sig_stopped();
+        return;
+    }
+}
 
 // GUI -->
-void Playlist::psl_clear_playlist()
+void PlaylistAVT::psl_clear_playlist()
 {
     _v_meta_data.clear();
     _cur_play_idx = -1;
     emit sig_playlist_updated(_v_meta_data, _cur_play_idx, 0);
 }
 
-void Playlist::psl_play()
+void PlaylistAVT::psl_play()
 {
     _pause = false;
 
-    if (_v_meta_data.size() == 0) {
+    if (_v_meta_data.empty()) {
         return;
     }
 
     if (_cur_play_idx < 0) {
-        int track_num = 0;
-        MetaData md = _v_meta_data[track_num];
-
-        if (checkTrack(md)) {
-            send_cur_playing_signal(track_num);
+        if (checkTrack(_v_meta_data[0])) {
+            set_for_playing(0);
         }
     } else {
         emit sig_resume_play();
     }
 }
 
-void Playlist::psl_pause()
+void PlaylistAVT::psl_pause()
 {
     _pause = true;
 }
 
-void Playlist::psl_stop()
-{
-    _cur_play_idx = -1;
-    _is_playing = false;
+void PlaylistAVT::psl_stop()
+{
+    set_for_playing(-1);
     emit sig_stopped();
     emit sig_playlist_updated(_v_meta_data, _cur_play_idx, 0);
 }
 
 // fwd was pressed -> next track
-void Playlist::psl_forward()
+void PlaylistAVT::psl_forward()
 {
     psl_next_track();
 }
 
 // GUI -->
-void Playlist::psl_backward()
+void PlaylistAVT::psl_backward()
 {
     if (_cur_play_idx <= 0) {
         return;
     }
 
     int track_num = _cur_play_idx - 1;
-    MetaData md = _v_meta_data[track_num];
-
-    if (checkTrack(md)) {
-        _v_meta_data.setCurPlayTrack(track_num);
-        send_cur_playing_signal(track_num);
+
+    if (checkTrack(_v_meta_data[track_num])) {
+        set_for_playing(track_num);
     }
 }
 
 // GUI -->
-void Playlist::psl_change_track(int new_row)
-{
-    if (uint(new_row) >= _v_meta_data.size()) {
-        return;
-    }
-
-    for (uint i = 0; i < _v_meta_data.size(); i++) {
-        _v_meta_data[i].pl_playing = (new_row == (int)i);
-        _v_meta_data[i].pl_selected = false;
-    }
-
-    MetaData md = _v_meta_data[new_row];
-    if (checkTrack(md)) {
-        send_cur_playing_signal(new_row);
-    } else {
-        _cur_play_idx = -1;
-        _v_meta_data.setCurPlayTrack(_cur_play_idx);
+void PlaylistAVT::psl_change_track(int new_row)
+{
+    if (!valid_row(new_row)) {
+        return;
+    }
+
+    if (checkTrack(_v_meta_data[new_row])) {
+        set_for_playing(new_row);
+    } else {
+        set_for_playing(-1);
         remove_row(new_row);
-        _is_playing = false;
         emit sig_stopped();
-    }
-}
-
-// insert tracks (also drag & drop)
-void Playlist::psl_insert_tracks(const MetaDataList& v_metadata, int row)
-{
-
-    //bool instant_play = ((_v_meta_data.size() == 0) && (!_is_playing));
-
-    // possibly the current playing index has to be updated
-    if (row < _cur_play_idx && _cur_play_idx != -1) {
-        _cur_play_idx += v_metadata.size();
-    }
-
-    // insert new tracks
-    for (uint i = 0; i < v_metadata.size(); i++) {
-
-        MetaData md = v_metadata[i];
-        _v_meta_data.insert_mid(md, i + row + 1);
-        if (md.pl_playing) {
-            _cur_play_idx = (i + row + 1);
-        }
-    }
+        emit sig_playlist_updated(_v_meta_data, _cur_play_idx, 0);
+    }
+}
+
+// insert tracks after idx which may be -1
+void PlaylistAVT::psl_insert_tracks(const MetaDataList& nmeta, int row)
+{
+    // Change to more conventional "insert before"
+    ++row;
+
+    qDebug() << "PlaylistAVT::psl_insert_tracks: cur size" << 
+        _v_meta_data.size() << " before row " << row;
+    if (_v_meta_data.empty()) {
+        if (row != 0) {
+            return;
+        }
+    } else if (row < 0 || row > int(_v_meta_data.size())) {
+        qDebug() << " bad row";
+        return;
+    }
+    
+    _v_meta_data.insert(_v_meta_data.begin() + row, nmeta.begin(), nmeta.end());
+
+    // Find the playing track (could be part of nmeta if this is a d&d
+    // cut/paste) and adjust _cur_play_idx
+    _cur_play_idx = -1;
+    for (auto it = _v_meta_data.begin(); it != _v_meta_data.end(); it++) {
+        if (it->pl_playing && _cur_play_idx == -1) {
+            _cur_play_idx = it - _v_meta_data.begin();
+        } else {
+            it->pl_playing = false;
+        }
+    }
+
+    send_next_playing_signal();
 
     emit sig_playlist_updated(_v_meta_data, _cur_play_idx, 0);
 }
 
-void Playlist::psl_append_tracks(MetaDataList& v_md)
-{
-    if (v_md.size() == 0) {
-        return;
-    }
-
-    int initsize = int(_v_meta_data.size());
-
-    foreach(MetaData md, v_md)
-    _v_meta_data.push_back(md);
-
-    if (_cur_play_idx == initsize - 1) {
-        // We were playing the last track. Set new next track for gapless,
-        send_next_playing_signal(_cur_play_idx + 1);
-    }
-    emit sig_playlist_updated(_v_meta_data, _cur_play_idx, 0);
-}
-
-// remove one row
-void Playlist::remove_row(int row)
-{
-    QList<int> remove_list;
-    remove_list << row;
-    psl_remove_rows(remove_list);
-}
-
-void Playlist::psl_remove_rows(const QList<int>& rows, bool select_next_row)
-{
-    if (rows.size() == 0) {
+void PlaylistAVT::psl_append_tracks(const MetaDataList& v_md)
+{
+    psl_insert_tracks(v_md, _v_meta_data.size() - 1);
+}
+
+void PlaylistAVT::psl_remove_rows(const QList<int>& rows, bool select_next_row)
+{
+    if (rows.empty())
         return;
     }
 
@@ -212,11 +313,9 @@
 
 
 // GUI -->
-void Playlist::psl_playlist_mode_changed(const Playlist_Mode& playlist_mode)
+void PlaylistAVT::psl_playlist_mode_changed(const Playlist_Mode& playlist_mode)
 {
     _settings->setPlaylistMode(playlist_mode);
     _playlist_mode = playlist_mode;
     _playlist_mode.print();
 }
-
-