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