mirror of https://code.videolan.org/videolan/vlc
qt: add NetworkSourcesModel
model for available media sources Signed-off-by: Pierre Lamot <pierre@videolabs.io>
This commit is contained in:
parent
4aacfd8529
commit
c1d75f7e71
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue