[vlc-devel] [PATCH 6/9] qt: add RecentModel based on medialibrary model

Pierre Lamot pierre at videolabs.io
Thu Oct 15 11:25:09 CEST 2020


---
 modules/gui/qt/Makefile.am                    |   3 +
 modules/gui/qt/maininterface/mainui.cpp       |   9 ++
 .../gui/qt/medialibrary/mlrecentsmodel.cpp    | 133 ++++++++++++++++++
 .../gui/qt/medialibrary/mlrecentsmodel.hpp    |  90 ++++++++++++
 .../qt/medialibrary/mlrecentsvideomodel.hpp   |   6 +-
 5 files changed, 238 insertions(+), 3 deletions(-)
 create mode 100644 modules/gui/qt/medialibrary/mlrecentsmodel.cpp
 create mode 100644 modules/gui/qt/medialibrary/mlrecentsmodel.hpp

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 216aac80c0..f65b3ca6c5 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -155,6 +155,8 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/medialibrary/mlhelper.cpp \
 	gui/qt/medialibrary/mlhelper.hpp \
 	gui/qt/medialibrary/mlqmltypes.hpp \
+	gui/qt/medialibrary/mlrecentsmodel.cpp \
+	gui/qt/medialibrary/mlrecentsmodel.hpp \
 	gui/qt/medialibrary/mlrecentsvideomodel.cpp \
 	gui/qt/medialibrary/mlrecentsvideomodel.hpp \
 	gui/qt/medialibrary/mlurlmodel.cpp \
@@ -315,6 +317,7 @@ nodist_libqt_plugin_la_SOURCES = \
 	gui/qt/medialibrary/mlgenre.moc.cpp \
 	gui/qt/medialibrary/mlgenremodel.moc.cpp \
 	gui/qt/medialibrary/mlqmltypes.moc.cpp \
+	gui/qt/medialibrary/mlrecentsmodel.moc.cpp \
 	gui/qt/medialibrary/mlrecentsvideomodel.moc.cpp \
 	gui/qt/medialibrary/mlurlmodel.moc.cpp \
 	gui/qt/medialibrary/mlvideo.moc.cpp \
diff --git a/modules/gui/qt/maininterface/mainui.cpp b/modules/gui/qt/maininterface/mainui.cpp
index d17992484e..41a78da1be 100644
--- a/modules/gui/qt/maininterface/mainui.cpp
+++ b/modules/gui/qt/maininterface/mainui.cpp
@@ -10,6 +10,7 @@
 #include "medialibrary/mlgenremodel.hpp"
 #include "medialibrary/mlurlmodel.hpp"
 #include "medialibrary/mlvideomodel.hpp"
+#include "medialibrary/mlrecentsmodel.hpp"
 #include "medialibrary/mlrecentsvideomodel.hpp"
 #include "medialibrary/mlfoldersmodel.hpp"
 
@@ -168,6 +169,14 @@ void MainUI::registerQMLTypes()
         qmlRegisterType<MLVideoModel>( "org.videolan.medialib", 0, 1, "MLVideoModel" );
         qmlRegisterType<MLRecentsVideoModel>( "org.videolan.medialib", 0, 1, "MLRecentsVideoModel" );
 
+        qRegisterMetaType<NetworkTreeItem>();
+        qmlRegisterType<NetworkMediaModel>( "org.videolan.medialib", 0, 1, "NetworkMediaModel");
+        qmlRegisterType<NetworkDeviceModel>( "org.videolan.medialib", 0, 1, "NetworkDeviceModel");
+        qmlRegisterType<NetworkSourcesModel>( "org.videolan.medialib", 0, 1, "NetworkSourcesModel");
+        qmlRegisterType<ServicesDiscoveryModel>( "org.videolan.medialib", 0, 1, "ServicesDiscoveryModel");
+        qmlRegisterType<MlFoldersModel>( "org.videolan.medialib", 0, 1, "MLFolderModel");
+        qmlRegisterType<MLRecentsModel>( "org.videolan.medialib", 0, 1, "MLRecentModel" );
+
         //expose base object, they aren't instanciable from QML side
         registerAnonymousType<MLAlbum>("org.videolan.medialib", 1);
         registerAnonymousType<MLArtist>("org.videolan.medialib", 1);
