[vlc-commits] qt: allow MlFoldersModel to be instantiated from qml
Pierre Lamot
git at videolan.org
Thu Feb 20 13:56:42 CET 2020
vlc | branch: master | Pierre Lamot <pierre at videolabs.io> | Tue Feb 11 13:54:48 2020 +0100| [7bd41a00c115185126ea32c675ec8d27b4e1cb06] | committer: Jean-Baptiste Kempf
qt: allow MlFoldersModel to be instantiated from qml
MlFoldersModel did require a vlc_medialibrary_t instance in its constructor
which can't be provided from QML.
* A setMl accessor is kept to keep it easily usable from Qt native.
* provide named roles
* remove delete role in favor of the exposed function (doesn't makes sens to
remove an entry by setting one of its properties)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=7bd41a00c115185126ea32c675ec8d27b4e1cb06
---
.../qt/dialogs/preferences/simple_preferences.cpp | 7 +-
modules/gui/qt/maininterface/main_interface.cpp | 2 +
modules/gui/qt/medialibrary/mlfoldersmodel.cpp | 96 ++++++++++++++++------
modules/gui/qt/medialibrary/mlfoldersmodel.hpp | 30 +++++--
4 files changed, 99 insertions(+), 36 deletions(-)
diff --git a/modules/gui/qt/dialogs/preferences/simple_preferences.cpp b/modules/gui/qt/dialogs/preferences/simple_preferences.cpp
index 115186cbb1..3538693320 100644
--- a/modules/gui/qt/dialogs/preferences/simple_preferences.cpp
+++ b/modules/gui/qt/dialogs/preferences/simple_preferences.cpp
@@ -732,7 +732,8 @@ SPrefsPanel::SPrefsPanel( intf_thread_t *_p_intf, QWidget *_parent,
if ( vlc_ml_instance_get( p_intf ) != NULL )
{
- mlModel = new MlFoldersModel( vlc_ml_instance_get( p_intf ) , this );
+ mlModel = new MlFoldersModel( this );
+ mlModel->setMl( vlc_ml_instance_get( p_intf ) );
mlTableView = ui.entryPointsTV;
@@ -1529,7 +1530,7 @@ QWidget *SPrefsPanel::MLgenerateWidget( QModelIndex index , MlFoldersModel *mlf
wid->setLayout( layout );
connect( cb , &QPushButton::clicked, [=]( ) {
- mlf->setData( index , cb->isChecked() , MlFoldersModel::CustomCheckBoxRole);
+ mlf->setData( index , cb->isChecked() , MlFoldersModel::Banned);
} );
return wid;
}
@@ -1546,7 +1547,7 @@ QWidget *SPrefsPanel::MLgenerateWidget( QModelIndex index , MlFoldersModel *mlf
connect( pb , &QPushButton::clicked , [=]() {
- mlf->setData( index , {} , MlFoldersModel::CustomRemoveRole);
+ mlf->removeAt(index.row());
} );
return wid;
diff --git a/modules/gui/qt/maininterface/main_interface.cpp b/modules/gui/qt/maininterface/main_interface.cpp
index f843bab77b..98aaceb74f 100644
--- a/modules/gui/qt/maininterface/main_interface.cpp
+++ b/modules/gui/qt/maininterface/main_interface.cpp
@@ -51,6 +51,7 @@
#include "medialibrary/mlgenremodel.hpp"
#include "medialibrary/mlvideomodel.hpp"
#include "medialibrary/mlrecentsvideomodel.hpp"
+#include "medialibrary/mlfoldersmodel.hpp"
#include "util/recent_media_model.hpp"
#include "util/settings.hpp"
@@ -352,6 +353,7 @@ void MainInterface::createMainWidget( QSettings * )
qRegisterMetaType<NetworkTreeItem>();
qmlRegisterType<NetworkMediaModel>( "org.videolan.medialib", 0, 1, "NetworkMediaModel");
qmlRegisterType<NetworkDeviceModel>( "org.videolan.medialib", 0, 1, "NetworkDeviceModel");
+ qmlRegisterType<MlFoldersModel>( "org.videolan.medialib", 0, 1, "MLFolderModel");
//expose base object, they aren't instanciable from QML side
qmlRegisterType<MLAlbum>();
diff --git a/modules/gui/qt/medialibrary/mlfoldersmodel.cpp b/modules/gui/qt/medialibrary/mlfoldersmodel.cpp
index 4829918488..a672350bc6 100644
--- a/modules/gui/qt/medialibrary/mlfoldersmodel.cpp
+++ b/modules/gui/qt/medialibrary/mlfoldersmodel.cpp
@@ -19,24 +19,52 @@
#include "mlfoldersmodel.hpp"
#include <cassert>
-MlFoldersModel::MlFoldersModel( vlc_medialibrary_t *p_ml , QObject *parent )
+MlFoldersModel::MlFoldersModel( QObject *parent )
: QAbstractListModel( parent )
- ,m_ml( p_ml )
- ,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_ml_event_handle( nullptr , [this](vlc_ml_event_callback_t* cb ) {
+ if ( m_ml )
+ vlc_ml_event_unregister_callback( m_ml , cb );
+ })
{
- assert( p_ml );
connect( this , &MlFoldersModel::onMLEntryPointModified , this , &MlFoldersModel::update );
- m_ml_event_handle.reset( vlc_ml_event_register_callback( m_ml , onMlEvent , this ) );
+}
+
+MlFoldersModel::EntryPoint::EntryPoint( const vlc_ml_entry_point_t& entryPoint)
+ : mrl(entryPoint.psz_mrl)
+ , banned(entryPoint.b_banned)
+{
+}
+
+void MlFoldersModel::setCtx(QmlMainContext *ctx)
+{
+ if (ctx)
+ {
+ m_ctx = ctx;
+ setMl(vlc_ml_instance_get( m_ctx->getIntf() ));
+ }
+ else
+ {
+ m_ctx = nullptr;
+ setMl(nullptr);
+ }
+ emit ctxChanged();
+}
+
+void MlFoldersModel::setMl(vlc_medialibrary_t *ml)
+{
+ if (ml)
+ m_ml_event_handle.reset( vlc_ml_event_register_callback( ml , onMlEvent , this ) );
+ else
+ m_ml_event_handle.reset( nullptr );
+ m_ml = ml;
update();
}
int MlFoldersModel::rowCount( QModelIndex const & ) const
{
- return m_mrls.count();
+ return static_cast<int>(m_mrls.size());
}
+
int MlFoldersModel::columnCount( QModelIndex const & ) const
{
return 3;
@@ -49,13 +77,23 @@ QVariant MlFoldersModel::data( const QModelIndex &index ,
switch ( role )
{
case Qt::DisplayRole :
- if ( index.column() == 1 )
- return QVariant::fromValue( m_mrls[index.row()].toDisplayString( QUrl::RemovePassword | QUrl::PreferLocalFile | QUrl::NormalizePathSegments ) );
- break;
- case CustomCheckBoxRole :
- return ( index.row() %2 ) ? //TODO: if mrl banned?
- Qt::Checked : Qt::Unchecked;
- break;
+ {
+ if ( index.column() != 1 )
+ return {};
+ QUrl url = QUrl::fromUserInput(m_mrls[index.row()].mrl);
+ if (!url.isValid())
+ return {};
+ return QVariant::fromValue( url.toDisplayString( QUrl::RemovePassword | QUrl::PreferLocalFile | QUrl::NormalizePathSegments ) );
+ }
+ case DisplayUrl:
+ {
+ QUrl url = QUrl::fromUserInput(m_mrls[index.row()].mrl);
+ if (!url.isValid())
+ return {};
+ return QVariant::fromValue( url.toDisplayString( QUrl::RemovePassword | QUrl::PreferLocalFile | QUrl::NormalizePathSegments ) );
+ }
+ case Banned:
+ return m_mrls[index.row()].banned;
default :
return {};
}
@@ -65,7 +103,8 @@ QVariant MlFoldersModel::data( const QModelIndex &index ,
void MlFoldersModel::removeAt( int index )
{
- vlc_ml_remove_folder( m_ml , qtu( m_mrls[index].toString() ) );
+ assert(index < static_cast<int>(m_mrls.size()));
+ vlc_ml_remove_folder( m_ml , qtu( m_mrls[index].mrl ) );
}
void MlFoldersModel::add( QUrl mrl )
@@ -83,10 +122,9 @@ void MlFoldersModel::update()
vlc_ml_list_folder( m_ml , &entrypoints ); //TODO: get list of banned folders as well
for ( unsigned int i=0 ; i<entrypoints->i_nb_items ; i++ )
- m_mrls.append( QUrl::fromUserInput( entrypoints->p_items[i].psz_mrl ) );
+ m_mrls.emplace_back( entrypoints->p_items[i] );
endResetModel();
-
}
Qt::ItemFlags MlFoldersModel::flags ( const QModelIndex & index ) const {
@@ -97,22 +135,27 @@ Qt::ItemFlags MlFoldersModel::flags ( const QModelIndex & index ) const {
return defaultFlags;
}
+QHash<int, QByteArray> MlFoldersModel::roleNames() const
+{
+ return {
+ {DisplayUrl, "display_url"},
+ {Banned, "banned"},
+ };
+}
+
bool MlFoldersModel::setData( const QModelIndex &index ,
const QVariant &value , int role){
if( !index.isValid() )
return false;
- else if( role == CustomCheckBoxRole ){
+ else if( role == Banned ){
if( !value.toBool() ){
- vlc_ml_unban_folder(m_ml, qtu( m_mrls[index.row()].toString() ) );
+ vlc_ml_unban_folder(m_ml, qtu( m_mrls[index.row()].mrl ) );
}
else{
- vlc_ml_ban_folder( m_ml , qtu( m_mrls[index.row()].toString() ) );
+ vlc_ml_ban_folder( m_ml , qtu( m_mrls[index.row()].mrl ) );
}
}
- else if(role == CustomRemoveRole){
- removeAt( index.row() );
- }
return true;
}
@@ -122,7 +165,7 @@ void MlFoldersModel::onMlEvent( void* data , const vlc_ml_event_t* event )
if ( event->i_type == VLC_ML_EVENT_ENTRY_POINT_ADDED || event->i_type == VLC_ML_EVENT_ENTRY_POINT_REMOVED ||
event->i_type == VLC_ML_EVENT_ENTRY_POINT_UNBANNED || event->i_type == VLC_ML_EVENT_ENTRY_POINT_BANNED )
{
- emit self->onMLEntryPointModified();
+ emit self->onMLEntryPointModified( QPrivateSignal() );
}
}
@@ -145,3 +188,4 @@ void MlFoldersModel::onMlEvent( void* data , const vlc_ml_event_t* event )
}
return QVariant();
}
+
diff --git a/modules/gui/qt/medialibrary/mlfoldersmodel.hpp b/modules/gui/qt/medialibrary/mlfoldersmodel.hpp
index 8b8823a8ce..c5e23f1070 100644
--- a/modules/gui/qt/medialibrary/mlfoldersmodel.hpp
+++ b/modules/gui/qt/medialibrary/mlfoldersmodel.hpp
@@ -31,13 +31,20 @@
#include <QList>
#include "mlhelper.hpp"
+#include <util/qml_main_context.hpp>
#include <vlc_media_library.h>
class MlFoldersModel : public QAbstractListModel
{
Q_OBJECT
+ Q_PROPERTY(QmlMainContext* ctx READ getCtx WRITE setCtx NOTIFY ctxChanged)
+
public:
- MlFoldersModel( vlc_medialibrary_t *p_ml , QObject * parent = nullptr );
+ MlFoldersModel( QObject * parent = nullptr );
+
+ void setCtx(QmlMainContext* ctx);
+ inline QmlMainContext* getCtx() { return m_ctx; }
+ void setMl(vlc_medialibrary_t* ml);
int rowCount( QModelIndex const &parent = {} ) const override;
int columnCount (QModelIndex const &parent = {} ) const override;
@@ -46,6 +53,8 @@ public:
Qt::ItemFlags flags ( const QModelIndex & index ) const override;
+ QHash<int, QByteArray> roleNames() const override;
+
bool setData( const QModelIndex &index , const QVariant &value ,
int role ) override;
@@ -54,20 +63,27 @@ public:
enum Roles
{
- CustomCheckBoxRole = Qt::UserRole + 1,
- CustomRemoveRole
+ Banned = Qt::UserRole + 1,
+ DisplayUrl
};
private:
- QList<QUrl> m_mrls;
- vlc_medialibrary_t *m_ml;
+ struct EntryPoint {
+ EntryPoint(const vlc_ml_entry_point_t &entryPoint );
+ QString mrl;
+ bool banned;
+ };
+
+ std::vector<EntryPoint> m_mrls;
+ vlc_medialibrary_t *m_ml = nullptr;
+ QmlMainContext* m_ctx = nullptr;
using EventCallbackPtr = std::unique_ptr<vlc_ml_event_callback_t,
std::function<void( vlc_ml_event_callback_t* )>> ;
EventCallbackPtr m_ml_event_handle;
signals:
- void limitChanged();
- void onMLEntryPointModified();
+ void ctxChanged();
+ void onMLEntryPointModified(QPrivateSignal);
public slots:
void update();
More information about the vlc-commits
mailing list