Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
PIM
Kalendar
Commits
f295a3df
Commit
f295a3df
authored
Jun 12, 2022
by
Carl Schwan
🚴
Committed by
Claudio Cambra
Aug 04, 2022
Browse files
Display email
Signed-off-by:
Carl Schwan
<
carl@carlschwan.eu
>
parent
d849ea9d
Changes
12
Hide whitespace changes
Inline
Side-by-side
src/mail/CMakeLists.txt
View file @
f295a3df
...
...
@@ -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
...
...
src/mail/mailmodel.cpp
View file @
f295a3df
...
...
@@ -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
Sender
Role
:
case
From
Role
:
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
::
Short
Format
);
return
format
.
formatRelativeDate
(
mail
->
date
()
->
dateTime
().
date
(),
QLocale
::
Long
Format
);
}
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
{};
...
...
src/mail/mailmodel.h
View file @
f295a3df
...
...
@@ -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
);
...
...
src/mail/mailplugin.cpp
View file @
f295a3df
...
...
@@ -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*"
);
}
src/mail/mime/messageparser.cpp
View file @
f295a3df
...
...
@@ -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
::
set
Message
(
const
QVariant
&
message
)
void
MessageParser
::
set
Item
(
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
;
}
src/mail/mime/messageparser.h
View file @
f295a3df
...
...
@@ -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
setMessa
ge
)
Q_PROPERTY
(
Akonadi
::
Item
item
READ
item
WRITE
setItem
NOTIFY
htmlChan
ge
d
)
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
set
Message
(
const
QVariant
&
to
);
Akonadi
::
Item
item
()
const
;
void
set
Item
(
const
Akonadi
::
Item
&
item
);
QAbstractItemModel
*
parts
()
const
;
QAbstractItemModel
*
attachments
()
const
;
QString
rawContent
()
const
;
...
...
src/mail/qml/ConversationViewer.qml
0 → 100644
View file @
f295a3df
// 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
}
}
}
src/mail/qml/FolderView.qml
View file @
f295a3df
...
...
@@ -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
,
})
}
}
}
...
...
src/mail/qml/MailViewer.qml
0 → 100644
View file @
f295a3df
// 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
}
}
src/mail/qml/mailpartview/MailPartModel.qml
View file @
f295a3df
...
...
@@ -64,8 +64,8 @@ DelegateModel {
id: buttons
anchors.left: parent.left
anchors.top: parent.top
anchors.rightMargin: K
ube
.Units.smallSpacing
spacing: K
ube
.Units.smallSpacing
anchors.rightMargin: K
irigami
.Units.smallSpacing
spacing: K
irigami
.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
:
K
ube
.
Units
.
smallSpacing
anchors.topMargin
:
K
irigami
.
Units
.
smallSpacing
anchors.top
:
buttons
.
bottom
anchors.bottom
:
partLoader
.
bottom
anchors.right
:
buttons
.
right
...
...
src/mail/qml/mailpartview/MailPartView.qml
View file @
f295a3df
/*
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
}
}
src/mail/qml/mailpartview/TextPart.qml
View file @
f295a3df
...
...
@@ -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
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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