File indexing completed on 2024-12-29 04:46:19
0001 /* 0002 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> 0003 Author: Stephen Kelly <stephen@kdab.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "incidenceattachmentmodel.h" 0009 0010 #include <Akonadi/EntityTreeModel> 0011 #include <Akonadi/ItemFetchJob> 0012 #include <Akonadi/ItemFetchScope> 0013 #include <Akonadi/Monitor> 0014 0015 using namespace CalendarSupport; 0016 using namespace Akonadi; 0017 0018 namespace CalendarSupport 0019 { 0020 class IncidenceAttachmentModelPrivate 0021 { 0022 IncidenceAttachmentModelPrivate(IncidenceAttachmentModel *qq, const QPersistentModelIndex &modelIndex, const Akonadi::Item &item = Akonadi::Item()) 0023 : q_ptr(qq) 0024 , m_modelIndex(modelIndex) 0025 , m_item(item) 0026 { 0027 if (modelIndex.isValid()) { 0028 QObject::connect(modelIndex.model(), SIGNAL(dataChanged(QModelIndex, QModelIndex)), qq, SLOT(resetModel())); 0029 } else if (item.isValid()) { 0030 createMonitor(); 0031 resetInternalData(); 0032 } 0033 } 0034 0035 void resetModel() 0036 { 0037 Q_Q(IncidenceAttachmentModel); 0038 q->beginResetModel(); 0039 resetInternalData(); 0040 q->endResetModel(); 0041 Q_EMIT q->rowCountChanged(); 0042 } 0043 0044 void itemFetched(Akonadi::Item::List list) 0045 { 0046 Q_ASSERT(list.size() == 1); 0047 setItem(list.first()); 0048 } 0049 0050 void setItem(const Akonadi::Item &item); 0051 0052 void createMonitor() 0053 { 0054 if (m_monitor) { 0055 return; 0056 } 0057 0058 m_monitor = new Akonadi::Monitor(q_ptr); 0059 m_monitor->setObjectName(QLatin1StringView("IncidenceAttachmentModelMonitor")); 0060 m_monitor->setItemMonitored(m_item); 0061 m_monitor->itemFetchScope().fetchFullPayload(true); 0062 QObject::connect(m_monitor, SIGNAL(itemChanged(Akonadi::Item, QSet<QByteArray>)), q_ptr, SLOT(resetModel())); 0063 QObject::connect(m_monitor, SIGNAL(itemRemoved(Akonadi::Item)), q_ptr, SLOT(resetModel())); 0064 } 0065 0066 void resetInternalData() 0067 { 0068 Item item = m_item; 0069 if (m_modelIndex.isValid()) { 0070 item = m_modelIndex.data(EntityTreeModel::ItemRole).value<Akonadi::Item>(); 0071 } 0072 0073 if (!item.isValid() || !item.hasPayload<KCalendarCore::Incidence::Ptr>()) { 0074 m_incidence = KCalendarCore::Incidence::Ptr(); 0075 return; 0076 } 0077 m_incidence = item.payload<KCalendarCore::Incidence::Ptr>(); 0078 } 0079 0080 Q_DECLARE_PUBLIC(IncidenceAttachmentModel) 0081 IncidenceAttachmentModel *const q_ptr; 0082 0083 QModelIndex m_modelIndex; 0084 Akonadi::Item m_item; 0085 KCalendarCore::Incidence::Ptr m_incidence; 0086 Akonadi::Monitor *m_monitor = nullptr; 0087 }; 0088 } 0089 0090 IncidenceAttachmentModel::IncidenceAttachmentModel(const QPersistentModelIndex &modelIndex, QObject *parent) 0091 : QAbstractListModel(parent) 0092 , d_ptr(new IncidenceAttachmentModelPrivate(this, modelIndex)) 0093 { 0094 } 0095 0096 IncidenceAttachmentModel::IncidenceAttachmentModel(const Akonadi::Item &item, QObject *parent) 0097 : QAbstractListModel(parent) 0098 , d_ptr(new IncidenceAttachmentModelPrivate(this, QModelIndex(), item)) 0099 { 0100 } 0101 0102 IncidenceAttachmentModel::IncidenceAttachmentModel(QObject *parent) 0103 : QAbstractListModel(parent) 0104 , d_ptr(new IncidenceAttachmentModelPrivate(this, QModelIndex())) 0105 { 0106 } 0107 0108 IncidenceAttachmentModel::~IncidenceAttachmentModel() = default; 0109 0110 KCalendarCore::Incidence::Ptr IncidenceAttachmentModel::incidence() const 0111 { 0112 Q_D(const IncidenceAttachmentModel); 0113 return d->m_incidence; 0114 } 0115 0116 void IncidenceAttachmentModel::setIndex(const QPersistentModelIndex &modelIndex) 0117 { 0118 Q_D(IncidenceAttachmentModel); 0119 beginResetModel(); 0120 d->m_modelIndex = modelIndex; 0121 d->m_item = Akonadi::Item(); 0122 d->resetInternalData(); 0123 endResetModel(); 0124 Q_EMIT rowCountChanged(); 0125 } 0126 0127 void IncidenceAttachmentModel::setItem(const Akonadi::Item &item) 0128 { 0129 Q_D(IncidenceAttachmentModel); 0130 if (!item.hasPayload<KCalendarCore::Incidence::Ptr>()) { 0131 auto job = new ItemFetchJob(item); 0132 job->fetchScope().fetchFullPayload(true); 0133 connect(job, SIGNAL(itemsReceived(Akonadi::Item::List)), SLOT(itemFetched(Akonadi::Item::List))); 0134 return; 0135 } 0136 d->setItem(item); 0137 } 0138 0139 void IncidenceAttachmentModelPrivate::setItem(const Akonadi::Item &item) 0140 { 0141 Q_Q(IncidenceAttachmentModel); 0142 q->beginResetModel(); 0143 m_modelIndex = QModelIndex(); 0144 m_item = item; 0145 createMonitor(); 0146 resetInternalData(); 0147 q->endResetModel(); 0148 Q_EMIT q->rowCountChanged(); 0149 } 0150 0151 int IncidenceAttachmentModel::rowCount(const QModelIndex &) const 0152 { 0153 Q_D(const IncidenceAttachmentModel); 0154 if (!d->m_incidence) { 0155 return 0; 0156 } else { 0157 return d->m_incidence->attachments().size(); 0158 } 0159 } 0160 0161 QVariant IncidenceAttachmentModel::data(const QModelIndex &index, int role) const 0162 { 0163 Q_D(const IncidenceAttachmentModel); 0164 if (!d->m_incidence) { 0165 return {}; 0166 } 0167 0168 const KCalendarCore::Attachment attachment = d->m_incidence->attachments().at(index.row()); 0169 switch (role) { 0170 case Qt::DisplayRole: 0171 return attachment.label(); 0172 case AttachmentDataRole: 0173 return attachment.decodedData(); 0174 case MimeTypeRole: 0175 return attachment.mimeType(); 0176 } 0177 return {}; 0178 } 0179 0180 QVariant IncidenceAttachmentModel::headerData(int section, Qt::Orientation orientation, int role) const 0181 { 0182 return QAbstractItemModel::headerData(section, orientation, role); 0183 } 0184 0185 QHash<int, QByteArray> CalendarSupport::IncidenceAttachmentModel::roleNames() const 0186 { 0187 QHash<int, QByteArray> roleNames = QAbstractListModel::roleNames(); 0188 roleNames.insert(IncidenceAttachmentModel::MimeTypeRole, "mimeType"); 0189 return roleNames; 0190 } 0191 0192 #include "moc_incidenceattachmentmodel.cpp"