Jellyfin Qt
QML Library for interacting with the Jellyfin multimedia server
Loading...
Searching...
No Matches
itemmodel.h
Go to the documentation of this file.
1/*
2 * Sailfin: a Jellyfin client written using Qt
3 * Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19#ifndef JELLYFIN_VIEWMODEL_ITEMMODEL_H
20#define JELLYFIN_VIEWMODEL_ITEMMODEL_H
21
22#include <QAbstractListModel>
23#include <QObject>
24#include <QScopedPointer>
25#include <QVariantList>
26
27#include "../dto/baseitemdto.h"
30#include "../model/item.h"
31#include "../viewmodel/item.h"
32#include "../apimodel.h"
33#include "modelstatus.h"
34#include "propertyhelper.h"
35
36// Jellyfin Forward Read/Write Property
37#define FWDPROP(type, propName, propSetName) \
38 public: \
39 Q_PROPERTY(type propName READ propName WRITE set##propSetName NOTIFY propName##Changed) \
40 type propName() const { return this->m_parameters.propName(); } \
41 void set##propSetName(type newValue) { \
42 this->m_parameters.set##propSetName( newValue ); \
43 emit propName##Changed(); \
44 autoReloadIfNeeded(); \
45 } \
46 Q_SIGNALS: \
47 void propName##Changed();
48
49#define FWDLISTPROP(type, propName, propSetName) \
50 public: \
51 Q_PROPERTY(QVariantList propName READ propName WRITE set##propSetName NOTIFY propName##Changed) \
52 QVariantList propName() const { \
53 QVariantList result; \
54 QList<type> list; \
55 result.reserve(list.size()); \
56 for (auto it = list.cbegin(); it != list.cend(); it++) { \
57 result.append(QVariant::fromValue<type>(*it)); \
58 } \
59 return result; \
60 } \
61 void set##propSetName(const QVariantList &newValue) { \
62 QList<type> list;\
63 list.reserve(newValue.size()); \
64 for(auto it = newValue.cbegin(); it != newValue.cend(); it++) { \
65 list.append(it->value<type>()); \
66 } \
67 this->m_parameters.set##propSetName(list); \
68 emit propName##Changed(); \
69 autoReloadIfNeeded(); \
70 } \
71 Q_SIGNALS: \
72 void propName##Changed();
73
74namespace Jellyfin {
75
76namespace ViewModel {
77
78// JellyFinRoleName
79#define JFRN(name) {RoleNames::name, #name}
80
81// This file contains all models that expose a Model::Item
82
87template <class T, class D, class R, class P>
89public:
90 explicit AbstractUserParameterLoader(Support::Loader<R, P> *loader, QObject *parent = nullptr)
91 : LoaderModelLoader<T, D, R, P>(loader, parent) {
93 }
94protected:
95 virtual bool canReload() const override {
96 return BaseModelLoader::canReload() && !this->m_parameters.userId().isNull();
97 }
98private:
99 void apiClientChanged(ApiClient *newApiClient) {
100 if (this->m_apiClient != nullptr) {
102 }
103 if (newApiClient != nullptr) {
104 this->connect(newApiClient, &ApiClient::userIdChanged, this, &AbstractUserParameterLoader<T, D, R, P>::userIdChanged);
105 if (!newApiClient->userId().isNull()) {
106 this->m_parameters.setUserId(newApiClient->userId());
107 }
108 }
109 }
110
111 void userIdChanged(const QString &newUserId) {
112 this->m_parameters.setUserId(newUserId);
113 this->autoReloadIfNeeded();
114 }
115};
116
122 Q_OBJECT
123public:
124 explicit UserViewsLoader(QObject *parent = nullptr);
125
126 FWDPROP(bool, includeExternalContent, IncludeExternalContent)
127 FWDPROP(bool, includeHidden, IncludeHidden)
128 FWDPROP(QStringList, presetViews, PresetViews)
129};
130
131using LatestMediaBase = AbstractUserParameterLoader<Model::Item, DTO::BaseItemDto, QList<DTO::BaseItemDto>, Jellyfin::Loader::GetLatestMediaParams>;
133 Q_OBJECT
134public:
135 explicit LatestMediaLoader(QObject *parent = nullptr);
136
137 // Optional
138 FWDPROP(QList<Jellyfin::DTO::ImageTypeClass::Value>, enableImageTypes, EnableImageTypes)
139 FWDPROP(bool, enableImages, EnableImages)
140 FWDPROP(bool, enableUserData, EnableUserData)
141 FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
142 FWDPROP(bool, groupItems, GroupItems)
143 FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
144 FWDPROP(QStringList, includeItemTypes, IncludeItemTypes)
145 FWDPROP(bool, isPlayed, IsPlayed)
146 FWDPROP(QString, parentId, ParentId)
147};
148
151 Q_OBJECT
152public:
153 explicit UserItemsLoader(QObject *parent = nullptr);
154
155 FWDPROP(QString, adjacentTo, AdjacentTo)
156 FWDPROP(QStringList, albumArtistIds, AlbumArtistIds)
157 FWDPROP(QStringList, albumIds, AlbumIds)
158 FWDPROP(QStringList, albums, Albums)
159 FWDPROP(QStringList, artistIds, ArtistIds)
160 FWDPROP(QStringList, artists, Artists)
161 FWDPROP(bool, collapseBoxSetItems, CollapseBoxSetItems)
162 FWDPROP(QStringList, contributingArtistIds, ContributingArtistIds)
163 FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, enableImageTypes, EnableImageTypes);
164 FWDPROP(bool, enableImages, EnableImages)
165 FWDPROP(bool, enableTotalRecordCount, EnableTotalRecordCount)
166 FWDPROP(bool, enableUserData, EnableUserData)
167 FWDPROP(QStringList, excludeArtistIds, ExcludeArtistIds)
168 FWDPROP(QStringList, excludeItemIds, ExcludeItemIds)
169 FWDPROP(QStringList, excludeItemTypes, ExcludeItemTypes)
170 FWDPROP(QList<Jellyfin::DTO::LocationTypeClass::Value>, excludeLocationTypes, ExcludeLocationTypes)
171 FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
172 FWDLISTPROP(Jellyfin::DTO::ItemFilterClass::Value, filters, Filters)
173 FWDPROP(QStringList, genreIds, GenreIds)
174 FWDPROP(QStringList, genres, Genres)
175 FWDPROP(bool, hasImdbId, HasImdbId)
176 FWDPROP(bool, hasOfficialRating, HasOfficialRating)
177 FWDPROP(bool, hasOverview, HasOverview)
178 FWDPROP(bool, hasParentalRating, HasParentalRating)
179 FWDPROP(bool, hasSpecialFeature, HasSpecialFeature)
180 FWDPROP(bool, hasSubtitles, HasSubtitles)
181 FWDPROP(bool, hasThemeSong, HasThemeSong)
182 FWDPROP(bool, hasThemeVideo, HasThemeVideo)
183 FWDPROP(bool, hasTmdbId, HasTmdbId)
184 FWDPROP(bool, hasTrailer, HasTrailer)
185 FWDPROP(bool, hasTvdbId, HasTvdbId)
186 FWDPROP(QStringList, ids, Ids)
187 FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
188 FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, imageTypes, ImageTypes)
189 FWDPROP(QStringList, includeItemTypes, IncludeItemTypes)
190 FWDPROP(bool, is3D, Is3D)
191 FWDPROP(bool, is4K, Is4K)
192 FWDPROP(bool, isFavorite, IsFavorite)
193 FWDPROP(bool, isHd, IsHd)
194 FWDPROP(bool, isLocked, IsLocked)
195 FWDPROP(bool, isMissing, IsMissing)
196 FWDPROP(bool, isPlaceHolder, IsPlaceHolder)
197 FWDPROP(bool, isPlayed, IsPlayed)
198 FWDPROP(bool, isUnaired, IsUnaired)
199 FWDLISTPROP(Jellyfin::DTO::LocationTypeClass::Value, locationTypes, LocationTypes)
200 FWDPROP(qint32, maxHeight, MaxHeight)
201 FWDPROP(QString, maxOfficialRating, MaxOfficialRating)
202 FWDPROP(QDateTime, maxPremiereDate, MaxPremiereDate)
203 FWDPROP(qint32, maxWidth, MaxWidth)
204 FWDPROP(QStringList, mediaTypes, MediaTypes)
205 FWDPROP(qint32, minHeight, MinHeight)
206 FWDPROP(QString, minOfficialRating, MinOfficialRating)
207 FWDPROP(QDateTime, minPremiereDate, MinPremiereDate)
208 FWDPROP(qint32, minWidth, MinWidth)
209 FWDPROP(QString, sortBy, SortBy)
210 FWDPROP(QString, sortOrder, SortOrder)
211 FWDPROP(QStringList, tags, Tags)
212 FWDPROP(QList<qint32>, years, Years)
213
214 FWDPROP(QString, parentId, ParentId)
215 FWDPROP(bool, recursive, Recursive)
216 FWDPROP(QString, searchTerm, SearchTerm)
217 //FWDPROP(bool, collapseBoxSetItems)
218};
219
222 Q_OBJECT
223public:
224 explicit ResumeItemsLoader(QObject *parent = nullptr);
225
226 FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, enableImageTypes, EnableImageTypes);
227 FWDPROP(bool, enableImages, EnableImages)
228 FWDPROP(bool, enableTotalRecordCount, EnableTotalRecordCount)
229 FWDPROP(bool, enableUserData, EnableUserData)
230 FWDPROP(QStringList, excludeItemTypes, ExcludeItemTypes)
231 FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
232 FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
233 FWDPROP(QStringList, includeItemTypes, IncludeItemTypes)
234 FWDPROP(QStringList, mediaTypes, MediaTypes)
235 FWDPROP(QString, parentId, ParentId)
236 FWDPROP(QString, searchTerm, SearchTerm)
237};
238
241 Q_OBJECT
242public:
243 explicit ShowSeasonsLoader(QObject *parent = nullptr);
244
245 FWDPROP(QString, seriesId, SeriesId)
246 FWDPROP(QString, adjacentTo, AdjacentTo)
247 FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, enableImageTypes, EnableImageTypes)
248 FWDPROP(bool, enableImages, EnableImages)
249 FWDPROP(bool, enableUserData, EnableUserData)
250 FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
251 FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
252 FWDPROP(bool, isMissing, IsMissing)
253 FWDPROP(bool, isSpecialSeason, IsSpecialSeason)
254
255};
256
259 Q_OBJECT
260public:
261 explicit ShowEpisodesLoader(QObject *parent = nullptr);
262
263 FWDPROP(QString, seriesId, SeriesId)
264 FWDPROP(QString, adjacentTo, AdjacentTo)
265 FWDPROP(bool, enableImages, EnableImages)
266 FWDPROP(bool, enableUserData, EnableUserData)
267 FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
268 FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
269 FWDPROP(bool, isMissing, IsMissing)
270 FWDPROP(qint32, season, Season)
271 FWDPROP(QString, seasonId, SeasonId)
272 FWDPROP(QString, sortBy, SortBy)
273 FWDPROP(QString, startItemId, StartItemId)
274};
275
278 Q_OBJECT
279public:
280 explicit NextUpLoader(QObject *parent = nullptr);
281
282 FWDPROP(bool, disableFirstEpisode, DisableFirstEpisode)
283 FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, enableImageTypes, EnableImageTypes);
284 FWDPROP(bool, enableImges, EnableImges)
285 FWDPROP(bool, enableTotalRecordCount, EnableTotalRecordCount)
286 FWDPROP(bool, enableUserData, EnableUserData)
287 FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
288 FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
289 FWDPROP(QString, parentId, ParentId)
290 FWDPROP(QString, seriesId, SeriesId)
291};
292
295 Q_OBJECT
296public:
297 explicit AlbumArtistLoader(QObject *parent = nullptr);
298
299 FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, enableImageTypes, EnableImageTypes);
300 FWDPROP(bool, enableImages, EnableImages)
301 FWDPROP(bool, enableTotalRecordCount, EnableTotalRecordCount)
302 FWDPROP(bool, enableUserData, EnableUserData)
303 FWDPROP(QStringList, excludeItemTypes, ExcludeItemTypes)
304 FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
305 FWDLISTPROP(Jellyfin::DTO::ItemFilterClass::Value, filters, Filters)
306 FWDPROP(QStringList, genreIds, GenreIds)
307 FWDPROP(QStringList, genres, Genres)
308 FWDPROP(qint32, imageTypeLimit, ImageTypeLimit)
309 FWDPROP(QStringList, includeItemTypes, IncludeItemTypes)
310 FWDPROP(bool, isFavorite, IsFavorite)
311 FWDPROP(int, limit, Limit)
312 FWDPROP(QStringList, mediaTypes, MediaTypes)
313 FWDPROP(double, minCommunityRating, MinCommunityRating)
314 FWDPROP(QString, nameLessThan, NameLessThan)
315 FWDPROP(QString, nameStartsWith, NameStartsWith)
316 FWDPROP(QString, nameStartsWithOrGreater, NameStartsWithOrGreater)
317 FWDPROP(QStringList, officialRatings, OfficialRatings)
318 FWDPROP(QString, parentId, ParentId)
319 FWDPROP(QStringList, personIds, PersonIds)
320 FWDPROP(QStringList, personTypes, PersonTypes)
321 FWDPROP(QString, searchTerm, SearchTerm)
322 FWDPROP(int, startIndex, StartIndex)
323 FWDPROP(QStringList, studioIds, StudioIds)
324 FWDPROP(QStringList, studios, Studios)
325 FWDPROP(QStringList, tags, Tags)
326 FWDPROP(QString, userId, UserId)
327 FWDLISTPROP(int, years, Years);
328};
329
332 Q_OBJECT
333public:
334 explicit LiveTvChannelsLoader(QObject *parent = nullptr);
335
337 FWDPROP(bool, isMovie, IsMovie)
338 FWDPROP(bool, isSeries, IsSeries)
339 FWDPROP(bool, isNews, IsNews)
340 FWDPROP(bool, isKids, IsKids)
341 FWDPROP(bool, isSports, IsSports)
342 FWDPROP(bool, isFavorite, IsFavorite)
343 FWDPROP(bool, isLiked, IsLiked)
344 FWDPROP(bool, isDisliked, IsDisliked)
345 FWDPROP(bool, enableImages, EnableImages)
346 FWDPROP(int, imageTypeLimit, ImageTypeLimit)
347 FWDLISTPROP(Jellyfin::DTO::ImageTypeClass::Value, enableImageTypes, EnableImageTypes)
348 FWDLISTPROP(Jellyfin::DTO::ItemFieldsClass::Value, fields, Fields)
349 FWDPROP(bool, enableUserData, EnableUserData)
350 FWDPROP(QStringList, sortBy, SortBy)
351 FWDPROP(Jellyfin::DTO::SortOrderClass::Value, sortOrder, SortOrder)
352 FWDPROP(bool, enableFavoriteSorting, EnableFavoriteSorting)
353 FWDPROP(bool, addCurrentProgram, AddCurrentProgram)
354};
355
360class ItemModel : public ApiModel<Model::Item> {
361 Q_OBJECT
362public:
405
406 explicit ItemModel (QObject *parent = nullptr);
407
408 virtual QHash<int, QByteArray> roleNames() const override {
409 return {
410 JFRN(jellyfinId),
411 JFRN(name),
412 JFRN(originalTitle),
413 JFRN(serverId),
414 JFRN(etag),
415 JFRN(sourceType),
416 JFRN(playlistItemId),
417 JFRN(dateCreated),
418 JFRN(dateLastMediaAdded),
419 JFRN(extraType),
420 // Handpicked, important ones
421 JFRN(imageTags),
422 JFRN(imageBlurHashes),
423 JFRN(mediaType),
424 JFRN(type),
425 JFRN(collectionType),
426 JFRN(indexNumber),
427 JFRN(runTimeTicks),
428 JFRN(artists),
429 JFRN(artistItems),
430 JFRN(isFolder),
431 JFRN(overview),
432 JFRN(parentIndexNumber),
433 JFRN(userDataRating),
434 JFRN(userDataPlayedPercentage),
435 JFRN(userDataUnplayedItemCount),
436 JFRN(userDataPlaybackPositionTicks),
437 JFRN(userDataPlayCount),
438 JFRN(userDataFavorite),
439 JFRN(userDataLikes),
440 JFRN(userDataLastPlayedDate),
441 JFRN(userDataPlayed),
442 JFRN(userDataKey),
443 JFRN(currentProgramName),
444 JFRN(currentProgramOverview),
445 JFRN(currentProgramStartDate),
446 JFRN(currentProgramEndDate),
447 };
448 }
449 QVariant data(const QModelIndex &index, int role) const override;
450 QSharedPointer<Model::Item> itemAt(int index);
451private slots:
452 void onInsertItems(const QModelIndex &parent, int start, int end);
453 void onUserDataUpdated(const DTO::UserItemDataDto &newUserData);
454};
455#undef JFRN
456
457} // NS Jellyfin
458} // NS ViewModel
459
460#undef FWDPROP
461
462#endif // JELLYFIN_VIEWMODEL_ITEMMODEL_H
An Api client for Jellyfin. Handles requests and authentication.
Definition apiclient.h:90
void userIdChanged(QString userId)
QString userId
Definition apiclient.h:103
Abstract model for displaying collections.
Definition apimodel.h:405
int limit
Definition apimodel.h:75
void autoReloadIfNeeded()
Definition apimodel.cpp:49
void apiClientChanged(ApiClient *newApiClient)
virtual bool canReload() const
Determines if this model is able to reload.
Definition apimodel.cpp:83
ApiClient * m_apiClient
Definition apimodel.h:117
Definition baseitemdtoqueryresult.h:50
Definition baseitemdto.h:70
Value
Definition channeltype.h:49
Definition imagetype.h:46
Value
Definition imagetype.h:49
Definition itemfields.h:46
Definition itemfilter.h:46
Definition locationtype.h:46
Definition sortorder.h:46
Value
Definition sortorder.h:49
Definition useritemdatadto.h:49
Definition apimodel.h:282
P m_parameters
Definition apimodel.h:328
Definition loader.h:134
Class intended for models which have a mandatory userId property, which can be extracted from the Api...
Definition itemmodel.h:88
AbstractUserParameterLoader(Support::Loader< R, P > *loader, QObject *parent=nullptr)
Definition itemmodel.h:90
virtual bool canReload() const override
Determines if this model is able to reload.
Definition itemmodel.h:95
Definition itemmodel.h:294
Base class for each model that works with items.
Definition itemmodel.h:360
RoleNames
Definition itemmodel.h:363
@ collectionType
Definition itemmodel.h:380
@ userDataPlayCount
Definition itemmodel.h:392
@ userDataPlayedPercentage
Definition itemmodel.h:389
@ currentProgramName
Definition itemmodel.h:398
@ artistItems
Definition itemmodel.h:384
@ parentIndexNumber
Definition itemmodel.h:387
@ userDataLastPlayedDate
Definition itemmodel.h:395
@ serverId
Definition itemmodel.h:367
@ runTimeTicks
Definition itemmodel.h:382
@ userDataKey
Definition itemmodel.h:397
@ currentProgramEndDate
Definition itemmodel.h:401
@ imageTags
Definition itemmodel.h:376
@ mediaType
Definition itemmodel.h:378
@ userDataPlaybackPositionTicks
Definition itemmodel.h:391
@ sourceType
Definition itemmodel.h:369
@ name
Definition itemmodel.h:365
@ imageBlurHashes
Definition itemmodel.h:377
@ currentProgramStartDate
Definition itemmodel.h:400
@ dateLastMediaAdded
Definition itemmodel.h:372
@ overview
Definition itemmodel.h:386
@ userDataRating
Definition itemmodel.h:388
@ etag
Definition itemmodel.h:368
@ indexNumber
Definition itemmodel.h:381
@ extraType
Definition itemmodel.h:373
@ userDataFavorite
Definition itemmodel.h:393
@ originalTitle
Definition itemmodel.h:366
@ dateCreated
Definition itemmodel.h:371
@ userDataUnplayedItemCount
Definition itemmodel.h:390
@ type
Definition itemmodel.h:379
@ artists
Definition itemmodel.h:383
@ userDataLikes
Definition itemmodel.h:394
@ playlistItemId
Definition itemmodel.h:370
@ isFolder
Definition itemmodel.h:385
@ userDataPlayed
Definition itemmodel.h:396
@ currentProgramOverview
Definition itemmodel.h:399
virtual QHash< int, QByteArray > roleNames() const override
Definition itemmodel.h:408
Definition item.h:104
Definition itemmodel.h:132
Definition loader.h:148
Definition itemmodel.h:277
Definition itemmodel.h:221
Definition itemmodel.h:258
Definition itemmodel.h:240
Definition itemmodel.h:150
Definition itemmodel.h:121
QStringList presetViews
Definition itemmodel.h:128
bool includeExternalContent
Definition itemmodel.h:126
bool includeHidden
Definition itemmodel.h:127
UserViewsLoader(QObject *parent=nullptr)
Definition itemmodel.cpp:44
Definition mediaplayer2.h:20
#define JFRN(name)
Definition itemmodel.h:79
#define FWDLISTPROP(type, propName, propSetName)
Definition itemmodel.h:49
#define FWDPROP(type, propName, propSetName)
Definition itemmodel.h:37
void writeRequestTypesFile R(File headerFile, File implementationFile, R endpoints) if(is(ElementType!R
Definition openapigenerator.d:278