/** Copyright 2013 by Sebastian KΓΌgler <sebas@kde.org>* Copyright 2014 by Martin GrΓ€Γlin <mgraesslin@kde.org>* Copyright 2016 by Kai Uwe Broulik <kde@privat.broulik.de>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU Library General Public License as* published by the Free Software Foundation; either version 2, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU Library General Public License for more details** You should have received a copy of the GNU Library General Public* License along with this program; if not, write to the* Free Software Foundation, Inc.,* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.*/import QtQuick 2.0import QtQuick.Layouts 1.1import QtGraphicalEffects 1.0import org.kde.plasma.core 2.0 as PlasmaCoreimport org.kde.plasma.components 2.0 as PlasmaComponentsimport org.kde.plasma.extras 2.0 as PlasmaExtrasimport org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddonsColumn {id: tooltipContentItemproperty Item toolTipproperty var parentIndexproperty var windowsproperty string mainTextproperty string subTextproperty variant iconproperty url launcherUrlproperty bool group: (windows.length > 1)readonly property int thumbnailWidth: units.gridUnit * 15readonly property int thumbnailHeight: units.gridUnit * 10property int preferredTextWidth: theme.mSize(theme.defaultFont).width * 30property int _s: units.largeSpacing / 2Layout.minimumWidth: Math.max(thumbnailWidth, windowRow.width, appLabelRow.width) + _sLayout.minimumHeight: childrenRect.heightLayout.maximumWidth: Layout.minimumWidthLayout.maximumHeight: Layout.minimumHeightspacing: _sstates: State {when: mpris2Source.hasPlayerPropertyChanges {target: thumbnailSourceItemopacity: 0 // cannot set visible to false or else WindowThumbnail won't provide thumbnail}PropertyChanges {target: playerControlsOpacityMaskvisible: truesource: thumbnailSourceItemmaskSource: playerControlsShadowMask}PropertyChanges {target: playerControlsRowvisible: mpris2Source.hasPlayer}}PlasmaCore.DataSource {id: mpris2Sourcereadonly property string current: {var desktopFileName = launcherUrl.toString().split('/').pop().replace(".desktop", "")for (var i = 0, length = sources.length; i < length; ++i) {var source = sources[i];if (data[sources[i]].DesktopEntry === desktopFileName) {return source}}return ""}readonly property bool hasPlayer: !!currentreadonly property bool playing: hasPlayer && data[current].PlaybackStatus === "Playing"readonly property bool canControl: hasPlayer && data[current].CanControlreadonly property bool canGoBack: hasPlayer && data[current].CanGoPreviousreadonly property bool canGoNext: hasPlayer && data[current].CanGoNextreadonly property bool canRaise: hasPlayer && data[current].CanRaisereadonly property var currentMetadata: hasPlayer ? data[current].Metadata : ({})readonly property string track: {var xesamTitle = currentMetadata["xesam:title"]if (xesamTitle) {return xesamTitle}// if no track title is given, print out the file namevar xesamUrl = currentMetadata["xesam:url"] ? currentMetadata["xesam:url"].toString() : ""if (!xesamUrl) {return ""}var lastSlashPos = xesamUrl.lastIndexOf('/')if (lastSlashPos < 0) {return ""}var lastUrlPart = xesamUrl.substring(lastSlashPos + 1)return decodeURIComponent(lastUrlPart)}readonly property string artist: currentMetadata["xesam:artist"] || ""readonly property string albumArt: currentMetadata["mpris:artUrl"] || ""function goPrevious() {startOperation("Previous")}function goNext() {startOperation("Next")}function playPause() {startOperation("PlayPause")}function raise() {startOperation("Raise")}function startOperation(op) {var service = mpris2Source.serviceForSource(current)var operation = service.operationDescription(op)return service.startOperationCall(operation)}engine: "mpris2"connectedSources: sources}Item {id: thumbnailContainerwidth: Math.max(parent.width, windowRow.width)height: albumArtImage.available ? albumArtImage.height :raisePlayerArea.visible ? raisePlayerArea.height :windowRow.heightItem {id: thumbnailSourceItemanchors.fill: parentPlasmaExtras.ScrollArea {id: scrollAreaanchors.horizontalCenter: parent.horizontalCenterwidth: Math.max(windowRow.width, thumbnailWidth)height: parent.heightvisible: !albumArtImage.availableverticalScrollBarPolicy: Qt.ScrollBarAlwaysOffhorizontalScrollBarPolicy: Qt.ScrollBarAlwaysOffComponent.onCompleted: {flickableItem.interactive = Qt.binding(function() {return contentItem.width > viewport.width;});}Row {id: windowRowwidth: childrenRect.widthheight: childrenRect.heightspacing: units.largeSpacingRepeater {model: plasmoid.configuration.showToolTips && !albumArtImage.available ? windows : nullPlasmaCore.WindowThumbnail {id: windowThumbnailwidth: thumbnailWidthheight: thumbnailHeightwinId: modelDataToolTipWindowMouseArea {anchors.fill: parentmodelIndex: tasksModel.makeModelIndex(parentIndex, group ? index : -1)winId: modelDatathumbnailItem: parent}}}}}Image {id: albumArtImage// also Image.Loading to prevent loading thumbnails just because the album art takes a split second to loadreadonly property bool available: status === Image.Ready || status === Image.Loadinganchors.centerIn: parentwidth: parent.widthheight: thumbnailHeightsourceSize: Qt.size(thumbnailWidth, thumbnailHeight)asynchronous: truesource: mpris2Source.albumArtfillMode: Image.PreserveAspectCropvisible: availableToolTipWindowMouseArea {anchors.fill: parentmodelIndex: tasksModel.makeModelIndex(parentIndex, group ? index : -1)winId: windows != undefined ? (windows[0] || 0) : 0}}MouseArea {id: raisePlayerAreaanchors.centerIn: parentwidth: thumbnailWidthheight: thumbnailHeight// if there's no window associated with this task, we might still be able to raise the playervisible: windows == undefined || !windows[0] && mpris2Source.canRaiseonClicked: mpris2Source.raise()PlasmaCore.IconItem {anchors.fill: parentsource: iconanimated: falseusesPlasmaTheme: falsevisible: !albumArtImage.available}}}Item {id: playerControlsShadowMaskanchors.fill: thumbnailSourceItemvisible: false // OpacityMask would render itRectangle {width: parent.widthheight: parent.height - playerControlsRow.height}Rectangle {anchors.bottom: parent.bottomwidth: parent.widthheight: playerControlsRow.heightopacity: 0.2}}OpacityMask {id: playerControlsOpacityMaskanchors.fill: thumbnailSourceItemvisible: false}// prevent accidental click-through when a control is disabledMouseArea {anchors.fill: playerControlsRowenabled: playerControlsRow.visible}RowLayout {id: playerControlsRowanchors {horizontalCenter: parent.horizontalCenterbottom: thumbnailSourceItem.bottom}width: thumbnailWidthspacing: 0enabled: mpris2Source.canControlvisible: falseColumnLayout {Layout.fillWidth: truespacing: 0PlasmaExtras.Heading {Layout.fillWidth: truelevel: 4wrapMode: Text.NoWrapelide: Text.ElideRighttext: mpris2Source.track || ""}PlasmaExtras.Heading {Layout.fillWidth: truelevel: 5wrapMode: Text.NoWrapelide: Text.ElideRighttext: mpris2Source.artist || ""}}PlasmaComponents.ToolButton {enabled: mpris2Source.canGoBackiconName: "media-skip-backward"tooltip: i18nc("Go to previous song", "Previous")Accessible.name: tooltiponClicked: mpris2Source.goPrevious()}PlasmaComponents.ToolButton {Layout.fillHeight: trueLayout.preferredWidth: height // make this button biggericonName: mpris2Source.playing ? "media-playback-pause" : "media-playback-start"tooltip: mpris2Source.playing ? i18nc("Pause player", "Pause") : i18nc("Start player", "Play")Accessible.name: tooltiponClicked: mpris2Source.playPause()}PlasmaComponents.ToolButton {enabled: mpris2Source.canGoNexticonName: "media-skip-forward"tooltip: i18nc("Go to next song", "Next")Accessible.name: tooltiponClicked: mpris2Source.goNext()}}}Row {id: appLabelRowwidth: childrenRect.width + _sheight: childrenRect.height + units.largeSpacingspacing: units.largeSpacingItem {id: imageContainerwidth: tooltipIcon.widthheight: tooltipIcon.heighty: _sPlasmaCore.IconItem {id: tooltipIconx: _swidth: units.iconSizes.desktopheight: widthanimated: falseusesPlasmaTheme: falsesource: icon}}Column {id: mainColumny: _s//This instance is purely for metricsPlasmaExtras.Heading {id: tooltipMaintextPlaceholdervisible: falselevel: 3text: mainTexttextFormat: Text.PlainText}PlasmaExtras.Heading {id: tooltipMaintextlevel: 3width: Math.min(tooltipMaintextPlaceholder.width, preferredTextWidth)//width: 400elide: Text.ElideRighttext: mainTexttextFormat: Text.PlainText}PlasmaComponents.Label {id: tooltipSubtextwidth: tooltipContentItem.preferredTextWidthheight: Math.min(theme.mSize(theme.defaultFont), contentHeight)wrapMode: Text.WordWraptext: subTexttextFormat: Text.PlainTextopacity: 0.5visible: text !== ""}}}}