1 | /* |
2 | Copyright (c) 2009 Stephen Kelly <steveire@gmail.com> |
3 | |
4 | This library is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU Library General Public License as published by |
6 | the Free Software Foundation; either version 2 of the License, or (at your |
7 | option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
12 | License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to the |
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
17 | 02110-1301, USA. |
18 | */ |
19 | |
20 | #include "partfetcher.h" |
21 | |
22 | #include "entitytreemodel.h" |
23 | #include "session.h" |
24 | #include "itemfetchjob.h" |
25 | #include "itemfetchscope.h" |
26 | #include <KLocalizedString> |
27 | |
28 | #ifndef KDE_USE_FINAL |
29 | Q_DECLARE_METATYPE(QSet<QByteArray>) |
30 | #endif |
31 | |
32 | using namespace Akonadi; |
33 | |
34 | namespace Akonadi |
35 | { |
36 | |
37 | class PartFetcherPrivate |
38 | { |
39 | PartFetcherPrivate(PartFetcher *partFetcher, const QModelIndex &index, const QByteArray &partName) |
40 | : m_persistentIndex(index) |
41 | , m_partName(partName) |
42 | , q_ptr(partFetcher) |
43 | { |
44 | } |
45 | |
46 | void fetchJobDone(KJob *); |
47 | |
48 | void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); |
49 | |
50 | QPersistentModelIndex m_persistentIndex; |
51 | QByteArray m_partName; |
52 | Item m_item; |
53 | |
54 | Q_DECLARE_PUBLIC(PartFetcher) |
55 | PartFetcher *q_ptr; |
56 | }; |
57 | |
58 | } |
59 | |
60 | void PartFetcherPrivate::fetchJobDone(KJob *job) |
61 | { |
62 | Q_Q(PartFetcher); |
63 | if (job->error()) { |
64 | q->setError(KJob::UserDefinedError); |
65 | q->setErrorText(i18n("Unable to fetch item for index" )); |
66 | q->emitResult(); |
67 | return; |
68 | } |
69 | |
70 | ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob *>(job); |
71 | |
72 | const Item::List list = fetchJob->items(); |
73 | |
74 | Q_ASSERT(list.size() == 1); |
75 | |
76 | // If m_persistentIndex comes from a selection proxy model, it could become |
77 | // invalid if the user clicks around a lot. |
78 | if (!m_persistentIndex.isValid()) { |
79 | q->setError(KJob::UserDefinedError); |
80 | q->setErrorText(i18n("Index is no longer available" )); |
81 | q->emitResult(); |
82 | return; |
83 | } |
84 | |
85 | const QSet<QByteArray> loadedParts = m_persistentIndex.data(EntityTreeModel::LoadedPartsRole).value<QSet<QByteArray> >(); |
86 | |
87 | Q_ASSERT(!loadedParts.contains(m_partName)); |
88 | |
89 | Item item = m_persistentIndex.data(EntityTreeModel::ItemRole).value<Item>(); |
90 | |
91 | item.apply(list.at(0)); |
92 | |
93 | QAbstractItemModel *model = const_cast<QAbstractItemModel *>(m_persistentIndex.model()); |
94 | |
95 | Q_ASSERT(model); |
96 | |
97 | QVariant itemVariant = QVariant::fromValue(item); |
98 | model->setData(m_persistentIndex, itemVariant, EntityTreeModel::ItemRole); |
99 | |
100 | m_item = item; |
101 | |
102 | emit q->emitResult(); |
103 | } |
104 | |
105 | PartFetcher::PartFetcher(const QModelIndex &index, const QByteArray &partName, QObject *parent) |
106 | : KJob(parent) |
107 | , d_ptr(new PartFetcherPrivate(this, index, partName)) |
108 | { |
109 | } |
110 | |
111 | PartFetcher::~PartFetcher() |
112 | { |
113 | delete d_ptr; |
114 | } |
115 | |
116 | void PartFetcher::start() |
117 | { |
118 | Q_D(PartFetcher); |
119 | |
120 | const QModelIndex index = d->m_persistentIndex; |
121 | |
122 | const QSet<QByteArray> loadedParts = index.data(EntityTreeModel::LoadedPartsRole).value<QSet<QByteArray> >(); |
123 | |
124 | if (loadedParts.contains(d->m_partName)) { |
125 | d->m_item = d->m_persistentIndex.data(EntityTreeModel::ItemRole).value<Item>(); |
126 | emitResult(); |
127 | return; |
128 | } |
129 | |
130 | const QSet<QByteArray> availableParts = index.data(EntityTreeModel::AvailablePartsRole).value<QSet<QByteArray> >(); |
131 | if (!availableParts.contains(d->m_partName)) { |
132 | setError(UserDefinedError); |
133 | setErrorText(i18n("Payload part '%1' is not available for this index" , QString::fromLatin1(d->m_partName))); |
134 | emitResult(); |
135 | return; |
136 | } |
137 | |
138 | Akonadi::Session *session = qobject_cast<Akonadi::Session *>(qvariant_cast<QObject *>(index.data(EntityTreeModel::SessionRole))); |
139 | |
140 | if (!session) { |
141 | setError(UserDefinedError); |
142 | setErrorText(i18n("No session available for this index" )); |
143 | emitResult(); |
144 | return; |
145 | } |
146 | |
147 | const Akonadi::Item item = index.data(EntityTreeModel::ItemRole).value<Akonadi::Item>(); |
148 | |
149 | if (!item.isValid()) { |
150 | setError(UserDefinedError); |
151 | setErrorText(i18n("No item available for this index" )); |
152 | emitResult(); |
153 | return; |
154 | } |
155 | |
156 | ItemFetchScope scope; |
157 | scope.fetchPayloadPart(d->m_partName); |
158 | ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob(item, session); |
159 | itemFetchJob->setFetchScope(scope); |
160 | |
161 | connect(itemFetchJob, SIGNAL(result(KJob*)), |
162 | this, SLOT(fetchJobDone(KJob*))); |
163 | } |
164 | |
165 | QModelIndex PartFetcher::index() const |
166 | { |
167 | Q_D(const PartFetcher); |
168 | |
169 | return d->m_persistentIndex; |
170 | } |
171 | |
172 | QByteArray PartFetcher::partName() const |
173 | { |
174 | Q_D(const PartFetcher); |
175 | |
176 | return d->m_partName; |
177 | } |
178 | |
179 | Item PartFetcher::item() const |
180 | { |
181 | Q_D(const PartFetcher); |
182 | |
183 | return d->m_item; |
184 | } |
185 | |
186 | #include "moc_partfetcher.cpp" |
187 | |