[vlc-devel] [PATCH v2 04/13] qt: medialib: pass explicit query parameters

Romain Vimont rom1v at videolabs.io
Thu Nov 26 17:10:36 CET 2020


MLSlidingWindowModel declares two pure virtual methods to be implemented
by subclasses:
 - countTotalElements()
 - fetch()

The query parameters to use were implicitly defined by the class fields.

Instead, pass them explicitly. This paves the way to implement a
separate cache and execute queries from a separate thread.
---
 modules/gui/qt/Makefile.am                    |  2 +
 modules/gui/qt/medialibrary/mlalbummodel.cpp  | 12 ++--
 modules/gui/qt/medialibrary/mlalbummodel.hpp  |  4 +-
 .../gui/qt/medialibrary/mlalbumtrackmodel.cpp | 12 ++--
 .../gui/qt/medialibrary/mlalbumtrackmodel.hpp |  4 +-
 modules/gui/qt/medialibrary/mlartistmodel.cpp | 12 ++--
 modules/gui/qt/medialibrary/mlartistmodel.hpp |  4 +-
 modules/gui/qt/medialibrary/mlbasemodel.cpp   | 33 ++++-----
 modules/gui/qt/medialibrary/mlbasemodel.hpp   | 33 ++++-----
 modules/gui/qt/medialibrary/mlgenremodel.cpp  |  9 +--
 modules/gui/qt/medialibrary/mlgenremodel.hpp  |  4 +-
 modules/gui/qt/medialibrary/mlqueryparams.cpp | 14 ++++
 modules/gui/qt/medialibrary/mlqueryparams.hpp | 68 +++++++++++++++++++
 .../gui/qt/medialibrary/mlrecentsmodel.cpp    |  8 +--
 .../gui/qt/medialibrary/mlrecentsmodel.hpp    |  4 +-
 .../qt/medialibrary/mlrecentsvideomodel.cpp   | 10 ++-
 .../qt/medialibrary/mlrecentsvideomodel.hpp   |  4 +-
 modules/gui/qt/medialibrary/mlurlmodel.cpp    | 10 +--
 modules/gui/qt/medialibrary/mlurlmodel.hpp    |  4 +-
 modules/gui/qt/medialibrary/mlvideomodel.cpp  | 15 ++--
 modules/gui/qt/medialibrary/mlvideomodel.hpp  |  4 +-
 21 files changed, 183 insertions(+), 87 deletions(-)
 create mode 100644 modules/gui/qt/medialibrary/mlqueryparams.cpp
 create mode 100644 modules/gui/qt/medialibrary/mlqueryparams.hpp

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index f327b81317..c158dae6eb 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -156,6 +156,8 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/medialibrary/mlhelper.cpp \
 	gui/qt/medialibrary/mlhelper.hpp \
 	gui/qt/medialibrary/mlqmltypes.hpp \
+	gui/qt/medialibrary/mlqueryparams.cpp \
+	gui/qt/medialibrary/mlqueryparams.hpp \
 	gui/qt/medialibrary/mlrecentsmodel.cpp \
 	gui/qt/medialibrary/mlrecentsmodel.hpp \
 	gui/qt/medialibrary/mlrecentsvideomodel.cpp \
diff --git a/modules/gui/qt/medialibrary/mlalbummodel.cpp b/modules/gui/qt/medialibrary/mlalbummodel.cpp
index 423081a0d0..6af6079975 100644
--- a/modules/gui/qt/medialibrary/mlalbummodel.cpp
+++ b/modules/gui/qt/medialibrary/mlalbummodel.cpp
@@ -88,13 +88,15 @@ QHash<int, QByteArray> MLAlbumModel::roleNames() const
     };
 }
 
-std::vector<std::unique_ptr<MLAlbum>> MLAlbumModel::fetch() const
+std::vector<std::unique_ptr<MLAlbum>> MLAlbumModel::fetch(const MLQueryParams &params) const
 {
+    auto queryParams = params.toCQueryParams();
+
     ml_unique_ptr<vlc_ml_album_list_t> album_list;
     if ( m_parent.id <= 0 )
-        album_list.reset( vlc_ml_list_albums(m_ml, &m_query_param ) );
+        album_list.reset( vlc_ml_list_albums(m_ml, &queryParams) );
     else
-        album_list.reset( vlc_ml_list_albums_of(m_ml, &m_query_param, m_parent.type, m_parent.id ) );
+        album_list.reset( vlc_ml_list_albums_of(m_ml, &queryParams, m_parent.type, m_parent.id ) );
     if ( album_list == nullptr )
         return {};
     std::vector<std::unique_ptr<MLAlbum>> res;
@@ -161,9 +163,9 @@ vlc_ml_sorting_criteria_t MLAlbumModel::roleToCriteria(int role) const
     }
 }
 
-size_t MLAlbumModel::countTotalElements() const
+size_t MLAlbumModel::countTotalElements(const MLQueryParams &params) const
 {
-    auto queryParams = m_query_param;
+    vlc_ml_query_params_t queryParams = params.toCQueryParams();
     queryParams.i_offset = 0;
     queryParams.i_nbResults = 0;
     if ( m_parent.id <= 0 )
diff --git a/modules/gui/qt/medialibrary/mlalbummodel.hpp b/modules/gui/qt/medialibrary/mlalbummodel.hpp
index 2ffe82c5ee..3aba91def7 100644
--- a/modules/gui/qt/medialibrary/mlalbummodel.hpp
+++ b/modules/gui/qt/medialibrary/mlalbummodel.hpp
@@ -58,8 +58,8 @@ public:
     Q_INVOKABLE QHash<int, QByteArray> roleNames() const override;
 
 private:
-    std::vector<std::unique_ptr<MLAlbum>> fetch() const override;
-    size_t countTotalElements() const override;
+    std::vector<std::unique_ptr<MLAlbum>> fetch(const MLQueryParams &params) const override;
+    size_t countTotalElements(const MLQueryParams &params) const override;
     vlc_ml_sorting_criteria_t roleToCriteria(int role) const override;
     vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override;
     QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override;
diff --git a/modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp b/modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp
index cd091129f0..e40d069884 100644
--- a/modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp
+++ b/modules/gui/qt/medialibrary/mlalbumtrackmodel.cpp
@@ -93,9 +93,9 @@ QHash<int, QByteArray> MLAlbumTrackModel::roleNames() const
     };
 }
 
-size_t MLAlbumTrackModel::countTotalElements() const
+size_t MLAlbumTrackModel::countTotalElements(const MLQueryParams &params) const
 {
-    auto queryParams = m_query_param;
+    auto queryParams = params.toCQueryParams();
     queryParams.i_offset = 0;
     queryParams.i_nbResults = 0;
     if ( m_parent.id <= 0 )
@@ -103,14 +103,16 @@ size_t MLAlbumTrackModel::countTotalElements() const
     return vlc_ml_count_media_of(m_ml, &queryParams, m_parent.type, m_parent.id );
 }
 
-std::vector<std::unique_ptr<MLAlbumTrack>> MLAlbumTrackModel::fetch() const
+std::vector<std::unique_ptr<MLAlbumTrack>> MLAlbumTrackModel::fetch(const MLQueryParams &params) const
 {
+    auto queryParams = params.toCQueryParams();
+
     ml_unique_ptr<vlc_ml_media_list_t> media_list;
 
     if ( m_parent.id <= 0 )
-        media_list.reset( vlc_ml_list_audio_media(m_ml, &m_query_param) );
+        media_list.reset( vlc_ml_list_audio_media(m_ml, &queryParams) );
     else
-        media_list.reset( vlc_ml_list_media_of(m_ml, &m_query_param, m_parent.type, m_parent.id ) );
+        media_list.reset( vlc_ml_list_media_of(m_ml, &queryParams, m_parent.type, m_parent.id ) );
     if ( media_list == nullptr )
         return {};
     std::vector<std::unique_ptr<MLAlbumTrack>> res;
diff --git a/modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp b/modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp
index 4289c58766..6fe867c319 100644
--- a/modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp
+++ b/modules/gui/qt/medialibrary/mlalbumtrackmodel.hpp
@@ -58,8 +58,8 @@ public:
     QHash<int, QByteArray> roleNames() const override;
 
 private:
-    std::vector<std::unique_ptr<MLAlbumTrack>> fetch() const override;
-    size_t countTotalElements() const override;
+    std::vector<std::unique_ptr<MLAlbumTrack>> fetch(const MLQueryParams &params) const override;
+    size_t countTotalElements(const MLQueryParams &params) const override;
     vlc_ml_sorting_criteria_t roleToCriteria(int role) const override;
     vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override;
     QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override;
diff --git a/modules/gui/qt/medialibrary/mlartistmodel.cpp b/modules/gui/qt/medialibrary/mlartistmodel.cpp
index a3f18f67f3..e264120cee 100644
--- a/modules/gui/qt/medialibrary/mlartistmodel.cpp
+++ b/modules/gui/qt/medialibrary/mlartistmodel.cpp
@@ -67,13 +67,15 @@ QHash<int, QByteArray> MLArtistModel::roleNames() const
     };
 }
 
