• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.11.3 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
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::Job
Base class for all actions in the Akonadi storage.
Definition: job.h:86
Akonadi::TransactionSequence
Base class for jobs that need to run a sequence of sub-jobs in a transaction.
Definition: transactionsequence.h:69
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Tue Nov 26 2013 09:03:17 by doxygen 1.8.5 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.3 API Reference

Skip menu "kdepimlibs-4.11.3 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