diff --git a/src/qml/EditableMetaDataDelegate.qml b/src/qml/EditableMetaDataDelegate.qml index 5b27b0b9..77b1bf03 100644 --- a/src/qml/EditableMetaDataDelegate.qml +++ b/src/qml/EditableMetaDataDelegate.qml @@ -1,73 +1,77 @@ /* * Copyright 2016 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.10 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.2 import org.kde.kirigami 2.5 as Kirigami import org.kde.elisa 1.0 RowLayout { id: delegateRow spacing: 0 Label { id: metaDataLabels text: { if (model.name !== undefined) { return i18nc("Label for a piece of metadata, e.g. 'Album Artist:'", "%1:", model.name) } return "" } font.weight: Font.Bold horizontalAlignment: Text.AlignRight Layout.alignment: Qt.AlignCenter Layout.preferredWidth: 0.8 * elisaTheme.coverImageSize Layout.rightMargin: !LayoutMirroring.enabled ? Kirigami.Units.smallSpacing : 0 Layout.leftMargin: LayoutMirroring.enabled ? Kirigami.Units.smallSpacing : 0 } Loader { id: textDisplayLoader + focus: model.index === 0 + active: model.type === EditableTrackMetadataModel.TextEntry || model.type === EditableTrackMetadataModel.UrlEntry || model.type === EditableTrackMetadataModel.IntegerEntry visible: model.type === EditableTrackMetadataModel.TextEntry || model.type === EditableTrackMetadataModel.UrlEntry || model.type === EditableTrackMetadataModel.IntegerEntry Layout.fillWidth: true Layout.alignment: Qt.AlignTop sourceComponent: TextField { text: model.display + focus: model.index === 0 + horizontalAlignment: Text.AlignLeft selectByMouse: true anchors.fill: parent onTextEdited: { if (model.display !== text) { model.display = text } } } } } diff --git a/src/qml/ElisaConfigurationDialog.qml b/src/qml/ElisaConfigurationDialog.qml index 682d8cf1..7cc63704 100644 --- a/src/qml/ElisaConfigurationDialog.qml +++ b/src/qml/ElisaConfigurationDialog.qml @@ -1,129 +1,132 @@ /* * Copyright 2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.11 import QtQuick.Controls 2.4 import QtQuick.Layouts 1.12 import QtQuick.Window 2.12 import QtQml.Models 2.3 import org.kde.kirigami 2.5 as Kirigami Window { id: dialog title: i18n("Configure") visible: true modality: Qt.ApplicationModal minimumWidth: 750 minimumHeight: 500 Shortcut { sequence: StandardKey.Cancel onActivated: close() } SystemPalette { id: myPalette colorGroup: SystemPalette.Active } Component { id: highlightBar Rectangle { width: 200; height: 50 color: myPalette.highlight } } Rectangle { anchors.fill: parent color: myPalette.window ColumnLayout { spacing: 0 anchors.fill: parent Kirigami.Heading { text: i18n("General") Layout.leftMargin: 5 Layout.rightMargin: 5 } GeneralConfiguration { Layout.fillWidth: true Layout.topMargin: 10 Layout.leftMargin: 20 Layout.rightMargin: 10 } Kirigami.Heading { text: i18n("Music Search Configuration") Layout.topMargin: 15 Layout.leftMargin: 5 Layout.rightMargin: 5 } FileScanningConfiguration { Layout.fillWidth: true Layout.fillHeight: true Layout.topMargin: 10 Layout.leftMargin: 20 Layout.rightMargin: 10 } DialogButtonBox { Layout.fillWidth: true Button { text: i18n("OK") + icon.name: 'dialog-ok-apply' DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole } Button { text: i18n("Apply") + icon.name: 'dialog-ok-apply' DialogButtonBox.buttonRole: DialogButtonBox.ApplyRole enabled: config.isDirty } Button { text: i18n("Cancel") + icon.name: 'dialog-cancel' DialogButtonBox.buttonRole: DialogButtonBox.RejectRole } onAccepted: { config.save() close() } onApplied: config.save() onRejected: close() } } } } diff --git a/src/qml/MediaTrackMetadataView.qml b/src/qml/MediaTrackMetadataView.qml index 24ad1940..283c38fa 100644 --- a/src/qml/MediaTrackMetadataView.qml +++ b/src/qml/MediaTrackMetadataView.qml @@ -1,257 +1,260 @@ /* * Copyright 2017 Alexander Stippich * Copyright 2018 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Window 2.2 import QtQml.Models 2.2 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 import org.kde.kirigami 2.5 as Kirigami import org.kde.elisa 1.0 Window { id: trackMetadata property var modelType property url fileName property bool editableMetadata property bool isCreation: false property alias showImage: metadataImage.visible property alias showTrackFileName: fileNameRow.visible property alias showDeleteButton: deleteButtonBox.visible property alias showApplyButton: applyButton.visible property double widthIndex: 2.8 signal rejected() LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft LayoutMirroring.childrenInherit: true title: isCreation ? i18nc("Window title for track metadata", "Create a Radio") : i18nc("Window title for track metadata", "View Details") EditableTrackMetadataModel { id: realModel manager: elisa.musicManager } modality: Qt.NonModal flags: Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint color: myPalette.window minimumHeight: elisaTheme.coverImageSize * 1.8 minimumWidth: elisaTheme.coverImageSize * trackMetadata.widthIndex ColumnLayout { anchors.fill: parent anchors.margins: Kirigami.Units.smallSpacing spacing: Kirigami.Units.smallSpacing RowLayout { id: metadataView Layout.fillHeight: true Layout.fillWidth: true spacing: 0 ImageWithFallback { id: metadataImage source: realModel.coverUrl fallback: elisaTheme.defaultAlbumImage sourceSize.width: elisaTheme.coverImageSize sourceSize.height: elisaTheme.coverImageSize fillMode: Image.PreserveAspectFit Layout.alignment: Qt.AlignTop | Qt.AlignHCenter Layout.preferredHeight: elisaTheme.coverImageSize Layout.preferredWidth: elisaTheme.coverImageSize Layout.minimumHeight: elisaTheme.coverImageSize Layout.minimumWidth: elisaTheme.coverImageSize Layout.maximumHeight: elisaTheme.coverImageSize Layout.maximumWidth: elisaTheme.coverImageSize } ListView { id: trackData Layout.fillWidth: true Layout.fillHeight: true Layout.leftMargin: 2 * Kirigami.Units.largeSpacing focus: true ScrollBar.vertical: ScrollBar { id: scrollBar } boundsBehavior: Flickable.StopAtBounds clip: true ScrollHelper { id: scrollHelper flickable: trackData anchors.fill: trackData } model: realModel Component { id: metaDataDelegate MetaDataDelegate { width: scrollBar.visible ? (!LayoutMirroring.enabled ? trackData.width - scrollBar.width : trackData.width) : trackData.width } } Component { id: editableMetaDataDelegate EditableMetaDataDelegate { width: scrollBar.visible ? (!LayoutMirroring.enabled ? trackData.width - scrollBar.width : trackData.width) : trackData.width } } delegate: editableMetadata ? editableMetaDataDelegate: metaDataDelegate } } RowLayout { id: fileNameRow Layout.alignment: Qt.AlignLeft | Qt.AlignBottom Layout.topMargin: Kirigami.Units.smallSpacing Layout.bottomMargin: Kirigami.Units.smallSpacing spacing: Kirigami.Units.largeSpacing Image { Layout.preferredWidth: fileNameLabel.height Layout.preferredHeight: fileNameLabel.height sourceSize.width: fileNameLabel.height sourceSize.height: fileNameLabel.height source: elisaTheme.folderIcon } LabelWithToolTip { id: fileNameLabel Layout.fillWidth: true text: realModel.fileUrl elide: Text.ElideRight } } Kirigami.InlineMessage { id: formInvalidNotification text: i18nc("Form validation error message for track data", "Data are not valid. %1", realModel.errorMessage) type: Kirigami.MessageType.Error showCloseButton: false visible: !realModel.isDataValid && realModel.isDirty Layout.topMargin: 5 Layout.fillWidth: true Layout.rightMargin: Kirigami.Units.largeSpacing Layout.leftMargin: Kirigami.Units.largeSpacing } RowLayout { spacing: Kirigami.Units.smallSpacing DialogButtonBox { id: deleteButtonBox Layout.minimumHeight: implicitHeight alignment: Qt.AlignLeft Button { id: deleteButton text: i18n("Delete") + icon.name: 'delete' DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole onClicked: { elisa.musicManager.deleteElementById(modelType, realModel.databaseId) trackMetadata.close() } } } DialogButtonBox { id: buttons Layout.fillWidth: true Layout.minimumHeight: implicitHeight alignment: Qt.AlignRight Button { id: applyButton enabled: realModel.isDataValid && realModel.isDirty text: i18n("Apply") + icon.name: 'dialog-ok-apply' DialogButtonBox.buttonRole: DialogButtonBox.ApplyRole onClicked: { realModel.saveData() if (!deleteButtonBox.visible && editableMetadata) { deleteButtonBox.visible = true } } } Button { text: i18n("Close") + icon.name: 'dialog-cancel' DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole onClicked: trackMetadata.close() } } } } Connections { target: elisa onMusicManagerChanged: { if (isCreation) { realModel.initializeForNewRadio() } else { realModel.initializeByUrl(modelType, fileName) } } } Component.onCompleted: { if (elisa.musicManager) { if (isCreation) { realModel.initializeForNewRadio() } else { realModel.initializeByUrl(modelType, fileName) } } } } diff --git a/src/qml/PlatformIntegration.qml b/src/qml/PlatformIntegration.qml index 6867edee..3457b939 100644 --- a/src/qml/PlatformIntegration.qml +++ b/src/qml/PlatformIntegration.qml @@ -1,81 +1,82 @@ /* * Copyright 2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ import QtQuick 2.7 import Qt.labs.platform 1.1 as NativeMenu import org.kde.elisa 1.0 Item { id: rootItem property alias playListModel: mpris2Interface.playListModel property alias audioPlayerManager: mpris2Interface.audioPlayerManager property alias player: mpris2Interface.audioPlayer property alias headerBarManager: mpris2Interface.headerBarManager property alias manageMediaPlayerControl: mpris2Interface.manageMediaPlayerControl property alias showProgressOnTaskBar: mpris2Interface.showProgressOnTaskBar property bool showSystemTrayIcon property var elisaMainWindow signal raisePlayer() Connections { target: elisaMainWindow onClosing: { if (systemTrayIcon.available && showSystemTrayIcon) { close.accepted = false elisaMainWindow.hide() } } } NativeMenu.MenuBar { NativeApplicationMenu { id: globalMenu } } Mpris2 { id: mpris2Interface playerName: 'elisa' onRaisePlayer: { rootItem.raisePlayer() } } NativeMenu.SystemTrayIcon { id: systemTrayIcon icon.name: 'elisa' tooltip: mainWindow.title visible: available && showSystemTrayIcon && !mainWindow.visible - menu: globalMenu + menu: NativeApplicationMenu { + } onActivated: { if (reason === NativeMenu.SystemTrayIcon.Trigger && !elisaMainWindow.visible) { elisaMainWindow.visible = true } else if (reason === NativeMenu.SystemTrayIcon.Trigger && elisaMainWindow.visible) { raisePlayer() } } } }