1/*
2    SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <kde@privat.broulik.de>
3
4    SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7import QtQuick 2.5
8import QtQuick.Layouts 1.1
9
10import org.kde.plasma.core 2.0 as PlasmaCore
11import org.kde.plasma.components 3.0 as PlasmaComponents3
12import org.kde.plasma.extras 2.0 as PlasmaExtras
13
14Item {
15    visible: mpris2Source.hasPlayer
16    implicitHeight: PlasmaCore.Units.gridUnit * 3
17    implicitWidth: PlasmaCore.Units.gridUnit * 16
18
19    RowLayout {
20        id: controlsRow
21        anchors.fill: parent
22        spacing: 0
23
24        enabled: mpris2Source.canControl
25
26        PlasmaCore.DataSource {
27            id: mpris2Source
28
29            readonly property string source: "@multiplex"
30            readonly property var playerData: data[source]
31
32            readonly property bool hasPlayer: sources.length > 1 && !!playerData
33            readonly property string identity: hasPlayer ? playerData.Identity : ""
34            readonly property bool playing: hasPlayer && playerData.PlaybackStatus === "Playing"
35            readonly property bool canControl: hasPlayer && playerData.CanControl
36            readonly property bool canGoBack: hasPlayer && playerData.CanGoPrevious
37            readonly property bool canGoNext: hasPlayer && playerData.CanGoNext
38
39            readonly property var currentMetadata: hasPlayer ? playerData.Metadata : ({})
40
41            readonly property string track: {
42                var xesamTitle = currentMetadata["xesam:title"]
43                if (xesamTitle) {
44                    return xesamTitle
45                }
46                // if no track title is given, print out the file name
47                var xesamUrl = currentMetadata["xesam:url"] ? currentMetadata["xesam:url"].toString() : ""
48                if (!xesamUrl) {
49                    return ""
50                }
51                var lastSlashPos = xesamUrl.lastIndexOf('/')
52                if (lastSlashPos < 0) {
53                    return ""
54                }
55                var lastUrlPart = xesamUrl.substring(lastSlashPos + 1)
56                return decodeURIComponent(lastUrlPart)
57            }
58            readonly property string artist: currentMetadata["xesam:artist"] || ""
59            readonly property string albumArt: currentMetadata["mpris:artUrl"] || ""
60
61            engine: "mpris2"
62            connectedSources: [source]
63
64            function startOperation(op) {
65                var service = serviceForSource(source)
66                var operation = service.operationDescription(op)
67                return service.startOperationCall(operation)
68            }
69
70            function goPrevious() {
71                startOperation("Previous");
72            }
73            function goNext() {
74                startOperation("Next");
75            }
76            function playPause(source) {
77                startOperation("PlayPause");
78            }
79        }
80
81        Image {
82            id: albumArt
83            Layout.preferredWidth: height
84            Layout.fillHeight: true
85            asynchronous: true
86            fillMode: Image.PreserveAspectFit
87            source: mpris2Source.albumArt
88            sourceSize.height: height
89            visible: status === Image.Loading || status === Image.Ready
90        }
91
92        Item { // spacer
93            width: PlasmaCore.Units.smallSpacing
94            height: 1
95        }
96
97        ColumnLayout {
98            Layout.fillWidth: true
99            spacing: 0
100
101            PlasmaComponents3.Label {
102                Layout.fillWidth: true
103                wrapMode: Text.NoWrap
104                elide: Text.ElideRight
105                text: mpris2Source.track || i18nd("plasma_lookandfeel_org.kde.lookandfeel", "No media playing")
106                textFormat: Text.PlainText
107                font.pointSize: PlasmaCore.Theme.defaultFont.pointSize + 1
108                maximumLineCount: 1
109            }
110
111            PlasmaExtras.DescriptiveLabel {
112                Layout.fillWidth: true
113                wrapMode: Text.NoWrap
114                elide: Text.ElideRight
115                // if no artist is given, show player name instead
116                text: mpris2Source.artist || mpris2Source.identity || ""
117                textFormat: Text.PlainText
118                font.pointSize: PlasmaCore.Theme.smallestFont.pointSize + 1
119                maximumLineCount: 1
120            }
121        }
122
123        PlasmaComponents3.ToolButton {
124            focusPolicy: Qt.TabFocus
125            enabled: mpris2Source.canGoBack
126            Layout.preferredHeight: PlasmaCore.Units.gridUnit*2
127            Layout.preferredWidth: Layout.preferredHeight
128            icon.name: LayoutMirroring.enabled ? "media-skip-forward" : "media-skip-backward"
129            onClicked: {
130                fadeoutTimer.running = false
131                mpris2Source.goPrevious()
132            }
133            visible: mpris2Source.canGoBack || mpris2Source.canGoNext
134            Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Previous track")
135        }
136
137        PlasmaComponents3.ToolButton {
138            focusPolicy: Qt.TabFocus
139            Layout.fillHeight: true
140            Layout.preferredWidth: height // make this button bigger
141            icon.name: mpris2Source.playing ? "media-playback-pause" : "media-playback-start"
142            onClicked: {
143                fadeoutTimer.running = false
144                mpris2Source.playPause()
145            }
146            Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Play or Pause media")
147        }
148
149        PlasmaComponents3.ToolButton {
150            focusPolicy: Qt.TabFocus
151            enabled: mpris2Source.canGoNext
152            Layout.preferredHeight: PlasmaCore.Units.gridUnit*2
153            Layout.preferredWidth: Layout.preferredHeight
154            icon.name: LayoutMirroring.enabled ? "media-skip-backward" : "media-skip-forward"
155            onClicked: {
156                fadeoutTimer.running = false
157                mpris2Source.goNext()
158            }
159            visible: mpris2Source.canGoBack || mpris2Source.canGoNext
160            Accessible.name: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Next track")
161        }
162    }
163}
164