--- /dev/null
+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();
+ }
+ }
+
+}
+
+