File indexing completed on 2024-11-10 04:40:43
0001 /* 0002 SPDX-FileCopyrightText: 2009 Stephen Kelly <steveire@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "partfetcher.h" 0008 0009 #include "entitytreemodel.h" 0010 #include "itemfetchjob.h" 0011 #include "itemfetchscope.h" 0012 #include "session.h" 0013 #include <KLocalizedString> 0014 0015 Q_DECLARE_METATYPE(QSet<QByteArray>) 0016 0017 using namespace Akonadi; 0018 0019 namespace Akonadi 0020 { 0021 class PartFetcherPrivate 0022 { 0023 PartFetcherPrivate(PartFetcher *partFetcher, const QModelIndex &index, const QByteArray &partName) 0024 : m_persistentIndex(index) 0025 , m_partName(partName) 0026 , q_ptr(partFetcher) 0027 { 0028 } 0029 0030 void fetchJobDone(KJob *job); 0031 0032 void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); 0033 0034 QPersistentModelIndex m_persistentIndex; 0035 QByteArray m_partName; 0036 Item m_item; 0037 0038 Q_DECLARE_PUBLIC(PartFetcher) 0039 PartFetcher *q_ptr; 0040 }; 0041 0042 } // namespace Akonadi 0043 0044 void PartFetcherPrivate::fetchJobDone(KJob *job) 0045 { 0046 Q_Q(PartFetcher); 0047 if (job->error()) { 0048 q->setError(KJob::UserDefinedError); 0049 q->setErrorText(i18n("Unable to fetch item for index")); 0050 q->emitResult(); 0051 return; 0052 } 0053 0054 auto fetchJob = qobject_cast<ItemFetchJob *>(job); 0055 0056 const Item::List list = fetchJob->items(); 0057 0058 Q_ASSERT(list.size() == 1); 0059 0060 // If m_persistentIndex comes from a selection proxy model, it could become 0061 // invalid if the user clicks around a lot. 0062 if (!m_persistentIndex.isValid()) { 0063 q->setError(KJob::UserDefinedError); 0064 q->setErrorText(i18n("Index is no longer available")); 0065 q->emitResult(); 0066 return; 0067 } 0068 0069 const auto loadedParts = m_persistentIndex.data(EntityTreeModel::LoadedPartsRole).value<QSet<QByteArray>>(); 0070 0071 Q_ASSERT(!loadedParts.contains(m_partName)); 0072 0073 Item item = m_persistentIndex.data(EntityTreeModel::ItemRole).value<Item>(); 0074 0075 item.apply(list.at(0)); 0076 0077 auto model = const_cast<QAbstractItemModel *>(m_persistentIndex.model()); 0078 0079 Q_ASSERT(model); 0080 0081 QVariant itemVariant = QVariant::fromValue(item); 0082 model->setData(m_persistentIndex, itemVariant, EntityTreeModel::ItemRole); 0083 0084 m_item = item; 0085 0086 q->emitResult(); 0087 } 0088 0089 PartFetcher::PartFetcher(const QModelIndex &index, const QByteArray &partName, QObject *parent) 0090 : KJob(parent) 0091 , d_ptr(new PartFetcherPrivate(this, index, partName)) 0092 { 0093 } 0094 0095 PartFetcher::~PartFetcher() = default; 0096 0097 void PartFetcher::start() 0098 { 0099 Q_D(PartFetcher); 0100 0101 const QModelIndex index = d->m_persistentIndex; 0102 0103 const auto loadedParts = index.data(EntityTreeModel::LoadedPartsRole).value<QSet<QByteArray>>(); 0104 0105 if (loadedParts.contains(d->m_partName)) { 0106 d->m_item = d->m_persistentIndex.data(EntityTreeModel::ItemRole).value<Item>(); 0107 emitResult(); 0108 return; 0109 } 0110 0111 const auto availableParts = index.data(EntityTreeModel::AvailablePartsRole).value<QSet<QByteArray>>(); 0112 if (!availableParts.contains(d->m_partName)) { 0113 setError(UserDefinedError); 0114 setErrorText(i18n("Payload part '%1' is not available for this index", QString::fromLatin1(d->m_partName))); 0115 emitResult(); 0116 return; 0117 } 0118 0119 auto session = qobject_cast<Akonadi::Session *>(qvariant_cast<QObject *>(index.data(EntityTreeModel::SessionRole))); 0120 0121 if (!session) { 0122 setError(UserDefinedError); 0123 setErrorText(i18n("No session available for this index")); 0124 emitResult(); 0125 return; 0126 } 0127 0128 const auto item = index.data(EntityTreeModel::ItemRole).value<Akonadi::Item>(); 0129 0130 if (!item.isValid()) { 0131 setError(UserDefinedError); 0132 setErrorText(i18n("No item available for this index")); 0133 emitResult(); 0134 return; 0135 } 0136 0137 ItemFetchScope scope; 0138 scope.fetchPayloadPart(d->m_partName); 0139 auto itemFetchJob = new Akonadi::ItemFetchJob(item, session); 0140 itemFetchJob->setFetchScope(scope); 0141 connect(itemFetchJob, &KJob::result, this, [d](KJob *job) { 0142 d->fetchJobDone(job); 0143 }); 0144 } 0145 0146 QModelIndex PartFetcher::index() const 0147 { 0148 Q_D(const PartFetcher); 0149 0150 return d->m_persistentIndex; 0151 } 0152 0153 QByteArray PartFetcher::partName() const 0154 { 0155 Q_D(const PartFetcher); 0156 0157 return d->m_partName; 0158 } 0159 0160 Item PartFetcher::item() const 0161 { 0162 Q_D(const PartFetcher); 0163 0164 return d->m_item; 0165 } 0166 0167 #include "moc_partfetcher.cpp"