[vlc-devel] [PATCH 8/9] qt: provide recent menu based on medialibrary model

Pierre Lamot pierre at videolabs.io
Thu Oct 15 11:25:11 CEST 2020


---
 modules/gui/qt/menus/custom_menus.cpp | 78 +++++++++++++++++++++++++++
 modules/gui/qt/menus/custom_menus.hpp | 21 ++++++++
 modules/gui/qt/menus/menus.cpp        | 12 +++++
 3 files changed, 111 insertions(+)

diff --git a/modules/gui/qt/menus/custom_menus.cpp b/modules/gui/qt/menus/custom_menus.cpp
index 5e431d1680..d8fc4c1980 100644
--- a/modules/gui/qt/menus/custom_menus.cpp
+++ b/modules/gui/qt/menus/custom_menus.cpp
@@ -322,3 +322,81 @@ void BooleanPropertyAction::setModelChecked(bool checked)
 {
     m_model->setProperty(qtu(m_propertyName), QVariant::fromValue<bool>(checked) );
 }
+
+
+RecentMenu::RecentMenu(MLRecentsModel* model, MediaLib* ml,  QWidget* parent)
+    : QMenu(parent)
+    , m_model(model)
+    , m_ml(ml)
+{
+    connect(m_model, &MLRecentsModel::rowsAboutToBeRemoved, this, &RecentMenu::onRowsAboutToBeRemoved);
+    connect(m_model, &MLRecentsModel::rowsInserted, this, &RecentMenu::onRowInserted);
+    connect(m_model, &MLRecentsModel::dataChanged, this, &RecentMenu::onDataChanged);
+    connect(m_model, &MLRecentsModel::modelAboutToBeReset, this, &RecentMenu::onModelAboutToBeReset);
+    connect(m_model, &MLRecentsModel::modelReset, this, &RecentMenu::onModelReset);
+    m_separator = addSeparator();
+    addAction( qtr("&Clear"), m_model, &MLRecentsModel::clearHistory );
+    onModelReset();
+}
+
+void RecentMenu::onRowsAboutToBeRemoved(const QModelIndex&, int first, int last)
+{
+    for (int i = last; i >= first; i--)
+    {
+        QAction* action = actions()[i];
+        delete action;
+    }
+    if (actions().count() == 0)
+        setEnabled(false);
+}
+
+void RecentMenu::onRowInserted(const QModelIndex&, int first, int last)
+{
+    for (int i = first; i <= last; i++)
+    {
+        QModelIndex index = m_model->index(i);
+        QString url = m_model->data(index, MLRecentsModel::RECENT_MEDIA_URL).toString();
+
+        QAction *choiceAction = new QAction(url, this);
+        insertAction(m_separator , choiceAction);
+        connect(choiceAction, &QAction::triggered, [this, i](){
+            QModelIndex dataIndex = m_model->index(i);
+            MLParentId id = m_model->data(dataIndex, MLRecentsModel::RECENT_MEDIA_ID).value<MLParentId>();
+            m_ml->addAndPlay(id);
+        });
+        setEnabled(true);
+    }
+}
+
+void RecentMenu::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& )
+{
+    for (int i = topLeft.row(); i <= bottomRight.row(); i++)
+    {
+        QAction *choiceAction = actions()[i];
+
+        QModelIndex index = m_model->index(i);
+        QString title = m_model->data(index, MLRecentsModel::RECENT_MEDIA_URL).toString();
+
+        choiceAction->setText(title);
+    }
+}
+
+void RecentMenu::onModelAboutToBeReset()
+{
+    for (QAction* action  :actions())
+    {
+        if (action == m_separator)
+            break;
+        delete action;
+    }
+    setEnabled(false);
+}
+
+void RecentMenu::onModelReset()
+{
+    int nb_rows = m_model->rowCount();
+    if (nb_rows == 0)
+        setEnabled(false);
+    else
+        onRowInserted({}, 0, nb_rows - 1);
+}
diff --git a/modules/gui/qt/menus/custom_menus.hpp b/modules/gui/qt/menus/custom_menus.hpp
index 1dc62a76d1..5c2f74ccda 100644
--- a/modules/gui/qt/menus/custom_menus.hpp
+++ b/modules/gui/qt/menus/custom_menus.hpp
@@ -25,6 +25,7 @@
 
 #include <QMenu>
 #include <QAbstractListModel>
+#include "medialibrary/mlrecentsmodel.hpp"
 
 class RendererAction : public QAction
 {
@@ -123,4 +124,24 @@ private:
     QString m_propertyName;
 };
 
+class RecentMenu : public QMenu
+{
+    Q_OBJECT
+public:
+    RecentMenu(MLRecentsModel* model, MediaLib* ml, QWidget *parent = nullptr);
+
+private slots:
+    void onRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
+    void onRowInserted(const QModelIndex &parent, int first, int last);
+    void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());
+    void onModelAboutToBeReset();
+    void onModelReset();
+
+private:
+    MLRecentsModel* m_model = nullptr;
+    QAction* m_separator = nullptr;
+    MediaLib* m_ml = nullptr;
+};
+
+
 #endif // CUSTOM_MENUS_HPP
diff --git a/modules/gui/qt/menus/menus.cpp b/modules/gui/qt/menus/menus.cpp
index d8f77d7486..997298fe5a 100644
--- a/modules/gui/qt/menus/menus.cpp
+++ b/modules/gui/qt/menus/menus.cpp
@@ -45,6 +45,7 @@
 #include "dialogs/extended/extended_panels.hpp"
 #include "util/varchoicemodel.hpp"
 #include "medialibrary/medialib.hpp"
+#include "medialibrary/mlrecentsmodel.hpp"
 
 
 #include <QMenu>
@@ -220,6 +221,17 @@ QMenu *VLCMenuBar::FileMenu( intf_thread_t *p_intf, QMenu *menu, MainInterface *
     addDPStaticEntry( menu, qtr( "Open &Location from clipboard" ),
                       NULL, &DialogsProvider::openUrlDialog, "Ctrl+V" );
 
+    if( var_InheritBool( p_intf, "qt-recentplay" ) && mi->hasMediaLibrary() )
+    {
+        MLRecentsModel* recentModel = new MLRecentsModel(nullptr);
+        recentModel->setMl(mi->getMediaLibrary());
+        recentModel->setNumberOfItemsToShow(10);
+        QMenu* recentsMenu = new RecentMenu(recentModel, mi->getMediaLibrary(), menu);
+        recentsMenu->setTitle(qtr( "Open &Recent Media" ) );
+        recentModel->setParent(recentsMenu);
+        menu->addMenu( recentsMenu );
+    }
+
     menu->addSeparator();
 
     addDPStaticEntry( menu, qtr( I_PL_SAVE ), "", &DialogsProvider::savePlayingToPlaylist,
-- 
2.25.1



More information about the vlc-devel mailing list