• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.11.5 API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • akonadi
  • calendar
incidencechanger_p.h
1 /*
2  Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
3 
4  Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
5  Author: Sergio Martins, <sergio.martins@kdab.com>
6 
7  Copyright (C) 2010-2012 SĂ©rgio Martins <iamsergio@gmail.com>
8 
9  This library is free software; you can redistribute it and/or modify it
10  under the terms of the GNU Library General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or (at your
12  option) any later version.
13 
14  This library is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
17  License for more details.
18 
19  You should have received a copy of the GNU Library General Public License
20  along with this library; see the file COPYING.LIB. If not, write to the
21  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  02110-1301, USA.
23 */
24 #ifndef AKONADI_INCIDENCECHANGER_P_H
25 #define AKONADI_INCIDENCECHANGER_P_H
26 
27 #include "incidencechanger.h"
28 #include "itiphandlerhelper_p.h"
29 #include "history.h"
30 
31 #include <akonadi/item.h>
32 #include <akonadi/collection.h>
33 #include <akonadi/transactionsequence.h>
34 
35 #include <QSet>
36 #include <QObject>
37 #include <QPointer>
38 #include <QVector>
39 
40 
41 class KJob;
42 class QWidget;
43 
44 namespace Akonadi {
45 
46 class TransactionSequence;
47 
48 class Change {
49 
50 public:
51  typedef QSharedPointer<Change> Ptr;
52  Change(IncidenceChanger *incidenceChanger, int changeId,
53  IncidenceChanger::ChangeType changeType, uint operationId,
54  QWidget *parent) : id(changeId)
55  , type(changeType)
56  , recordToHistory(incidenceChanger->historyEnabled())
57  , parentWidget(parent)
58  , atomicOperationId(operationId)
59  , resultCode(Akonadi::IncidenceChanger::ResultCodeSuccess)
60  , completed(false)
61  , queuedModification(false)
62  , useGroupwareCommunication(incidenceChanger->groupwareCommunication())
63  , changer(incidenceChanger)
64  {
65  }
66 
67  virtual ~Change()
68  {
69  if (parentChange) {
70  parentChange->childAboutToDie(this);
71  }
72  }
73 
74  virtual void childAboutToDie(Change *child)
75  {
76  Q_UNUSED(child);
77  }
78 
79  virtual void emitCompletionSignal() = 0;
80 
81  const int id;
82  const IncidenceChanger::ChangeType type;
83  const bool recordToHistory;
84  const QPointer<QWidget> parentWidget;
85  uint atomicOperationId;
86 
87  // If this change is internal, i.e. not initiated by the user, mParentChange will
88  // contain the non-internal change.
89  QSharedPointer<Change> parentChange;
90 
91  Akonadi::Item::List originalItems;
92  Akonadi::Item newItem;
93 
94  QString errorString;
95  IncidenceChanger::ResultCode resultCode;
96  bool completed;
97  bool queuedModification;
98  bool useGroupwareCommunication;
99 protected:
100  IncidenceChanger *const changer;
101 };
102 
103 class ModificationChange : public Change
104 {
105 public:
106  typedef QSharedPointer<ModificationChange> Ptr;
107  ModificationChange(IncidenceChanger *changer, int id, uint atomicOperationId,
108  QWidget *parent) : Change(changer, id,
109  IncidenceChanger::ChangeTypeModify,
110  atomicOperationId, parent)
111  {
112  }
113 
114  ~ModificationChange()
115  {
116  if (!parentChange)
117  emitCompletionSignal();
118  }
119 
121  void emitCompletionSignal();
122 };
123 
124 class CreationChange : public Change
125 {
126 public:
127  typedef QSharedPointer<CreationChange> Ptr;
128  CreationChange(IncidenceChanger *changer, int id, uint atomicOperationId,
129  QWidget *parent) : Change(changer, id, IncidenceChanger::ChangeTypeCreate,
130  atomicOperationId, parent)
131  {
132  }
133 
134  ~CreationChange()
135  {
136  //kDebug() << "CreationChange::~ will emit signal with " << resultCode;
137  if (!parentChange)
138  emitCompletionSignal();
139  }
140 
142  void emitCompletionSignal();
143 
144  Akonadi::Collection mUsedCol1lection;
145 };
146 
147 class DeletionChange : public Change
148 {
149 public:
150  typedef QSharedPointer<DeletionChange> Ptr;
151  DeletionChange(IncidenceChanger *changer, int id, uint atomicOperationId,
152  QWidget *parent) : Change(changer, id, IncidenceChanger::ChangeTypeDelete,
153  atomicOperationId, parent)
154  {
155  }
156 
157  ~DeletionChange()
158  {
159  //kDebug() << "DeletionChange::~ will emit signal with " << resultCode;
160  if (!parentChange)
161  emitCompletionSignal();
162  }
163 
165  void emitCompletionSignal();
166 
167  QVector<Akonadi::Item::Id> mItemIds;
168 };
169 
170 struct AtomicOperation {
171  uint m_id;
172 
173  // To make sure they are not repeated
174  QSet<Akonadi::Item::Id> m_itemIdsInOperation;
175 
176  // After endAtomicOperation() is called we don't accept more changes
177  bool m_endCalled;
178 
179  // Number of completed changes(jobs)
180  int m_numCompletedChanges;
181  QString m_description;
182  bool m_transactionCompleted;
183 
184  AtomicOperation(IncidenceChanger::Private *icp, uint ident);
185 
186  ~AtomicOperation()
187  {
188  //kDebug() << "AtomicOperation::~ " << wasRolledback << changes.count();
189  if (m_wasRolledback) {
190  for (int i=0; i<m_changes.count(); ++i) {
191  // When a job that can finish successfully is aborted because the transaction failed
192  // because of some other job, akonadi is returning an Unknown error
193  // which isnt very specific
194  if (m_changes[i]->completed &&
195  (m_changes[i]->resultCode == IncidenceChanger::ResultCodeSuccess ||
196  (m_changes[i]->resultCode == IncidenceChanger::ResultCodeJobError &&
197  m_changes[i]->errorString == QLatin1String("Unknown error.")))) {
198  m_changes[i]->resultCode = IncidenceChanger::ResultCodeRolledback;
199  }
200  }
201  }
202  }
203 
204  // Did all jobs return ?
205  bool pendingJobs() const
206  {
207  return m_changes.count() > m_numCompletedChanges;
208  }
209 
210  void setRolledback()
211  {
212  //kDebug() << "AtomicOperation::setRolledBack()";
213  m_wasRolledback = true;
214  transaction()->rollback();
215  }
216 
217  bool rolledback() const
218  {
219  return m_wasRolledback;
220  }
221 
222  void addChange(const Change::Ptr &change)
223  {
224  if (change->type == IncidenceChanger::ChangeTypeDelete) {
225  DeletionChange::Ptr deletion = change.staticCast<DeletionChange>();
226  foreach(Akonadi::Item::Id id, deletion->mItemIds) {
227  Q_ASSERT(!m_itemIdsInOperation.contains(id));
228  m_itemIdsInOperation.insert(id);
229  }
230  } else if (change->type == IncidenceChanger::ChangeTypeModify) {
231  Q_ASSERT(!m_itemIdsInOperation.contains(change->newItem.id()));
232  m_itemIdsInOperation.insert(change->newItem.id());
233  }
234 
235  m_changes << change;
236  }
237 
238  Akonadi::TransactionSequence *transaction();
239 
240 private:
241  QVector<Change::Ptr> m_changes;
242  bool m_wasRolledback;
243  Akonadi::TransactionSequence *m_transaction; // constructed in first use
244  IncidenceChanger::Private *m_incidenceChangerPrivate;
245 };
246 
247 class IncidenceChanger::Private : public QObject
248 {
249  Q_OBJECT
250 public:
251  explicit Private(bool enableHistory, IncidenceChanger *mIncidenceChanger);
252  ~Private();
253 
258  bool deleteAlreadyCalled(Akonadi::Item::Id id) const;
259 
260  QString showErrorDialog(Akonadi::IncidenceChanger::ResultCode, QWidget *parent);
261 
262  void setChangeInternal(int changeId);
263 
264  bool hasRights(const Akonadi::Collection &collection, IncidenceChanger::ChangeType) const;
265  void queueModification(Change::Ptr);
266  void performModification(Change::Ptr);
267  bool atomicOperationIsValid(uint atomicOperationId) const;
268  Akonadi::Job* parentJob(const Change::Ptr &) const;
269  void cancelTransaction();
270  void cleanupTransaction();
271  bool allowAtomicOperation(int atomicOperationId, const Change::Ptr &change) const;
272 
273  bool handleInvitationsBeforeChange(const Change::Ptr &change);
274  bool handleInvitationsAfterChange(const Change::Ptr &change);
275  static bool myAttendeeStatusChanged(const KCalCore::Incidence::Ptr &newIncidence,
276  const KCalCore::Incidence::Ptr &oldIncidence,
277  const QStringList &myEmails);
278 
279 public Q_SLOTS:
280  void handleCreateJobResult(KJob*);
281  void handleModifyJobResult(KJob*);
282  void handleDeleteJobResult(KJob*);
283  void handleTransactionJobResult(KJob*);
284  void performNextModification(Akonadi::Item::Id id);
285 
286 public:
287  int mLatestChangeId;
288  QHash<const KJob*,Change::Ptr> mChangeForJob;
289  bool mShowDialogsOnError;
290  Akonadi::Collection mDefaultCollection;
291  DestinationPolicy mDestinationPolicy;
292  QVector<Akonadi::Item::Id> mDeletedItemIds;
293 
294  History *mHistory;
295  bool mUseHistory;
296 
305  QHash<Akonadi::Item::Id,Change::Ptr> mQueuedModifications;
306 
310  QHash<Akonadi::Item::Id,Change::Ptr> mModificationsInProgress;
311 
312  QHash<int,Change::Ptr> mChangeById;
313 
317  QHash<uint,AtomicOperation*> mAtomicOperations;
318 
319  bool mRespectsCollectionRights;
320  bool mGroupwareCommunication;
321 
322  QHash<Akonadi::TransactionSequence*, uint> mAtomicOperationByTransaction;
323  QHash<uint,ITIPHandlerHelper::SendResult> mInvitationStatusByAtomicOperation;
324 
325  uint mLatestAtomicOperationId;
326  bool mBatchOperationInProgress;
327  Akonadi::Collection mLastCollectionUsed;
328 
329  QMap<KJob *, QSet<KCalCore::IncidenceBase::Field> > mDirtyFieldsByJob;
330 
331 private:
332  IncidenceChanger *q;
333 };
334 
335 }
336 
337 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Thu Jan 9 2014 17:55:07 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs-4.11.5 API Reference

Skip menu "kdepimlibs-4.11.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal