[vlc-devel] [PATCH 03/15] qt/mlplaylistmodel: Add insert, move and remove support

Benjamin Arnaud benjamin.arnaud at videolabs.io
Thu Mar 11 09:16:47 UTC 2021


---
 .../gui/qt/medialibrary/mlplaylistmodel.cpp   | 134 ++++++++++++++++++
 .../gui/qt/medialibrary/mlplaylistmodel.hpp   |  10 ++
 2 files changed, 144 insertions(+)

diff --git a/modules/gui/qt/medialibrary/mlplaylistmodel.cpp b/modules/gui/qt/medialibrary/mlplaylistmodel.cpp
index 7f00210fd8..8993ade0ed 100644
--- a/modules/gui/qt/medialibrary/mlplaylistmodel.cpp
+++ b/modules/gui/qt/medialibrary/mlplaylistmodel.cpp
@@ -22,6 +22,9 @@
 
 #include "mlplaylistmodel.hpp"
 
+// Util includes
+#include "util/qmlinputitem.hpp"
+
 // MediaLibrary includes
 #include "mlhelper.hpp"
 #include "mlplaylistmedia.hpp"
@@ -45,6 +48,122 @@ static const QHash<QByteArray, vlc_ml_sorting_criteria_t> criterias =
 /* explicit */ MLPlaylistModel::MLPlaylistModel(QObject * parent)
     : MLBaseModel(parent) {}
 
+//-------------------------------------------------------------------------------------------------
+// Interface
+//-------------------------------------------------------------------------------------------------
+
+/* Q_INVOKABLE */ void MLPlaylistModel::insert(const QVariantList & items, int at)
+{
+    assert(m_ml);
+
+    int64_t id = parentId().id;
+
+    assert(id);
+
+    for (const QVariant & variant : items)
+    {
+        if (variant.canConvert<QmlInputItem>() == false)
+            continue;
+
+        const QmlInputItem & item = variant.value<QmlInputItem>();
+
+        const char * psz_uri = item.item->psz_uri;
+
+        if (psz_uri == nullptr)
+            continue;
+
+        vlc_ml_media_t * media = vlc_ml_get_media_by_mrl(m_ml, psz_uri);
+
+        if (media == nullptr)
+        {
+            media = vlc_ml_new_external_media(m_ml, psz_uri);
+
+            if (media == nullptr)
+                continue;
+        }
+
+        vlc_ml_playlist_insert(m_ml, id, media->i_id, at);
+
+        vlc_ml_media_release(media);
+
+        at++;
+    }
+}
+
+/* Q_INVOKABLE */ void MLPlaylistModel::move(const QModelIndexList & indexes, int to)
+{
+    assert(m_ml);
+
+    int64_t id = parentId().id;
+
+    assert(id);
+
+    int count = rowCount();
+
+    QList<int> rows = getRows(indexes);
+
+    std::sort(rows.begin(), rows.end());
+
+    for (auto it = rows.begin(); it != rows.end(); it++)
+    {
+        int from = *it;
+
+        if (from < 0 || from > count || to < 0 || to > count)
+            continue;
+
+        if (from > to || from < (to - 1))
+        {
+            beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
+
+            if (from < to)
+                to--;
+
+            vlc_ml_playlist_move(m_ml, id, from, to);
+
+            endMoveRows();
+
+            to++;
+        }
+        else if (from == to) {
+            to++;
+        }
+
+        // NOTE: Fixing the next index(s) according to the previous move.
+        for (auto itB = it; itB != rows.end(); itB++)
+        {
+            int index = *itB;
+
+            if (index > from && index < to)
+                (*itB)--;
+        }
+    }
+}
+
+/* Q_INVOKABLE */ void MLPlaylistModel::remove(const QModelIndexList & indexes)
+{
+    assert(m_ml);
+
+    int64_t id = parentId().id;
+
+    assert(id);
+
+    QList<int> rows = getRows(indexes);
+
+    // NOTE: This is useful to avoid fixing the next index after each remove.
+    std::sort(rows.begin(), rows.end(), std::greater<int>());
+
+    for (int from : rows)
+    {
+        if (from < 0 || from >= rowCount())
+            continue;
+
+        beginRemoveRows(QModelIndex(), from, from);
+
+        vlc_ml_playlist_remove(m_ml, id, from);
+
+        endRemoveRows();
+    }
+}
 
 //-------------------------------------------------------------------------------------------------
 // QAbstractItemModel implementation
@@ -150,6 +269,21 @@ ListCacheLoader<std::unique_ptr<MLItem>> * MLPlaylistModel::createLoader() const
     return new Loader(*this);
 }
 
+//-------------------------------------------------------------------------------------------------
+// Private functions
+
+QList<int> MLPlaylistModel::getRows(const QModelIndexList & indexes) const
+{
+    QList<int> rows;
+
+    for (const QModelIndex & index : indexes)
+    {
+        rows.append(index.row());
+    }
+
+    return rows;
+}
+
 //-------------------------------------------------------------------------------------------------
 // Private MLBaseModel reimplementation
 //-------------------------------------------------------------------------------------------------
diff --git a/modules/gui/qt/medialibrary/mlplaylistmodel.hpp b/modules/gui/qt/medialibrary/mlplaylistmodel.hpp
index 85b47cc825..2fb9b663c9 100644
--- a/modules/gui/qt/medialibrary/mlplaylistmodel.hpp
+++ b/modules/gui/qt/medialibrary/mlplaylistmodel.hpp
@@ -48,6 +48,13 @@ public:
 public:
     explicit MLPlaylistModel(QObject * parent = nullptr);
 
+public: // Interface
+    Q_INVOKABLE void insert(const QVariantList & items, int at);
+
+    Q_INVOKABLE void move(const QModelIndexList & indexes, int to);
+
+    Q_INVOKABLE void remove(const QModelIndexList & indexes);
+
 public: // QAbstractItemModel implementation
     QHash<int, QByteArray> roleNames() const override;
 
@@ -62,6 +69,9 @@ protected: // MLBaseModel implementation
 
     ListCacheLoader<std::unique_ptr<MLItem>> * createLoader() const override;
 
+private: // Functions
+    QList<int> getRows(const QModelIndexList & indexes) const;
+
 private: // MLBaseModel implementation
     void onVlcMlEvent(const MLEvent & event) override;
 
-- 
2.25.1



More information about the vlc-devel mailing list