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