-std::vector<std::unique_ptr<MLArtist>> MLArtistModel::fetch() const
+std::vector<std::unique_ptr<MLArtist>> MLArtistModel::fetch(const MLQueryParams &params) const
 {
+    auto queryParams = params.toCQueryParams();
+
     ml_unique_ptr<vlc_ml_artist_list_t> artist_list;
     if ( m_parent.id <= 0 )
-        artist_list.reset( vlc_ml_list_artists(m_ml, &m_query_param, false) );
+        artist_list.reset( vlc_ml_list_artists(m_ml, &queryParams, false) );
     else
-        artist_list.reset( vlc_ml_list_artist_of(m_ml, &m_query_param, m_parent.type, m_parent.id) );
+        artist_list.reset( vlc_ml_list_artist_of(m_ml, &queryParams, m_parent.type, m_parent.id) );
     if ( artist_list == nullptr )
         return {};
     std::vector<std::unique_ptr<MLArtist>> res;
@@ -82,9 +84,9 @@ std::vector<std::unique_ptr<MLArtist>> MLArtistModel::fetch() const
     return res;
 }
 
-size_t MLArtistModel::countTotalElements() const
+size_t MLArtistModel::countTotalElements(const MLQueryParams &params) const
 {
-    auto queryParams = m_query_param;
+    auto queryParams = params.toCQueryParams();
     queryParams.i_offset = 0;
     queryParams.i_nbResults = 0;
 
diff --git a/modules/gui/qt/medialibrary/mlartistmodel.hpp b/modules/gui/qt/medialibrary/mlartistmodel.hpp
index e85a9b9149..d0fe4d1baa 100644
--- a/modules/gui/qt/medialibrary/mlartistmodel.hpp
+++ b/modules/gui/qt/medialibrary/mlartistmodel.hpp
@@ -49,8 +49,8 @@ public:
     QHash<int, QByteArray> roleNames() const override;
 
 private:
-    std::vector<std::unique_ptr<MLArtist>> fetch() const override;
-    size_t countTotalElements() const override;
+    std::vector<std::unique_ptr<MLArtist>> fetch(const MLQueryParams &params) const override;
+    size_t countTotalElements(const MLQueryParams &params) const override;
     vlc_ml_sorting_criteria_t roleToCriteria(int role) const override;
     vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override;
     QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override;
diff --git a/modules/gui/qt/medialibrary/mlbasemodel.cpp b/modules/gui/qt/medialibrary/mlbasemodel.cpp
index f7f2e127e6..97c9341b1d 100644
--- a/modules/gui/qt/medialibrary/mlbasemodel.cpp
+++ b/modules/gui/qt/medialibrary/mlbasemodel.cpp
@@ -24,17 +24,14 @@
 MLBaseModel::MLBaseModel(QObject *parent)
     : QAbstractListModel(parent)
     , m_ml(nullptr)
-    , m_search_pattern_cstr( nullptr, &free )
     , m_ml_event_handle( nullptr, [this](vlc_ml_event_callback_t* cb ) {
             assert( m_ml != nullptr );
             vlc_ml_event_unregister_callback( m_ml, cb );
         })
     , m_need_reset( false )
 {
-    memset(&m_query_param, 0, sizeof(vlc_ml_query_params_t));
-    m_query_param.b_desc = false;
-    m_query_param.i_nbResults = 20; //FIXME: value for test
-    m_query_param.i_sort = VLC_ML_SORTING_DEFAULT;
+    m_sort = VLC_ML_SORTING_DEFAULT;
+    m_sort_desc = false;
 
     connect( this, &MLBaseModel::resetRequested, this, &MLBaseModel::onResetRequested );
 }
@@ -46,8 +43,8 @@ MLBaseModel::~MLBaseModel()
 void MLBaseModel::sortByColumn(QByteArray name, Qt::SortOrder order)
 {
     beginResetModel();
-    m_query_param.b_desc = (order == Qt::SortOrder::DescendingOrder);
-    m_query_param.i_sort = nameToCriteria(name);
+    m_sort_desc = (order == Qt::SortOrder::DescendingOrder);
+    m_sort = nameToCriteria(name);
     clear();
     endResetModel();
 }
@@ -143,26 +140,26 @@ const QString& MLBaseModel::searchPattern() const
 
 void MLBaseModel::setSearchPattern( const QString& pattern )
 {
+    QString patternToApply = pattern.length() < 3 ? nullptr : pattern;
+    if (patternToApply == m_search_pattern)
+        /* No changes */
+        return;
+
     beginResetModel();
-    if ( pattern.length() >= 3 )
-        m_search_pattern_cstr = vlc::wrap_cptr( strdup( qtu( pattern ) ) );
-    else
-        m_search_pattern_cstr.reset();
-    m_search_pattern = pattern;
-    m_query_param.psz_pattern = m_search_pattern_cstr.get();
+    m_search_pattern = patternToApply;
     clear();
     endResetModel();
 }
 
 Qt::SortOrder MLBaseModel::getSortOrder() const
 {
-    return m_query_param.b_desc ? Qt::SortOrder::DescendingOrder : Qt::SortOrder::AscendingOrder;
+    return m_sort_desc ? Qt::SortOrder::DescendingOrder : Qt::SortOrder::AscendingOrder;
 }
 
 void MLBaseModel::setSortOder(Qt::SortOrder order)
 {
     beginResetModel();
-    m_query_param.b_desc = (order == Qt::SortOrder::DescendingOrder);
+    m_sort_desc = (order == Qt::SortOrder::DescendingOrder);
     clear();
     endResetModel();
     emit sortOrderChanged();
@@ -170,13 +167,13 @@ void MLBaseModel::setSortOder(Qt::SortOrder order)
 
 const QString MLBaseModel::getSortCriteria() const
 {
-    return criteriaToName(m_query_param.i_sort);
+    return criteriaToName(m_sort);
 }
 
 void MLBaseModel::setSortCriteria(const QString& criteria)
 {
     beginResetModel();
-    m_query_param.i_sort = nameToCriteria(criteria.toUtf8());
+    m_sort = nameToCriteria(criteria.toUtf8());
     clear();
     endResetModel();
     emit sortCriteriaChanged();
@@ -185,7 +182,7 @@ void MLBaseModel::setSortCriteria(const QString& criteria)
 void MLBaseModel::unsetSortCriteria()
 {
     beginResetModel();
-    m_query_param.i_sort = VLC_ML_SORTING_DEFAULT;
+    m_sort = VLC_ML_SORTING_DEFAULT;
     clear();
     endResetModel();
     emit sortCriteriaChanged();
diff --git a/modules/gui/qt/medialibrary/mlbasemodel.hpp b/modules/gui/qt/medialibrary/mlbasemodel.hpp
index 1d2cb2233a..093e8c774f 100644
--- a/modules/gui/qt/medialibrary/mlbasemodel.hpp
+++ b/modules/gui/qt/medialibrary/mlbasemodel.hpp
@@ -32,6 +32,7 @@
 #include "medialib.hpp"
 #include <memory>
 #include "mlevent.hpp"
+#include "mlqueryparams.hpp"
 
 class MediaLib;
 
@@ -110,9 +111,9 @@ protected:
 
     vlc_medialibrary_t* m_ml;
     MediaLib* m_mediaLib;
-    mutable vlc_ml_query_params_t m_query_param;
-    std::unique_ptr<char, void(*)(void*)> m_search_pattern_cstr;
     QString m_search_pattern;
+    vlc_ml_sorting_criteria_t m_sort;
+    bool m_sort_desc;
 
     std::unique_ptr<vlc_ml_event_callback_t,
                     std::function<void(vlc_ml_event_callback_t*)>> m_ml_event_handle;
@@ -136,8 +137,8 @@ public:
         : MLBaseModel(parent)
         , m_initialized(false)
         , m_total_count(0)
+        , m_offset(0)
     {
-        m_query_param.i_nbResults = BatchSize;
     }
 
     int rowCount(const QModelIndex &parent = {}) const override
@@ -147,7 +148,8 @@ public:
 
         if ( m_initialized == false )
         {
-            m_total_count = countTotalElements();
+            MLQueryParams params{ m_search_pattern.toUtf8(), m_sort, m_sort_desc };
+            m_total_count = countTotalElements(params);
             m_initialized = true;
             emit countChanged( static_cast<unsigned int>(m_total_count) );
         }
@@ -157,7 +159,7 @@ public:
 
     void clear() override
     {
-        m_query_param.i_offset = 0;
+        m_offset = 0;
         m_initialized = false;
         m_total_count = 0;
         m_item_list.clear();
@@ -226,19 +228,17 @@ protected:
         if ( idx >= m_total_count )
             return nullptr;
 
-        if ( idx < m_query_param.i_offset ||  idx >= m_query_param.i_offset + m_item_list.size() )
+        if ( idx < m_offset ||  idx >= m_offset + m_item_list.size() )
         {
-            if (m_query_param.i_nbResults == 0)
-                m_query_param.i_offset = 0;
-            else
-                m_query_param.i_offset = idx - idx % m_query_param.i_nbResults;
-            m_item_list = fetch();
+            m_offset = idx - idx % BatchSize;
+            MLQueryParams params{ m_search_pattern.toUtf8(), m_sort, m_sort_desc, m_offset, BatchSize };
+            m_item_list = fetch(params);
         }
 
         //db has changed
-        if ( idx - m_query_param.i_offset >= m_item_list.size() || idx < m_query_param.i_offset )
+        if ( idx >= m_offset + m_item_list.size() || idx < m_offset )
             return nullptr;
-        return m_item_list[idx - m_query_param.i_offset].get();
+        return m_item_list[idx - m_offset].get();
     }
 
     virtual void onVlcMlEvent(const MLEvent &event) override
@@ -248,7 +248,7 @@ protected:
             case VLC_ML_EVENT_MEDIA_THUMBNAIL_GENERATED:
             {
                 if (event.media_thumbnail_generated.b_success) {
-                    int idx = static_cast<int>(m_query_param.i_offset);
+                    int idx = static_cast<int>(m_offset);
                     for ( const auto& it : m_item_list ) {
                         if (it->getId().id == event.media_thumbnail_generated.i_media_id) {
                             thumbnailUpdated(idx);
@@ -266,13 +266,14 @@ protected:
     }
 
 private:
-    virtual size_t countTotalElements() const = 0;
-    virtual std::vector<std::unique_ptr<T>> fetch() const = 0;
+    virtual size_t countTotalElements(const MLQueryParams &params) const = 0;
+    virtual std::vector<std::unique_ptr<T>> fetch(const MLQueryParams &params) const = 0;
     virtual void thumbnailUpdated( int ) {}
 
     mutable std::vector<std::unique_ptr<T>> m_item_list;
     mutable bool m_initialized;
     mutable size_t m_total_count;
+    mutable size_t m_offset; /* offset of m_item_list in the global list */
 };
 
 #endif // MLBASEMODEL_HPP
diff --git a/modules/gui/qt/medialibrary/mlgenremodel.cpp b/modules/gui/qt/medialibrary/mlgenremodel.cpp
index 339cd49384..9ae0186761 100644
--- a/modules/gui/qt/medialibrary/mlgenremodel.cpp
+++ b/modules/gui/qt/medialibrary/mlgenremodel.cpp
@@ -68,10 +68,11 @@ QHash<int, QByteArray> MLGenreModel::roleNames() const
     };
 }
 
-std::vector<std::unique_ptr<MLGenre>> MLGenreModel::fetch() const
+std::vector<std::unique_ptr<MLGenre>> MLGenreModel::fetch(const MLQueryParams &params) const
 {
+    auto queryParams = params.toCQueryParams();
     ml_unique_ptr<vlc_ml_genre_list_t> genre_list(
-        vlc_ml_list_genres(m_ml, &m_query_param)
+        vlc_ml_list_genres(m_ml, &queryParams)
     );
     if ( genre_list == nullptr )
         return {};
@@ -81,9 +82,9 @@ std::vector<std::unique_ptr<MLGenre>> MLGenreModel::fetch() const
     return res;
 }
 
-size_t MLGenreModel::countTotalElements() const
+size_t MLGenreModel::countTotalElements(const MLQueryParams &params) const
 {
-    auto queryParams = m_query_param;
+    auto queryParams = params.toCQueryParams();
     queryParams.i_offset = 0;
     queryParams.i_nbResults = 0;
     return vlc_ml_count_genres( m_ml, &queryParams );
diff --git a/modules/gui/qt/medialibrary/mlgenremodel.hpp b/modules/gui/qt/medialibrary/mlgenremodel.hpp
index 3bc4928c3c..33dc8c89db 100644
--- a/modules/gui/qt/medialibrary/mlgenremodel.hpp
+++ b/modules/gui/qt/medialibrary/mlgenremodel.hpp
@@ -52,8 +52,8 @@ public:
     QVariant data(const QModelIndex &index, int role) const override;
 
 private:
-    std::vector<std::unique_ptr<MLGenre>> fetch() const override;
-    size_t countTotalElements() const override;
+    std::vector<std::unique_ptr<MLGenre>> fetch(const MLQueryParams &params) const override;
+    size_t countTotalElements(const MLQueryParams &params) const override;
     void onVlcMlEvent(const MLEvent &event) override;
     void thumbnailUpdated(int idx) override;
     vlc_ml_sorting_criteria_t roleToCriteria(int role) const override;
diff --git a/modules/gui/qt/medialibrary/mlqueryparams.cpp b/modules/gui/qt/medialibrary/mlqueryparams.cpp
new file mode 100644
index 0000000000..8d0bc99e6d
--- /dev/null
+++ b/modules/gui/qt/medialibrary/mlqueryparams.cpp
@@ -0,0 +1,14 @@
+#include "mlqueryparams.hpp"
+
+vlc_ml_query_params_t MLQueryParams::toCQueryParams() const
+{
+    vlc_ml_query_params_t params;
+    params.psz_pattern = searchPatternUtf8.isNull()
+                       ? nullptr
+                       : searchPatternUtf8.constData();
+    params.i_nbResults = nbResults;
+    params.i_offset = offset;
+    params.i_sort = sort;
+    params.b_desc = desc;
+    return params;
+}
diff --git a/modules/gui/qt/medialibrary/mlqueryparams.hpp b/modules/gui/qt/medialibrary/mlqueryparams.hpp
new file mode 100644
index 0000000000..fc15e2095c
--- /dev/null
+++ b/modules/gui/qt/medialibrary/mlqueryparams.hpp
@@ -0,0 +1,68 @@
+/*****************************************************************************
+ * Copyright (C) 2020 VLC authors and VideoLAN
+ *
+ * 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 MLQUERYPARAMS_HPP
+#define MLQUREYPARAMS_HPP
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <QByteArray>
+#include "vlc_media_library.h"
+
+/**
+ * C++ owned version of vlc_ml_query_params_t, so that it can be moved or
+ * copied.
+ */
+class MLQueryParams
+{
+public:
+    MLQueryParams(QByteArray searchPatternUtf8, vlc_ml_sorting_criteria_t sort,
+                  bool desc, size_t index, size_t count)
+        : searchPatternUtf8(std::move(searchPatternUtf8))
+        , nbResults(count)
+        , offset(index)
+        , sort(sort)
+        , desc(desc)
+    {
+    }
+
+    MLQueryParams(QByteArray patternUtf8, vlc_ml_sorting_criteria_t sort,
+                  bool desc)
+        : MLQueryParams(std::move(patternUtf8), sort, desc, 0, 0)
+    {
+    }
+
+    /**
+     * Expose the MLQueryParams content to a vlc_ml_query_params_t.
+     *
+     * The returned value is valid as long as the MLQueryParams instance is
+     * alive.
+     */
+    vlc_ml_query_params_t toCQueryParams() const;
+
+private:
+    QByteArray searchPatternUtf8;
+    uint32_t nbResults;
+    uint32_t offset;
+    vlc_ml_sorting_criteria_t sort;
+    bool desc;
+};
+
+#endif
diff --git a/modules/gui/qt/medialibrary/mlrecentsmodel.cpp b/modules/gui/qt/medialibrary/mlrecentsmodel.cpp
index 5d0ce5bdde..8bd538d20c 100644
--- a/modules/gui/qt/medialibrary/mlrecentsmodel.cpp
+++ b/modules/gui/qt/medialibrary/mlrecentsmodel.cpp
@@ -79,10 +79,10 @@ void MLRecentsModel::clearHistory()
     vlc_ml_clear_history(m_ml);
 }
 
-std::vector<std::unique_ptr<MLRecentMedia> > MLRecentsModel::fetch() const
+std::vector<std::unique_ptr<MLRecentMedia> > MLRecentsModel::fetch(const MLQueryParams &params) const
 {
     std::vector<std::unique_ptr<MLRecentMedia>> res;
-    auto queryParams = m_query_param;
+    auto queryParams = params.toCQueryParams();
     if (m_numberOfItemsToShow >= 0)
     {
         if (queryParams.i_offset <= static_cast<uint32_t>(m_numberOfItemsToShow))
@@ -100,9 +100,9 @@ std::vector<std::unique_ptr<MLRecentMedia> > MLRecentsModel::fetch() const
     return res;
 }
 
-size_t MLRecentsModel::countTotalElements() const
+size_t MLRecentsModel::countTotalElements(const MLQueryParams &params) const
 {
-    auto queryParams = m_query_param;
+    auto queryParams = params.toCQueryParams();
     queryParams.i_offset = 0;
     queryParams.i_nbResults = m_numberOfItemsToShow;
     size_t realCount = vlc_ml_count_history( m_ml, &queryParams );
diff --git a/modules/gui/qt/medialibrary/mlrecentsmodel.hpp b/modules/gui/qt/medialibrary/mlrecentsmodel.hpp
index 171132b84a..1cd2e17abe 100644
--- a/modules/gui/qt/medialibrary/mlrecentsmodel.hpp
+++ b/modules/gui/qt/medialibrary/mlrecentsmodel.hpp
@@ -76,8 +76,8 @@ public:
     int getNumberOfItemsToShow() const;
 
 private:
-    std::vector<std::unique_ptr<MLRecentMedia>> fetch() const override;
-    size_t countTotalElements() const override;
+    std::vector<std::unique_ptr<MLRecentMedia>> fetch(const MLQueryParams &params) const override;
+    size_t countTotalElements(const MLQueryParams &params) const override;
     vlc_ml_sorting_criteria_t roleToCriteria( int /* role */ ) const override{
         return VLC_ML_SORTING_DEFAULT;
     }
diff --git a/modules/gui/qt/medialibrary/mlrecentsvideomodel.cpp b/modules/gui/qt/medialibrary/mlrecentsvideomodel.cpp
index 9c09945c50..643c351515 100644
--- a/modules/gui/qt/medialibrary/mlrecentsvideomodel.cpp
+++ b/modules/gui/qt/medialibrary/mlrecentsvideomodel.cpp
@@ -92,10 +92,11 @@ QHash<int, QByteArray> MLRecentsVideoModel::roleNames() const
     };
 }
 
-std::vector<std::unique_ptr<MLVideo> > MLRecentsVideoModel::fetch() const
+std::vector<std::unique_ptr<MLVideo> > MLRecentsVideoModel::fetch(const MLQueryParams &params) const
 {
+    auto queryParams = params.toCQueryParams();
     ml_unique_ptr<vlc_ml_media_list_t> media_list{ vlc_ml_list_history(
-                m_ml, &m_query_param ) };
+                m_ml, &queryParams ) };
     if ( media_list == nullptr )
         return {};
     std::vector<std::unique_ptr<MLVideo>> res;
@@ -109,10 +110,13 @@ std::vector<std::unique_ptr<MLVideo> > MLRecentsVideoModel::fetch() const
     return res;
 }
 
-size_t MLRecentsVideoModel::countTotalElements() const
+size_t MLRecentsVideoModel::countTotalElements(const MLQueryParams &params) const
 {
     // FIXME: countTotalElements() may not depend on fetch(), since the call to
     // fetch() depends on countTotalElements()
+
+    (void) params;
+
     if(numberOfItemsToShow == -1){
         return m_video_count;
     }
diff --git a/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp b/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp
index 0b8e4be0ab..9a68459d42 100644
--- a/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp
+++ b/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp
@@ -45,8 +45,8 @@ public:
     int numberOfItemsToShow = 10;
 
 private:
-    std::vector<std::unique_ptr<MLVideo>> fetch() const override;
-    size_t countTotalElements() const override;
+    std::vector<std::unique_ptr<MLVideo>> fetch(const MLQueryParams &params) const override;
+    size_t countTotalElements(const MLQueryParams &params) const override;
     vlc_ml_sorting_criteria_t roleToCriteria( int /* role */ ) const override{
         return VLC_ML_SORTING_DEFAULT;
     }
diff --git a/modules/gui/qt/medialibrary/mlurlmodel.cpp b/modules/gui/qt/medialibrary/mlurlmodel.cpp
index 4dd949adba..eb2f219d4b 100644
--- a/modules/gui/qt/medialibrary/mlurlmodel.cpp
+++ b/modules/gui/qt/medialibrary/mlurlmodel.cpp
@@ -72,19 +72,21 @@ void MLUrlModel::addAndPlay( const QString &url )
     });
 }
 
