vlc | branch: master | Prince Gupta <guptaprince8...@gmail.com> | Tue Feb 23 15:54:01 2021 +0530| [86eab699f1cb4deb0b2515fb2b0d8a4108c32600] | committer: Pierre Lamot
qt: improve interface of MLFoldersModel Signed-off-by: Pierre Lamot <pie...@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 _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits