Warning, /multimedia/kid3/src/qml/app/FrameEditDialog.qml is written in an unsupported language. File is not indexed.

0001 /**
0002  * \file FrameEditDialog.qml
0003  * Dialog to edit frames.
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 Kid3 1.1 as Kid3
0027 
0028 Dialog {
0029   id: page
0030 
0031   property QtObject frameObject
0032   property string imageSource
0033   signal frameEdited(variant frame)
0034 
0035   modal: true
0036   width: Math.min(parent.width, constants.gu(70))
0037   x: (parent.width - width) / 2
0038   y: 0
0039   standardButtons: Dialog.Ok | Dialog.Cancel
0040 
0041   function openFrame(frame) {
0042     page.title = frame.internalName
0043     fieldList.model = frame.fields
0044     frameObject = frame
0045     page.open()
0046     if (frame.type === Kid3.Frame.FT_Picture) {
0047       app.setCoverArtImageData(frame.getBinaryData())
0048     }
0049   }
0050 
0051   Component {
0052     id: textLineEdit
0053     TextField {
0054       text: _modelData.value
0055       selectByMouse: true
0056       onAccepted: {
0057         focus = false
0058       }
0059       onActiveFocusChanged: {
0060         if (!activeFocus) {
0061           _modelData.value = text
0062         }
0063       }
0064     }
0065   }
0066 
0067   Component {
0068     id: textEdit
0069 
0070     Row {
0071       width: parent.width
0072 
0073       Frame {
0074         // Some space is left on the right side for flicking on a touch device.
0075         width: parent.width - (fieldList.atYBeginning ? 0 : constants.gu(6))
0076         TextArea {
0077           id: textArea
0078           width: parent.width
0079           text: _modelData.value
0080           selectByMouse: true
0081           wrapMode: TextEdit.Wrap
0082           onActiveFocusChanged: {
0083             if (!activeFocus) {
0084               _modelData.value = text
0085             }
0086           }
0087         }
0088       }
0089     }
0090   }
0091 
0092   Component {
0093     id: comboBoxEdit
0094 
0095     ComboBox {
0096       model: if (_modelData.id === Kid3.Frame.ID_TextEnc)
0097                script.getTextEncodingNames()
0098              else if (_modelData.id === Kid3.Frame.ID_PictureType)
0099                script.getPictureTypeNames()
0100              else if (_modelData.id === Kid3.Frame.ID_TimestampFormat)
0101                script.getTimestampFormatNames()
0102              else if (_modelData.id === Kid3.Frame.ID_ContentType)
0103                script.getContentTypeNames()
0104       currentIndex: _modelData.value
0105       onCurrentIndexChanged: _modelData.value = currentIndex
0106     }
0107   }
0108 
0109   MessageDialog {
0110     signal completed(bool ok)
0111 
0112     id: confirmOverwriteDialog
0113     width: Math.min(parent.width, constants.gu(70))
0114     x: (parent.width - width) / 2
0115     y: parent.height / 6
0116     parent: page.parent  // Overlay.overlay
0117     title: qsTr("Warning")
0118     text: qsTr("File already exists. Overwrite?")
0119     standardButtons: Dialog.Yes | Dialog.No
0120     onYes: completed(true)
0121     onNo: completed(false)
0122   }
0123 
0124   Component {
0125     id: exportFileSelectDialog
0126     FileSelectDialog {
0127       property variant field
0128       parent: page.parent  // Overlay.overlay
0129       title: qsTr("Export")
0130       saveMode: true
0131       nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.JPG", "*.JPEG", "*.PNG"]
0132       onFinished: {
0133         if (path) {
0134           if (script.fileExists(path)) {
0135             function writeIfOk(ok) {
0136               confirmOverwriteDialog.completed.disconnect(writeIfOk)
0137               if (ok) {
0138                 script.writeFile(path, field.value)
0139               }
0140             }
0141 
0142             confirmOverwriteDialog.completed.connect(writeIfOk)
0143             confirmOverwriteDialog.open()
0144           } else {
0145             script.writeFile(path, field.value)
0146           }
0147         }
0148       }
0149     }
0150   }
0151 
0152   Component {
0153     id: importFileSelectDialog
0154     FileSelectDialog {
0155       property variant field
0156       parent: page.parent  // Overlay.overlay
0157       title: qsTr("Import")
0158       nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.JPG", "*.JPEG", "*.PNG"]
0159       onFinished: {
0160         if (path) {
0161           field.value = script.readFile(path)
0162           page.imageSource = "file://" + path
0163         } else {
0164           page.imageSource = app.coverArtImageId
0165         }
0166       }
0167     }
0168   }
0169 
0170   Component {
0171     id: imageView
0172 
0173     Column {
0174       width: parent.width
0175       spacing: constants.spacing
0176 
0177       Button {
0178         id: importButton
0179         width: parent.width
0180         text: qsTr("Import")
0181         onClicked: {
0182           var coverFileName = configs.fileConfig().defaultCoverFileName
0183           if (coverFileName.indexOf("%") !== -1) {
0184             coverFileName = app.selectionInfo.formatString(Kid3.Frame.TagV2V1,
0185                                                            coverFileName)
0186           }
0187           constants.openPopup(importFileSelectDialog, importButton,
0188                         {"folder": app.dirName,
0189                          "currentFile": coverFileName,
0190                          "field": _modelData})
0191         }
0192       }
0193 
0194       Button {
0195         id: exportButton
0196         width: parent.width
0197         text: qsTr("Export")
0198 
0199         onClicked: {
0200           var coverFileName = configs.fileConfig().defaultCoverFileName
0201           if (coverFileName.indexOf("%") !== -1) {
0202             coverFileName = app.selectionInfo.formatString(Kid3.Frame.TagV2V1,
0203                                                            coverFileName)
0204           }
0205           constants.openPopup(exportFileSelectDialog, exportButton,
0206                         {"folder": app.dirName,
0207                          "currentFile": coverFileName,
0208                          "field": _modelData})
0209         }
0210       }
0211 
0212       Item {
0213         id: imageItem
0214         width: parent.width
0215         height: 120
0216         Image {
0217           anchors.fill: parent
0218           fillMode: Image.PreserveAspectFit
0219           source: page.imageSource
0220           cache: false
0221         }
0222       }
0223     }
0224   }
0225 
0226   contentItem: ListView {
0227     id: fieldList
0228     clip: true
0229 
0230     // height: someFunction(contentHeight) will report a binding loop,
0231     // therefore the height is updated manually.
0232     function updateHeight() {
0233       /// TODO: Calculate button height instead of 145.
0234       page.height = Math.min(contentHeight + 145,
0235                         page.parent.height -
0236                         3 * constants.rowHeight -
0237                         3 * constants.margins)
0238     }
0239     onVisibleChanged: if (visible) updateHeight()
0240     onContentHeightChanged: updateHeight()
0241 
0242     delegate: Column {
0243       width: parent.width
0244       spacing: constants.spacing
0245       Label {
0246         id: nameLabel
0247         text: modelData.name
0248       }
0249 
0250       Loader {
0251         width: parent.width
0252         property QtObject _modelData: modelData
0253         sourceComponent:
0254             if (typeof modelData.value === "number")
0255               if (modelData.id === Kid3.Frame.ID_TextEnc ||
0256                   modelData.id === Kid3.Frame.ID_PictureType ||
0257                   modelData.id === Kid3.Frame.ID_TimestampFormat ||
0258                   modelData.id === Kid3.Frame.ID_ContentType)
0259                 comboBoxEdit
0260               else
0261                 textLineEdit
0262             else if (typeof modelData.value === "string")
0263               if (modelData.id === Kid3.Frame.ID_Text)
0264                 textEdit
0265               else
0266                 textLineEdit
0267             else if (typeof modelData.value === "object")
0268               if (modelData.id === Kid3.Frame.ID_Data &&
0269                   modelData.type === Kid3.Frame.FT_Picture)
0270                 imageView
0271       }
0272       ThinDivider {
0273         anchors {
0274           left: parent.left
0275           right: parent.right
0276         }
0277         visible: index != fieldList.count - 1
0278       }
0279     }
0280   }
0281 
0282   onOpened: {
0283     page.imageSource = app.coverArtImageId
0284   }
0285   onRejected: {
0286     page.close()
0287     page.frameEdited(null)
0288     frameObject = null
0289   }
0290   onAccepted: {
0291     fieldList.focus = false // to force editingFinished on delegate
0292     page.close()
0293     page.frameEdited(frameObject)
0294     // To force update of picture collapsible
0295     if (frameObject.type === Kid3.Frame.FT_Picture) {
0296       app.setCoverArtImageData(frameObject.getBinaryData())
0297     }
0298     frameObject = null
0299   }
0300 }