Warning, /multimedia/kid3/src/qml/app/SettingsPage.qml is written in an unsupported language. File is not indexed.
0001 /**
0002 * \file SettingsPage.qml
0003 * Settings page.
0004 *
0005 * \b Project: Kid3
0006 * \author Urs Fleisch
0007 * \date 16 Feb 2015
0008 *
0009 * Copyright (C) 2015-2019 Urs Fleisch
0010 *
0011 * This program is free software; you can redistribute it and/or modify
0012 * it under the terms of the GNU Lesser General Public License as published by
0013 * the Free Software Foundation; version 3.
0014 *
0015 * This program is distributed in the hope that it will be useful,
0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0018 * GNU Lesser General Public License for more details.
0019 *
0020 * You should have received a copy of the GNU Lesser General Public License
0021 * along with this program. If not, see <http://www.gnu.org/licenses/>.
0022 */
0023
0024 import QtQuick 2.11
0025 import QtQuick.Controls 2.4
0026
0027 AbstractSettingsPage {
0028 id: settingsPage
0029
0030 title: qsTr("Settings")
0031 model: [
0032 SettingsElement { name: qsTr("Tags") },
0033 SettingsElement { name: qsTr("Files") },
0034 SettingsElement { name: qsTr("Plugins") },
0035 SettingsElement { name: qsTr("Appearance") }
0036 ]
0037 onClicked: pageStack.push(
0038 [ tagsPage, filesPage, pluginsPage, appearancePage ][index])
0039 Component {
0040 id: tagsPage
0041 AbstractSettingsPage {
0042 property QtObject tagCfg: configs.tagConfig()
0043 property QtObject fmtCfg: configs.tagFormatConfig()
0044 title: qsTr("Tags")
0045 visible: false
0046 model: [
0047 SettingsElement {
0048 name: qsTr("Mark truncated fields")
0049 onActivated: function() { value = tagCfg.markTruncations; }
0050 onDeactivated: function() { tagCfg.markTruncations = value; }
0051 },
0052 SettingsElement {
0053 name: qsTr("ID3v1 text encoding")
0054 dropDownModel: configs.tagConfig().getTextCodecNames()
0055 onActivated: function() { value = tagCfg.textEncodingV1Index; }
0056 onDeactivated: function() { tagCfg.textEncodingV1Index = value; }
0057 },
0058 SettingsElement {
0059 name: qsTr("ID3v2 text encoding")
0060 dropDownModel: configs.tagConfig().getTextEncodingNames()
0061 onActivated: function() { value = tagCfg.textEncoding; }
0062 onDeactivated: function() { tagCfg.textEncoding = value; }
0063 },
0064 SettingsElement {
0065 name: qsTr("Use track/total number of tracks format")
0066 onActivated: function() { value = tagCfg.enableTotalNumberOfTracks; }
0067 onDeactivated: function() { tagCfg.enableTotalNumberOfTracks = value; }
0068 },
0069 SettingsElement {
0070 name: qsTr("Genre as text instead of numeric string")
0071 onActivated: function() { value = tagCfg.genreNotNumeric; }
0072 onDeactivated: function() { tagCfg.genreNotNumeric = value; }
0073 },
0074 SettingsElement {
0075 name: qsTr("WAV files with lowercase id3 chunk")
0076 onActivated: function() { value = tagCfg.lowercaseId3RiffChunk; }
0077 onDeactivated: function() { tagCfg.lowercaseId3RiffChunk = value; }
0078 },
0079 SettingsElement {
0080 name: qsTr("Version used for new ID3v2 tags")
0081 dropDownModel: configs.tagConfig().getId3v2VersionNames()
0082 onActivated: function() { value = tagCfg.id3v2Version; }
0083 onDeactivated: function() { tagCfg.id3v2Version = value; }
0084 },
0085 SettingsElement {
0086 name: qsTr("Track number digits")
0087 onActivated: function() { value = tagCfg.trackNumberDigits; }
0088 onDeactivated: function() { tagCfg.trackNumberDigits = value; }
0089 },
0090 SettingsElement {
0091 name: qsTr("Ogg/Vorbis comment field name")
0092 dropDownModel: configs.tagConfig().getCommentNames()
0093 onActivated: function() {
0094 value = dropDownModel.indexOf(tagCfg.commentName)
0095 }
0096 onDeactivated: function() {
0097 tagCfg.commentName = dropDownModel[value]
0098 }
0099 },
0100 SettingsElement {
0101 name: qsTr("Ogg/Vorbis picture field name")
0102 dropDownModel: configs.tagConfig().getPictureNames()
0103 onActivated: function() { value = tagCfg.pictureNameIndex; }
0104 onDeactivated: function() { tagCfg.pictureNameIndex = value; }
0105 },
0106 SettingsElement {
0107 name: qsTr("RIFF track number field name")
0108 dropDownModel: configs.tagConfig().getRiffTrackNames()
0109 onActivated: function() {
0110 value = dropDownModel.indexOf(tagCfg.riffTrackName)
0111 }
0112 onDeactivated: function() {
0113 tagCfg.riffTrackName = dropDownModel[value]
0114 }
0115 },
0116 SettingsElement {
0117 name: qsTr("Mark if picture larger than maximum size")
0118 onActivated: function() { value = tagCfg.markOversizedPictures; }
0119 onDeactivated: function() { tagCfg.markOversizedPictures = value; }
0120 },
0121 SettingsElement {
0122 name: qsTr("Picture maximum size (bytes)")
0123 onActivated: function() { value = tagCfg.maximumPictureSize; }
0124 onDeactivated: function() { tagCfg.maximumPictureSize = value; }
0125 },
0126 SettingsElement {
0127 name: qsTr("Show only custom genres")
0128 onActivated: function() { value = tagCfg.onlyCustomGenres; }
0129 onDeactivated: function() { tagCfg.onlyCustomGenres = value; }
0130 onEdit: function() {
0131 stringListEditPage.title = qsTr("Custom Genres")
0132 stringListEditPage.onActivated = function() {
0133 stringListEditPage.setElements(tagCfg.customGenres)
0134 }
0135 stringListEditPage.onDeactivated = function() {
0136 tagCfg.customGenres = stringListEditPage.getElements()
0137 }
0138 page.StackView.view.push(stringListEditPage)
0139 }
0140 },
0141 SettingsElement {
0142 name: qsTr("Case conversion")
0143 dropDownModel: configs.tagFormatConfig().getCaseConversionNames()
0144 onActivated: function() { value = fmtCfg.caseConversion; }
0145 onDeactivated: function() { fmtCfg.caseConversion = value; }
0146 },
0147 SettingsElement {
0148 name: qsTr("Locale")
0149 dropDownModel: configs.tagFormatConfig().getLocaleNames()
0150 onActivated: function() {
0151 var idx = dropDownModel.indexOf(fmtCfg.localeName)
0152 value = idx === -1 ? 0 : idx
0153 }
0154 onDeactivated: function() {
0155 fmtCfg.localeName = value > 0 ? dropDownModel[value] : ""
0156 }
0157 },
0158 SettingsElement {
0159 name: qsTr("String replacement")
0160 onActivated: function() { value = fmtCfg.strRepEnabled; }
0161 onDeactivated: function() { fmtCfg.strRepEnabled = value; }
0162 onEdit: function() {
0163 mapEditPage.title = qsTr("String Replacement")
0164 mapEditPage.onActivated = function() {
0165 mapEditPage.setElements(fmtCfg.strRepMap)
0166 }
0167 mapEditPage.onDeactivated = function() {
0168 fmtCfg.strRepMap = mapEditPage.getElements()
0169 }
0170 page.StackView.view.push(mapEditPage)
0171 }
0172 },
0173 SettingsElement {
0174 name: qsTr("Custom frames")
0175 onEdit: function() {
0176 stringListEditPage.title = qsTr("Custom Frames")
0177 stringListEditPage.onActivated = function() {
0178 stringListEditPage.setElements(
0179 tagCfg.customFrameNamesToDisplayNames(tagCfg.customFrames))
0180 }
0181 stringListEditPage.onDeactivated = function() {
0182 tagCfg.customFrames = tagCfg.customFrameNamesFromDisplayNames(
0183 stringListEditPage.getElements())
0184 }
0185 page.StackView.view.push(stringListEditPage)
0186 }
0187 },
0188 SettingsElement {
0189 name: qsTr("Quick access frames")
0190 onEdit: function() {
0191 page.StackView.view.push(quickAccessFramesPage)
0192 }
0193 }
0194 ]
0195 StackView.onActivated: activateAll()
0196 StackView.onDeactivated: deactivateAll()
0197 }
0198 }
0199 Component {
0200 id: filesPage
0201 AbstractSettingsPage {
0202 property QtObject fileCfg: configs.fileConfig()
0203 property QtObject fmtCfg: configs.filenameFormatConfig()
0204 title: qsTr("Files")
0205 visible: false
0206 model: [
0207 SettingsElement {
0208 name: qsTr("Load last-opened files")
0209 onActivated: function() { value = fileCfg.loadLastOpenedFile; }
0210 onDeactivated: function() { fileCfg.loadLastOpenedFile = value; }
0211 },
0212 SettingsElement {
0213 name: qsTr("Preserve file timestamp")
0214 onActivated: function() { value = fileCfg.preserveTime; }
0215 onDeactivated: function() { fileCfg.preserveTime = value; }
0216 },
0217 SettingsElement {
0218 name: qsTr("Mark changes")
0219 onActivated: function() { value = fileCfg.markChanges; }
0220 onDeactivated: function() { fileCfg.markChanges = value; }
0221 },
0222 SettingsElement {
0223 name: qsTr("Automatically apply format")
0224 onActivated: function() { value = fmtCfg.formatWhileEditing; }
0225 onDeactivated: function() { fmtCfg.formatWhileEditing = value; }
0226 },
0227 SettingsElement {
0228 name: qsTr("Use for playlist and folder names")
0229 onActivated: function() { value = fmtCfg.useForOtherFileNames; }
0230 onDeactivated: function() { fmtCfg.useForOtherFileNames = value; }
0231 },
0232 SettingsElement {
0233 name: qsTr("Use maximum length")
0234 onActivated: function() { value = fmtCfg.enableMaximumLength; }
0235 onDeactivated: function() { fmtCfg.enableMaximumLength = value; }
0236 },
0237 SettingsElement {
0238 name: qsTr("Maximum length")
0239 onActivated: function() { value = fmtCfg.maximumLength; }
0240 onDeactivated: function() { fmtCfg.maximumLength = value; }
0241 },
0242 SettingsElement {
0243 name: qsTr("Case conversion")
0244 dropDownModel: configs.filenameFormatConfig().getCaseConversionNames()
0245 onActivated: function() { value = fmtCfg.caseConversion; }
0246 onDeactivated: function() { fmtCfg.caseConversion = value; }
0247 },
0248 SettingsElement {
0249 name: qsTr("Locale")
0250 dropDownModel: configs.filenameFormatConfig().getLocaleNames()
0251 onActivated: function() {
0252 var idx = dropDownModel.indexOf(fmtCfg.localeName)
0253 value = idx === -1 ? 0 : idx
0254 }
0255 onDeactivated: function() {
0256 fmtCfg.localeName = value > 0 ? dropDownModel[value] : ""
0257 }
0258 },
0259 SettingsElement {
0260 name: qsTr("String replacement")
0261 onActivated: function() { value = fmtCfg.strRepEnabled; }
0262 onDeactivated: function() { fmtCfg.strRepEnabled = value; }
0263 onEdit: function() {
0264 mapEditPage.title = qsTr("String Replacement")
0265 mapEditPage.onActivated = function() {
0266 mapEditPage.setElements(fmtCfg.strRepMap)
0267 }
0268 mapEditPage.onDeactivated = function() {
0269 fmtCfg.strRepMap = mapEditPage.getElements()
0270 }
0271 page.StackView.view.push(mapEditPage)
0272 }
0273 },
0274 SettingsElement {
0275 name: qsTr("Filename for cover")
0276 onActivated: function() { value = fileCfg.defaultCoverFileName; }
0277 onDeactivated: function() { fileCfg.defaultCoverFileName = value; }
0278 },
0279 SettingsElement {
0280 name: qsTr("Playlist text encoding")
0281 dropDownModel: configs.fileConfig().getTextCodecNames()
0282 onActivated: function() { value = fileCfg.textEncodingIndex; }
0283 onDeactivated: function() { fileCfg.textEncodingIndex = value; }
0284 },
0285 SettingsElement {
0286 name: qsTr("To filename format")
0287 dropDownModel: configs.fileConfig().toFilenameFormats
0288 width: constants.gu(51)
0289 onActivated: function() {
0290 value = dropDownModel.indexOf(fileCfg.toFilenameFormat)
0291 }
0292 onDeactivated: function() {
0293 fileCfg.toFilenameFormat = dropDownModel[value]
0294 }
0295 onEdit: function() {
0296 stringListEditPage.title = qsTr("Filename from Tag")
0297 stringListEditPage.onActivated = function() {
0298 stringListEditPage.setElements(dropDownModel)
0299 stringListEditPage.currentIndex = value
0300 }
0301 stringListEditPage.onDeactivated = function() {
0302 var lst = stringListEditPage.getElements()
0303 configs.fileConfig().toFilenameFormats = lst
0304 configs.fileConfig().toFilenameFormat =
0305 lst[stringListEditPage.currentIndex]
0306 }
0307 page.StackView.view.push(stringListEditPage)
0308 }
0309 },
0310 SettingsElement {
0311 name: qsTr("From filename format")
0312 dropDownModel: configs.fileConfig().fromFilenameFormats
0313 width: constants.gu(51)
0314 onActivated: function() {
0315 value = dropDownModel.indexOf(fileCfg.fromFilenameFormat)
0316 }
0317 onDeactivated: function() {
0318 fileCfg.fromFilenameFormat = dropDownModel[value]
0319 }
0320 onEdit: function() {
0321 stringListEditPage.title = qsTr("Tag from Filename")
0322 stringListEditPage.onActivated = function() {
0323 stringListEditPage.setElements(dropDownModel)
0324 stringListEditPage.currentIndex = value
0325 }
0326 stringListEditPage.onDeactivated = function() {
0327 var lst = stringListEditPage.getElements()
0328 configs.fileConfig().fromFilenameFormats = lst
0329 configs.fileConfig().fromFilenameFormat =
0330 lst[stringListEditPage.currentIndex]
0331 }
0332 page.StackView.view.push(stringListEditPage)
0333 }
0334 }
0335 ]
0336 StackView.onActivated: activateAll()
0337 StackView.onDeactivated: deactivateAll()
0338 }
0339 }
0340 Component {
0341 id: pluginsPage
0342 AbstractSettingsPage {
0343 title: qsTr("Plugins")
0344 visible: false
0345 StackView.onActivated: {
0346 var tagCfg = configs.tagConfig()
0347 var importCfg = configs.importConfig()
0348 var disabledTagPlugins, disabledImportPlugins, i, name
0349 disabledTagPlugins = tagCfg.disabledPlugins
0350 disabledImportPlugins = importCfg.disabledPlugins
0351 for (i = 0; i < model.length; ++i) {
0352 name = model[i].name
0353 model[i].value =
0354 disabledTagPlugins.indexOf(name) === -1 &&
0355 disabledImportPlugins.indexOf(name) === -1
0356 }
0357 }
0358 StackView.onDeactivated: {
0359 var tagCfg = configs.tagConfig()
0360 var importCfg = configs.importConfig()
0361 var disabledTagPlugins, disabledImportPlugins, i, name
0362 var availableTagPlugins = tagCfg.availablePlugins
0363 var availableImportPlugins = importCfg.availablePlugins
0364 disabledTagPlugins = []
0365 disabledImportPlugins = []
0366 for (i = 0; i < model.length; ++i) {
0367 if (model[i].value === false) {
0368 name = model[i].name
0369 if (availableTagPlugins.indexOf(name) !== -1) {
0370 disabledTagPlugins.push(name)
0371 } else if (availableImportPlugins.indexOf(name) !== -1) {
0372 disabledImportPlugins.push(name)
0373 }
0374 }
0375 }
0376 tagCfg.disabledPlugins = disabledTagPlugins
0377 importCfg.disabledPlugins = disabledImportPlugins
0378 }
0379 Component.onCompleted: {
0380 // A deep copy is necessary in QtQuick 2 because of QTBUG-33149
0381 // (concat does not work with QStringList) and to avoid modification of
0382 // the original list in the config.
0383 var availablePlugins = configs.tagConfig().availablePlugins.slice()
0384 availablePlugins = availablePlugins.concat(
0385 configs.importConfig().availablePlugins)
0386 var settingsModel = []
0387 var elementComponent = Qt.createComponent("SettingsElement.qml")
0388 for (var i = 0; i < availablePlugins.length; ++i) {
0389 var elementObj = elementComponent.createObject(pluginsPage)
0390 elementObj.name = availablePlugins[i]
0391 settingsModel.push(elementObj)
0392 }
0393 model = settingsModel
0394 }
0395 }
0396 }
0397 Component {
0398 id: appearancePage
0399 AbstractSettingsPage {
0400 property QtObject mainWindowCfg: configs.mainWindowConfig()
0401 title: qsTr("Appearance")
0402 visible: false
0403 model: [
0404 SettingsElement {
0405 name: qsTr("Language")
0406 dropDownModel: [qsTr("System")]
0407 .concat(configs.mainWindowConfig().availableLanguages())
0408 onActivated: function() {
0409 value = mainWindowCfg.language
0410 ? dropDownModel.indexOf(mainWindowCfg.language) : 0
0411 }
0412 onDeactivated: function() {
0413 mainWindowCfg.language = value > 0 ? dropDownModel[value] : ""
0414 }
0415 },
0416 SettingsElement {
0417 name: qsTr("Theme")
0418 dropDownModel: configs.mainWindowConfig().getQtQuickStyleNames()
0419 onActivated: function() {
0420 value = dropDownModel.indexOf(mainWindowCfg.qtQuickStyle)
0421 }
0422 onDeactivated: function() {
0423 mainWindowCfg.qtQuickStyle = dropDownModel[value]
0424 }
0425 }
0426 ]
0427 StackView.onActivated: activateAll()
0428 StackView.onDeactivated: deactivateAll()
0429 }
0430 }
0431
0432 Component {
0433 id: quickAccessFramesPage
0434 AbstractSettingsPage {
0435 title: qsTr("Quick Access Frames")
0436 visible: false
0437 StackView.onActivated: {
0438 var nameSelection = configs.tagConfig().selectedQuickAccessFrames()
0439 var len = Math.min(model.length, nameSelection.length), i
0440 for (i = 0; i < len; ++i) {
0441 model[i].name = nameSelection[i].name
0442 model[i].value = nameSelection[i].selected
0443 model[i].data = nameSelection[i].type
0444 }
0445 }
0446 StackView.onDeactivated: {
0447 var tagCfg = configs.tagConfig()
0448 var nameSelection = tagCfg.selectedQuickAccessFrames()
0449 var len = Math.min(model.length, nameSelection.length), i
0450 for (i = 0; i < len; ++i) {
0451 nameSelection[i].name = model[i].name
0452 nameSelection[i].selected = model[i].value
0453 nameSelection[i].type = model[i].data
0454 }
0455 tagCfg.setSelectedQuickAccessFrames(nameSelection)
0456 app.applyChangedConfiguration()
0457 }
0458 Component.onCompleted: {
0459 var nameSelection = configs.tagConfig().selectedQuickAccessFrames()
0460 var settingsModel = []
0461 var elementComponent = Qt.createComponent("SettingsElement.qml")
0462 for (var i = 0; i < nameSelection.length; ++i) {
0463 var elementObj = elementComponent.createObject(quickAccessFramesPage)
0464 elementObj.name = nameSelection[i].name
0465 settingsModel.push(elementObj)
0466 }
0467 model = settingsModel
0468 }
0469 }
0470 }
0471
0472 StringListEditPage {
0473 id: stringListEditPage
0474 property var onActivated
0475 property var onDeactivated
0476 visible: false
0477 StackView.onActivated: this.onActivated()
0478 StackView.onDeactivated: this.onDeactivated()
0479 }
0480 MapEditPage {
0481 id: mapEditPage
0482 property var onActivated
0483 property var onDeactivated
0484 visible: false
0485 StackView.onActivated: this.onActivated()
0486 StackView.onDeactivated: this.onDeactivated()
0487 }
0488 }