diff --git a/modules/gui/qt/medialibrary/mlrecentsmodel.cpp b/modules/gui/qt/medialibrary/mlrecentsmodel.cpp
new file mode 100644
index 0000000000..3b1ef5ffa9
--- /dev/null
+++ b/modules/gui/qt/medialibrary/mlrecentsmodel.cpp
@@ -0,0 +1,133 @@
+/*****************************************************************************
+ * 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.
+ *****************************************************************************/
+
+#include "mlrecentsmodel.hpp"
+#include <QDateTime>
+
+MLRecentMedia::MLRecentMedia( const vlc_ml_media_t *media )
+    : m_id (media->i_id, VLC_ML_PARENT_UNKNOWN)
+    , m_url ( media->p_files->i_nb_items > 0 ? media->p_files->p_items[0].psz_mrl : "" )
+    , m_lastPlayedDate(QDateTime::fromTime_t( media->i_last_played_date ))
+{
+}
+
+MLRecentMedia::MLRecentMedia( const MLRecentMedia& media )
+    : m_id(media.m_id)
+    , m_url(media.m_url)
+    , m_lastPlayedDate(media.m_lastPlayedDate)
+{
+}
+
+MLRecentMedia* MLRecentMedia::clone() const {
+    return new MLRecentMedia( *this );
+}
+
+
+MLRecentsModel::MLRecentsModel( QObject* parent )
+    : MLSlidingWindowModel<MLRecentMedia>( parent )
+{
+}
+
+QVariant MLRecentsModel::data( const QModelIndex& index , int role ) const
+{
+    if (!index.isValid() || index.row() < 0)
+        return QVariant();
+
+    const MLRecentMedia* media = item(index.row());
+    if ( !media )
+        return QVariant();
+
+    switch (role)
+    {
+    case RECENT_MEDIA_ID:
+        return QVariant::fromValue( media->getId() );
+    case RECENT_MEDIA_URL:
+        return QVariant::fromValue( media->getUrl().toString(QUrl::PreferLocalFile | QUrl::RemovePassword));
+    case RECENT_MEDIA_LAST_PLAYED_DATE:
+        return QVariant::fromValue( media->getLastPlayedDate().toString( QLocale::system().dateFormat( QLocale::ShortFormat )));
+    default :
+        return QVariant();
+    }
+}
+
+QHash<int, QByteArray> MLRecentsModel::roleNames() const
+{
+    return {
+        { RECENT_MEDIA_ID, "id" },
+        { RECENT_MEDIA_URL, "url" },
+        { RECENT_MEDIA_LAST_PLAYED_DATE, "last_played_date" }
+    };
+}
+
+void MLRecentsModel::clearHistory()
+{
+    vlc_ml_clear_history(m_ml);
+}
+
+std::vector<std::unique_ptr<MLRecentMedia> > MLRecentsModel::fetch()
+{
+    std::vector<std::unique_ptr<MLRecentMedia>> res;
+    auto queryParams = m_query_param;
+    if (m_numberOfItemsToShow >= 0)
+    {
+        if (queryParams.i_offset <= static_cast<uint32_t>(m_numberOfItemsToShow))
+           queryParams.i_nbResults = static_cast<uint32_t>(m_numberOfItemsToShow) - queryParams.i_offset;
+        else
+            return res;
+    }
+
+    ml_unique_ptr<vlc_ml_media_list_t> media_list{ vlc_ml_list_history(
+                m_ml, &queryParams ) };
+    if ( media_list == nullptr )
+        return {};
+    for( vlc_ml_media_t &media: ml_range_iterate<vlc_ml_media_t>( media_list ) )
+        res.emplace_back( std::make_unique<MLRecentMedia>( &media ) );
+    return res;
+}
+
+size_t MLRecentsModel::countTotalElements() const
+{
+    auto queryParams = m_query_param;
+    queryParams.i_offset = 0;
+    queryParams.i_nbResults = m_numberOfItemsToShow;
+    size_t realCount = vlc_ml_count_history( m_ml, &queryParams );
+    if (m_numberOfItemsToShow >= 0)
+        return std::min( realCount, static_cast<size_t>(m_numberOfItemsToShow) );
+    return realCount;
+}
+
+void MLRecentsModel::onVlcMlEvent( const vlc_ml_event_t* event )
+{
+    switch ( event->i_type )
+    {
+        case VLC_ML_EVENT_MEDIA_ADDED:
+        case VLC_ML_EVENT_MEDIA_UPDATED:
+        case VLC_ML_EVENT_MEDIA_DELETED:
+            m_need_reset = true;
+            break;
+        default:
+            break;
+    }
+    MLBaseModel::onVlcMlEvent( event );
+}
+void MLRecentsModel::setNumberOfItemsToShow( int n ){
+    m_numberOfItemsToShow = n;
+}
+int MLRecentsModel::getNumberOfItemsToShow() const {
+    return m_numberOfItemsToShow;
+}
diff --git a/modules/gui/qt/medialibrary/mlrecentsmodel.hpp b/modules/gui/qt/medialibrary/mlrecentsmodel.hpp
new file mode 100644
index 0000000000..6feb7da3da
--- /dev/null
+++ b/modules/gui/qt/medialibrary/mlrecentsmodel.hpp
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * 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 ML_RECENTS_MODEL_H
+#define ML_RECENTS_MODEL_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_media_library.h>
+
+#include "mlbasemodel.hpp"
+#include "mlvideo.hpp"
+
+#include <QObject>
+#include <QDateTime>
+
+class MLRecentMedia {
+public:
+    MLRecentMedia( const vlc_ml_media_t *_data );
+
+    MLRecentMedia( const MLRecentMedia& url );
+
+    inline QUrl getUrl() const { return m_url; }
+    inline QDateTime getLastPlayedDate() const { return m_lastPlayedDate; }
+    inline MLParentId getId() const { return m_id; }
+
+    MLRecentMedia *clone() const;
+
+private:
+    MLParentId m_id;
+    QUrl m_url;
+    QDateTime m_lastPlayedDate;
+};
+
+class MLRecentsModel : public MLSlidingWindowModel<MLRecentMedia>
+{
+    Q_OBJECT
+    Q_PROPERTY(int numberOfItemsToShow READ getNumberOfItemsToShow WRITE setNumberOfItemsToShow)
+
+public:
+    enum Roles {
+        RECENT_MEDIA_ID = Qt::UserRole + 1,
+        RECENT_MEDIA_URL,
+        RECENT_MEDIA_LAST_PLAYED_DATE
+    };
+    Q_ENUM(Roles)
+
+    explicit MLRecentsModel( QObject* parent = nullptr );
+    virtual ~MLRecentsModel() = default;
+
+    QVariant data( const QModelIndex& index , int role ) const override;
+    QHash<int, QByteArray> roleNames() const override;
+    int m_numberOfItemsToShow = -1;
+
+    Q_INVOKABLE void clearHistory();
+
+    void setNumberOfItemsToShow(int);
+    int getNumberOfItemsToShow() const;
+
+private:
+    std::vector<std::unique_ptr<MLRecentMedia>> fetch() override;
+    size_t countTotalElements() const override;
+    vlc_ml_sorting_criteria_t roleToCriteria( int /* role */ ) const override{
+        return VLC_ML_SORTING_DEFAULT;
+    }
+    vlc_ml_sorting_criteria_t nameToCriteria( QByteArray /* name */ ) const override{
+        return VLC_ML_SORTING_DEFAULT;
+    }
+    virtual void onVlcMlEvent( const vlc_ml_event_t* event ) override;
+};
+
+#endif // ML_RECENTS_MODEL_H
diff --git a/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp b/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp
index 055eecf174..ef6e473ae6 100644
--- a/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp
+++ b/modules/gui/qt/medialibrary/mlrecentsvideomodel.hpp
@@ -16,8 +16,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-#ifndef MCRECENTSMODEL_H
-#define MCRECENTSMODEL_H
+#ifndef ML_RECENTS_VIDEO_MODEL_H
+#define ML_RECENTS_VIDEO_MODEL_H
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -59,4 +59,4 @@ private:
     int m_video_count;
 };
 
-#endif // MCRECENTSMODEL_H
+#endif // ML_RECENTS_VIDEO_MODEL_H
-- 
2.25.1



More information about the vlc-devel mailing list