Warning, /multimedia/elisa/src/qml/SettingsForm.qml is written in an unsupported language. File is not indexed.

0001 /*
0002    SPDX-FileCopyrightText: 2017 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
0003    SPDX-FileCopyrightText: 2020 (c) Nate Graham <nate@kde.org>
0004    SPDX-FileCopyrightText: 2020 (c) Devin Lin <espidev@gmail.com>
0005 
0006    SPDX-License-Identifier: LGPL-3.0-or-later
0007  */
0008 
0009 import QtCore
0010 import QtQuick 2.11
0011 import QtQuick.Layouts 1.12
0012 import QtQuick.Window 2.12
0013 import QtQuick.Controls 2.4 as QQC2
0014 import QtQuick.Dialogs as Dialogs
0015 
0016 import org.kde.kirigami 2.14 as Kirigami
0017 
0018 import org.kde.elisa 1.0
0019 
0020 import ".."
0021 
0022 ColumnLayout {
0023     readonly property alias dirtyClosingDialog: dirtyClosingDialog
0024 
0025     signal closeForm()
0026 
0027     function saveAndCloseForm() {
0028         ElisaConfigurationDialog.save()
0029         closeForm()
0030     }
0031 
0032     function discardAndCloseForm() {
0033         ElisaConfigurationDialog.cancel()
0034         closeForm()
0035     }
0036 
0037     function applyChanges() {
0038         ElisaConfigurationDialog.save()
0039     }
0040 
0041     Dialogs.MessageDialog {
0042         id: dirtyClosingDialog
0043 
0044         title: i18nc("@title:window", "Warning")
0045         text: i18nc("@info", 'You have unsaved changes. Do you want to apply the changes or discard them?')
0046         buttons: Dialogs.MessageDialog.Save | Dialogs.MessageDialog.Discard | Dialogs.MessageDialog.Cancel
0047 
0048         onButtonClicked: (button, role) => {
0049             switch(button) {
0050                 case Dialogs.MessageDialog.Save: {
0051                     saveAndCloseForm()
0052                 }
0053                 case Dialogs.MessageDialog.Discard: {
0054                     discardAndCloseForm()
0055                 }
0056             }
0057             close()
0058         }
0059     }
0060 
0061     // General settings
0062     // ================
0063     Kirigami.FormLayout {
0064         Layout.fillWidth: true
0065 
0066         QQC2.CheckBox {
0067             Kirigami.FormData.label: i18nc("@title:group", "General:")
0068 
0069             Layout.fillWidth: true
0070 
0071             text: i18nc("@option:check", "Show background on Now Playing page")
0072 
0073             checked: ElisaConfigurationDialog.showNowPlayingBackground
0074             onToggled: ElisaConfigurationDialog.showNowPlayingBackground = checked
0075             Accessible.onToggleAction: onToggled
0076             Accessible.onPressAction: onToggled
0077         }
0078 
0079         QQC2.CheckBox {
0080             id: progressCheckBox
0081 
0082             Layout.fillWidth: true
0083 
0084             text: i18nc("@option:check", "Show progress on Task Manager entries")
0085 
0086             checked: ElisaConfigurationDialog.showProgressInTaskBar
0087             onToggled: ElisaConfigurationDialog.showProgressInTaskBar = checked
0088             Accessible.onToggleAction: onToggled
0089             Accessible.onPressAction: onToggled
0090         }
0091 
0092         QQC2.CheckBox {
0093             Layout.fillWidth: true
0094 
0095             text: i18nc("@option:check", "Keep running in System Tray when main window is closed")
0096 
0097             checked: ElisaConfigurationDialog.showSystemTrayIcon
0098             onToggled: ElisaConfigurationDialog.showSystemTrayIcon = checked
0099             Accessible.onToggleAction: onToggled
0100             Accessible.onPressAction: onToggled
0101         }
0102 
0103         QQC2.CheckBox {
0104             Layout.fillWidth: true
0105 
0106             text: i18nc("@option:check", "Start playing on startup")
0107 
0108             checked: ElisaConfigurationDialog.playAtStartup
0109             onToggled: ElisaConfigurationDialog.playAtStartup = checked
0110             Accessible.onToggleAction: onToggled
0111             Accessible.onPressAction: onToggled
0112         }
0113 
0114         QQC2.CheckBox {
0115             Layout.fillWidth: true
0116 
0117             text: i18nc("@option:check", "Scan for New Music on startup")
0118 
0119             checked: ElisaConfigurationDialog.scanAtStartup
0120             onToggled: {
0121                 startupScanWarningMessage.visible = !checked
0122                 ElisaConfigurationDialog.scanAtStartup = checked
0123             }
0124             Accessible.onToggleAction: onToggled
0125             Accessible.onPressAction: onToggled
0126         }
0127 
0128         Kirigami.InlineMessage {
0129             id: startupScanWarningMessage
0130             Layout.fillWidth: true
0131 
0132             // Not visible by default, the message only becomes visible when "Scan for New Music on startup" checkbox is unchecked. See onToggled implementation of the checkbox.
0133             visible: false
0134 
0135             type: Kirigami.MessageType.Warning
0136             text: xi18nc("@info", "When using this setting, you will need to manually refresh the music collection whenever new files are added to configured music folders. You can do this with the <interface>Scan for new music</interface> item in Elisa's hamburger menu.")
0137         }
0138 
0139 
0140         Item {
0141             Kirigami.FormData.isSection: true
0142         }
0143 
0144         QQC2.ButtonGroup { id: ratingStyleGroup }
0145 
0146         QQC2.RadioButton {
0147             Kirigami.FormData.label: i18nc("@title:group", "Song rating style:")
0148 
0149             Layout.fillWidth: true
0150 
0151             text: i18nc("@option:radio", "0-5 stars")
0152 
0153             QQC2.ButtonGroup.group: ratingStyleGroup
0154 
0155             checked: !ElisaConfigurationDialog.useFavoriteStyleRatings
0156             onToggled: ElisaConfigurationDialog.useFavoriteStyleRatings = !checked
0157             Accessible.onToggleAction: onToggled
0158             Accessible.onPressAction: onToggled
0159         }
0160         QQC2.RadioButton {
0161             Layout.fillWidth: true
0162 
0163             text: i18nc("@option:radio", "Favorite/not favorite")
0164 
0165             QQC2.ButtonGroup.group: ratingStyleGroup
0166 
0167             checked: ElisaConfigurationDialog.useFavoriteStyleRatings
0168             onToggled: ElisaConfigurationDialog.useFavoriteStyleRatings = checked
0169 
0170             Accessible.onToggleAction: onToggled
0171             Accessible.onPressAction: onToggled
0172         }
0173 
0174         Item {
0175             Kirigami.FormData.isSection: true
0176             visible: Kirigami.Settings.isMobile
0177         }
0178 
0179         // select colour scheme (mobile only, since desktop has it in the application menu)
0180         QQC2.ComboBox {
0181             Kirigami.FormData.label: i18nc("@label:listbox", "Color Scheme:")
0182 
0183             visible: Kirigami.Settings.isMobile
0184 
0185             model: ElisaApplication.colorSchemesModel
0186             textRole: "display"
0187 
0188             delegate: QQC2.ItemDelegate {
0189                 width: parent.width
0190 
0191                 required property var model
0192 
0193                 icon.name: "image://colorScheme/" + model.display
0194                 text: model.display
0195                 checked: model.display === ElisaConfigurationDialog.colorScheme
0196                 onClicked: {
0197                     ElisaApplication.activateColorScheme(model.display)
0198                     ElisaConfigurationDialog.setColorScheme(model.display)
0199                     ElisaConfigurationDialog.save()
0200                 }
0201             }
0202         }
0203 
0204         Item {
0205             Kirigami.FormData.isSection: true
0206             visible: Kirigami.Settings.isMobile
0207         }
0208 
0209         // scan for new music (mobile only, since on desktop it is in the application menu)
0210         QQC2.Button {
0211             visible: Kirigami.Settings.isMobile
0212             text: i18nc("@action:button", "Scan for New Music")
0213             icon.name: "view-refresh"
0214             onClicked: {
0215                 ElisaApplication.musicManager.scanCollection(MusicListenersManager.Soft)
0216                 showPassiveNotification(i18nc("@info", "Started scanning for music"))
0217             }
0218         }
0219 
0220         QQC2.Button {
0221             visible: Kirigami.Settings.isMobile
0222             text: i18nc("@action:button", "Reset Database and Re-Scan Everything")
0223             icon.name: "edit-clear-all"
0224             onClicked: {
0225                 ElisaApplication.musicManager.scanCollection(MusicListenersManager.Hard)
0226                 showPassiveNotification(i18nc("@info", "Database has been reset"))
0227                 showPassiveNotification(i18nc("@info", "Started scanning for music"))
0228             }
0229         }
0230 
0231         Item {
0232             Kirigami.FormData.isSection: true
0233             visible: !Kirigami.Settings.isMobile
0234         }
0235 
0236         // desktop only, since the mobile sidebar does not support it
0237         QQC2.ComboBox {
0238             id: embeddedCategoryCombo
0239             visible: !Kirigami.Settings.isMobile
0240 
0241             Kirigami.FormData.label: i18nc("@label:listbox", "Embed category in sidebar:")
0242 
0243             model: [i18nc("@item:inlistbox Configure dialog, embed no category in views navigation list", "Nothing"),
0244                 i18nc("@item:inlistbox Configure dialog, embed all albums in views navigation list", "Albums"),
0245                 i18nc("@item:inlistbox Configure dialog, embed all artists in views navigation list", "Artists"),
0246                 i18nc("@item:inlistbox Configure dialog, embed all genres in views navigation list", "Genres")]
0247 
0248             editable: false
0249             currentIndex: (ElisaConfigurationDialog.embeddedView === ElisaUtils.Genre ? 3 : (ElisaConfigurationDialog.embeddedView === ElisaUtils.Album ? 1 : (ElisaConfigurationDialog.embeddedView === ElisaUtils.Artist ? 2 : 0)))
0250 
0251             onActivated: {
0252                 ElisaConfigurationDialog.embeddedView = (currentIndex === 0 ? ElisaUtils.Unknown : (currentIndex === 1 ? ElisaUtils.Album : (currentIndex === 2 ? ElisaUtils.Artist : ElisaUtils.Genre)))
0253             }
0254 
0255             Connections {
0256                 target: ElisaConfigurationDialog
0257 
0258                 function onEmbeddedViewChanged() {
0259                     if (ElisaConfigurationDialog.embeddedView == ElisaUtils.Unknown) {
0260                         embeddedCategoryCombo.currentIndex = 0
0261                     } else if (ElisaConfigurationDialog.embeddedView == ElisaUtils.Album) {
0262                         embeddedCategoryCombo.currentIndex = 1
0263                     } else if (ElisaConfigurationDialog.embeddedView == ElisaUtils.Artist) {
0264                         embeddedCategoryCombo.currentIndex = 2
0265                     } else if (ElisaConfigurationDialog.embeddedView == ElisaUtils.Genre) {
0266                         embeddedCategoryCombo.currentIndex = 3
0267                     }
0268                 }
0269             }
0270         }
0271 
0272         Item {
0273             Kirigami.FormData.isSection: true
0274         }
0275 
0276         QQC2.ComboBox {
0277             id: initialViewCombo
0278 
0279             Kirigami.FormData.label: i18nc("@label:listbox", "Initial view on startup:")
0280 
0281             model: [i18nc("@item:inlistbox Title of the view of the playlist", "Now Playing"),
0282                 i18nc("@item:inlistbox Title of the view of recently played tracks", "Recently Played"),
0283                 i18nc("@item:inlistbox Title of the view of frequently played tracks", "Frequently Played"),
0284                 i18nc("@item:inlistbox Title of the view of all albums", "Albums"),
0285                 i18nc("@item:inlistbox Title of the view of all artists", "Artists"),
0286                 i18nc("@item:inlistbox Title of the view of all tracks", "Tracks"),
0287                 i18nc("@item:inlistbox Title of the view of all genres", "Genres"),
0288                 i18nc("@item:inlistbox Title of the file browser view", "Files"),
0289                 i18nc("@item:inlistbox Title of the file radios browser view", "Radio Stations"),
0290             ]
0291 
0292             editable: false
0293             currentIndex: ElisaConfigurationDialog.initialViewIndex
0294 
0295             onActivated: {
0296                 ElisaConfigurationDialog.initialViewIndex = currentIndex
0297             }
0298 
0299             Connections {
0300                 target: ElisaConfigurationDialog
0301 
0302                 function onInitialViewIndexChanged() {
0303                     initialViewCombo.currentIndex = ElisaConfigurationDialog.initialViewIndex
0304                 }
0305             }
0306         }
0307 
0308         RowLayout {
0309             Kirigami.FormData.label: i18nc("@label:textbox", "Initial location for Files view:")
0310             spacing: Kirigami.Units.smallSpacing
0311 
0312             QQC2.TextField {
0313                 id: initialFilesViewPathTextField
0314 
0315                 text: ElisaConfigurationDialog.initialFilesViewPath
0316                 onTextChanged: {
0317                     ElisaConfigurationDialog.initialFilesViewPath = text
0318                 }
0319             }
0320 
0321             QQC2.Button {
0322                 icon.name: "document-open-folder"
0323                 text: i18nc("@action:button as in, choose a file path on disk", "Choose…")
0324                 onClicked: {
0325                     filesViewPathChooserDialog.visible = true
0326                 }
0327 
0328                 Dialogs.FolderDialog {
0329                     id: filesViewPathChooserDialog
0330 
0331                     title: i18nc("@title:window", "Choose a Folder")
0332                     currentFolder: ElisaConfigurationDialog.initialFilesViewPath
0333 
0334                     onAccepted: {
0335                         const url = selectedFolder
0336                         initialFilesViewPathTextField.text = url.toString().replace("file://", "")
0337                     }
0338                 }
0339             }
0340         }
0341 
0342         Item {
0343             Kirigami.FormData.isSection: true
0344         }
0345 
0346         Item {
0347             Kirigami.FormData.isSection: true
0348         }
0349 
0350         // Playlist save settings
0351         // ======================
0352 
0353         ColumnLayout {
0354             Kirigami.FormData.label: i18n("When saving playlist files:")
0355             Kirigami.FormData.buddyFor: playlistFilePathTypeBox
0356 
0357             Layout.fillWidth: true
0358 
0359             spacing: Kirigami.Units.smallSpacing
0360 
0361             QQC2.ComboBox {
0362                 id: playlistFilePathTypeBox
0363                 model: [i18nc("@item:inlistbox Configure dialog, playlist save type", "Prefer relative paths"),
0364                         i18nc("@item:inlistbox Configure dialog, playlist save type", "Always use absolute paths")]
0365 
0366                 currentIndex: ElisaConfigurationDialog.alwaysUseAbsolutePlaylistPaths ? 1 : 0
0367                 onActivated: {
0368                     ElisaConfigurationDialog.alwaysUseAbsolutePlaylistPaths = currentIndex === 0 ? false : true
0369                 }
0370             }
0371 
0372             QQC2.Label {
0373                 Layout.fillWidth: true
0374                 Layout.maximumWidth: Kirigami.Units.gridUnit * 16
0375                 text: xi18nc("@info:tooltip Playlist Relative Paths", "When <interface>Prefer relative paths</interface> is selected, files in the same folder as the playlist will be referred with only the filename. Absolute paths are used in other cases.")
0376                 wrapMode: Text.Wrap
0377                 font: Kirigami.Theme.smallFont
0378             }
0379         }
0380     }
0381 
0382     // Music locations list
0383     // ====================
0384     ColumnLayout {
0385         Layout.fillWidth: true
0386         Layout.fillHeight: true
0387 
0388         Kirigami.Heading {
0389             Layout.fillWidth: true
0390             text: i18nc("@title The configured folders where the user's music collection can be found", "Music folders:")
0391             level: 4
0392         }
0393 
0394         QQC2.ScrollView {
0395             id: scrollview
0396 
0397             Layout.fillWidth: true
0398             Layout.fillHeight: true
0399             Layout.maximumHeight: Kirigami.Units.gridUnit * 12
0400 
0401             // HACK: workaround for https://bugreports.qt.io/browse/QTBUG-83890
0402             QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
0403 
0404             // Show the border
0405             Component.onCompleted: {
0406                 if (scrollview.background) {
0407                     scrollview.background.visible = true;
0408                 }
0409             }
0410 
0411             contentItem: ListView {
0412                 id: pathList
0413 
0414                 clip: true
0415 
0416                 model: ElisaConfigurationDialog.rootPath
0417 
0418                 delegate: Kirigami.SwipeListItem {
0419                     id: delegate
0420                     // Don't need a highlight effect on hover
0421                     hoverEnabled: false
0422 
0423                     contentItem: QQC2.Label {
0424                         text: modelData
0425                         width: delegate.width - delegate.leftPadding
0426                                               - delegate.rightPadding
0427                                               - (action.visible ? action.width : 0)
0428                         elide: Text.ElideMiddle
0429                         verticalAlignment: Text.AlignVCenter
0430                     }
0431 
0432                     actions: Kirigami.Action {
0433                         id: action
0434                         icon.name: "edit-delete"
0435                         text: i18nc("@action:button", "Stop looking for music here")
0436 
0437                         visible: pathList.count > 1
0438                         onTriggered: ElisaConfigurationDialog.removeMusicLocation(modelData)
0439                     }
0440                 }
0441             }
0442         }
0443 
0444         RowLayout {
0445             spacing: Kirigami.Units.largeSpacing * 2
0446 
0447             QQC2.Button {
0448                 text: i18nc("@action:button", "Add New Location")
0449                 icon.name: "list-add"
0450 
0451                 Layout.alignment: Qt.AlignTop | Qt.AlignLeft
0452 
0453                 onClicked: fileDialog.open()
0454                 Accessible.onPressAction: onClicked
0455 
0456                 Dialogs.FolderDialog {
0457                     id: fileDialog
0458                     title: i18nc("@title:window", "Choose a Folder")
0459 
0460                     currentFolder: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0]
0461 
0462                     visible: false
0463 
0464                     onAccepted: {
0465                         var oldPaths = ElisaConfigurationDialog.rootPath
0466                         oldPaths.push(fileDialog.selectedFolder)
0467                         ElisaConfigurationDialog.rootPath = oldPaths
0468                     }
0469                 }
0470             }
0471         }
0472     }
0473 }