vlc | branch: master | Benjamin Arnaud <[email protected]> | Thu Mar 18 10:01:19 2021 +0100| [8a2ff7cfe3001876345da30622ad6ae5394eac89] | committer: Pierre Lamot
qt: Create MLGroupListModel Signed-off-by: Pierre Lamot <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8a2ff7cfe3001876345da30622ad6ae5394eac89 --- modules/gui/qt/Makefile.am | 3 + modules/gui/qt/medialibrary/mlgrouplistmodel.cpp | 287 +++++++++++++++++++++++ modules/gui/qt/medialibrary/mlgrouplistmodel.hpp | 91 +++++++ po/POTFILES.in | 2 + 4 files changed, 383 insertions(+) diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am index fe9ac33221..bfe3bbe2ad 100644 --- a/modules/gui/qt/Makefile.am +++ b/modules/gui/qt/Makefile.am @@ -159,6 +159,8 @@ libqt_plugin_la_SOURCES = \ gui/qt/medialibrary/mlgenremodel.hpp \ gui/qt/medialibrary/mlgroup.cpp \ gui/qt/medialibrary/mlgroup.hpp \ + gui/qt/medialibrary/mlgrouplistmodel.cpp \ + gui/qt/medialibrary/mlgrouplistmodel.hpp \ gui/qt/medialibrary/mlhelper.cpp \ gui/qt/medialibrary/mlhelper.hpp \ gui/qt/medialibrary/mlqmltypes.hpp \ @@ -343,6 +345,7 @@ nodist_libqt_plugin_la_SOURCES = \ gui/qt/medialibrary/mlgenre.moc.cpp \ gui/qt/medialibrary/mlgenremodel.moc.cpp \ gui/qt/medialibrary/mlgroup.moc.cpp \ + gui/qt/medialibrary/mlgrouplistmodel.moc.cpp \ gui/qt/medialibrary/mlqmltypes.moc.cpp \ gui/qt/medialibrary/mlrecentsmodel.moc.cpp \ gui/qt/medialibrary/mlrecentsvideomodel.moc.cpp \ diff --git a/modules/gui/qt/medialibrary/mlgrouplistmodel.cpp b/modules/gui/qt/medialibrary/mlgrouplistmodel.cpp new file mode 100644 index 0000000000..7f5fc6f3b8 --- /dev/null +++ b/modules/gui/qt/medialibrary/mlgrouplistmodel.cpp @@ -0,0 +1,287 @@ +/***************************************************************************** + * Copyright (C) 2021 VLC authors and VideoLAN + * + * Authors: Benjamin Arnaud <[email protected]> + * + * 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. + *****************************************************************************/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mlgrouplistmodel.hpp" + +// VLC includes +#include <vlc_media_library.h> + +// MediaLibrary includes +#include "mlhelper.hpp" +#include "mlgroup.hpp" +#include "mlvideo.hpp" + +//------------------------------------------------------------------------------------------------- +// Static variables + +static const QHash<QByteArray, vlc_ml_sorting_criteria_t> criterias = +{ + {"id", VLC_ML_SORTING_DEFAULT}, + {"name", VLC_ML_SORTING_ALPHA}, + {"date", VLC_ML_SORTING_INSERTIONDATE} +}; + +//================================================================================================= +// MLGroupListModel +//================================================================================================= + +/* explicit */ MLGroupListModel::MLGroupListModel(vlc_medialibrary_t * ml, QObject * parent) + : MLBaseModel(parent) +{ + m_ml = ml; +} + +/* explicit */ MLGroupListModel::MLGroupListModel(QObject * parent) + : MLBaseModel(parent) {} + +//------------------------------------------------------------------------------------------------- +// QAbstractItemModel implementation +//------------------------------------------------------------------------------------------------- + +QHash<int, QByteArray> MLGroupListModel::roleNames() const /* override */ +{ + return + { + { GROUP_ID, "id" }, + { GROUP_NAME, "name" }, + { GROUP_THUMBNAIL, "thumbnail" }, + { GROUP_DURATION, "duration" }, + { GROUP_DATE, "date" }, + { GROUP_COUNT, "count" }, + // NOTE: Media specific. + { GROUP_TITLE, "title" }, + { GROUP_RESOLUTION, "resolution_name" }, + { GROUP_CHANNEL, "channel" }, + { GROUP_MRL, "mrl" }, + { GROUP_MRL_DISPLAY, "display_mrl" }, + { GROUP_PROGRESS, "progress" }, + { GROUP_PLAYCOUNT, "playcount" }, + { GROUP_VIDEO_TRACK, "videoDesc" }, + { GROUP_AUDIO_TRACK, "audioDesc" }, + { GROUP_TITLE_FIRST_SYMBOL, "title_first_symbol" } + }; +} + +QVariant MLGroupListModel::data(const QModelIndex & index, int role) const /* override */ +{ + + MLItem * item = this->item(index.row()); + + if (item == nullptr) + return QVariant(); + + if (item->getId().type == VLC_ML_PARENT_GROUP) + { + MLGroup * group = static_cast<MLGroup *> (item); + + switch (role) + { + // NOTE: This is the condition for QWidget view(s). + case Qt::DisplayRole: + if (index.column() == 0) + return QVariant::fromValue(group->getName()); + else + return QVariant(); + // NOTE: These are the conditions for QML view(s). + case GROUP_ID: + return QVariant::fromValue(group->getId()); + case GROUP_NAME: + return QVariant::fromValue(group->getName()); + case GROUP_THUMBNAIL: + return QVariant::fromValue(group->getThumbnail()); + case GROUP_DURATION: + return QVariant::fromValue(group->getDuration()); + case GROUP_DATE: + return QVariant::fromValue(group->getDate()); + case GROUP_COUNT: + return QVariant::fromValue(group->getCount()); + default: + return QVariant(); + } + } + else + { + MLVideo * video = static_cast<MLVideo *> (item); + + switch (role) + { + // NOTE: This is the condition for QWidget view(s). + case Qt::DisplayRole: + if (index.column() == 0) + return QVariant::fromValue(video->getTitle()); + else + return QVariant(); + // NOTE: These are the conditions for QML view(s). + case GROUP_ID: + return QVariant::fromValue(video->getId()); + case GROUP_NAME: + return QVariant::fromValue(video->getTitle()); + case GROUP_THUMBNAIL: + return QVariant::fromValue(video->getThumbnail()); + case GROUP_DURATION: + return QVariant::fromValue(video->getDuration()); + case GROUP_DATE: + return QVariant(); + case GROUP_COUNT: + return 1; + // NOTE: Media specific. + case GROUP_TITLE: + return QVariant::fromValue(video->getTitle()); + case GROUP_RESOLUTION: + return QVariant::fromValue(video->getResolutionName()); + case GROUP_CHANNEL: + return QVariant::fromValue(video->getChannel()); + case GROUP_MRL: + return QVariant::fromValue(video->getMRL()); + case GROUP_MRL_DISPLAY: + return QVariant::fromValue(video->getDisplayMRL()); + case GROUP_PROGRESS: + return QVariant::fromValue(video->getProgress()); + case GROUP_PLAYCOUNT: + return QVariant::fromValue(video->getPlayCount()); + case GROUP_VIDEO_TRACK: + return QVariant::fromValue(video->getVideoDesc()); + case GROUP_AUDIO_TRACK: + return QVariant::fromValue(video->getAudioDesc()); + case GROUP_TITLE_FIRST_SYMBOL: + return QVariant::fromValue(getFirstSymbol(video->getTitle())); + default: + return QVariant(); + } + } +} + +//------------------------------------------------------------------------------------------------- +// Protected MLBaseModel implementation +//------------------------------------------------------------------------------------------------- + +vlc_ml_sorting_criteria_t MLGroupListModel::roleToCriteria(int role) const /* override */ +{ + switch (role) + { + case GROUP_NAME: + return VLC_ML_SORTING_ALPHA; + case GROUP_DATE: + return VLC_ML_SORTING_INSERTIONDATE; + default: + return VLC_ML_SORTING_DEFAULT; + } +} + +vlc_ml_sorting_criteria_t MLGroupListModel::nameToCriteria(QByteArray name) const /* override */ +{ + return criterias.value(name, VLC_ML_SORTING_DEFAULT); +} + +QByteArray MLGroupListModel::criteriaToName(vlc_ml_sorting_criteria_t criteria) const +/* override */ +{ + return criterias.key(criteria, ""); +} + +//------------------------------------------------------------------------------------------------- + +ListCacheLoader<std::unique_ptr<MLItem>> * MLGroupListModel::createLoader() const /* override */ +{ + return new Loader(*this); +} + +//------------------------------------------------------------------------------------------------- +// Private MLBaseModel reimplementation +//------------------------------------------------------------------------------------------------- + +void MLGroupListModel::onVlcMlEvent(const MLEvent & event) /* override */ +{ + int type = event.i_type; + + if (type == VLC_ML_EVENT_GROUP_ADDED || type == VLC_ML_EVENT_GROUP_UPDATED + || + type == VLC_ML_EVENT_GROUP_DELETED) + { + m_need_reset = true; + + // NOTE: Maybe we should call this from MLBaseModel ? + emit resetRequested(); + } + + MLBaseModel::onVlcMlEvent(event); +} + +void MLGroupListModel::thumbnailUpdated(int idx) /* override */ +{ + emit dataChanged(index(idx), index(idx), { GROUP_THUMBNAIL }); +} + +//================================================================================================= +// Loader +//================================================================================================= + +MLGroupListModel::Loader::Loader(const MLGroupListModel & model) + : MLBaseModel::BaseLoader(model) {} + +size_t MLGroupListModel::Loader::count() const /* override */ +{ + vlc_ml_query_params_t params = getParams().toCQueryParams(); + + return vlc_ml_count_groups(m_ml, ¶ms); +} + +std::vector<std::unique_ptr<MLItem>> +MLGroupListModel::Loader::load(size_t index, size_t count) const /* override */ +{ + vlc_ml_query_params_t params = getParams(index, count).toCQueryParams(); + + ml_unique_ptr<vlc_ml_group_list_t> list(vlc_ml_list_groups(m_ml, ¶ms)); + + if (list == nullptr) + return {}; + + std::vector<std::unique_ptr<MLItem>> result; + + for (const vlc_ml_group_t & group : ml_range_iterate<vlc_ml_group_t>(list)) + { + // NOTE: When it's a group of one we convert it to a MLVideo. + if (group.i_nb_total_media == 1) + { + vlc_ml_query_params_t query; + + memset(&query, 0, sizeof(vlc_ml_query_params_t)); + + ml_unique_ptr<vlc_ml_media_list_t> list(vlc_ml_list_group_media(m_ml, + &query, group.i_id)); + + // NOTE: Do we really need to check 'i_nb_items' here ? + if (list->i_nb_items == 1) + { + result.emplace_back(std::make_unique<MLVideo>(m_ml, &(list->p_items[0]))); + + continue; + } + } + + result.emplace_back(std::make_unique<MLGroup>(m_ml, &group)); + } + + return result; +} diff --git a/modules/gui/qt/medialibrary/mlgrouplistmodel.hpp b/modules/gui/qt/medialibrary/mlgrouplistmodel.hpp new file mode 100644 index 0000000000..b1b826335f --- /dev/null +++ b/modules/gui/qt/medialibrary/mlgrouplistmodel.hpp @@ -0,0 +1,91 @@ +/***************************************************************************** + * Copyright (C) 2021 VLC authors and VideoLAN + * + * Authors: Benjamin Arnaud <[email protected]> + * + * 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 MLGROUPLISTMODEL_HPP +#define MLGROUPLISTMODEL_HPP + +// MediaLibrary includes +#include "mlbasemodel.hpp" + +// Forward declarations +class vlc_medialibrary_t; + +class MLGroupListModel : public MLBaseModel +{ + Q_OBJECT + +public: + enum Roles + { + GROUP_ID = Qt::UserRole + 1, + GROUP_NAME, + GROUP_THUMBNAIL, + GROUP_DURATION, + GROUP_DATE, + GROUP_COUNT, + // NOTE: Media specific. + GROUP_TITLE, + GROUP_RESOLUTION, + GROUP_CHANNEL, + GROUP_MRL, + GROUP_MRL_DISPLAY, + GROUP_PROGRESS, + GROUP_PLAYCOUNT, + GROUP_VIDEO_TRACK, + GROUP_AUDIO_TRACK, + GROUP_TITLE_FIRST_SYMBOL + }; + +public: + explicit MLGroupListModel(vlc_medialibrary_t * ml, QObject * parent = nullptr); + + explicit MLGroupListModel(QObject * parent = nullptr); + +public: // QAbstractItemModel implementation + QHash<int, QByteArray> roleNames() const override; + + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + +protected: // MLBaseModel implementation + vlc_ml_sorting_criteria_t roleToCriteria(int role) const override; + + vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override; + + QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override; + + ListCacheLoader<std::unique_ptr<MLItem>> * createLoader() const override; + +private: // MLBaseModel implementation + void onVlcMlEvent(const MLEvent & event) override; + + void thumbnailUpdated(int idx) override; + +private: + struct Loader : public MLBaseModel::BaseLoader + { + Loader(const MLGroupListModel & model); + + size_t count() const override; + + std::vector<std::unique_ptr<MLItem>> load(size_t index, size_t count) const override; + }; +}; + +#endif // MLGROUPLISTMODEL_HPP diff --git a/po/POTFILES.in b/po/POTFILES.in index 83679ba718..0293b48792 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -775,6 +775,8 @@ modules/gui/qt/medialibrary/mlfoldersmodel.cpp modules/gui/qt/medialibrary/mlfoldersmodel.hpp modules/gui/qt/medialibrary/mlgroup.cpp modules/gui/qt/medialibrary/mlgroup.hpp +modules/gui/qt/medialibrary/mlgrouplistmodel.cpp +modules/gui/qt/medialibrary/mlgrouplistmodel.hpp modules/gui/qt/medialibrary/mlplaylistlistmodel.cpp modules/gui/qt/medialibrary/mlplaylistlistmodel.hpp modules/gui/qt/medialibrary/mlplaylistmedia.cpp _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
