Commit f99c72eb authored by Matthieu Gallien's avatar Matthieu Gallien 🎵

various small code fixes from clang-tidy, clazy and manual review

parent 8bb8eb35
Pipeline #37673 passed with stage
in 44 minutes and 26 seconds
......@@ -181,7 +181,6 @@ if (UpnpLibQt_FOUND)
upnp/upnpcontrolmediaserver.cpp
upnp/didlparser.cpp
upnp/upnpdiscoverallmusic.cpp
models/upnpalbummodel.cpp
)
endif()
......
/*
SPDX-FileCopyrightText: 2015 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "upnpalbummodel.h"
#include "upnp/didlparser.h"
#include "upnp/upnpcontrolcontentdirectory.h"
#include <QtXml/QDomDocument>
#include <QtCore/QVector>
#include <QtCore/QUrl>
#include <QtCore/QPointer>
#include <QtCore/QDebug>
class UpnpAlbumModelPrivate
{
public:
UpnpControlContentDirectory *mContentDirectory = nullptr;
DidlParser mDidlParser;
QString mBrowseFlag;
QString mFilter;
QString mSortCriteria;
QVector<QString> mChilds;
QHash<QString, QPointer<DidlParser>> mAlbumParsers;
QString mServerName;
bool mUseLocalIcons = false;
};
UpnpAlbumModel::UpnpAlbumModel(QObject *parent) : QAbstractItemModel(parent), d(new UpnpAlbumModelPrivate)
{
d->mDidlParser.setSearchCriteria(QStringLiteral("upnp:class = \"object.container.album.musicAlbum\""));
d->mDidlParser.setParentId(QStringLiteral("0"));
connect(&d->mDidlParser, &DidlParser::isDataValidChanged, this, &UpnpAlbumModel::contentChanged);
}
UpnpAlbumModel::~UpnpAlbumModel()
{
delete d;
}
int UpnpAlbumModel::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid()) {
return d->mDidlParser.newMusicTrackIds().size();
}
if (!d->mAlbumParsers.contains(d->mChilds[parent.row()])) {
return 0;
}
auto childParser = d->mAlbumParsers[d->mChilds[parent.row()]];
if (!childParser) {
return 0;
}
return childParser->newMusicTrackIds().size();
}
QHash<int, QByteArray> UpnpAlbumModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[static_cast<int>(ColumnsRoles::TitleRole)] = "title";
roles[static_cast<int>(ColumnsRoles::DurationRole)] = "duration";
roles[static_cast<int>(ColumnsRoles::ArtistRole)] = "artist";
roles[static_cast<int>(ColumnsRoles::AlbumRole)] = "album";
roles[static_cast<int>(ColumnsRoles::TrackNumberRole)] = "trackNumber";
roles[static_cast<int>(ColumnsRoles::RatingRole)] = "rating";
roles[static_cast<int>(ColumnsRoles::ImageRole)] = "image";
roles[static_cast<int>(ColumnsRoles::ItemClassRole)] = "itemClass";
roles[static_cast<int>(ColumnsRoles::CountRole)] = "count";
roles[static_cast<int>(ColumnsRoles::IsPlayingRole)] = "isPlaying";
return roles;
}
bool UpnpAlbumModel::canFetchMore(const QModelIndex &parent) const
{
if (!parent.isValid()) {
return false;
}
if (parent.internalId() != 0) {
return false;
}
if (!d->mAlbumParsers.contains(d->mChilds[parent.row()])) {
return true;
}
auto childParser = d->mAlbumParsers[d->mChilds[parent.row()]];
if (!childParser) {
return true;
}
return false;
}
void UpnpAlbumModel::fetchMore(const QModelIndex &parent)
{
if (!d->mAlbumParsers.contains(d->mChilds[parent.row()])) {
d->mAlbumParsers[d->mChilds[parent.row()]] = new DidlParser(this);
auto newParser = d->mAlbumParsers[d->mChilds[parent.row()]];
newParser->setBrowseFlag(d->mDidlParser.browseFlag());
newParser->setFilter(d->mDidlParser.filter());
newParser->setSortCriteria(d->mDidlParser.sortCriteria());
newParser->setContentDirectory(d->mDidlParser.contentDirectory());
newParser->setParentId(d->mChilds[parent.row()]);
connect(newParser, &DidlParser::isDataValidChanged, this, &UpnpAlbumModel::contentChanged);
newParser->browse();
}
}
Qt::ItemFlags UpnpAlbumModel::flags(const QModelIndex &index) const
{
if (!index.isValid()) {
return Qt::NoItemFlags;
}
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
QVariant UpnpAlbumModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return {};
}
if (index.column() != 0) {
return {};
}
if (index.row() < 0) {
return {};
}
if (index.row() >= d->mDidlParser.newMusicTrackIds().size()) {
return {};
}
if (index.internalId() != 0) {
if (!d->mAlbumParsers.contains(d->mChilds[index.internalId() - 1])) {
return 0;
}
auto childParser = d->mAlbumParsers[d->mChilds[index.internalId() - 1]];
if (!childParser) {
return 0;
}
return internalDataTrack(index, role, childParser);
}
return internalDataAlbum(index, role, &d->mDidlParser);
}
QVariant UpnpAlbumModel::internalDataAlbum(const QModelIndex &index, int role, DidlParser *currentParser) const
{
ColumnsRoles convertedRole = static_cast<ColumnsRoles>(role);
//const auto &albumId = currentParser->newMusicTrackIds()[index.row()];
const auto &albumId = index.row();
switch(convertedRole)
{
case ColumnsRoles::TitleRole:
return {}/*currentParser->newMusicTracks()[albumId].title()*/;
case ColumnsRoles::DurationRole:
return {};
case ColumnsRoles::CreatorRole:
return {};
case ColumnsRoles::ArtistRole:
return {}/*currentParser->newMusicTracks()[albumId].artist()*/;
case ColumnsRoles::AlbumRole:
return {};
case ColumnsRoles::RatingRole:
return {};
case ColumnsRoles::ImageRole:
if (false/*currentParser->newMusicTracks()[albumId].albumCover().isValid()*/) {
return {}/*currentParser->newMusicTracks()[albumId].albumCover()*/;
} else {
if (d->mUseLocalIcons) {
return QUrl(QStringLiteral("qrc:/media-optical-audio.svg"));
} else {
return QUrl(QStringLiteral("image://icon/media-optical-audio"));
}
}
case ColumnsRoles::ResourceRole:
return {}/*currentParser->newMusicTracks()[albumId].resourceURI()*/;
case ColumnsRoles::ItemClassRole:
return {};
case ColumnsRoles::CountRole:
//return currentParser->newMusicTracks()[albumId].mTracksCount;
return 1;
case ColumnsRoles::IdRole:
return {};
//return currentParser->newMusicTracks()[albumId].mId;
case ColumnsRoles::ParentIdRole:
return {};
//return currentParser->newMusicTracks()[albumId].mParentId;
case ColumnsRoles::IsPlayingRole:
return {};
case ColumnsRoles::TrackNumberRole:
return {};
}
return {};
}
QVariant UpnpAlbumModel::internalDataTrack(const QModelIndex &index, int role, DidlParser *currentParser) const
{
ColumnsRoles convertedRole = static_cast<ColumnsRoles>(role);
if (index.row() < 0 || index.row() >= currentParser->newMusicTrackIds().size()) {
return {};
}
//const auto &musicTrackId = currentParser->newMusicTrackIds()[index.row()];
const auto &musicTrackId = index.row();
// switch(convertedRole)
// {
// case ColumnsRoles::TitleRole:
// return currentParser->newMusicTracks()[musicTrackId].title();
// case ColumnsRoles::DurationRole:
// if (currentParser->newMusicTracks()[musicTrackId].duration().hour() == 0) {
// return currentParser->newMusicTracks()[musicTrackId].duration().toString(QStringLiteral("mm:ss"));
// } else {
// return currentParser->newMusicTracks()[musicTrackId].duration().toString();
// }
// case ColumnsRoles::CreatorRole:
// return currentParser->newMusicTracks()[musicTrackId].artist();
// case ColumnsRoles::ArtistRole:
// return currentParser->newMusicTracks()[musicTrackId].artist();
// case ColumnsRoles::AlbumRole:
// return currentParser->newMusicTracks()[musicTrackId].album();
// case ColumnsRoles::TrackNumberRole:
// return currentParser->newMusicTracks()[musicTrackId].trackNumber();
// case ColumnsRoles::RatingRole:
// return 0;
// case ColumnsRoles::ImageRole:
// return data(index.parent(), role);
// case ColumnsRoles::ResourceRole:
// return currentParser->newMusicTracks()[musicTrackId].resourceURI();
// case ColumnsRoles::ItemClassRole:
// return {};
// case ColumnsRoles::CountRole:
// return {};
// case ColumnsRoles::IdRole:
// return currentParser->newMusicTracks()[musicTrackId].id();
// case ColumnsRoles::ParentIdRole:
// return currentParser->newMusicTracks()[musicTrackId].parentId();
// case ColumnsRoles::IsPlayingRole:
// return false;
// }
return {};
}
QModelIndex UpnpAlbumModel::index(int row, int column, const QModelIndex &parent) const
{
if (!parent.isValid()) {
return createIndex(row, column, quintptr(0));
}
return createIndex(row, column, quintptr(parent.row()) + 1);
}
QModelIndex UpnpAlbumModel::parent(const QModelIndex &child) const
{
// child is valid
if (!child.isValid()) {
return {};
}
if (child.internalId() == 0) {
return {};
}
return createIndex(int(child.internalId() - 1), 0, quintptr(0));
}
int UpnpAlbumModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 1;
}
UpnpControlContentDirectory *UpnpAlbumModel::contentDirectory() const
{
return d->mContentDirectory;
}
DidlParser *UpnpAlbumModel::didlParser() const
{
return &d->mDidlParser;
}
const QString &UpnpAlbumModel::browseFlag() const
{
return d->mBrowseFlag;
}
const QString &UpnpAlbumModel::filter() const
{
return d->mFilter;
}
const QString &UpnpAlbumModel::sortCriteria() const
{
return d->mSortCriteria;
}
QString UpnpAlbumModel::serverName() const
{
return d->mServerName;
}
bool UpnpAlbumModel::useLocalIcons() const
{
return d->mUseLocalIcons;
}
void UpnpAlbumModel::setContentDirectory(UpnpControlContentDirectory *directory)
{
if (directory) {
beginResetModel();
}
if (d->mContentDirectory) {
disconnect(d->mContentDirectory, &UpnpControlContentDirectory::systemUpdateIDChanged,
&d->mDidlParser, &DidlParser::systemUpdateIDChanged);
}
d->mContentDirectory = directory;
if (!d->mContentDirectory) {
Q_EMIT contentDirectoryChanged();
return;
}
connect(d->mContentDirectory, &UpnpControlContentDirectory::systemUpdateIDChanged,
&d->mDidlParser, &DidlParser::systemUpdateIDChanged);
d->mDidlParser.setContentDirectory(directory);
d->mDidlParser.setBrowseFlag(browseFlag());
d->mDidlParser.setFilter(filter());
d->mDidlParser.setSortCriteria(sortCriteria());
d->mDidlParser.search();
endResetModel();
Q_EMIT contentDirectoryChanged();
}
void UpnpAlbumModel::setBrowseFlag(const QString &flag)
{
d->mBrowseFlag = flag;
Q_EMIT browseFlagChanged();
}
void UpnpAlbumModel::setFilter(const QString &flag)
{
d->mFilter = flag;
Q_EMIT filterChanged();
}
void UpnpAlbumModel::setSortCriteria(const QString &criteria)
{
d->mSortCriteria = criteria;
Q_EMIT sortCriteriaChanged();
}
void UpnpAlbumModel::setServerName(QString serverName)
{
if (d->mServerName == serverName)
return;
d->mServerName = serverName;
emit serverNameChanged();
}
void UpnpAlbumModel::setUseLocalIcons(bool useLocalIcons)
{
if (d->mUseLocalIcons == useLocalIcons)
return;
d->mUseLocalIcons = useLocalIcons;
emit useLocalIconsChanged();
}
void UpnpAlbumModel::contentChanged(const QString &parentId)
{
if (parentId == QStringLiteral("0")) {
beginResetModel();
d->mChilds = d->mDidlParser.newMusicTrackIds();
endResetModel();
return;
}
auto indexChild = d->mChilds.indexOf(parentId);
if (indexChild == -1) {
return;
}
if (!d->mAlbumParsers.contains(parentId)) {
return;
}
auto childParser = d->mAlbumParsers[parentId];
if (!childParser) {
return;
}
beginInsertRows(index(indexChild, 0), 0, childParser->newMusicTrackIds().size() - 1);
endInsertRows();
}
#include "moc_upnpalbummodel.cpp"
/*
SPDX-FileCopyrightText: 2015 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef UPNPALBUMMODEL_H
#define UPNPALBUMMODEL_H
#include "datatypes.h"
#include <QtCore/QAbstractItemModel>
class UpnpAlbumModelPrivate;
class UpnpSsdpEngine;
class UpnpControlAbstractDevice;
class UpnpControlContentDirectory;
class UpnpDiscoveryResult;
class QDomNode;
class DidlParser;
class UpnpAlbumModel : public QAbstractItemModel
{
Q_OBJECT
Q_PROPERTY(UpnpControlContentDirectory* contentDirectory
READ contentDirectory
WRITE setContentDirectory
NOTIFY contentDirectoryChanged)
Q_PROPERTY(DidlParser* didlParser
READ didlParser
NOTIFY didlParserChanged)
Q_PROPERTY(QString browseFlag
READ browseFlag
WRITE setBrowseFlag
NOTIFY browseFlagChanged)
Q_PROPERTY(QString filter
READ filter
WRITE setFilter
NOTIFY filterChanged)
Q_PROPERTY(QString sortCriteria
READ sortCriteria
WRITE setSortCriteria
NOTIFY sortCriteriaChanged)
Q_PROPERTY(QString serverName
READ serverName
WRITE setServerName
NOTIFY serverNameChanged)
Q_PROPERTY(bool useLocalIcons
READ useLocalIcons
WRITE setUseLocalIcons
NOTIFY useLocalIconsChanged)
public:
enum ItemClass {
Container = 0,
Album = 1,
Artist = 2,
AudioTrack = 3,
};
enum ColumnsRoles {
TitleRole = Qt::UserRole + 1,
DurationRole = TitleRole + 1,
CreatorRole = DurationRole + 1,
ArtistRole = CreatorRole + 1,
AlbumRole = ArtistRole + 1,
TrackNumberRole = AlbumRole + 1,
RatingRole = TrackNumberRole + 1,
ImageRole = RatingRole + 1,
ResourceRole = ImageRole + 1,
ItemClassRole = ResourceRole + 1,
CountRole = ItemClassRole + 1,
IdRole = CountRole + 1,
ParentIdRole = IdRole + 1,
IsPlayingRole = ParentIdRole + 1,
};
explicit UpnpAlbumModel(QObject *parent = nullptr);
~UpnpAlbumModel() override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
bool canFetchMore(const QModelIndex &parent) const override;
void fetchMore(const QModelIndex &parent) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &child) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
UpnpControlContentDirectory* contentDirectory() const;
DidlParser* didlParser() const;
const QString& browseFlag() const;
const QString& filter() const;
const QString& sortCriteria() const;
QString serverName() const;
bool useLocalIcons() const;
Q_SIGNALS:
void contentDirectoryChanged();
void musicDatabaseChanged();
void didlParserChanged();
void browseFlagChanged();
void filterChanged();
void sortCriteriaChanged();
void newAudioTrack(const DataTypes::TrackDataType &audioTrack);
void serverNameChanged();
void useLocalIconsChanged();
public Q_SLOTS:
void setContentDirectory(UpnpControlContentDirectory *directory);
void setBrowseFlag(const QString &flag);
void setFilter(const QString &flag);
void setSortCriteria(const QString &criteria);
void setServerName(QString serverName);
void setUseLocalIcons(bool useLocalIcons);
private Q_SLOTS:
void contentChanged(const QString &parentId);
private:
QVariant internalDataAlbum(const QModelIndex &index, int role, DidlParser *currentParser) const;
QVariant internalDataTrack(const QModelIndex &index, int role, DidlParser *currentParser) const;
UpnpAlbumModelPrivate *d;
};
Q_DECLARE_METATYPE(UpnpAlbumModel::ItemClass)
#endif // UPNPALBUMMODEL_H
......@@ -100,9 +100,9 @@ public:
bool androidIndexerAvailable() const;
UpnpSsdpEngine* ssdpEngine() const;
[[nodiscard]] [[nodiscard]] UpnpSsdpEngine* ssdpEngine() const;
UpnpDiscoverAllMusic* upnpServiceDiscovery() const;
[[nodiscard]] [[nodiscard]] UpnpDiscoverAllMusic* upnpServiceDiscovery() const;
Q_SIGNALS:
......