[vlc-commits] [Git][videolan/vlc][master] 13 commits: qml: implement Util.VanillaObject

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Tue May 17 12:01:36 UTC 2022



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
f6f4339c by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: implement Util.VanillaObject

QtObject which supports direct children

- - - - -
1a498a98 by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: implement Helpers.isInteger

- - - - -
744a060f by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: implement NativeMenu

can be used to create native menus with support asyncronously retreive data from MLBaseModel like model

- - - - -
8404ed4d by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: implement MLContextMenu

a generic ML context model

- - - - -
3d29cf68 by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: fix Helpers.get for 0 value

- - - - -
2e1146cb by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: use MLContextMenu in video views

- - - - -
54358a91 by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: use MLContextMenu in 'Continue Watching' section of video

- - - - -
6bde26f7 by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: replace AlbumContextMenu with MLContextMenu

- - - - -
04e42c40 by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: replace ArtistContextMenu with MLContextMenu

- - - - -
82f832f8 by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: replace GenreContextMenu with MLContextMenu

- - - - -
4537b2a2 by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: replace AlbumTrackContextMenu with MLContextMenu

- - - - -
a3c9670f by Prince Gupta at 2022-05-17T11:37:24+00:00
qml: replace URLContextMenu with MLContextMenu

- - - - -
3d9a2e7d by Prince Gupta at 2022-05-17T11:37:24+00:00
qt: purse c++ medialib view menus

- - - - -


19 changed files:

- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/mainui.cpp
- modules/gui/qt/medialibrary/qml/MediaGroupDisplay.qml
- modules/gui/qt/medialibrary/qml/MusicAlbums.qml
- modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
- modules/gui/qt/medialibrary/qml/MusicArtist.qml
- modules/gui/qt/medialibrary/qml/MusicGenres.qml
- modules/gui/qt/medialibrary/qml/MusicTrackListDisplay.qml
- modules/gui/qt/medialibrary/qml/UrlListDisplay.qml
- modules/gui/qt/medialibrary/qml/VideoAll.qml
- modules/gui/qt/medialibrary/qml/VideoAllSubDisplay.qml
- modules/gui/qt/medialibrary/qml/VideoDisplayRecentVideos.qml
- modules/gui/qt/menus/qml_menu_wrapper.cpp
- modules/gui/qt/menus/qml_menu_wrapper.hpp
- modules/gui/qt/util/qml/Helpers.js
- + modules/gui/qt/util/qml/MLContextMenu.qml
- + modules/gui/qt/util/qml/NativeMenu.qml
- + modules/gui/qt/util/qml/VanillaObject.qml
- modules/gui/qt/vlc.qrc


Changes:

=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -882,6 +882,9 @@ libqt_plugin_la_QML = \
 	gui/qt/util/qml/ViewDragAutoScrollHandler.qml \
 	gui/qt/util/qml/BindingRev8.qml \
 	gui/qt/util/qml/BindingRev14.qml \
+	gui/qt/util/qml/VanillaObject.qml \
+	gui/qt/util/qml/NativeMenu.qml \
+	gui/qt/util/qml/MLContextMenu.qml \
 	gui/qt/widgets/qml/ActionButtonOverlay.qml \
 	gui/qt/widgets/qml/ActionButtonPrimary.qml \
 	gui/qt/widgets/qml/BannerTabButton.qml \


=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -347,14 +347,6 @@ void MainUI::registerQMLTypes()
         registerAnonymousType<MLArtist>(uri, versionMajor);
         registerAnonymousType<MLAlbumTrack>(uri, versionMajor);
 
-        qmlRegisterType<AlbumContextMenu>( uri, versionMajor, versionMinor, "AlbumContextMenu" );
-        qmlRegisterType<ArtistContextMenu>( uri, versionMajor, versionMinor, "ArtistContextMenu" );
-        qmlRegisterType<GenreContextMenu>( uri, versionMajor, versionMinor, "GenreContextMenu" );
-        qmlRegisterType<AlbumTrackContextMenu>( uri, versionMajor, versionMinor, "AlbumTrackContextMenu" );
-        qmlRegisterType<URLContextMenu>( uri, versionMajor, versionMinor, "URLContextMenu" );
-        qmlRegisterType<VideoContextMenu>( uri, versionMajor, versionMinor, "VideoContextMenu" );
-        qmlRegisterType<VideoGroupsContextMenu>( uri, versionMajor, versionMinor, "VideoGroupsContextMenu" );
-        qmlRegisterType<VideoFoldersContextMenu>( uri, versionMajor, versionMinor, "VideoFoldersContextMenu" );
         qmlRegisterType<PlaylistListContextMenu>( uri, versionMajor, versionMinor, "PlaylistListContextMenu" );
         qmlRegisterType<PlaylistMediaContextMenu>( uri, versionMajor, versionMinor, "PlaylistMediaContextMenu" );
 


