Warning, /multimedia/kid3/src/qml/app/Main.qml is written in an unsupported language. File is not indexed.
0001 /** 0002 * \file Main.qml 0003 * Main entry point for QML application. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 16 Feb 2015 0008 * 0009 * Copyright (C) 2015-2018 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 import QtQuick.Controls.Material 2.4 0027 import QtQml 2.11 0028 import Kid3 1.1 as Kid3 0029 0030 ApplicationWindow { 0031 id: root 0032 visible: true 0033 visibility: Qt.platform.os === "android" ? "FullScreen" : "Windowed" 0034 objectName: "mainView" 0035 title: "Kid3" 0036 width: constants.gu(100) 0037 height: constants.gu(100) 0038 0039 FontLoader { 0040 id: materialFont 0041 source: "../icons/kid3material.ttf" 0042 } 0043 0044 UiConstants { 0045 id: constants 0046 } 0047 0048 Kid3.FrameEditorObject { 0049 id: frameEditor 0050 } 0051 0052 Kid3.ScriptUtils { 0053 id: script 0054 } 0055 0056 Kid3.ConfigObjects { 0057 id: configs 0058 } 0059 0060 FrameSelectDialog { 0061 id: frameSelectDialog 0062 parent: Overlay.overlay 0063 0064 onFrameSelected: frameEditor.onFrameSelectionFinished(name) 0065 0066 Connections { 0067 target: frameEditor 0068 onFrameSelectionRequested: frameSelectDialog.openFrameNames(frameNames) 0069 } 0070 } 0071 0072 FrameEditDialog { 0073 id: frameEditDialog 0074 parent: Overlay.overlay 0075 onFrameEdited: frameEditor.onFrameEditFinished(frame) 0076 0077 Connections { 0078 target: frameEditor 0079 onFrameEditRequested: frameEditDialog.openFrame(frame) 0080 } 0081 } 0082 0083 MessageDialog { 0084 property bool doNotRevert: false 0085 0086 signal completed(bool ok) 0087 0088 id: saveModifiedDialog 0089 x: (parent.width - width) / 2 0090 y: parent.height / 6 0091 parent: Overlay.overlay 0092 title: qsTr("Warning") 0093 text: qsTr("The current folder has been modified.\nDo you want to save it?") 0094 onYes: { 0095 saveDirectory(function() { 0096 completed(true) 0097 }) 0098 } 0099 onNo: { 0100 if (!doNotRevert) { 0101 app.deselectAllFiles() 0102 app.revertFileModifications() 0103 } 0104 completed(true) 0105 } 0106 onCancel: completed(false) 0107 0108 // Open dialog if any file modified. 0109 // completed(ok) is signalled with false if canceled. 0110 function openIfModified() { 0111 if (app.modified && app.dirName) { 0112 open() 0113 } else { 0114 completed(true) 0115 } 0116 } 0117 } 0118 0119 MessageDialog { 0120 property var errorMsgs: [] 0121 0122 signal completed() 0123 0124 id: writeErrorDialog 0125 x: (parent.width - width) / 2 0126 y: parent.height / 6 0127 parent: Overlay.overlay 0128 title: qsTr("File Error") 0129 text: qsTr("Error while writing file:\n") + errorMsgs.join("\n") 0130 standardButtons: Dialog.Close 0131 onClosed: { 0132 completed() 0133 } 0134 } 0135 0136 MessageDialog { 0137 property string externalFilesDir 0138 0139 signal completed() 0140 0141 id: sdCardErrorDialog 0142 x: (parent.width - width) / 2 0143 y: parent.height / 6 0144 parent: Overlay.overlay 0145 title: qsTr("File Error") 0146 text: qsTr("SD card is only writable in %1").arg(externalFilesDir) 0147 standardButtons: Dialog.Close 0148 onClosed: { 0149 completed() 0150 } 0151 } 0152 0153 MessageDialog { 0154 property var errorMsgs: [] 0155 0156 signal completed(bool ok) 0157 0158 id: changePermissionsDialog 0159 x: (parent.width - width) / 2 0160 y: parent.height / 6 0161 parent: Overlay.overlay 0162 title: qsTr("File Error") 0163 text: qsTr("Error while writing file. Do you want to change the permissions?") 0164 + "\n" + errorMsgs.join("\n") 0165 standardButtons: Dialog.Yes | Dialog.No 0166 onYes: { 0167 completed(true) 0168 } 0169 onNo: { 0170 completed(false) 0171 } 0172 } 0173 0174 Shortcut { 0175 sequences: ["Esc", "Back"] 0176 enabled: pageStack.depth > 1 0177 onActivated: { 0178 pageStack.pop() 0179 } 0180 } 0181 0182 StackView { 0183 id: pageStack 0184 initialItem: mainPage 0185 anchors.fill: parent 0186 0187 MainPage { 0188 id: mainPage 0189 visible: false 0190 parent: Overlay.overlay 0191 onConfirmedOpenRequested: confirmedOpenDirectory(path) 0192 onSaveRequested: saveDirectory(onCompleted) 0193 } 0194 } 0195 0196 Text { 0197 visible: false 0198 Component.onCompleted: { 0199 // Linux Desktop: pixelSize 12 => gu = 8 0200 // Android Emulator Galaxy Nexus: 32 => gu = 21 0201 constants.gridUnit = Math.max(8 * font.pixelSize / 12, 8) 0202 constants.titlePixelSize = 18 * font.pixelSize / 12 0203 constants.imageScaleFactor = Math.max(font.pixelSize / 12.0, 1.0) 0204 } 0205 } 0206 0207 Component.onCompleted: { 0208 app.frameEditor = frameEditor 0209 app.readConfig() 0210 var path = configs.fileConfig().lastOpenedFile 0211 if (!path || !script.fileExists(path)) { 0212 path = script.musicPath() 0213 } 0214 app.openDirectory(path) 0215 if (mainPage.Material) { 0216 constants.highlightColor = mainPage.Material.primary 0217 constants.highlightedTextColor = mainPage.Material.foreground 0218 constants.textColor = mainPage.Material.foreground 0219 constants.baseColor = mainPage.Material.background 0220 } 0221 } 0222 0223 Component.onDestruction: { 0224 app.frameEditor = null 0225 } 0226 0227 Connections { 0228 target: app 0229 0230 onConfirmedOpenDirectoryRequested: confirmedOpenDirectory(paths) 0231 onFileSelectionUpdateRequested: mainPage.updateCurrentSelection() 0232 onSelectedFilesUpdated: app.tagsToFrameModels() 0233 onSelectedFilesChanged: app.tagsToFrameModels() 0234 } 0235 Connections { 0236 target: app.downloadClient 0237 onDownloadFinished: app.imageDownloaded(data, contentType, url) 0238 } 0239 0240 DropArea { 0241 anchors.fill: parent 0242 onDropped: { 0243 if (drop.hasUrls) { 0244 app.openDropUrls(drop.urls) 0245 } 0246 } 0247 } 0248 0249 function saveDirectory(onCompleted) { 0250 var errorFiles = app.saveDirectory() 0251 var numErrorFiles = errorFiles.length 0252 if (numErrorFiles > 0) { 0253 var errorMsgs = [], notWritableFiles = [] 0254 for (var i = 0; i < numErrorFiles; i++) { 0255 var errorFile = errorFiles[i] 0256 var slashPos = errorFile.lastIndexOf("/") 0257 var fileName = slashPos !== -1 ? errorFile.substr(slashPos + 1) 0258 : errorFile 0259 if (!script.fileIsWritable(errorFile)) { 0260 errorMsgs.push(qsTr("%1 is not writable").arg(fileName)) 0261 notWritableFiles.push(errorFile) 0262 } else { 0263 errorMsgs.push(fileName) 0264 } 0265 } 0266 if (notWritableFiles.length === 0) { 0267 function resultReceived() { 0268 writeErrorDialog.completed.disconnect(resultReceived) 0269 if (onCompleted) { 0270 onCompleted(); 0271 } 0272 } 0273 writeErrorDialog.errorMsgs = errorMsgs 0274 writeErrorDialog.completed.connect(resultReceived) 0275 writeErrorDialog.open() 0276 } else if (Qt.platform.os === "android" && 0277 notWritableFiles[0].substr(0, 19) !== "/storage/emulated/0" && 0278 notWritableFiles[0].substr(0, 9) === "/storage/" && 0279 notWritableFiles[0].indexOf( 0280 "Android/data/net.sourceforge.kid3/") === -1) { 0281 var externalFilesDir = notWritableFiles[0].substr( 0282 0, notWritableFiles[0].indexOf("/", 9) + 1) + 0283 "Android/data/net.sourceforge.kid3/" 0284 if (!script.fileExists(externalFilesDir)) { 0285 script.makeDir(externalFilesDir) 0286 } 0287 function resultReceived() { 0288 sdCardErrorDialog.completed.disconnect(resultReceived) 0289 if (onCompleted) { 0290 onCompleted(); 0291 } 0292 } 0293 sdCardErrorDialog.externalFilesDir = externalFilesDir 0294 sdCardErrorDialog.completed.connect(resultReceived) 0295 sdCardErrorDialog.open() 0296 } else { 0297 function resultReceived(ok) { 0298 changePermissionsDialog.completed.disconnect(resultReceived) 0299 if (ok) { 0300 for (var i = 0; i < notWritableFiles.length; i++) { 0301 var errorFile = notWritableFiles[i] 0302 var perms = script.getFilePermissions(errorFile) 0303 script.setFilePermissions(errorFile, perms | 0x0200) 0304 } 0305 // Try again 0306 app.saveDirectory() 0307 } 0308 if (onCompleted) { 0309 onCompleted(); 0310 } 0311 } 0312 changePermissionsDialog.errorMsgs = errorMsgs 0313 changePermissionsDialog.completed.connect(resultReceived) 0314 changePermissionsDialog.open() 0315 } 0316 } else { 0317 if (onCompleted) { 0318 onCompleted(); 0319 } 0320 } 0321 } 0322 0323 function confirmedOpenDirectory(path) { 0324 function openIfCompleted(ok) { 0325 saveModifiedDialog.completed.disconnect(openIfCompleted) 0326 if (ok) { 0327 app.openDirectory(path) 0328 } 0329 } 0330 0331 mainPage.updateCurrentSelection() 0332 saveModifiedDialog.doNotRevert = false 0333 saveModifiedDialog.completed.connect(openIfCompleted) 0334 saveModifiedDialog.openIfModified() 0335 } 0336 0337 function confirmedQuit() { 0338 mainPage.updateCurrentSelection() 0339 saveModifiedDialog.doNotRevert = true 0340 saveModifiedDialog.completed.connect(quitIfCompleted) 0341 saveModifiedDialog.openIfModified() 0342 } 0343 0344 function quitIfCompleted(ok) { 0345 saveModifiedDialog.completed.disconnect(quitIfCompleted) 0346 if (ok) { 0347 var currentFile = mainPage.currentFilePath() 0348 if (currentFile) { 0349 configs.fileConfig().lastOpenedFile = currentFile 0350 } 0351 app.saveConfig() 0352 Qt.quit() 0353 } 0354 } 0355 0356 onClosing: { 0357 confirmedQuit() 0358 if (app.modified) { 0359 close.accepted = false 0360 } 0361 } 0362 }