<div dir="ltr">This is a resend.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 5 Aug 2019 at 14:53, Abel Tesfaye <<a href="mailto:abeltesfaye45@gmail.com">abeltesfaye45@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Abel Tesfaye <<a href="mailto:Abeltesfaye45@gmail.com" target="_blank">Abeltesfaye45@gmail.com</a>><br>
<br>
---<br>
 modules/gui/qt/Makefile.am                    |   3 +<br>
 .../mediacenter/ml_folders_model.cpp          | 147 ++++++++++++++++++<br>
 .../mediacenter/ml_folders_model.hpp          |  80 ++++++++++<br>
 3 files changed, 230 insertions(+)<br>
 create mode 100644 modules/gui/qt/components/mediacenter/ml_folders_model.cpp<br>
 create mode 100644 modules/gui/qt/components/mediacenter/ml_folders_model.hpp<br>
<br>
diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am<br>
index bdf5dcd5cf..2932cf2426 100644<br>
--- a/modules/gui/qt/Makefile.am<br>
+++ b/modules/gui/qt/Makefile.am<br>
@@ -112,6 +112,8 @@ libqt_plugin_la_SOURCES = \<br>
        gui/qt/components/settings.hpp \<br>
        gui/qt/components/audio_device_model.cpp  \<br>
        gui/qt/components/audio_device_model.hpp \<br>
+       gui/qt/components/mediacenter/ml_folders_model.hpp  \<br>
+       gui/qt/components/mediacenter/ml_folders_model.cpp \<br>
        gui/qt/components/voutwindow/videosurface.cpp \<br>
        gui/qt/components/voutwindow/videosurface.hpp \<br>
        gui/qt/components/voutwindow/qvoutwindow.cpp \<br>
@@ -269,6 +271,7 @@ nodist_libqt_plugin_la_SOURCES = \<br>
        gui/qt/components/selectable_list_model.moc.cpp \<br>
        gui/qt/components/settings.moc.cpp \<br>
        gui/qt/components/audio_device_model.moc.cpp \<br>
+       gui/qt/components/mediacenter/ml_folders_model.moc.cpp \<br>
        gui/qt/components/voutwindow/videosurface.moc.cpp \<br>
        gui/qt/components/voutwindow/qvoutwindow.moc.cpp \<br>
        gui/qt/components/voutwindow/qvoutwindowdummy.moc.cpp \<br>
