Commit 4baa7adb authored by Martin Straka's avatar Martin Straka

First prototype of open ZFO file

parent 555b9d19
......@@ -60,6 +60,7 @@ ApplicationWindow {
property Component pageSettingsPin: PageSettingsPin {}
property Component pageSettingsStorage: PageSettingsStorage {}
property Component pageSettingsSync: PageSettingsSync {}
property Component pageZfoMessageDetail: PageZfoMessageDetail {}
// header background color
property string mainHeaderBgColor: "#00539b"
......
......@@ -282,7 +282,6 @@ Component {
anchors.fill: parent
onClicked: {
statusBar.visible = false
messages.fillMessageList(rUserName, MessageType.TYPE_RECEIVED)
pageView.push(pageMessageList, {"acntName": rAcntName, "userName": rUserName, "msgType": MessageType.TYPE_RECEIVED}, StackView.Immediate)
}
}
......@@ -345,7 +344,6 @@ Component {
anchors.fill: parent
onClicked: {
statusBar.visible = false
messages.fillMessageList(rUserName, MessageType.TYPE_SENT)
pageView.push(pageMessageList, {"acntName": rAcntName, "userName": rUserName, "msgType": MessageType.TYPE_SENT}, StackView.Immediate)
}
}
......
......@@ -41,6 +41,9 @@ Component {
property string msgId
Component.onCompleted: {
messages.markMessageAsLocallyRead(userName, msgId, true)
messages.fillMessageDetail(userName, msgId)
files.fillFileList(userName, msgId)
if (attachmentList.count == 0) {
emptyList.visible = true
msgDownloadButton.visible = true
......@@ -163,6 +166,13 @@ Component {
messageDetailText.text = txt
}
}
Connections {
target: files
onPushNewMessageDeatilPage: {
statusBar.visible = false
pageView.push(pageZfoMessageDetail, {"zfoId": zfoId}, StackView.Immediate)
}
}
}
}
}
......
......@@ -45,6 +45,7 @@ Component {
property int msgType
Component.onCompleted: {
messages.fillMessageList(userName, msgType)
if (messageList.count == 0) {
emptyList.visible = true
settingsButton.visible = false
......@@ -272,9 +273,6 @@ Component {
onClicked: {
statusBar.visible = false
pageView.push(pageMessageDetail, {"acntName": acntName, "userName": userName, "msgType": msgType, "msgId": rMsgId}, StackView.Immediate)
messages.markMessageAsLocallyRead(userName, rMsgId, true)
messages.fillMessageDetail(userName, rMsgId)
files.fillFileList(userName, rMsgId)
}
onPressAndHold: {
statusBar.visible = false
......
/*
* 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.Window 2.1
import QtQuick.Layouts 1.2
import QtQuick.Dialogs 1.2
import QtGraphicalEffects 1.0
import cz.nic.mobileDatovka.messages 1.0
Component {
id: pageZfoMessageDetail
Item {
id: msgZfoDetailPage
/* These properties must be set by caller. */
property string zfoId
Component.onCompleted: {
//files.fillZfoFileList(zfoId)
}
Rectangle {
id: header
anchors.top: parent.top
width: parent.width
height: headerHeight
color: datovkaPalette.highlight
Image {
id: backElement3
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: defaultMargin
sourceSize.height: navImgHeight
source: "qrc:/ui/back.svg"
}
Rectangle {
anchors.left: parent.left
width: parent.width * 0.5
height: parent.height
color: "transparent"
MouseArea {
anchors.fill: parent
onClicked: {
statusBar.visible = false
pageView.pop(StackView.Immediate)
}
}
}
Column {
anchors.verticalCenter: parent.verticalCenter
anchors.left: backElement3.right
anchors.leftMargin: defaultMargin
Text {
text: qsTr("Message from ZFO file")
font.bold: true
color: datovkaPalette.text
}
Text {
text: qsTr("Message ID") + " " + zfoId
font.bold: true
color: datovkaPalette.text
}
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
Image {
id: msgDownloadButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeight
source: "qrc:/ui/reply.svg"
MouseArea {
anchors.fill: parent
onClicked: {
console.log("EMAIL")
}
}
}
Image {
id: attachmentMenuButon
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeight
source: "qrc:/ui/save-to-disk.svg"
MouseArea {
anchors.fill: parent
onClicked: {
console.log("DISK")
}
}
}
}
}
Rectangle {
id: messageDetail
anchors.top: header.bottom
width: parent.width
height: parent.height * 0.5
color: datovkaPalette.base
ListModel {
id: messageDetailModel
ListElement {
text: ""
}
}
ListView {
id: messageDetailList
anchors.fill: parent
anchors.margins: defaultMargin
clip: true
spacing: 0
opacity: 1
visible: true
interactive: true
model: messageDetailModel
delegate: Text {
id: messageDetailText
color: datovkaPalette.text
width: parent.width
textFormat: TextEdit.RichText
wrapMode: Text.WordWrap
Connections {
target: files
onMessageDetailChanged: {
messageDetailText.text = txt
}
}
}
}
}
Item {
id: attachmentLabel
anchors.top: messageDetail.bottom
width: parent.width
height: textFontSizeInPixels * 2
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: defaultMargin
textFormat: TextEdit.RichText
text: "<h3>" + qsTr("Attachments") + "</h3>"
font.bold: true
}
Rectangle {
id: attachmentLabelLine
anchors.bottom: parent.bottom
height: 1
width: parent.width
color: datovkaPalette.mid
}
}
ListView {
id: attachmentList
anchors.top: attachmentLabel.bottom
anchors.bottom: parent.bottom
clip: true
spacing: 1
opacity: 1
visible: true
width: parent.width
interactive: true
model: fileListModel
delegate: Rectangle {
id: attachmentItem
width: parent.width
height: headerHeight
color: datovkaPalette.base
Image {
id: imageAttachment
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeight
source: rFileIcon
}
Item {
anchors.left: imageAttachment.right
anchors.leftMargin: defaultMargin
height: parent.height
width: parent.width
Column {
anchors.verticalCenter: parent.verticalCenter
Text {
id: filenameid
anchors.left: parent.left
text: rFileName
color: datovkaPalette.text
font.bold: true
}
Text {
id: filesizeid
anchors.left: parent.left
text: rFileSize
color: datovkaPalette.mid
font.pointSize: textFontSizeSmall
renderType: Text.NativeRendering
}
}
}
Rectangle {
id: next
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
height: parent.height
width: parent.width * 0.07
color: parent.color
Image {
id: nextImage
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: defaultMargin
sourceSize.height: navImgHeight
source: "qrc:/ui/next.svg"
}
ColorOverlay {
anchors.fill: nextImage
source: nextImage
color: datovkaPalette.text
}
}
MouseArea {
anchors.fill: parent
onClicked: {
locker.ignoreNextSuspension()
// TODO - files.openAttachment(userName, msgId, rFileId)
}
}
Rectangle {
anchors.top: parent.bottom
height: 1
width: parent.width
color: datovkaPalette.mid
}
}
}
}
}
......@@ -111,5 +111,6 @@
<file>../qml/pages/PageSettingsStorage.qml</file>
<file>../qml/pages/PageSettingsSync.qml</file>
<file>../qml/main.qml</file>
<file>../qml/pages/PageZfoMessageDetail.qml</file>
</qresource>
</RCC>
......@@ -37,6 +37,13 @@
#include "src/models/accountmodel.h"
#include "src/sqlite/file_db_container.h"
#include "src/sqlite/message_db_container.h"
#include "src/net/xml_layer.h"
#include "src/sqlite/dbs.h"
#ifndef Q_OS_WIN
#include "src/crypto/crypto.h"
#endif
/* ========================================================================= */
......@@ -227,6 +234,11 @@ void Files::openAttachment(const QString &userName, qint64 msgId, int fileId)
return;
}
if (isAttachmentZfoFile(fileName)) {
parseXMLData(decodeZfoFile(file.content));
return;
}
QByteArray data = QByteArray::fromBase64(file.content.toUtf8());
fileName = writeFileToTmpDir(fileName, TEMP_DIR_NAME, data);
......@@ -540,3 +552,152 @@ bool Files::deleteAttachmentsFromDb(const QString &userName, qint64 msgId)
return false;
}
/* ========================================================================= */
/*
* Func: Test, if attachmenti is ZFO
*/
bool Files::isAttachmentZfoFile(const QString &fileName)
/* ========================================================================= */
{
qDebug("%s()", __func__);
QFileInfo fi(fileName);
return (fi.suffix().toLower() == "zfo");
}
/* ========================================================================= */
/*
* Func: Decode data from ZFO file.
*/
QByteArray Files::decodeZfoFile(const QString &content)
/* ========================================================================= */
{
qDebug("%s()", __func__);
Q_ASSERT(!content.isEmpty());
if (content.isEmpty()) {
qDebug() << "ERROR: File content is empty!";
return QByteArray();
}
/* decode signature from base64 and obtain something cms message */
QByteArray cmsData = QByteArray::fromBase64(content.toUtf8());
/* decode cms and obtain message xml data - used openssl */
void *xmlContent = NULL;
size_t xmlContentLen = 0;
if (extract_cms_data(cmsData.data(), cmsData.length(), &xmlContent,
&xmlContentLen) != 0) {
return QByteArray();
}
if (xmlContentLen == 0) {
free(xmlContent); xmlContent = NULL;
return QByteArray();
}
QByteArray soap((char*)xmlContent, xmlContentLen);
free(xmlContent); xmlContent = NULL;
return soap;
}
/* ========================================================================= */
/*
* Func: Parse XML data.
*/
bool Files::parseXMLData(QByteArray data)
/* ========================================================================= */
{
qDebug("%s()", __func__);
bool success = false;
Q_ASSERT(!data.isEmpty());
if (data.isEmpty()) {
qDebug() << "ERROR: XML content is empty!";
return success;
}
data.prepend("<?xml version='1.0' encoding='utf-8'?>"
"<SOAP-ENV:Envelope "
"xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
"<SOAP-ENV:Body>");
data.append("</SOAP-ENV:Body></SOAP-ENV:Envelope>");
//qDebug() << data;
QXmlStreamReader xml;
xml.addData(data);
XmlLayer xmlLayer;
Messages::Message msg;
QList<Files::File> fileList;
while(!xml.atEnd() && !xml.hasError()) {
QXmlStreamReader::TokenType token = xml.readNext();
if (xml.error() != QXmlStreamReader::NoError) {
return success;
}
if (token == QXmlStreamReader::StartDocument) {
continue;
}
if (token == QXmlStreamReader::StartElement) {
if (xml.name() == "dmDm") {
success = xmlLayer.completeMessageParse(xml, msg, fileList);
}
}
}
if (!success) {
return success;
}
emit pushNewMessageDeatilPage(QString::number(msg.dmID));
QString html = divStart;
html += "<h3>" + QObject::tr("General") + "</h3>";
html += strongInfoLine(QObject::tr("Subject"), msg.dmAnnotation);
QString size = QString::number(msg.dmAttachmentSize);
html += strongInfoLine(QObject::tr("Attachment size"),
(size == "0") ? "&lt;1 KB" : "~" + size + " KB");
html += strongInfoLine(QObject::tr("Personal delivery"),
(msg.dmPersonalDelivery) ? QObject::tr("Yes") : QObject::tr("No"));
html += strongInfoLine(QObject::tr("Delivery by fiction"),
(msg.dmAllowSubstDelivery) ? QObject::tr("Yes") : QObject::tr("No"));
html += "<h3>" + QObject::tr("Sender") + "</h3>";
html += strongInfoLine(QObject::tr("Databox ID"), msg.dbIDSender);
html += strongInfoLine(QObject::tr("Name"), msg.dmSender);
html += strongInfoLine(QObject::tr("Address"),msg.dmSenderAddress);
html += "<h3>" + QObject::tr("Recipient") + "</h3>";
html += strongInfoLine(QObject::tr("Databox ID"), msg.dbIDRecipient);
html += strongInfoLine(QObject::tr("Name"), msg.dmRecipient);
html += strongInfoLine(QObject::tr("Address"),msg.dmRecipientAddress);
/* TODO - add additional information to html */
html += "<h3>" + QObject::tr("Message state") + "</h3>";
html += strongInfoLine(QObject::tr("Delivery time"),
dateTimeStrFromDbFormat(
dateTimeStrToUTCDbFormat(msg.dmDeliveryTime),
DATETIME_QML_FORMAT));
html += strongInfoLine(QObject::tr("Accetance time"),
dateTimeStrFromDbFormat(
dateTimeStrToUTCDbFormat(msg.dmAcceptanceTime),
DATETIME_QML_FORMAT));
html += strongInfoLine(QObject::tr("Status"),
QString::number(msg.dmMessageStatus));
html += divEnd;
emit messageDetailChanged(html);
return success;
}
......@@ -128,6 +128,41 @@ signals:
*/
void statusBarTextChanged(QString txt, bool busy);
/*!
* @brief Send message detait html string to QML.
*/
void messageDetailChanged(QString txt);
/*!
* @brief Push a new message detail page to stackview in QML.
*/
void pushNewMessageDeatilPage(QString zfoId);
private:
/*!
* @brief Test, if attachment is ZFO file.
*
* @param[in] fileName - file name.
* @return true if file is zfo.
*/
bool isAttachmentZfoFile(const QString &fileName);
/*!
* @brief Decode data from ZFO file.
*
* @param[in] content - file content.
* @return decoded data or QByteArray().
*/
QByteArray decodeZfoFile(const QString &content);
/*!
* @brief Parse XML data.
*
* @param[in] data - file data.
* @return true if success.
*/
bool parseXMLData(QByteArray data);
};
#endif // FILES_H
......@@ -77,6 +77,7 @@ const struct QmlTypeEntry qmlPages[] = {
{ "PageSettingsPin", 1, 0 },
{ "PageSettingsStorage", 1, 0 },
{ "PageSettingsSync", 1, 0 },
{ "PageZfoMessageDetail", 1, 0 },
{ NULL, 0, 0 }
};
......
......@@ -184,6 +184,17 @@ public:
*/
bool isdsLogoutOtp(IsdsContext &ctx);
/*!
* @brief Parse completeMessageParse XML.
*
* @param[in] xml - xml Data for parsing.
* @param[out] msg - envelope message structure.
* @param[out] fileList - list of files structure.
* @return true if success.
*/
bool completeMessageParse(QXmlStreamReader &xml, Messages::Message &msg,
QList<Files::File> &fileList);
private:
/*!
......@@ -316,17 +327,6 @@ private:
Messages::Message msgEnvelopeParse(QXmlStreamReader &xml,
enum MessageDb::MessageType messageType);
/*!
* @brief Parse completeMessageParse XML.
*
* @param[in] xml - xml Data for parsing.
* @param[out] msg - envelope message structure.
* @param[out] fileList - list of files structure.
* @return true if success.
*/
bool completeMessageParse(QXmlStreamReader &xml, Messages::Message &msg,
QList<Files::File> &fileList);
/*!
* @brief Parse parse file XML.
*
......
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