Commit 24722008 authored by Karel Slaný's avatar Karel Slaný Committed by Martin Straka

Experimental version of QML-based file selection dialogue.

parent 1c44c904
......@@ -107,6 +107,7 @@ SOURCES += \
src/net/isds_wrapper.cpp \
src/net/net_layer.cpp \
src/net/xml_layer.cpp \
src/qml_interaction/interaction_filesystem.cpp \
src/qml_interaction/interaction_zfo_file.cpp \
src/qml_interaction/message_info.cpp \
src/settings.cpp \
......@@ -155,6 +156,7 @@ HEADERS += \
src/net/isds_wrapper.h \
src/net/net_layer.h \
src/net/xml_layer.h \
src/qml_interaction/interaction_filesystem.h \
src/qml_interaction/interaction_zfo_file.h \
src/qml_interaction/message_info.h \
src/settings.h \
......
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import Qt.labs.folderlistmodel 2.1
import cz.nic.mobileDatovka.qmlInteraction 1.0
Dialog {
id: root
focus: true
modal: true
title: ""
standardButtons: (selectedFileName != "") ? (Dialog.Ok | Dialog.Cancel) : Dialog.Cancel
/* Place the dialogue in the centre. */
x: parent.width / 2 - width / 2
y: parent.height / 2 - height / 2
signal finished(string path)
property string selectedFileName: ""
function raise() {
root.open()
}
function stripUrlPrefix(url) {
return url.toString().replace(/^(file:\/{2})/, "")
}
InteractionFilesystem {
id: interactionFilesystem
}
contentItem: ColumnLayout {
spacing: 6
RowLayout {
anchors {
left: parent.left;
right: parent.right;
}
spacing: 6
Button {
id: upButton
text: "<"
MouseArea {
anchors.fill: parent
onClicked: {
/* Navigate to parent folder. */
if (folderModel.parentFolder != "") {
folderModel.folder = folderModel.parentFolder
}
}
}
}
Text {
text: "file://"
}
TextField {
id: pathField
Layout.fillWidth: true
text: stripUrlPrefix(folderModel.folder)
onEditingFinished: {
/* Navigate to supplied location if location exists. */
var path = interactionFilesystem.absoluteDirPath(text)
if (path != "") {
folderModel.folder = "file://" + path
} else {
path = interactionFilesystem.absolutePath(text)
if (path != "") {
folderModel.folder = "file://" + path
} else {
/* Restore original location. */
text = stripUrlPrefix(folderModel.folder)
}
}
}
}
}
ListView {
width: root.parent.width / 2
height: root.parent.height / 2
FolderListModel {
id: folderModel
showDirsFirst: true
nameFilters: ["*.*"]
folder: "file://" + interactionFilesystem.locateHome()
onFolderChanged: {
selectedFileName = ""
pathField.text = stripUrlPrefix(folder)
}
}
Component {
id: fileDelegate
Rectangle {
color: (fileName == selectedFileName) ? datovkaPalette.highlight : "#00000000"
width: childrenRect.width
height: childrenRect.height
Text {
/* Add '>' to directory names. */
text: fileName + (fileIsDir ? " >" : "")
}
MouseArea {
anchors.fill: parent
onClicked: {
/* Navigate to selected directory. */
if (fileIsDir) {
folderModel.folder = fileURL
} else {
selectedFileName = fileName
}
}
}
}
}
model: folderModel
delegate: fileDelegate
}
}
onAccepted: {
if (selectedFileName != "") {
finished(stripUrlPrefix(folderModel.folder) + "/" + selectedFileName)
} else {
finished("")
}
}
onRejected: {
finished("")
}
}
......@@ -114,6 +114,7 @@ ApplicationWindow {
/* Exposes nested stack to code outside the page component. */
property var nestedStack: null
/* Password/OTP input dialog, emitted from C++ */
InputDialogue {
id: inputDialog
......@@ -128,6 +129,13 @@ ApplicationWindow {
}
}
FileDialogue {
id: fileDialogue
onFinished: {
console.log("FileDialogue closed with '" + path + "'")
}
}
StackView { // Page area.
id: mainStack
anchors.fill: parent
......
......@@ -89,10 +89,13 @@ Component {
MouseArea {
anchors.fill: parent
onClicked: {
fileDialogue.raise()
/*
pageView.push(pageAboutApp, {
"pageView": pageView,
"statusBar": statusBar
}, StackView.Immediate)
*/
}
}
}
......
......@@ -102,6 +102,7 @@
<file>../qml/components/ScrollContent.qml</file>
<file>../qml/components/SpinBoxZeroMax.qml</file>
<file>../qml/dialogues/InputDialogue.qml</file>
<file>../qml/dialogues/FileDialogue.qml</file>
<file>../qml/dialogues/MessageDialogue.qml</file>
<file>../qml/dialogues/PasteInputDialogue.qml</file>
<file>../qml/pages/PageAboutApp.qml</file>
......
......@@ -46,6 +46,7 @@
#if defined(Q_OS_ANDROID)
#include "src/os_android.h"
#endif /* defined(Q_OS_ANDROID) */
#include "src/qml_interaction/interaction_filesystem.h"
#include "src/qml_interaction/interaction_zfo_file.h"
#include "src/settings.h"
#include "src/sqlite/db_tables.h"
......@@ -118,6 +119,7 @@ const struct QmlTypeEntry qmlComponents[] = {
*/
static
const struct QmlTypeEntry qmlDialogues[] = {
{ "FileDialogue", 1, 0 },
{ "InputDialogue", 1, 0},
{ "MessageDialogue", 1, 0},
{ "PasteInputDialogue", 1, 0 },
......@@ -285,6 +287,7 @@ int main(int argc, char *argv[])
AccountListModel::declareQML();
Dialogues::declareQML();
FileListModel::declareQML();
InteractionFilesystem::declareQML();
ListSortFilterProxyModel::declareQML();
MessageListModel::declareQML();
Messages::declareQML();
......
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#include <QFileInfo>
#include <QQmlEngine> /* qmlRegisterType */
#include <QStandardPaths>
#include "src/qml_interaction/interaction_filesystem.h"
void InteractionFilesystem::declareQML(void)
{
qmlRegisterType<InteractionFilesystem>("cz.nic.mobileDatovka.qmlInteraction", 1, 0, "InteractionFilesystem");
qRegisterMetaType<InteractionFilesystem>();
}
InteractionFilesystem::InteractionFilesystem(QObject *parent)
: QObject(parent)
{
}
InteractionFilesystem::InteractionFilesystem(const InteractionFilesystem &inter)
: QObject()
{
Q_UNUSED(inter)
}
QString InteractionFilesystem::locateHome(void)
{
const QStringList homesLocation(
QStandardPaths::standardLocations(QStandardPaths::HomeLocation));
if (!homesLocation.isEmpty()) {
return homesLocation.at(0);
} else {
return QStringLiteral(".");
}
}
QString InteractionFilesystem::absoluteDirPath(const QString &path)
{
if (path.isEmpty()) {
return QString();
}
QFileInfo fileInfo(path);
if (fileInfo.isDir() && fileInfo.isReadable()) {
return fileInfo.absoluteFilePath();
}
return QString();
}
QString InteractionFilesystem::absolutePath(const QString &path)
{
if (path.isEmpty()) {
return QString();
}
QFileInfo fileInfo(path);
if (fileInfo.isFile()) {
return fileInfo.absolutePath();
}
return QString();
}
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#ifndef _INTERACTION_FILESYSTEM_H_
#define _INTERACTION_FILESYSTEM_H_
#include <QObject>
#include <QString>
/*!
* @provides interface between QML and file-system functionality.
*/
class InteractionFilesystem : public QObject {
Q_OBJECT
public:
/* Don't forget to declare various properties to the QML system. */
static
void declareQML(void);
/*!
* @brief Constructor.
*
* @param[in] parent Parent object.
*/
explicit InteractionFilesystem(QObject *parent = Q_NULLPTR);
/*!
* @brief Copy constructor.
*
* @note Needed for QVariant conversion.
*
* @param[in] inter Object to be copied.
*/
InteractionFilesystem(const InteractionFilesystem &inter);
/*!
* @brief Returns home location.
*
* @return Home location path.
*/
static Q_INVOKABLE
QString locateHome(void);
/*!
* @brief Check whether path is a readable directory.
*
* @param[in] path Absolute or relative path.
* @return Non-empty absolute path to directory if supplied path is a
* directory. Returns empty string if directory does not exist or
* is not accessible.
*/
static Q_INVOKABLE
QString absoluteDirPath(const QString &path);
/*!
* @brief Check whether path is a readable file.
*
* @param[in] path Absolute or relative path.
* @return Non-empty absolute path to directory without file name if
* the supplied path is a file. Returns empty string if directory
* does not exist or is not accessible.
*/
static Q_INVOKABLE
QString absolutePath(const QString &path);
};
/* QML passes its arguments via QVariant. */
Q_DECLARE_METATYPE(InteractionFilesystem)
#endif /* _INTERACTION_FILESYSTEM_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment