[vlc-devel] [PATCH 15/18] qml: use a native implementation for network contextual menu

Pierre Lamot pierre at videolabs.io
Wed Sep 23 14:27:49 CEST 2020


---
 modules/gui/qt/maininterface/mainui.cpp       |  1 +
 modules/gui/qt/menus/qml_menu_wrapper.cpp     | 58 ++++++++++++++
 modules/gui/qt/menus/qml_menu_wrapper.hpp     | 11 +++
 .../qt/network/qml/NetworkBrowseDisplay.qml   | 76 ++-----------------
 4 files changed, 78 insertions(+), 68 deletions(-)

diff --git a/modules/gui/qt/maininterface/mainui.cpp b/modules/gui/qt/maininterface/mainui.cpp
index fd2b19b4b4..9137e5682a 100644
--- a/modules/gui/qt/maininterface/mainui.cpp
+++ b/modules/gui/qt/maininterface/mainui.cpp
@@ -206,6 +206,7 @@ void MainUI::registerQMLTypes()
     qmlRegisterType<PlayerControlBarModel>( "org.videolan.vlc", 0, 1, "PlayerControlBarModel");
 
     qmlRegisterType<QmlGlobalMenu>( "org.videolan.vlc", 0, 1, "QmlGlobalMenu" );
+    qmlRegisterType<NetworkMediaContextMenu>( "org.videolan.vlc", 0, 1, "NetworkMediaContextMenu" );
 }
 
 void MainUI::onQmlWarning(const QList<QQmlError>& qmlErrors)
diff --git a/modules/gui/qt/menus/qml_menu_wrapper.cpp b/modules/gui/qt/menus/qml_menu_wrapper.cpp
index 006ff0bb3d..6f964e62e0 100644
--- a/modules/gui/qt/menus/qml_menu_wrapper.cpp
+++ b/modules/gui/qt/menus/qml_menu_wrapper.cpp
@@ -24,6 +24,7 @@
 #include "medialibrary/mlartistmodel.hpp"
 #include "medialibrary/mlgenremodel.hpp"
 #include "medialibrary/mlalbumtrackmodel.hpp"
+#include "network/networkmediamodel.hpp"
 
 
 #include <QSignalMapper>
@@ -206,3 +207,60 @@ void VideoContextMenu::popup(const QModelIndexList& selected, QPoint pos, QVaria
     menu->popup(pos);
 }
 
+NetworkMediaContextMenu::NetworkMediaContextMenu(QObject* parent)
+    : QObject(parent)
+{}
+
+void NetworkMediaContextMenu::popup(const QModelIndexList& selected, QPoint pos)
+{
+    if (!m_model)
+        return;
+
+    QMenu* menu = new QMenu();
+    QAction* action;
+
+    menu->setAttribute(Qt::WA_DeleteOnClose);
+
+    action = menu->addAction( qtr("Add and play") );
+    connect(action, &QAction::triggered, [this, selected]( ) {
+        m_model->addAndPlay(selected);
+    });
+
+    action = menu->addAction( qtr("Enqueue") );
+    connect(action, &QAction::triggered, [this, selected]( ) {
+        m_model->addToPlaylist(selected);
+    });
+
+    bool canBeIndexed = false;
+    unsigned countIndexed = 0;
+    for (const QModelIndex& idx : selected)
+    {
+        QVariant canIndex = m_model->data(m_model->index(idx.row()), NetworkMediaModel::NETWORK_CANINDEX );
+        if (canIndex.isValid() && canIndex.toBool())
+            canBeIndexed = true;
+        else
+            continue;
+        QVariant isIndexed = m_model->data(m_model->index(idx.row()), NetworkMediaModel::NETWORK_INDEXED );
+        if (!isIndexed.isValid())
+            continue;
+        if (isIndexed.toBool())
+            ++countIndexed;
+    }
+
+    if (canBeIndexed)
+    {
+        bool removeFromML = countIndexed > 0;
+        action = menu->addAction(removeFromML
+            ? qtr("Remove from Media Library")
+            : qtr("Add to Media Library"));
+
+        connect(action, &QAction::triggered, [this, selected, removeFromML]( ) {
+            for (const QModelIndex& idx : selected) {
+                m_model->setData(m_model->index(idx.row()), !removeFromML, NetworkMediaModel::NETWORK_INDEXED);
+            }
+        });
+    }
+
+    menu->popup(pos);
+}
+
diff --git a/modules/gui/qt/menus/qml_menu_wrapper.hpp b/modules/gui/qt/menus/qml_menu_wrapper.hpp
index ba3e3d0ac9..4a5a87668d 100644
--- a/modules/gui/qt/menus/qml_menu_wrapper.hpp
+++ b/modules/gui/qt/menus/qml_menu_wrapper.hpp
@@ -31,6 +31,7 @@ class MLGenreModel;
 class MLArtistModel;
 class MLAlbumTrackModel;
 class MLVideoModel;
+class NetworkMediaModel;
 class QmlMainContext;
 
 #define SIMPLE_MENU_PROPERTY(type, name, defaultValue) \
@@ -130,6 +131,16 @@ public slots:
 signals:
     void showMediaInformation(int index);
 };
+
+class NetworkMediaContextMenu : public QObject {
+    Q_OBJECT
+    SIMPLE_MENU_PROPERTY(NetworkMediaModel*, model, nullptr)
+public:
+    NetworkMediaContextMenu(QObject* parent = nullptr);
+public slots:
+    void popup(const QModelIndexList& selected, QPoint pos );
+};
+
 #undef SIMPLE_MENU_PROPERTY
 
 #endif // QMLMENUWRAPPER_HPP
diff --git a/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml b/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
index aff74a58e2..e5b78f1097 100644
--- a/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
+++ b/modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
@@ -49,6 +49,11 @@ Widgets.NavigableFocusScope {
         model: providerModel
     }
 
+    NetworkMediaContextMenu {
+        id: contextMenu
+        model: providerModel
+    }
+
     function resetFocus() {
         var initialIndex = root.initialIndex
         if (initialIndex >= providerModel.count)
@@ -75,66 +80,6 @@ Widgets.NavigableFocusScope {
         }
     }
 
-    Widgets.MenuExt {
-        id: contextMenu
-        property var selectionModel: undefined
-        property var model: ({})
-        closePolicy: Popup.CloseOnReleaseOutside | Popup.CloseOnEscape
-        focus:true
-
-        Instantiator {
-            id: instanciator
-            property var modelActions: {
-                "play": function() {
-                    if (selectionModel) {
-                        providerModel.addAndPlay(selectionModel.selectedIndexes )
-                    }
-                    contextMenu.close()
-                },
-                "enqueue": function() {
-                    if (selectionModel) {
-                        providerModel.addToPlaylist(selectionModel.selectedIndexes )
-                    }
-                    contextMenu.close()
-                },
-                "index": function(index) {
-                    contextMenu.model.indexed = contextMenu.model.indexed
-                    contextMenu.close()
-                }
-            }
-
-            model: [{
-                    active: true,
-                    text: i18n.qtr("Play"),
-                    action: "play"
-                }, {
-                    active: true,
-                    text: i18n.qtr("Enqueue"),
-                    action: "enqueue"
-                }, {
-                    active:  contextMenu.model && !!contextMenu.model.can_index,
-                    text: contextMenu.model && contextMenu.model.indexed ? i18n.qtr("Remove from Media Library") : i18n.qtr("Add to Media Library") ,
-                    action: "index"
-                }
-            ]
-
-            onObjectAdded: model[index].active && contextMenu.insertItem( index, object )
-            onObjectRemoved: model[index].active && contextMenu.removeItem( object )
-            delegate: Widgets.MenuItemExt {
-                focus: true
-                text: modelData.text
-                onTriggered: {
-                    if (modelData.action && instanciator.modelActions[modelData.action]) {
-                        instanciator.modelActions[modelData.action]()
-                    }
-                }
-            }
-        }
-
-        onClosed: contextMenu.parent.forceActiveFocus()
-    }
-
-
     Component{
         id: gridComponent
 
@@ -212,9 +157,7 @@ Widgets.NavigableFocusScope {
                 }
 
                 onContextMenuButtonClicked: {
-                    contextMenu.model = providerModel
-                    contextMenu.selectionModel = selectionModel
-                    contextMenu.popup()
+                    contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
                 }
             }
 
@@ -397,11 +340,8 @@ Widgets.NavigableFocusScope {
                 else
                     providerModel.addAndPlay( index )
             }
-            onContextMenuButtonClicked: {
-                contextMenu.model = providerModel
-                contextMenu.selectionModel = selectionModel
-                contextMenu.popup(menuParent)
-            }
+            onContextMenuButtonClicked: contextMenu.popup(selectionModel.selectedIndexes, menuParent.mapToGlobal(0,0))
+            onRightClick: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
         }
     }
 
-- 
2.25.1



More information about the vlc-devel mailing list