Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Elisa
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
13
Merge Requests
13
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Multimedia
Elisa
Commits
f99c72eb
Commit
f99c72eb
authored
Oct 11, 2020
by
Matthieu Gallien
🎵
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
various small code fixes from clang-tidy, clazy and manual review
parent
8bb8eb35
Pipeline
#37673
passed with stage
in 44 minutes and 26 seconds
Changes
16
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
112 additions
and
713 deletions
+112
-713
src/CMakeLists.txt
src/CMakeLists.txt
+0
-1
src/models/upnpalbummodel.cpp
src/models/upnpalbummodel.cpp
+0
-446
src/models/upnpalbummodel.h
src/models/upnpalbummodel.h
+0
-173
src/musiclistenersmanager.h
src/musiclistenersmanager.h
+2
-2
src/upnp/didlparser.cpp
src/upnp/didlparser.cpp
+32
-14
src/upnp/didlparser.h
src/upnp/didlparser.h
+15
-15
src/upnp/upnpcontentdirectorymodel.h
src/upnp/upnpcontentdirectorymodel.h
+16
-16
src/upnp/upnpcontrolconnectionmanager.cpp
src/upnp/upnpcontrolconnectionmanager.cpp
+2
-2
src/upnp/upnpcontrolconnectionmanager.h
src/upnp/upnpcontrolconnectionmanager.h
+5
-5
src/upnp/upnpcontrolcontentdirectory.cpp
src/upnp/upnpcontrolcontentdirectory.cpp
+1
-1
src/upnp/upnpcontrolcontentdirectory.h
src/upnp/upnpcontrolcontentdirectory.h
+5
-5
src/upnp/upnpcontrolmediaserver.h
src/upnp/upnpcontrolmediaserver.h
+1
-1
src/upnp/upnpdiscoverallmusic.h
src/upnp/upnpdiscoverallmusic.h
+2
-2
src/viewconfigurationdata.cpp
src/viewconfigurationdata.cpp
+15
-14
src/viewconfigurationdata.h
src/viewconfigurationdata.h
+4
-4
src/viewmanager.cpp
src/viewmanager.cpp
+12
-12
No files found.
src/CMakeLists.txt
View file @
f99c72eb
...
...
@@ -181,7 +181,6 @@ if (UpnpLibQt_FOUND)
upnp/upnpcontrolmediaserver.cpp
upnp/didlparser.cpp
upnp/upnpdiscoverallmusic.cpp
models/upnpalbummodel.cpp
)
endif
()
...
...
src/models/upnpalbummodel.cpp
deleted
100644 → 0
View file @
8bb8eb35
/*
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"
src/models/upnpalbummodel.h
deleted
100644 → 0
View file @
8bb8eb35
/*
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
src/musiclistenersmanager.h
View file @
f99c72eb
...
...
@@ -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: