File indexing completed on 2024-09-08 04:54:27
0001 // SPDX-FileCopyrightText: 2021 Simon Schmeisser <s.schmeisser@gmx.net> 0002 // SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org> 0003 // SPDX-License-Identifier: GPL-3.0-or-later 0004 0005 #include "mailmodel.h" 0006 0007 #include "messagestatus.h" 0008 #include <Akonadi/EntityTreeModel> 0009 #include <Akonadi/ItemModifyJob> 0010 #include <Akonadi/MessageStatus> 0011 #include <KFormat> 0012 #include <KLocalizedString> 0013 #include <KMime/Message> 0014 #include <QQmlEngine> 0015 0016 MailModel::MailModel(QObject *parent) 0017 : QSortFilterProxyModel(parent) 0018 { 0019 } 0020 0021 QHash<int, QByteArray> MailModel::roleNames() const 0022 { 0023 return { 0024 {TitleRole, QByteArrayLiteral("title")}, 0025 {DateRole, QByteArrayLiteral("date")}, 0026 {DateTimeRole, QByteArrayLiteral("datetime")}, 0027 {SenderRole, QByteArrayLiteral("sender")}, 0028 {FromRole, QByteArrayLiteral("from")}, 0029 {ToRole, QByteArrayLiteral("to")}, 0030 {StatusRole, QByteArrayLiteral("status")}, 0031 {FavoriteRole, QByteArrayLiteral("favorite")}, 0032 {TextColorRole, QByteArrayLiteral("textColor")}, 0033 {BackgroundColorRole, QByteArrayLiteral("backgroudColor")}, 0034 {ItemRole, QByteArrayLiteral("item")}, 0035 }; 0036 } 0037 0038 QVariant MailModel::data(const QModelIndex &index, int role) const 0039 { 0040 QVariant itemVariant = sourceModel()->data(mapToSource(index), Akonadi::EntityTreeModel::ItemRole); 0041 0042 Akonadi::Item item = itemVariant.value<Akonadi::Item>(); 0043 0044 if (!item.hasPayload<KMime::Message::Ptr>()) { 0045 return {}; 0046 } 0047 const KMime::Message::Ptr mail = item.payload<KMime::Message::Ptr>(); 0048 0049 // Static for speed reasons 0050 static const QString noSubject = i18nc("displayed as subject when the subject of a mail is empty", "No Subject"); 0051 static const QString unknown(i18nc("displayed when a mail has unknown sender, receiver or date", "Unknown")); 0052 0053 QString subject = mail->subject()->asUnicodeString(); 0054 if (subject.isEmpty()) { 0055 subject = QLatin1Char('(') + noSubject + QLatin1Char(')'); 0056 } 0057 0058 MessageStatus stat; 0059 stat.setStatusFromFlags(item.flags()); 0060 0061 // NOTE: remember to update AkonadiBrowserSortModel::lessThan if you insert/move columns 0062 switch (role) { 0063 case TitleRole: 0064 if (mail->subject()) { 0065 return mail->subject()->asUnicodeString(); 0066 } else { 0067 return noSubject; 0068 } 0069 case FromRole: 0070 if (mail->from()) { 0071 return mail->from()->asUnicodeString(); 0072 } else { 0073 return QString(); 0074 } 0075 case SenderRole: 0076 if (mail->sender()) { 0077 return mail->sender()->asUnicodeString(); 0078 } else { 0079 return QString(); 0080 } 0081 case ToRole: 0082 if (mail->to()) { 0083 return mail->to()->asUnicodeString(); 0084 } else { 0085 return unknown; 0086 } 0087 case DateRole: 0088 if (mail->date()) { 0089 KFormat format; 0090 return format.formatRelativeDate(mail->date()->dateTime().date(), QLocale::LongFormat); 0091 } else { 0092 return QString(); 0093 } 0094 case DateTimeRole: 0095 if (mail->date()) { 0096 return mail->date()->dateTime(); 0097 } else { 0098 return QString(); 0099 } 0100 case StatusRole: 0101 return QVariant::fromValue(stat); 0102 case ItemRole: 0103 return QVariant::fromValue(item); 0104 } 0105 0106 return {}; 0107 } 0108 0109 Akonadi::Item MailModel::itemForRow(int row) const 0110 { 0111 return data(index(row, 0), ItemRole).value<Akonadi::Item>(); 0112 } 0113 0114 void MailModel::updateMessageStatus(int row, MessageStatus messageStatus) 0115 { 0116 Akonadi::Item item = itemForRow(row); 0117 item.setFlags(messageStatus.statusFlags()); 0118 auto job = new Akonadi::ItemModifyJob(item, this); 0119 job->disableRevisionCheck(); 0120 job->setIgnorePayload(true); 0121 0122 Q_EMIT dataChanged(index(row, 0), index(row, 0), {StatusRole}); 0123 } 0124 0125 MessageStatus MailModel::copyMessageStatus(MessageStatus messageStatus) 0126 { 0127 MessageStatus newStatus; 0128 newStatus.set(messageStatus); 0129 return messageStatus; 0130 } 0131 0132 QString MailModel::searchString() const 0133 { 0134 return m_searchString; 0135 } 0136 0137 void MailModel::setSearchString(const QString &searchString) 0138 { 0139 if (searchString == m_searchString) { 0140 return; 0141 } 0142 m_searchString = searchString; 0143 invalidateFilter(); 0144 Q_EMIT searchStringChanged(); 0145 } 0146 0147 bool MailModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 0148 { 0149 Q_UNUSED(sourceParent) 0150 if (m_searchString.isEmpty()) { 0151 return true; 0152 } 0153 QVariant itemVariant = sourceModel()->index(sourceRow, 0).data(Akonadi::EntityTreeModel::ItemRole); 0154 0155 Akonadi::Item item = itemVariant.value<Akonadi::Item>(); 0156 0157 if (!item.hasPayload<KMime::Message::Ptr>()) { 0158 return false; 0159 } 0160 const KMime::Message::Ptr mail = item.payload<KMime::Message::Ptr>(); 0161 0162 if (mail->subject() && mail->subject()->asUnicodeString().contains(m_searchString)) { 0163 return true; 0164 } 0165 if (mail->from() && mail->from()->asUnicodeString().contains(m_searchString)) { 0166 return true; 0167 } 0168 return false; 0169 }