Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25290d978f | ||
|
|
d562d3aeca | ||
|
|
c4bcb2e4c1 | ||
|
|
16dde731ec | ||
|
|
7abf23f746 | ||
|
|
ecdf4f7a46 | ||
|
|
084c8b0f57 |
No files matched your search
+5
-5
@@ -15,12 +15,12 @@ project(audiotube VERSION ${RELEASE_SERVICE_VERSION})
|
||||
include(FeatureSummary)
|
||||
|
||||
set(QT5_MIN_VERSION 5.15)
|
||||
set(KF5_MIN_VERSION 5.81)
|
||||
set(KF_MIN_VERSION 5.81)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
|
||||
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
||||
@@ -39,12 +39,12 @@ ecm_setup_version(${PROJECT_VERSION}
|
||||
|
||||
kde_enable_exceptions()
|
||||
|
||||
find_package(Qt${QT_MAJOR_VERSION} ${QT5_MIN_VERSION} REQUIRED COMPONENTS Core Gui Qml QuickControls2 Svg Sql Widgets Concurrent DBus)
|
||||
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Kirigami2 I18n CoreAddons Crash WindowSystem)
|
||||
find_package(Qt${QT_MAJOR_VERSION} ${QT5_MIN_VERSION} REQUIRED COMPONENTS Core Gui Qml QuickControls2 Svg Sql Widgets Multimedia Concurrent DBus)
|
||||
find_package(KF6 REQUIRED COMPONENTS Kirigami2 I18n CoreAddons Crash WindowSystem)
|
||||
find_package(pybind11 REQUIRED)
|
||||
find_package(Ytdlp REQUIRED RUNTIME)
|
||||
find_package(YTMusicAPI 0.24.0 REQUIRED RUNTIME)
|
||||
find_package(KF5KirigamiAddons 0.6.0 REQUIRED)
|
||||
find_package(KF6KirigamiAddons 0.6.0 REQUIRED)
|
||||
find_package(FutureSQL${QT_MAJOR_VERSION} REQUIRED)
|
||||
|
||||
ki18n_install(po)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "org.kde.audiotube",
|
||||
"runtime": "org.kde.Platform",
|
||||
"runtime-version": "5.15-22.08",
|
||||
"runtime-version": "6.4-22.08",
|
||||
"sdk": "org.kde.Sdk",
|
||||
"command": "audiotube",
|
||||
"tags": ["nightly"],
|
||||
|
||||
+5
-4
@@ -45,10 +45,11 @@ target_link_libraries(audiotube
|
||||
Qt::Svg
|
||||
Qt::Widgets
|
||||
Qt::Concurrent
|
||||
KF5::I18n
|
||||
KF5::CoreAddons
|
||||
KF5::Crash
|
||||
KF5::WindowSystem
|
||||
Qt::Multimedia
|
||||
KF6::I18n
|
||||
KF6::CoreAddons
|
||||
KF6::Crash
|
||||
KF6::WindowSystem
|
||||
FutureSQL${QT_MAJOR_VERSION}::FutureSQL
|
||||
declarative
|
||||
ytm
|
||||
|
||||
@@ -6,7 +6,7 @@ import QtQuick 2.15
|
||||
import org.kde.kirigami 2.14 as Kirigami
|
||||
import QtQuick.Controls 2.14 as Controls
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.0
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import org.kde.ytmusic 1.0
|
||||
|
||||
@@ -125,8 +125,8 @@ Item {
|
||||
id: overflowMenu
|
||||
Instantiator {
|
||||
model: root.overflowActions
|
||||
onObjectAdded: overflowMenu.insertItem(index, object)
|
||||
onObjectRemoved: overflowMenu.removeItem(object)
|
||||
onObjectAdded: (index) => overflowMenu.insertItem(index, object)
|
||||
onObjectRemoved: (index) => overflowMenu.removeItem(object)
|
||||
delegate: Controls.MenuItem {
|
||||
required property var modelData
|
||||
icon.name: modelData.icon.name
|
||||
|
||||
@@ -6,8 +6,8 @@ import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtMultimedia 5.12
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtMultimedia
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
import org.kde.ytmusic 1.0
|
||||
@@ -288,12 +288,12 @@ Item {
|
||||
focusPolicy: Qt.TabFocus
|
||||
implicitHeight: 40
|
||||
implicitWidth: 60
|
||||
onClicked: audio.playbackState === Audio.PlayingState ? audio.pause() : audio.play()
|
||||
enabled: info.title
|
||||
onClicked: audio.playbackState === MediaPlayer.PlayingState ? audio.pause() : audio.play()
|
||||
contentItem: Item{
|
||||
Kirigami.Icon {
|
||||
anchors.centerIn:parent
|
||||
source: audio.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
|
||||
source: audio.playbackState === MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start"
|
||||
color: "white"
|
||||
width: Kirigami.Units.gridUnit
|
||||
height: Kirigami.Units.gridUnit
|
||||
@@ -569,7 +569,7 @@ Item {
|
||||
enabled: isWidescreen
|
||||
visible: isWidescreen
|
||||
|
||||
property real volume: QtMultimedia.convertVolume(value, QtMultimedia.LogarithmicVolumeScale, QtMultimedia.LinearVolumeScale)
|
||||
property real volume: PlayerUtils.convertVolume(value)
|
||||
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
|
||||
@@ -581,14 +581,10 @@ Item {
|
||||
wheelEnabled: true
|
||||
|
||||
onMoved: {
|
||||
valueChanged()
|
||||
}
|
||||
function valueChanged() {
|
||||
audio.volume = volume
|
||||
if(value==0) {
|
||||
audioOutput.volume = volumeSlider.volume
|
||||
if (value==0) {
|
||||
muteButton.muteAudio()
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
muteButton.unmuteAudio()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtMultimedia 5.12
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtMultimedia
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
import org.kde.ytmusic 1.0
|
||||
@@ -203,11 +203,11 @@ Item {
|
||||
implicitWidth: 60
|
||||
Layout.fillHeight: !isWidescreen
|
||||
|
||||
onClicked: audio.playbackState === Audio.PlayingState ? audio.pause() : audio.play()
|
||||
onClicked: audio.playbackState === MediaPlayer.PlayingState ? audio.pause() : audio.play()
|
||||
contentItem: Item {
|
||||
Kirigami.Icon {
|
||||
anchors.centerIn:parent
|
||||
source: audio.playbackState === Audio.PlayingState ? "media-playback-pause" : "media-playback-start"
|
||||
source: audio.playbackState === MediaPlayer.PlayingState ? "media-playback-pause" : "media-playback-start"
|
||||
color: "white"
|
||||
width: Kirigami.Units.gridUnit
|
||||
height: Kirigami.Units.gridUnit
|
||||
|
||||
@@ -20,7 +20,7 @@ Kirigami.NavigationTabBar {
|
||||
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
iconName: "file-library-symbolic"
|
||||
icon.name: "file-library-symbolic"
|
||||
text: i18n("Library")
|
||||
checked: pageStack.currentItem && pageStack.currentItem.objectName == "libraryPage"
|
||||
onTriggered: {
|
||||
@@ -32,7 +32,7 @@ Kirigami.NavigationTabBar {
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
iconName: "search"
|
||||
icon.name: "search"
|
||||
text: i18n("Search")
|
||||
checked: pageStack.currentItem && pageStack.currentItem.objectName == "searchPage"
|
||||
onTriggered: {
|
||||
@@ -44,7 +44,7 @@ Kirigami.NavigationTabBar {
|
||||
|
||||
},
|
||||
Kirigami.Action {
|
||||
iconName: "non-starred-symbolic"
|
||||
icon.name: "non-starred-symbolic"
|
||||
text: i18n("Favourites")
|
||||
checked: pageStack.currentItem && pageStack.currentItem.objectName == "favourites"
|
||||
onTriggered: {
|
||||
@@ -57,7 +57,7 @@ Kirigami.NavigationTabBar {
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
iconName: "edit-undo-history"
|
||||
icon.name: "edit-undo-history"
|
||||
text: i18n("Played Songs")
|
||||
checked: pageStack.currentItem && pageStack.currentItem.objectName == "history"
|
||||
onTriggered: {
|
||||
@@ -71,7 +71,7 @@ Kirigami.NavigationTabBar {
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
iconName: "amarok_playlist"
|
||||
icon.name: "amarok_playlist"
|
||||
text: i18n("Playlists")
|
||||
checked: pageStack.currentItem && pageStack.currentItem.objectName == "playlists"
|
||||
onTriggered: {
|
||||
|
||||
@@ -8,8 +8,8 @@ import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.12 as Controls
|
||||
|
||||
import QtMultimedia 5.12
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtMultimedia
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
import org.kde.ytmusic 1.0
|
||||
@@ -114,16 +114,21 @@ Flickable {
|
||||
videoId: UserPlaylistModel.currentVideoId
|
||||
}
|
||||
|
||||
property var audioPlayer: Audio {
|
||||
property var audioPlayer: MediaPlayer {
|
||||
id: audio
|
||||
|
||||
source: info.audioUrl
|
||||
onStatusChanged: {
|
||||
if (status === Audio.EndOfMedia) {
|
||||
onSourceChanged: play()
|
||||
onMediaStatusChanged: {
|
||||
if (mediaStatus === MediaPlayer.EndOfMedia) {
|
||||
console.log("Song ended");
|
||||
UserPlaylistModel.next();
|
||||
}
|
||||
}
|
||||
|
||||
audioOutput: AudioOutput {
|
||||
id: audioOutput
|
||||
}
|
||||
}
|
||||
|
||||
contentHeight: height * 2
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtGraphicalEffects 1.0
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
Item {
|
||||
property alias radius: mask.radius
|
||||
|
||||
@@ -7,7 +7,7 @@ import QtQuick 2.1
|
||||
import QtQuick.Controls 2.12 as Controls
|
||||
import QtQuick.Layouts 1.3
|
||||
import org.kde.kirigami 2.14 as Kirigami
|
||||
import QtGraphicalEffects 1.0
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import org.kde.ytmusic 1.0
|
||||
|
||||
Item {
|
||||
@@ -370,6 +370,8 @@ Item {
|
||||
}
|
||||
|
||||
delegate: Kirigami.AbstractListItem {
|
||||
required property string searchQuery
|
||||
|
||||
id: completionDelegate
|
||||
highlighted: focus || (completionList.selectedDelegate == index)
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
@@ -387,8 +389,8 @@ Item {
|
||||
implicitWidth: completionList.delegateHeight
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
}
|
||||
Controls.Label {
|
||||
text: model.display
|
||||
Controls.Label{
|
||||
text: searchQuery
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
@@ -405,7 +407,7 @@ Item {
|
||||
|
||||
}
|
||||
onClicked: {
|
||||
searchField.text = model.display
|
||||
searchField.text = searchQuery
|
||||
searchField.accepted()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as Controls
|
||||
import QtQuick.Controls as Controls
|
||||
import org.kde.ytmusic 1.0
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
import QtQuick.Layouts 1.15
|
||||
@@ -105,7 +105,7 @@ Item {
|
||||
Kirigami.BasicListItem{
|
||||
Layout.topMargin: 10
|
||||
label: i18n("Play Next")
|
||||
icon: "go-next"
|
||||
icon.name: "go-next"
|
||||
onClicked: {
|
||||
UserPlaylistModel.playNext(drawer.videoId, drawer.songTitle, drawer.artists)
|
||||
drawer.close()
|
||||
@@ -114,7 +114,7 @@ Item {
|
||||
Kirigami.BasicListItem{
|
||||
|
||||
label: i18n("Add to queue")
|
||||
icon: "media-playlist-append"
|
||||
icon.name: "media-playlist-append"
|
||||
onClicked: {
|
||||
UserPlaylistModel.append(drawer.videoId, drawer.songTitle, drawer.artists)
|
||||
drawer.close()
|
||||
@@ -124,7 +124,7 @@ Item {
|
||||
readonly property QtObject favouriteWatcher: Library.favouriteWatcher(drawer.videoId)
|
||||
|
||||
label: favouriteWatcher ? (favouriteWatcher.isFavourite ? i18n("Remove Favourite"): i18n("Add Favourite")): ""
|
||||
icon: favouriteWatcher ? (favouriteWatcher.isFavourite ? "starred-symbolic" : "non-starred-symbolic") : ""
|
||||
icon.name: favouriteWatcher ? (favouriteWatcher.isFavourite ? "starred-symbolic" : "non-starred-symbolic") : ""
|
||||
onClicked: {
|
||||
if (favouriteWatcher) {
|
||||
if (favouriteWatcher.isFavourite) {
|
||||
@@ -141,7 +141,7 @@ Item {
|
||||
readonly property QtObject wasPlayedWatcher: Library.wasPlayedWatcher(drawer.videoId)
|
||||
|
||||
label: i18n("Remove from History")
|
||||
icon: "list-remove"
|
||||
icon.name: "list-remove"
|
||||
onClicked: {
|
||||
Library.removePlaybackHistoryItem(drawer.videoId)
|
||||
drawer.close()
|
||||
|
||||
@@ -27,7 +27,7 @@ Kirigami.PromptDialog {
|
||||
customFooterActions: [
|
||||
Kirigami.Action {
|
||||
text: i18n("New Playlist")
|
||||
iconName: "list-add"
|
||||
icon.name: "list-add"
|
||||
onTriggered: {
|
||||
addPlaylistDialog.open()
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 2.12 as Controls
|
||||
import QtQuick.Layouts 1.3
|
||||
import org.kde.kirigami 2.14 as Kirigami
|
||||
import QtGraphicalEffects 1.0
|
||||
import org.kde.kirigami as Kirigami
|
||||
import QtMultimedia 5.12
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import org.kde.ytmusic 1.0
|
||||
|
||||
|
||||
@@ -282,6 +282,13 @@ SearchHistoryModel::SearchHistoryModel(QFuture<std::vector<SingleValue<QString>>
|
||||
});
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> SearchHistoryModel::roleNames() const
|
||||
{
|
||||
return {
|
||||
{ Qt::DisplayRole, "searchQuery" }
|
||||
};
|
||||
}
|
||||
|
||||
int SearchHistoryModel::rowCount(const QModelIndex &parent) const {
|
||||
if(parent.isValid()) {
|
||||
return 0;
|
||||
|
||||
@@ -99,6 +99,8 @@ class SearchHistoryModel : public QAbstractListModel {
|
||||
|
||||
public:
|
||||
SearchHistoryModel(QFuture<std::vector<SingleValue<QString>>> &&historyFuture, QObject *parent = nullptr);
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
void removeSearch(const QString &search);
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
@@ -40,7 +40,6 @@ constexpr auto URI = "org.kde.ytmusic";
|
||||
|
||||
Q_DECL_EXPORT int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// set default style and icon theme
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "playerutils.h"
|
||||
|
||||
#include <QAudio>
|
||||
|
||||
PlayerUtils::PlayerUtils(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
@@ -13,3 +15,8 @@ QString PlayerUtils::formatTimestamp(quint64 stamp)
|
||||
{
|
||||
return m_format.formatDuration(stamp, KFormat::FoldHours);
|
||||
}
|
||||
|
||||
float PlayerUtils::convertVolume(float volume)
|
||||
{
|
||||
return QAudio::convertVolume(volume, QAudio::LogarithmicVolumeScale, QAudio::LinearVolumeScale);
|
||||
}
|
||||
@@ -16,6 +16,7 @@ public:
|
||||
explicit PlayerUtils(QObject *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE QString formatTimestamp(quint64 stamp);
|
||||
Q_INVOKABLE float convertVolume(float volume);
|
||||
|
||||
private:
|
||||
KFormat m_format;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <dbusextendedabstractinterface.h>
|
||||
|
||||
#include <QtDBus/QDBusMetaType>
|
||||
#include <QtDBus/QDBusMessage>
|
||||
#include <QtDBus/QDBusPendingCall>
|
||||
#include <QtDBus/QDBusPendingCallWatcher>
|
||||
@@ -134,7 +133,7 @@ QVariant DBusExtendedAbstractInterface::internalPropGet(const char *propname, vo
|
||||
if (m_useCache) {
|
||||
int propertyIndex = metaObject()->indexOfProperty(propname);
|
||||
QMetaProperty metaProperty = metaObject()->property(propertyIndex);
|
||||
return QVariant(metaProperty.type(), propertyPtr);
|
||||
return QVariant(metaProperty.metaType(), propertyPtr);
|
||||
}
|
||||
|
||||
if (m_sync) {
|
||||
@@ -151,7 +150,7 @@ QVariant DBusExtendedAbstractInterface::internalPropGet(const char *propname, vo
|
||||
|
||||
if (-1 == propertyIndex) {
|
||||
QString errorMessage = QStringLiteral("Got unknown property \"%1\" to read")
|
||||
.arg(QString::fromLatin1(propname));
|
||||
.arg(QString::fromLatin1(propname));
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return QVariant();
|
||||
@@ -161,7 +160,7 @@ QVariant DBusExtendedAbstractInterface::internalPropGet(const char *propname, vo
|
||||
|
||||
if (!metaProperty.isReadable()) {
|
||||
QString errorMessage = QStringLiteral("Property \"%1\" is NOT readable")
|
||||
.arg(QString::fromLatin1(propname));
|
||||
.arg(QString::fromLatin1(propname));
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return QVariant();
|
||||
@@ -169,16 +168,16 @@ QVariant DBusExtendedAbstractInterface::internalPropGet(const char *propname, vo
|
||||
|
||||
// is this metatype registered?
|
||||
const char *expectedSignature = "";
|
||||
if (int(metaProperty.type()) != QMetaType::QVariant) {
|
||||
expectedSignature = QDBusMetaType::typeToSignature(metaProperty.userType());
|
||||
if (metaProperty.metaType() != QMetaType(QMetaType::QVariant)) {
|
||||
expectedSignature = QDBusMetaType::typeToSignature(metaProperty.metaType());
|
||||
if (0 == expectedSignature) {
|
||||
QString errorMessage =
|
||||
QStringLiteral("Type %1 must be registered with Qt D-Bus "
|
||||
"before it can be used to read property "
|
||||
"%2.%3")
|
||||
.arg(metaProperty.typeName(),
|
||||
interface(),
|
||||
propname);
|
||||
QStringLiteral("Type %1 must be registered with Qt D-Bus "
|
||||
"before it can be used to read property "
|
||||
"%2.%3")
|
||||
.arg(metaProperty.typeName(),
|
||||
interface(),
|
||||
propname);
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return QVariant();
|
||||
@@ -186,7 +185,7 @@ QVariant DBusExtendedAbstractInterface::internalPropGet(const char *propname, vo
|
||||
}
|
||||
|
||||
asyncProperty(propname);
|
||||
return QVariant(metaProperty.type(), propertyPtr);
|
||||
return QVariant(metaProperty.metaType(), propertyPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +207,7 @@ void DBusExtendedAbstractInterface::internalPropSet(const char *propname, const
|
||||
|
||||
if (-1 == propertyIndex) {
|
||||
QString errorMessage = QStringLiteral("Got unknown property \"%1\" to write")
|
||||
.arg(QString::fromLatin1(propname));
|
||||
.arg(QString::fromLatin1(propname));
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return;
|
||||
@@ -218,13 +217,13 @@ void DBusExtendedAbstractInterface::internalPropSet(const char *propname, const
|
||||
|
||||
if (!metaProperty.isWritable()) {
|
||||
QString errorMessage = QStringLiteral("Property \"%1\" is NOT writable")
|
||||
.arg(QString::fromLatin1(propname));
|
||||
.arg(QString::fromLatin1(propname));
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return;
|
||||
}
|
||||
|
||||
asyncSetProperty(propname, QVariant(metaProperty.type(), propertyPtr));
|
||||
asyncSetProperty(propname, QVariant(metaProperty.metaType(), propertyPtr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +249,70 @@ void DBusExtendedAbstractInterface::asyncSetProperty(const QString &propertyName
|
||||
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(onAsyncSetPropertyFinished(QDBusPendingCallWatcher*)));
|
||||
}
|
||||
|
||||
QVariant DBusExtendedAbstractInterface::demarshall(const QString &interface, const QMetaProperty &metaProperty, const QVariant &value, QDBusError *error)
|
||||
{
|
||||
Q_ASSERT(metaProperty.isValid());
|
||||
Q_ASSERT(error != 0);
|
||||
|
||||
if (value.userType() == metaProperty.userType()) {
|
||||
// No need demarshalling. Passing back straight away ...
|
||||
*error = QDBusError();
|
||||
return value;
|
||||
}
|
||||
|
||||
QVariant result = QVariant(metaProperty.metaType(), (void *)nullptr);
|
||||
QString errorMessage;
|
||||
const char *expectedSignature = QDBusMetaType::typeToSignature(metaProperty.metaType());
|
||||
|
||||
if (value.userType() == qMetaTypeId<QDBusArgument>()) {
|
||||
// demarshalling a DBus argument ...
|
||||
QDBusArgument dbusArg = value.value<QDBusArgument>();
|
||||
|
||||
if (expectedSignature == dbusArg.currentSignature().toLatin1()) {
|
||||
QDBusMetaType::demarshall(dbusArg, metaProperty.metaType(), result.data());
|
||||
if (!result.isValid()) {
|
||||
errorMessage = QStringLiteral("Unexpected failure demarshalling "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
expectedSignature);
|
||||
}
|
||||
} else {
|
||||
errorMessage = QStringLiteral("Unexpected `user type' (%2) "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(dbusArg.currentSignature(),
|
||||
interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
QString::fromLatin1(expectedSignature));
|
||||
}
|
||||
} else {
|
||||
const char *actualSignature = QDBusMetaType::typeToSignature(value.metaType());
|
||||
|
||||
errorMessage = QStringLiteral("Unexpected `%1' (%2) "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(QString::fromLatin1(value.typeName()),
|
||||
QString::fromLatin1(actualSignature),
|
||||
interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
QString::fromLatin1(expectedSignature));
|
||||
}
|
||||
|
||||
if (errorMessage.isEmpty()) {
|
||||
*error = QDBusError();
|
||||
} else {
|
||||
*error = QDBusMessage::createError(QDBusError::InvalidSignature, errorMessage);
|
||||
qDebug() << Q_FUNC_INFO << errorMessage;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::onAsyncPropertyFinished(DBusExtendedPendingCallWatcher *watcher)
|
||||
{
|
||||
QDBusPendingReply<QVariant> reply = *watcher;
|
||||
@@ -355,66 +418,4 @@ void DBusExtendedAbstractInterface::onPropertiesChanged(const QString& interface
|
||||
}
|
||||
}
|
||||
|
||||
QVariant DBusExtendedAbstractInterface::demarshall(const QString &interface, const QMetaProperty &metaProperty, const QVariant &value, QDBusError *error)
|
||||
{
|
||||
Q_ASSERT(metaProperty.isValid());
|
||||
Q_ASSERT(error != 0);
|
||||
|
||||
if (value.userType() == metaProperty.userType()) {
|
||||
// No need demarshalling. Passing back straight away ...
|
||||
*error = QDBusError();
|
||||
return value;
|
||||
}
|
||||
|
||||
QVariant result = QVariant(metaProperty.userType(), (void*)0);
|
||||
QString errorMessage;
|
||||
const char *expectedSignature = QDBusMetaType::typeToSignature(metaProperty.userType());
|
||||
|
||||
if (value.userType() == qMetaTypeId<QDBusArgument>()) {
|
||||
// demarshalling a DBus argument ...
|
||||
QDBusArgument dbusArg = value.value<QDBusArgument>();
|
||||
|
||||
if (expectedSignature == dbusArg.currentSignature().toLatin1()) {
|
||||
QDBusMetaType::demarshall(dbusArg, metaProperty.userType(), result.data());
|
||||
if (!result.isValid()) {
|
||||
errorMessage = QStringLiteral("Unexpected failure demarshalling "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
expectedSignature);
|
||||
}
|
||||
} else {
|
||||
errorMessage = QStringLiteral("Unexpected `user type' (%2) "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(dbusArg.currentSignature(),
|
||||
interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
QString::fromLatin1(expectedSignature));
|
||||
}
|
||||
} else {
|
||||
const char *actualSignature = QDBusMetaType::typeToSignature(value.userType());
|
||||
|
||||
errorMessage = QStringLiteral("Unexpected `%1' (%2) "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(QString::fromLatin1(value.typeName()),
|
||||
QString::fromLatin1(actualSignature),
|
||||
interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
QString::fromLatin1(expectedSignature));
|
||||
}
|
||||
|
||||
if (errorMessage.isEmpty()) {
|
||||
*error = QDBusError();
|
||||
} else {
|
||||
*error = QDBusMessage::createError(QDBusError::InvalidSignature, errorMessage);
|
||||
qDebug() << Q_FUNC_INFO << errorMessage;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -7,8 +7,11 @@
|
||||
#ifndef DBUSEXTENDEDABSTRACTINTERFACE_H
|
||||
#define DBUSEXTENDEDABSTRACTINTERFACE_H
|
||||
|
||||
#include "qmetaobject.h"
|
||||
#include <dbusextended.h>
|
||||
|
||||
#include <QtDBus/QDBusMetaType>
|
||||
|
||||
#include <QDBusAbstractInterface>
|
||||
#include <QDBusError>
|
||||
|
||||
@@ -43,6 +46,7 @@ protected:
|
||||
void connectNotify(const QMetaMethod &signal) override;
|
||||
void disconnectNotify(const QMetaMethod &signal) override;
|
||||
QVariant internalPropGet(const char *propname, void *propertyPtr);
|
||||
|
||||
void internalPropSet(const char *propname, const QVariant &value, void *propertyPtr);
|
||||
|
||||
Q_SIGNALS:
|
||||
@@ -63,6 +67,7 @@ private Q_SLOTS:
|
||||
private:
|
||||
QVariant asyncProperty(const QString &propertyName);
|
||||
void asyncSetProperty(const QString &propertyName, const QVariant &value);
|
||||
|
||||
static QVariant demarshall(const QString &interface, const QMetaProperty &metaProperty, const QVariant &value, QDBusError *error);
|
||||
|
||||
bool m_sync;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "mprismanager.h"
|
||||
|
||||
#include "mpriscontroller.h"
|
||||
#include "qregularexpression.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
@@ -49,9 +50,8 @@ MprisManager::MprisManager(QObject *parent)
|
||||
QStringList serviceNames = connection.interface()->registeredServiceNames();
|
||||
QStringList::const_iterator i = serviceNames.constBegin();
|
||||
while (i != serviceNames.constEnd()) {
|
||||
QRegExp rx(mprisNameSpace);
|
||||
rx.setPatternSyntax(QRegExp::Wildcard);
|
||||
if (rx.exactMatch(*i)) {
|
||||
auto rx = QRegularExpression::fromWildcard(mprisNameSpace);
|
||||
if (rx.match(*i).hasMatch()) {
|
||||
onServiceAppeared(*i);
|
||||
}
|
||||
|
||||
@@ -154,9 +154,8 @@ void MprisManager::setCurrentService(const QString &service)
|
||||
return;
|
||||
}
|
||||
|
||||
QRegExp rx(mprisNameSpace);
|
||||
rx.setPatternSyntax(QRegExp::Wildcard);
|
||||
if (!rx.exactMatch(service)) {
|
||||
auto rx = QRegularExpression::fromWildcard(mprisNameSpace);
|
||||
if (!rx.match(service).hasMatch()) {
|
||||
qWarning() << "Mpris:" << service << "is not a proper Mpris2 service";
|
||||
return;
|
||||
}
|
||||
@@ -361,9 +360,8 @@ void MprisManager::onNameOwnerChanged(const QString &service, const QString &old
|
||||
// bus, not just the ones for our name space of interest, and we
|
||||
// will have to filter on our own :(
|
||||
|
||||
QRegExp rx(mprisNameSpace);
|
||||
rx.setPatternSyntax(QRegExp::Wildcard);
|
||||
if (!rx.exactMatch(service)) {
|
||||
auto rx = QRegularExpression::fromWildcard(mprisNameSpace);
|
||||
if (!rx.match(service).hasMatch()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ class QByteArray;
|
||||
template<class T> class QList;
|
||||
template<class Key, class Value> class QMap;
|
||||
class QString;
|
||||
class QStringList;
|
||||
class QVariant;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
@@ -23,10 +23,8 @@ MprisPlayerInterface::MprisPlayerInterface(const QString &service, const QString
|
||||
, m_canPause(false)
|
||||
, m_canPlay(false)
|
||||
, m_canSeek(false)
|
||||
, m_loopStatus(Mpris::None)
|
||||
, m_maximumRate(1)
|
||||
, m_minimumRate(1)
|
||||
, m_playbackStatus(Mpris::Stopped)
|
||||
, m_position(0)
|
||||
, m_rate(1)
|
||||
, m_shuffle(false)
|
||||
|
||||
@@ -14,12 +14,7 @@ VideoInfoExtractor::VideoInfoExtractor(QObject *parent)
|
||||
connect(this, &VideoInfoExtractor::videoIdChanged, this, [this] {
|
||||
if (m_videoId.isEmpty()) {
|
||||
m_videoInfo = {};
|
||||
Q_EMIT audioUrlChanged();
|
||||
Q_EMIT titleChanged();
|
||||
Q_EMIT artistChanged();
|
||||
Q_EMIT channelChanged();
|
||||
Q_EMIT songChanged();
|
||||
Q_EMIT thumbnailChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -29,12 +24,7 @@ VideoInfoExtractor::VideoInfoExtractor(QObject *parent)
|
||||
connectFuture(future, this, [this](const video_info::VideoInfo &videoInfo) {
|
||||
m_videoInfo = videoInfo;
|
||||
setLoading(false);
|
||||
Q_EMIT audioUrlChanged();
|
||||
Q_EMIT titleChanged();
|
||||
Q_EMIT artistChanged();
|
||||
Q_EMIT channelChanged();
|
||||
Q_EMIT songChanged();
|
||||
Q_EMIT thumbnailChanged();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,34 +15,29 @@ class VideoInfoExtractor : public QObject
|
||||
|
||||
Q_PROPERTY(QString videoId READ videoId WRITE setVideoId NOTIFY videoIdChanged)
|
||||
|
||||
Q_PROPERTY(QUrl audioUrl READ audioUrl NOTIFY audioUrlChanged)
|
||||
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
|
||||
Q_PROPERTY(QString artist READ artist NOTIFY artistChanged) // may be empty if it is a video
|
||||
Q_PROPERTY(QString channel READ channel NOTIFY channelChanged)
|
||||
Q_PROPERTY(QString thumbnail READ thumbnail NOTIFY thumbnailChanged)
|
||||
Q_PROPERTY(bool loading READ loading WRITE setLoading NOTIFY loadingChanged)
|
||||
Q_PROPERTY(QUrl audioUrl READ audioUrl NOTIFY songChanged)
|
||||
Q_PROPERTY(QString title READ title NOTIFY songChanged)
|
||||
Q_PROPERTY(QString artist READ artist NOTIFY songChanged) // may be empty if it is a video
|
||||
Q_PROPERTY(QString channel READ channel NOTIFY songChanged)
|
||||
Q_PROPERTY(QString thumbnail READ thumbnail NOTIFY songChanged)
|
||||
Q_PROPERTY(bool loading READ loading WRITE setLoading NOTIFY songChanged)
|
||||
|
||||
public:
|
||||
explicit VideoInfoExtractor(QObject *parent = nullptr);
|
||||
|
||||
QUrl audioUrl() const;
|
||||
Q_SIGNAL void audioUrlChanged();
|
||||
|
||||
QString videoId() const;
|
||||
void setVideoId(const QString &videoId);
|
||||
Q_SIGNAL void videoIdChanged();
|
||||
|
||||
QString title() const;
|
||||
Q_SIGNAL void titleChanged();
|
||||
|
||||
|
||||
QString artist() const;
|
||||
Q_SIGNAL void artistChanged();
|
||||
|
||||
|
||||
QString channel() const;
|
||||
Q_SIGNAL void channelChanged();
|
||||
|
||||
QString thumbnail() const;
|
||||
Q_SIGNAL void thumbnailChanged();
|
||||
|
||||
bool loading() const;
|
||||
void setLoading(bool loading);
|
||||
|
||||
Reference in new issue
Block a user