vlc | branch: master | Prince Gupta <guptaprince8...@gmail.com> | Tue Sep 8 17:47:58 2020 +0530| [c1d75f7e71e9648633a5e21e969cc09d93abee92] | committer: Pierre Lamot
qt: add NetworkSourcesModel model for available media sources Signed-off-by: Pierre Lamot <pie...@videolabs.io> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c1d75f7e71e9648633a5e21e969cc09d93abee92 --- modules/gui/qt/Makefile.am | 3 + modules/gui/qt/maininterface/mainui.cpp | 2 + modules/gui/qt/network/networksourcesmodel.cpp | 151 +++++++++++++++++++++++++ modules/gui/qt/network/networksourcesmodel.hpp | 95 ++++++++++++++++ 4 files changed, 251 insertions(+) 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 _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits