Integrated file selection dialogue with the main code. Improved the
[openvpnui.git] / qml / filebrowse / pages / FilePage.qml
1 import QtQuick 2.0
2 import Sailfish.Silica 1.0
3 import harbour.file.browser.FileInfo 1.0
4 import QtMultimedia 5.0
5 import "functions.js" as Functions
6 import "../components"
7
8 Page {
9     id: page
10     allowedOrientations: Orientation.All
11     property string file: "/"
12
13     FileInfo {
14         id: fileInfo
15         file: page.file
16
17         // called when open command exits
18         onProcessExited: {
19             if (exitCode === 0) {
20                 notificationPanel.showTextWithTimer(qsTr("Open successful"),
21                                                qsTr("Sometimes the application stays in the background"));
22             } else if (exitCode === 1) {
23                 notificationPanel.showTextWithTimer(qsTr("Internal error"),
24                                                "xdg-open exit code 1");
25             } else if (exitCode === 2) {
26                 notificationPanel.showTextWithTimer(qsTr("File not found"),
27                                                page.file);
28             } else if (exitCode === 3) {
29                 notificationPanel.showTextWithTimer(qsTr("No application to open the file"),
30                                                qsTr("xdg-open found no preferred application (3)"));
31             } else if (exitCode === 4) {
32                 notificationPanel.showTextWithTimer(qsTr("Action failed"),
33                                                "xdg-open exit code 4");
34             } else if (exitCode === -88888) {
35                 notificationPanel.showTextWithTimer(qsTr("xdg-open not found"), "");
36
37             } else if (exitCode === -99999) {
38                 notificationPanel.showTextWithTimer(qsTr("xdg-open crash?"), "");
39
40             } else {
41                 notificationPanel.showTextWithTimer(qsTr("xdg-open error"), "exit code: "+exitCode);
42             }
43         }
44     }
45
46     SilicaFlickable {
47         id: flickable
48         anchors.fill: parent
49         contentHeight: column.height
50         VerticalScrollDecorator { flickable: flickable }
51
52         PullDownMenu {
53             enabled: !fileInfo.isDir
54             visible: !fileInfo.isDir
55
56             MenuItem {
57                 text: qsTr("Select")
58                 visible: !fileInfo.isDir
59                 onClicked: Functions.fileSelect(page.file)
60             }
61             MenuItem {
62                 text: qsTr("View Contents")
63                 visible: !fileInfo.isDir
64                 onClicked: pageStack.push(Qt.resolvedUrl("ViewPage.qml"),
65                                           { path: page.file });
66             }
67
68             // file type specific menu items
69
70             MenuItem {
71                 text: qsTr("Go to Target")
72                 visible: fileInfo.icon === "folder-link"
73                 onClicked: Functions.goToFolder(fileInfo.symLinkTarget);
74             }
75         }
76
77         Column {
78             id: column
79             anchors.left: parent.left
80             anchors.right: parent.right
81             anchors.leftMargin: Theme.paddingLarge
82             anchors.rightMargin: Theme.paddingLarge
83
84             PageHeader {
85                 title: Functions.formatPathForTitle(fileInfo.absolutePath) + " " +
86                        Functions.unicodeBlackDownPointingTriangle()
87                 MouseArea {
88                     anchors.fill: parent
89                     onClicked: dirPopup.show();
90                 }
91             }
92
93             // file info texts, visible if error is not set
94             Column {
95                 visible: fileInfo.errorMessage === ""
96                 anchors.left: parent.left
97                 anchors.right: parent.right
98
99                 Image { // preview of image, max height 400
100                     id: imagePreview
101                     visible: isImageFile(fileInfo)
102                     source: visible ? fileInfo.file : "" // access the source only if img is visible
103                     anchors.left: parent.left
104                     anchors.right: parent.right
105                     height: implicitHeight < 400 && implicitHeight != 0 ? implicitHeight : 400
106                     width: parent.width
107                     fillMode: Image.PreserveAspectFit
108                     asynchronous: true
109                 }
110                 IconButton {
111                     id: playButton
112                     visible: isAudioFile(fileInfo)
113                     icon.source: audioPlayer.playbackState !== MediaPlayer.PlayingState ?
114                                      "image://theme/icon-l-play" :
115                                      "image://theme/icon-l-pause"
116                     anchors.horizontalCenter: parent.horizontalCenter
117                     onClicked: playAudio();
118                     MediaPlayer { // prelisten of audio
119                         id: audioPlayer
120                         source: ""
121                     }
122                 }
123                 Spacer { height: 10; visible: playButton.visible } // fix to playButton height
124                 // clickable icon and filename
125                 MouseArea {
126                     id: openButton
127                     width: parent.width
128                     height: openArea.height
129                     onClicked: openFile()
130
131                     Rectangle {
132                         anchors.fill: parent
133                         color: Theme.highlightColor
134                         opacity: 0.2
135                         visible: openButton.pressed
136                     }
137                     Column {
138                         id: openArea
139                         width: parent.width
140                         Image {
141                             id: icon
142                             anchors.topMargin: 6
143                             anchors.horizontalCenter: parent.horizontalCenter
144                             source: "../images/large-"+fileInfo.icon+".png"
145                             visible: !imagePreview.visible && !playButton.visible
146                         }
147                         Spacer { // spacing if image or play button is visible
148                             id: spacer
149                             height: 24
150                             visible: imagePreview.visible || playButton.visible
151                         }
152                         Label {
153                             id: filename
154                             width: parent.width
155                             text: fileInfo.name
156                             wrapMode: Text.Wrap
157                             horizontalAlignment: Text.AlignHCenter
158                         }
159                         Label {
160                             visible: fileInfo.symLinkTarget !== ""
161                             width: parent.width
162                             text: Functions.unicodeArrow()+" "+fileInfo.symLinkTarget
163                             wrapMode: Text.Wrap
164                             horizontalAlignment: Text.AlignHCenter
165                             font.pixelSize: Theme.fontSizeExtraSmall
166                         }
167                         Spacer { height: 20 }
168                     }
169                 }
170                 Spacer { height: 20 }
171
172                 Label {
173                     visible: fileInfo.suffix === "apk" || fileInfo.suffix === "rpm" && !fileInfo.isDir
174                     width: parent.width
175                     text: qsTr("Installable packages may contain malware.")
176                     color: "red"
177                     font.pixelSize: Theme.fontSizeExtraSmall
178                     horizontalAlignment: Text.AlignHCenter
179                     wrapMode: Text.Wrap
180                 }
181                 Spacer {
182                     visible: fileInfo.suffix === "apk" || fileInfo.suffix === "rpm" && !fileInfo.isDir
183                     height: 40
184                 }
185
186                 CenteredField {
187                     label: qsTr("Location")
188                     value: fileInfo.absolutePath
189                 }
190                 CenteredField {
191                     label: qsTr("Size")
192                     value: fileInfo.size
193                 }
194                 CenteredField {
195                     label: qsTr("Permissions")
196                     value: fileInfo.permissions
197                 }
198                 CenteredField {
199                     label: qsTr("Owner")
200                     value: fileInfo.owner
201                 }
202                 CenteredField {
203                     label: qsTr("Group")
204                     value: fileInfo.group
205                 }
206                 CenteredField {
207                     label: qsTr("Last modified")
208                     value: fileInfo.modified
209                 }
210                 CenteredField {
211                     label: qsTr("Created")
212                     value: fileInfo.created
213                 }
214             }
215
216             // error label, visible if error message is set
217             Label {
218                 visible: fileInfo.errorMessage !== ""
219                 anchors.left: parent.left
220                 anchors.right: parent.right
221                 horizontalAlignment: Text.AlignHCenter
222                 text: fileInfo.errorMessage
223                 color: Theme.highlightColor
224                 wrapMode: Text.Wrap
225             }
226         }
227     }
228
229     DirPopup {
230         id: dirPopup
231         anchors.fill: parent
232         menuTop: 100
233     }
234
235     NotificationPanel {
236         id: notificationPanel
237         page: page
238     }
239
240     function isImageFile(fileInfo)
241     {
242         if (fileInfo.isDir) return false;
243         return fileInfo.suffix === "jpg" || fileInfo.suffix === "jpeg" ||
244                 fileInfo.suffix === "png" || fileInfo.suffix === "gif";
245     }
246
247     function isAudioFile(fileInfo)
248     {
249         if (fileInfo.isDir) return false;
250         return fileInfo.suffix === "wav" || fileInfo.suffix === "mp3" ||
251                 fileInfo.suffix === "ogg" || fileInfo.suffix === "flac" ||
252                 fileInfo.suffix === "aac" || fileInfo.suffix === "m4a";
253     }
254
255     function isVideoFile(fileInfo)
256     {
257         if (fileInfo.isDir) return false;
258         return fileInfo.suffix === "mp4" || fileInfo.suffix === "m4v";
259     }
260
261     function isMediaFile(fileInfo)
262     {
263         if (fileInfo.isDir) return false;
264         return isAudioFile(fileInfo) | isVideoFile(fileInfo);
265     }
266
267     function openFile()
268     {
269         // perform action depending on file type
270         if (fileInfo.icon === "folder-link") {
271             Functions.goToFolder(fileInfo.symLinkTarget);
272
273         } else if (fileInfo.isDir) {
274             Functions.goToFolder(fileInfo.file);
275
276         } else if (isAudioFile(fileInfo)) {
277             playAudio();
278
279         } else if (isImageFile(fileInfo) || isVideoFile(fileInfo)) {
280             fileInfo.executeCommand("xdg-open", [ page.file ])
281
282         } else {
283             pageStack.push(Qt.resolvedUrl("ViewPage.qml"), { path: page.file });
284         }
285     }
286
287     function playAudio()
288     {
289         if (audioPlayer.playbackState !== MediaPlayer.PlayingState) {
290             audioPlayer.source = fileInfo.file;
291             audioPlayer.play();
292         } else {
293             audioPlayer.stop();
294         }
295     }
296
297 }
298
299