incidenceattachmentmodel.cpp 5.6 KB
Newer Older
1
/*
2
  SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
3 4
    Author: Stephen Kelly <stephen@kdab.com>

5
  SPDX-License-Identifier: LGPL-2.0-or-later
6 7 8 9 10 11 12 13 14 15 16 17
*/

#include "incidenceattachmentmodel.h"

#include <EntityTreeModel>
#include <ItemFetchJob>
#include <ItemFetchScope>
#include <Monitor>

using namespace CalendarSupport;
using namespace Akonadi;

Laurent Montel's avatar
Laurent Montel committed
18
namespace CalendarSupport {
19 20
class IncidenceAttachmentModelPrivate
{
Laurent Montel's avatar
Laurent Montel committed
21
    IncidenceAttachmentModelPrivate(IncidenceAttachmentModel *qq, const QPersistentModelIndex &modelIndex, const Akonadi::Item &item = Akonadi::Item())
Laurent Montel's avatar
Laurent Montel committed
22 23 24
        : q_ptr(qq)
        , m_modelIndex(modelIndex)
        , m_item(item)
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
    {
        if (modelIndex.isValid()) {
            QObject::connect(modelIndex.model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
                             qq, SLOT(resetModel()));
        } else if (item.isValid()) {
            createMonitor();
            resetInternalData();
        }
    }

    void resetModel()
    {
        Q_Q(IncidenceAttachmentModel);
        q->beginResetModel();
        resetInternalData();
        q->endResetModel();
        Q_EMIT q->rowCountChanged();
    }

    void itemFetched(Akonadi::Item::List list)
    {
        Q_ASSERT(list.size() == 1);
        setItem(list.first());
    }

    void setItem(const Akonadi::Item &item);

    void createMonitor()
    {
        if (m_monitor) {
            return;
        }

        m_monitor = new Akonadi::Monitor(q_ptr);
59
        m_monitor->setObjectName(QStringLiteral("IncidenceAttachmentModelMonitor"));
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
        m_monitor->setItemMonitored(m_item);
        m_monitor->itemFetchScope().fetchFullPayload(true);
        QObject::connect(m_monitor, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)),
                         q_ptr, SLOT(resetModel()));
        QObject::connect(m_monitor, SIGNAL(itemRemoved(Akonadi::Item)),
                         q_ptr, SLOT(resetModel()));
    }

    void resetInternalData()
    {
        Item item = m_item;
        if (m_modelIndex.isValid()) {
            item = m_modelIndex.data(EntityTreeModel::ItemRole).value<Akonadi::Item>();
        }

75 76
        if (!item.isValid() || !item.hasPayload<KCalendarCore::Incidence::Ptr>()) {
            m_incidence = KCalendarCore::Incidence::Ptr();
77 78
            return;
        }
79
        m_incidence = item.payload<KCalendarCore::Incidence::Ptr>();
80 81 82 83 84 85 86
    }

    Q_DECLARE_PUBLIC(IncidenceAttachmentModel)
    IncidenceAttachmentModel *const q_ptr;

    QModelIndex m_modelIndex;
    Akonadi::Item m_item;
87
    KCalendarCore::Incidence::Ptr m_incidence;
Laurent Montel's avatar
Laurent Montel committed
88
    Akonadi::Monitor *m_monitor = nullptr;
89 90 91
};
}

Laurent Montel's avatar
Laurent Montel committed
92
IncidenceAttachmentModel::IncidenceAttachmentModel(const QPersistentModelIndex &modelIndex, QObject *parent)
Laurent Montel's avatar
Laurent Montel committed
93 94
    : QAbstractListModel(parent)
    , d_ptr(new IncidenceAttachmentModelPrivate(this, modelIndex))
95 96 97 98
{
}

IncidenceAttachmentModel::IncidenceAttachmentModel(const Akonadi::Item &item, QObject *parent)
Laurent Montel's avatar
Laurent Montel committed
99 100
    : QAbstractListModel(parent)
    , d_ptr(new IncidenceAttachmentModelPrivate(this, QModelIndex(), item))
101 102 103 104
{
}

IncidenceAttachmentModel::IncidenceAttachmentModel(QObject *parent)
Laurent Montel's avatar
Laurent Montel committed
105 106
    : QAbstractListModel(parent)
    , d_ptr(new IncidenceAttachmentModelPrivate(this, QModelIndex()))
107 108 109 110 111 112 113 114
{
}

IncidenceAttachmentModel::~IncidenceAttachmentModel()
{
    delete d_ptr;
}

115
KCalendarCore::Incidence::Ptr IncidenceAttachmentModel::incidence() const
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
{
    Q_D(const IncidenceAttachmentModel);
    return d->m_incidence;
}

void IncidenceAttachmentModel::setIndex(const QPersistentModelIndex &modelIndex)
{
    Q_D(IncidenceAttachmentModel);
    beginResetModel();
    d->m_modelIndex = modelIndex;
    d->m_item = Akonadi::Item();
    d->resetInternalData();
    endResetModel();
    Q_EMIT rowCountChanged();
}

void IncidenceAttachmentModel::setItem(const Akonadi::Item &item)
{
    Q_D(IncidenceAttachmentModel);
135
    if (!item.hasPayload<KCalendarCore::Incidence::Ptr>()) {
Laurent Montel's avatar
Laurent Montel committed
136
        auto *job = new ItemFetchJob(item);
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
        job->fetchScope().fetchFullPayload(true);
        connect(job, SIGNAL(itemsReceived(Akonadi::Item::List)),
                SLOT(itemFetched(Akonadi::Item::List)));
        return;
    }
    d->setItem(item);
}

void IncidenceAttachmentModelPrivate::setItem(const Akonadi::Item &item)
{
    Q_Q(IncidenceAttachmentModel);
    q->beginResetModel();
    m_modelIndex = QModelIndex();
    m_item = item;
    createMonitor();
    resetInternalData();
    q->endResetModel();
    Q_EMIT q->rowCountChanged();
}

int IncidenceAttachmentModel::rowCount(const QModelIndex &) const
{
    Q_D(const IncidenceAttachmentModel);
    if (!d->m_incidence) {
        return 0;
    } else {
        return d->m_incidence->attachments().size();
    }
}

QVariant IncidenceAttachmentModel::data(const QModelIndex &index, int role) const
{
    Q_D(const IncidenceAttachmentModel);
    if (!d->m_incidence) {
        return QVariant();
    }

174
    const KCalendarCore::Attachment attachment = d->m_incidence->attachments().at(index.row());
175 176
    switch (role) {
    case Qt::DisplayRole:
177
        return attachment.label();
178
    case AttachmentDataRole:
179
        return attachment.decodedData();
180
    case MimeTypeRole:
181
        return attachment.mimeType();
182 183 184 185
    }
    return QVariant();
}

Laurent Montel's avatar
Laurent Montel committed
186
QVariant IncidenceAttachmentModel::headerData(int section, Qt::Orientation orientation, int role) const
187 188 189 190
{
    return QAbstractItemModel::headerData(section, orientation, role);
}

191 192 193 194 195 196 197
QHash<int, QByteArray> CalendarSupport::IncidenceAttachmentModel::roleNames() const
{
    QHash<int, QByteArray> roleNames = QAbstractListModel::roleNames();
    roleNames.insert(IncidenceAttachmentModel::MimeTypeRole, "mimeType");
    return roleNames;
}

198
#include "moc_incidenceattachmentmodel.cpp"