KCal Library
calendarresources.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the kcal library. 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 */ 00035 #include "calendarresources.moc" 00036 #include "incidence.h" 00037 #include "journal.h" 00038 #include "resourcecalendar.h" 00039 00040 #include "kresources/manager.h" 00041 #include "kresources/selectdialog.h" 00042 #include "kabc/lock.h" 00043 00044 #include <kdebug.h> 00045 #include <kdatetime.h> 00046 #include <kstandarddirs.h> 00047 #include <klocale.h> 00048 00049 #include <QtCore/QString> 00050 #include <QtCore/QList> 00051 00052 #include <stdlib.h> 00053 00054 using namespace KCal; 00055 00060 //@cond PRIVATE 00061 class KCal::CalendarResources::Private 00062 { 00063 public: 00064 Private( const QString &family ) 00065 : mAddingInProgress( false ), 00066 mLastUsedResource( 0 ), 00067 mManager( new CalendarResourceManager( family ) ), 00068 mStandardPolicy( new StandardDestinationPolicy( mManager ) ), 00069 mDestinationPolicy( mStandardPolicy ), 00070 mAskPolicy( new AskDestinationPolicy( mManager ) ), 00071 mException( 0 ), 00072 mPendingDeleteFromResourceMap( false ) 00073 {} 00074 ~Private() 00075 { 00076 delete mManager; 00077 delete mStandardPolicy; 00078 delete mAskPolicy; 00079 } 00080 bool mAddingInProgress; 00081 ResourceCalendar *mLastUsedResource; 00082 00083 bool mOpen; //flag that indicates if the resources are "open" 00084 00085 KRES::Manager<ResourceCalendar>* mManager; 00086 QMap <Incidence*, ResourceCalendar*> mResourceMap; 00087 00088 StandardDestinationPolicy *mStandardPolicy; 00089 DestinationPolicy *mDestinationPolicy; 00090 AskDestinationPolicy *mAskPolicy; 00091 00092 QMap<ResourceCalendar *, Ticket *> mTickets; 00093 QMap<ResourceCalendar *, int> mChangeCounts; 00094 00095 ErrorFormat *mException; 00096 00097 bool mPendingDeleteFromResourceMap; 00098 00099 template< class IncidenceList > 00100 void appendIncidences( IncidenceList &result, const IncidenceList &extra, 00101 ResourceCalendar * ); 00102 }; 00103 00104 class KCal::CalendarResources::DestinationPolicy::Private 00105 { 00106 public: 00107 Private( CalendarResourceManager *manager, QWidget *parent ) 00108 : mManager( manager ), 00109 mParent( parent ) 00110 {} 00111 CalendarResourceManager *mManager; 00112 QWidget *mParent; 00113 }; 00114 00115 class KCal::CalendarResources::StandardDestinationPolicy::Private 00116 { 00117 public: 00118 Private() 00119 {} 00120 }; 00121 00122 class KCal::CalendarResources::AskDestinationPolicy::Private 00123 { 00124 public: 00125 Private() 00126 {} 00127 }; 00128 00129 class KCal::CalendarResources::Ticket::Private 00130 { 00131 public: 00132 Private( ResourceCalendar *resource ) 00133 : mResource( resource ) 00134 {} 00135 ResourceCalendar *mResource; 00136 }; 00137 //@endcond 00138 00139 CalendarResources::DestinationPolicy::DestinationPolicy( 00140 CalendarResourceManager *manager, QWidget *parent ) 00141 : d( new KCal::CalendarResources::DestinationPolicy::Private( manager, parent ) ) 00142 { 00143 } 00144 00145 CalendarResources::DestinationPolicy::~DestinationPolicy() 00146 { 00147 delete d; 00148 } 00149 00150 QWidget *CalendarResources::DestinationPolicy::parent() 00151 { 00152 return d->mParent; 00153 } 00154 00155 void CalendarResources::DestinationPolicy::setParent( QWidget *parent ) 00156 { 00157 d->mParent = parent; 00158 } 00159 00160 CalendarResourceManager *CalendarResources::DestinationPolicy::resourceManager() 00161 { 00162 return d->mManager; 00163 } 00164 00165 bool CalendarResources::DestinationPolicy::hasCalendarResources() 00166 { 00167 CalendarResourceManager::ActiveIterator it; 00168 for ( it = resourceManager()->activeBegin(); 00169 it != resourceManager()->activeEnd(); ++it ) { 00170 if ( !(*it)->readOnly() ) { 00171 if ( resourceManager()->standardResource() == *it ) { 00172 return true; 00173 } else { 00174 return true; 00175 } 00176 } 00177 } 00178 return false; 00179 } 00180 00181 CalendarResources::StandardDestinationPolicy::StandardDestinationPolicy( 00182 CalendarResourceManager *manager, QWidget *parent ) 00183 : DestinationPolicy( manager, parent ), 00184 d( new KCal::CalendarResources::StandardDestinationPolicy::Private ) 00185 { 00186 } 00187 00188 CalendarResources::StandardDestinationPolicy::~StandardDestinationPolicy() 00189 { 00190 delete d; 00191 } 00192 00193 ResourceCalendar *CalendarResources::StandardDestinationPolicy::destination( Incidence *incidence ) 00194 { 00195 Q_UNUSED( incidence ); 00196 return resourceManager()->standardResource(); 00197 } 00198 00199 CalendarResources::AskDestinationPolicy::AskDestinationPolicy( 00200 CalendarResourceManager *manager, QWidget *parent ) 00201 : DestinationPolicy( manager, parent ), 00202 d( new KCal::CalendarResources::AskDestinationPolicy::Private ) 00203 { 00204 } 00205 00206 CalendarResources::AskDestinationPolicy::~AskDestinationPolicy() 00207 { 00208 delete d; 00209 } 00210 00211 ResourceCalendar *CalendarResources::AskDestinationPolicy::destination( Incidence *incidence ) 00212 { 00213 Q_UNUSED( incidence ); 00214 QList<KRES::Resource*> list; 00215 00216 CalendarResourceManager::ActiveIterator it; 00217 for ( it = resourceManager()->activeBegin(); 00218 it != resourceManager()->activeEnd(); ++it ) { 00219 if ( !(*it)->readOnly() ) { 00220 //Insert the first the Standard resource to get be the default selected. 00221 if ( resourceManager()->standardResource() == *it ) { 00222 list.insert( 0, *it ); 00223 } else { 00224 list.append( *it ); 00225 } 00226 } 00227 } 00228 00229 KRES::Resource *r; 00230 r = KRES::SelectDialog::getResource( list, parent() ); 00231 return static_cast<ResourceCalendar *>( r ); 00232 } 00233 00234 CalendarResources::CalendarResources( const KDateTime::Spec &timeSpec, 00235 const QString &family ) 00236 : Calendar( timeSpec ), 00237 d( new KCal::CalendarResources::Private( family ) ) 00238 { 00239 00240 connect( this, SIGNAL(batchAddingBegins()), this, SLOT(beginAddingIncidences()) ); 00241 connect( this, SIGNAL(batchAddingEnds()), this, SLOT(endAddingIncidences()) ); 00242 00243 d->mManager->addObserver( this ); 00244 } 00245 00246 CalendarResources::CalendarResources( const QString &timeZoneId, 00247 const QString &family ) 00248 : Calendar( timeZoneId ), 00249 d( new KCal::CalendarResources::Private( family ) ) 00250 { 00251 connect( this, SIGNAL(batchAddingBegins()), this, SLOT(beginAddingIncidences()) ); 00252 connect( this, SIGNAL(batchAddingEnds()), this, SLOT(endAddingIncidences()) ); 00253 00254 d->mManager->addObserver( this ); 00255 } 00256 00257 CalendarResources::~CalendarResources() 00258 { 00259 close(); 00260 clearException(); 00261 delete d; 00262 } 00263 00264 void CalendarResources::clearException() 00265 { 00266 delete d->mException; 00267 d->mException = 0; 00268 } 00269 00270 ErrorFormat *CalendarResources::exception() 00271 { 00272 return d->mException; 00273 } 00274 00275 void CalendarResources::readConfig( KConfig *config ) 00276 { 00277 d->mManager->readConfig( config ); 00278 00279 CalendarResourceManager::Iterator it; 00280 for ( it = d->mManager->begin(); it != d->mManager->end(); ++it ) { 00281 connectResource( *it ); 00282 } 00283 } 00284 00285 void CalendarResources::load() 00286 { 00287 if ( !d->mManager->standardResource() ) { 00288 kDebug() << "Warning! No standard resource yet."; 00289 } 00290 00291 // set the timezone for all resources. Otherwise we'll have those terrible tz 00292 // troubles ;-(( 00293 CalendarResourceManager::Iterator i1; 00294 for ( i1 = d->mManager->begin(); i1 != d->mManager->end(); ++i1 ) { 00295 (*i1)->setTimeSpec( timeSpec() ); 00296 } 00297 00298 QList<ResourceCalendar *> failed; 00299 00300 // Open all active resources 00301 CalendarResourceManager::ActiveIterator it; 00302 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00303 if ( !(*it)->load() ) { 00304 failed.append( *it ); 00305 } 00306 Incidence::List incidences = (*it)->rawIncidences(); 00307 Incidence::List::Iterator incit; 00308 for ( incit = incidences.begin(); incit != incidences.end(); ++incit ) { 00309 (*incit)->registerObserver( this ); 00310 notifyIncidenceAdded( *incit ); 00311 } 00312 } 00313 00314 QList<ResourceCalendar *>::ConstIterator it2; 00315 for ( it2 = failed.constBegin(); it2 != failed.constEnd(); ++it2 ) { 00316 (*it2)->setActive( false ); 00317 emit signalResourceModified( *it2 ); 00318 } 00319 00320 d->mOpen = true; 00321 emit calendarLoaded(); 00322 } 00323 00324 bool CalendarResources::reload() 00325 { 00326 save(); 00327 close(); 00328 load(); 00329 return true; 00330 } 00331 00332 CalendarResourceManager *CalendarResources::resourceManager() const 00333 { 00334 return d->mManager; 00335 } 00336 00337 void CalendarResources::setStandardDestinationPolicy() 00338 { 00339 d->mDestinationPolicy = d->mStandardPolicy; 00340 } 00341 00342 void CalendarResources::setAskDestinationPolicy() 00343 { 00344 d->mDestinationPolicy = d->mAskPolicy; 00345 } 00346 00347 QWidget *CalendarResources::dialogParentWidget() 00348 { 00349 return d->mDestinationPolicy->parent(); 00350 } 00351 00352 void CalendarResources::setDialogParentWidget( QWidget *parent ) 00353 { 00354 d->mDestinationPolicy->setParent( parent ); 00355 } 00356 00357 void CalendarResources::close() 00358 { 00359 if ( d->mOpen ) { 00360 CalendarResourceManager::ActiveIterator it; 00361 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00362 (*it)->close(); 00363 } 00364 00365 setModified( false ); 00366 d->mOpen = false; 00367 } 00368 } 00369 00370 bool CalendarResources::save() 00371 { 00372 bool status = true; 00373 if ( d->mOpen && isModified() ) { 00374 status = false; 00375 CalendarResourceManager::ActiveIterator it; 00376 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00377 status = (*it)->save() || status; 00378 } 00379 setModified( false ); 00380 } 00381 00382 return status; 00383 } 00384 00385 bool CalendarResources::isSaving() 00386 { 00387 CalendarResourceManager::ActiveIterator it; 00388 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00389 if ( (*it)->isSaving() ) { 00390 return true; 00391 } 00392 } 00393 return false; 00394 } 00395 00396 bool CalendarResources::addIncidence( Incidence *incidence, 00397 ResourceCalendar *resource ) 00398 { 00399 // FIXME: Use proper locking via begin/endChange! 00400 bool validRes = false; 00401 CalendarResourceManager::ActiveIterator it; 00402 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00403 if ( (*it) == resource ) { 00404 validRes = true; 00405 } 00406 } 00407 00408 ResourceCalendar *oldResource = 0; 00409 if ( d->mResourceMap.contains( incidence ) ) { 00410 oldResource = d->mResourceMap[incidence]; 00411 } 00412 d->mResourceMap[incidence] = resource; 00413 if ( validRes && beginChange( incidence ) && 00414 resource->addIncidence( incidence ) ) { 00415 // d->mResourceMap[incidence] = resource; 00416 incidence->registerObserver( this ); 00417 notifyIncidenceAdded( incidence ); 00418 setModified( true ); 00419 endChange( incidence ); 00420 return true; 00421 } else { 00422 if ( oldResource ) { 00423 d->mResourceMap[incidence] = oldResource; 00424 } else { 00425 d->mResourceMap.remove( incidence ); 00426 } 00427 } 00428 00429 return false; 00430 } 00431 00432 bool CalendarResources::addIncidence( Incidence *incidence ) 00433 { 00434 clearException(); 00435 00436 ResourceCalendar *resource = d->mLastUsedResource; 00437 00438 if ( !d->mAddingInProgress || d->mLastUsedResource == 0 ) { 00439 resource = d->mDestinationPolicy->destination( incidence ); 00440 d->mLastUsedResource = resource; 00441 } 00442 00443 if ( resource ) { 00444 d->mResourceMap[ incidence ] = resource; 00445 00446 if ( beginChange( incidence ) && resource->addIncidence( incidence ) ) { 00447 incidence->registerObserver( this ); 00448 notifyIncidenceAdded( incidence ); 00449 00450 d->mResourceMap[ incidence ] = resource; 00451 setModified( true ); 00452 endChange( incidence ); 00453 return true; 00454 } else { 00455 d->mResourceMap.remove( incidence ); 00456 } 00457 } else { 00458 d->mException = new ErrorFormat( ErrorFormat::UserCancel ); 00459 } 00460 00461 return false; 00462 } 00463 00464 bool CalendarResources::addEvent( Event *event ) 00465 { 00466 return addIncidence( event ); 00467 } 00468 00469 bool CalendarResources::addEvent( Event *Event, ResourceCalendar *resource ) 00470 { 00471 return addIncidence( Event, resource ); 00472 } 00473 00474 bool CalendarResources::deleteEvent( Event *event ) 00475 { 00476 bool status; 00477 if ( d->mResourceMap.find( event ) != d->mResourceMap.end() ) { 00478 status = d->mResourceMap[event]->deleteEvent( event ); 00479 if ( status ) { 00480 d->mPendingDeleteFromResourceMap = true; 00481 } 00482 } else { 00483 status = false; 00484 CalendarResourceManager::ActiveIterator it; 00485 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00486 status = (*it)->deleteEvent( event ) || status; 00487 } 00488 } 00489 if ( status ) { 00490 notifyIncidenceDeleted( event ); 00491 } 00492 00493 setModified( status ); 00494 return status; 00495 } 00496 00497 void CalendarResources::deleteAllEvents() 00498 { 00499 CalendarResourceManager::ActiveIterator it; 00500 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00501 (*it)->deleteAllEvents(); 00502 } 00503 } 00504 00505 Event *CalendarResources::event( const QString &uid ) 00506 { 00507 CalendarResourceManager::ActiveIterator it; 00508 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00509 Event *event = (*it)->event( uid ); 00510 if ( event ) { 00511 d->mResourceMap[event] = *it; 00512 return event; 00513 } 00514 } 00515 00516 // Not found 00517 return 0; 00518 } 00519 00520 bool CalendarResources::addTodo( Todo *todo ) 00521 { 00522 return addIncidence( todo ); 00523 } 00524 00525 bool CalendarResources::addTodo( Todo *todo, ResourceCalendar *resource ) 00526 { 00527 return addIncidence( todo, resource ); 00528 } 00529 00530 bool CalendarResources::deleteTodo( Todo *todo ) 00531 { 00532 bool status; 00533 if ( d->mResourceMap.find( todo ) != d->mResourceMap.end() ) { 00534 status = d->mResourceMap[todo]->deleteTodo( todo ); 00535 if ( status ) { 00536 d->mPendingDeleteFromResourceMap = true; 00537 } 00538 } else { 00539 CalendarResourceManager::ActiveIterator it; 00540 status = false; 00541 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00542 status = (*it)->deleteTodo( todo ) || status; 00543 } 00544 } 00545 00546 setModified( status ); 00547 return status; 00548 } 00549 00550 void CalendarResources::deleteAllTodos() 00551 { 00552 CalendarResourceManager::ActiveIterator it; 00553 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00554 (*it)->deleteAllTodos(); 00555 } 00556 } 00557 00558 Todo::List CalendarResources::rawTodos( TodoSortField sortField, 00559 SortDirection sortDirection ) 00560 { 00561 Todo::List result; 00562 00563 CalendarResourceManager::ActiveIterator it; 00564 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00565 d->appendIncidences<Todo::List>( result, 00566 (*it)->rawTodos( TodoSortUnsorted ), *it ); 00567 } 00568 return sortTodos( &result, sortField, sortDirection ); 00569 } 00570 00571 Todo *CalendarResources::todo( const QString &uid ) 00572 { 00573 CalendarResourceManager::ActiveIterator it; 00574 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00575 Todo *todo = (*it)->todo( uid ); 00576 if ( todo ) { 00577 d->mResourceMap[todo] = *it; 00578 return todo; 00579 } 00580 } 00581 00582 // Not found 00583 return 0; 00584 } 00585 00586 Todo::List CalendarResources::rawTodosForDate( const QDate &date ) 00587 { 00588 Todo::List result; 00589 00590 CalendarResourceManager::ActiveIterator it; 00591 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00592 d->appendIncidences<Todo::List>( result, 00593 (*it)->rawTodosForDate( date ), *it ); 00594 } 00595 return result; 00596 } 00597 00598 Alarm::List CalendarResources::alarmsTo( const KDateTime &to ) 00599 { 00600 Alarm::List result; 00601 CalendarResourceManager::ActiveIterator it; 00602 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00603 result += (*it)->alarmsTo( to ); 00604 } 00605 return result; 00606 } 00607 00608 Alarm::List CalendarResources::alarms( const KDateTime &from, 00609 const KDateTime &to ) 00610 { 00611 Alarm::List result; 00612 CalendarResourceManager::ActiveIterator it; 00613 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00614 result += (*it)->alarms( from, to ); 00615 } 00616 return result; 00617 } 00618 00619 bool CalendarResources::hasCalendarResources() 00620 { 00621 return d->mDestinationPolicy->hasCalendarResources(); 00622 } 00623 00624 /****************************** PROTECTED METHODS ****************************/ 00625 00626 Event::List CalendarResources::rawEventsForDate( const QDate &date, 00627 const KDateTime::Spec &timeSpec, 00628 EventSortField sortField, 00629 SortDirection sortDirection ) 00630 { 00631 Event::List result; 00632 CalendarResourceManager::ActiveIterator it; 00633 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00634 d->appendIncidences<Event::List>( result, 00635 (*it)->rawEventsForDate( date, timeSpec ), *it ); 00636 } 00637 return sortEventsForDate( &result, date, timeSpec, sortField, sortDirection ); 00638 } 00639 00640 Event::List CalendarResources::rawEvents( const QDate &start, const QDate &end, 00641 const KDateTime::Spec &timeSpec, bool inclusive ) 00642 { 00643 Event::List result; 00644 CalendarResourceManager::ActiveIterator it; 00645 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00646 d->appendIncidences<Event::List>( result, 00647 (*it)->rawEvents( start, end, timeSpec, inclusive ), *it ); 00648 } 00649 return result; 00650 } 00651 00652 Event::List CalendarResources::rawEventsForDate( const KDateTime &kdt ) 00653 { 00654 // @TODO: Remove the code duplication by the resourcemap iteration block. 00655 Event::List result; 00656 CalendarResourceManager::ActiveIterator it; 00657 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00658 d->appendIncidences<Event::List>( result, 00659 (*it)->rawEventsForDate( kdt ), *it ); 00660 } 00661 return result; 00662 } 00663 00664 Event::List CalendarResources::rawEvents( EventSortField sortField, 00665 SortDirection sortDirection ) 00666 { 00667 Event::List result; 00668 CalendarResourceManager::ActiveIterator it; 00669 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00670 d->appendIncidences<Event::List>( result, 00671 (*it)->rawEvents( EventSortUnsorted ), *it ); 00672 } 00673 return sortEvents( &result, sortField, sortDirection ); 00674 } 00675 00676 bool CalendarResources::addJournal( Journal *journal ) 00677 { 00678 return addIncidence( journal ); 00679 } 00680 00681 bool CalendarResources::addJournal( Journal *journal, ResourceCalendar *resource ) 00682 { 00683 return addIncidence( journal, resource ); 00684 } 00685 00686 bool CalendarResources::deleteJournal( Journal *journal ) 00687 { 00688 bool status; 00689 if ( d->mResourceMap.find( journal ) != d->mResourceMap.end() ) { 00690 status = d->mResourceMap[journal]->deleteJournal( journal ); 00691 if ( status ) { 00692 d->mPendingDeleteFromResourceMap = true; 00693 } 00694 } else { 00695 CalendarResourceManager::ActiveIterator it; 00696 status = false; 00697 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00698 status = (*it)->deleteJournal( journal ) || status; 00699 } 00700 } 00701 00702 setModified( status ); 00703 return status; 00704 } 00705 00706 void CalendarResources::deleteAllJournals() 00707 { 00708 CalendarResourceManager::ActiveIterator it; 00709 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00710 (*it)->deleteAllJournals(); 00711 } 00712 } 00713 00714 Journal *CalendarResources::journal( const QString &uid ) 00715 { 00716 CalendarResourceManager::ActiveIterator it; 00717 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00718 Journal *journal = (*it)->journal( uid ); 00719 if ( journal ) { 00720 d->mResourceMap[journal] = *it; 00721 return journal; 00722 } 00723 } 00724 00725 // Not found 00726 return 0; 00727 } 00728 00729 Journal::List CalendarResources::rawJournals( JournalSortField sortField, 00730 SortDirection sortDirection ) 00731 { 00732 Journal::List result; 00733 CalendarResourceManager::ActiveIterator it; 00734 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00735 d->appendIncidences<Journal::List>( result, 00736 (*it)->rawJournals( JournalSortUnsorted ), *it ); 00737 } 00738 return sortJournals( &result, sortField, sortDirection ); 00739 } 00740 00741 Journal::List CalendarResources::rawJournalsForDate( const QDate &date ) 00742 { 00743 00744 Journal::List result; 00745 00746 CalendarResourceManager::ActiveIterator it; 00747 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) { 00748 d->appendIncidences<Journal::List>( result, 00749 (*it)->rawJournalsForDate( date ), *it ); 00750 } 00751 return result; 00752 } 00753 00754 //@cond PRIVATE 00755 template< class IncidenceList > 00756 void CalendarResources::Private::appendIncidences( IncidenceList &result, 00757 const IncidenceList &extra, 00758 ResourceCalendar *resource ) 00759 { 00760 result += extra; 00761 for ( typename IncidenceList::ConstIterator it = extra.begin(); 00762 it != extra.end(); 00763 ++it ) { 00764 mResourceMap[ *it ] = resource; 00765 } 00766 } 00767 //@endcond 00768 00769 void CalendarResources::connectResource( ResourceCalendar *resource ) 00770 { 00771 connect( resource, SIGNAL(resourceChanged(ResourceCalendar*)), 00772 SIGNAL(calendarChanged()) ); 00773 connect( resource, SIGNAL(resourceSaved(ResourceCalendar*)), 00774 SIGNAL(calendarSaved()) ); 00775 00776 connect( resource, SIGNAL(resourceLoadError(ResourceCalendar*,QString)), 00777 SLOT(slotLoadError(ResourceCalendar*,QString)) ); 00778 connect( resource, SIGNAL(resourceSaveError(ResourceCalendar*,QString)), 00779 SLOT(slotSaveError(ResourceCalendar*,QString)) ); 00780 } 00781 00782 ResourceCalendar *CalendarResources::resource( Incidence *incidence ) 00783 { 00784 if ( d->mResourceMap.find( incidence ) != d->mResourceMap.end() ) { 00785 return d->mResourceMap[ incidence ]; 00786 } 00787 return 0; 00788 } 00789 00790 void CalendarResources::resourceAdded( ResourceCalendar *resource ) 00791 { 00792 if ( !resource->isActive() ) { 00793 return; 00794 } 00795 00796 if ( resource->open() ) { 00797 resource->load(); 00798 } 00799 00800 connectResource( resource ); 00801 00802 emit signalResourceAdded( resource ); 00803 } 00804 00805 void CalendarResources::resourceModified( ResourceCalendar *resource ) 00806 { 00807 emit signalResourceModified( resource ); 00808 } 00809 00810 void CalendarResources::resourceDeleted( ResourceCalendar *resource ) 00811 { 00812 emit signalResourceDeleted( resource ); 00813 } 00814 00815 void CalendarResources::doSetTimeSpec( const KDateTime::Spec &timeSpec ) 00816 { 00817 // set the timezone for all resources. Otherwise we'll have those terrible 00818 // tz troubles ;-(( 00819 CalendarResourceManager::Iterator i1; 00820 for ( i1 = d->mManager->begin(); i1 != d->mManager->end(); ++i1 ) { 00821 (*i1)->setTimeSpec( timeSpec ); 00822 } 00823 } 00824 00825 CalendarResources::Ticket::Ticket( ResourceCalendar *resource ) 00826 : d( new KCal::CalendarResources::Ticket::Private( resource ) ) 00827 { 00828 } 00829 00830 CalendarResources::Ticket::~Ticket() 00831 { 00832 delete d; 00833 } 00834 00835 CalendarResources::Ticket *CalendarResources::requestSaveTicket( ResourceCalendar *resource ) 00836 { 00837 KABC::Lock *lock = resource->lock(); 00838 if ( !lock ) { 00839 return 0; 00840 } 00841 if ( lock->lock() ) { 00842 return new Ticket( resource ); 00843 } else { 00844 return 0; 00845 } 00846 } 00847 00848 ResourceCalendar *CalendarResources::Ticket::resource() const 00849 { 00850 return d->mResource; 00851 } 00852 00853 bool CalendarResources::save( Ticket *ticket, Incidence *incidence ) 00854 { 00855 if ( !ticket || !ticket->resource() ) { 00856 return false; 00857 } 00858 00859 // @TODO: Check if the resource was changed at all. If not, don't save. 00860 if ( ticket->resource()->save( incidence ) ) { 00861 releaseSaveTicket( ticket ); 00862 return true; 00863 } 00864 00865 return false; 00866 } 00867 00868 void CalendarResources::releaseSaveTicket( Ticket *ticket ) 00869 { 00870 ticket->resource()->lock()->unlock(); 00871 delete ticket; 00872 } 00873 00874 bool CalendarResources::beginChange( Incidence *incidence ) 00875 { 00876 ResourceCalendar *r = resource( incidence ); 00877 if ( !r ) { 00878 r = d->mDestinationPolicy->destination( incidence ); 00879 if ( !r ) { 00880 kError() << "Unable to get destination resource."; 00881 return false; 00882 } 00883 d->mResourceMap[ incidence ] = r; 00884 } 00885 d->mPendingDeleteFromResourceMap = false; 00886 00887 int count = incrementChangeCount( r ); 00888 if ( count == 1 ) { 00889 Ticket *ticket = requestSaveTicket( r ); 00890 if ( !ticket ) { 00891 kDebug() << "unable to get ticket."; 00892 decrementChangeCount( r ); 00893 return false; 00894 } else { 00895 d->mTickets[ r ] = ticket; 00896 } 00897 } 00898 00899 return true; 00900 } 00901 00902 bool CalendarResources::endChange( Incidence *incidence ) 00903 { 00904 ResourceCalendar *r = resource( incidence ); 00905 if ( !r ) { 00906 return false; 00907 } 00908 00909 int count = decrementChangeCount( r ); 00910 00911 if ( d->mPendingDeleteFromResourceMap ) { 00912 d->mResourceMap.remove( incidence ); 00913 d->mPendingDeleteFromResourceMap = false; 00914 } 00915 00916 if ( count == 0 ) { 00917 bool ok = save( d->mTickets[ r ], incidence ); 00918 if ( ok ) { 00919 d->mTickets.remove( r ); 00920 } else { 00921 return false; 00922 } 00923 } 00924 00925 return true; 00926 } 00927 00928 void CalendarResources::beginAddingIncidences() 00929 { 00930 d->mAddingInProgress = true; 00931 } 00932 00933 void CalendarResources::endAddingIncidences() 00934 { 00935 d->mAddingInProgress = false; 00936 d->mLastUsedResource = 0; 00937 } 00938 00939 int CalendarResources::incrementChangeCount( ResourceCalendar *r ) 00940 { 00941 if ( !d->mChangeCounts.contains( r ) ) { 00942 d->mChangeCounts.insert( r, 0 ); 00943 } 00944 00945 int count = d->mChangeCounts[ r ]; 00946 ++count; 00947 d->mChangeCounts[ r ] = count; 00948 00949 return count; 00950 } 00951 00952 int CalendarResources::decrementChangeCount( ResourceCalendar *r ) 00953 { 00954 if ( !d->mChangeCounts.contains( r ) ) { 00955 kError() << "No change count for resource."; 00956 return 0; 00957 } 00958 00959 int count = d->mChangeCounts[ r ]; 00960 --count; 00961 if ( count < 0 ) { 00962 kError() << "Can't decrement change count. It already is 0."; 00963 count = 0; 00964 } 00965 d->mChangeCounts[ r ] = count; 00966 00967 return count; 00968 } 00969 00970 void CalendarResources::slotLoadError( ResourceCalendar *r, const QString &err ) 00971 { 00972 Q_UNUSED( r ); 00973 emit signalErrorMessage( err ); 00974 } 00975 00976 void CalendarResources::slotSaveError( ResourceCalendar *r, const QString &err ) 00977 { 00978 Q_UNUSED( r ); 00979 emit signalErrorMessage( err ); 00980 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:49:42 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:49:42 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.