1/**
2 * \file MainPage.qml
3 * Main page.
4 *
5 * \b Project: Kid3
6 * \author Urs Fleisch
7 * \date 16 Feb 2015
8 *
9 * Copyright (C) 2015-2018  Urs Fleisch
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; version 3.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24import QtQuick 2.11
25import QtQuick.Controls 2.4
26
27Page {
28  id: page
29
30  signal confirmedOpenRequested(string path)
31  signal saveRequested(variant onCompleted)
32
33  function updateCurrentSelection() {
34    collapsibleV1.acceptEdit()
35    collapsibleV2.acceptEdit()
36    collapsibleV3.acceptEdit()
37    app.frameModelsToTags()
38    if (app.selectionInfo.singleFileSelected) {
39      app.selectionInfo.fileName = collapsibleFile.fileName
40    }
41  }
42
43  function currentFilePath() {
44    return fileList.currentFilePath()
45  }
46
47  title: (app.dirName.split("/").pop() || "/") +
48         (app.modified ? qsTr(" [modified]") : "") +
49         (app.filtered ? qsTr(" [filtered %1/%2]")
50             .arg(app.filterPassedCount).arg(app.filterTotalCount) : "") +
51         " - Kid3"
52
53  Shortcut {
54    sequence: "Menu"
55    onActivated: menu.open()
56  }
57
58  header: ToolBar {
59    height: constants.controlHeight
60    IconButton {
61      id: prevButton
62      anchors.left: parent.left
63      anchors.verticalCenter: parent.verticalCenter
64      iconName: page.StackView.view.depth > 1 ? "go-previous"
65                                              : "drawer";
66      color: titleLabel.color
67      width: height
68      onClicked: {
69        if (page.StackView.view.depth > 1) {
70          page.StackView.view.pop()
71        } else if (drawer.position === 1.0) {
72          drawer.close()
73        } else {
74          drawer.open()
75        }
76      }
77    }
78    Label {
79      id: titleLabel
80      anchors.left: prevButton.right
81      anchors.right: buttonRow.left
82      anchors.verticalCenter: parent.verticalCenter
83      clip: true
84      text: page.title
85      MouseArea {
86        anchors.fill: parent
87        onPressAndHold: {
88          openDialog.folder = app.dirName
89          openDialog.open()
90        }
91
92        FileSelectDialog {
93          id: openDialog
94          parent: Overlay.overlay
95          title: qsTr("Open")
96          onFinished: if (path) confirmedOpenRequested(path)
97        }
98      }
99    }
100    Row {
101      id: buttonRow
102      anchors.right: parent.right
103      anchors.verticalCenter: parent.verticalCenter
104      spacing: constants.spacing
105      IconButton {
106        iconName: "go-up"
107        color: titleLabel.color
108        width: height
109        onClicked: {
110          var parentDir = fileList.parentFilePath()
111          if (parentDir) {
112            confirmedOpenDirectory(parentDir)
113          }
114        }
115      }
116      IconButton {
117        property bool selectAll: true
118        iconName: "select"
119        color: titleLabel.color
120        width: height
121        onClicked: {
122          if (selectAll) {
123            app.selectAllFiles()
124          } else {
125            app.deselectAllFiles()
126          }
127          selectAll = !selectAll
128        }
129      }
130      IconButton {
131        id: previousButton
132        iconName: "go-previous"
133        color: titleLabel.color
134        visible: body.state != "narrow" || drawer.position === 0.0
135        width: height
136        onClicked: app.previousFile(true, true)
137      }
138      IconButton {
139        iconName: "go-next"
140        color: titleLabel.color
141        visible: previousButton.visible
142        width: height
143        onClicked: app.nextFile(true, true)
144      }
145      IconButton {
146        id: menuButton
147        iconName: "navigation-menu"
148        color: titleLabel.color
149        width: height
150        onClicked: menu.open()
151        Menu {
152          id: menu
153          width: constants.gu(35)
154          MenuItem {
155            text: qsTr("About")
156            onTriggered: aboutDialog.open()
157
158            AboutDialog {
159              id: aboutDialog
160              parent: Overlay.overlay
161            }
162          }
163          MenuItem {
164            text: qsTr("Open")
165            onTriggered: {
166              openDialog.folder = app.dirName
167              openDialog.open()
168            }
169          }
170          MenuItem {
171            text: qsTr("Save")
172            onTriggered: {
173              app.frameModelsToTags()
174              saveRequested(function() {
175                app.tagsToFrameModels()
176              })
177            }
178          }
179          MenuItem {
180            text: qsTr("Settings")
181            onTriggered: page.StackView.view.push(settingsPage)
182
183            SettingsPage {
184              id: settingsPage
185              visible: false
186            }
187          }
188          MenuItem {
189            text: qsTr("Automatic Import")
190            onTriggered: page.StackView.view.push(batchImportPage)
191
192            BatchImportPage {
193              id: batchImportPage
194              visible: false
195            }
196          }
197          MenuItem {
198            text: qsTr("Create Playlist")
199            onTriggered: app.writePlaylist()
200          }
201          MenuItem {
202            text: qsTr("Rename Folder")
203            onTriggered: page.StackView.view.push(renameDirPage)
204
205            RenameDirectoryPage {
206              id: renameDirPage
207              visible: false
208            }
209          }
210          MenuItem {
211            text: qsTr("Number Tracks")
212            onTriggered: numberTracksDialog.open()
213
214            NumberTracksDialog {
215              id: numberTracksDialog
216              parent: Overlay.overlay
217            }
218          }
219          MenuItem {
220            text: qsTr("Filter")
221            onTriggered: page.StackView.view.push(filterPage)
222
223            FilterPage {
224              id: filterPage
225              visible: false
226            }
227          }
228          MenuItem {
229            text: qsTr("Apply Filename Format")
230            onTriggered: app.applyFilenameFormat()
231          }
232          MenuItem {
233            text: qsTr("Apply Tag Format")
234            onTriggered: app.applyTagFormat()
235          }
236          MenuItem {
237            text: qsTr("Apply Text Encoding")
238            onTriggered: app.applyTextEncoding()
239          }
240          MenuItem {
241            text: qsTr("Convert ID3v2.3 to ID3v2.4")
242            onTriggered: app.convertToId3v24()
243          }
244          MenuItem {
245            text: qsTr("Convert ID3v2.4 to ID3v2.3")
246            onTriggered: app.convertToId3v23()
247          }
248          MenuItem {
249            text: qsTr("Revert")
250            onTriggered: app.revertFileModifications()
251          }
252          MenuItem {
253            text: qsTr("Quit")
254            onTriggered: confirmedQuit()
255          }
256
257        }
258      }
259    }
260  }
261  Item {
262    id: body
263
264    property int rightSideSpace: width - drawer.width
265
266    anchors.fill: parent
267
268    Drawer {
269      id: drawer
270      y: header.height
271      width: Math.min(constants.gu(44), body.width - constants.gu(4))
272      height: parent.height - y
273      modal: false
274      interactive: false
275
276      FileList {
277        id: fileList
278        color: constants.baseColor
279        anchors.fill: parent
280
281        onFileActivated: {
282          if (body.state === "narrow") {
283            drawer.close()
284          }
285        }
286      }
287    }
288
289    Rectangle {
290      id: rightSide
291
292      color: constants.baseColor
293      anchors.right: parent.right
294      anchors.top: parent.top
295      anchors.bottom: parent.bottom
296      width: body.width - drawer.width * drawer.position
297
298      Flickable {
299        id: rightSideFlickable
300        anchors.fill: parent
301        contentWidth: width
302        contentHeight: collapsibleColumn.height
303        clip: true
304        Column {
305          id: collapsibleColumn
306          width: parent.width
307
308          FileCollapsible {
309            id: collapsibleFile
310            anchors.topMargin: constants.margins
311            anchors.left: parent.left
312            anchors.right: parent.right
313          }
314
315          TagCollapsible {
316            id: collapsibleV1
317            tagNr: 0
318            anchors.topMargin: constants.margins
319            anchors.left: parent.left
320            anchors.right: parent.right
321          }
322
323          TagCollapsible {
324            id: collapsibleV2
325            tagNr: 1
326            anchors.topMargin: constants.margins
327            anchors.left: parent.left
328            anchors.right: parent.right
329          }
330
331          TagCollapsible {
332            id: collapsibleV3
333            tagNr: 2
334            anchors.topMargin: constants.margins
335            anchors.left: parent.left
336            anchors.right: parent.right
337          }
338
339          PictureCollapsible {
340            id: collapsiblePicture
341            anchors.topMargin: constants.margins
342            anchors.left: parent.left
343            anchors.right: parent.right
344          }
345        }
346      }
347    }
348
349    states: [
350      State {
351        name: ""
352        StateChangeScript {
353          script: drawer.open()
354        }
355      },
356      State {
357        name: "hidden"
358        when: page.StackView.view.depth > 1
359        StateChangeScript {
360          script: drawer.close()
361        }
362      },
363      State {
364        name: "narrow"
365        when: body.rightSideSpace < constants.gu(45)
366        PropertyChanges {
367          target: drawer
368          interactive: page.StackView.view.depth === 1
369        }
370        PropertyChanges {
371          target: rightSide
372          width: body.width
373        }
374      }
375    ]
376  }
377}
378