libkcal

calendarresources.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of libkcal.
00003 
00004     Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00029 #include <stdlib.h>
00030 
00031 #include <qdatetime.h>
00032 #include <qstring.h>
00033 #include <qptrlist.h>
00034 
00035 #include <kdebug.h>
00036 #include <kstandarddirs.h>
00037 #include <klocale.h>
00038 
00039 #include "vcaldrag.h"
00040 #include "vcalformat.h"
00041 #include "icalformat.h"
00042 #include "exceptions.h"
00043 #include "incidence.h"
00044 #include "journal.h"
00045 #include "filestorage.h"
00046 
00047 #include <kresources/manager.h>
00048 #include <kresources/selectdialog.h>
00049 #include <kabc/lock.h>
00050 
00051 #include "resourcecalendar.h"
00052 #include "resourcelocal.h"
00053 
00054 #include "calendarresources.h"
00055 
00056 using namespace KCal;
00057 
00058 ResourceCalendar
00059 *CalendarResources::StandardDestinationPolicy::destination( Incidence * )
00060 {
00061   return resourceManager()->standardResource();
00062 }
00063 
00064 ResourceCalendar
00065 *CalendarResources::AskDestinationPolicy::destination( Incidence * )
00066 {
00067   QPtrList<KRES::Resource> list;
00068 
00069   CalendarResourceManager::ActiveIterator it;
00070   for ( it = resourceManager()->activeBegin();
00071         it != resourceManager()->activeEnd(); ++it ) {
00072     if ( !(*it)->readOnly() ) {
00073       //Insert the first the Standard resource to get be the default selected.
00074       if ( resourceManager()->standardResource() == *it )
00075         list.insert( 0, *it );
00076       else
00077         list.append( *it );
00078     }
00079   }
00080 
00081   KRES::Resource *r;
00082   r = KRES::SelectDialog::getResource( list, parent() );
00083   return static_cast<ResourceCalendar *>( r );
00084 }
00085 
00086 CalendarResources::CalendarResources( const QString &timeZoneId,
00087                                       const QString &family )
00088   : Calendar( timeZoneId )
00089 {
00090   init( family );
00091 }
00092 
00093 void CalendarResources::init( const QString &family )
00094 {
00095   kdDebug(5800) << "CalendarResources::init( " << family << " )" << endl;
00096 
00097   mManager = new CalendarResourceManager( family );
00098   mManager->addObserver( this );
00099 
00100   mStandardPolicy = new StandardDestinationPolicy( mManager );
00101   mAskPolicy = new AskDestinationPolicy( mManager );
00102   mDestinationPolicy = mStandardPolicy;
00103 }
00104 
00105 CalendarResources::~CalendarResources()
00106 {
00107   close();
00108   delete mManager;
00109   delete mStandardPolicy;
00110   delete mAskPolicy;
00111 }
00112 
00113 void CalendarResources::readConfig( KConfig *config )
00114 {
00115   mManager->readConfig( config );
00116 
00117   CalendarResourceManager::Iterator it;
00118   for ( it = mManager->begin(); it != mManager->end(); ++it ) {
00119     connectResource( *it );
00120   }
00121 }
00122 
00123 void CalendarResources::load()
00124 {
00125   kdDebug(5800) << "CalendarResources::load()" << endl;
00126 
00127   if ( !mManager->standardResource() ) {
00128     kdDebug(5800) << "Warning! No standard resource yet." << endl;
00129   }
00130 
00131   // set the timezone for all resources. Otherwise we'll have those terrible tz
00132   // troubles ;-((
00133   CalendarResourceManager::Iterator i1;
00134   for ( i1 = mManager->begin(); i1 != mManager->end(); ++i1 ) {
00135     (*i1)->setTimeZoneId( timeZoneId() );
00136   }
00137 
00138   QValueList<ResourceCalendar *> failed;
00139 
00140   // Open all active resources
00141   CalendarResourceManager::ActiveIterator it;
00142   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00143     if ( !(*it)->load() ) {
00144       failed.append( *it );
00145     }
00146     Incidence::List incidences = (*it)->rawIncidences();
00147     Incidence::List::Iterator incit;
00148     for ( incit = incidences.begin(); incit != incidences.end(); ++incit ) {
00149       (*incit)->registerObserver( this );
00150       notifyIncidenceAdded( *incit );
00151     }
00152   }
00153 
00154   QValueList<ResourceCalendar *>::ConstIterator it2;
00155   for ( it2 = failed.begin(); it2 != failed.end(); ++it2 ) {
00156     (*it2)->setActive( false );
00157     emit signalResourceModified( *it2 );
00158   }
00159 
00160   mOpen = true;
00161 }
00162 
00163 bool CalendarResources::reload( const QString &tz )
00164 {
00165   save();
00166   close();
00167   setTimeZoneId( tz );
00168   load();
00169   return true;
00170 }
00171 
00172 void CalendarResources::setStandardDestinationPolicy()
00173 {
00174   mDestinationPolicy = mStandardPolicy;
00175 }
00176 
00177 void CalendarResources::setAskDestinationPolicy()
00178 {
00179   mDestinationPolicy = mAskPolicy;
00180 }
00181 
00182 QWidget *CalendarResources::dialogParentWidget()
00183 {
00184   return mDestinationPolicy->parent();
00185 }
00186 
00187 void CalendarResources::setDialogParentWidget( QWidget *parent )
00188 {
00189   mDestinationPolicy->setParent( parent );
00190 }
00191 
00192 void CalendarResources::close()
00193 {
00194   kdDebug(5800) << "CalendarResources::close" << endl;
00195 
00196   if ( mOpen ) {
00197     CalendarResourceManager::ActiveIterator it;
00198     for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00199       (*it)->close();
00200     }
00201 
00202     setModified( false );
00203     mOpen = false;
00204   }
00205 }
00206 
00207 void CalendarResources::save()
00208 {
00209   kdDebug(5800) << "CalendarResources::save()" << endl;
00210 
00211   if ( mOpen && isModified() ) {
00212     CalendarResourceManager::ActiveIterator it;
00213     for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00214       (*it)->save();
00215     }
00216 
00217     setModified( false );
00218   }
00219 }
00220 
00221 bool CalendarResources::isSaving()
00222 {
00223   CalendarResourceManager::ActiveIterator it;
00224   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00225     if ( (*it)->isSaving() ) {
00226       return true;
00227     }
00228   }
00229 
00230   return false;
00231 }
00232 
00233 bool CalendarResources::addIncidence( Incidence *incidence,
00234                                       ResourceCalendar *resource )
00235 {
00236   // FIXME: Use proper locking via begin/endChange!
00237   bool validRes = false;
00238   CalendarResourceManager::ActiveIterator it;
00239   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00240     if ( (*it) == resource )
00241       validRes = true;
00242   }
00243   ResourceCalendar *oldResource = 0;
00244   if ( mResourceMap.contains( incidence ) ) {
00245     oldResource = mResourceMap[incidence];
00246   }
00247   mResourceMap[incidence] = resource;
00248   if ( validRes && beginChange( incidence ) &&
00249        resource->addIncidence( incidence ) ) {
00250 //    mResourceMap[incidence] = resource;
00251     incidence->registerObserver( this );
00252     notifyIncidenceAdded( incidence );
00253     setModified( true );
00254     endChange( incidence );
00255     return true;
00256   } else {
00257     if ( oldResource )
00258       mResourceMap[incidence] = oldResource;
00259     else
00260       mResourceMap.remove( incidence );
00261   }
00262 
00263   return false;
00264 }
00265 
00266 bool CalendarResources::addIncidence( Incidence *incidence )
00267 {
00268   kdDebug(5800) << "CalendarResources::addIncidence" << this << endl;
00269 
00270   ResourceCalendar *resource = mDestinationPolicy->destination( incidence );
00271 
00272   if ( resource ) {
00273     mResourceMap[ incidence ] = resource;
00274 
00275     if ( beginChange( incidence ) && resource->addIncidence( incidence ) ) {
00276       incidence->registerObserver( this );
00277       notifyIncidenceAdded( incidence );
00278 
00279 
00280       mResourceMap[ incidence ] = resource;
00281       setModified( true );
00282       endChange( incidence );
00283       return true;
00284     } else {
00285       mResourceMap.remove( incidence );
00286     }
00287   } else
00288     kdDebug(5800) << "CalendarResources::addIncidence(): no resource" << endl;
00289 
00290   return false;
00291 }
00292 
00293 bool CalendarResources::addEvent( Event *event )
00294 {
00295   kdDebug(5800) << "CalendarResources::addEvent" << endl;
00296   return addIncidence( event );
00297 }
00298 
00299 bool CalendarResources::addEvent( Event *Event, ResourceCalendar *resource )
00300 {
00301   return addIncidence( Event, resource );
00302 }
00303 
00304 bool CalendarResources::deleteEvent( Event *event )
00305 {
00306   kdDebug(5800) << "CalendarResources::deleteEvent" << endl;
00307 
00308   bool status;
00309   if ( mResourceMap.find( event ) != mResourceMap.end() ) {
00310     status = mResourceMap[event]->deleteEvent( event );
00311     if ( status )
00312       mResourceMap.remove( event );
00313   } else {
00314     status = false;
00315     CalendarResourceManager::ActiveIterator it;
00316     for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00317       status = (*it)->deleteEvent( event ) || status;
00318     }
00319   }
00320 
00321   setModified( status );
00322   return status;
00323 }
00324 
00325 Event *CalendarResources::event( const QString &uid )
00326 {
00327   CalendarResourceManager::ActiveIterator it;
00328   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00329     Event* event = (*it)->event( uid );
00330     if ( event ) {
00331       mResourceMap[event] = *it;
00332       return event;
00333     }
00334   }
00335 
00336   // Not found
00337   return 0;
00338 }
00339 
00340 bool CalendarResources::addTodo( Todo *todo )
00341 {
00342   kdDebug(5800) << "CalendarResources::addTodo" << endl;
00343   return addIncidence( todo );
00344 }
00345 
00346 bool CalendarResources::addTodo( Todo *todo, ResourceCalendar *resource )
00347 {
00348   return addIncidence( todo, resource );
00349 }
00350 
00351 bool CalendarResources::deleteTodo( Todo *todo )
00352 {
00353   kdDebug(5800) << "CalendarResources::deleteTodo" << endl;
00354 
00355   bool status;
00356   if ( mResourceMap.find( todo ) != mResourceMap.end() ) {
00357     status = mResourceMap[todo]->deleteTodo( todo );
00358     if ( status )
00359       mResourceMap.remove( todo );
00360   } else {
00361     CalendarResourceManager::ActiveIterator it;
00362     status = false;
00363     for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00364       status = (*it)->deleteTodo( todo ) || status;
00365     }
00366   }
00367 
00368   setModified( status );
00369   return status;
00370 }
00371 
00372 Todo::List CalendarResources::rawTodos( TodoSortField sortField,
00373                                         SortDirection sortDirection )
00374 {
00375   Todo::List result;
00376 
00377   CalendarResourceManager::ActiveIterator it;
00378   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00379     Todo::List todos = (*it)->rawTodos( TodoSortUnsorted );
00380     Todo::List::ConstIterator it2;
00381     for ( it2 = todos.begin(); it2 != todos.end(); ++it2 ) {
00382       result.append( *it2 );
00383       mResourceMap[ *it2 ] = *it;
00384     }
00385   }
00386   return sortTodos( &result, sortField, sortDirection );
00387 }
00388 
00389 Todo *CalendarResources::todo( const QString &uid )
00390 {
00391   kdDebug(5800) << "CalendarResources::todo(uid)" << endl;
00392 
00393   CalendarResourceManager::ActiveIterator it;
00394   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00395     Todo *todo = (*it)->todo( uid );
00396     if ( todo ) {
00397       mResourceMap[todo] = *it;
00398       return todo;
00399     }
00400   }
00401 
00402   // Not found
00403   return 0;
00404 }
00405 
00406 Todo::List CalendarResources::rawTodosForDate( const QDate &date )
00407 {
00408   Todo::List result;
00409 
00410   CalendarResourceManager::ActiveIterator it;
00411   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00412     Todo::List todos = (*it)->rawTodosForDate( date );
00413     Todo::List::ConstIterator it2;
00414     for ( it2 = todos.begin(); it2 != todos.end(); ++it2 ) {
00415       result.append( *it2 );
00416       mResourceMap[ *it2 ] = *it;
00417     }
00418   }
00419 
00420   return result;
00421 }
00422 
00423 Alarm::List CalendarResources::alarmsTo( const QDateTime &to )
00424 {
00425   kdDebug(5800) << "CalendarResources::alarmsTo" << endl;
00426 
00427   Alarm::List result;
00428   CalendarResourceManager::ActiveIterator resit;
00429   for ( resit = mManager->activeBegin(); resit != mManager->activeEnd(); ++resit ) {
00430     Alarm::List list = (*resit)->alarmsTo( to );
00431     Alarm::List::Iterator alarmit;
00432     for ( alarmit = list.begin(); alarmit != list.end(); ++alarmit )
00433       result.append( *alarmit );
00434   }
00435   return result;
00436 }
00437 
00438 Alarm::List CalendarResources::alarms( const QDateTime &from,
00439                                        const QDateTime &to )
00440 {
00441   Alarm::List result;
00442   CalendarResourceManager::ActiveIterator resit;
00443   for ( resit = mManager->activeBegin(); resit != mManager->activeEnd(); ++resit ) {
00444     Alarm::List list = (*resit)->alarms( from, to );
00445     Alarm::List::Iterator alarmit;
00446     for ( alarmit = list.begin(); alarmit != list.end(); ++alarmit )
00447       result.append( *alarmit );
00448   }
00449   return result;
00450 }
00451 
00452 /****************************** PROTECTED METHODS ****************************/
00453 
00454 Event::List CalendarResources::rawEventsForDate( const QDate &date,
00455                                                  EventSortField sortField,
00456                                                  SortDirection sortDirection )
00457 {
00458   Event::List result;
00459   CalendarResourceManager::ActiveIterator it;
00460   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00461     Event::List list = (*it)->rawEventsForDate( date );
00462     Event::List::ConstIterator it2;
00463     for ( it2 = list.begin(); it2 != list.end(); ++it2 ) {
00464       result.append( *it2 );
00465       mResourceMap[ *it2 ] = *it;
00466     }
00467   }
00468   return sortEvents( &result, sortField, sortDirection );
00469 }
00470 
00471 Event::List CalendarResources::rawEvents( const QDate &start, const QDate &end,
00472                                           bool inclusive )
00473 {
00474   kdDebug(5800) << "CalendarResources::rawEvents(start,end,inclusive)" << endl;
00475 
00476   Event::List result;
00477   CalendarResourceManager::ActiveIterator it;
00478   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00479     Event::List list = (*it)->rawEvents( start, end, inclusive );
00480     Event::List::ConstIterator it2;
00481     for ( it2 = list.begin(); it2 != list.end(); ++it2 ) {
00482       result.append( *it2 );
00483       mResourceMap[ *it2 ] = *it;
00484     }
00485   }
00486   return result;
00487 }
00488 
00489 Event::List CalendarResources::rawEventsForDate( const QDateTime &qdt )
00490 {
00491   kdDebug(5800) << "CalendarResources::rawEventsForDate(qdt)" << endl;
00492 
00493   // @TODO: Remove the code duplication by the resourcemap iteration block.
00494   Event::List result;
00495   CalendarResourceManager::ActiveIterator it;
00496   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00497     Event::List list = (*it)->rawEventsForDate( qdt );
00498     Event::List::ConstIterator it2;
00499     for ( it2 = list.begin(); it2 != list.end(); ++it2 ) {
00500       result.append( *it2 );
00501       mResourceMap[ *it2 ] = *it;
00502     }
00503   }
00504   return result;
00505 }
00506 
00507 Event::List CalendarResources::rawEvents( EventSortField sortField,
00508                                           SortDirection sortDirection )
00509 {
00510   kdDebug(5800) << "CalendarResources::rawEvents()" << endl;
00511 
00512   Event::List result;
00513   CalendarResourceManager::ActiveIterator it;
00514   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00515     Event::List list = (*it)->rawEvents( EventSortUnsorted );
00516     Event::List::ConstIterator it2;
00517     for ( it2 = list.begin(); it2 != list.end(); ++it2 ) {
00518       result.append( *it2 );
00519       mResourceMap[ *it2 ] = *it;
00520     }
00521   }
00522   return sortEvents( &result, sortField, sortDirection );
00523 }
00524 
00525 
00526 bool CalendarResources::addJournal( Journal *journal )
00527 {
00528   kdDebug(5800) << "CalendarResources::addJournal" << endl;
00529   return addIncidence( journal );
00530 }
00531 
00532 bool CalendarResources::deleteJournal( Journal *journal )
00533 {
00534   kdDebug(5800) << "CalendarResources::deleteJournal" << endl;
00535 
00536   bool status;
00537   if ( mResourceMap.find( journal ) != mResourceMap.end() ) {
00538     status = mResourceMap[journal]->deleteJournal( journal );
00539     if ( status )
00540       mResourceMap.remove( journal );
00541   } else {
00542     CalendarResourceManager::ActiveIterator it;
00543     status = false;
00544     for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00545       status = (*it)->deleteJournal( journal ) || status;
00546     }
00547   }
00548 
00549   setModified( status );
00550   return status;
00551 }
00552 
00553 bool CalendarResources::addJournal( Journal *journal,
00554                                     ResourceCalendar *resource
00555   )
00556 {
00557   return addIncidence( journal, resource );
00558 }
00559 
00560 Journal *CalendarResources::journal( const QString &uid )
00561 {
00562   kdDebug(5800) << "CalendarResources::journal(uid)" << endl;
00563 
00564   CalendarResourceManager::ActiveIterator it;
00565   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00566     Journal* journal = (*it)->journal( uid );
00567     if ( journal ) {
00568       mResourceMap[journal] = *it;
00569       return journal;
00570     }
00571   }
00572 
00573   // Not found
00574   return 0;
00575 }
00576 
00577 Journal::List CalendarResources::rawJournals( JournalSortField sortField,
00578                                               SortDirection sortDirection )
00579 {
00580   kdDebug(5800) << "CalendarResources::rawJournals()" << endl;
00581 
00582   Journal::List result;
00583   CalendarResourceManager::ActiveIterator it;
00584   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00585     Journal::List journals = (*it)->rawJournals( JournalSortUnsorted );
00586     Journal::List::ConstIterator it2;
00587     for ( it2 = journals.begin(); it2 != journals.end(); ++it2 ) {
00588       result.append( *it2 );
00589       mResourceMap[ *it2 ] = *it;
00590     }
00591   }
00592   return sortJournals( &result, sortField, sortDirection );
00593 }
00594 
00595 Journal::List CalendarResources::rawJournalsForDate( const QDate &date )
00596 {
00597 
00598   Journal::List result;
00599 
00600   CalendarResourceManager::ActiveIterator it;
00601   for ( it = mManager->activeBegin(); it != mManager->activeEnd(); ++it ) {
00602     Journal::List journals = (*it)->rawJournalsForDate( date );
00603     Journal::List::ConstIterator it2;
00604     for ( it2 = journals.begin(); it2 != journals.end(); ++it2 ) {
00605       result.append( *it2 );
00606       mResourceMap[ *it2 ] = *it;
00607     }
00608   }
00609   return result;
00610 }
00611 
00612 void CalendarResources::connectResource( ResourceCalendar *resource )
00613 {
00614   connect( resource, SIGNAL( resourceChanged( ResourceCalendar * ) ),
00615            SIGNAL( calendarChanged() ) );
00616   connect( resource, SIGNAL( resourceSaved( ResourceCalendar * ) ),
00617            SIGNAL( calendarSaved() ) );
00618 
00619   connect( resource, SIGNAL( resourceLoadError( ResourceCalendar *,
00620                                                 const QString & ) ),
00621            SLOT( slotLoadError( ResourceCalendar *, const QString & ) ) );
00622   connect( resource, SIGNAL( resourceSaveError( ResourceCalendar *,
00623                                                 const QString & ) ),
00624            SLOT( slotSaveError( ResourceCalendar *, const QString & ) ) );
00625 }
00626 
00627 ResourceCalendar *CalendarResources::resource( Incidence *incidence )
00628 {
00629   if ( mResourceMap.find( incidence ) != mResourceMap.end() ) {
00630     return mResourceMap[ incidence ];
00631   }
00632   return 0;
00633 }
00634 
00635 void CalendarResources::resourceAdded( ResourceCalendar *resource )
00636 {
00637   kdDebug(5800) << "Resource added: " << resource->resourceName() << endl;
00638 
00639   if ( !resource->isActive() )
00640     return;
00641 
00642   if ( resource->open() ) {
00643     resource->load();
00644   }
00645 
00646   connectResource( resource );
00647 
00648   emit signalResourceAdded( resource );
00649 }
00650 
00651 void CalendarResources::resourceModified( ResourceCalendar *resource )
00652 {
00653   kdDebug(5800) << "Resource modified: " << resource->resourceName() << endl;
00654 
00655   emit signalResourceModified( resource );
00656 }
00657 
00658 void CalendarResources::resourceDeleted( ResourceCalendar *resource )
00659 {
00660   kdDebug(5800) << "Resource deleted: " << resource->resourceName() << endl;
00661 
00662   emit signalResourceDeleted( resource );
00663 }
00664 
00665 void CalendarResources::doSetTimeZoneId( const QString &timeZoneId )
00666 {
00667   // set the timezone for all resources. Otherwise we'll have those terrible
00668   // tz troubles ;-((
00669   CalendarResourceManager::Iterator i1;
00670   for ( i1 = mManager->begin(); i1 != mManager->end(); ++i1 ) {
00671     (*i1)->setTimeZoneId( timeZoneId );
00672   }
00673 }
00674 
00675 void CalendarResources::setTimeZoneIdViewOnly( const QString &timeZoneId )
00676 {
00677   reload( timeZoneId );
00678 }
00679 
00680 CalendarResources::Ticket
00681 *CalendarResources::requestSaveTicket( ResourceCalendar *resource )
00682 {
00683   kdDebug(5800) << "CalendarResources::requestSaveTicket()" << endl;
00684 
00685   KABC::Lock *lock = resource->lock();
00686   if ( !lock )
00687     return 0;
00688   if ( lock->lock() )
00689     return new Ticket( resource );
00690   else
00691     return 0;
00692 }
00693 
00694 bool CalendarResources::save( Ticket *ticket, Incidence *incidence )
00695 {
00696   kdDebug(5800) << "CalendarResources::save( Ticket *)" << endl;
00697 
00698   if ( !ticket || !ticket->resource() )
00699     return false;
00700 
00701   kdDebug(5800) << "tick " << ticket->resource()->resourceName() << endl;
00702 
00703     // @TODO: Check if the resource was changed at all. If not, don't save.
00704   if ( ticket->resource()->save( incidence ) ) {
00705     releaseSaveTicket( ticket );
00706     return true;
00707   }
00708 
00709   return false;
00710 }
00711 
00712 void CalendarResources::releaseSaveTicket( Ticket *ticket )
00713 {
00714   ticket->resource()->lock()->unlock();
00715   delete ticket;
00716 }
00717 
00718 bool CalendarResources::beginChange( Incidence *incidence )
00719 {
00720   kdDebug(5800) << "CalendarResources::beginChange()" << endl;
00721 
00722   ResourceCalendar *r = resource( incidence );
00723   if ( !r ) {
00724     r = mDestinationPolicy->destination( incidence );
00725     if ( !r ) {
00726       kdError() << "Unable to get destination resource." << endl;
00727       return false;
00728     }
00729     mResourceMap[ incidence ] = r;
00730   }
00731 
00732   int count = incrementChangeCount( r );
00733   if ( count == 1 ) {
00734     Ticket *ticket = requestSaveTicket( r );
00735     if ( !ticket ) {
00736       kdDebug(5800) << "CalendarResources::beginChange(): unable to get ticket."
00737                     << endl;
00738       decrementChangeCount( r );
00739       return false;
00740     } else {
00741       mTickets[ r ] = ticket;
00742     }
00743   }
00744 
00745   return true;
00746 }
00747 
00748 bool CalendarResources::endChange( Incidence *incidence )
00749 {
00750   kdDebug(5800) << "CalendarResource::endChange()" << endl;
00751 
00752   ResourceCalendar *r = resource( incidence );
00753   if ( !r )
00754     return false;
00755 
00756   int count = decrementChangeCount( r );
00757 
00758   if ( count == 0 ) {
00759     bool ok = save( mTickets[ r ], incidence );
00760     if ( ok ) {
00761       mTickets.remove( r );
00762     } else {
00763       return false;
00764     }
00765   }
00766 
00767   return true;
00768 }
00769 
00770 int CalendarResources::incrementChangeCount( ResourceCalendar *r )
00771 {
00772   if ( !mChangeCounts.contains( r ) ) {
00773     mChangeCounts.insert( r, 0 );
00774   }
00775 
00776   int count = mChangeCounts[ r ];
00777   ++count;
00778   mChangeCounts[ r ] = count;
00779 
00780   return count;
00781 }
00782 
00783 int CalendarResources::decrementChangeCount( ResourceCalendar *r )
00784 {
00785   if ( !mChangeCounts.contains( r ) ) {
00786     kdError() << "No change count for resource." << endl;
00787     return 0;
00788   }
00789 
00790   int count = mChangeCounts[ r ];
00791   --count;
00792   if ( count < 0 ) {
00793     kdError() << "Can't decrement change count. It already is 0." << endl;
00794     count = 0;
00795   }
00796   mChangeCounts[ r ] = count;
00797 
00798   return count;
00799 }
00800 
00801 void CalendarResources::slotLoadError( ResourceCalendar *, const QString &err )
00802 {
00803   emit signalErrorMessage( err );
00804 }
00805 
00806 void CalendarResources::slotSaveError( ResourceCalendar *, const QString &err )
00807 {
00808   emit signalErrorMessage( err );
00809 }
00810 
00811 #include "calendarresources.moc"