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 }