[vlc-devel] [PATCH] qt: implement recent medias menu

Thomas Guillem thomas at gllm.fr
Wed Apr 24 12:35:35 CEST 2019



On Wed, Apr 24, 2019, at 12:17, Abel Tesfaye wrote:
> Hello,
> 
> If the ML is an optional component then wouldn't the recents.cpp/hpp implementation be required as a fallback(incase ML isn't available)?

I think so yes.

Here is my config:
Debian testing with Qt 5.11.3 on gnome-shell (via X11). But pierre could not reproduce it either with a similar config.

> 
> Thanks
> 
> On Wed, 24 Apr 2019 at 11:32, Hugo Beauzée-Luyssen <hugo at beauzee.fr> wrote:
>> On Wed, Apr 24, 2019, at 10:03 AM, Thomas Guillem wrote:
>>  > Hello Abel,
>>  > 
>>  > I'm OK with your patches bug I got 2 issues (that could be fixed 
>>  > afterward in seperate commits)
>>  > 
>>  > - Entries are disapearing when I hover them with my mouse pointer, cf. 
>>  > https://gllm.fr/~tom/vlc/vlc-recents-bug.png It seems that I'm the only 
>>  > one with this issue (Pierre could not reproduce it).
>>  > 
>>  > - The name of the media should be displayed instead of the URI.
>>  > 
>>  > Regards,
>>  > 
>>  > On Tue, Apr 23, 2019, at 12:59, Abel Tesfaye wrote:
>>  > > The sub menu located at media -> open recent media used to be empty. 
>>  > > This commit fixed that.
>>  > > ---
>>  > > modules/gui/qt/Makefile.am | 3 +
>>  > > .../gui/qt/components/player_controller.cpp | 3 +
>>  > > .../gui/qt/components/recent_media_model.cpp | 97 +++++++++++++++++++
>>  > > .../gui/qt/components/recent_media_model.hpp | 69 +++++++++++++
>>  > > modules/gui/qt/dialogs_provider.cpp | 2 -
>>  > > modules/gui/qt/main_interface.cpp | 3 +-
>>  > > modules/gui/qt/qml/menus/MainDropdownMenu.qml | 3 +-
>>  > > modules/gui/qt/qml/menus/MediaMenu.qml | 36 ++++++-
>>  > > modules/gui/qt/recents.cpp | 1 +
>>  > > modules/gui/qt/recents.hpp | 9 +-
>>  > > 10 files changed, 218 insertions(+), 8 deletions(-)
>>  > > create mode 100644 modules/gui/qt/components/recent_media_model.cpp
>>  > > create mode 100644 modules/gui/qt/components/recent_media_model.hpp
>>  > > 
>>  > > diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
>>  > > index 5f1498e7ad..203ded3d90 100644
>>  > > --- a/modules/gui/qt/Makefile.am
>>  > > +++ b/modules/gui/qt/Makefile.am
>>  > > @@ -103,6 +103,8 @@ libqt_plugin_la_SOURCES = \
>>  > > gui/qt/components/controller.cpp gui/qt/components/controller.hpp \
>>  > > gui/qt/components/controller_widget.cpp \
>>  > > gui/qt/components/controller_widget.hpp \
>>  > > + gui/qt/components/recent_media_model.cpp \
>>  > > + gui/qt/components/recent_media_model.hpp \
>>  > > gui/qt/components/voutwindow/videosurface.cpp \
>>  > > gui/qt/components/voutwindow/videosurface.hpp \
>>  > > gui/qt/components/voutwindow/qvoutwindow.cpp \
>>  > > @@ -253,6 +255,7 @@ nodist_libqt_plugin_la_SOURCES = \
>>  > > gui/qt/components/controller.moc.cpp \
>>  > > gui/qt/components/controller_widget.moc.cpp \
>>  > > gui/qt/components/custom_menus.moc.cpp \
>>  > > + gui/qt/components/recent_media_model.moc.cpp \
>>  > > gui/qt/components/voutwindow/videosurface.moc.cpp \
>>  > > gui/qt/components/voutwindow/qvoutwindow.moc.cpp \
>>  > > gui/qt/components/voutwindow/qvoutwindowdummy.moc.cpp \
>>  > > diff --git a/modules/gui/qt/components/player_controller.cpp 
>>  > > b/modules/gui/qt/components/player_controller.cpp
>>  > > index 5a445d174c..cd8fc33b45 100644
>>  > > --- a/modules/gui/qt/components/player_controller.cpp
>>  > > +++ b/modules/gui/qt/components/player_controller.cpp
>>  > > @@ -202,6 +202,9 @@ static void 
>>  > > on_player_current_media_changed(vlc_player_t *, input_item_t *new_m
>>  > > that->UpdateName( newMediaPtr.get() );
>>  > > that->UpdateArt( newMediaPtr.get() );
>>  > > that->UpdateMeta( newMediaPtr.get() );
>>  > > +
>>  > > + RecentsMRL::getInstance( that->p_intf )->addRecent( 
>>  > > newMediaPtr.get()->psz_uri );
>>  > > +
>>  > > emit q->inputChanged( newMediaPtr != nullptr );
>>  > > });
>>  > > }
>>  > > diff --git a/modules/gui/qt/components/recent_media_model.cpp 
>>  > > b/modules/gui/qt/components/recent_media_model.cpp
>>  > > new file mode 100644
>>  > > index 0000000000..447409ce20
>>  > > --- /dev/null
>>  > > +++ b/modules/gui/qt/components/recent_media_model.cpp
>>  > > @@ -0,0 +1,97 @@
>>  > > +/*****************************************************************************
>>  > > + * Copyright (C) 2019 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.
>>  > > + 
>>  > > *****************************************************************************/
>>  > > +
>>  > > +#include "recent_media_model.hpp"
>>  > > +#include <cassert>
>>  > > +
>>  > > +namespace {
>>  > > + enum Roles
>>  > > + {
>>  > > + MRLRole = Qt::UserRole
>>  > > + };
>>  > > +}
>>  > > +
>>  > > +VLCRecentMediaModel::VLCRecentMediaModel(intf_thread_t *p_intf,QObject 
>>  > > *parent)
>>  > > + : QAbstractListModel(parent)
>>  > > +{
>>  > > + assert(p_intf);
>>  > > + rmrl = RecentsMRL::getInstance(p_intf);
>>  > > +
>>  > > + connect(rmrl, SIGNAL(saved()), this, SLOT(update()));
>>  > > + connect(this, SIGNAL(limitChanged()), this, SLOT(update()));
>>  > > +
>>  > > + update();
>>  > > +}
>>  > > +
>>  > > +int VLCRecentMediaModel::rowCount(QModelIndex const & ) const
>>  > > +{
>>  > > + return items.count();
>>  > > +}
>>  > > +
>>  > > +QVariant VLCRecentMediaModel::data(QModelIndex const &index, const int 
>>  > > role) const
>>  > > +{
>>  > > + if (!index.isValid())
>>  > > + return {};
>>  > > + switch (role)
>>  > > + {
>>  > > + case MRLRole :
>>  > > + return QVariant::fromValue(items[index.row()]);
>>  > > + default :
>>  > > + return {};
>>  > > + }
>>  > > +}
>>  > > +
>>  > > +QHash<int, QByteArray> VLCRecentMediaModel::roleNames() const
>>  > > +{
>>  > > + QHash<int, QByteArray> roleNames;
>>  > > + roleNames.insert(MRLRole, "mrl");
>>  > > + return roleNames;
>>  > > +}
>>  > > +
>>  > > +void VLCRecentMediaModel::clear()
>>  > > +{
>>  > > + if (!items.isEmpty())
>>  > > + {
>>  > > + rmrl->clear();
>>  > > + update();
>>  > > + }
>>  > > +}
>>  > > +
>>  > > +void VLCRecentMediaModel::update()
>>  > > +{
>>  > > + beginResetModel();
>>  > > + items = rmrl->recentList().mid(0,i_limit);
>>  > > + endResetModel();
>>  > > +}
>>  > > +
>>  > > +QStringList VLCRecentMediaModel::getItems()
>>  > > +{
>>  > > + return items;
>>  > > +}
>>  > > +
>>  > > +int VLCRecentMediaModel::getLimit() const
>>  > > +{
>>  > > + return i_limit; 
>>  > > +}
>>  > > +
>>  > > +void VLCRecentMediaModel::setLimit(int l)
>>  > > +{
>>  > > + i_limit = l;
>>  > > + update();
>>  > > + emit limitChanged();
>>  > > +}
>>  > > diff --git a/modules/gui/qt/components/recent_media_model.hpp 
>>  > > b/modules/gui/qt/components/recent_media_model.hpp
>>  > > new file mode 100644
>>  > > index 0000000000..c37fae9b77
>>  > > --- /dev/null
>>  > > +++ b/modules/gui/qt/components/recent_media_model.hpp
>>  > > @@ -0,0 +1,69 @@
>>  > > +/*****************************************************************************
>>  > > + * Copyright (C) 2019 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.
>>  > > + 
>>  > > *****************************************************************************/
>>  > > +
>>  > > +#ifndef VLC_RECENT_MEDIA_MODEL_HPP
>>  > > +#define VLC_RECENT_MEDIA_MODEL_HPP
>>  > > +
>>  > > +#ifdef HAVE_CONFIG_H
>>  > > +
>>  > > +# include "config.h"
>>  > > +
>>  > > +#endif
>>  > > +
>>  > > +#include "qt.hpp"
>>  > > +#include <QAbstractListModel>
>>  > > +
>>  > > +#include <QObject>
>>  > > +#include <QStringList>
>>  > > +#include "recents.hpp"
>>  > > +
>>  > > +class VLCRecentMediaModel : public QAbstractListModel
>>  > > +{
>>  > > + Q_OBJECT
>>  > > + Q_PROPERTY(int limit READ getLimit WRITE setLimit NOTIFY 
>>  > > limitChanged)
>>  > > +
>>  > > +public:
>>  > > + VLCRecentMediaModel(intf_thread_t *p_intf,QObject * parent = 
>>  > > nullptr);
>>  > > +
>>  > > + Q_INVOKABLE void clear();
>>  > > +
>>  > > + Q_INVOKABLE int rowCount(QModelIndex const &parent = {}) const 
>>  > > override;
>>  > > +
>>  > > + QVariant data(QModelIndex const &index, const int role = 
>>  > > Qt::DisplayRole) const override;
>>  > > +
>>  > > + QHash<int, QByteArray> roleNames() const override;
>>  > > +
>>  > > + QStringList items;
>>  > > +
>>  > > + void setLimit(int l);
>>  > > + int getLimit() const;
>>  > > +
>>  > > +private:
>>  > > + RecentsMRL *rmrl;
>>  > > + int i_limit = 10;
>>  > > +
>>  > > +signals:
>>  > > + void limitChanged();
>>  > > +
>>  > > +public slots:
>>  > > + void update();
>>  > > + QStringList getItems();
>>  > > +
>>  > > +};
>>  > > +
>>  > > +#endif // VLC_RECENT_MEDIA_MODEL_HPP
>>  > > diff --git a/modules/gui/qt/dialogs_provider.cpp 
>>  > > b/modules/gui/qt/dialogs_provider.cpp
>>  > > index 17d6b35a44..58c88a7c1f 100644
>>  > > --- a/modules/gui/qt/dialogs_provider.cpp
>>  > > +++ b/modules/gui/qt/dialogs_provider.cpp
>>  > > @@ -566,8 +566,6 @@ QString DialogsProvider::getDirectoryDialog( 
>>  > > intf_thread_t *p_intf )
>>  > > dir = qfu( uri );
>>  > > free( uri );
>>  > > 
>>  > > - RecentsMRL::getInstance( p_intf )->addRecent( dir );
>>  > > -
>>  > > return dir;
>>  > > }
>>  > > 
>>  > > diff --git a/modules/gui/qt/main_interface.cpp 
>>  > > b/modules/gui/qt/main_interface.cpp
>>  > > index 7f135f93ba..ac56e3bc2d 100644
>>  > > --- a/modules/gui/qt/main_interface.cpp
>>  > > +++ b/modules/gui/qt/main_interface.cpp
>>  > > @@ -51,6 +51,7 @@
>>  > > #include "components/mediacenter/mlgenremodel.hpp"
>>  > > #include "components/mediacenter/mlvideomodel.hpp"
>>  > > #include "components/mediacenter/mlnetworkmodel.hpp"
>>  > > +#include "components/recent_media_model.hpp"
>>  > > 
>>  > > #include "components/navigation_history.hpp"
>>  > > #include "components/aboutmodel.hpp"
>>  > > @@ -63,7 +64,6 @@
>>  > > #include "util/qmleventfilter.hpp"
>>  > > 
>>  > > #include "menus.hpp" // Menu creation
>>  > > -#include "recents.hpp" // RecentItems when DnD
>>  > > 
>>  > > #include <QCloseEvent>
>>  > > #include <QKeyEvent>
>>  > > @@ -379,6 +379,7 @@ void MainInterface::createMainWidget( QSettings * )
>>  > > rootCtx->setContextProperty( "rootQMLView", mediacenterView);
>>  > > rootCtx->setContextProperty( "rootWindow", this);
>>  > > rootCtx->setContextProperty( "dialogProvider", 
>>  > > DialogsProvider::getInstance());
>>  > > + rootCtx->setContextProperty( "recentsMedias", new 
>>  > > VLCRecentMediaModel( p_intf, this ));
>>  > > 
>>  > > if (b_hasMedialibrary)
>>  > > {
>>  > > diff --git a/modules/gui/qt/qml/menus/MainDropdownMenu.qml 
>>  > > b/modules/gui/qt/qml/menus/MainDropdownMenu.qml
>>  > > index 4ea0025281..8df4e56c20 100644
>>  > > --- a/modules/gui/qt/qml/menus/MainDropdownMenu.qml
>>  > > +++ b/modules/gui/qt/qml/menus/MainDropdownMenu.qml
>>  > > @@ -21,7 +21,8 @@ import QtQuick.Controls 2.4
>>  > > import "qrc:///utils/" as Utils
>>  > > 
>>  > > //main menus, to be used as a dropdown menu
>>  > > -Utils.MenuExt {
>>  > > +Utils.MenuExt { 
>>  > > + id: mainDropdownMenu
>>  > > //make the menu modal, as we are not attached to a QQuickWindow
>>  > > modal: true
>>  > > closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape
>>  > > diff --git a/modules/gui/qt/qml/menus/MediaMenu.qml 
>>  > > b/modules/gui/qt/qml/menus/MediaMenu.qml
>>  > > index 8414b14f8b..8f95dc19ee 100644
>>  > > --- a/modules/gui/qt/qml/menus/MediaMenu.qml
>>  > > +++ b/modules/gui/qt/qml/menus/MediaMenu.qml
>>  > > @@ -30,7 +30,41 @@ Utils.MenuExt {
>>  > > Action { text: qsTr("Open &Capture Device..."); onTriggered: 
>>  > > dialogProvider.openCaptureDialog(); 
>>  > > icon.source:"qrc:/type/capture-card.svg"; shortcut: "Ctrl+C" }
>>  > > Action { text: qsTr("Open &Location from clipboard"); onTriggered: 
>>  > > dialogProvider.openUrlDialog(); 
>>  > > shortcut: "Ctrl+V" }
>>  > > 
>>  > > - /* FIXME recent */
>>  > > +
>>  > > + Utils.MenuExt {
>>  > > + id: recentsMenu
>>  > > + title: qsTr("Open &Recent Media")
>>  > > + property bool hasData: true
>>  > > + onAboutToShow:{
>>  > > + recentsMenu.hasData = Boolean(recentsMedias.rowCount())
>>  > > + }
>>  > > + Instantiator {
>>  > > + model: recentsMedias
>>  > > + Utils.MenuItemExt {
>>  > > + text: mrl
>>  > > + onTriggered:{
>>  > > + mainDropdownMenu.close() //needed since menuItem 
>>  > > isn't a direct child of a menu
>>  > > + mainPlaylistController.append([mrl], true)
>>  > > + }
>>  > > +
>>  > > + Shortcut {
>>  > > + sequence: "Ctrl+" + (index + 1)
>>  > > + onActivated: mainPlaylistController.append([mrl], 
>>  > > true)
>>  > > + context: Qt.ApplicationShortcut
>>  > > + }
>>  > > + }
>>  > > + onObjectAdded: recentsMenu.insertItem(recentsMenu.count - 
>>  > > 2, object)
>>  > > + onObjectRemoved: recentsMenu.removeItem(object)
>>  > > + }
>>  > > +
>>  > > + MenuSeparator{}
>>  > > +
>>  > > + Utils.MenuItemExt {
>>  > > + text: qsTr("Clear")
>>  > > + enabled: recentsMenu.hasData
>>  > > + onTriggered:recentsMedias.clear()
>>  > > + }
>>  > > + }
>>  > > 
>>  > > Action { text: qsTr("Save Playlist to &File..."); onTriggered: 
>>  > > dialogProvider.savePlayingToPlaylist(); icon.source: ""; 
>>  > > shortcut: "Ctrl+Y" }
>>  > > Action { text: qsTr("Conve&rt / Save..." ); onTriggered: 
>>  > > dialogProvider.openAndTranscodingDialogs(); icon.source: ""; 
>>  > > shortcut: "Ctrl+R" }
>>  > > diff --git a/modules/gui/qt/recents.cpp b/modules/gui/qt/recents.cpp
>>  > > index 0857bbba76..4ba7d38fb1 100644
>>  > > --- a/modules/gui/qt/recents.cpp
>>  > > +++ b/modules/gui/qt/recents.cpp
>>  > > @@ -158,6 +158,7 @@ void RecentsMRL::save()
>>  > > {
>>  > > getSettings()->setValue( "RecentsMRL/list", recents );
>>  > > getSettings()->setValue( "RecentsMRL/times", times );
>>  > > + emit saved();
>>  > > }
>>  > > 
>>  > > void RecentsMRL::playMRL( const QString &mrl )
>>  > > diff --git a/modules/gui/qt/recents.hpp b/modules/gui/qt/recents.hpp
>>  > > index 86215f21ff..bb2286ca2c 100644
>>  > > --- a/modules/gui/qt/recents.hpp
>>  > > +++ b/modules/gui/qt/recents.hpp
>>  > > @@ -54,16 +54,16 @@ class RecentsMRL : public QObject, public 
>>  > > Singleton<RecentsMRL>
>>  > > friend class Singleton<RecentsMRL>;
>>  > > 
>>  > > public:
>>  > > + 
>>  > > void addRecent( const QString & );
>>  > > - QStringList recentList();
>>  > > QSignalMapper *signalMapper;
>>  > > 
>>  > > vlc_tick_t time( const QString &mrl );
>>  > > void setTime( const QString &mrl, const vlc_tick_t time );
>>  > > + virtual ~RecentsMRL();
>>  > > 
>>  > > private:
>>  > > RecentsMRL( intf_thread_t* _p_intf );
>>  > > - virtual ~RecentsMRL();
>>  > > 
>>  > > intf_thread_t *p_intf;
>>  > > 
>>  > > @@ -74,8 +74,11 @@ private:
>>  > > 
>>  > > void load();
>>  > > void save();
>>  > > -
>>  > > + 
>>  > > +signals:
>>  > > + void saved();
>>  > > public slots:
>>  > > + QStringList recentList();
>>  > > void clear();
>>  > > void playMRL( const QString & );
>>  > > };
>> 
>>  Hi,
>> 
>>  Thanks for your patch!
>> 
>>  I agree that this feature needs to be reintroduced, although I think it should use the media library history instead, and removed the recents.cpp/hpp previous implementation.
>> 
>>  Regards,
>> 
>>  -- 
>>  Hugo Beauzée-Luyssen
>> hugo at beauzee.fr
>>  _______________________________________________
>>  vlc-devel mailing list
>>  To unsubscribe or modify your subscription options:
>> https://mailman.videolan.org/listinfo/vlc-devel
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20190424/0295e464/attachment-0001.html>


More information about the vlc-devel mailing list