Commit f295a3df authored by Carl Schwan's avatar Carl Schwan 🚴 Committed by Claudio Cambra
Browse files

Display email



Signed-off-by: Carl Schwan's avatarCarl Schwan <carl@carlschwan.eu>
parent d849ea9d
......@@ -33,10 +33,12 @@ target_sources(kalendar_mail_plugin PRIVATE
ecm_target_qml_sources(kalendar_mail_plugin SOURCES
qml/MailSidebar.qml
qml/FolderView.qml
qml/MailViewer.qml
qml/ConversationViewer.qml
)
ecm_target_qml_sources(kalendar_contact_plugin
PRIVATE PATH private SOURCES
ecm_target_qml_sources(kalendar_mail_plugin
PRIVATE PATH mailpartview SOURCES
qml/mailpartview/HtmlPart.qml
qml/mailpartview/ICalPart.qml
qml/mailpartview/MailPart.qml
......
......@@ -13,6 +13,7 @@
#include <KMime/Message>
#include <QQmlEngine>
#include <kformat.h>
#include <qvariant.h>
MailModel::MailModel(QObject *parent)
: QIdentityProxyModel(parent)
......@@ -27,10 +28,13 @@ QHash<int, QByteArray> MailModel::roleNames() const
{DateRole, QByteArrayLiteral("date")},
{DateTimeRole, QByteArrayLiteral("datetime")},
{SenderRole, QByteArrayLiteral("sender")},
{FromRole, QByteArrayLiteral("from")},
{ToRole, QByteArrayLiteral("to")},
{UnreadRole, QByteArrayLiteral("unread")},
{FavoriteRole, QByteArrayLiteral("favorite")},
{TextColorRole, QByteArrayLiteral("textColor")},
{BackgroundColorRole, QByteArrayLiteral("backgroudColor")},
{ItemRole, QByteArrayLiteral("item")},
};
}
......@@ -99,31 +103,39 @@ QVariant MailModel::data(const QModelIndex &index, int role) const
} else {
return QStringLiteral("(No subject)");
}
case SenderRole:
case FromRole:
if (mail->from()) {
return mail->from()->asUnicodeString();
} else {
return QString();
}
case SenderRole:
if (mail->sender()) {
return mail->sender()->asUnicodeString();
} else {
return QString();
}
case ToRole:
if (mail->to()) {
return mail->sender()->asUnicodeString();
} else {
return QString();
}
case DateRole:
if (mail->date()) {
KFormat format;
return format.formatRelativeDate(mail->date()->dateTime().date(), QLocale::ShortFormat);
return format.formatRelativeDate(mail->date()->dateTime().date(), QLocale::LongFormat);
} else {
return QString();
}
case DateTimeRole:
if (mail->date()) {
return mail->date()->asUnicodeString();
return mail->date()->dateTime();
} else {
return QString();
}
case MailRole:
{
//auto wrapper = new MessageWrapper(item);
//QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership);
//return QVariant::fromValue(wrapper);
}
case ItemRole:
return QVariant::fromValue(item);
}
return {};
......
......@@ -18,13 +18,15 @@ public:
enum AnimalRoles {
TitleRole = Qt::UserRole + 1,
SenderRole,
FromRole,
ToRole,
TextColorRole,
DateRole,
DateTimeRole,
BackgroundColorRole,
UnreadRole,
MailRole,
FavoriteRole,
ItemRole,
};
explicit MailModel(QObject *parent = nullptr);
......
......@@ -9,6 +9,8 @@
#include "mailmanager.h"
#include "mailmodel.h"
#include "mime/htmlutils.h"
#include "mime/messageparser.h"
void CalendarPlugin::registerTypes(const char *uri)
{
......@@ -19,5 +21,14 @@ void CalendarPlugin::registerTypes(const char *uri)
Q_UNUSED(scriptEngine)
return new MailManager;
});
qmlRegisterSingletonType<HtmlUtils::HtmlUtils>("org.kde.kalendar.mail", 1, 0, "HtmlUtils", [](QQmlEngine *engine, QJSEngine *scriptEngine) {
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return new HtmlUtils::HtmlUtils;
});
qmlRegisterType<MessageParser>(uri, 1, 0, "MessageParser");
qRegisterMetaType<MailModel*>("MailModel*");
}
......@@ -19,6 +19,9 @@
#include "messageparser.h"
#include "../mimetreeparser/objecttreeparser.h"
#include <Akonadi/Item>
#include <Akonadi/ItemFetchJob>
#include <Akonadi/ItemFetchScope>
#include <QElapsedTimer>
#include "async.h"
......@@ -41,30 +44,33 @@ MessageParser::~MessageParser()
{
}
QVariant MessageParser::message() const
Akonadi::Item MessageParser::item() const
{
return {};
}
void MessageParser::setMessage(const QVariant &message)
void MessageParser::setItem(const Akonadi::Item &item)
{
mRawContent = message.toString();
asyncRun<std::shared_ptr<MimeTreeParser::ObjectTreeParser>>(
this,
[=] {
auto job = new Akonadi::ItemFetchJob(item);
job->fetchScope().fetchFullPayload();
connect(job, &Akonadi::ItemFetchJob::result, this, [this](KJob *job) {
auto fetchJob = qobject_cast<Akonadi::ItemFetchJob *>(job);
auto item = fetchJob->items().at(0);
if (item.hasPayload<KMime::Message::Ptr>()) {
const auto message = item.payload<KMime::Message::Ptr>();
QElapsedTimer time;
time.start();
auto parser = std::make_shared<MimeTreeParser::ObjectTreeParser>();
parser->parseObjectTree(message.toByteArray());
parser->parseObjectTree(message.data());
qDebug() << "Message parsing took: " << time.elapsed();
parser->decryptParts();
qDebug() << "Message parsing and decryption/verification: " << time.elapsed();
return parser;
},
[this](const std::shared_ptr<MimeTreeParser::ObjectTreeParser> &parser) {
d->mParser = parser;
Q_EMIT htmlChanged();
});
} else {
qWarning() << "This is not a mime item.";
}
});
}
QString MessageParser::rawContent() const
......@@ -91,7 +97,6 @@ QAbstractItemModel *MessageParser::parts() const
return nullptr;
}
const auto model = new PartModel(d->mParser);
// new ModelTest(model, model);
return model;
}
......@@ -101,6 +106,5 @@ QAbstractItemModel *MessageParser::attachments() const
return nullptr;
}
const auto model = new AttachmentModel(d->mParser);
// new ModelTest(model, model);
return model;
}
......@@ -22,6 +22,7 @@
#include <QString>
#include <QStringList>
#include <Akonadi/Item>
#include <QAbstractItemModel>
#include <QModelIndex>
......@@ -39,7 +40,7 @@ class ObjectTreeParser;
class MessageParser : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant message READ message WRITE setMessage)
Q_PROPERTY(Akonadi::Item item READ item WRITE setItem NOTIFY htmlChanged)
Q_PROPERTY(QAbstractItemModel *parts READ parts NOTIFY htmlChanged)
Q_PROPERTY(QAbstractItemModel *attachments READ attachments NOTIFY htmlChanged)
Q_PROPERTY(QString rawContent READ rawContent NOTIFY htmlChanged)
......@@ -50,8 +51,8 @@ public:
explicit MessageParser(QObject *parent = Q_NULLPTR);
~MessageParser();
QVariant message() const;
void setMessage(const QVariant &to);
Akonadi::Item item() const;
void setItem(const Akonadi::Item &item);
QAbstractItemModel *parts() const;
QAbstractItemModel *attachments() const;
QString rawContent() const;
......
// SPDX-FileCopyrightText: 2016 Michael Bohlender <michael.bohlender@kdemail.net>
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
import QtQuick 2.15
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.14 as Kirigami
import QtQuick.Controls 2.15 as QQC2
import org.kde.kalendar 1.0
import org.kde.kalendar.mail 1.0
import org.kde.kitemmodels 1.0 as KItemModels
import './mailpartview'
Kirigami.ScrollablePage {
id: root
title: props.title
readonly property int mode: KalendarApplication.Mail
property var item
property var props
ColumnLayout {
// TODO use repeater to see the full conversation
MailViewer {
item: root.item
subject: props.title
from: props.from
to: props.to
sender: props.sender
dateTime: props.datetime
}
}
}
......@@ -22,17 +22,12 @@ import org.kde.kitemmodels 1.0 as KItemModels
section.property: "date"
delegate: Kirigami.BasicListItem {
label: model.title
subtitle: sender
subtitle: model.from
onClicked: {
if (!folderView.mailViewer) {
folderView.mailViewer = root.pageStack.push(mailComponent, {
viewerHelper: MailManager.folderModel.viewerHelper
});
} else {
applicationWindow().pageStack.currentIndex = applicationWindow().pageStack.depth - 1;
}
QuickMail.folderModel.loadItem(index);
applicationWindow().pageStack.push(Qt.resolvedUrl('ConversationViewer.qml'), {
item: model.item,
props: model,
})
}
}
}
......
// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
import QtQuick 2.15
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.14 as Kirigami
import QtQuick.Controls 2.15 as QQC2
import org.kde.kalendar 1.0
import org.kde.kalendar.mail 1.0
import org.kde.kitemmodels 1.0 as KItemModels
import './mailpartview'
QQC2.Page {
id: root
property var item
property string subject
property string from
property string sender
property string to
property date dateTime
Layout.fillWidth: true
header: QQC2.ToolBar {
topInset: 1
leftInset: 1
rightInset: 1
bottomInset: 1
leftPadding: Kirigami.Units.largeSpacing
rightPadding: Kirigami.Units.largeSpacing
topPadding: Kirigami.Units.largeSpacing
bottomPadding: Kirigami.Units.largeSpacing
background: Item {
implicitHeight: 40
Kirigami.Separator {
anchors {
left: parent.left
right: parent.right
top: undefined
bottom: parent.bottom
}
}
}
contentItem: GridLayout {
columns: 3
QQC2.Label {
text: i18n('From:')
Layout.rightMargin: Kirigami.Units.largeSpacing
}
QQC2.Label {
text: root.from
}
QQC2.Label {
text: root.dateTime.toLocaleString()
Layout.fillWidth: true
horizontalAlignment: Text.AlignRight
}
QQC2.Label {
text: i18n('To:')
Layout.rightMargin: Kirigami.Units.largeSpacing
}
QQC2.Label {
text: root.to
}
}
}
contentItem: MailPartView {
item: root.item
}
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
background: Rectangle {
color: Kirigami.Theme.backgroundColor
property color borderColor: Kirigami.Theme.textColor
border.color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3)
radius: 4
}
}
......@@ -64,8 +64,8 @@ DelegateModel {
id: buttons
anchors.left: parent.left
anchors.top: parent.top
anchors.rightMargin: Kube.Units.smallSpacing
spacing: Kube.Units.smallSpacing
anchors.rightMargin: Kirigami.Units.smallSpacing
spacing: Kirigami.Units.smallSpacing
Kube.IconButton {
id: encryptedButton
width: Kube.Units.gridUnit
......@@ -94,7 +94,7 @@ DelegateModel {
Rectangle {
id: border
visible: encryptedButton.hovered || signedButton.hovered
anchors.topMargin: Kube.Units.smallSpacing
anchors.topMargin: Kirigami.Units.smallSpacing
anchors.top: buttons.bottom
anchors.bottom: partLoader.bottom
anchors.right: buttons.right
......
/*
Copyright (C) 2016 Michael Bohlender, <michael.bohlender@kdemail.net>
// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
// SPDX-FileCopyrightText: 2016 Michael Bohlender <michael.bohlender@kdemail.net>
// SPDX-License-Identifier: GPL-2.0-or-later
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 2 of the License, or
(at your option) any later version.
import QtQuick 2.15
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.14 as Kirigami
import QtQuick.Controls 2.15 as Controls
import org.kde.kalendar 1.0
import org.kde.kalendar.mail 1.0
import org.kde.kitemmodels 1.0 as KItemModels
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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import QtQuick 2.4
import org.kde.kirigami 2.19 as Kirigami
Kirigami.ScrollablePage {
ListView {
id: root
implicitHeight: contentHeight
property var item
property alias rootIndex: visualModel.rootIndex
property alias model: visualModel.model
property alias searchString: visualModel.searchString
property alias autoLoadImages: visualModel.autoLoadImages
property var attachmentModel: messageParser.attachments
ListView {
id: partListView
spacing: 5
height: contentHeight
width: parent.width - 10
interactive: false
model: MailPartModel {
id: visualModel
}
interactive: false
spacing: Kirigami.Units.smallSpacing
model: MailPartModel {
id: visualModel
model: messageParser.parts
}
MessageParser {
id: messageParser
item: root.item
}
}
......@@ -3,7 +3,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
import QtQuick 2.7
import QtQuick.Controls 2
import QtQuick.Controls 2.15 as QQC2
import org.kde.kalendar 1.0
import org.kde.kalendar.mail 1.0
......@@ -28,6 +28,9 @@ Item {
QQC2.TextArea {
id: textEdit
objectName: "textView"
background: Item {}
readOnly: true
textFormat: TextEdit.RichText
anchors {
top: parent.top
......
Supports Markdown
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