Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Datovka projects
mobile Datovka
Commits
4baa7adb
Commit
4baa7adb
authored
Jan 27, 2017
by
Martin Straka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First prototype of open ZFO file
parent
555b9d19
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
478 additions
and
16 deletions
+478
-16
qml/main.qml
qml/main.qml
+1
-0
qml/pages/PageAccountList.qml
qml/pages/PageAccountList.qml
+0
-2
qml/pages/PageMessageDetail.qml
qml/pages/PageMessageDetail.qml
+10
-0
qml/pages/PageMessageList.qml
qml/pages/PageMessageList.qml
+1
-3
qml/pages/PageZfoMessageDetail.qml
qml/pages/PageZfoMessageDetail.qml
+257
-0
res/qml.qrc
res/qml.qrc
+1
-0
src/files.cpp
src/files.cpp
+161
-0
src/files.h
src/files.h
+35
-0
src/main.cpp
src/main.cpp
+1
-0
src/net/xml_layer.h
src/net/xml_layer.h
+11
-11
No files found.
qml/main.qml
View file @
4baa7adb
...
...
@@ -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
"
...
...
qml/pages/PageAccountList.qml
View file @
4baa7adb
...
...
@@ -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
)
}
}
...
...
qml/pages/PageMessageDetail.qml
View file @
4baa7adb
...
...
@@ -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
)
}
}
}
}
}
...
...
qml/pages/PageMessageList.qml
View file @
4baa7adb
...
...
@@ -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
...
...
qml/pages/PageZfoMessageDetail.qml
0 → 100644
View file @
4baa7adb
/*
* 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
}
}
}
}
}
res/qml.qrc
View file @
4baa7adb
...
...
@@ -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>
src/files.cpp
View file @
4baa7adb
...
...
@@ -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"
)
?
"<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
;
}
src/files.h
View file @
4baa7adb
...
...
@@ -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
src/main.cpp
View file @
4baa7adb
...
...
@@ -77,6 +77,7 @@ const struct QmlTypeEntry qmlPages[] = {
{
"PageSettingsPin"
,
1
,
0
},
{
"PageSettingsStorage"
,
1
,
0
},
{
"PageSettingsSync"
,
1
,
0
},
{
"PageZfoMessageDetail"
,
1
,
0
},
{
NULL
,
0
,
0
}
};
...
...
src/net/xml_layer.h
View file @
4baa7adb
...
...
@@ -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.
*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment