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 }