/*
* 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 .
*
* 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
#include
#include
#include
#include /* qmlRegisterType */
#include "ios/src/url_opener.h"
#include "src/auxiliaries/attachment_helper.h"
#include "src/auxiliaries/email_helper.h"
#include "src/common.h"
#include "src/dialogues/dialogues.h"
#include "src/files.h"
#include "src/io/filesystem.h"
#include "src/models/accountmodel.h"
#include "src/net/xml_layer.h"
#include "src/qml_interaction/attachment_data.h"
#include "src/qml_interaction/message_envelope.h"
#include "src/settings.h"
#include "src/sqlite/file_db_container.h"
#include "src/sqlite/message_db_container.h"
#include "src/sqlite/dbs.h"
#ifndef Q_OS_WIN
#include "src/crypto/crypto.h"
#endif
Files::Files(QObject *parent) : QObject(parent)
{
}
void Files::declareQML(void)
{
qmlRegisterType("cz.nic.mobileDatovka.files", 1, 0, "FileIdType");
qRegisterMetaType();
}
void Files::attachmentSavingNotification(const QString &destPath)
{
QFileInfo fi(destPath);
Dialogues::errorMessage(
!destPath.isEmpty() ? Dialogues::INFORMATION : Dialogues::CRITICAL,
QObject::tr("Attachment saving"),
!destPath.isEmpty() ? QObject::tr("Attachments have been saved.") :
QObject::tr("Attachments have not been saved!"),
QObject::tr("Path: '%1'").arg(fi.absolutePath()));
}
QString Files::fileSaveLocation(void)
{
return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
}
void Files::deleteExpiredFilesFromDbs(int days)
{
qDebug("%s()", __func__);
QStringList msgIDList;
QStringList userNameList = AccountListModel::globAccounts.keys();
foreach (const QString &userName, userNameList) {
FileDb *fDb = NULL;
fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation, userName,
AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == NULL) {
qDebug() << "ERROR: File database cannot open!" << userName;
return;
}
msgIDList = fDb->cleanFilesInDb(days);
if (msgIDList.isEmpty()) {
continue;
}
MessageDb *msgDb = NULL;
msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (msgDb == NULL) {
qDebug() << "ERROR: Message database cannot open!";
return;
}
msgDb->beginTransaction();
foreach (const QString &msgId, msgIDList) {
msgDb->setAttachmentDownloaded(msgId.toLongLong(),
false);
}
msgDb->commitTransaction();
}
}
QString Files::getAttachmentFileIcon(const QString &fileName)
{
return getAttachmentFileIconFromFileExtension(fileName);
}
qint64 Files::getAttachmentSizeInBytes(const QString &filePath)
{
QFileInfo fileInfo(filePath);
return fileInfo.size();
}
QByteArray Files::getFileRawContentFromDb(const QString &userName,
const QString &msgIdStr, int fileId)
{
qDebug("%s()", __func__);
/* Obtain message identifier. */
bool ok = false;
qint64 msgId = msgIdStr.toLongLong(&ok);
if (!ok || (msgId < 0)) {
return QByteArray();
}
FileDb *fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == Q_NULLPTR) {
qCritical() << "Cannot open file database!";
return QByteArray();
}
FileDb::FileData file = fDb->getFileContentFromDb(fileId);
return base64ToRaw(file.content.toUtf8());
}
void Files::openAttachmentFromDb(const QString &userName,
const QString &msgIdStr, int fileId)
{
qDebug("%s()", __func__);
/* Obtain message identifier. */
bool ok = false;
qint64 msgId = msgIdStr.toLongLong(&ok);
if (!ok || (msgId < 0)) {
return;
}
FileDb *fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == Q_NULLPTR) {
qCritical() << "Cannot open file database!";
return;
}
FileDb::FileData file = fDb->getFileContentFromDb(fileId);
openAttachment(file.filename, file.content.toUtf8());
}
void Files::openAttachment(const QString &fileName, const QByteArray &base64Data)
{
Q_ASSERT(!fileName.isEmpty());
Q_ASSERT(!base64Data.isEmpty());
if (fileName.isEmpty() || base64Data.isEmpty()) {
qCritical() << "File name or its content is empty!";
return;
}
if (isZfoFile(fileName)) {
/* Don't open zfo files from here. */
Q_ASSERT(0);
qCritical() << "This should open ZFO files by itself.";
return;
}
QString filePath(writeFileToTmpDir(fileName, TEMP_DIR_NAME,
base64ToRaw(base64Data)));
if (!filePath.isEmpty()) {
qInfo() << "Creating temporary file" << filePath;
openAttachmentFromPath(filePath);
} else {
qCritical() << "Cannot create temporary file for" << fileName;
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("Open attachment error"),
tr("Cannot save selected file to disk for opening."),
QString());
}
}
void Files::openAttachmentFromPath(const QString &filePath)
{
Q_ASSERT(!filePath.isEmpty());
if (filePath.isEmpty()) {
qCritical() << "File path is empty!";
return;
}
if (isZfoFile(filePath)) {
/* Don't open zfo files from here. */
Q_ASSERT(0);
qCritical() << "This should open ZFO files by itself.";
return;
}
#if defined Q_OS_IOS
UrlOpener urlOpener;
urlOpener.openFile(filePath);
/*
* TODO - we may check exceptions form objective-C (openFile)
* and return as bool.
*/
#else /* !defined Q_OS_IOS */
if (!QDesktopServices::openUrl(QUrl::fromLocalFile(filePath))) {
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("Open attachment error"),
tr("There is no application to open this file format."),
tr("File: '%1'").arg(filePath));
}
#endif /* defined Q_OS_IOS */
}
void Files::sendAttachmentsWithEmail(const QString &userName, qint64 msgId)
{
qDebug("%s()", __func__);
if (userName.isEmpty() || msgId <= 0) {
return;
}
QString body;
QString subject;
QStringList fileList;
MessageDb *msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (msgDb == NULL) {
qDebug() << "ERROR: Message database cannot open!";
return;
}
if (!msgDb->getMessageDataForEmail(msgId, body, subject)) {
qDebug() << "ERROR: Message data mssing!";
return;
}
FileDb *fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == NULL) {
qDebug() << "ERROR: File database cannot open!";
return;
}
QList filelist;
filelist = fDb->getFilesFromDb(msgId);
if (filelist.isEmpty()) {
qDebug() << "ERROR: File list is empty!";
return;
}
const QString boundary = generateBoundaryString();
QString emailMessage = createEmailMessage(body, subject, boundary);
deleteFilesFromDir(EMAIL_DIR_NAME);
foreach (const FileDb::FileData &file, filelist) {
QString fileName = file.filename;
if (fileName.isEmpty()) {
qDebug() << "ERROR: File name is empty!";
return;
}
fileName = writeFileToEmailDir(fileName, msgId,
base64ToRaw(file.content.toUtf8()));
fileList.append(fileName);
addAttachmentToEmailMessage(emailMessage, file.filename,
file.content.toUtf8(), boundary);
qDebug() << fileName;
}
finishEmailMessage(emailMessage, boundary);
sendEmail(emailMessage, fileList, subject, body, msgId);
}
void Files::deleteFileDb(const QString &userName)
{
qDebug("%s()", __func__);
int msgResponse = Dialogues::message(Dialogues::QUESTION,
tr("Delete files: %1").arg(userName),
tr("Do you want to clean up the file database of account '%1'?").arg(userName),
tr("Note: All attachment files of messages will be removed from the database."),
Dialogues::NO | Dialogues::YES, Dialogues::NO);
if (msgResponse == Dialogues::NO) {
return;
}
FileDb *fDb = NULL;
fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation, userName,
AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == NULL) {
qDebug() << "ERROR: File database open error!";
return;
}
if (!globFileDbsPtr->deleteDb(fDb)) {
qDebug() << "ERROR: File database could not delete!";
return;
}
MessageDb *msgDb = NULL;
msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation, userName,
AccountListModel::globAccounts[userName].storeToDisk());
if (msgDb == NULL) {
qDebug() << "ERROR: Message database cannot open!";
return;
}
if (!msgDb->setAttachmentsDownloaded(false)) {
qDebug() << "ERROR: Message data mssing!";
return;
}
}
void Files::vacuumFileDbs(void)
{
qDebug("%s()", __func__);
emit statusBarTextChanged(tr("Vacuum databases"), true);
QStringList userNameList = AccountListModel::globAccounts.keys();
foreach (const QString &userName, userNameList) {
FileDb *fDb = NULL;
fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation, userName,
AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == NULL) {
qDebug() << "ERROR: File database cannot open!" << userName;
return;
}
fDb->vacuumFileDb();
}
emit statusBarTextChanged(tr("Operation Vacuum has finished"), false);
}
bool Files::deleteAttachmentsFromDb(const QString &userName, qint64 msgId)
{
qDebug("%s()", __func__);
FileDb *fDb = NULL;
fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation, userName,
AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == NULL) {
qDebug() << "ERROR: File database cannot open!" << userName;
return false;
}
if (fDb->deleteFilesFromDb(msgId)) {
MessageDb *msgDb = NULL;
msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (msgDb == NULL) {
qDebug() << "ERROR: Message database cannot open!";
return false;
}
return msgDb->setAttachmentDownloaded(msgId, false);
}
return false;
}
bool Files::fileReadable(const QString &filePath)
{
if (filePath.isEmpty()) {
Q_ASSERT(0);
qCritical() << "Target ZFO path is empty!";
return false;
}
{
QFileInfo fileInfo(filePath);
if (!fileInfo.isFile() || !fileInfo.isReadable()) {
qCritical() << "Cannot open ZFO file from" << filePath;
return false;
}
}
return true;
}
bool Files::isZfoFile(const QString &fileName)
{
return QFileInfo(fileName).suffix().toLower() == QStringLiteral("zfo");
}
QByteArray Files::rawFileContent(const QString &filePath)
{
if (!fileReadable(filePath)) {
return QByteArray();
}
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
Q_ASSERT(0);
qCritical() << "Cannot open file" << filePath;
return QByteArray();
}
QByteArray rawData(file.readAll());
file.close();
return rawData;
}
QByteArray Files::base64ToRaw(const QByteArray &base64Data)
{
return QByteArray::fromBase64(base64Data);
}
MsgInfo *Files::zfoData(const QVariant &attachModelVariant,
const QByteArray &rawZfoData)
{
enum MsgInfo::ZfoType type = MsgInfo::TYPE_UNKNOWN;
QString idStr, annot, htmlDescr, emailBody;
bool ret = parseXmlData(&type, &idStr, &annot, &htmlDescr,
FileListModel::fromVariant(attachModelVariant),
&emailBody, getXmlFromCms(rawZfoData));
return ret ?
new (std::nothrow) MsgInfo(type, idStr, annot, htmlDescr,
emailBody) :
new (std::nothrow) MsgInfo();
}
bool Files::setAttachmentModel(FileListModel &attachModel,
const QString &userName, qint64 msgId)
{
qDebug("%s()", __func__);
FileDb *fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == Q_NULLPTR) {
qCritical() << "Cannot open file database!";
return false;
}
attachModel.clearAll();
fDb->getFileListFromDb(attachModel, msgId);
return true;
}
void Files::sendAttachmentEmailZfo(const QVariant &attachModelVariant,
const QString &msgIdStr, QString subject, QString body)
{
qDebug("%s()", __func__);
/* Obtain pointer to attachment model. */
const FileListModel *attachModel =
FileListModel::fromVariant(attachModelVariant);
if (attachModel == Q_NULLPTR) {
Q_ASSERT(0);
return;
}
/* Obtain message identifier. */
bool ok = false;
qint64 msgId = msgIdStr.toLongLong(&ok);
if (!ok || (msgId < 0)) {
return;
}
QStringList fileList;
const QString boundary = generateBoundaryString();
QString emailMessage = createEmailMessage(body, subject, boundary);
deleteFilesFromDir(EMAIL_DIR_NAME);
for (int row = 0; row < attachModel->rowCount(); ++row) {
QModelIndex idx(attachModel->index(row));
/*
* On Android the attachment must be saved and the explicitly
* add into the email message.
*/
QByteArray base64Data(attachModel->data(idx,
FileListModel::ROLE_FILE_DATA).toByteArray());
QString attachName(attachModel->data(idx,
FileListModel::ROLE_FILE_NAME).toString());
QString filePath(writeFileToEmailDir(attachName, msgId,
base64ToRaw(base64Data)));
fileList.append(filePath);
addAttachmentToEmailMessage(emailMessage, attachName,
base64Data, boundary);
}
finishEmailMessage(emailMessage, boundary);
sendEmail(emailMessage, fileList, subject, body, msgId);
}
void Files::saveAttachmentsToDiskDb(const QString &userName,
const QString &msgIdStr)
{
qDebug("%s()", __func__);
/* User name must be supplied. */
if (userName.isEmpty()) {
Q_ASSERT(0);
return;
}
/* Obtain message identifier. */
bool ok = false;
qint64 msgId = msgIdStr.toLongLong(&ok);
if (!ok || (msgId < 0)) {
return;
}
QList filelist;
{
FileDb *fDb = Q_NULLPTR;
fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation, userName,
AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == Q_NULLPTR) {
qCritical() << "Cannot open file database!";
return;
}
filelist = fDb->getFilesFromDb(msgId);
if (filelist.isEmpty()) {
qCritical() << "File list is empty!";
return;
}
}
QString destPath;
foreach (const FileDb::FileData &file, filelist) {
destPath = writeFileToDir(fileSaveLocation(), file.filename,
msgId, base64ToRaw(file.content.toUtf8()));
}
attachmentSavingNotification(destPath);
}
void Files::saveAttachmentsToDiskZfo(const QVariant &attachModelVariant,
const QString &msgIdStr)
{
qDebug("%s()", __func__);
/* Obtain pointer to attachment model. */
const FileListModel *attachModel =
FileListModel::fromVariant(attachModelVariant);
if (attachModel == Q_NULLPTR) {
Q_ASSERT(0);
return;
}
/* Obtain message identifier. */
bool ok = false;
qint64 msgId = msgIdStr.toLongLong(&ok);
if (!ok || (msgId < 0)) {
return;
}
QString destPath;
for (int row = 0; row < attachModel->rowCount(); ++row) {
QModelIndex idx(attachModel->index(row));
destPath = writeFileToDir(fileSaveLocation(),
attachModel->data(idx,
FileListModel::ROLE_FILE_NAME).toString(),
msgId,
base64ToRaw(attachModel->data(idx,
FileListModel::ROLE_FILE_DATA).toByteArray()));
}
attachmentSavingNotification(destPath);
}
void Files::deleteTmpFileFromStorage(const QString &filePath)
{
#if defined Q_OS_IOS
QFile file(filePath);
file.remove();
#else
Q_UNUSED(filePath);
#endif /* defined Q_OS_IOS */
}
void Files::sendEmail(const QString &emailMessage, const QStringList &fileList,
const QString &subject, const QString &body, qint64 msgId)
{
if (!fileList.isEmpty()) {
#if defined Q_OS_IOS
UrlOpener urlOpener;
urlOpener.createEmail(body, subject, fileList);
#elif defined Q_OS_ANDROID
QDesktopServices::openUrl(QUrl("mailto:?subject=" +
subject + "&body=" + body));
#elif defined Q_OS_WINRT
QDesktopServices::openUrl(QUrl("mailto:?subject=" +
subject + "&body=" + body));
#else
QString tmpEmailFile = writeFileToEmailDir(QString::number(msgId)
+ "_mail.eml", msgId, emailMessage.toUtf8());
QDesktopServices::openUrl(QUrl::fromLocalFile(tmpEmailFile));
#endif
/* TODO -- Handle openUrl() return value. */
} else {
qDebug() << "Tmp file save error";
}
Q_UNUSED(subject);
Q_UNUSED(body);
Q_UNUSED(emailMessage);
Q_UNUSED(msgId);
}
QByteArray Files::getXmlFromCms(const QByteArray &rawData)
{
qDebug("%s()", __func__);
if (rawData.isEmpty()) {
Q_ASSERT(0);
qCritical() << "File content is empty!";
return QByteArray();
}
/* Decode CMS and obtain message XML data - uses OpenSSL. */
void *xmlContent = NULL;
size_t xmlContentLen = 0;
if (extract_cms_data(rawData.data(), rawData.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;
}
QByteArray Files::decodeZfoFile(const QByteArray &base64ZfoData)
{
qDebug("%s()", __func__);
if (base64ZfoData.isEmpty()) {
Q_ASSERT(0);
qCritical() << "File content is empty.";
return QByteArray();
}
/* decode signature from base64 and obtain something CMS message */
return getXmlFromCms(base64ToRaw(base64ZfoData));
}
bool Files::parseXmlData(enum MsgInfo::ZfoType *type, QString *idStr,
QString *annotation, QString *msgDescrHtml, FileListModel *attachModel,
QString *emailBody, QByteArray xmlData)
{
qDebug("%s()", __func__);
if (xmlData.isEmpty()) {
qCritical() << "XML content is empty!";
return false;
}
xmlData.prepend(""
""
"");
xmlData.append("");
/* Test if zfo is message, delivery info or unknown format */
if (xmlData.contains(QByteArray("MessageDownloadResponse"))) {
if (type != Q_NULLPTR) {
*type = MsgInfo::TYPE_MESSAGE;
}
return parseAndShowXmlData(MsgInfo::TYPE_MESSAGE, idStr,
annotation, msgDescrHtml, attachModel, emailBody, xmlData);
} else if (xmlData.contains(QByteArray("GetDeliveryInfoResponse"))) {
if (type != Q_NULLPTR) {
*type = MsgInfo::TYPE_DELIVERY_INFO;
}
return parseAndShowXmlData(MsgInfo::TYPE_DELIVERY_INFO, idStr,
annotation, msgDescrHtml, attachModel, emailBody, xmlData);
} else {
if (type != Q_NULLPTR) {
*type = MsgInfo::TYPE_UNKNOWN;
}
qCritical() << "Unknown ZFO format";
}
return false;
}
bool Files::parseAndShowXmlData(enum MsgInfo::ZfoType type, QString *idStr,
QString *annotation, QString *msgDescrHtml, FileListModel *attachModel,
QString *emailBody, QByteArray &xmlData)
{
qDebug("%s()", __func__);
QXmlStreamReader xml;
XmlLayer xmlLayer;
MsgEnvelope msg;
QList fileList;
QList eventList;
if (type == MsgInfo::TYPE_UNKNOWN) {
Q_ASSERT(0);
return false;
}
/* parse message envelope and files */
xml.addData(xmlData);
while(!xml.atEnd() && !xml.hasError()) {
QXmlStreamReader::TokenType token = xml.readNext();
if (xml.error() != QXmlStreamReader::NoError) {
return false;
}
if (token == QXmlStreamReader::StartDocument) {
continue;
}
if (token == QXmlStreamReader::StartElement) {
if (xml.name() == "dmDm") {
xmlLayer.completeMessageParse(xml, msg, fileList);
}
}
}
if (type == MsgInfo::TYPE_DELIVERY_INFO) {
/* parse delivery info */
xml.clear();
xml.addData(xmlData);
while(!xml.atEnd() && !xml.hasError()){
QXmlStreamReader::TokenType token = xml.readNext();
if (token == QXmlStreamReader::StartDocument) {
continue;
}
if (token == QXmlStreamReader::StartElement) {
if (xml.name() == "dmEvent") {
eventList.append(xmlLayer.parseEvent(xml));
}
}
}
}
QString html = divStart;
html += "" + QObject::tr("General") + "
";
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 += "" + QObject::tr("Sender") + "
";
html += strongInfoLine(QObject::tr("Databox ID"), msg.dbIDSender());
html += strongInfoLine(QObject::tr("Name"), msg.dmSender());
html += strongInfoLine(QObject::tr("Address"),msg.dmSenderAddress());
html += "" + QObject::tr("Recipient") + "
";
html += strongInfoLine(QObject::tr("Databox ID"), msg.dbIDRecipient());
html += strongInfoLine(QObject::tr("Name"), msg.dmRecipient());
html += strongInfoLine(QObject::tr("Address"),msg.dmRecipientAddress());
if (!msg.dmToHands().isEmpty()) {
html += strongInfoLine(QObject::tr("To hands"),
msg.dmToHands());
}
QString tmpHtml;
if (!msg.dmSenderIdent().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Our file mark"),
msg.dmSenderIdent());
}
if (!msg.dmSenderRefNumber().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Our reference number"),
msg.dmSenderRefNumber());
}
if (!msg.dmRecipientIdent().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Your file mark"),
msg.dmRecipientIdent());
}
if (!msg.dmRecipientRefNumber().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Your reference number"),
msg.dmRecipientRefNumber());
}
if (!msg.dmLegalTitleLaw().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Law"),
msg.dmLegalTitleLaw());
}
if (!msg.dmLegalTitleYear().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Year"),
msg.dmLegalTitleYear());
}
if (!msg.dmLegalTitleSect().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Section"),
msg.dmLegalTitleSect());
}
if (!msg.dmLegalTitlePar().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Paragraph"),
msg.dmLegalTitlePar());
}
if (!msg.dmLegalTitlePoint().isEmpty()) {
tmpHtml += strongInfoLine(QObject::tr("Letter"),
msg.dmLegalTitlePoint());
}
if (!tmpHtml.isEmpty()) {
html += "" + QObject::tr("Additional info") + "
";
html += tmpHtml;
}
html += "" + QObject::tr("Message state") + "
";
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()));
if (type == MsgInfo::TYPE_DELIVERY_INFO) {
html += "" + QObject::tr("Events") + "
";
foreach (const Messages::Event &event, eventList) {
html += divStart +
strongInfoLine(dateTimeStrFromDbFormat(
dateTimeStrToUTCDbFormat(event.dmEventTime),
DATETIME_QML_FORMAT), event.dmEventDescr)
+ divEnd;
}
}
html += divEnd;
// Create body for email
QString body = generateEmailBodyText(msg.dmID(), msg.dmSender(),
msg.dmRecipient(), dateTimeStrFromDbFormat(
dateTimeStrToUTCDbFormat(msg.dmAcceptanceTime()),
DATETIME_QML_FORMAT));
if (idStr != Q_NULLPTR) {
*idStr = QString::number(msg.dmID());
}
if (annotation != Q_NULLPTR) {
*annotation = msg.dmAnnotation();
}
if (msgDescrHtml != Q_NULLPTR) {
*msgDescrHtml = html;
}
if (attachModel != Q_NULLPTR) {
attachModel->clearAll();
foreach (const AttachmentData &file, fileList) {
attachModel->appendFileEntry(FileListModel::Entry(-1, file.dmFileDescr(),
file._dmFileSize(), file._icon(), file.dmEncodedContent(), QString()));
}
}
if (emailBody != Q_NULLPTR) {
*emailBody = body;
}
return true;
}