[vlc-commits] qt: improve interface of MLFoldersModel

Prince Gupta git at videolan.org
Mon Mar 1 10:40:17 UTC 2021


vlc | branch: master | Prince Gupta <guptaprince8832 at gmail.com> | Tue Feb 23 15:54:01 2021 +0530| [86eab699f1cb4deb0b2515fb2b0d8a4108c32600] | committer: Pierre Lamot

qt: improve interface of MLFoldersModel

Signed-off-by: Pierre Lamot <pierre at videolabs.io>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=86eab699f1cb4deb0b2515fb2b0d8a4108c32600
---

 .../qt/dialogs/preferences/simple_preferences.cpp  |  47 +++----
 .../qt/dialogs/preferences/simple_preferences.hpp  |   4 +-
 modules/gui/qt/maininterface/mainui.cpp            |   4 +-
 modules/gui/qt/medialibrary/mlfoldersmodel.cpp     | 145 +++++++--------------
 modules/gui/qt/medialibrary/mlfoldersmodel.hpp     |  65 ++++-----
 5 files changed, 103 insertions(+), 162 deletions(-)

diff --git a/modules/gui/qt/dialogs/preferences/simple_preferences.cpp b/modules/gui/qt/dialogs/preferences/simple_preferences.cpp
index adf40d8fc9..477d258345 100644
--- a/modules/gui/qt/dialogs/preferences/simple_preferences.cpp
+++ b/modules/gui/qt/dialogs/preferences/simple_preferences.cpp
@@ -30,6 +30,7 @@
 #include "preferences_widgets.hpp"
 #include "maininterface/main_interface.hpp"
 #include "util/color_scheme_model.hpp"
+#include "util/proxycolumnmodel.hpp"
 
 #include <vlc_config_cat.h>
 #include <vlc_configuration.h>
@@ -976,7 +977,7 @@ SPrefsPanel::SPrefsPanel( intf_thread_t *_p_intf, QWidget *_parent,
 
                 if ( vlc_ml_instance_get( p_intf ) != NULL )
                 {
-                    mlModel = new MlFoldersModel( this );
+                    mlModel = new ProxyColumnModel<MLFoldersModel>(1, {{0, qtr("Path")}, {1, qtr("Remove")}}, this );
                     mlModel->setMl( vlc_ml_instance_get( p_intf ) );
 
                     mlTableView = ui.entryPointsTV;
@@ -1564,28 +1565,8 @@ void SPrefsPanel::MLaddNewEntryPoint( ){
         mlModel->add( newEntryPoints );
 }
 
-QWidget *SPrefsPanel::MLgenerateWidget( QModelIndex index , MlFoldersModel *mlf , QWidget *parent){
-    if ( index.column() == 0 ){
-
-        QWidget *wid = new QWidget( parent );
-
-        QBoxLayout* layout = new QBoxLayout( QBoxLayout::LeftToRight , wid );
-
-        QCheckBox*cb = new QCheckBox( wid );
-        cb->setFixedSize( 16 , 16 );
-
-        //cb->setChecked(mlf->data(index, MlFoldersModel::CustomCheckBoxRole).toBool()); //TODO: disable banning till un-banning works
-        cb->setEnabled( false );
-
-        layout->addWidget( cb , Qt::AlignCenter );
-        wid->setLayout( layout );
-
-        connect( cb , &QPushButton::clicked, [=]( ) {
-            mlf->setData( index , cb->isChecked() , MlFoldersModel::Banned);
-        } );
-        return wid;
-    }
-    else if ( index.column( ) == 2 ){
+QWidget *SPrefsPanel::MLgenerateWidget( QModelIndex index , MLFoldersModel *mlf , QWidget *parent){
+    if ( index.column( ) == 1 ){
         QWidget *wid = new QWidget( parent );
 
         QBoxLayout* layout = new QBoxLayout( QBoxLayout::LeftToRight , wid );
@@ -1608,17 +1589,21 @@ QWidget *SPrefsPanel::MLgenerateWidget( QModelIndex index , MlFoldersModel *mlf
 }
 
 void SPrefsPanel::MLdrawControls( ) {
-  for ( int col = 0 ; col < mlModel->columnCount( ) ; col++ )
-    for (int row = 0 ; row < mlModel->rowCount() ; row++ )
-      {
-    QModelIndex index = mlModel->index ( row , col );
-    mlTableView->setIndexWidget ( index, MLgenerateWidget ( index, mlModel,
-                               mlTableView ) );
-      }
+
+    const auto model = mlTableView->model();
+    for ( int col = 0 ; col < model->columnCount( model->index(0, 0) ) ; col++ )
+    {
+        for (int row = 0 ; row < model->rowCount() ; row++ )
+        {
+            QModelIndex index = model->index ( row , col );
+            mlTableView->setIndexWidget ( index, MLgenerateWidget ( index, mlModel,
+                                       mlTableView ) );
+        }
+    }
 
   mlTableView->resizeColumnsToContents( );
   mlTableView->horizontalHeader()->setMinimumSectionSize( 100 );
-  mlTableView->horizontalHeader()->setSectionResizeMode( 1 , QHeaderView::Stretch );
+  mlTableView->horizontalHeader()->setSectionResizeMode( 0 , QHeaderView::Stretch );
 
   mlTableView->horizontalHeader()->setFixedHeight( 24 );
 }
diff --git a/modules/gui/qt/dialogs/preferences/simple_preferences.hpp b/modules/gui/qt/dialogs/preferences/simple_preferences.hpp
index 85b2b6e069..da7a4e9a0d 100644
--- a/modules/gui/qt/dialogs/preferences/simple_preferences.hpp
+++ b/modules/gui/qt/dialogs/preferences/simple_preferences.hpp
@@ -116,7 +116,7 @@ private:
 
     char *lang;
 
-    MlFoldersModel *mlModel;
+    MLFoldersModel *mlModel;
     QTableView * mlTableView;
 
 #ifdef _WIN32
@@ -137,7 +137,7 @@ private slots:
     void saveAsso();
 #endif
     void MLaddNewEntryPoint( );
-    QWidget * MLgenerateWidget( QModelIndex index , MlFoldersModel *mlf , QWidget *parent );
+    QWidget * MLgenerateWidget( QModelIndex index , MLFoldersModel *mlf , QWidget *parent );
     void MLdrawControls( );
 
     void configML();
diff --git a/modules/gui/qt/maininterface/mainui.cpp b/modules/gui/qt/maininterface/mainui.cpp
index 61bfc50e2e..84b9c7a457 100644
--- a/modules/gui/qt/maininterface/mainui.cpp
+++ b/modules/gui/qt/maininterface/mainui.cpp
@@ -180,7 +180,7 @@ void MainUI::registerQMLTypes()
         qmlRegisterType<NetworkDeviceModel>( "org.videolan.medialib", 0, 1, "NetworkDeviceModel");
         qmlRegisterType<NetworkSourcesModel>( "org.videolan.medialib", 0, 1, "NetworkSourcesModel");
         qmlRegisterType<ServicesDiscoveryModel>( "org.videolan.medialib", 0, 1, "ServicesDiscoveryModel");
-        qmlRegisterType<MlFoldersModel>( "org.videolan.medialib", 0, 1, "MLFolderModel");
+        qmlRegisterType<MLFoldersModel>( "org.videolan.medialib", 0, 1, "MLFolderModel");
         qmlRegisterType<MLRecentsModel>( "org.videolan.medialib", 0, 1, "MLRecentModel" );
 
         //expose base object, they aren't instanciable from QML side
@@ -205,7 +205,7 @@ void MainUI::registerQMLTypes()
     qmlRegisterType<NetworkDeviceModel>( "org.videolan.vlc", 0, 1, "NetworkDeviceModel");
     qmlRegisterType<NetworkSourcesModel>( "org.videolan.vlc", 0, 1, "NetworkSourcesModel");
     qmlRegisterType<ServicesDiscoveryModel>( "org.videolan.vlc", 0, 1, "ServicesDiscoveryModel");
-    qmlRegisterType<MlFoldersModel>( "org.videolan.vlc", 0, 1, "MLFolderModel");
+    qmlRegisterType<MLFoldersModel>( "org.videolan.vlc", 0, 1, "MLFolderModel");
     qmlRegisterType<ImageLuminanceExtractor>( "org.videolan.vlc", 0, 1, "ImageLuminanceExtractor");
 
     qmlRegisterUncreatableType<NavigationHistory>("org.videolan.vlc", 0, 1, "History", "Type of global variable history" );
diff --git a/modules/gui/qt/medialibrary/mlfoldersmodel.cpp b/modules/gui/qt/medialibrary/mlfoldersmodel.cpp
index 984eb57b01..2ac1aa3f99 100644
--- a/modules/gui/qt/medialibrary/mlfoldersmodel.cpp
+++ b/modules/gui/qt/medialibrary/mlfoldersmodel.cpp
@@ -19,23 +19,23 @@
 #include "mlfoldersmodel.hpp"
 #include <cassert>
 
-MlFoldersModel::MlFoldersModel( QObject *parent )
+MLFoldersBaseModel::MLFoldersBaseModel( QObject *parent )
     : QAbstractListModel( parent )
     , m_ml_event_handle( nullptr , [this](vlc_ml_event_callback_t* cb ) {
         if ( m_ml )
             vlc_ml_event_unregister_callback( m_ml , cb );
     })
 {
-    connect( this , &MlFoldersModel::onMLEntryPointModified , this , &MlFoldersModel::update );
+    connect( this , &MLFoldersBaseModel::onMLEntryPointModified , this , &MLFoldersBaseModel::update );
 }
 
-MlFoldersModel::EntryPoint::EntryPoint( const vlc_ml_entry_point_t& entryPoint)
+MLFoldersBaseModel::EntryPoint::EntryPoint( const vlc_ml_entry_point_t& entryPoint)
     : mrl(entryPoint.psz_mrl)
     , banned(entryPoint.b_banned)
 {
 }
 
-void MlFoldersModel::setCtx(QmlMainContext *ctx)
+void MLFoldersBaseModel::setCtx(QmlMainContext *ctx)
 {
     if (ctx)
     {
@@ -50,7 +50,7 @@ void MlFoldersModel::setCtx(QmlMainContext *ctx)
     emit ctxChanged();
 }
 
-void MlFoldersModel::setMl(vlc_medialibrary_t *ml)
+void MLFoldersBaseModel::setMl(vlc_medialibrary_t *ml)
 {
     if (ml)
         m_ml_event_handle.reset( vlc_ml_event_register_callback( ml , onMlEvent , this ) );
@@ -60,31 +60,23 @@ void MlFoldersModel::setMl(vlc_medialibrary_t *ml)
     update();
 }
 
-int MlFoldersModel::rowCount( QModelIndex const & ) const
+int MLFoldersBaseModel::rowCount( QModelIndex const & ) const
 {
     return static_cast<int>(m_mrls.size());
 }
 
-int MlFoldersModel::columnCount( QModelIndex const & ) const
-{
-    return 3;
-}
-
-QVariant MlFoldersModel::data( const QModelIndex &index ,
+QVariant MLFoldersBaseModel::data( const QModelIndex &index ,
                               int role) const {
-    if ( index.isValid() )
+    if ( !index.isValid() )
+        return {};
+
+    switch ( role )
     {
-        switch ( role )
-        {
-        case Qt::DisplayRole :
-        {
-            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 Banned:
+            return m_mrls[index.row()].banned;
+        case MRL:
+            return m_mrls[index.row()].mrl;
+        case Qt::DisplayRole:
         case DisplayUrl:
         {
             QUrl url = QUrl::fromUserInput(m_mrls[index.row()].mrl);
@@ -92,101 +84,58 @@ QVariant MlFoldersModel::data( const QModelIndex &index ,
                 return {};
             return QVariant::fromValue( url.toDisplayString( QUrl::RemovePassword | QUrl::PreferLocalFile | QUrl::NormalizePathSegments ) );
         }
-        case Banned:
-            return m_mrls[index.row()].banned;
         default :
             return {};
-        }
     }
-    return {};
 }
 
-void MlFoldersModel::removeAt( int index )
+QHash<int, QByteArray> MLFoldersBaseModel::roleNames() const
 {
-    assert(index  < static_cast<int>(m_mrls.size()));
-    vlc_ml_remove_folder( m_ml , qtu( m_mrls[index].mrl ) );
+    return {
+        {DisplayUrl, "display_url"},
+        {Banned, "banned"},
+    };
 }
 
-void MlFoldersModel::add( QUrl mrl )
+void MLFoldersBaseModel::update()
 {
-    vlc_ml_add_folder( m_ml , qtu( mrl.toString( QUrl::None ) ) );
+    beginResetModel();
+    m_mrls = entryPoints();
+    endResetModel();
 }
 
-void MlFoldersModel::update()
+void MLFoldersBaseModel::onMlEvent( void* data , const vlc_ml_event_t* event )
 {
-    beginResetModel();
-
-    m_mrls.clear();
+    auto self = static_cast<MLFoldersBaseModel *>( data );
+    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( QPrivateSignal() );
+    }
+}
 
-    vlc_ml_entry_point_list_t * entrypoints;
-    vlc_ml_list_folder( m_ml , &entrypoints ); //TODO: get list of banned folders as well
+std::vector<MLFoldersBaseModel::EntryPoint> MLFoldersModel::entryPoints() const
+{
+    std::vector<MLFoldersBaseModel::EntryPoint> r;
 
+    vlc_ml_entry_point_list_t * entrypoints = nullptr;
+    vlc_ml_list_folder( ml() , &entrypoints );
     for ( unsigned int i=0 ; i<entrypoints->i_nb_items ; i++ )
-        m_mrls.emplace_back( entrypoints->p_items[i] );
-
+        r.emplace_back( entrypoints->p_items[i] );
     vlc_ml_release(entrypoints);
 
-    endResetModel();
+    return r;
 }
 
-Qt::ItemFlags MlFoldersModel::flags ( const QModelIndex & index ) const {
-    Qt::ItemFlags defaultFlags = QAbstractListModel::flags( index );
-    if ( index.isValid() ){
-        return defaultFlags;
-    }
-    return defaultFlags;
-}
-
-QHash<int, QByteArray> MlFoldersModel::roleNames() const
+void MLFoldersModel::removeAt( int index )
 {
-    return {
-        {DisplayUrl, "display_url"},
-        {Banned, "banned"},
-    };
+    assert(index < rowCount());
+    const QModelIndex idx = this->index( index, 0 );
+    if (idx.isValid())
+        vlc_ml_remove_folder( ml() , qtu( data( idx, MLFoldersBaseModel::MRL ).value<QString>() ) );
 }
 
-bool MlFoldersModel::setData( const QModelIndex &index ,
-                                const QVariant &value , int role){
-    if( !index.isValid() )
-        return false;
-
-    else if( role == Banned ){
-        if( !value.toBool() ){
-            vlc_ml_unban_folder(m_ml, qtu( m_mrls[index.row()].mrl ) );
-        }
-        else{
-            vlc_ml_ban_folder( m_ml , qtu( m_mrls[index.row()].mrl ) );
-        }
-    }
-
-    return true;
-}
-void MlFoldersModel::onMlEvent( void* data , const vlc_ml_event_t* event )
+void MLFoldersModel::add(const QUrl &mrl )
 {
-    auto self = static_cast<MlFoldersModel*>( data );
-    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( QPrivateSignal() );
-    }
+    vlc_ml_add_folder( ml() , qtu( mrl.toString( QUrl::None ) ) );
 }
-
- QVariant MlFoldersModel::headerData( int section , Qt::Orientation orientation , int /*role*/) const
- {
-     if ( orientation == Qt::Horizontal ) {
-         switch ( section ) {
-             case 0:
-                 return qtr("Banned");
-
-             case 1:
-                 return qtr("Path");
-
-             case 2:
-                 return qtr("Remove");
-
-             default:
-                 return qtr("Unknown");
-         }
-     }
-     return QVariant();
- }
diff --git a/modules/gui/qt/medialibrary/mlfoldersmodel.hpp b/modules/gui/qt/medialibrary/mlfoldersmodel.hpp
index c5e23f1070..2006151899 100644
--- a/modules/gui/qt/medialibrary/mlfoldersmodel.hpp
+++ b/modules/gui/qt/medialibrary/mlfoldersmodel.hpp
@@ -34,63 +34,70 @@
 #include <util/qml_main_context.hpp>
 #include <vlc_media_library.h>
 
-class MlFoldersModel : public QAbstractListModel
+class MLFoldersBaseModel : public QAbstractListModel
 {
     Q_OBJECT
     Q_PROPERTY(QmlMainContext* ctx READ getCtx WRITE setCtx NOTIFY ctxChanged)
 
 public:
-    MlFoldersModel( QObject * parent = nullptr );
+    enum Roles
+    {
+        Banned = Qt::UserRole + 1,
+        DisplayUrl,
+        MRL
+    };
+
+    MLFoldersBaseModel( QObject *parent = nullptr );
 
     void setCtx(QmlMainContext* ctx);
     inline QmlMainContext* getCtx() { return m_ctx; }
     void setMl(vlc_medialibrary_t* ml);
+    inline vlc_medialibrary_t *ml() const { return m_ml; }
 
     int rowCount( QModelIndex const &parent = {} ) const  override;
-    int columnCount (QModelIndex const &parent = {} ) const  override;
-
     QVariant data( QModelIndex const &index , const int role = Qt::DisplayRole ) const  override;
-
-    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;
+public slots:
+    virtual void removeAt( int index ) = 0;
+    virtual void add( const QUrl &mrl ) = 0;
 
-    static void onMlEvent( void* data , const vlc_ml_event_t* event );
-    QVariant headerData( int section , Qt::Orientation orientation , int role ) const override;
+signals:
+    void ctxChanged();
+    void onMLEntryPointModified(QPrivateSignal);
 
-    enum Roles
+protected:
+    struct EntryPoint
     {
-        Banned = Qt::UserRole + 1,
-        DisplayUrl
-    };
-private:
-    struct EntryPoint {
         EntryPoint(const vlc_ml_entry_point_t &entryPoint );
-        QString  mrl;
+        QString mrl;
         bool banned;
     };
 
+    virtual std::vector<EntryPoint> entryPoints() const = 0;
+
+private:
+    static void onMlEvent( void* data , const vlc_ml_event_t* event );
+    void update();
+
+    using EventCallbackPtr = std::unique_ptr<vlc_ml_event_callback_t, std::function<void( vlc_ml_event_callback_t* )>>;
+
     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 ctxChanged();
-    void onMLEntryPointModified(QPrivateSignal);
+};
 
-public slots:
-    void update();
-    void removeAt( int index );
-    void add( QUrl mrl );
+class MLFoldersModel : public MLFoldersBaseModel
+{
+public:
+    using MLFoldersBaseModel::MLFoldersBaseModel;
 
+    void removeAt( int index ) override;
+    void add( const QUrl &mrl ) override;
 
+private:
+    std::vector<EntryPoint> entryPoints() const final;
 };
 
 #endif // ML_FOLDERS_MODEL_HPP



More information about the vlc-commits mailing list