=====================================
modules/gui/qt/medialibrary/qml/MediaGroupDisplay.qml
=====================================
@@ -23,6 +23,7 @@ import QtQuick 2.11
 import org.videolan.medialib 0.1
 
 import "qrc:///widgets/" as Widgets
+import "qrc:///util/" as Util
 import "qrc:///style/"
 
 VideoAll {
@@ -53,7 +54,7 @@ VideoAll {
         parentId: initialId
     }
 
-    contextMenu: VideoContextMenu { model: modelVideo }
+    contextMenu: Util.MLContextMenu { model: modelVideo; showPlayAsAudioAction: true }
 
     header: Column {
         width: root.width


=====================================
modules/gui/qt/medialibrary/qml/MusicAlbums.qml
=====================================
@@ -112,8 +112,9 @@ FocusScope {
         defaultCover: VLCStyle.noArtAlbumCover
     }
 
-    AlbumContextMenu {
+    Util.MLContextMenu {
         id: contextMenu
+
         model: albumModelId
     }
 


=====================================
modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
=====================================
@@ -85,8 +85,9 @@ FocusScope {
         model: artistModel
     }
 
-    ArtistContextMenu {
+    Util.MLContextMenu {
         id: contextMenu
+
         model: artistModel
     }
 


=====================================
modules/gui/qt/medialibrary/qml/MusicArtist.qml
=====================================
@@ -281,13 +281,15 @@ FocusScope {
         parentId: albumModel.parentId
     }
 
-    AlbumContextMenu {
+    Util.MLContextMenu {
         id: contextMenu
+
         model: albumModel
     }
 
-    AlbumTrackContextMenu {
+    Util.MLContextMenu {
         id: trackContextMenu
+
         model: trackModel
     }
 


=====================================
modules/gui/qt/medialibrary/qml/MusicGenres.qml
=====================================
@@ -124,8 +124,9 @@ FocusScope {
         }
     }
 
-    GenreContextMenu {
+    Util.MLContextMenu {
         id: contextMenu
+
         model: genreModel
     }
 


=====================================
modules/gui/qt/medialibrary/qml/MusicTrackListDisplay.qml
=====================================
@@ -104,8 +104,9 @@ Widgets.KeyNavigableTableView {
         model: rootmodel
     }
 
-    AlbumTrackContextMenu {
+    Util.MLContextMenu {
         id: contextMenu
+
         model: rootmodel
     }
 }


=====================================
modules/gui/qt/medialibrary/qml/UrlListDisplay.qml
=====================================
@@ -78,8 +78,9 @@ Widgets.KeyNavigableTableView {
         model: urlModel
     }
 
-    URLContextMenu {
+    Util.MLContextMenu {
         id: contextMenu
+
         model: urlModel
     }
 


=====================================
modules/gui/qt/medialibrary/qml/VideoAll.qml
=====================================
@@ -27,6 +27,7 @@ import org.videolan.vlc 0.1
 import "qrc:///widgets/" as Widgets
 import "qrc:///main/"    as MainInterface
 import "qrc:///util/"    as Util
+import "qrc:///util/Helpers.js" as Helpers
 import "qrc:///style/"
 
 FocusScope {
@@ -282,8 +283,11 @@ FocusScope {
                 onContextMenuButtonClicked: {
                     gridView.rightClickOnItem(index);
 
-                    root.contextMenu.popup(modelSelect.selectedIndexes, globalMousePos,
-                                           { "information" : index });
+                    var options = {}
+                    if (Helpers.get(model, "isVideo", true))
+                        options["information"] = index
+
+                    root.contextMenu.popup(modelSelect.selectedIndexes, globalMousePos, options);
                 }
 
                 // Animations


=====================================
modules/gui/qt/medialibrary/qml/VideoAllSubDisplay.qml
=====================================
@@ -24,6 +24,7 @@ import org.videolan.vlc 0.1
 import org.videolan.medialib 0.1
 
 import "qrc:///widgets/" as Widgets
+import "qrc:///util/" as Util
 import "qrc:///style/"
 
 VideoAll {
@@ -52,7 +53,7 @@ VideoAll {
 
     model: !!_meta ? _meta.model : null
 
-    contextMenu: !!_meta ? _meta.contextMenu : null
+    contextMenu: Util.MLContextMenu { model: _meta ? _meta.model : null; showPlayAsAudioAction: true }
 
     // Functions
 
@@ -119,8 +120,6 @@ VideoAll {
 
             property var model: MLVideoModel { ml: MediaLib }
 
-            property var contextMenu: VideoContextMenu { model: metaVideo.model }
-
             function onAction(indexes) {
                 g_mainDisplay.showPlayer()
 
@@ -142,8 +141,6 @@ VideoAll {
 
             property var model: MLVideoGroupsModel { ml: MediaLib }
 
-            property var contextMenu: VideoGroupsContextMenu { model: metaGroup.model }
-
             function onAction(indexes) {
                 var index = indexes[0]
 
@@ -188,8 +185,6 @@ VideoAll {
 
             property var model: MLVideoFoldersModel { ml: MediaLib }
 
-            property var contextMenu: VideoFoldersContextMenu { model: metaFolder.model }
-
             function onAction(indexes) {
                 var index = indexes[0]
 


=====================================
modules/gui/qt/medialibrary/qml/VideoDisplayRecentVideos.qml
=====================================
@@ -50,10 +50,12 @@ FocusScope {
 
     // Childs
 
-    VideoContextMenu {
+    Util.MLContextMenu {
         id: contextMenu
 
         model: listView.model
+
+        showPlayAsAudioAction: true
     }
 
     Column {


=====================================
modules/gui/qt/menus/qml_menu_wrapper.cpp
=====================================
@@ -18,16 +18,8 @@
 #include "qml_menu_wrapper.hpp"
 #include "menus.hpp"
 #include "medialibrary/medialib.hpp"
-#include "medialibrary/mlvideomodel.hpp"
-#include "medialibrary/mlvideogroupsmodel.hpp"
-#include "medialibrary/mlvideofoldersmodel.hpp"
 #include "medialibrary/mlplaylistlistmodel.hpp"
 #include "medialibrary/mlplaylistmodel.hpp"
-#include "medialibrary/mlalbummodel.hpp"
-#include "medialibrary/mlartistmodel.hpp"
-#include "medialibrary/mlgenremodel.hpp"
-#include "medialibrary/mlalbumtrackmodel.hpp"
-#include "medialibrary/mlurlmodel.hpp"
 #include "medialibrary/mlbookmarkmodel.hpp"
 #include "network/networkdevicemodel.hpp"
 #include "network/networkmediamodel.hpp"
@@ -36,6 +28,7 @@
 #include "dialogs/dialogs_provider.hpp"
 
 // Qt includes
+#include <QPainter>
 #include <QSignalMapper>
 #include <QScreen>
 
@@ -589,275 +582,6 @@ void QmlAudioMenu::beforePopup(QMenu * menu) /* override */
     });
 }
 
-BaseMedialibMenu::BaseMedialibMenu(QObject* parent)
-    : QObject(parent)
-{}
-
-void BaseMedialibMenu::medialibAudioContextMenu(MediaLib* ml, const QVariantList& mlId, const QPoint& pos, const QVariantMap& options)
-{
-    m_menu = std::make_unique<QMenu>();
-    QAction* action;
-
-    action = m_menu->addAction( qtr("Add and play") );
-    connect(action, &QAction::triggered, [ml, mlId]( ) {
-        ml->addAndPlay(mlId);
-    });
-
-    action = m_menu->addAction( qtr("Enqueue") );
-    connect(action, &QAction::triggered, [ml, mlId]( ) {
-        ml->addToPlaylist(mlId);
-    });
-
-    action = m_menu->addAction( qtr("Add to playlist") );
-    connect(action, &QAction::triggered, [mlId]( ) {
-        DialogsProvider::getInstance()->playlistsDialog(mlId);
-    });
-
-    if (options.contains("information") && options["information"].type() == QVariant::Int) {
-
-        action = m_menu->addAction( qtr("Information") );
-        QSignalMapper* sigmapper = new QSignalMapper(m_menu.get());
-        connect(action, &QAction::triggered, sigmapper, QOverload<>::of(&QSignalMapper::map));
-        sigmapper->setMapping(action, options["information"].toInt());
-        connect(sigmapper, QSIGNALMAPPER_MAPPEDINT_SIGNAL,
-                this, &BaseMedialibMenu::showMediaInformation);
-    }
-    m_menu->popup(pos);
-}
-
-AlbumContextMenu::AlbumContextMenu(QObject* parent)
-    : BaseMedialibMenu(parent)
-{}
-
-void AlbumContextMenu::popup(const QModelIndexList& selected, QPoint pos, QVariantMap options)
-{
-    BaseMedialibMenu::popup(m_model, MLAlbumModel::ALBUM_ID, selected, pos, options);
-}
-
-
-ArtistContextMenu::ArtistContextMenu(QObject* parent)
-    : BaseMedialibMenu(parent)
-{}
-
-void ArtistContextMenu::popup(const QModelIndexList &selected, QPoint pos, QVariantMap options)
-{
-    BaseMedialibMenu::popup(m_model, MLArtistModel::ARTIST_ID, selected, pos, options);
-}
-
-GenreContextMenu::GenreContextMenu(QObject* parent)
-    : BaseMedialibMenu(parent)
-{}
-
-void GenreContextMenu::popup(const QModelIndexList& selected, QPoint pos, QVariantMap options)
-{
-    BaseMedialibMenu::popup(m_model, MLGenreModel::GENRE_ID, selected, pos, options);
-}
-
-AlbumTrackContextMenu::AlbumTrackContextMenu(QObject* parent)
-    : BaseMedialibMenu(parent)
-{}
-
-void AlbumTrackContextMenu::popup(const QModelIndexList &selected, QPoint pos, QVariantMap options)
-{
-    BaseMedialibMenu::popup(m_model, MLAlbumTrackModel::TRACK_ID, selected, pos, options);
-}
-
-URLContextMenu::URLContextMenu(QObject* parent)
-    : BaseMedialibMenu(parent)
-{}
-
-void URLContextMenu::popup(const QModelIndexList &selected, QPoint pos, QVariantMap options)
-{
-    BaseMedialibMenu::popup(m_model, MLUrlModel::URL_ID, selected, pos, options);
-}
-
-
-VideoContextMenu::VideoContextMenu(QObject* parent)
-    : QObject(parent)
-{}
-
-
-void VideoContextMenu::popup(const QModelIndexList& selected, QPoint pos, QVariantMap options)
-{
-    if (!m_model)
-        return;
-
-    m_menu = std::make_unique<QMenu>();
-    QAction* action;
-
-    MediaLib* ml= m_model->ml();
-
-    QVariantList itemIdList;
-    for (const QModelIndex& modelIndex : selected)
-        itemIdList.push_back(m_model->data(modelIndex, MLVideoModel::VIDEO_ID));
-
-    action = m_menu->addAction( qtr("Add and play") );
-
-    connect(action, &QAction::triggered, [ml, itemIdList, options]( ) {
-        ml->addAndPlay(itemIdList, options["player-options"].toStringList());
-    });
-
-    action = m_menu->addAction( qtr("Enqueue") );
-    connect(action, &QAction::triggered, [ml, itemIdList]( ) {
-        ml->addToPlaylist(itemIdList);
-    });
-
-    action = m_menu->addAction( qtr("Add to playlist") );
-    connect(action, &QAction::triggered, [itemIdList]( ) {
-        DialogsProvider::getInstance()->playlistsDialog(itemIdList);
-    });
-
-    action = m_menu->addAction( qtr("Play as audio") );
-    connect(action, &QAction::triggered, [ml, itemIdList, options]( ) {
-        QStringList list = options["player-options"].toStringList();
-        list.prepend(":no-video");
-        ml->addAndPlay(itemIdList, list);
-    });
-
-    if (options.contains("information") && options["information"].type() == QVariant::Int) {
-        action = m_menu->addAction( qtr("Information") );
-        QSignalMapper* sigmapper = new QSignalMapper(m_menu.get());
-        connect(action, &QAction::triggered, sigmapper, QOverload<>::of(&QSignalMapper::map));
-        sigmapper->setMapping(action, options["information"].toInt());
-        connect(sigmapper, QSIGNALMAPPER_MAPPEDINT_SIGNAL,
-                this, &VideoContextMenu::showMediaInformation);
-    }
-
-    m_menu->popup(pos);
-}
-
-//=================================================================================================
-// VideoGroupsContextMenu
-//=================================================================================================
-
-VideoGroupsContextMenu::VideoGroupsContextMenu(QObject * parent) : QObject(parent) {}
-
-void VideoGroupsContextMenu::popup(const QModelIndexList & selected, QPoint pos,
-                                   QVariantMap options)
-{
-    if (m_model == nullptr)
-        return;
-
-    QVariantList ids;
-
-    for (const QModelIndex & index : selected)
-        ids.push_back(m_model->data(index, MLVideoModel::VIDEO_ID));
-
-    m_menu = std::make_unique<QMenu>();
-
-    MediaLib * ml = m_model->ml();
-
-    QAction * action = m_menu->addAction(qtr("Add and play"));
-
-    connect(action, &QAction::triggered, [ml, ids, options]()
-    {
-        ml->addAndPlay(ids, options["player-options"].toStringList());
-    });
-
-    action = m_menu->addAction(qtr("Enqueue"));
-
-    connect(action, &QAction::triggered, [ml, ids]()
-    {
-        ml->addToPlaylist(ids);
-    });
-
-    action = m_menu->addAction(qtr("Add to playlist"));
-
-    connect(action, &QAction::triggered, [ids]()
-    {
-        DialogsProvider::getInstance()->playlistsDialog(ids);
-    });
-
-    action = m_menu->addAction(qtr("Play as audio"));
-
-    connect(action, &QAction::triggered, [ml, ids, options]()
-    {
-        QStringList list = options["player-options"].toStringList();
-
-        list.prepend(":no-video");
-
-        ml->addAndPlay(ids, list);
-    });
-
-    // NOTE: At the moment informations are only available for single video(s).
-    if (selected.count() == 1
-        &&
-        m_model->data(selected.first(), MLVideoGroupsModel::GROUP_IS_VIDEO) == true
-        &&
-        options.contains("information") && options["information"].type() == QVariant::Int)
-    {
-        action = m_menu->addAction(qtr("Information"));
-
-        QSignalMapper * mapper = new QSignalMapper(m_menu.get());
-
-        mapper->setMapping(action, options["information"].toInt());
-
-        connect(action, &QAction::triggered, mapper, QOverload<>::of(&QSignalMapper::map));
-
-        connect(mapper, QSIGNALMAPPER_MAPPEDINT_SIGNAL,
-                this, &VideoGroupsContextMenu::showMediaInformation);
-    }
-
-    m_menu->popup(pos);
-}
-
-// VideoFoldersContextMenu
-
-VideoFoldersContextMenu::VideoFoldersContextMenu(QObject * parent)
-    : QObject(parent)
-{}
-
-
-void VideoFoldersContextMenu::popup(const QModelIndexList & selected, QPoint pos,
-                                    QVariantMap options)
-{
-    if (m_model == nullptr)
-        return;
-
-    QVariantList ids;
-
-    for (const QModelIndex & index : selected)
-        ids.push_back(m_model->data(index, MLVideoFoldersModel::FOLDER_ID));
-
-    m_menu = std::make_unique<QMenu>();
-
-    MediaLib * ml = m_model->ml();
-
-    QAction * action = m_menu->addAction(qtr("Add and play"));
-
-    connect(action, &QAction::triggered, [ml, ids, options]()
-    {
-        ml->addAndPlay(ids, options["player-options"].toStringList());
-    });
-
-    action = m_menu->addAction(qtr("Enqueue"));
-
-    connect(action, &QAction::triggered, [ml, ids]()
-    {
-        ml->addToPlaylist(ids);
-    });
-
-    action = m_menu->addAction(qtr("Add to playlist"));
-
-    connect(action, &QAction::triggered, [ids]()
-    {
-        DialogsProvider::getInstance()->playlistsDialog(ids);
-    });
-
-    action = m_menu->addAction(qtr("Play as audio"));
-
-    connect(action, &QAction::triggered, [ml, ids, options]()
-    {
-        QStringList list = options["player-options"].toStringList();
-
-        list.prepend(":no-video");
-
-        ml->addAndPlay(ids, list);
-    });
-
-    m_menu->popup(pos);
-}
-
 //=================================================================================================
 // PlaylistListContextMenu
 //=================================================================================================


=====================================
modules/gui/qt/menus/qml_menu_wrapper.hpp
=====================================
@@ -27,14 +27,6 @@
 #include "maininterface/mainctx.hpp"
 
 class MediaLib;
-class MLAlbumModel;
-class MLGenreModel;
-class MLArtistModel;
-class MLAlbumTrackModel;
-class MLUrlModel;
-class MLVideoModel;
-class MLVideoGroupsModel;
-class MLVideoFoldersModel;
 class MLPlaylistListModel;
 class MLPlaylistModel;
 class NetworkDeviceModel;
@@ -293,143 +285,6 @@ protected: // QmlTrackMenu implementation
     void beforePopup(QMenu * menu) override;
 };
 
-class BaseMedialibMenu : public QObject
-{
-    Q_OBJECT
-public:
-    BaseMedialibMenu(QObject* parent = nullptr);
-signals:
-    void showMediaInformation(int index);
-
-protected:
-    void medialibAudioContextMenu(MediaLib* ml, const QVariantList& mlId, const QPoint& pos, const QVariantMap& options);
-
-    template<typename ModelType>
-    void popup(ModelType* model, typename ModelType::Roles role,  const QModelIndexList &selected, const  QPoint& pos, const QVariantMap& options) {
-        if (!model)
-            return;
-
-        MediaLib* ml= model->ml();
-        if (!ml)
-            return;
-
-        QVariantList itemIdList;
-        for (const QModelIndex& modelIndex : selected)
-            itemIdList.push_back(model->data(modelIndex, role));
-        medialibAudioContextMenu(ml, itemIdList, pos, options);
-    }
-
-private:
-    std::unique_ptr<QMenu> m_menu;
-};
-
-class AlbumContextMenu : public BaseMedialibMenu {
-    Q_OBJECT
-    SIMPLE_MENU_PROPERTY(MLAlbumModel*, model, nullptr)
-public:
-    AlbumContextMenu(QObject* parent = nullptr);
-public slots:
-    void popup(const QModelIndexList& selected, QPoint pos, QVariantMap options = {});
-};
-
-
-class ArtistContextMenu : public BaseMedialibMenu {
-    Q_OBJECT
-    SIMPLE_MENU_PROPERTY(MLArtistModel*, model, nullptr)
-public:
-    ArtistContextMenu(QObject* parent = nullptr);
-public slots:
-    void popup(const QModelIndexList& selected, QPoint pos, QVariantMap options = {});
-};
-
-
-class GenreContextMenu : public BaseMedialibMenu {
-    Q_OBJECT
-    SIMPLE_MENU_PROPERTY(MLGenreModel*, model, nullptr)
-public:
-    GenreContextMenu(QObject* parent = nullptr);
-public slots:
-    void popup(const QModelIndexList& selected, QPoint pos, QVariantMap options = {});
-};
-
-
-class AlbumTrackContextMenu : public BaseMedialibMenu {
-    Q_OBJECT
-    SIMPLE_MENU_PROPERTY(MLAlbumTrackModel*, model, nullptr)
-public:
-    AlbumTrackContextMenu(QObject* parent = nullptr);
-public slots:
-    void popup(const QModelIndexList& selected, QPoint pos, QVariantMap options = {});
-};
-
-class URLContextMenu : public BaseMedialibMenu {
-    Q_OBJECT
-    SIMPLE_MENU_PROPERTY(MLUrlModel*, model, nullptr)
-public:
-    URLContextMenu(QObject* parent = nullptr);
-public slots:
-    void popup(const QModelIndexList& selected, QPoint pos, QVariantMap options = {});
-};
-
-class VideoContextMenu : public QObject {
-    Q_OBJECT
-    SIMPLE_MENU_PROPERTY(MLVideoModel*, model, nullptr)
-public:
-    VideoContextMenu(QObject* parent = nullptr);
-
-public slots:
-    void popup(const QModelIndexList& selected, QPoint pos, QVariantMap options = {} );
-signals:
-    void showMediaInformation(int index);
-private:
-    std::unique_ptr<QMenu> m_menu;
-};
-
-//-------------------------------------------------------------------------------------------------
-// Groups
-//-------------------------------------------------------------------------------------------------
-
-class VideoGroupsContextMenu : public QObject {
-    Q_OBJECT
-
-    SIMPLE_MENU_PROPERTY(MLVideoGroupsModel *, model, nullptr)
-
-public:
-    VideoGroupsContextMenu(QObject * parent = nullptr);
-
-public slots:
-    void popup(const QModelIndexList & selected, QPoint pos, QVariantMap options = {});
-
-signals:
-    void showMediaInformation(int index);
-
-private:
-    std::unique_ptr<QMenu> m_menu;
-};
-
-// Folders
-
-class VideoFoldersContextMenu : public QObject {
-    Q_OBJECT
-
-    SIMPLE_MENU_PROPERTY(MLVideoFoldersModel *, model, nullptr)
-
-public:
-    VideoFoldersContextMenu(QObject * parent = nullptr);
-
-public slots:
-    void popup(const QModelIndexList & selected, QPoint pos, QVariantMap options = {});
-
-signals:
-    // FIXME: This signal is required for VideoAll Connections.
-    void showMediaInformation(int index);
-
-private:
-    std::unique_ptr<QMenu> m_menu;
-};
-
-//-------------------------------------------------------------------------------------------------
-
 class PlaylistListContextMenu : public QObject {
     Q_OBJECT
     SIMPLE_MENU_PROPERTY(MLPlaylistListModel *, model, nullptr)


=====================================
modules/gui/qt/util/qml/Helpers.js
=====================================
@@ -50,7 +50,7 @@ function isValidInstanceOf(object, type) {
 // or the value is invalid, returns defaultValue
 function get(dict, key, defaultValue) {
     var v = typeof dict !== "undefined" ? dict[key] : undefined
-    return !v ? defaultValue : v
+    return typeof v === "undefined" ? defaultValue : v
 }
 
 // NOTE: This allows us to force another 'reason' even when the item has activeFocus.
@@ -72,3 +72,7 @@ function contains(rect, pos) {
     return (clamp(pos.x, rect.x, rect.x + rect.width) === pos.x)
             && (clamp(pos.y, rect.y, rect.y + rect.height) === pos.y)
 }
+
+function isInteger(data) {
+    return (typeof data === 'number' && (data % 1) === 0)
+}


=====================================
modules/gui/qt/util/qml/MLContextMenu.qml
=====================================
@@ -0,0 +1,102 @@
+
+/*****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+import QtQml 2.11
+
+import org.videolan.vlc 0.1
+
+import "qrc:///util/Helpers.js" as Helpers
+
+// @brief - a generic ML context menu
+NativeMenu {
+    id: root
+
+    /* required */ property var model: null
+
+    property string idDataRole: "id"
+
+    property bool showPlayAsAudioAction: false
+
+    signal showMediaInformation(int index)
+
+    actions: [{
+            "text": I18n.qtr("Play"),
+            "action": addAndPlay
+        }, {
+            "text": I18n.qtr("Play as audio"),
+            "action": playAsAudio,
+            "visible": root.showPlayAsAudioAction
+        }, {
+            "text": I18n.qtr("Enqueue"),
+            "action": enqueue
+        }, {
+            "text": I18n.qtr("Add to a playlist"),
+            "action": addToAPlaylist
+        }, {
+            "text": I18n.qtr("Information"),
+            "action": _signalShowInformation,
+            "visible": showInformationAvailable
+        }]
+
+    onRequestData: {
+        model.getData(indexes, function (data) {
+            setData(requestID, data)
+        })
+    }
+
+    function showInformationAvailable(options, indexes) {
+        return indexes.length === 1
+                && Helpers.isInteger(Helpers.get(options, "information", null))
+    }
+
+    function addAndPlay(dataList, options, indexes) {
+        model.ml.addAndPlay(_mlIDList(dataList), _playerOptions(options))
+    }
+
+    function playAsAudio(dataList, options, indexes) {
+        model.ml.addAndPlay(_mlIDList(dataList), _playerOptions(options, ":no-video"))
+    }
+
+    function enqueue(dataList, options, indexes) {
+        model.ml.addToPlaylist(_mlIDList(dataList), _playerOptions(options))
+    }
+
+    function addToAPlaylist(dataList, options, indexes) {
+        DialogsProvider.playlistsDialog(_mlIDList(dataList))
+    }
+
+    function _signalShowInformation(dataList, options) {
+        var index = Helpers.get(options, "information", null)
+        console.assert(Helpers.isInteger(index))
+        showMediaInformation(index)
+    }
+
+    function _playerOptions(options, extraOptions) {
+        var playerOpts = Helpers.get(options, "player-options", [])
+        return playerOpts.concat(extraOptions)
+    }
+
+    function _mlIDList(dataList) {
+        var idList = []
+        for (var i in dataList) {
+            idList.push(dataList[i][idDataRole])
+        }
+
+        return idList
+    }
+}


=====================================
modules/gui/qt/util/qml/NativeMenu.qml
=====================================
@@ -0,0 +1,115 @@
+
+/*****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+import QtQml 2.11
+
+import org.videolan.vlc 0.1
+
+
+// @brief - a class that can be used to create native menus with support
+// to asyncronously retreive data from MLBaseModel like model
+
+VanillaObject {
+    id: root
+
+    /**
+      actions - list of action to show
+
+      each action is an Object and contains following keys
+        "text" - (string) display text of the action
+
+        "action" - (function(dataList, options, indexes)) a function that will be called when action is selected
+
+        "visible" - (Boolean or function(options, indexes) -> Boolean) (optional) a boolean value or function which
+                    controls whether the action is shown in the menu following 'popup' call
+
+       e.g see MLContextMenu.qml
+    **/
+
+    property var actions: []
+
+    signal requestData(var requestID, var indexes)
+
+
+    property var _options: null
+
+    property var _indexes: []
+
+    property bool _pendingData: false
+
+    property var _dataList: null
+
+    property int _currentRequest: 0
+
+    property int _actionOnDataReceived: -1
+
+    property var _effectiveActions: null
+
+
+    function popup(_indexes, point, _options) {
+        root._options = _options
+        root._indexes = _indexes
+        _actionOnDataReceived = -1
+        _pendingData = true
+        _dataList = null
+
+        var requestID = ++_currentRequest
+        requestData(requestID, _indexes)
+
+        var textStrings = []
+        _effectiveActions = []
+        for (var i in actions) {
+            if (!actions[i].hasOwnProperty("visible")
+                    || (typeof actions[i].visible === "boolean" && actions[i].visible)
+                    || (typeof actions[i].visible === "function" && actions[i].visible(_options, _indexes))) {
+                _effectiveActions.push(actions[i])
+                textStrings.push(actions[i].text)
+            }
+        }
+
+        menu.popup(point, textStrings)
+    }
+
+    function setData(id, data) {
+        if (_currentRequest !== id)
+            return;
+
+        _dataList = data
+        _pendingData = false
+
+        if (_actionOnDataReceived !== -1)
+           _executeAction(_actionOnDataReceived)
+    }
+
+    function _executeAction(index) {
+        var action = root._effectiveActions[index]
+        action.action(_dataList, _options, _indexes)
+    }
+
+
+    StringListMenu {
+        id: menu
+
+        onSelected: {
+            if (root._pendingData)
+                root._actionOnDataReceived = index
+            else
+                root._executeAction(index)
+        }
+    }
+}


=====================================
modules/gui/qt/util/qml/VanillaObject.qml
=====================================
@@ -0,0 +1,27 @@
+
+/*****************************************************************************
+ * Copyright (C) 2022 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+import QtQuick 2.11
+
+QtObject {
+    id: object
+
+    default property alias children: object.__children
+
+    property list<QtObject> __children: [QtObject {}]
+}


=====================================
modules/gui/qt/vlc.qrc
=====================================
@@ -32,6 +32,9 @@
         <file alias="ViewDragAutoScrollHandler.qml">util/qml/ViewDragAutoScrollHandler.qml</file>
         <file alias="BindingRev8.qml">util/qml/BindingRev8.qml</file>
         <file alias="BindingRev14.qml">util/qml/BindingRev14.qml</file>
+        <file alias="VanillaObject.qml">util/qml/VanillaObject.qml</file>
+        <file alias="NativeMenu.qml">util/qml/NativeMenu.qml</file>
+        <file alias="MLContextMenu.qml">util/qml/MLContextMenu.qml</file>
     </qresource>
     <qresource prefix="/toolbar">
         <file alias="faster.svg">pixmaps/faster.svg</file>



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/90f810121b42d7a2dc6e66d8c0e0711e3589f355...3d9a2e7d241c58743a9946f96d3469371133bb60

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/90f810121b42d7a2dc6e66d8c0e0711e3589f355...3d9a2e7d241c58743a9946f96d3469371133bb60
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list