[vlc-commits] qt: allow changing root element in MLNetworkModel without recreating the model

Pierre Lamot git at videolan.org
Sun Jul 28 08:43:57 CEST 2019


vlc | branch: master | Pierre Lamot <pierre at videolabs.io> | Thu Jul 18 18:42:55 2019 +0200| [453e2fe7a8184bb1c261348689c990efa486347c] | committer: Jean-Baptiste Kempf

qt: allow changing root element in MLNetworkModel without recreating the model

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

 .../qt/components/mediacenter/mlnetworkmodel.cpp   | 35 +++++++++++++++++-----
 .../qt/components/mediacenter/mlnetworkmodel.hpp   | 22 ++++++++++++--
 .../gui/qt/qml/mediacenter/MCNetworkDisplay.qml    | 11 +++----
 3 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/modules/gui/qt/components/mediacenter/mlnetworkmodel.cpp b/modules/gui/qt/components/mediacenter/mlnetworkmodel.cpp
index 90ec18dcf7..f5c0bdc9db 100644
--- a/modules/gui/qt/components/mediacenter/mlnetworkmodel.cpp
+++ b/modules/gui/qt/components/mediacenter/mlnetworkmodel.cpp
@@ -118,21 +118,42 @@ bool MLNetworkModel::setData( const QModelIndex& idx, const QVariant& value, int
     return res == VLC_SUCCESS;
 }
 
-void MLNetworkModel::setContext(QmlMainContext* ctx, NetworkTreeItem parentTree )
+void MLNetworkModel::setCtx(QmlMainContext* ctx)
 {
-    assert(!m_ctx);
     if (ctx) {
         m_ctx = ctx;
         m_ml = vlc_ml_instance_get( m_ctx->getIntf() );
-        m_treeItem = parentTree;
+    }
+    if (m_ctx && m_hasTree) {
         initializeMediaSources();
     }
+    emit ctxChanged();
+}
+
+void MLNetworkModel::setTree(QVariant parentTree)
+{
+    if (parentTree.canConvert<NetworkTreeItem>())
+        m_treeItem = parentTree.value<NetworkTreeItem>();
+    else
+        m_treeItem = NetworkTreeItem();
+    m_hasTree = true;
+    if (m_ctx && m_hasTree) {
+        initializeMediaSources();
+    }
+    emit treeChanged();
 }
 
 bool MLNetworkModel::initializeMediaSources()
 {
     auto libvlc = vlc_object_instance(m_ctx->getIntf());
 
+    m_listeners.clear();
+    if (!m_items.empty()) {
+        beginResetModel();
+        m_items.clear();
+        endResetModel();
+    }
+
     // When listing all found devices, we have no specified media and no parent,
     // but we can't go up a level in this case.
     // Otherwise, we can have a parent (when listing a subdirectory of a device)
@@ -194,7 +215,7 @@ bool MLNetworkModel::initializeMediaSources()
     std::unique_ptr<SourceListener> l{ new SourceListener( m_treeItem.source, this ) };
     if ( l->listener == nullptr )
         return false;
-    vlc_media_tree_Preparse( tree, libvlc, m_treeItem.media );
+    vlc_media_tree_Preparse( tree, libvlc, m_treeItem.media.get() );
     m_listeners.push_back( std::move( l ) );
 
     return true;
@@ -206,7 +227,7 @@ void MLNetworkModel::onItemCleared( MediaSourcePtr mediaSource, input_item_node_
     {
         input_item_node_t *res;
         input_item_node_t *parent;
-        if ( vlc_media_tree_Find( m_treeItem.source->tree, m_treeItem.media,
+        if ( vlc_media_tree_Find( m_treeItem.source->tree, m_treeItem.media.get(),
                                           &res, &parent ) == false )
             return;
         refreshMediaList( std::move( mediaSource ), res->pp_children, res->i_children, true );
@@ -221,7 +242,7 @@ void MLNetworkModel::onItemAdded( MediaSourcePtr mediaSource, input_item_node_t*
 {
     if ( m_treeItem.media == nullptr )
         refreshDeviceList( std::move( mediaSource ), children, count, false );
-    else if ( parent->p_item == m_treeItem.media )
+    else if ( parent->p_item == m_treeItem.media.get() )
         refreshMediaList( std::move( mediaSource ), children, count, false );
 }
 
@@ -289,7 +310,7 @@ void MLNetworkModel::refreshMediaList( MediaSourcePtr mediaSource,
                                     &item.indexed ) != VLC_SUCCESS )
                 item.indexed = false;
         }
-        item.tree = NetworkTreeItem{ mediaSource, it, m_treeItem.media };
+        item.tree = NetworkTreeItem( mediaSource, it, m_treeItem.media.get() );
         items->push_back( std::move( item ) );
     }
     callAsync([this, clear, items]() {
diff --git a/modules/gui/qt/components/mediacenter/mlnetworkmodel.hpp b/modules/gui/qt/components/mediacenter/mlnetworkmodel.hpp
index a708c1f3bb..0f3274ec9c 100644
--- a/modules/gui/qt/components/mediacenter/mlnetworkmodel.hpp
+++ b/modules/gui/qt/components/mediacenter/mlnetworkmodel.hpp
@@ -37,6 +37,10 @@
 using MediaSourcePtr = vlc_shared_data_ptr_type(vlc_media_source_t,
                                 vlc_media_source_Hold, vlc_media_source_Release);
 
+using InputItemPtr = vlc_shared_data_ptr_type(input_item_t,
+                                              input_item_Hold,
+                                              input_item_Release);
+
 class NetworkTreeItem
 {
     Q_GADGET
@@ -54,8 +58,8 @@ public:
     NetworkTreeItem& operator=( NetworkTreeItem&& ) = default;
 
     MediaSourcePtr source;
-    input_item_t *media;
-    input_item_t *parent;
+    InputItemPtr media;
+    InputItemPtr parent;
 };
 
 class MLNetworkModel : public QAbstractListModel
@@ -71,6 +75,9 @@ public:
     };
     Q_ENUM( ItemType );
 
+    Q_PROPERTY(QmlMainContext* ctx READ getCtx WRITE setCtx NOTIFY ctxChanged)
+    Q_PROPERTY(QVariant tree READ getTree WRITE setTree NOTIFY treeChanged)
+
     explicit MLNetworkModel(QObject* parent = nullptr);
     MLNetworkModel( QmlMainContext* ctx, QString parentMrl, QObject* parent = nullptr );
 
@@ -81,7 +88,15 @@ public:
     Qt::ItemFlags flags( const QModelIndex& idx ) const override;
     bool setData( const QModelIndex& idx,const QVariant& value, int role ) override;
 
-    Q_INVOKABLE void setContext(QmlMainContext* ctx, NetworkTreeItem parentMrl);
+    void setCtx(QmlMainContext* ctx);
+    void setTree(QVariant tree);
+
+    inline QmlMainContext* getCtx() { return m_ctx; }
+    inline QVariant getTree() { return QVariant::fromValue( m_treeItem); }
+
+signals:
+    void ctxChanged();
+    void treeChanged();
 
 private:
     struct Item
@@ -152,6 +167,7 @@ private:
     std::vector<Item> m_items;
     QmlMainContext* m_ctx = nullptr;
     vlc_medialibrary_t* m_ml;
+    bool m_hasTree = false;
     NetworkTreeItem m_treeItem;
     std::vector<std::unique_ptr<SourceListener>> m_listeners;
 };
diff --git a/modules/gui/qt/qml/mediacenter/MCNetworkDisplay.qml b/modules/gui/qt/qml/mediacenter/MCNetworkDisplay.qml
index 1f58c17ef8..8b0149ffa9 100644
--- a/modules/gui/qt/qml/mediacenter/MCNetworkDisplay.qml
+++ b/modules/gui/qt/qml/mediacenter/MCNetworkDisplay.qml
@@ -28,15 +28,15 @@ import "qrc:///style/"
 Utils.NavigableFocusScope {
     id: root
 
-    property var tree
+    property alias tree: mlModel.tree
 
     Utils.SelectableDelegateModel {
         id: delegateModel
 
         model:  MLNetworkModel {
-            Component.onCompleted: {
-                setContext(mainctx, root.tree)
-            }
+            id: mlModel
+            ctx: mainctx
+            tree: undefined
         }
 
         delegate: Package {
@@ -69,7 +69,8 @@ Utils.NavigableFocusScope {
                 medialib.addAndPlay( list )
             } else {
                 if (delegateModel.items.get(index).model.type != MLNetworkModel.TYPE_FILE)  {
-                    history.push(["mc", "network", { tree: delegateModel.items.get(index).model.tree }], History.Go);
+                    root.tree = delegateModel.items.get(index).model.tree
+                    history.push(["mc", "network", { tree: delegateModel.items.get(index).model.tree }], History.Stay);
                 } else {
                     medialib.addAndPlay( delegateModel.items.get(index).model.mrl );
                 }



More information about the vlc-commits mailing list