Commit 76dd6c67 authored by Karel Slaný's avatar Karel Slaný

Added QML message dialogue torso.

parent 79d114b1
......@@ -86,6 +86,7 @@ SOURCES += \
src/dialogues/dialogues.cpp \
src/dialogues/qml_dialogue_helper.cpp \
src/dialogues/qml_input_dialogue.cpp \
src/dialogues/qml_message_dialogue.cpp \
src/dialogues/widget_input_dialogue.cpp \
src/dialogues/widget_message_dialogue.cpp \
src/files.cpp \
......@@ -123,6 +124,7 @@ HEADERS += \
src/dialogues/dialogues.h \
src/dialogues/qml_dialogue_helper.h \
src/dialogues/qml_input_dialogue.h \
src/dialogues/qml_message_dialogue.h \
src/dialogues/widget_input_dialogue.h \
src/dialogues/widget_message_dialogue.h \
src/files.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.0
import QtQuick.Dialogs 1.2
/*
* All objectName properties are used to navigate through the structure from
* within C++ code.
*/
Item {
id: root
objectName: "root"
/* Expose children. */
property alias dialogue: dialogue
signal dialogueClosed()
Dialog {
id: dialogue
objectName: "dialogue"
property alias content: content
//visible: true /* Set from C++. */
title: ""
modality: Qt.ApplicationModal
standardButtons: Dialog.NoButton
Column {
id: content
property alias messageText: messageText
property alias infoMessageText: infoMessageText
anchors.fill: parent
Text {
id: messageText
objectName: "messageText"
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
text: ""
//color: datovkaPalette.mid /* TODO */
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
Text {
id: infoMessageText
objectName: "infoMessageText"
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
text: ""
//color: datovkaPalette.mid /* TODO */
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
}
onVisibleChanged: {
if (!visible) {
root.dialogueClosed()
}
}
}
}
......@@ -383,6 +383,64 @@ ApplicationWindow {
dlgEmitter.emitRejected();
}
}
onDlgMessage: {
/*
* Create a dynamic dialogue object set content and connect
* functionality.
*/
var dlgComponent = Qt.createComponent("qrc:/qml/dialogues/MessageDialogue.qml", Component.PreferSynchronous);
var dlgObj;
if (dlgComponent.status == Component.Ready) {
finishCreation();
} else {
dlgComponent.statusChanged.connect(finishCreation);
}
function finishCreation() {
if (dlgComponent.status == Component.Error) {
// Error handling.
console.log("Error loading dlgComponent:", dlgComponent.errorString());
return;
} else if (dlgComponent.status != Component.Ready) {
return;
}
dlgObj = dlgComponent.createObject(mainWindow, {"objectName": "messageDialogue"});
if (dlgObj == null) {
// Error handling.
console.log("Error creating dialogue object");
return;
}
dlgObj.dialogue.title = title
dlgObj.dialogue.content.messageText.text = message
dlgObj.dialogue.content.infoMessageText.text = infoMessage
dlgObj.dialogue.standardButtons = StandardButton.Ok
/* Connect signals. */
dlgObj.dialogueClosed.connect(gatherDataAndDeleteObject);
dlgObj.dialogue.open();
}
function gatherDataAndDeleteObject() {
/* TODO -- Gather pressed button value. */
dlgEmitter.emitClosed(1, -1)
console.log("Destroying dialogue.");
dlgObj.destroy();
mainStack.forceActiveFocus(); /* Dialogue stole focus. */
}
function emitClosed() {
console.log("Closed");
dlgEmitter.emitClosed(1, -1);
}
}
}
function navigateBack(mainStack, nestedStack, event) {
......
......@@ -98,6 +98,7 @@
<file>../qml/components/MessageList.qml</file>
<file>../qml/components/OverlaidImage.qml</file>
<file>../qml/components/SpinBoxZeroMax.qml</file>
<file>../qml/dialogues/MessageDialogue.qml</file>
<file>../qml/dialogues/PasteInputDialogue.qml</file>
<file>../qml/pages/PageAboutApp.qml</file>
<file>../qml/pages/PageAccountDetail.qml</file>
......
......@@ -29,6 +29,7 @@
#include "src/dialogues/dialogues.h"
#include "src/dialogues/qml_input_dialogue.h"
#include "src/dialogues/qml_message_dialogue.h"
#include "src/dialogues/widget_input_dialogue.h"
#include "src/dialogues/widget_message_dialogue.h"
......@@ -214,6 +215,10 @@ int Dialogues::message(enum Icon icon, const QString &title,
void Dialogues::errorMessage(enum Icon icon, const QString &title,
const QString &text, const QString &infoText)
{
#if defined(USE_QML_DIALOGUES)
QmlMessageDialogue::errorMessage(Q_NULLPTR, title, text, infoText);
#else /* !defined(USE_QML_DIALOGUES) */
WidgetMessageDialogue::errorMessage(toMessageBoxIcon(icon), title,
text, infoText);
#endif /* defined(USE_QML_DIALOGUES) */
}
......@@ -21,10 +21,13 @@
* the two.
*/
#include <QGuiApplication>
#include <QQmlEngine> /* qmlRegisterType */
#include "src/dialogues/qml_dialogue_helper.h"
QmlDlgHelper *QmlDlgHelper::dlgEmitter = Q_NULLPTR;
void QmlDlgHelper::declareQML(void)
{
qmlRegisterType<QmlDlgHelper>("cz.nic.mobileDatovka.qmlDialogue", 1, 0, "QmlDlgEchoMode");
......@@ -39,3 +42,18 @@ void QmlDlgHelper::emitRejected(void)
{
emit rejected();
}
void QmlDlgHelper::emitClosed(int button, int customButton)
{
emit closed(button, customButton);
}
QWindow *QmlDlgHelper::topLevelWindow(void)
{
foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
if ((w != Q_NULLPTR) && (w->parent() == Q_NULLPTR)) {
return w;
}
}
return Q_NULLPTR;
}
......@@ -26,6 +26,7 @@
#include <QObject>
#include <QString>
#include <QWindow>
/*!
* @brief Class defining enumeration types.
......@@ -70,6 +71,32 @@ public:
Q_INVOKABLE
void emitRejected(void);
/*!
* @brief Emits closed signal.
*
* @param[in] button Pressed button code.
* @param[in] customButton Custom button value.
*/
Q_INVOKABLE
void emitClosed(int button, int customButton);
/*!
* @brief Return pointer to top level window.
*
* @return non-null pointer to window if top level window could be
* acquired.
*/
static
QWindow *topLevelWindow(void);
/*
* Cannot be a static object. Android code complains:
* Illegal attempt to connect to object that is in a different thread
* than the QML engine.
*/
static
QmlDlgHelper *dlgEmitter; /*!< Object used to invoke QML dialogues. */
signals:
/*!
* @brief This signal should be emitted when QML text input dialogue
......@@ -90,6 +117,19 @@ signals:
* was rejected.
*/
void rejected(void);
/*!
* @brief This signal should be emitted when QML message dialogue
* should be displayed.
*/
void dlgMessage(const QString &title, const QString &message,
const QString &infoMessage);
/*!
* @brief This signal should be emitted when QML message dialogue
* was closed.
*/
void closed(int button, int customButton);
};
#endif /* _QML_DIALOGUE_HELPER_H_ */
......@@ -21,13 +21,11 @@
* the two.
*/
#include <QGuiApplication>
#include <QQmlApplicationEngine>
//#include <QQuickItem>
#include "src/dialogues/qml_input_dialogue.h"
QmlDlgHelper *QmlInputDialogue::dlgEmitter = Q_NULLPTR;
QObject *QmlInputDialogue::s_dlgTextInput = Q_NULLPTR;
QmlInputDialogue::QmlInputDialogue(QObject *parent, QWindow *window)
......@@ -111,7 +109,7 @@ QString QmlInputDialogue::getText(QWindow *parent, const QString &title,
const QString &placeholderText, bool *ok,
Qt::InputMethodHints inputMethodHints)
{
QmlInputDialogue dialogue(parent, topLevelWindow());
QmlInputDialogue dialogue(parent, QmlDlgHelper::topLevelWindow());
bool explicitPasteMenu = false;
......@@ -119,21 +117,21 @@ QString QmlInputDialogue::getText(QWindow *parent, const QString &title,
explicitPasteMenu = true;
#endif /* Q_OS_ANDROID */
if (dlgEmitter == Q_NULLPTR) {
if (QmlDlgHelper::dlgEmitter == Q_NULLPTR) {
Q_ASSERT(0);
return QString();
}
/* Cause QML window to pop up. */
emit dlgEmitter->dlgGetText(title, message, echoMode, text,
placeholderText, inputMethodHints, explicitPasteMenu);
/* Connects signals and slots that interrupt the event loop. */
connect(dlgEmitter, SIGNAL(accepted(QString)),
connect(QmlDlgHelper::dlgEmitter, SIGNAL(accepted(QString)),
&dialogue, SLOT(readGetText(QString)));
connect(dlgEmitter, SIGNAL(rejected()),
connect(QmlDlgHelper::dlgEmitter, SIGNAL(rejected()),
&dialogue.m_loop, SLOT(quit()));
/* Cause QML window to pop up. */
emit QmlDlgHelper::dlgEmitter->dlgGetText(title, message, echoMode, text,
placeholderText, inputMethodHints, explicitPasteMenu);
dialogue.m_loop.exec();
if (ok != Q_NULLPTR) {
......@@ -142,17 +140,6 @@ QString QmlInputDialogue::getText(QWindow *parent, const QString &title,
return dialogue.m_readText;
}
QWindow *QmlInputDialogue::topLevelWindow(void)
{
foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
if ((w != Q_NULLPTR) && (w->parent() == Q_NULLPTR)) {
return w;
}
}
return Q_NULLPTR;
}
void QmlInputDialogue::searchPersistentDialogues(QQmlApplicationEngine *engine)
{
if (engine == Q_NULLPTR) {
......
......@@ -72,15 +72,6 @@ public:
const QString &placeholderText = QString(), bool *ok = Q_NULLPTR,
Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
/*!
* @brief Return pointer to top level window.
*
* @return non-null pointer to window if top level window could be
* acquired.
*/
static
QWindow *topLevelWindow(void);
/*!
* @brief Set pointers to persistent (defined in QML) dialogues.
*
......@@ -89,14 +80,6 @@ public:
static
void searchPersistentDialogues(QQmlApplicationEngine *engine);
/*
* Cannot be a static object. Android code complains:
* Illegal attempt to connect to object that is in a different thread
* than the QML engine.
*/
static
QmlDlgHelper *dlgEmitter; /*!< Object used to invoke QML dialogues. */
private slots:
/*!
* @brief This slot us called when dialogue window is accepted.
......
/*
* 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 "src/dialogues/qml_dialogue_helper.h"
#include "src/dialogues/qml_message_dialogue.h"
QmlMessageDialogue::QmlMessageDialogue(QObject *parent, QWindow *window)
: QObject(parent),
m_alreadyReturned(false),
m_loop(this)
{
Q_UNUSED(window)
}
void QmlMessageDialogue::errorMessage(QWindow *parent, const QString &title,
const QString &text, const QString &infoText)
{
QmlMessageDialogue dialogue(parent, QmlDlgHelper::topLevelWindow());
/* Connects signals and slots that interrupt the event loop. */
connect(QmlDlgHelper::dlgEmitter, SIGNAL(closed(int, int)),
&dialogue, SLOT(dlgClosed(int, int)));
/* Cause QML window to pop up. */
emit QmlDlgHelper::dlgEmitter->dlgMessage(title, text, infoText);
if (!dialogue.m_alreadyReturned) {
dialogue.m_loop.exec();
}
}
void QmlMessageDialogue::dlgClosed(int button, int customButton)
{
m_alreadyReturned = true;
m_loop.quit();
}
/*
* 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 _QML_MESSAGE_DIALOGUE_H_
#define _QML_MESSAGE_DIALOGUE_H_
#include <QEventLoop>
#include <QObject>
#include <QString>
#include <QWindow>
/*!
* @brief Encapsulates QML-based dialogues.
*/
class QmlMessageDialogue : public QObject {
Q_OBJECT
private:
/*!
* @brief Private constructor.
*
* @param[in] parent Parent object.
*/
explicit QmlMessageDialogue(QObject *parent = Q_NULLPTR,
QWindow *window = Q_NULLPTR);
public:
/*!
* @brief Generates error message dialogue with.
*
* @param[in] parent Parent window.
* @param[in] title Window title.
* @param[in] text Text shown in dialogue window.
* @param[in] infoText Informative text.
*/
static
void errorMessage(QWindow *parent, const QString &title,
const QString &text, const QString &infoText);
private slots:
/*!
* @brief This slot us called when dialogue window is closed.
*
* @param[in] button Pressed button code.
* @param[in] customButton Custom button value.
*/
void dlgClosed(int button, int customButton);
private:
bool m_alreadyReturned; /*!< True if dialogue closed before loop start. */
QEventLoop m_loop; /*!< Loop used for action blocking. */
};
#endif /* _QML_MESSAGE_DIALOGUE_H_ */
......@@ -113,6 +113,7 @@ const struct QmlTypeEntry qmlComponents[] = {
*/
static
const struct QmlTypeEntry qmlDialogues[] = {
{ "MessageDialogue", 1, 0},
{ "PasteInputDialogue", 1, 0 },
{ NULL, 0, 0 }
};
......@@ -170,7 +171,7 @@ int main(int argc, char *argv[])
* application.
*/
QmlDlgHelper dlgHelper;
QmlInputDialogue::dlgEmitter = &dlgHelper;
QmlDlgHelper::dlgEmitter = &dlgHelper;
/* Perform check that configuration file can be accessed. */
const QString settingsFileName(Settings::settingsPath());
......@@ -295,7 +296,7 @@ int main(int argc, char *argv[])
ctx->setContextProperty("settings", &settings);
ctx->setContextProperty("locker", &locker);
ctx->setContextProperty("interactionZfoFile", &interactionZfoFile);
ctx->setContextProperty("dlgEmitter", QmlInputDialogue::dlgEmitter);
ctx->setContextProperty("dlgEmitter", QmlDlgHelper::dlgEmitter);
/* register and set models in QML */
ctx->setContextProperty(globAccountsModelPtr->objectName(),
......
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