Commit 4043561f authored by Nate Graham's avatar Nate Graham 🔩
Browse files

Redo configuration window

The configuration window is re-done in a modern style. The changes
include:
- Use Form Layout style
- Use standard style list delegates
- Use standard Kirigami Units for distances, sizes, and paddings
- Use an invokable function to remove paths rather than directly
  manipulating the model from inside the view
- Re-word some text for clarity and brevity
- Display warning for using filesystem crawling only when the option is
  selected
- Combine everything into a single file for simplicity
- Don't let the user remove the last music search path
- Re-order properties to conform to standard style
- Use QQC2 import name

These changes fix the following bugs:
BUG: 425140
BUG: 418578
FIXED-IN: 21.04

Note that this bumps the frameworks dependency to 5.77 due to the use of
the new trailing property in Kirigami.BasicListItem.
parent 219ef4fb
Pipeline #43647 passed with stage
in 9 minutes and 43 seconds
......@@ -22,7 +22,7 @@ find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Core Network Qml Quick T
find_package(Qt5Core ${REQUIRED_QT_VERSION} CONFIG REQUIRED Private)
set(REQUIRED_KF5_VERSION "5.70.0")
set(REQUIRED_KF5_VERSION "5.77.0")
find_package(ECM ${REQUIRED_KF5_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
......
......@@ -426,8 +426,6 @@ if (Qt5Quick_FOUND AND Qt5Widgets_FOUND)
qml/HeaderFooterToolbar.qml
qml/ElisaConfigurationDialog.qml
qml/FileScanningConfiguration.qml
qml/GeneralConfiguration.qml
)
qt5_add_resources(elisa_SOURCES resources.qrc)
......
......@@ -193,6 +193,12 @@ void ElisaConfigurationDialog::setColorScheme(const QString &scheme)
setDirty();
}
void ElisaConfigurationDialog::removeMusicLocation(QString location)
{
mRootPath.removeAll(location);
emit rootPathChanged(mRootPath);
}
void ElisaConfigurationDialog::configChanged()
{
setRootPath(Elisa::ElisaConfiguration::rootPath());
......
......@@ -111,6 +111,9 @@ public:
return mColorScheme;
}
Q_INVOKABLE void removeMusicLocation(QString location);
Q_SIGNALS:
void rootPathChanged(const QStringList &rootPath);
......
/*
SPDX-FileCopyrightText: 2017 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
SPDX-FileCopyrightText: 2020 (c) Nate Graham <nate@kde.org>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
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
import QtQuick.Controls 2.4 as QQC2
import QtQuick.Dialogs 1.3 as Dialogs
import org.kde.kirigami 2.14 as Kirigami
import org.kde.elisa 1.0
......@@ -21,12 +23,12 @@ Window {
visible: true
modality: Qt.ApplicationModal
minimumWidth: 750
minimumHeight: 500
minimumWidth: Kirigami.Units.gridUnit * 36
minimumHeight: Kirigami.Units.gridUnit * 29
// Close when pressing Esc key
Shortcut {
sequence: StandardKey.Cancel
onActivated: close()
}
......@@ -35,87 +37,287 @@ Window {
colorGroup: SystemPalette.Active
}
Component {
id: highlightBar
Rectangle {
width: 200; height: 50
color: myPalette.highlight
}
}
// Draw standard window backround
Rectangle {
anchors.fill: parent
color: myPalette.window
ColumnLayout {
spacing: 0
anchors.fill: parent
anchors.margins: Kirigami.Units.smallSpacing
// General settings
// ================
Kirigami.FormLayout {
QQC2.CheckBox {
Kirigami.FormData.label: i18n("General:")
text: i18n("Show progress on Task Manager entries")
checked: ElisaConfigurationDialog.showProgressInTaskBar
onToggled: ElisaConfigurationDialog.showProgressInTaskBar = checked
Accessible.onToggleAction: onToggled
Accessible.onPressAction: onToggled
}
QQC2.CheckBox {
text: i18n("Keep running in System Tray when main window is closed")
checked: ElisaConfigurationDialog.showSystemTrayIcon
onToggled: ElisaConfigurationDialog.showSystemTrayIcon = checked
Accessible.onToggleAction: onToggled
Accessible.onPressAction: onToggled
}
QQC2.CheckBox {
text: i18n("Start playing on startup")
checked: ElisaConfigurationDialog.playAtStartup
onToggled: ElisaConfigurationDialog.playAtStartup = checked
Accessible.onToggleAction: onToggled
Accessible.onPressAction: onToggled
}
Item {
Kirigami.FormData.isSection: true
}
QQC2.ComboBox {
id: embeddedCategoryCombo
Kirigami.FormData.label: i18n("Embed category in sidebar:")
model: [i18nc("Configure dialog, embed no category in views navigation list", "Nothing"),
i18nc("Configure dialog, embed all albums in views navigation list", "Albums"),
i18nc("Configure dialog, embed all artists in views navigation list", "Artists"),
i18nc("Configure dialog, embed all genres in views navigation list", "Genres")]
editable: false
currentIndex: (ElisaConfigurationDialog.embeddedView === ElisaUtils.Genre ? 3 : (ElisaConfigurationDialog.embeddedView === ElisaUtils.Album ? 1 : (ElisaConfigurationDialog.embeddedView === ElisaUtils.Artist ? 2 : 0)))
onActivated: {
ElisaConfigurationDialog.embeddedView = (currentIndex === 0 ? ElisaUtils.Unknown : (currentIndex === 1 ? ElisaUtils.Album : (currentIndex === 2 ? ElisaUtils.Artist : ElisaUtils.Genre)))
}
Connections {
target: ElisaConfigurationDialog
onEmbeddedViewChanged:
{
if (ElisaConfigurationDialog.embeddedView == ElisaUtils.Unknown) {
embeddedCategoryCombo.currentIndex = 0
} else if (ElisaConfigurationDialog.embeddedView == ElisaUtils.Album) {
embeddedCategoryCombo.currentIndex = 1
} else if (ElisaConfigurationDialog.embeddedView == ElisaUtils.Artist) {
embeddedCategoryCombo.currentIndex = 2
} else if (ElisaConfigurationDialog.embeddedView == ElisaUtils.Genre) {
embeddedCategoryCombo.currentIndex = 3
}
}
}
}
Item {
Kirigami.FormData.isSection: true
}
QQC2.ComboBox {
id: initialViewCombo
Kirigami.FormData.label: i18n("Initial view on startup:")
model: [i18nc("Title of the view of the playlist", "Now Playing"),
i18nc("Title of the view of recently played tracks", "Recently Played"),
i18nc("Title of the view of frequently played tracks", "Frequently Played"),
i18nc("Title of the view of all albums", "Albums"),
i18nc("Title of the view of all artists", "Artists"),
i18nc("Title of the view of all tracks", "Tracks"),
i18nc("Title of the view of all genres", "Genres"),
i18nc("Title of the file browser view", "Files"),
i18nc("Title of the file radios browser view", "Radios"),
]
editable: false
currentIndex: ElisaConfigurationDialog.initialViewIndex
onActivated: {
ElisaConfigurationDialog.initialViewIndex = currentIndex
}
Connections {
target: ElisaConfigurationDialog
onInitialViewIndexChanged: initialViewCombo.currentIndex = ElisaConfigurationDialog.initialViewIndex
}
}
Kirigami.Heading {
text: i18n("General")
Item {
Kirigami.FormData.isSection: true
}
// Indexing settings
// =================
QQC2.ComboBox {
id: indexingTypeCombo
Kirigami.FormData.label: i18n("Music indexing:")
// Work around https://bugs.kde.org/show_bug.cgi?id=403153
implicitWidth: Kirigami.Units.gridUnit * 12
editable: false
model: [i18nc("Configure dialog, indexing type", "Use fast native indexer"),
i18nc("Configure dialog, indexing type", "Scan the filesystem directly")]
Layout.leftMargin: 5
Layout.rightMargin: 5
currentIndex: ElisaConfigurationDialog.forceUsageOfFastFileSearch ? 1 : 0
onActivated: {
ElisaConfigurationDialog.forceUsageOfFastFileSearch = currentIndex === 0 ? false : true
}
}
}
GeneralConfiguration {
Kirigami.InlineMessage {
Layout.fillWidth: true
Layout.leftMargin: Kirigami.Units.largeSpacing * 5
Layout.rightMargin: Kirigami.Units.largeSpacing * 5
Layout.topMargin: 10
Layout.leftMargin: 20
Layout.rightMargin: 10
}
visible: indexingTypeCombo.currentIndex === 1
Kirigami.Heading {
text: i18n("Music Search Configuration")
type: Kirigami.MessageType.Warning
text: xi18n("This is slower than the fast indexer. Please activate it only if Elisa cannot find your music and searching for one of the missing music files using your file manager also does not work. Please report this as a bug.")
Layout.topMargin: 15
Layout.leftMargin: 5
Layout.rightMargin: 5
actions: [
Kirigami.Action {
text: i18n("Report Bug")
iconName: "tools-report-bug"
onTriggered: Qt.openUrlExternally("https://bugs.kde.org/enter_bug.cgi?product=frameworks-baloo")
}
]
}
FileScanningConfiguration {
// Music locations list
// ====================
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: Kirigami.Units.largeSpacing * 5
Layout.rightMargin: Kirigami.Units.largeSpacing * 5
Kirigami.Heading {
Layout.fillWidth: true
text: i18nc("The configured folders where the user's music collection can be found", "Music folders:")
level: 4
}
QQC2.ScrollView {
id: scrollview
Layout.fillWidth: true
Layout.fillHeight: true
// Show the border
Component.onCompleted: {
scrollview.background.visible = true;
}
ListView {
id:pathList
clip: true
model: ElisaConfigurationDialog.rootPath
delegate: Kirigami.BasicListItem {
implicitHeight: Kirigami.Units.gridUnit * 2
// Don't need a highlight effect on hover
activeBackgroundColor: "transparent"
activeTextColor: myPalette.text
text: modelData
trailing: QQC2.Button {
icon.name: "edit-delete"
visible: pathList.count > 1
onClicked: ElisaConfigurationDialog.removeMusicLocation(modelData)
Accessible.onPressAction: onClicked
Layout.topMargin: 10
Layout.leftMargin: 20
Layout.rightMargin: 10
QQC2.ToolTip {
text: i18n("Stop looking for music here")
}
}
}
}
}
QQC2.Button {
text: i18n("Add New Location")
icon.name: "list-add"
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
onClicked: fileDialog.open()
Accessible.onPressAction: onClicked
Dialogs.FileDialog {
id: fileDialog
title: i18n("Choose a Folder")
folder: shortcuts.home
selectFolder: true
visible: false
onAccepted: {
var oldPaths = ElisaConfigurationDialog.rootPath
oldPaths.push(fileDialog.fileUrls)
ElisaConfigurationDialog.rootPath = oldPaths
}
}
}
}
DialogButtonBox {
QQC2.DialogButtonBox {
Layout.fillWidth: true
Button {
QQC2.Button {
text: i18n("OK")
icon.name: 'dialog-ok-apply'
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.AcceptRole
Accessible.onPressAction: onClicked
}
onAccepted: {
ElisaConfigurationDialog.save()
close()
}
Button {
QQC2.Button {
text: i18n("Apply")
icon.name: 'dialog-ok-apply'
DialogButtonBox.buttonRole: DialogButtonBox.ApplyRole
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.ApplyRole
Accessible.onPressAction: onClicked
enabled: ElisaConfigurationDialog.isDirty
}
onApplied: ElisaConfigurationDialog.save()
Button {
QQC2.Button {
text: i18n("Cancel")
icon.name: 'dialog-cancel'
DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
QQC2.DialogButtonBox.buttonRole: QQC2.DialogButtonBox.RejectRole
Accessible.onPressAction: onClicked
}
onAccepted: {
ElisaConfigurationDialog.save()
close()
}
onApplied: ElisaConfigurationDialog.save()
onRejected: close()
}
}
......
/*
SPDX-FileCopyrightText: 2017 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import QtQml.Models 2.3
import QtQuick.Dialogs 1.2 as Dialogs
import org.kde.elisa 1.0
ColumnLayout {
spacing: 0
CheckBox {
id: forceFileIndexerUsageCheckBox
text: i18n("Force filesystem indexing")
checked: !ElisaConfigurationDialog.forceUsageOfFastFileSearch
onCheckedChanged: ElisaConfigurationDialog.forceUsageOfFastFileSearch = !checked
}
Label {
text: i18n("This is much slower than usage of fast search!\nPlease activate it only if Elisa cannot find your music and searching for the file also does not work.\nPlease report this as a bug.")
}
RowLayout {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.topMargin: 10
spacing: 0
SystemPalette {
id: myPalette
colorGroup: SystemPalette.Active
}
Component {
id: highlightBar
Rectangle {
width: 200; height: 50
color: myPalette.highlight
}
}
Component {
id: pathDelegate
Item {
id: delegateItem
height: 3 * 30
width: scrollBar.visible ? pathList.width - scrollBar.width : pathList.width
Rectangle {
anchors.fill: parent
anchors.margins: 0.1 * 30
color: myPalette.base
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: pathList.currentIndex = delegateItem.DelegateModel.itemsIndex
Label {
text: modelData
anchors.centerIn: parent
}
ToolButton {
icon.name: 'list-remove'
Accessible.onPressAction: onClicked
anchors.top: parent.top
anchors.right: parent.right
onClicked:
{
var oldPaths = ElisaConfigurationDialog.rootPath
oldPaths.splice(delegateItem.DelegateModel.itemsIndex, 1)
ElisaConfigurationDialog.rootPath = oldPaths
}
}
}
}
}
}
ListView {
id:pathList
Layout.fillWidth: true
Layout.fillHeight: true
boundsBehavior: Flickable.StopAtBounds
clip: true
model: DelegateModel {
model: ElisaConfigurationDialog.rootPath
delegate: pathDelegate
}
ScrollBar.vertical: ScrollBar {
id: scrollBar
}
highlight: highlightBar
}
ColumnLayout {
Layout.fillHeight: true
Layout.leftMargin: !LayoutMirroring.enabled ? (0.3 * 30) : 0
Layout.rightMargin: LayoutMirroring.enabled ? (0.3 * 30) : 0
Button {
text: i18n("Add new path")
onClicked: fileDialog.open()
Accessible.onPressAction: onClicked
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Dialogs.FileDialog {
id: fileDialog
title: i18n("Choose a Folder")
folder: shortcuts.home
selectFolder: true
visible: false
onAccepted: {
var oldPaths = ElisaConfigurationDialog.rootPath
oldPaths.push(fileDialog.fileUrls)
ElisaConfigurationDialog.rootPath = oldPaths
}
}
}
Item {
Layout.fillHeight: true
}
}
}
}
/*
SPDX-FileCopyrightText: 2017 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.8 as Kirigami
import org.kde.elisa 1.0
ColumnLayout {
spacing: Kirigami.Units.smallSpacing
SystemPalette {
id: myPalette
colorGroup: SystemPalette.Active
}
CheckBox {
checked: ElisaConfigurationDialog.showProgressInTaskBar
text: i18n("Show progress on Task Manager entries")
onCheckedChanged: ElisaConfigurationDialog.showProgressInTaskBar = checked
}
CheckBox {
checked: ElisaConfigurationDialog.showSystemTrayIcon
text: i18n("Keep running in System Tray when main window is closed")
onToggled: ElisaConfigurationDialog.showSystemTrayIcon = checked
}
CheckBox {
checked: ElisaConfigurationDialog.playAtStartup
text: i18n("Start playing on startup")