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

akonadi

  • akonadi
  • calendar
calendarbase.cpp
1 /*
2  Copyright (C) 2011 Sérgio Martins <sergio.martins@kdab.com>
3  Copyright (C) 2012 Sérgio Martins <iamsergio@gmail.com>
4 
5  This library is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or (at your
8  option) any later version.
9 
10  This library is distributed in the hope that it will be useful, but WITHOUT
11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13  License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to the
17  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  02110-1301, USA.
19 */
20 
21 #include "calendarbase.h"
22 #include "calendarbase_p.h"
23 #include "incidencechanger.h"
24 
25 #include <akonadi/item.h>
26 #include <akonadi/collection.h>
27 
28 #include <KSystemTimeZones>
29 
30 using namespace Akonadi;
31 using namespace KCalCore;
32 
33 CalendarBasePrivate::CalendarBasePrivate( CalendarBase *qq ) : QObject()
34  , mIncidenceChanger( new IncidenceChanger() )
35  , mBatchInsertionCancelled( false )
36  , q( qq )
37 {
38  connect( mIncidenceChanger,
39  SIGNAL(createFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
40  SLOT(slotCreateFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)) );
41 
42  connect( mIncidenceChanger,
43  SIGNAL(deleteFinished(int,QVector<Akonadi::Item::Id>,Akonadi::IncidenceChanger::ResultCode,QString)),
44  SLOT(slotDeleteFinished(int,QVector<Akonadi::Item::Id>,Akonadi::IncidenceChanger::ResultCode,QString)) );
45 
46  connect( mIncidenceChanger,
47  SIGNAL(modifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
48  SLOT(slotModifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)) );
49 
50  mIncidenceChanger->setDestinationPolicy( IncidenceChanger::DestinationPolicyAsk );
51  mIncidenceChanger->setGroupwareCommunication( false );
52  mIncidenceChanger->setHistoryEnabled( false );
53 }
54 
55 CalendarBasePrivate::~CalendarBasePrivate()
56 {
57  delete mIncidenceChanger;
58  mIncidenceChanger = 0;
59 }
60 
61 void CalendarBasePrivate::internalInsert( const Akonadi::Item &item )
62 {
63  Q_ASSERT( item.isValid() );
64  mItemById.insert( item.id(), item );
65  KCalCore::Incidence::Ptr incidence= item.payload<KCalCore::Incidence::Ptr>();
66  Q_ASSERT( incidence );
67  if ( incidence ) {
68  //kDebug() << "Inserting incidence in calendar. id=" << item.id() << "uid=" << incidence->uid();
69  Q_ASSERT( !incidence->uid().isEmpty() );
70  mItemIdByUid.insert( incidence->uid(), item.id() );
71 
72  // Insert parent relationships
73  const QString parentUid = incidence->relatedTo();
74  if ( !parentUid.isEmpty() ) {
75  mParentUidToChildrenUid[parentUid].append( incidence->uid() );
76  }
77  // Must be the last one due to re-entrancy
78  q->MemoryCalendar::addIncidence( incidence );
79  }
80 }
81 
82 void CalendarBasePrivate::internalRemove( const Akonadi::Item &item )
83 {
84  Q_ASSERT( item.isValid() );
85  Q_ASSERT( item.hasPayload<KCalCore::Incidence::Ptr>() );
86  Incidence::Ptr incidence = q->incidence( item.payload<KCalCore::Incidence::Ptr>()->uid() );
87 
88 
89  // Null incidence means it was deleted via CalendarBase::deleteIncidence(), but then
90  // the ETMCalendar received the monitor notification and tried to delete it again.
91  if ( incidence ) {
92  mItemById.remove( item.id() );
93  // kDebug() << "Deleting incidence from calendar .id=" << item.id() << "uid=" << incidence->uid();
94  mItemIdByUid.remove( incidence->uid() );
95 
96  mParentUidToChildrenUid.remove( incidence->uid() );
97  const QString parentUid = incidence->relatedTo();
98  if ( !parentUid.isEmpty() ) {
99  mParentUidToChildrenUid[parentUid].removeAll( incidence->uid() );
100  }
101  // Must be the last one due to re-entrancy
102  q->MemoryCalendar::deleteIncidence( incidence );
103  }
104 }
105 
106 void CalendarBasePrivate::deleteAllIncidencesOfType( const QString &mimeType )
107 {
108  QHash<Item::Id, Item>::iterator i;
109  Item::List incidences;
110  for( i = mItemById.begin(); i != mItemById.end(); ++i ) {
111  if ( i.value().payload<KCalCore::Incidence::Ptr>()->mimeType() == mimeType )
112  incidences.append( i.value() );
113  }
114 
115  mIncidenceChanger->deleteIncidences( incidences );
116 }
117 
118 void CalendarBasePrivate::slotDeleteFinished( int changeId,
119  const QVector<Akonadi::Item::Id> &itemIds,
120  IncidenceChanger::ResultCode resultCode,
121  const QString &errorMessage )
122 {
123  Q_UNUSED( changeId );
124  if ( resultCode == IncidenceChanger::ResultCodeSuccess ) {
125  foreach( const Akonadi::Item::Id &id, itemIds ) {
126  if ( mItemById.contains( id ) )
127  internalRemove( mItemById.value( id ) );
128  }
129  }
130  emit q->deleteFinished( resultCode == IncidenceChanger::ResultCodeSuccess, errorMessage );
131 }
132 
133 void CalendarBasePrivate::slotCreateFinished( int changeId,
134  const Akonadi::Item &item,
135  IncidenceChanger::ResultCode resultCode,
136  const QString &errorMessage )
137 {
138  Q_UNUSED( changeId );
139  Q_UNUSED( item );
140  if ( resultCode == IncidenceChanger::ResultCodeSuccess ) {
141  internalInsert( item );
142  }
143  emit q->createFinished( resultCode == IncidenceChanger::ResultCodeSuccess, errorMessage );
144 }
145 
146 //TODO: unit-test this
147 void CalendarBasePrivate::slotModifyFinished( int changeId,
148  const Akonadi::Item &item,
149  IncidenceChanger::ResultCode resultCode,
150  const QString &errorMessage )
151 {
152  Q_UNUSED( changeId );
153  Q_UNUSED( item );
154  if ( resultCode == IncidenceChanger::ResultCodeSuccess ) {
155  KCalCore::IncidenceBase::Ptr incidence = item.payload<KCalCore::IncidenceBase::Ptr>();
156  Q_ASSERT( incidence );
157  //update our local one
158  *(static_cast<IncidenceBase*>(q->incidence( incidence->uid() ).data() ) ) = *(incidence.data());
159  }
160  emit q->modifyFinished( resultCode == IncidenceChanger::ResultCodeSuccess, errorMessage );
161 }
162 
163 CalendarBase::CalendarBase() : MemoryCalendar( KSystemTimeZones::local() )
164  , d_ptr( new CalendarBasePrivate( this ) )
165 {
166 }
167 
168 CalendarBase::CalendarBase( CalendarBasePrivate *const dd ) : MemoryCalendar( KSystemTimeZones::local() )
169  , d_ptr( dd )
170 {
171 }
172 
173 CalendarBase::~CalendarBase()
174 {
175 }
176 
177 Akonadi::Item CalendarBase::item( Akonadi::Item::Id id ) const
178 {
179  Q_D(const CalendarBase);
180  Akonadi::Item i;
181  if ( d->mItemById.contains( id ) ) {
182  i = d->mItemById[id];
183  } else {
184  kDebug() << "Can't find any item with id " << id;
185  }
186  return i;
187 }
188 
189 Akonadi::Item CalendarBase::item( const QString &uid ) const
190 {
191  Q_D(const CalendarBase);
192  Q_ASSERT( !uid.isEmpty() );
193  Akonadi::Item i;
194  if ( d->mItemIdByUid.contains( uid ) ) {
195  const Akonadi::Item::Id id = d->mItemIdByUid[uid];
196  if ( !d->mItemById.contains( id ) ) {
197  kError() << "Item with id " << id << "(uid=" << uid << ") not found, but in uid map";
198  Q_ASSERT_X( false, "CalendarBase::item", "not in mItemById" );
199  }
200  i = d->mItemById[id];
201  } else {
202  kDebug() << "Can't find any incidence with uid " << uid;
203  }
204  return i;
205 }
206 
207 Akonadi::Item::List CalendarBase::itemList( const KCalCore::Incidence::List &incidences ) const
208 {
209  Akonadi::Item::List items;
210 
211  foreach( const KCalCore::Incidence::Ptr &incidence, incidences ) {
212  if ( incidence ) {
213  items << item( incidence->uid() );
214  } else {
215  items << Akonadi::Item();
216  }
217  }
218 
219  return items;
220 }
221 
222 KCalCore::Incidence::List CalendarBase::childIncidences( const Akonadi::Item::Id &parentId ) const
223 {
224  Q_D(const CalendarBase);
225  KCalCore::Incidence::List childs;
226 
227  if ( d->mItemById.contains( parentId ) ) {
228  const Akonadi::Item item = d->mItemById.value( parentId );
229  Q_ASSERT( item.isValid() );
230  Q_ASSERT( item.hasPayload<KCalCore::Incidence::Ptr>() );
231 
232  childs = childIncidences( item.payload<KCalCore::Incidence::Ptr>()->uid() );
233  }
234 
235  return childs;
236 }
237 
238 KCalCore::Incidence::List CalendarBase::childIncidences( const QString &parentUid ) const
239 {
240  Q_D(const CalendarBase);
241  KCalCore::Incidence::List children;
242  const QStringList uids = d->mParentUidToChildrenUid.value( parentUid );
243  Q_FOREACH( const QString &uid, uids ) {
244  Incidence::Ptr child = incidence( uid );
245  if ( child )
246  children.append( child );
247  else
248  kWarning() << "Invalid child with uid " << uid;
249  }
250  return children;
251 }
252 
253 Akonadi::Item::List CalendarBase::childItems( const Akonadi::Item::Id &parentId ) const
254 {
255  Q_D(const CalendarBase);
256  Akonadi::Item::List childs;
257 
258  if ( d->mItemById.contains( parentId ) ) {
259  const Akonadi::Item item = d->mItemById.value( parentId );
260  Q_ASSERT( item.isValid() );
261  Q_ASSERT( item.hasPayload<KCalCore::Incidence::Ptr>() );
262 
263  childs = childItems( item.payload<KCalCore::Incidence::Ptr>()->uid() );
264  }
265 
266  return childs;
267 }
268 
269 Akonadi::Item::List CalendarBase::childItems( const QString &parentUid ) const
270 {
271  Q_D(const CalendarBase);
272  Akonadi::Item::List children;
273  const QStringList uids = d->mParentUidToChildrenUid.value( parentUid );
274  Q_FOREACH( const QString &uid, uids ) {
275  Akonadi::Item child = item( uid );
276  if ( child.isValid() && child.hasPayload<KCalCore::Incidence::Ptr>() )
277  children.append( child );
278  else
279  kWarning() << "Invalid child with uid " << uid;
280  }
281  return children;
282 }
283 
284 bool CalendarBase::addEvent( const KCalCore::Event::Ptr &event )
285 {
286  return addIncidence( event );
287 }
288 
289 bool CalendarBase::deleteEvent( const KCalCore::Event::Ptr &event )
290 {
291  return deleteIncidence( event );
292 }
293 
294 void CalendarBase::deleteAllEvents()
295 {
296  Q_D(CalendarBase);
297  d->deleteAllIncidencesOfType( Event::eventMimeType() );
298 }
299 
300 bool CalendarBase::addTodo( const KCalCore::Todo::Ptr &todo )
301 {
302  return addIncidence( todo );
303 }
304 
305 bool CalendarBase::deleteTodo( const KCalCore::Todo::Ptr &todo )
306 {
307  return deleteIncidence( todo );
308 }
309 
310 void CalendarBase::deleteAllTodos()
311 {
312  Q_D(CalendarBase);
313  d->deleteAllIncidencesOfType( Todo::todoMimeType() );
314 }
315 
316 bool CalendarBase::addJournal( const KCalCore::Journal::Ptr &journal )
317 {
318  return addIncidence( journal );
319 }
320 
321 bool CalendarBase::deleteJournal( const KCalCore::Journal::Ptr &journal )
322 {
323  return deleteIncidence( journal );
324 }
325 
326 void CalendarBase::deleteAllJournals()
327 {
328  Q_D(CalendarBase);
329  d->deleteAllIncidencesOfType( Journal::journalMimeType() );
330 }
331 
332 bool CalendarBase::addIncidence( const KCalCore::Incidence::Ptr &incidence )
333 {
334  //TODO: Parent for dialogs
335  Q_D(CalendarBase);
336 
337  // User canceled on the collection selection dialog
338  if ( batchAdding() && d->mBatchInsertionCancelled )
339  return -1;
340 
341  Akonadi::Collection collection;
342 
343  if ( batchAdding() && d->mCollectionForBatchInsertion.isValid() )
344  collection = d->mCollectionForBatchInsertion;
345 
346  const int changeId = d->mIncidenceChanger->createIncidence( incidence, collection );
347 
348  if ( batchAdding() ) {
349  const Akonadi::Collection lastCollection = d->mIncidenceChanger->lastCollectionUsed();
350  if ( changeId != -1 && !lastCollection.isValid() ) {
351  d->mBatchInsertionCancelled = true;
352  } else if ( lastCollection.isValid() && !d->mCollectionForBatchInsertion.isValid() ) {
353  d->mCollectionForBatchInsertion = d->mIncidenceChanger->lastCollectionUsed();
354  }
355  }
356 
357  return changeId != -1;
358 }
359 
360 bool CalendarBase::deleteIncidence( const KCalCore::Incidence::Ptr &incidence )
361 {
362  Q_D(CalendarBase);
363  Q_ASSERT( incidence );
364  Akonadi::Item item_ = item( incidence->uid() );
365  return -1 != d->mIncidenceChanger->deleteIncidence( item_ );
366 }
367 
368 bool CalendarBase::modifyIncidence( const KCalCore::IncidenceBase::Ptr &newIncidence )
369 {
370  Q_D(CalendarBase);
371  Q_ASSERT( newIncidence );
372  const Akonadi::Item item_ = item( newIncidence->uid() );
373  return -1 != d->mIncidenceChanger->modifyIncidence( item_ );
374 }
375 
376 void CalendarBase::setWeakPointer( const QWeakPointer<CalendarBase> &pointer )
377 {
378  Q_D(CalendarBase);
379  d->mWeakPointer = pointer;
380 }
381 
382 QWeakPointer<CalendarBase> CalendarBase::weakPointer() const
383 {
384  Q_D(const CalendarBase);
385  return d->mWeakPointer;
386 }
387 
388 IncidenceChanger* CalendarBase::incidenceChanger() const
389 {
390  Q_D(const CalendarBase);
391  return d->mIncidenceChanger;
392 }
393 
394 void CalendarBase::startBatchAdding()
395 {
396  KCalCore::MemoryCalendar::startBatchAdding();
397 }
398 
399 void CalendarBase::endBatchAdding()
400 {
401  Q_D(CalendarBase);
402  d->mCollectionForBatchInsertion = Akonadi::Collection();
403  d->mBatchInsertionCancelled = false;
404  KCalCore::MemoryCalendar::endBatchAdding();
405 }
406 
407 #include "calendarbase.moc"
408 #include "calendarbase_p.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:27:32 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.10.5 API Reference

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