diff --git a/modules/gui/qt/components/mediacenter/ml_folders_model.cpp b/modules/gui/qt/components/mediacenter/ml_folders_model.cpp<br>
new file mode 100644<br>
index 0000000000..e7469830e7<br>
--- /dev/null<br>
+++ b/modules/gui/qt/components/mediacenter/ml_folders_model.cpp<br>
@@ -0,0 +1,147 @@<br>
+/*****************************************************************************<br>
+ * Copyright (C) 2019 VLC authors and VideoLAN<br>
+ *<br>
+ * This program is free software; you can redistribute it and/or modify<br>
+ * it under the terms of the GNU General Public License as published by<br>
+ * the Free Software Foundation; either version 2 of the License, or<br>
+ * ( at your option ) any later version.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful,<br>
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
+ * GNU General Public License for more details.<br>
+ *<br>
+ * You should have received a copy of the GNU General Public License<br>
+ * along with this program; if not, write to the Free Software<br>
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.<br>
+ *****************************************************************************/<br>
+<br>
+#include "ml_folders_model.hpp"<br>
+#include <cassert><br>
+<br>
+MlFoldersModel::MlFoldersModel( vlc_medialibrary_t *p_ml , QObject *parent )<br>
+    : QAbstractListModel( parent )<br>
+    ,m_ml( p_ml )<br>
+    ,m_ml_event_handle( nullptr , [this](vlc_ml_event_callback_t* cb ) {<br>
+        assert( m_ml != nullptr );<br>
+        vlc_ml_event_unregister_callback( m_ml , cb );<br>
+})<br>
+{<br>
+    assert( p_ml );<br>
+    connect( this , &MlFoldersModel::onMLEntryPointModified , this , &MlFoldersModel::update );<br>
+    m_ml_event_handle.reset( vlc_ml_event_register_callback( m_ml , onMlEvent , this ) );<br>
+    update();<br>
+}<br>
+<br>
+int MlFoldersModel::rowCount( QModelIndex const & ) const<br>
+{<br>
+    return m_mrls.count();<br>
+}<br>
+int MlFoldersModel::columnCount( QModelIndex const & ) const<br>
+{<br>
+    return 3;<br>
+}<br>
+<br>
+QVariant MlFoldersModel::data( const QModelIndex &index ,<br>
+                              int role) const {<br>
+    if ( index.isValid() )<br>
+    {<br>
+        switch ( role )<br>
+        {<br>
+        case Qt::DisplayRole :<br>
+            if ( index.column() == 1 )<br>
+                return QVariant::fromValue( m_mrls[index.row()].toDisplayString( QUrl::RemovePassword | QUrl::PreferLocalFile | QUrl::NormalizePathSegments ) );<br>
+            break;<br>
+        case CustomCheckBoxRole :<br>
+            return ( index.row() %2 ) ? //TODO: if mrl banned?<br>
+                                      Qt::Checked : Qt::Unchecked;<br>
+            break;<br>
+        default :<br>
+            return {};<br>
+        }<br>
+    }<br>
+    return {};<br>
+}<br>
+<br>
+void MlFoldersModel::removeAt( int index )<br>
+{<br>
+    vlc_ml_remove_folder( m_ml , qtu( m_mrls[index].toString() ) );<br>
+}<br>
+<br>
+void MlFoldersModel::add( QUrl mrl )<br>
+{<br>
+    vlc_ml_add_folder( m_ml , qtu( mrl.toString( QUrl::None ) ) );<br>
+}<br>
+<br>
+void MlFoldersModel::update()<br>
+{<br>
+    beginResetModel();<br>
+<br>
+    m_mrls.clear();<br>
+<br>
+    vlc_ml_entry_point_list_t * entrypoints;<br>
+    vlc_ml_list_folder( m_ml , &entrypoints ); //TODO: get list of banned folders as well<br>
+<br>
+    for ( unsigned int i=0 ; i<entrypoints->i_nb_items ; i++ )<br>
+        m_mrls.append( QUrl::fromUserInput( entrypoints->p_items[i].psz_mrl ) );<br>
+<br>
+    endResetModel();<br>
+<br>
+}<br>
+<br>
+Qt::ItemFlags MlFoldersModel::flags ( const QModelIndex & index ) const {<br>
+    Qt::ItemFlags defaultFlags = QAbstractListModel::flags( index );<br>
+    if ( index.isValid() ){<br>
+        return defaultFlags;<br>
+    }<br>
+    return defaultFlags;<br>
+}<br>
+<br>
+bool MlFoldersModel::setData( const QModelIndex &index ,<br>
+                                const QVariant &value , int role){<br>
+    if( !index.isValid() )<br>
+        return false;<br>
+<br>
+    else if( role == CustomCheckBoxRole ){<br>
+        if( !value.toBool() ){<br>
+            vlc_ml_unban_folder(m_ml, qtu( m_mrls[index.row()].toString() ) );<br>
+        }<br>
+        else{<br>
+            vlc_ml_ban_folder( m_ml , qtu( m_mrls[index.row()].toString() ) );<br>
+        }<br>
+    }<br>
+    else if(role == CustomRemoveRole){<br>
+        removeAt( index.row() );<br>
+    }<br>
+<br>
+    return true;<br>
+}<br>
+void MlFoldersModel::onMlEvent( void* data , const vlc_ml_event_t* event )<br>
+{<br>
+    auto self = static_cast<MlFoldersModel*>( data );<br>
+    if ( event->i_type == VLC_ML_EVENT_ENTRY_POINT_ADDED || event->i_type == VLC_ML_EVENT_ENTRY_POINT_REMOVED ||<br>
+         event->i_type == VLC_ML_EVENT_ENTRY_POINT_UNBANNED || event->i_type == VLC_ML_EVENT_ENTRY_POINT_BANNED  )<br>
+    {<br>
+        emit self->onMLEntryPointModified();<br>
+    }<br>
+}<br>
+<br>
+ QVariant MlFoldersModel::headerData( int section , Qt::Orientation orientation , int /*role*/) const<br>
+ {<br>
+     if ( orientation == Qt::Horizontal ) {<br>
+         switch ( section ) {<br>
+             case 0:<br>
+                 return qtr("Banned");<br>
+<br>
+             case 1:<br>
+                 return qtr("Path");<br>
+<br>
+             case 2:<br>
+                 return qtr("Remove");<br>
+<br>
+             default:<br>
+                 return qtr("Unknown");<br>
+         }<br>
+     }<br>
+     return QVariant();<br>
+ }<br>
diff --git a/modules/gui/qt/components/mediacenter/ml_folders_model.hpp b/modules/gui/qt/components/mediacenter/ml_folders_model.hpp<br>
new file mode 100644<br>
index 0000000000..2ef0f568bb<br>
--- /dev/null<br>
+++ b/modules/gui/qt/components/mediacenter/ml_folders_model.hpp<br>
@@ -0,0 +1,80 @@<br>
+/*****************************************************************************<br>
+ * Copyright (C) 2019 VLC authors and VideoLAN<br>
+ *<br>
+ * This program is free software; you can redistribute it and/or modify<br>
+ * it under the terms of the GNU General Public License as published by<br>
+ * the Free Software Foundation; either version 2 of the License, or<br>
+ * ( at your option ) any later version.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful,<br>
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
+ * GNU General Public License for more details.<br>
+ *<br>
+ * You should have received a copy of the GNU General Public License<br>
+ * along with this program; if not, write to the Free Software<br>
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.<br>
+ *****************************************************************************/<br>
+<br>
+#ifndef ML_FOLDERS_MODEL_HPP<br>
+#define ML_FOLDERS_MODEL_HPP<br>
+<br>
+#ifdef HAVE_CONFIG_H<br>
+<br>
+# include "config.h"<br>
+<br>
+#endif<br>
+<br>
+#include "qt.hpp"<br>
+#include <QAbstractListModel><br>
+#include <QUrl><br>
+#include <QList><br>
+#include "components/mediacenter/mlhelper.hpp"<br>
+<br>
+#include <vlc_media_library.h><br>
+<br>
+class MlFoldersModel : public QAbstractListModel<br>
+{<br>
+    Q_OBJECT<br>
+public:<br>
+    MlFoldersModel( vlc_medialibrary_t *p_ml , QObject * parent = nullptr );<br>
+<br>
+    int rowCount( QModelIndex const &parent = {} ) const  override;<br>
+    int columnCount (QModelIndex const &parent = {} ) const  override;<br>
+<br>
+    QVariant data( QModelIndex const &index , const int role = Qt::DisplayRole ) const  override;<br>
+<br>
+    Qt::ItemFlags flags ( const QModelIndex & index ) const ;<br>
+<br>
+    bool setData( const QModelIndex &index , const QVariant &value ,<br>
+                 int role );<br>
+<br>
+    static void onMlEvent( void* data , const vlc_ml_event_t* event );<br>
+    QVariant headerData( int section , Qt::Orientation orientation , int role ) const override;<br>
+<br>
+    enum Roles<br>
+    {<br>
+        CustomCheckBoxRole = Qt::UserRole + 1,<br>
+        CustomRemoveRole<br>
+    };<br>
+private:<br>
+    QList<QUrl> m_mrls;<br>
+    vlc_medialibrary_t *m_ml;<br>
+<br>
+    using EventCallbackPtr = std::unique_ptr<vlc_ml_event_callback_t,<br>
+    std::function<void( vlc_ml_event_callback_t* )>> ;<br>
+<br>
+    EventCallbackPtr m_ml_event_handle;<br>
+signals:<br>
+    void limitChanged();<br>
+    void  onMLEntryPointModified();<br>
+<br>
+public slots:<br>
+    void update();<br>
+    void removeAt( int index );<br>
+    void add( QUrl mrl );<br>
+<br>
+<br>
+};<br>
+<br>
+#endif // ML_FOLDERS_MODEL_HPP<br>
-- <br>
2.21.0<br>
<br>
</blockquote></div>