Integrated file selection dialogue with the main code. Improved the
[openvpnui.git] / qml / filebrowse / pages / FilePage.qml
diff --git a/qml/filebrowse/pages/FilePage.qml b/qml/filebrowse/pages/FilePage.qml
new file mode 100644 (file)
index 0000000..1519d41
--- /dev/null
@@ -0,0 +1,299 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import harbour.file.browser.FileInfo 1.0
+import QtMultimedia 5.0
+import "functions.js" as Functions
+import "../components"
+
+Page {
+    id: page
+    allowedOrientations: Orientation.All
+    property string file: "/"
+
+    FileInfo {
+        id: fileInfo
+        file: page.file
+
+        // called when open command exits
+        onProcessExited: {
+            if (exitCode === 0) {
+                notificationPanel.showTextWithTimer(qsTr("Open successful"),
+                                               qsTr("Sometimes the application stays in the background"));
+            } else if (exitCode === 1) {
+                notificationPanel.showTextWithTimer(qsTr("Internal error"),
+                                               "xdg-open exit code 1");
+            } else if (exitCode === 2) {
+                notificationPanel.showTextWithTimer(qsTr("File not found"),
+                                               page.file);
+            } else if (exitCode === 3) {
+                notificationPanel.showTextWithTimer(qsTr("No application to open the file"),
+                                               qsTr("xdg-open found no preferred application (3)"));
+            } else if (exitCode === 4) {
+                notificationPanel.showTextWithTimer(qsTr("Action failed"),
+                                               "xdg-open exit code 4");
+            } else if (exitCode === -88888) {
+                notificationPanel.showTextWithTimer(qsTr("xdg-open not found"), "");
+
+            } else if (exitCode === -99999) {
+                notificationPanel.showTextWithTimer(qsTr("xdg-open crash?"), "");
+
+            } else {
+                notificationPanel.showTextWithTimer(qsTr("xdg-open error"), "exit code: "+exitCode);
+            }
+        }
+    }
+
+    SilicaFlickable {
+        id: flickable
+        anchors.fill: parent
+        contentHeight: column.height
+        VerticalScrollDecorator { flickable: flickable }
+
+        PullDownMenu {
+            enabled: !fileInfo.isDir
+            visible: !fileInfo.isDir
+
+            MenuItem {
+                text: qsTr("Select")
+                visible: !fileInfo.isDir
+                onClicked: Functions.fileSelect(page.file)
+            }
+            MenuItem {
+                text: qsTr("View Contents")
+                visible: !fileInfo.isDir
+                onClicked: pageStack.push(Qt.resolvedUrl("ViewPage.qml"),
+                                          { path: page.file });
+            }
+
+            // file type specific menu items
+
+            MenuItem {
+                text: qsTr("Go to Target")
+                visible: fileInfo.icon === "folder-link"
+                onClicked: Functions.goToFolder(fileInfo.symLinkTarget);
+            }
+        }
+
+        Column {
+            id: column
+            anchors.left: parent.left
+            anchors.right: parent.right
+            anchors.leftMargin: Theme.paddingLarge
+            anchors.rightMargin: Theme.paddingLarge
+
+            PageHeader {
+                title: Functions.formatPathForTitle(fileInfo.absolutePath) + " " +
+                       Functions.unicodeBlackDownPointingTriangle()
+                MouseArea {
+                    anchors.fill: parent
+                    onClicked: dirPopup.show();
+                }
+            }
+
+            // file info texts, visible if error is not set
+            Column {
+                visible: fileInfo.errorMessage === ""
+                anchors.left: parent.left
+                anchors.right: parent.right
+
+                Image { // preview of image, max height 400
+                    id: imagePreview
+                    visible: isImageFile(fileInfo)
+                    source: visible ? fileInfo.file : "" // access the source only if img is visible
+                    anchors.left: parent.left
+                    anchors.right: parent.right
+                    height: implicitHeight < 400 && implicitHeight != 0 ? implicitHeight : 400
+                    width: parent.width
+                    fillMode: Image.PreserveAspectFit
+                    asynchronous: true
+                }
+                IconButton {
+                    id: playButton
+                    visible: isAudioFile(fileInfo)
+                    icon.source: audioPlayer.playbackState !== MediaPlayer.PlayingState ?
+                                     "image://theme/icon-l-play" :
+                                     "image://theme/icon-l-pause"
+                    anchors.horizontalCenter: parent.horizontalCenter
+                    onClicked: playAudio();
+                    MediaPlayer { // prelisten of audio
+                        id: audioPlayer
+                        source: ""
+                    }
+                }
+                Spacer { height: 10; visible: playButton.visible } // fix to playButton height
+                // clickable icon and filename
+                MouseArea {
+                    id: openButton
+                    width: parent.width
+                    height: openArea.height
+                    onClicked: openFile()
+
+                    Rectangle {
+                        anchors.fill: parent
+                        color: Theme.highlightColor
+                        opacity: 0.2
+                        visible: openButton.pressed
+                    }
+                    Column {
+                        id: openArea
+                        width: parent.width
+                        Image {
+                            id: icon
+                            anchors.topMargin: 6
+                            anchors.horizontalCenter: parent.horizontalCenter
+                            source: "../images/large-"+fileInfo.icon+".png"
+                            visible: !imagePreview.visible && !playButton.visible
+                        }
+                        Spacer { // spacing if image or play button is visible
+                            id: spacer
+                            height: 24
+                            visible: imagePreview.visible || playButton.visible
+                        }
+                        Label {
+                            id: filename
+                            width: parent.width
+                            text: fileInfo.name
+                            wrapMode: Text.Wrap
+                            horizontalAlignment: Text.AlignHCenter
+                        }
+                        Label {
+                            visible: fileInfo.symLinkTarget !== ""
+                            width: parent.width
+                            text: Functions.unicodeArrow()+" "+fileInfo.symLinkTarget
+                            wrapMode: Text.Wrap
+                            horizontalAlignment: Text.AlignHCenter
+                            font.pixelSize: Theme.fontSizeExtraSmall
+                        }
+                        Spacer { height: 20 }
+                    }
+                }
+                Spacer { height: 20 }
+
+                Label {
+                    visible: fileInfo.suffix === "apk" || fileInfo.suffix === "rpm" && !fileInfo.isDir
+                    width: parent.width
+                    text: qsTr("Installable packages may contain malware.")
+                    color: "red"
+                    font.pixelSize: Theme.fontSizeExtraSmall
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.Wrap
+                }
+                Spacer {
+                    visible: fileInfo.suffix === "apk" || fileInfo.suffix === "rpm" && !fileInfo.isDir
+                    height: 40
+                }
+
+                CenteredField {
+                    label: qsTr("Location")
+                    value: fileInfo.absolutePath
+                }
+                CenteredField {
+                    label: qsTr("Size")
+                    value: fileInfo.size
+                }
+                CenteredField {
+                    label: qsTr("Permissions")
+                    value: fileInfo.permissions
+                }
+                CenteredField {
+                    label: qsTr("Owner")
+                    value: fileInfo.owner
+                }
+                CenteredField {
+                    label: qsTr("Group")
+                    value: fileInfo.group
+                }
+                CenteredField {
+                    label: qsTr("Last modified")
+                    value: fileInfo.modified
+                }
+                CenteredField {
+                    label: qsTr("Created")
+                    value: fileInfo.created
+                }
+            }
+
+            // error label, visible if error message is set
+            Label {
+                visible: fileInfo.errorMessage !== ""
+                anchors.left: parent.left
+                anchors.right: parent.right
+                horizontalAlignment: Text.AlignHCenter
+                text: fileInfo.errorMessage
+                color: Theme.highlightColor
+                wrapMode: Text.Wrap
+            }
+        }
+    }
+
+    DirPopup {
+        id: dirPopup
+        anchors.fill: parent
+        menuTop: 100
+    }
+
+    NotificationPanel {
+        id: notificationPanel
+        page: page
+    }
+
+    function isImageFile(fileInfo)
+    {
+        if (fileInfo.isDir) return false;
+        return fileInfo.suffix === "jpg" || fileInfo.suffix === "jpeg" ||
+                fileInfo.suffix === "png" || fileInfo.suffix === "gif";
+    }
+
+    function isAudioFile(fileInfo)
+    {
+        if (fileInfo.isDir) return false;
+        return fileInfo.suffix === "wav" || fileInfo.suffix === "mp3" ||
+                fileInfo.suffix === "ogg" || fileInfo.suffix === "flac" ||
+                fileInfo.suffix === "aac" || fileInfo.suffix === "m4a";
+    }
+
+    function isVideoFile(fileInfo)
+    {
+        if (fileInfo.isDir) return false;
+        return fileInfo.suffix === "mp4" || fileInfo.suffix === "m4v";
+    }
+
+    function isMediaFile(fileInfo)
+    {
+        if (fileInfo.isDir) return false;
+        return isAudioFile(fileInfo) | isVideoFile(fileInfo);
+    }
+
+    function openFile()
+    {
+        // perform action depending on file type
+        if (fileInfo.icon === "folder-link") {
+            Functions.goToFolder(fileInfo.symLinkTarget);
+
+        } else if (fileInfo.isDir) {
+            Functions.goToFolder(fileInfo.file);
+
+        } else if (isAudioFile(fileInfo)) {
+            playAudio();
+
+        } else if (isImageFile(fileInfo) || isVideoFile(fileInfo)) {
+            fileInfo.executeCommand("xdg-open", [ page.file ])
+
+        } else {
+            pageStack.push(Qt.resolvedUrl("ViewPage.qml"), { path: page.file });
+        }
+    }
+
+    function playAudio()
+    {
+        if (audioPlayer.playbackState !== MediaPlayer.PlayingState) {
+            audioPlayer.source = fileInfo.file;
+            audioPlayer.play();
+        } else {
+            audioPlayer.stop();
+        }
+    }
+
+}
+
+