/*****************************************************************************
* Copyright (C) 2021 VLC authors and VideoLAN
*
* Authors: Benjamin Arnaud <bunjee@omega.gg>
*
* 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 "mlvideogroupsmodel.hpp"
// VLC includes
#include <vlc_media_library.h>
// Util includes
#include "util/covergenerator.hpp"
#include "util/vlctick.hpp"
// MediaLibrary includes
#include "mlcustomcover.hpp"
#include "mlgroup.hpp"
#include "mlvideo.hpp"
#include "mlhelper.hpp"
//-------------------------------------------------------------------------------------------------
// Static variables
// NOTE: We multiply by 3 to cover most dpi settings.
static const int MLVIDEOGROUPSMODEL_COVER_WIDTH = 260 * 3; // 16 / 10 ratio
static const int MLVIDEOGROUPSMODEL_COVER_HEIGHT = 162 * 3;
//=================================================================================================
// MLVideoGroupsModel
//=================================================================================================
/* explicit */ MLVideoGroupsModel::MLVideoGroupsModel(QObject * parent) : MLVideoModel(parent) {}
//-------------------------------------------------------------------------------------------------
// MLVideoModel reimplementation
//-------------------------------------------------------------------------------------------------
QHash<int, QByteArray> MLVideoGroupsModel::roleNames() const /* override */
{
QHash<int, QByteArray> hash = MLVideoModel::roleNames();
const QHash<int, QByteArray> groupRoles =
{
{GROUP_IS_VIDEO, QByteArrayLiteral("isVideo")},
{GROUP_TITLE_FIRST_SYMBOL, QByteArrayLiteral("group_title_first_symbol")},
{GROUP_DATE, QByteArrayLiteral("date")},
{GROUP_COUNT, QByteArrayLiteral("count")},
{GROUP_NB_VIDEOS, QByteArrayLiteral("nb_videos")},
};
hash.insert(groupRoles);
return hash;
}
// Protected MLVideoModel implementation
QVariant MLVideoGroupsModel::itemRoleData(const MLItem * item, const int role) const /* override */
{
if (item == nullptr)
return QVariant();
if (item->getId().type == VLC_ML_PARENT_GROUP)
{
auto group = static_cast<const MLGroup *> (item);
switch (role)
{
// NOTE: This is the condition for QWidget view(s).
case Qt::DisplayRole:
return QVariant::fromValue(group->getTitle());
// NOTE: These are the conditions for QML view(s).
case MEDIA_ID:
return QVariant::fromValue(group->getId());
case MEDIA_TITLE:
return QVariant::fromValue(group->getTitle());
case VIDEO_THUMBNAIL:
{
return MLCustomCover::url(
group->getId(),
QSize(MLVIDEOGROUPSMODEL_COVER_WIDTH, MLVIDEOGROUPSMODEL_COVER_HEIGHT),
QStringLiteral(":/placeholder/noart_videoCover.svg")
);
}
case MEDIA_DURATION:
return QVariant::fromValue(group->getDuration());
case GROUP_IS_VIDEO:
return false;
case GROUP_TITLE_FIRST_SYMBOL:
return QVariant::fromValue( getFirstSymbol(group->getTitle() ));
case GROUP_DATE:
return QVariant::fromValue(group->getDate());
case GROUP_COUNT:
case GROUP_NB_VIDEOS:
return QVariant::fromValue(group->getCount());
default:
return QVariant();
}
}
else
{
auto video = static_cast<const MLVideo *> (item);
switch (role)
{
case Qt::DisplayRole:
return QVariant::fromValue(video->title());
case GROUP_TITLE_FIRST_SYMBOL:
// videos and groups are shown mixed, force this item into a group
// for grouping the data must be sorted by title
return QVariant::fromValue( getFirstSymbol(video->title() ));
case GROUP_IS_VIDEO:
return true;
case GROUP_DATE:
return QVariant();
case GROUP_COUNT:
case GROUP_NB_VIDEOS:
return 1;
// NOTE: Media specific.
default:
return MLVideoModel::itemRoleData(item, role);
}
}
}
vlc_ml_sorting_criteria_t MLVideoGroupsModel::nameToCriteria(QByteArray name) const /* override */
{
return QHash<QByteArray, vlc_ml_sorting_criteria_t> {
{ QByteArrayLiteral("title"), VLC_ML_SORTING_ALPHA },
{ QByteArrayLiteral("duration"), VLC_ML_SORTING_DURATION },
{ QByteArrayLiteral("date"), VLC_ML_SORTING_INSERTIONDATE },
}.value(name, VLC_ML_SORTING_DEFAULT);
}
std::unique_ptr<MLListCacheLoader> MLVideoGroupsModel::createMLLoader() const /* override */
{
return std::make_unique<MLListCacheLoader>(m_mediaLib, std::make_shared<MLVideoGroupsModel::Loader>(*this));
}
void MLVideoGroupsModel::onVlcMlEvent(const MLEvent & event) /* override */
{
int type = event.i_type;
switch (type)
{
case VLC_ML_EVENT_GROUP_ADDED:
{
emit resetRequested();
return;
}
case VLC_ML_EVENT_MEDIA_ADDED:
{
if (event.creation.media.i_type == VLC_ML_MEDIA_TYPE_VIDEO)
{
emit resetRequested();
return;
}
break;
}
case VLC_ML_EVENT_GROUP_UPDATED:
{
MLItemId itemId(event.modification.i_entity_id, VLC_ML_PARENT_GROUP);
updateItemInCache(itemId);
return;
}
case VLC_ML_EVENT_MEDIA_UPDATED:
{
MLItemId itemId(event.modification.i_entity_id, VLC_ML_PARENT_UNKNOWN);
updateItemInCache(itemId);
return;
}
case VLC_ML_EVENT_GROUP_DELETED:
{
MLItemId itemId(event.deletion.i_entity_id, VLC_ML_PARENT_GROUP);
deleteItemInCache(itemId);
return;
}
case VLC_ML_EVENT_MEDIA_DELETED:
{
MLItemId itemId(event.deletion.i_entity_id, VLC_ML_PARENT_UNKNOWN);
deleteItemInCache(itemId);
return;
}
default:
break;
}
MLBaseModel::onVlcMlEvent(event);
}
//=================================================================================================
// Loader
//=================================================================================================
size_t MLVideoGroupsModel::Loader::count(vlc_medialibrary_t* ml, const vlc_ml_query_params_t* queryParams) const /* override */
{
return vlc_ml_count_groups(ml, queryParams);
}
std::vector<std::unique_ptr<MLItem>>
MLVideoGroupsModel::Loader::load(vlc_medialibrary_t* ml,
const vlc_ml_query_params_t* queryParams) const /* override */
{
ml_unique_ptr<vlc_ml_group_list_t> list(vlc_ml_list_groups(ml, queryParams));
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 = vlc_ml_query_params_create();
ml_unique_ptr<vlc_ml_media_list_t> list(vlc_ml_list_group_media(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>(&(list->p_items[0])));
continue;
}
}
result.emplace_back(std::make_unique<MLGroup>(&group));
}
return result;
}
std::unique_ptr<MLItem>
MLVideoGroupsModel::Loader::loadItemById(vlc_medialibrary_t* ml, MLItemId itemId) const
{
if (itemId.type == VLC_ML_PARENT_UNKNOWN)
{
ml_unique_ptr<vlc_ml_media_t> media(vlc_ml_get_media(ml, itemId.id));
if (!media)
return nullptr;
return std::make_unique<MLVideo>(media.get());
}
else if (itemId.type == VLC_ML_PARENT_GROUP)
{
ml_unique_ptr<vlc_ml_group_t> group(vlc_ml_get_group(ml, itemId.id));
if (!group)
return nullptr;
return std::make_unique<MLGroup>(group.get());
}
else
{
vlc_assert_unreachable();
return nullptr;
}
}
¤ Dauer der Verarbeitung: 0.7 Sekunden
¤
*© Formatika GbR, Deutschland
|
|