[vlc-devel] [PATCH 02/18] qt: add NetworkSourcesModel

Prince Gupta guptaprince8832 at gmail.com
Wed Sep 23 19:40:00 CEST 2020


model for available media sources
---
 modules/gui/qt/Makefile.am                    |   3 +
 modules/gui/qt/maininterface/mainui.cpp       |   2 +
 .../gui/qt/network/networksourcesmodel.cpp    | 151 ++++++++++++++++++
 .../gui/qt/network/networksourcesmodel.hpp    |  95 +++++++++++
 4 files changed, 251 insertions(+)
 create mode 100644 modules/gui/qt/network/networksourcesmodel.cpp
 create mode 100644 modules/gui/qt/network/networksourcesmodel.hpp

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 10b204f8b4..12d41fc14f 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -168,6 +168,8 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/menus/menus.cpp gui/qt/menus/menus.hpp \
 	gui/qt/network/networkdevicemodel.cpp \
 	gui/qt/network/networkdevicemodel.hpp \
+	gui/qt/network/networksourcesmodel.cpp \
+	gui/qt/network/networksourcesmodel.hpp \
 	gui/qt/network/networkmediamodel.cpp \
 	gui/qt/network/networkmediamodel.hpp \
 	gui/qt/network/networksourcelistener.cpp \
@@ -317,6 +319,7 @@ nodist_libqt_plugin_la_SOURCES = \
 	gui/qt/menus/qml_menu_wrapper.moc.cpp \
 	gui/qt/menus/menus.moc.cpp \
 	gui/qt/network/networkdevicemodel.moc.cpp \
+	gui/qt/network/networksourcesmodel.moc.cpp \
 	gui/qt/network/networkmediamodel.moc.cpp \
 	gui/qt/player/input_models.moc.cpp \
 	gui/qt/player/player_controller.moc.cpp \
diff --git a/modules/gui/qt/maininterface/mainui.cpp b/modules/gui/qt/maininterface/mainui.cpp
index 5d829123b3..2ce8b8d2af 100644
--- a/modules/gui/qt/maininterface/mainui.cpp
+++ b/modules/gui/qt/maininterface/mainui.cpp
@@ -31,6 +31,7 @@
 
 #include "network/networkmediamodel.hpp"
 #include "network/networkdevicemodel.hpp"
+#include "network/networksourcesmodel.hpp"
 
 #include "maininterface/main_interface.hpp"
 
@@ -165,6 +166,7 @@ void MainUI::registerQMLTypes()
         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<MlFoldersModel>( "org.videolan.medialib", 0, 1, "MLFolderModel");
 
         //expose base object, they aren't instanciable from QML side
