[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