1 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>
3 This file is part of the Trojita Qt IMAP e-mail client,
4 http://trojita.flaska.net/
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of
9 the License or (at your option) version 3 or any later version
10 accepted by the membership of KDE e.V. (or its successor approved
11 by the membership of KDE e.V.), which shall act as a proxy
12 defined in Section 14 of version 3 of the license.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "OneMessageModel.h"
24 #include "kdeui-itemviews/kdescendantsproxymodel.h"
25 #include "FindInterestingPart.h"
26 #include "ItemRoles.h"
28 #include "SubtreeModel.h"
29 #include "Imap/Network/MsgPartNetAccessManager.h"
36 OneMessageModel::OneMessageModel(Model
*model
): QObject(model
), m_subtree(0)
38 m_subtree
= new SubtreeModelOfModel(this);
39 m_subtree
->setSourceModel(model
);
40 connect(m_subtree
, &QAbstractItemModel::modelReset
, this, &OneMessageModel::envelopeChanged
);
41 connect(m_subtree
, &QAbstractItemModel::dataChanged
, this, &OneMessageModel::envelopeChanged
);
42 connect(this, &OneMessageModel::envelopeChanged
, this, &OneMessageModel::flagsChanged
);
43 connect(model
, &QAbstractItemModel::dataChanged
, this, &OneMessageModel::handleModelDataChanged
);
44 m_flatteningModel
= new KDescendantsProxyModel(this);
45 m_flatteningModel
->setSourceModel(m_subtree
);
46 QHash
<int, QByteArray
> roleNames
;
47 roleNames
[RoleIsFetched
] = "isFetched";
48 roleNames
[RolePartMimeType
] = "mimeType";
49 roleNames
[RolePartCharset
] = "charset";
50 roleNames
[RolePartContentFormat
] = "contentFormat";
51 roleNames
[RolePartEncoding
] = "encoding";
52 roleNames
[RolePartBodyFldId
] = "bodyFldId";
53 roleNames
[RolePartBodyDisposition
] = "bodyDisposition";
54 roleNames
[RolePartFileName
] = "fileName";
55 roleNames
[RolePartOctets
] = "size";
56 roleNames
[RolePartId
] = "partId";
57 roleNames
[RolePartPathToPart
] = "pathToPart";
58 m_flatteningModel
->proxySetRoleNames(roleNames
);
61 void OneMessageModel::setMessage(const QString
&mailbox
, const uint uid
)
63 m_mainPartUrl
= QUrl(QStringLiteral("about:blank"));
64 emit
mainPartUrlChanged();
65 QAbstractItemModel
*abstractModel
= qobject_cast
<QAbstractItemModel
*>(QObject::parent());
66 Q_ASSERT(abstractModel
);
67 Model
*model
= qobject_cast
<Model
*>(abstractModel
);
69 setMessage(model
->messageIndexByUid(mailbox
, uid
));
72 void OneMessageModel::setMessage(const QModelIndex
&message
)
74 Q_ASSERT(!message
.isValid() || message
.model() == QObject::parent());
76 m_subtree
->setRootItem(message
);
78 // Now try to locate the interesting part of the current message
81 FindInterestingPart::MainPartReturnCode res
= FindInterestingPart::findMainPartOfMessage(m_message
, idx
, partMessage
, 0);
83 case Imap::Mailbox::FindInterestingPart::MAINPART_FOUND
:
84 case Imap::Mailbox::FindInterestingPart::MAINPART_PART_LOADING
:
85 Q_ASSERT(idx
.isValid());
86 m_mainPartUrl
= QLatin1String("trojita-imap://msg") + idx
.data(RolePartPathToPart
).toString();
88 case Imap::Mailbox::FindInterestingPart::MAINPART_MESSAGE_NOT_LOADED
:
90 m_mainPartUrl
= QLatin1String("data:text/plain;charset=utf-8;base64,") + QString::fromLocal8Bit(QByteArray("").toBase64());
92 case Imap::Mailbox::FindInterestingPart::MAINPART_PART_CANNOT_DETERMINE
:
93 // FIXME: show a decent message here
94 m_mainPartUrl
= QLatin1String("data:text/plain;charset=utf-8;base64,") + QString::fromLocal8Bit(QByteArray(partMessage
.toUtf8()).toBase64());
97 emit
mainPartUrlChanged();
100 QDateTime
OneMessageModel::date() const
102 return m_message
.data(RoleMessageDate
).toDateTime();
105 QDateTime
OneMessageModel::receivedDate() const
107 return m_message
.data(RoleMessageInternalDate
).toDateTime();
110 QString
OneMessageModel::subject() const
112 return m_message
.data(RoleMessageSubject
).toString();
115 QVariantList
OneMessageModel::from() const
117 return m_message
.data(RoleMessageFrom
).toList();
120 QVariantList
OneMessageModel::to() const
122 return m_message
.data(RoleMessageTo
).toList();
125 QVariantList
OneMessageModel::cc() const
127 return m_message
.data(RoleMessageCc
).toList();
130 QVariantList
OneMessageModel::bcc() const
132 return m_message
.data(RoleMessageBcc
).toList();
135 QVariantList
OneMessageModel::sender() const
137 return m_message
.data(RoleMessageSender
).toList();
140 QVariantList
OneMessageModel::replyTo() const
142 return m_message
.data(RoleMessageReplyTo
).toList();
145 QByteArray
OneMessageModel::inReplyTo() const
147 return m_message
.data(RoleMessageInReplyTo
).toByteArray();
150 QByteArray
OneMessageModel::messageId() const
152 return m_message
.data(RoleMessageMessageId
).toByteArray();
155 bool OneMessageModel::isMarkedDeleted() const
157 return m_message
.data(RoleMessageIsMarkedDeleted
).toBool();
160 bool OneMessageModel::isMarkedRead() const
162 return m_message
.data(RoleMessageIsMarkedRead
).toBool();
165 bool OneMessageModel::isMarkedForwarded() const
167 return m_message
.data(RoleMessageIsMarkedForwarded
).toBool();
170 bool OneMessageModel::isMarkedReplied() const
172 return m_message
.data(RoleMessageIsMarkedReplied
).toBool();
175 bool OneMessageModel::isMarkedRecent() const
177 return m_message
.data(RoleMessageIsMarkedRecent
).toBool();
180 bool OneMessageModel::isMarkedFlagged() const
182 return m_message
.data(RoleMessageIsMarkedFlagged
).toBool();
185 bool OneMessageModel::isMarkedJunk() const
187 return m_message
.data(RoleMessageIsMarkedJunk
).toBool() &&
188 !m_message
.data(RoleMessageIsMarkedNotJunk
).toBool();
191 bool OneMessageModel::isMarkedNotJunk() const
193 return (m_message
.data(RoleMessageIsMarkedNotJunk
).toBool() &&
194 !m_message
.data(RoleMessageIsMarkedJunk
).toBool());
198 QUrl
OneMessageModel::mainPartUrl() const
200 return m_mainPartUrl
;
203 QObject
*OneMessageModel::attachmentsModel() const
205 return m_flatteningModel
;
208 QModelIndex
OneMessageModel::mainPartModelIndex()
210 return Imap::Network::MsgPartNetAccessManager::pathToPart(
211 m_message
, m_mainPartUrl
.path().toUtf8());
214 void OneMessageModel::setMarkedDeleted(const bool marked
)
216 if (!m_message
.isValid())
219 qobject_cast
<Model
*>(parent())->markMessagesDeleted(QList
<QModelIndex
>() << m_message
, marked
? FLAG_ADD
: FLAG_REMOVE
);
222 void OneMessageModel::setMarkedRead(const bool marked
)
224 if (!m_message
.isValid())
227 qobject_cast
<Model
*>(parent())->markMessagesRead(QList
<QModelIndex
>() << m_message
, marked
? FLAG_ADD
: FLAG_REMOVE
);
230 void OneMessageModel::handleModelDataChanged(const QModelIndex
&topLeft
, const QModelIndex
&bottomRight
)
232 Q_ASSERT(topLeft
.row() == bottomRight
.row());
233 Q_ASSERT(topLeft
.parent() == bottomRight
.parent());
234 Q_ASSERT(topLeft
.model() == bottomRight
.model());
236 if (m_message
.isValid() && topLeft
== m_message
)
240 bool OneMessageModel::hasValidIndex() const
242 return m_message
.isValid();