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