[vlc-devel] [PATCH 16/18] qml: use a native implementation for playlist contextual menu
Pierre Lamot
pierre at videolabs.io
Wed Sep 23 14:27:50 CEST 2020
---
modules/gui/qt/maininterface/mainui.cpp | 1 +
modules/gui/qt/menus/qml_menu_wrapper.cpp | 111 +++++++++++++
modules/gui/qt/menus/qml_menu_wrapper.hpp | 17 ++
modules/gui/qt/playlist/qml/PLItem.qml | 8 +-
.../gui/qt/playlist/qml/PlaylistListView.qml | 155 +-----------------
5 files changed, 142 insertions(+), 150 deletions(-)
diff --git a/modules/gui/qt/maininterface/mainui.cpp b/modules/gui/qt/maininterface/mainui.cpp
index 9137e5682a..c30e5e4c82 100644
--- a/modules/gui/qt/maininterface/mainui.cpp
+++ b/modules/gui/qt/maininterface/mainui.cpp
@@ -207,6 +207,7 @@ void MainUI::registerQMLTypes()
qmlRegisterType<QmlGlobalMenu>( "org.videolan.vlc", 0, 1, "QmlGlobalMenu" );
qmlRegisterType<NetworkMediaContextMenu>( "org.videolan.vlc", 0, 1, "NetworkMediaContextMenu" );
+ qmlRegisterType<PlaylistContextMenu>( "org.videolan.vlc", 0, 1, "PlaylistContextMenu" );
}
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 6f964e62e0..e48548b6b9 100644
--- a/modules/gui/qt/menus/qml_menu_wrapper.cpp
+++ b/modules/gui/qt/menus/qml_menu_wrapper.cpp
@@ -25,6 +25,9 @@
#include "medialibrary/mlgenremodel.hpp"
#include "medialibrary/mlalbumtrackmodel.hpp"
#include "network/networkmediamodel.hpp"
+#include "playlist/playlist_controller.hpp"
+#include "playlist/playlist_model.hpp"
+#include "dialogs/dialogs_provider.hpp"
#include <QSignalMapper>
@@ -264,3 +267,111 @@ void NetworkMediaContextMenu::popup(const QModelIndexList& selected, QPoint pos)
menu->popup(pos);
}
+PlaylistContextMenu::PlaylistContextMenu(QObject* parent)
+ : QObject(parent)
+{}
+
+void PlaylistContextMenu::popup(int currentIndex, QPoint pos )
+{
+ if (!m_controler || !m_model)
+ return;
+
+ QMenu* menu = new QMenu();
+ QAction* action;
+
+ QList<QUrl> selectedUrlList;
+ for (const int modelIndex : m_model->getSelection())
+ selectedUrlList.push_back(m_model->itemAt(modelIndex).getUrl());
+
+ PlaylistItem currentItem;
+ if (currentIndex >= 0)
+ currentItem = m_model->itemAt(currentIndex);
+
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+
+ if (currentItem)
+ {
+ action = menu->addAction( qtr("Play") );
+ connect(action, &QAction::triggered, [this, currentIndex]( ) {
+ m_controler->goTo(currentIndex, true);
+ });
+
+ menu->addSeparator();
+ }
+
+ if (m_model->getSelectedCount() > 0) {
+ action = menu->addAction( qtr("Stream") );
+ connect(action, &QAction::triggered, [selectedUrlList]( ) {
+ DialogsProvider::getInstance()->streamingDialog(selectedUrlList, false);
+ });
+
+ action = menu->addAction( qtr("Save") );
+ connect(action, &QAction::triggered, [selectedUrlList]( ) {
+ DialogsProvider::getInstance()->streamingDialog(selectedUrlList, true);
+ });
+
+ menu->addSeparator();
+ }
+
+ if (currentItem) {
+ action = menu->addAction( qtr("Information") );
+ action->setIcon(QIcon(":/menu/info.svg"));
+ connect(action, &QAction::triggered, [currentItem]( ) {
+ DialogsProvider::getInstance()->mediaInfoDialog(currentItem);
+ });
+
+ menu->addSeparator();
+
+ action = menu->addAction( qtr("Show Containing Directory...") );
+ action->setIcon(QIcon(":/type/folder-grey.svg"));
+ connect(action, &QAction::triggered, [currentItem]( ) {
+ DialogsProvider::getInstance()->mediaInfoDialog(currentItem);
+ });
+
+ menu->addSeparator();
+ }
+
+ action = menu->addAction( qtr("Add File...") );
+ action->setIcon(QIcon(":/buttons/playlist/playlist_add.svg"));
+ connect(action, &QAction::triggered, []( ) {
+ DialogsProvider::getInstance()->simpleOpenDialog(false);
+ });
+
+ action = menu->addAction( qtr("Add Directory...") );
+ action->setIcon(QIcon(":/buttons/playlist/playlist_add.svg"));
+ connect(action, &QAction::triggered, []( ) {
+ DialogsProvider::getInstance()->PLAppendDir();
+ });
+
+ action = menu->addAction( qtr("Advanced Open...") );
+ action->setIcon(QIcon(":/buttons/playlist/playlist_add.svg"));
+ connect(action, &QAction::triggered, []( ) {
+ DialogsProvider::getInstance()->PLAppendDialog();
+ });
+
+ menu->addSeparator();
+
+ if (m_model->getSelectedCount() > 0)
+ {
+ action = menu->addAction( qtr("Save Playlist to File...") );
+ connect(action, &QAction::triggered, []( ) {
+ DialogsProvider::getInstance()->savePlayingToPlaylist();
+ });
+
+ menu->addSeparator();
+
+ action = menu->addAction( qtr("Remove Selected") );
+ action->setIcon(QIcon(":/buttons/playlist/playlist_remove.svg"));
+ connect(action, &QAction::triggered, [this]( ) {
+ m_model->removeItems(m_model->getSelection());
+ });
+ }
+
+ action = menu->addAction( qtr("Clear the playlist") );
+ action->setIcon(QIcon(":/toolbar/clear.svg"));
+ connect(action, &QAction::triggered, [this]( ) {
+ m_controler->clear();
+ });
+
+ menu->popup(pos);
+}
diff --git a/modules/gui/qt/menus/qml_menu_wrapper.hpp b/modules/gui/qt/menus/qml_menu_wrapper.hpp
index 4a5a87668d..9af03a4a6b 100644
--- a/modules/gui/qt/menus/qml_menu_wrapper.hpp
+++ b/modules/gui/qt/menus/qml_menu_wrapper.hpp
@@ -33,6 +33,12 @@ class MLAlbumTrackModel;
class MLVideoModel;
class NetworkMediaModel;
class QmlMainContext;
+namespace vlc {
+namespace playlist {
+class PlaylistControllerModel;
+class PlaylistListModel;
+}
+}
#define SIMPLE_MENU_PROPERTY(type, name, defaultValue) \
Q_PROPERTY(type name READ get##name WRITE set##name) \
@@ -141,6 +147,17 @@ public slots:
void popup(const QModelIndexList& selected, QPoint pos );
};
+
+class PlaylistContextMenu : public QObject {
+ Q_OBJECT
+ SIMPLE_MENU_PROPERTY(vlc::playlist::PlaylistListModel*, model, nullptr)
+ SIMPLE_MENU_PROPERTY(vlc::playlist::PlaylistControllerModel*, controler, nullptr)
+public:
+ PlaylistContextMenu(QObject* parent = nullptr);
+public slots:
+ void popup(int currentIndex, QPoint pos );
+};
+
#undef SIMPLE_MENU_PROPERTY
#endif // QMLMENUWRAPPER_HPP
diff --git a/modules/gui/qt/playlist/qml/PLItem.qml b/modules/gui/qt/playlist/qml/PLItem.qml
index 4c08acf164..e056774679 100644
--- a/modules/gui/qt/playlist/qml/PLItem.qml
+++ b/modules/gui/qt/playlist/qml/PLItem.qml
@@ -32,8 +32,8 @@ Rectangle {
property var plmodel
- signal itemClicked(int button, int modifier)
- signal itemDoubleClicked(int keys, int modifier)
+ signal itemClicked(int button, int modifier, var globalMousePos)
+ signal itemDoubleClicked(int keys, int modifier, var globalMousePos)
signal dragStarting()
property alias hovered: mouse.containsMouse
@@ -113,11 +113,11 @@ Rectangle {
acceptedButtons: acceptedButtons | Qt.RightButton
onClicked:{
- plitem.itemClicked(mouse.button, mouse.modifiers);
+ plitem.itemClicked(mouse.button, mouse.modifiers, this.mapToGlobal(mouse.x, mouse.y));
}
onDoubleClicked: {
if (mouse.button !== Qt.RightButton)
- plitem.itemDoubleClicked(mouse.buttons, mouse.modifiers);
+ plitem.itemDoubleClicked(mouse.buttons, mouse.modifiers, this.mapToGlobal(mouse.x, mouse.y));
}
drag.target: dragItem
diff --git a/modules/gui/qt/playlist/qml/PlaylistListView.qml b/modules/gui/qt/playlist/qml/PlaylistListView.qml
index ac7af1a892..c49b30bc8a 100644
--- a/modules/gui/qt/playlist/qml/PlaylistListView.qml
+++ b/modules/gui/qt/playlist/qml/PlaylistListView.qml
@@ -37,7 +37,6 @@ Widgets.NavigableFocusScope {
property int leftPadding: 0
property int rightPadding: 0
property alias backgroundColor: parentRect.color
- property alias mediaLibAvailable: contextMenu.medialibAvailable
property bool forceDark: false
property VLCColors _colors: forceDark ? vlcNightColors : VLCStyle.colors
@@ -58,6 +57,12 @@ Widgets.NavigableFocusScope {
color: parent.color
}
+ PlaylistContextMenu {
+ id: contextMenu
+ model: root.plmodel
+ controler: mainPlaylistController
+ }
+
PlaylistMenu {
id: overlayMenu
anchors.fill: parent
@@ -130,138 +135,6 @@ Widgets.NavigableFocusScope {
}
}
- Widgets.MenuExt {
- id: contextMenu
- property alias model: root.plmodel
- property int itemIndex: -1
- property bool medialibAvailable: false
- closePolicy: Popup.CloseOnReleaseOutside | Popup.CloseOnEscape
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Play")
- icon.source: "qrc:/toolbar/play_b.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- mainPlaylistController.goTo(contextMenu.itemIndex, true)
- }
- }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Stream")
- icon.source: "qrc:/menu/stream.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- var selection = contextMenu.model.getSelection()
- if (selection.length === 0)
- return
-
- dialogProvider.streamingDialog(selection.map(function(i) { return contextMenu.model.itemAt(i).url; }), false)
- }
- }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Save")
- onTriggered: {
- var selection = contextMenu.model.getSelection()
- if (selection.length === 0)
- return
-
- dialogProvider.streamingDialog(selection.map(function(i) { return contextMenu.model.itemAt(i).url; }))
- }
- }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Information...")
- icon.source: "qrc:/menu/info.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- dialogProvider.mediaInfoDialog(contextMenu.model.itemAt(contextMenu.itemIndex))
- }
- }
-
- MenuSeparator { }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Show Containing Directory...")
- icon.source: "qrc:/type/folder-grey.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- mainPlaylistController.explore(contextMenu.model.itemAt(contextMenu.itemIndex))
- }
- }
-
- MenuSeparator { }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Add File...")
- icon.source: "qrc:/buttons/playlist/playlist_add.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- dialogProvider.simpleOpenDialog(false)
- }
- }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Add Directory...")
- icon.source: "qrc:/buttons/playlist/playlist_add.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- dialogProvider.PLAppendDir()
- }
- }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Advanced Open...")
- icon.source: "qrc:/buttons/playlist/playlist_add.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- dialogProvider.PLAppendDialog()
- }
- }
-
- MenuSeparator { }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Save Playlist to File...")
- onTriggered: {
- dialogProvider.savePlayingToPlaylist();
- }
- }
-
- MenuSeparator { }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Remove Selected")
- icon.source: "qrc:/buttons/playlist/playlist_remove.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- contextMenu.model.removeItems(contextMenu.model.getSelection())
- }
- }
-
- Widgets.MenuItemExt {
- text: i18n.qtr("Clear the playlist")
- icon.source: "qrc:/toolbar/clear.svg"
- icon.width: VLCStyle.icon_small
- icon.height: VLCStyle.icon_small
- onTriggered: {
- mainPlaylistController.clear()
- }
- }
-
- MenuSeparator { }
-
- onClosed: contextMenu.parent.forceActiveFocus()
- }
-
ColumnLayout {
anchors.fill: parent
anchors.bottomMargin: VLCStyle.margin_normal
@@ -383,18 +256,11 @@ Widgets.NavigableFocusScope {
acceptedButtons: Qt.RightButton | Qt.LeftButton
onClicked: {
+ view.forceActiveFocus()
if( mouse.button === Qt.RightButton )
- {
- view.forceActiveFocus()
- root.plmodel.deselectAll()
- contextMenu.itemIndex = -1
- contextMenu.popup()
- }
+ contextMenu.popup(-1, this.mapToGlobal(mouse.x, mouse.y))
else if ( mouse.button === Qt.LeftButton )
- {
- view.forceActiveFocus()
root.plmodel.deselectAll()
- }
}
}
@@ -479,10 +345,7 @@ Widgets.NavigableFocusScope {
}
if (button === Qt.RightButton)
- {
- contextMenu.itemIndex = index
- contextMenu.popup()
- }
+ contextMenu.popup(index, globalMousePos)
}
onItemDoubleClicked: mainPlaylistController.goTo(index, true)
color: _colors.getBgColor(model.selected, plitem.hovered, plitem.activeFocus)
--
2.25.1
More information about the vlc-devel
mailing list