diff --git a/modules/gui/qt/network/networksourcesmodel.cpp b/modules/gui/qt/network/networksourcesmodel.cpp
new file mode 100644
index 0000000000..15f20b5586
--- /dev/null
+++ b/modules/gui/qt/network/networksourcesmodel.cpp
@@ -0,0 +1,151 @@
+/*****************************************************************************
+ * 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 "networksourcesmodel.hpp"
+#include "networkmediamodel.hpp"
+
+#include "playlist/media.hpp"
+#include "playlist/playlist_controller.hpp"
+
+NetworkSourcesModel::NetworkSourcesModel( QObject* parent )
+    : QAbstractListModel( parent )
+    , m_ml( nullptr )
+{
+}
+
+QVariant NetworkSourcesModel::data( const QModelIndex& index, int role ) const
+{
+    if (!m_ctx)
+        return {};
+    auto idx = index.row();
+    if ( idx < 0 || (size_t)idx >= m_items.size() )
+        return {};
+    const auto& item = m_items[idx];
+    switch ( role )
+    {
+        case SOURCE_NAME:
+            return item.name;
+        case SOURCE_LONGNAME:
+            return item.longName;
+        case SOURCE_TYPE:
+            return idx == 0 ? TYPE_DUMMY : TYPE_SOURCE;
+        case SOURCE_ARTWORK:
+            return item.artworkUrl;
+        default:
+            return {};
+    }
+}
+
+QHash<int, QByteArray> NetworkSourcesModel::roleNames() const
+{
+    return {
+        { SOURCE_NAME, "name" },
+        { SOURCE_LONGNAME, "long_name" },
+        { SOURCE_TYPE, "type" },
+        { SOURCE_ARTWORK, "artwork" }
+    };
+}
+
+int NetworkSourcesModel::rowCount(const QModelIndex& parent) const
+{
+    if ( parent.isValid() )
+        return 0;
+    return getCount();
+}
+
+
+void NetworkSourcesModel::setCtx(QmlMainContext* ctx)
+{
+    if (ctx) {
+        m_ctx = ctx;
+        m_ml = vlc_ml_instance_get( m_ctx->getIntf() );
+    }
+    if (m_ctx) {
+        initializeMediaSources();
+    }
+    emit ctxChanged();
+}
+
+int NetworkSourcesModel::getCount() const
+{
+    assert( m_items.size() < INT32_MAX );
+    return static_cast<int>( m_items.size() );
+}
+
+QMap<QString, QVariant> NetworkSourcesModel::getDataAt(int idx)
+{
+    QMap<QString, QVariant> dataDict;
+    QHash<int,QByteArray> roles = roleNames();
+    for (auto role: roles.keys()) {
+        dataDict[roles[role]] = data(index(idx), role);
+    }
+    return dataDict;
+}
+
+bool NetworkSourcesModel::initializeMediaSources()
+{
+    auto libvlc = vlc_object_instance(m_ctx->getIntf());
+
+    if (!m_items.empty()) {
+        beginResetModel();
+        endResetModel();
+        emit countChanged();
+    }
+    m_items = {Item{}}; // dummy item that UI uses to add entry for "add a service"
+
+    auto provider = vlc_media_source_provider_Get( libvlc );
+
+    using SourceMetaPtr = std::unique_ptr<vlc_media_source_meta_list_t,
+                                          decltype( &vlc_media_source_meta_list_Delete )>;
+
+    SourceMetaPtr providerList( vlc_media_source_provider_List( provider, static_cast<services_discovery_category_e>(m_sdSource) ),
+                                &vlc_media_source_meta_list_Delete );
+    if ( providerList == nullptr )
+        return false;
+
+    auto nbProviders = vlc_media_source_meta_list_Count( providerList.get() );
+
+    beginResetModel();
+    for ( auto i = 0u; i < nbProviders; ++i )
+    {
+        auto meta = vlc_media_source_meta_list_Get( providerList.get(), i );
+
+        Item item;
+        item.name = qfu(meta->name);
+        item.longName = qfu(meta->longname);
+
+        if ( item.name.startsWith( "podcast" ) )
+        {
+            item.artworkUrl = QUrl::fromLocalFile(":/sidebar/podcast.svg");
+        }
+        else if ( item.name.startsWith("lua{") )
+        {
+            int i_head = item.name.indexOf( "sd='" ) + 4;
+            int i_tail = item.name.indexOf( '\'', i_head );
+            const QString iconName = QString( ":/sidebar/sd/%1.svg" ).arg( item.name.mid( i_head, i_tail - i_head ) );
+            item.artworkUrl = QFileInfo::exists( iconName ) ? QUrl::fromLocalFile( iconName )
+                                                            : QUrl::fromLocalFile( ":/sidebar/network.svg" );
+        }
+
+        m_items.push_back( std::move(item) );
+    }
+    endResetModel();
+    emit countChanged();
+
+    return m_items.empty() == false;
+}
diff --git a/modules/gui/qt/network/networksourcesmodel.hpp b/modules/gui/qt/network/networksourcesmodel.hpp
new file mode 100644
index 0000000000..f7b5bf4396
--- /dev/null
+++ b/modules/gui/qt/network/networksourcesmodel.hpp
@@ -0,0 +1,95 @@
+/*****************************************************************************
+ * 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 MLNetworkSourcesModel_HPP
+#define MLNetworkSourcesModel_HPP
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <QAbstractListModel>
+
+#include <vlc_media_library.h>
+#include <vlc_media_source.h>
+#include <vlc_threads.h>
+#include <vlc_cxx_helpers.hpp>
+
+#include <util/qml_main_context.hpp>
+#include "networksourcelistener.hpp"
+
+#include <memory>
+
+class NetworkSourcesModel : public QAbstractListModel
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QmlMainContext* ctx READ getCtx WRITE setCtx NOTIFY ctxChanged)
+    Q_PROPERTY(int count READ getCount NOTIFY countChanged)
+
+public:
+    enum Role {
+        SOURCE_NAME = Qt::UserRole + 1,
+        SOURCE_LONGNAME,
+        SOURCE_TYPE,
+        SOURCE_ARTWORK
+    };
+    Q_ENUM(Role);
+
+    enum ItemType {
+        TYPE_DUMMY = -1, // provided for UI for entry "Add a service"
+        TYPE_SOURCE = 0
+    };
+    Q_ENUM(ItemType);
+
+    NetworkSourcesModel( QObject* parent = nullptr );
+
+    QVariant data(const QModelIndex& index, int role) const override;
+    QHash<int, QByteArray> roleNames() const override;
+    int rowCount(const QModelIndex& parent) const override;
+
+    void setCtx(QmlMainContext* ctx);
+
+    inline QmlMainContext* getCtx() { return m_ctx; }
+
+    int getCount() const;
+
+    Q_INVOKABLE QMap<QString, QVariant> getDataAt(int index);
+
+signals:
+    void ctxChanged();
+    void countChanged();
+
+private:
+    struct Item
+    {
+        QString name;
+        QString longName;
+        QUrl artworkUrl;
+    };
+
+    bool initializeMediaSources();
+
+private:
+    std::vector<Item> m_items;
+    QmlMainContext* m_ctx = nullptr;
+    vlc_medialibrary_t* m_ml = nullptr;
+    services_discovery_category_e m_sdSource = services_discovery_category_e::SD_CAT_INTERNET;
+};
+
+#endif // MLNetworkSourcesModel_HPP
-- 
2.25.1



More information about the vlc-devel mailing list