-size_t MLUrlModel::countTotalElements() const
+size_t MLUrlModel::countTotalElements(const MLQueryParams &params) const
 {
-    auto queryParams = m_query_param;
+    auto queryParams = params.toCQueryParams();
     queryParams.i_offset = 0;
     queryParams.i_nbResults = 0;
     auto s = vlc_ml_count_stream_history( m_ml, &queryParams );
     return s;
 }
 
-std::vector<std::unique_ptr<MLUrl>> MLUrlModel::fetch() const
+std::vector<std::unique_ptr<MLUrl>> MLUrlModel::fetch(const MLQueryParams &params) const
 {
+    auto queryParams = params.toCQueryParams();
+
     ml_unique_ptr<vlc_ml_media_list_t> media_list;
-    media_list.reset( vlc_ml_list_stream_history(m_ml, &m_query_param) );
+    media_list.reset( vlc_ml_list_stream_history(m_ml, &queryParams) );
     if ( media_list == nullptr )
         return {};
 
diff --git a/modules/gui/qt/medialibrary/mlurlmodel.hpp b/modules/gui/qt/medialibrary/mlurlmodel.hpp
index bbc3bdc173..1828f15c89 100644
--- a/modules/gui/qt/medialibrary/mlurlmodel.hpp
+++ b/modules/gui/qt/medialibrary/mlurlmodel.hpp
@@ -70,8 +70,8 @@ public:
     Q_INVOKABLE void addAndPlay( const QString& url );
 
 private:
-    std::vector<std::unique_ptr<MLUrl>> fetch() const override;
-    size_t countTotalElements() const override;
+    std::vector<std::unique_ptr<MLUrl>> fetch(const MLQueryParams &params) const override;
+    size_t countTotalElements(const MLQueryParams &params) const override;
     vlc_ml_sorting_criteria_t roleToCriteria(int role) const override;
     virtual void onVlcMlEvent( const MLEvent &event ) override;
 };
diff --git a/modules/gui/qt/medialibrary/mlvideomodel.cpp b/modules/gui/qt/medialibrary/mlvideomodel.cpp
index 63338b2f96..1e861d2714 100644
--- a/modules/gui/qt/medialibrary/mlvideomodel.cpp
+++ b/modules/gui/qt/medialibrary/mlvideomodel.cpp
@@ -92,10 +92,11 @@ QHash<int, QByteArray> MLVideoModel::roleNames() const
     };
 }
 
-std::vector<std::unique_ptr<MLVideo> > MLVideoModel::fetch() const
+std::vector<std::unique_ptr<MLVideo> > MLVideoModel::fetch(const MLQueryParams &params) const
 {
+    auto queryParams = params.toCQueryParams();
     ml_unique_ptr<vlc_ml_media_list_t> media_list{ vlc_ml_list_video_media(
-                m_ml, &m_query_param ) };
+                m_ml, &queryParams ) };
     if ( media_list == nullptr )
         return {};
     std::vector<std::unique_ptr<MLVideo>> res;
@@ -104,12 +105,12 @@ std::vector<std::unique_ptr<MLVideo> > MLVideoModel::fetch() const
     return res;
 }
 
-size_t MLVideoModel::countTotalElements() const
+size_t MLVideoModel::countTotalElements(const MLQueryParams &params) const
 {
-    vlc_ml_query_params_t params = m_query_param;
-    params.i_offset = 0;
-    params.i_nbResults = 0;
-    return vlc_ml_count_video_media(m_ml, &params);
+    auto queryParams = params.toCQueryParams();
+    queryParams.i_offset = 0;
+    queryParams.i_nbResults = 0;
+    return vlc_ml_count_video_media(m_ml, &queryParams);
 }
 
 vlc_ml_sorting_criteria_t MLVideoModel::roleToCriteria(int role) const
diff --git a/modules/gui/qt/medialibrary/mlvideomodel.hpp b/modules/gui/qt/medialibrary/mlvideomodel.hpp
index f373d26b6b..2d60df10b6 100644
--- a/modules/gui/qt/medialibrary/mlvideomodel.hpp
+++ b/modules/gui/qt/medialibrary/mlvideomodel.hpp
@@ -63,8 +63,8 @@ public:
     QHash<int, QByteArray> roleNames() const override;
 
 private:
-    std::vector<std::unique_ptr<MLVideo>> fetch() const override;
-    size_t countTotalElements() const override;
+    std::vector<std::unique_ptr<MLVideo>> fetch(const MLQueryParams &params) const override;
+    size_t countTotalElements(const MLQueryParams &params) const override;
     vlc_ml_sorting_criteria_t roleToCriteria(int role) const override;
     vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override;
     virtual void onVlcMlEvent( const MLEvent &event ) override;
-- 
2.29.2



More information about the vlc-devel mailing list