From b8933ddca4b5231185cac163e05a643aa1ce5f1d Mon Sep 17 00:00:00 2001 From: Henk Kalkwater Date: Wed, 24 Aug 2022 17:00:14 +0200 Subject: [PATCH] Move QObject-wrapping code into templates Previously, this pattern was copy-pasted in a few places. This is undesirable, so the code has been moved into templates. Fixes #30 --- core/CMakeLists.txt | 1 + core/include/JellyfinQt/viewmodel/utils.h | 78 +++++++++++++++++++++++ core/src/viewmodel/item.cpp | 7 +- core/src/viewmodel/itemmodel.cpp | 7 +- core/src/viewmodel/playlist.cpp | 11 +--- 5 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 core/include/JellyfinQt/viewmodel/utils.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index f14f161..3ecc7b1 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -68,6 +68,7 @@ set(JellyfinQt_HEADERS include/JellyfinQt/viewmodel/userdata.h include/JellyfinQt/viewmodel/usermodel.h include/JellyfinQt/viewmodel/user.h + include/JellyfinQt/viewmodel/utils.h include/JellyfinQt/apiclient.h include/JellyfinQt/apimodel.h include/JellyfinQt/credentialmanager.h diff --git a/core/include/JellyfinQt/viewmodel/utils.h b/core/include/JellyfinQt/viewmodel/utils.h new file mode 100644 index 0000000..1343e06 --- /dev/null +++ b/core/include/JellyfinQt/viewmodel/utils.h @@ -0,0 +1,78 @@ +/* + * Sailfin: a Jellyfin client written using Qt + * Copyright (C) 2022 Chris Josten and the Sailfin Contributors. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef JELLYFIN_VIEWMODEL_UTILS_H +#define JELLYFIN_VIEWMODEL_UTILS_H + +#include +#include +#include + +/** + * \brief Wraps a data object in a QObject. + * + * This class is made for use in the ViewModel namespace, since many + * objects follow the pattern of having a constructor with a QSharedPointer + * and a parent. + * + * The QObject wrapper class W must have a accessible constructor which takes only a QSharedPointer + * as argument. + * + * \tparam W The QObject wrapper class + * \tparam D The DTO class + * \param data The data to wrap in a QObject + * \param parent The QObject to set as the parent of the newly created type. + */ +template +W *wrapQObject(D data, QObject *parent) { + return new W(QSharedPointer::create(data), parent); +} + +/** + * \brief Wraps a list of DTO items in a QVariantList of QObject's + * \see wrapQObject() + * \param begin The begin iterator of the list of DTO items + * \param end The end iterator of the list of DTO items + * \param parent The QObject to set as the parent of the QObjects in the newly created list. + */ +template +QVariantList wrapQVariantList(It begin, It end, QObject *parent) { + QVariantList result; + for (It it = begin; it != end; it++) { + result.append(QVariant::fromValue(wrapQObject(*it, parent))); + } + return result; +} + +/** + * \brief Wraps a list of DTO items in a QObjectList. + * \see wrapQObject() + * \param begin The begin iterator of the list of DTO items + * \param end The end iterator of the list of DTO items + * \param parent The QObject to set as the parent of the QObjects in the newly created list. + */ +template +QObjectList wrapQObjectList(It begin, It end, QObject *parent) { + QObjectList result; + for (It it = begin; it != end; it++) { + result.append(wrapQObject(*it, parent)); + } + return result; +} + +#endif // JELLYFIN_VIEWMODEL_UTILS_H diff --git a/core/src/viewmodel/item.cpp b/core/src/viewmodel/item.cpp index 99f2668..0a6ee4a 100644 --- a/core/src/viewmodel/item.cpp +++ b/core/src/viewmodel/item.cpp @@ -22,6 +22,7 @@ #include "JellyfinQt/loader/http/items.h" #include "JellyfinQt/loader/http/userlibrary.h" #include "JellyfinQt/viewmodel/userdata.h" +#include "JellyfinQt/viewmodel/utils.h" namespace Jellyfin { namespace ViewModel { @@ -81,11 +82,9 @@ void Item::updateMediaStreams() { qDebug() << m_audioStreams.size() << " audio streams, " << m_videoStreams.size() << " video streams, " << m_subtitleStreams.size() << " subtitle streams, " << m_allMediaStreams.size() << " streams total"; - m_artistItems.clear(); const QList artists = m_data->artistItems(); - for (auto it = artists.cbegin(); it != artists.cend(); it++) { - m_artistItems.append(new NameGuidPair(QSharedPointer::create(*it), this)); - } + qDeleteAll(m_artistItems); + m_artistItems = wrapQObjectList(artists.cbegin(), artists.cend(), this); } void Item::setUserData(DTO::UserItemDataDto &newData) { diff --git a/core/src/viewmodel/itemmodel.cpp b/core/src/viewmodel/itemmodel.cpp index e725681..f99d05e 100644 --- a/core/src/viewmodel/itemmodel.cpp +++ b/core/src/viewmodel/itemmodel.cpp @@ -27,6 +27,7 @@ #include "JellyfinQt/loader/http/tvshows.h" #include "JellyfinQt/viewmodel/userdata.h" +#include "JellyfinQt/viewmodel/utils.h" #define JF_CASE(roleName) case roleName: \ try { \ @@ -96,12 +97,8 @@ QVariant ItemModel::data(const QModelIndex &index, int role) const { return QVariant(item->runTimeTicks().value_or(0)); JF_CASE(artists) case RoleNames::artistItems: { - QVariantList data; auto artists = item->artistItems(); - for (auto it = artists.cbegin(); it != artists.cend(); it++) { - data.append(QVariant::fromValue(new NameGuidPair(QSharedPointer::create(*it), const_cast(this)))); - } - return data; + return wrapQVariantList(artists.cbegin(), artists.cend(), const_cast(this)); } case RoleNames::isFolder: return QVariant(item->isFolder().value_or(false)); diff --git a/core/src/viewmodel/playlist.cpp b/core/src/viewmodel/playlist.cpp index 129e2df..99178ba 100644 --- a/core/src/viewmodel/playlist.cpp +++ b/core/src/viewmodel/playlist.cpp @@ -19,6 +19,7 @@ #include "JellyfinQt/viewmodel/playlist.h" #include "JellyfinQt/viewmodel/item.h" +#include "JellyfinQt/viewmodel/utils.h" namespace Jellyfin { namespace ViewModel { @@ -87,14 +88,8 @@ QVariant Playlist::data(const QModelIndex &index, int role) const { case RoleNames::artists: return QVariant(rowData->artists()); case RoleNames::artistItems: { - QVariantList result; - - auto items = rowData->artistItems(); - for (auto it = items.cbegin(); it != items.cend(); it++) { - result.append(QVariant::fromValue(new NameGuidPair(QSharedPointer::create(*it), const_cast(this)))); - } - - return result; + auto artists = rowData->artistItems(); + return wrapQVariantList(artists.cbegin(), artists.cend(), const_cast(this)); } case RoleNames::runTimeTicks: return QVariant(rowData->runTimeTicks().value_or(-1));