00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "calendarview.h"
00034
00035 #ifndef KORG_NOPRINTER
00036 #include "calprinter.h"
00037 #endif
00038 #include "koeventeditor.h"
00039 #include "kotodoeditor.h"
00040 #include "kojournaleditor.h"
00041 #include "koprefs.h"
00042 #include "koeventviewerdialog.h"
00043 #include "publishdialog.h"
00044 #include "koglobals.h"
00045 #include "koviewmanager.h"
00046 #include "koagendaview.h"
00047 #include "kodialogmanager.h"
00048 #include "statusdialog.h"
00049 #include "datenavigatorcontainer.h"
00050 #include "kotodoview.h"
00051 #include "datenavigator.h"
00052 #include "resourceview.h"
00053 #include "navigatorbar.h"
00054 #include "history.h"
00055 #include "kogroupware.h"
00056 #include "freebusymanager.h"
00057 #include "komonthview.h"
00058 #include "datechecker.h"
00059 #include "komessagebox.h"
00060 #include "exportwebdialog.h"
00061 #include "kocorehelper.h"
00062 #include "incidencechanger.h"
00063 #include "kholidays.h"
00064 #include "mailscheduler.h"
00065 #include "komailclient.h"
00066 #include "multiagendaview.h"
00067
00068 #include <libkcal/calhelper.h>
00069 #include <libkcal/vcaldrag.h>
00070 #include <libkcal/icaldrag.h>
00071 #include <libkcal/icalformat.h>
00072 #include <libkcal/vcalformat.h>
00073 #include <libkcal/scheduler.h>
00074 #include <libkcal/calendarlocal.h>
00075 #include <libkcal/journal.h>
00076 #include <libkcal/calfilter.h>
00077 #include <libkcal/attendee.h>
00078 #include <libkcal/dndfactory.h>
00079 #include <libkcal/freebusy.h>
00080 #include <libkcal/filestorage.h>
00081 #include <libkcal/calendarresources.h>
00082 #include <libkcal/calendarnull.h>
00083 #include <libkcal/htmlexportsettings.h>
00084
00085 #include <kglobal.h>
00086 #include <kdebug.h>
00087 #include <kstandarddirs.h>
00088 #include <kfiledialog.h>
00089 #include <kmessagebox.h>
00090 #include <knotifyclient.h>
00091 #include <kconfig.h>
00092 #include <krun.h>
00093 #include <kdirwatch.h>
00094
00095 #include <qapplication.h>
00096 #include <qclipboard.h>
00097 #include <qcursor.h>
00098 #include <qmultilineedit.h>
00099 #include <qtimer.h>
00100 #include <qwidgetstack.h>
00101 #include <qptrlist.h>
00102 #include <qfile.h>
00103 #include <qlayout.h>
00104 #ifndef KORG_NOSPLITTER
00105 #include <qsplitter.h>
00106 #endif
00107 #include <qvbox.h>
00108 #include <qwhatsthis.h>
00109
00110 #include <stdlib.h>
00111 #include <assert.h>
00112
00113 using namespace KOrg;
00114
00115 CalendarView::CalendarView( QWidget *parent, const char *name )
00116 : CalendarViewBase( parent, name ),
00117 mHistory( 0 ),
00118 mCalendar( CalendarNull::self() ),
00119 mChanger( 0 )
00120 {
00121 kdDebug(5850) << "CalendarView::CalendarView( Calendar )" << endl;
00122
00123 mViewManager = new KOViewManager( this );
00124 mDialogManager = new KODialogManager( this );
00125
00126 mModified = false;
00127 mReadOnly = false;
00128 mSelectedIncidence = 0;
00129
00130 mFilters.setAutoDelete( true );
00131
00132 mExtensions.setAutoDelete( true );
00133
00134 mDateNavigator = new DateNavigator( this );
00135 mDateChecker = new DateChecker( this );
00136
00137 QBoxLayout *topLayout = new QVBoxLayout( this );
00138
00139 #ifndef KORG_NOSPLITTER
00140
00141 mPanner = new QSplitter( QSplitter::Horizontal, this,
00142 "CalendarView::Panner" );
00143 topLayout->addWidget( mPanner );
00144
00145 mLeftSplitter = new QSplitter( QSplitter::Vertical, mPanner,
00146 "CalendarView::LeftFrame" );
00147
00148
00149 mDateNavigatorContainer = new DateNavigatorContainer( mLeftSplitter,
00150 "CalendarView::DateNavigator" );
00151
00152
00153 mLeftSplitter->setCollapsible( mDateNavigatorContainer, true );
00154 mTodoList = new KOTodoView( CalendarNull::self(), mLeftSplitter, "todolist" );
00155
00156 mEventViewer = new KOEventViewer( CalendarNull::self(), mLeftSplitter,"EventViewer" );
00157
00158 QVBox *rightBox = new QVBox( mPanner );
00159 mNavigatorBar = new NavigatorBar( rightBox );
00160 mRightFrame = new QWidgetStack( rightBox );
00161 rightBox->setStretchFactor( mRightFrame, 1 );
00162
00163 mLeftFrame = mLeftSplitter;
00164 #else
00165 QWidget *mainBox;
00166 QWidget *leftFrame;
00167
00168 if ( KOPrefs::instance()->mVerticalScreen ) {
00169 mainBox = new QVBox( this );
00170 leftFrame = new QHBox( mainBox );
00171 } else {
00172 mainBox = new QHBox( this );
00173 leftFrame = new QVBox( mainBox );
00174 }
00175
00176 topLayout->addWidget( mainBox );
00177
00178 mDateNavigatorContainer = new KDateNavigator( leftFrame, true,
00179 "CalendarView::DateNavigator",
00180 QDate::currentDate() );
00181 mTodoList = new KOTodoView( CalendarNull::self(), leftFrame, "todolist" );
00182
00183 mEventViewer = new KOEventViewer ( CalendarNull::self(), leftFrame, "EventViewer" );
00184
00185 QWidget *rightBox = new QWidget( mainBox );
00186 QBoxLayout *rightLayout = new QVBoxLayout( rightBox );
00187
00188 mNavigatorBar = new NavigatorBar( QDate::currentDate(), rightBox );
00189 rightLayout->addWidget( mNavigatorBar );
00190
00191 mRightFrame = new QWidgetStack( rightBox );
00192 rightLayout->addWidget( mRightFrame );
00193
00194 mLeftFrame = leftFrame;
00195
00196 if ( KOPrefs::instance()->mVerticalScreen ) {
00197
00198 mTodoList->setFixedHeight( mDateNavigatorContainer->sizeHint().height() );
00199 }
00200 #endif
00201
00202
00203 connect( mDateNavigator, SIGNAL( datesSelected( const KCal::DateList &, const QDate & ) ),
00204 SLOT( showDates( const KCal::DateList &, const QDate & ) ) );
00205
00206
00207 connect( mNavigatorBar, SIGNAL( prevYearClicked() ),
00208 mDateNavigator, SLOT( selectPreviousYear() ) );
00209 connect( mNavigatorBar, SIGNAL( nextYearClicked() ),
00210 mDateNavigator, SLOT( selectNextYear() ) );
00211 connect( mNavigatorBar, SIGNAL( prevMonthClicked() ),
00212 mDateNavigator, SLOT( selectPreviousMonth() ) );
00213 connect( mNavigatorBar, SIGNAL( nextMonthClicked() ),
00214 mDateNavigator, SLOT( selectNextMonth() ) );
00215 connect( mNavigatorBar, SIGNAL( monthSelected(int) ),
00216 mDateNavigator, SLOT( selectMonth(int) ) );
00217 connect( mNavigatorBar, SIGNAL( yearSelected(int)),
00218 mDateNavigator, SLOT(selectYear(int)) );
00219
00220
00221
00222 connect( mDateNavigatorContainer, SIGNAL( weekClicked( const QDate & ) ),
00223 this, SLOT( selectWeek( const QDate & ) ) );
00224 connect( mDateNavigatorContainer, SIGNAL( prevMonthClicked(const QDate &, const QDate &, const QDate &) ),
00225 mDateNavigator, SLOT( selectPreviousMonth(const QDate &, const QDate &, const QDate &) ) );
00226 connect( mDateNavigatorContainer, SIGNAL( nextMonthClicked(const QDate &, const QDate &, const QDate &) ),
00227 mDateNavigator, SLOT( selectNextMonth(const QDate &, const QDate &, const QDate &) ) );
00228 connect( mDateNavigatorContainer, SIGNAL( prevYearClicked() ),
00229 mDateNavigator, SLOT( selectPreviousYear() ) );
00230 connect( mDateNavigatorContainer, SIGNAL( nextYearClicked() ),
00231 mDateNavigator, SLOT( selectNextYear() ) );
00232 connect( mDateNavigatorContainer, SIGNAL( monthSelected(int) ),
00233 mDateNavigator, SLOT( selectMonth(int) ) );
00234 connect( mDateNavigatorContainer, SIGNAL(yearSelected(int)),
00235 mDateNavigator, SLOT(selectYear(int)) );
00236 connect( mDateNavigatorContainer, SIGNAL( goPrevious() ),
00237 mDateNavigator, SLOT( selectPrevious() ) );
00238 connect( mDateNavigatorContainer, SIGNAL( goNext() ),
00239 mDateNavigator, SLOT( selectNext() ) );
00240
00241 connect( mDateNavigatorContainer, SIGNAL( datesSelected( const KCal::DateList & ) ),
00242 mDateNavigator, SLOT( selectDates( const KCal::DateList & ) ) );
00243
00244 connect( mDateNavigatorContainer, SIGNAL(incidenceDropped(Incidence*, const QDate&)),
00245 SLOT( addIncidenceOn( Incidence *, const QDate & ) ) );
00246 connect( mDateNavigatorContainer, SIGNAL(incidenceDroppedMove(Incidence*,const QDate&)),
00247 SLOT( moveIncidenceTo( Incidence *, const QDate & ) ) );
00248
00249 connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00250 mTodoList, SLOT( dayPassed( const QDate & ) ) );
00251 connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00252 SIGNAL( dayPassed( const QDate & ) ) );
00253 connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00254 mDateNavigatorContainer, SLOT( updateToday() ) );
00255
00256 connect( this, SIGNAL( configChanged() ),
00257 mDateNavigatorContainer, SLOT( updateConfig() ) );
00258
00259 connect( this, SIGNAL( incidenceSelected(Incidence *, const QDate &) ),
00260 mEventViewer, SLOT ( setIncidence (Incidence *, const QDate &) ) );
00261
00262
00263 QString s;
00264 s = i18n( "<p><em>No Item Selected</em></p>"
00265 "<p>Select an event, to-do or journal entry to view its details "
00266 "here.</p>");
00267
00268 mEventViewer->setDefaultText( s );
00269 QWhatsThis::add( mEventViewer,
00270 i18n( "View the details of events, journal entries or to-dos "
00271 "selected in KOrganizer's main view here." ) );
00272 mEventViewer->setIncidence( 0, QDate() );
00273
00274 mViewManager->connectTodoView( mTodoList );
00275 mViewManager->connectView( mTodoList );
00276
00277 KOGlobals::self()->
00278 setHolidays( new KHolidays( KOPrefs::instance()->mHolidays ) );
00279
00280 connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00281 SLOT( checkClipboard() ) );
00282
00283 connect( mTodoList, SIGNAL( incidenceSelected( Incidence *,const QDate & ) ),
00284 SLOT( processTodoListSelection( Incidence *,const QDate & ) ) );
00285 disconnect( mTodoList, SIGNAL( incidenceSelected( Incidence *,const QDate & ) ),
00286 this, SLOT( processMainViewSelection( Incidence *,const QDate & ) ) );
00287
00288 kdDebug(5850) << "CalendarView::CalendarView() done" << endl;
00289 }
00290
00291 CalendarView::~CalendarView()
00292 {
00293 kdDebug(5850) << "~CalendarView()" << endl;
00294
00295 mCalendar->unregisterObserver( this );
00296
00297 delete mDialogManager;
00298 delete mViewManager;
00299 delete mEventViewer;
00300 kdDebug(5850) << "~CalendarView() done" << endl;
00301 }
00302
00303 void CalendarView::setCalendar( Calendar *cal )
00304 {
00305 kdDebug(5850)<<"CalendarView::setCalendar"<<endl;
00306 mCalendar = cal;
00307
00308 delete mHistory;
00309 mHistory = new History( mCalendar );
00310 connect( mHistory, SIGNAL( undone() ), SLOT( updateView() ) );
00311 connect( mHistory, SIGNAL( redone() ), SLOT( updateView() ) );
00312
00313 if ( mChanger ) delete mChanger;
00314 setIncidenceChanger( new IncidenceChanger( mCalendar, this ) );
00315
00316 mCalendar->registerObserver( this );
00317
00318 mDateNavigatorContainer->setCalendar( mCalendar );
00319
00320 mTodoList->setCalendar( mCalendar );
00321
00322 mEventViewer->setCalendar( mCalendar );
00323 }
00324
00325 void CalendarView::setIncidenceChanger( IncidenceChangerBase *changer )
00326 {
00327 mChanger = changer;
00328 emit newIncidenceChanger( mChanger );
00329 connect( mChanger, SIGNAL( incidenceAdded( Incidence* ) ),
00330 this, SLOT( incidenceAdded( Incidence* ) ) );
00331 connect( mChanger, SIGNAL( incidenceChanged( Incidence*, Incidence*, KOGlobals::WhatChanged ) ),
00332 this, SLOT( incidenceChanged( Incidence*, Incidence*, KOGlobals::WhatChanged ) ) );
00333 connect( mChanger, SIGNAL( incidenceToBeDeleted( Incidence * ) ),
00334 this, SLOT( incidenceToBeDeleted( Incidence * ) ) );
00335 connect( mChanger, SIGNAL( incidenceDeleted( Incidence * ) ),
00336 this, SLOT( incidenceDeleted( Incidence * ) ) );
00337
00338 connect( mChanger, SIGNAL( schedule( Scheduler::Method, Incidence*) ),
00339 this, SLOT( schedule( Scheduler::Method, Incidence*) ) );
00340
00341
00342 connect( this, SIGNAL( cancelAttendees( Incidence * ) ),
00343 mChanger, SLOT( cancelAttendees( Incidence * ) ) );
00344 }
00345
00346 Calendar *CalendarView::calendar()
00347 {
00348 if ( mCalendar ) return mCalendar;
00349 else return CalendarNull::self();
00350 }
00351
00352 QPair<ResourceCalendar *, QString> CalendarView::viewSubResourceCalendar()
00353 {
00354 QPair<ResourceCalendar *, QString> p( 0, QString() );
00355 KOrg::BaseView *cV = mViewManager->currentView();
00356 if ( cV && cV == mViewManager->multiAgendaView() ) {
00357 cV = mViewManager->multiAgendaView()->selectedAgendaView();
00358 }
00359 if ( cV ) {
00360 p = qMakePair( cV->resourceCalendar(), cV->subResourceCalendar() );
00361 }
00362 return p;
00363 }
00364
00365 KOIncidenceEditor *CalendarView::editorDialog( Incidence *incidence ) const
00366 {
00367 if (mDialogList.find(incidence) != mDialogList.end ())
00368 return mDialogList[incidence];
00369 else return 0;
00370 }
00371
00372 QDate CalendarView::activeDate( bool fallbackToToday )
00373 {
00374 KOrg::BaseView *curView = mViewManager->currentView();
00375 if ( curView ) {
00376 if ( curView->selectionStart().isValid() ) {
00377 return curView->selectionStart().date();
00378 }
00379
00380
00381 if ( !curView->selectedIncidenceDates().isEmpty() ) {
00382 if ( curView->selectedIncidenceDates().first().isValid() ) {
00383 return curView->selectedIncidenceDates().first();
00384 }
00385 }
00386 }
00387
00388
00389 if ( fallbackToToday ) {
00390 return QDate::currentDate();
00391 } else {
00392 return mDateNavigator->selectedDates().first();
00393 }
00394 }
00395
00396 QDate CalendarView::activeIncidenceDate()
00397 {
00398 KOrg::BaseView *curView = mViewManager->currentView();
00399 if ( curView ) {
00400 DateList dates = curView->selectedIncidenceDates();
00401 if ( !dates.isEmpty() ) {
00402 return dates.first();
00403 }
00404 }
00405
00406 return QDate();
00407 }
00408
00409 QDate CalendarView::startDate()
00410 {
00411 DateList dates = mDateNavigator->selectedDates();
00412
00413 return dates.first();
00414 }
00415
00416 QDate CalendarView::endDate()
00417 {
00418 DateList dates = mDateNavigator->selectedDates();
00419
00420 return dates.last();
00421 }
00422
00423
00424 bool CalendarView::openCalendar(const QString& filename, bool merge)
00425 {
00426 kdDebug(5850) << "CalendarView::openCalendar(): " << filename << endl;
00427
00428 if (filename.isEmpty()) {
00429 kdDebug(5850) << "CalendarView::openCalendar(): Error! Empty filename." << endl;
00430 return false;
00431 }
00432
00433 if (!QFile::exists(filename)) {
00434 kdDebug(5850) << "CalendarView::openCalendar(): Error! File '" << filename
00435 << "' doesn't exist." << endl;
00436 }
00437
00438 bool loadedSuccesfully = true;
00439 if ( !merge ) {
00440 mCalendar->close();
00441 CalendarLocal *cl = dynamic_cast<CalendarLocal*>( mCalendar );
00442 if ( cl ) {
00443 loadedSuccesfully = cl->load( filename );
00444 } else {
00445 CalendarResources *cr = dynamic_cast<CalendarResources*>( mCalendar );
00446 assert( cr );
00447
00448 return false;
00449 }
00450 } else {
00451
00452 FileStorage storage( mCalendar );
00453 storage.setFileName( filename );
00454 loadedSuccesfully = storage.load();
00455 }
00456
00457 if ( loadedSuccesfully ) {
00458 if ( merge )
00459 setModified( true );
00460 else {
00461 setModified( false );
00462 mViewManager->setDocumentId( filename );
00463 mTodoList->setDocumentId( filename );
00464 }
00465 updateCategories();
00466 updateView();
00467 return true;
00468 } else {
00469
00470
00471 if ( !merge ) mCalendar->close();
00472
00473 KMessageBox::error(this,i18n("Could not load calendar '%1'.").arg(filename));
00474
00475 return false;
00476 }
00477 }
00478
00479 bool CalendarView::saveCalendar( const QString& filename )
00480 {
00481 kdDebug(5850) << "CalendarView::saveCalendar(): " << filename << endl;
00482
00483
00484 mViewManager->currentView()->flushView();
00485
00486 FileStorage storage( mCalendar );
00487 storage.setFileName( filename );
00488 storage.setSaveFormat( new ICalFormat );
00489
00490 bool success = storage.save();
00491
00492 if ( !success ) {
00493 return false;
00494 }
00495
00496 return true;
00497 }
00498
00499 void CalendarView::closeCalendar()
00500 {
00501 kdDebug(5850) << "CalendarView::closeCalendar()" << endl;
00502
00503
00504 emit closingDown();
00505
00506 mCalendar->close();
00507 setModified( false );
00508 updateView();
00509 }
00510
00511 void CalendarView::archiveCalendar()
00512 {
00513 mDialogManager->showArchiveDialog();
00514 }
00515
00516
00517 void CalendarView::readSettings()
00518 {
00519
00520
00521 QString str;
00522
00523
00524
00525
00526 KConfig *config = KOGlobals::self()->config();
00527
00528 #ifndef KORG_NOSPLITTER
00529 config->setGroup( "KOrganizer Geometry" );
00530
00531 QValueList<int> sizes = config->readIntListEntry( "Separator1" );
00532 if ( sizes.count() != 2 ) {
00533 sizes << mDateNavigatorContainer->minimumSizeHint().width();
00534 sizes << 300;
00535 }
00536 mPanner->setSizes( sizes );
00537
00538 sizes = config->readIntListEntry( "Separator2" );
00539 mLeftSplitter->setSizes( sizes );
00540 #endif
00541
00542 mEventViewer->readSettings( config );
00543
00544 mViewManager->readSettings( config );
00545 mTodoList->restoreLayout( config, QString( "Todo Layout" ) );
00546
00547 readFilterSettings( config );
00548
00549 config->setGroup( "Views" );
00550 const int dateCount = config->readNumEntry( "ShownDatesCount", 7 );
00551 if ( dateCount == 7 ) {
00552 mDateNavigator->selectWeek();
00553 } else {
00554 mDateNavigator->selectDates( mDateNavigator->selectedDates().first(), dateCount );
00555 }
00556 }
00557
00558
00559 void CalendarView::writeSettings()
00560 {
00561
00562
00563 KConfig *config = KOGlobals::self()->config();
00564
00565 #ifndef KORG_NOSPLITTER
00566 config->setGroup( "KOrganizer Geometry" );
00567
00568 QValueList<int> list = mPanner->sizes();
00569 config->writeEntry( "Separator1", list );
00570
00571 list = mLeftSplitter->sizes();
00572 config->writeEntry( "Separator2", list );
00573 #endif
00574 mEventViewer->writeSettings( config );
00575 mViewManager->writeSettings( config );
00576 mTodoList->saveLayout( config, QString( "Todo Layout" ) );
00577
00578 KOPrefs::instance()->writeConfig();
00579
00580 writeFilterSettings( config );
00581
00582 config->setGroup( "Views" );
00583 config->writeEntry( "ShownDatesCount", mDateNavigator->selectedDates().count() );
00584
00585 config->sync();
00586 }
00587
00588 void CalendarView::readFilterSettings( KConfig *config )
00589 {
00590
00591
00592 mFilters.clear();
00593
00594 config->setGroup( "General" );
00595
00596 QStringList filterList = config->readListEntry ("CalendarFilters" );
00597 QString currentFilter = config->readEntry( "Current Filter" );
00598
00599 QStringList::ConstIterator it = filterList.begin();
00600 QStringList::ConstIterator end = filterList.end();
00601 while( it != end ) {
00602
00603 CalFilter *filter;
00604 filter = new CalFilter( *it );
00605 config->setGroup( "Filter_" + (*it) );
00606 filter->setCriteria( config->readNumEntry( "Criteria", 0 ) );
00607 filter->setCategoryList( config->readListEntry( "CategoryList" ) );
00608 if ( filter->criteria() & KCal::CalFilter::HideTodosWithoutAttendeeInEmailList )
00609 filter->setEmailList( KOPrefs::instance()->allEmails() );
00610 filter->setCompletedTimeSpan( config->readNumEntry( "HideTodoDays", 0 ) );
00611 mFilters.append( filter );
00612
00613 ++it;
00614 }
00615
00616 config->setGroup( "General" );
00617 int pos = filterList.findIndex( currentFilter );
00618 mCurrentFilter = 0;
00619 if ( pos>=0 ) {
00620 mCurrentFilter = mFilters.at( pos );
00621 }
00622 updateFilter();
00623 }
00624
00625 void CalendarView::writeFilterSettings( KConfig *config )
00626 {
00627
00628
00629 QStringList filterList;
00630
00631 CalFilter *filter = mFilters.first();
00632 while( filter ) {
00633
00634 filterList << filter->name();
00635 config->setGroup( "Filter_" + filter->name() );
00636 config->writeEntry( "Criteria", filter->criteria() );
00637 config->writeEntry( "CategoryList", filter->categoryList() );
00638 config->writeEntry( "HideTodoDays", filter->completedTimeSpan() );
00639 filter = mFilters.next();
00640 }
00641 config->setGroup( "General" );
00642 config->writeEntry( "CalendarFilters", filterList );
00643 if ( mCurrentFilter ) {
00644 config->writeEntry( "Current Filter", mCurrentFilter->name() );
00645 } else {
00646 config->writeEntry( "Current Filter", QString::null );
00647 }
00648 }
00649
00650
00651 void CalendarView::goDate( const QDate &date )
00652 {
00653 mDateNavigator->selectDate( date );
00654 }
00655
00656 void CalendarView::showDate( const QDate &date )
00657 {
00658 int dateCount = mDateNavigator->datesCount();
00659 if ( dateCount == 7 ) {
00660 mDateNavigator->selectWeek( date );
00661 } else {
00662 mDateNavigator->selectDates( date, dateCount );
00663 }
00664 }
00665
00666 void CalendarView::goToday()
00667 {
00668 mDateNavigator->selectToday();
00669 }
00670
00671 void CalendarView::goNext()
00672 {
00673 if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) ) {
00674 mDateNavigator->selectNextMonth();
00675 } else {
00676 mDateNavigator->selectNext();
00677 }
00678 }
00679
00680 void CalendarView::goPrevious()
00681 {
00682 if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) ) {
00683 mDateNavigator->selectPreviousMonth();
00684 } else {
00685 mDateNavigator->selectPrevious();
00686 }
00687 }
00688
00689 void CalendarView::updateConfig( const QCString& receiver)
00690 {
00691 if ( receiver != "korganizer" ) return;
00692 kdDebug(5850) << "CalendarView::updateConfig()" << endl;
00693
00694 KOGlobals::self()->
00695 setHolidays( new KHolidays( KOPrefs::instance()->mHolidays ) );
00696
00697 QString tz( mCalendar->timeZoneId() );
00698
00699
00700 if ( tz != KOPrefs::instance()->mTimeZoneId ) {
00701
00702 const QString question( i18n("The timezone setting was changed. Do you want to keep the absolute time of "
00703 "the items in your calendar, which will show them to be at a different time than "
00704 "before, or move them to be at the old time also in the new timezone?") );
00705 int rc = KMessageBox::questionYesNo( this, question,
00706 i18n("Keep Absolute Times?"),
00707 KGuiItem(i18n("Keep Times")),
00708 KGuiItem(i18n("Move Times")),
00709 "calendarKeepAbsoluteTimes");
00710 if ( rc == KMessageBox::Yes ) {
00711
00712 mCalendar->setTimeZoneIdViewOnly( KOPrefs::instance()->mTimeZoneId );
00713 } else {
00714
00715
00716 mCalendar->setTimeZoneId( KOPrefs::instance()->mTimeZoneId );
00717 }
00718 }
00719 emit configChanged();
00720
00721
00722 mViewManager->updateMultiCalendarDisplay();
00723
00724
00725 mViewManager->raiseCurrentView();
00726 }
00727
00728
00729 void CalendarView::incidenceAdded( Incidence *incidence )
00730 {
00731 setModified( true );
00732 history()->recordAdd( incidence );
00733 changeIncidenceDisplay( incidence, KOGlobals::INCIDENCEADDED );
00734 updateUnmanagedViews();
00735 checkForFilteredChange( incidence );
00736 }
00737
00738 void CalendarView::incidenceChanged( Incidence *oldIncidence,
00739 Incidence *newIncidence,
00740 KOGlobals::WhatChanged modification )
00741 {
00742 KOIncidenceEditor *tmp = editorDialog( newIncidence );
00743 if ( tmp ) {
00744 kdDebug(5850) << "Incidence modified and open" << endl;
00745 tmp->modified();
00746 }
00747 setModified( true );
00748 history()->recordEdit( oldIncidence, newIncidence );
00749
00750
00751
00752
00753 if ( newIncidence->type() == "Todo" &&
00754 KOPrefs::instance()->recordTodosInJournals() &&
00755 ( modification == KOGlobals::COMPLETION_MODIFIED ||
00756 modification == KOGlobals::COMPLETION_MODIFIED_WITH_RECURRENCE ) ) {
00757
00758 Todo *todo = static_cast<Todo *>(newIncidence);
00759 if ( todo->isCompleted() ||
00760 modification == KOGlobals::COMPLETION_MODIFIED_WITH_RECURRENCE ) {
00761 QString timeStr = KGlobal::locale()->formatTime( QTime::currentTime() );
00762 QString description = i18n( "To-do completed: %1 (%2)" ).arg(
00763 newIncidence->summary() ).arg( timeStr );
00764
00765 Journal::List journals = calendar()->journals( QDate::currentDate() );
00766 Journal *journal;
00767
00768 if ( journals.isEmpty() ) {
00769 journal = new Journal();
00770 journal->setDtStart( QDateTime::currentDateTime() );
00771
00772 QString dateStr = KGlobal::locale()->formatDate( QDate::currentDate() );
00773 journal->setSummary( i18n("Journal of %1").arg( dateStr ) );
00774 journal->setDescription( description );
00775
00776
00777 if ( !mChanger->addIncidence( journal, 0, QString(), this ) ) {
00778 KODialogManager::errorSaveIncidence( this, journal );
00779 delete journal;
00780 return;
00781 }
00782
00783 } else {
00784 journal = *(journals.at(0));
00785 Journal *oldJournal = journal->clone();
00786 journal->setDescription( journal->description().append( "\n" + description ) );
00787
00788 if ( !mChanger->changeIncidence( oldJournal, journal,
00789 KOGlobals::DESCRIPTION_MODIFIED, this ) ) {
00790 KODialogManager::errorSaveIncidence( this, journal );
00791 delete journal;
00792 return;
00793 }
00794 }
00795 }
00796 }
00797
00798 changeIncidenceDisplay( newIncidence, KOGlobals::INCIDENCEEDITED );
00799 updateUnmanagedViews();
00800 checkForFilteredChange( newIncidence );
00801 }
00802
00803 void CalendarView::incidenceToBeDeleted( Incidence *incidence )
00804 {
00805 KOIncidenceEditor *tmp = editorDialog( incidence );
00806 if (tmp) {
00807 kdDebug(5850) << "Incidence to be deleted and open in editor" << endl;
00808 tmp->delayedDestruct();
00809 }
00810 setModified( true );
00811 history()->recordDelete( incidence );
00812
00813 updateUnmanagedViews();
00814 }
00815
00816 void CalendarView::incidenceDeleted( Incidence *incidence )
00817 {
00818 changeIncidenceDisplay( incidence, KOGlobals::INCIDENCEDELETED );
00819 updateUnmanagedViews();
00820 }
00821
00822 void CalendarView::checkForFilteredChange( Incidence *incidence )
00823 {
00824 CalFilter *filter = calendar()->filter();
00825 if ( filter && !filter->filterIncidence( incidence ) ) {
00826
00827
00828 KMessageBox::information( this, i18n("The item \"%1\" is filtered by "
00829 "your current filter rules, so it will be hidden and not "
00830 "appear in the view.").arg( incidence->summary() ),
00831 i18n("Filter Applied"), "ChangedIncidenceFiltered" );
00832 }
00833 }
00834
00835 void CalendarView::startMultiModify( const QString &text )
00836 {
00837 history()->startMultiModify( text );
00838 }
00839
00840 void CalendarView::endMultiModify()
00841 {
00842 history()->endMultiModify();
00843 }
00844
00845
00846 void CalendarView::changeIncidenceDisplay( Incidence *incidence, int action )
00847 {
00848 mDateNavigatorContainer->updateView();
00849 mDialogManager->updateSearchDialog();
00850
00851 if ( incidence ) {
00852
00853 mViewManager->currentView()->changeIncidenceDisplay( incidence, action );
00854 if ( mTodoList ) mTodoList->changeIncidenceDisplay( incidence, action );
00855 mEventViewer->changeIncidenceDisplay( incidence, activeDate( true ), action );
00856 } else {
00857 mViewManager->currentView()->updateView();
00858 if ( mTodoList ) mTodoList->updateView();
00859 }
00860 }
00861
00862
00863 void CalendarView::updateView(const QDate &start, const QDate &end)
00864 {
00865 mTodoList->updateView();
00866 mViewManager->updateView(start, end);
00867 mDateNavigatorContainer->updateView();
00868 }
00869
00870 void CalendarView::updateView()
00871 {
00872 DateList tmpList = mDateNavigator->selectedDates();
00873
00874
00875 updateView( tmpList.first(), tmpList.last() );
00876 }
00877
00878 void CalendarView::updateUnmanagedViews()
00879 {
00880 mDateNavigatorContainer->updateDayMatrix();
00881 }
00882
00883 int CalendarView::msgItemDelete( Incidence *incidence )
00884 {
00885 return KMessageBox::warningContinueCancel(this,
00886 i18n("The item \"%1\" will be permanently deleted.").arg( incidence->summary() ),
00887 i18n("KOrganizer Confirmation"), KGuiItem(i18n("&Delete"),"editdelete"));
00888 }
00889
00890
00891 void CalendarView::edit_cut()
00892 {
00893 Incidence *incidence = incToSendToClipboard( true );
00894
00895 if ( !incidence || !mChanger ) {
00896 KNotifyClient::beep();
00897 return;
00898 }
00899
00900 Incidence::List incidences;
00901 int km = KMessageBox::Yes;
00902
00903 if ( !incidence->relations().isEmpty() &&
00904 incidence->type() == "Todo" ) {
00905 km = KMessageBox::questionYesNoCancel( this,
00906 i18n("The item \"%1\" has sub-to-dos. "
00907 "Do you want to cut just this item and "
00908 "make all its sub-to-dos independent, or "
00909 "cut the to-do with all its sub-to-dos?"
00910 ).arg( incidence->summary() ),
00911 i18n("KOrganizer Confirmation"),
00912 i18n("Cut Only This"),
00913 i18n("Cut All"));
00914 }
00915
00916 if ( km == KMessageBox::Yes ) {
00917 incidences.append( incidence );
00918 makeChildrenIndependent( incidence );
00919 } else if ( km == KMessageBox::No ) {
00920
00921 getIncidenceHierarchy( incidence, incidences );
00922 }
00923
00924 if ( km != KMessageBox::Cancel ) {
00925 mChanger->cutIncidences( incidences, this );
00926 }
00927 }
00928
00929 void CalendarView::edit_copy()
00930 {
00931 Incidence *incidence = incToSendToClipboard( false );
00932
00933 if ( !incidence ) {
00934 KNotifyClient::beep();
00935 return;
00936 }
00937
00938 Incidence::List incidences;
00939 int km = KMessageBox::Yes;
00940
00941 if ( !incidence->relations().isEmpty() &&
00942 incidence->type() == "Todo" ) {
00943 km = KMessageBox::questionYesNoCancel( this,
00944 i18n("The item \"%1\" has sub-to-dos. "
00945 "Do you want to copy just this item or "
00946 "copy the to-do with all its sub-to-dos?"
00947 ).arg( incidence->summary() ),
00948 i18n("KOrganizer Confirmation"),
00949 i18n("Copy Only This"),
00950 i18n("Copy All"));
00951 }
00952
00953 if ( km == KMessageBox::Yes ) {
00954 incidences.append( incidence );
00955 } else if ( km == KMessageBox::No ) {
00956
00957 getIncidenceHierarchy( incidence, incidences );
00958 }
00959
00960 if ( km != KMessageBox::Cancel ) {
00961 DndFactory factory( mCalendar );
00962 if ( !factory.copyIncidences( incidences ) ) {
00963 KNotifyClient::beep();
00964 }
00965 }
00966 }
00967
00968 Incidence* CalendarView::incToSendToClipboard( bool cut )
00969 {
00970 Incidence *originalInc = selectedIncidence();
00971
00972 if ( originalInc && originalInc->doesRecur() &&
00973 originalInc->type() == "Event" ) {
00974
00975 Incidence *inc;
00976 KOGlobals::WhichOccurrences chosenOption;
00977 if ( cut ) {
00978 inc = singleOccurrenceOrAll( originalInc, KOGlobals::CUT, chosenOption, QDate(), true );
00979 } else {
00980
00981
00982 Incidence *originalIncSaved = originalInc->clone();
00983 inc = singleOccurrenceOrAll( originalIncSaved, KOGlobals::COPY, chosenOption, QDate(), false );
00984
00985
00986 if ( chosenOption == KOGlobals::ALL ) {
00987 inc = originalInc;
00988 delete originalIncSaved;
00989 }
00990
00991
00992 if ( chosenOption == KOGlobals::NONE ) {
00993 delete originalIncSaved;
00994 }
00995 }
00996
00997 return inc;
00998 } else {
00999 return originalInc;
01000 }
01001 }
01002
01003 void CalendarView::edit_paste()
01004 {
01005
01006
01007
01008 QDate date;
01009 bool timeSet = false;
01010 QTime time;
01011 QDateTime endDT;
01012 bool useEndTime = false;
01013
01014 KOrg::BaseView *curView = mViewManager->currentView();
01015 if ( !curView ) {
01016 return;
01017 }
01018
01019 KOAgendaView *aView = mViewManager->agendaView();
01020 KOMonthView *mView = mViewManager->monthView();
01021 if ( curView == mViewManager->multiAgendaView() ) {
01022 aView = mViewManager->multiAgendaView()->selectedAgendaView();
01023 curView = aView;
01024 }
01025
01026 if ( curView == aView && aView->selectionStart().isValid() ) {
01027 date = aView->selectionStart().date();
01028 endDT = aView->selectionEnd();
01029 useEndTime = !aView->selectedIsSingleCell();
01030 if ( !aView->selectedIsAllDay() ) {
01031 time = aView->selectionStart().time();
01032 timeSet = true;
01033 }
01034 } else if ( curView == mView && mView->selectionStart().isValid() ) {
01035 date = mView->selectionStart().date();
01036 } else if ( !mDateNavigator->selectedDates().isEmpty() &&
01037 curView->supportsDateNavigation() ) {
01038
01039 date = mDateNavigator->selectedDates().first();
01040 }
01041
01042 if ( !date.isValid() && curView->supportsDateNavigation() ) {
01043 KMessageBox::sorry(
01044 this,
01045 i18n( "Paste failed: unable to determine a valid target date." ) );
01046 return;
01047 }
01048
01049 DndFactory factory( mCalendar );
01050 Incidence::List pastedIncidences;
01051 if ( timeSet && time.isValid() ) {
01052 pastedIncidences = factory.pasteIncidences( date, &time );
01053 } else {
01054 pastedIncidences = factory.pasteIncidences( date );
01055 }
01056
01057 Incidence::List::Iterator it;
01058 for ( it = pastedIncidences.begin(); it != pastedIncidences.end(); ++it ) {
01059 QPair<ResourceCalendar *, QString>p = viewSubResourceCalendar();
01060
01061
01062 if ( ( *it )->type() == "Event" ) {
01063 Event *pastedEvent = static_cast<Event*>( *it );
01064
01065
01066 if ( aView && endDT.isValid() && useEndTime ) {
01067 if ( ( pastedEvent->doesFloat() && aView->selectedIsAllDay() ) ||
01068 ( !pastedEvent->doesFloat() && !aView->selectedIsAllDay() ) ) {
01069 pastedEvent->setDtEnd( endDT );
01070 }
01071 }
01072
01073
01074
01075 pastedEvent->setRelatedTo( 0 );
01076 pastedEvent->setRelatedToUid( QString() );
01077
01078 mChanger->addIncidence( pastedEvent, p.first, p.second, this );
01079
01080 } else if ( ( *it )->type() == "Todo" ) {
01081 Todo *pastedTodo = static_cast<Todo*>( *it );
01082 Todo *_selectedTodo = selectedTodo();
01083
01084
01085
01086 if ( _selectedTodo && !pastedTodo->relatedTo() ) {
01087 pastedTodo->setRelatedTo( _selectedTodo );
01088 }
01089 mChanger->addIncidence( pastedTodo, p.first, p.second, this );
01090 }
01091 }
01092 }
01093
01094 void CalendarView::edit_options()
01095 {
01096 mDialogManager->showOptionsDialog();
01097 }
01098
01099 void CalendarView::dateTimesForNewEvent( QDateTime &startDt, QDateTime &endDt, bool &allDay )
01100 {
01101 mViewManager->currentView()->eventDurationHint( startDt, endDt, allDay );
01102
01103 if ( !startDt.isValid() || !endDt.isValid() ) {
01104 startDt.setDate( activeDate( true ) );
01105 startDt.setTime( KOPrefs::instance()->mStartTime.time() );
01106
01107 int addSecs = ( KOPrefs::instance()->mDefaultDuration.time().hour() * 3600 ) +
01108 ( KOPrefs::instance()->mDefaultDuration.time().minute() * 60 );
01109
01110 endDt = startDt.addSecs( addSecs );
01111 }
01112 }
01113
01114 KOEventEditor *CalendarView::newEventEditor( ResourceCalendar *res, const QString &subRes,
01115 const QDateTime &startDtParam,
01116 const QDateTime &endDtParam, bool allDayParam )
01117 {
01118
01119 bool allDay = allDayParam;
01120 QDateTime startDt( startDtParam ), endDt( endDtParam );
01121
01122
01123 dateTimesForNewEvent( startDt, endDt, allDay );
01124
01125 KOEventEditor *eventEditor = mDialogManager->getEventEditor();
01126 eventEditor->newEvent();
01127 connectIncidenceEditor( eventEditor );
01128 eventEditor->setResource( res, subRes );
01129 eventEditor->setDates( startDt, endDt, allDay );
01130 mDialogManager->connectTypeAhead( eventEditor, dynamic_cast<KOrg::AgendaView*>(viewManager()->currentView()) );
01131 return eventEditor;
01132 }
01133
01134 void CalendarView::newEvent()
01135 {
01136 KOrg::BaseView *currentView = mViewManager->currentView();
01137 if ( currentView == mViewManager->multiAgendaView() ) {
01138 currentView = mViewManager->multiAgendaView()->selectedAgendaView();
01139 }
01140
01141 newEvent( currentView->resourceCalendar(),
01142 currentView->subResourceCalendar() );
01143 }
01144
01145 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes )
01146 {
01147 kdDebug(5850) << "CalendarView::newEvent()" << endl;
01148 newEvent( res, subRes, QDateTime(), QDateTime() );
01149 }
01150
01151 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes,
01152 const QDate &dt )
01153 {
01154 QDateTime startDt( dt, KOPrefs::instance()->mStartTime.time() );
01155 newEvent( res, subRes, QDateTime( dt ), QDateTime() );
01156 }
01157
01158 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes,
01159 const QDateTime &startDt )
01160 {
01161 newEvent( res, subRes, startDt, QDateTime() );
01162 }
01163
01164 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes,
01165 const QDateTime &startDt, const QDateTime &endDt,
01166 bool allDay )
01167 {
01168 KOEventEditor *eventEditor = newEventEditor( res, subRes,
01169 startDt, endDt, allDay );
01170 eventEditor->show();
01171 }
01172
01173 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes,
01174 const QString &summary, const QString &description,
01175 const QStringList &attachments, const QStringList &attendees,
01176 const QStringList &attachmentMimetypes, bool inlineAttachment )
01177 {
01178 KOEventEditor *eventEditor = newEventEditor( res, subRes );
01179 eventEditor->setTexts( summary, description );
01180
01181
01182 eventEditor->addAttachments( attachments, attachmentMimetypes, inlineAttachment );
01183 eventEditor->addAttendees( attendees );
01184 eventEditor->show();
01185 }
01186
01187 void CalendarView::newTodo( ResourceCalendar *res, const QString &subRes,
01188 const QString &summary, const QString &description,
01189 const QStringList &attachments, const QStringList &attendees,
01190 const QStringList &attachmentMimetypes,
01191 bool inlineAttachment, bool isTask )
01192 {
01193 kdDebug(5850) << k_funcinfo << endl;
01194 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01195 connectIncidenceEditor( todoEditor );
01196 todoEditor->newTodo();
01197 todoEditor->setResource( res, subRes );
01198 todoEditor->setTexts( summary, description );
01199 todoEditor->addAttachments( attachments, attachmentMimetypes, inlineAttachment );
01200 todoEditor->addAttendees( attendees );
01201 todoEditor->selectCreateTask( isTask );
01202 todoEditor->show();
01203 }
01204
01205 void CalendarView::newTodo()
01206 {
01207 KOrg::BaseView *currentView = mViewManager->currentView();
01208 if ( currentView == mViewManager->multiAgendaView() ) {
01209 currentView = mViewManager->multiAgendaView()->selectedAgendaView();
01210 }
01211
01212 newTodo( currentView->resourceCalendar(),
01213 currentView->subResourceCalendar() );
01214 }
01215
01216 void CalendarView::newTodo( ResourceCalendar *res, const QString &subRes )
01217 {
01218 kdDebug(5850) << k_funcinfo << endl;
01219 QDateTime dtDue;
01220 bool allday = true;
01221 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01222 connectIncidenceEditor( todoEditor );
01223 todoEditor->newTodo();
01224 todoEditor->setResource( res, subRes );
01225 if ( mViewManager->currentView()->isEventView() ) {
01226 dtDue.setDate( mDateNavigator->selectedDates().first() );
01227 QDateTime dtDummy = QDateTime::currentDateTime();
01228 mViewManager->currentView()->eventDurationHint( dtDue, dtDummy, allday );
01229 todoEditor->setDates( dtDue, allday );
01230 }
01231 todoEditor->show();
01232 }
01233
01234 void CalendarView::newTodo( ResourceCalendar *res, const QString &subRes,
01235 const QDate &date )
01236 {
01237 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01238 connectIncidenceEditor( todoEditor );
01239 todoEditor->newTodo();
01240 todoEditor->setResource( res, subRes );
01241 todoEditor->setDates( QDateTime( date, QTime::currentTime() ), true );
01242 todoEditor->show();
01243 }
01244
01245 void CalendarView::newJournal()
01246 {
01247 KOrg::BaseView *currentView = mViewManager->currentView();
01248 if ( currentView == mViewManager->multiAgendaView() ) {
01249 currentView = mViewManager->multiAgendaView()->selectedAgendaView();
01250 }
01251
01252 newJournal( currentView->resourceCalendar(),
01253 currentView->subResourceCalendar() );
01254 }
01255
01256 void CalendarView::newJournal( ResourceCalendar *res, const QString &subRes )
01257 {
01258 kdDebug(5850) << "CalendarView::newJournal()" << endl;
01259 newJournal( res, subRes, QString::null, QDate() );
01260 }
01261
01262 void CalendarView::newJournal( ResourceCalendar *res, const QString &subRes,
01263 const QDate &date)
01264 {
01265 newJournal( res, subRes, QString::null, date );
01266 }
01267
01268 void CalendarView::newJournal( ResourceCalendar *res, const QString &subRes,
01269 const QString &text, const QDate &date )
01270 {
01271 KOJournalEditor *journalEditor = mDialogManager->getJournalEditor();
01272 connectIncidenceEditor( journalEditor );
01273 journalEditor->newJournal();
01274 journalEditor->setResource( res, subRes );
01275 journalEditor->setTexts( text );
01276 if ( !date.isValid() ) {
01277 journalEditor->setDate( mDateNavigator->selectedDates().first() );
01278 } else {
01279 journalEditor->setDate( date );
01280 }
01281 journalEditor->show();
01282 }
01283
01284 void CalendarView::newSubTodo()
01285 {
01286 Todo *todo = selectedTodo();
01287 if ( todo ) newSubTodo( todo );
01288 }
01289
01290 void CalendarView::newSubTodo(Todo *parentEvent)
01291 {
01292 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01293 connectIncidenceEditor( todoEditor );
01294 todoEditor->newTodo();
01295 todoEditor->setDates( QDateTime(), false, parentEvent );
01296 todoEditor->show();
01297 }
01298
01299 bool CalendarView::addIncidence( const QString &ical )
01300 {
01301 kdDebug(5850) << "CalendarView::addIncidence:\n" << ical << endl;
01302 ICalFormat format;
01303 format.setTimeZone( mCalendar->timeZoneId(), true );
01304 Incidence *incidence = format.fromString( ical );
01305 if ( !incidence ) return false;
01306 if ( !mChanger->addIncidence( incidence, 0, QString(), this ) ) {
01307 delete incidence;
01308 return false;
01309 }
01310 return true;
01311 }
01312
01313 void CalendarView::appointment_show()
01314 {
01315 Incidence *incidence = selectedIncidence();
01316 if ( incidence ) {
01317 showIncidence( incidence, activeIncidenceDate() );
01318 } else {
01319 KNotifyClient::beep();
01320 }
01321 }
01322
01323 void CalendarView::appointment_edit()
01324 {
01325 Incidence *incidence = selectedIncidence();
01326 if ( incidence ) {
01327 editIncidence( incidence, activeIncidenceDate() );
01328 } else {
01329 KNotifyClient::beep();
01330 }
01331 }
01332
01333 void CalendarView::appointment_delete()
01334 {
01335 Incidence *incidence = selectedIncidence();
01336 if (incidence)
01337 deleteIncidence( incidence );
01338 else
01339 KNotifyClient::beep();
01340 }
01341
01342 void CalendarView::todo_unsub()
01343 {
01344 Todo *anTodo = selectedTodo();
01345 if( incidence_unsub ( anTodo ) ) {
01346 updateView();
01347 }
01348 }
01349
01350 bool CalendarView::incidence_unsub( Incidence *inc )
01351 {
01352 bool status = false;
01353 if ( !inc || !inc->relatedTo() ) {
01354 return false;
01355 }
01356
01357 if ( mChanger->beginChange( inc, 0, QString() ) ) {
01358 Incidence *oldInc = inc->clone();
01359 inc->setRelatedTo( 0 );
01360 mChanger->changeIncidence( oldInc, inc, KOGlobals::RELATION_MODIFIED, this );
01361 mChanger->endChange( inc, 0, QString() );
01362 delete oldInc;
01363 setModified(true);
01364 status = true;
01365 }
01366 if ( ! status ) {
01367 KMessageBox::sorry( this, i18n("Unable to turn sub-to-do into a top-level "
01368 "to-do, because it cannot be locked.") );
01369 }
01370
01371 return status;
01372 }
01373
01374 bool CalendarView::makeSubTodosIndependent ( )
01375 {
01376 bool status = false;
01377 Todo *aTodo = selectedTodo();
01378
01379 if ( makeChildrenIndependent( aTodo ) ) {
01380 updateView();
01381 status = true;
01382 }
01383 return status;
01384 }
01385
01386 bool CalendarView::makeChildrenIndependent ( Incidence *inc )
01387 {
01388 if ( !inc || inc->relations().isEmpty() ) {
01389 return false;
01390 }
01391
01392 startMultiModify ( i18n( "Make sub-to-dos independent" ) );
01393 Incidence::List subIncs( inc->relations() );
01394 Incidence::List::Iterator it;
01395
01396 for ( it= subIncs.begin(); it != subIncs.end(); ++it ) {
01397 incidence_unsub ( *it );
01398 }
01399 endMultiModify();
01400 return true;
01401 }
01402
01403 bool CalendarView::deleteIncidence( const QString &uid, bool force )
01404 {
01405 Incidence *inc = mCalendar->incidence( uid );
01406 if ( inc ) {
01407 deleteIncidence( inc, force );
01408 return true;
01409 } else {
01410 return false;
01411 }
01412 }
01413
01414 void CalendarView::toggleAlarm( Incidence *incidence )
01415 {
01416 if ( !incidence || !mChanger ) {
01417 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01418 return;
01419 }
01420 Incidence*oldincidence = incidence->clone();
01421 if ( !mChanger->beginChange( incidence, 0, QString() ) ) {
01422 kdDebug(5850) << "Unable to lock incidence " << endl;
01423 delete oldincidence;
01424 return;
01425 }
01426
01427 Alarm::List alarms = incidence->alarms();
01428 Alarm::List::ConstIterator it;
01429 for ( it = alarms.begin(); it != alarms.end(); ++it ) {
01430 (*it)->toggleAlarm();
01431 }
01432 if ( alarms.isEmpty() ) {
01433
01434 Alarm *alm = incidence->newAlarm();
01435 alm->setType( Alarm::Display );
01436 alm->setEnabled( true );
01437 int duration;
01438 switch( KOPrefs::instance()->mReminderTimeUnits ) {
01439 default:
01440 case 0:
01441 duration = KOPrefs::instance()->mReminderTime * 60;
01442 break;
01443 case 1:
01444 duration = KOPrefs::instance()->mReminderTime * 60 * 60;
01445 break;
01446 case 2:
01447 duration = KOPrefs::instance()->mReminderTime * 60 * 60 * 24;
01448 break;
01449 }
01450 if ( incidence->type() == "Event" ) {
01451 alm->setStartOffset( KCal::Duration( -duration ) );
01452 } else {
01453 alm->setEndOffset( KCal::Duration( -duration ) );
01454 }
01455 }
01456 mChanger->changeIncidence( oldincidence, incidence, KOGlobals::ALARM_MODIFIED, this );
01457 mChanger->endChange( incidence, 0, QString() );
01458 delete oldincidence;
01459
01460
01461 }
01462
01463 void CalendarView::dissociateOccurrence( Incidence *incidence, const QDate &date )
01464 {
01465 if ( !incidence || !mChanger ) {
01466 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01467 return;
01468 }
01469
01470 QPair<ResourceCalendar *, QString>p =
01471 CalHelper::incSubResourceCalendar( calendar(), incidence );
01472
01473 if ( !mChanger->beginChange( incidence, p.first, p.second ) ) {
01474 kdDebug(5850) << "Unable to lock incidence " << endl;
01475 return;
01476 }
01477 startMultiModify( i18n("Dissociate occurrence") );
01478 Incidence*oldincidence = incidence->clone();
01479
01480 Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
01481
01482 if ( newInc ) {
01483 mChanger->changeIncidence( oldincidence, incidence, KOGlobals::NOTHING_MODIFIED, this );
01484 mChanger->addIncidence( newInc, p.first, p.second, this );
01485 } else {
01486 KMessageBox::sorry( this, i18n("Dissociating the occurrence failed."),
01487 i18n("Dissociating Failed") );
01488 }
01489 mChanger->endChange( incidence, p.first, p.second );
01490 endMultiModify();
01491 delete oldincidence;
01492 }
01493
01494 void CalendarView::dissociateFutureOccurrence( Incidence *incidence, const QDate &date )
01495 {
01496 if ( !incidence || !mChanger ) {
01497 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01498 return;
01499 }
01500
01501 QPair<ResourceCalendar *, QString>p =
01502 CalHelper::incSubResourceCalendar( calendar(), incidence );
01503
01504 if ( !mChanger->beginChange( incidence, p.first, p.second ) ) {
01505 kdDebug(5850) << "Unable to lock incidence " << endl;
01506 return;
01507 }
01508 startMultiModify( i18n("Dissociate future occurrences") );
01509 Incidence*oldincidence = incidence->clone();
01510
01511 Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
01512 if ( newInc ) {
01513 mChanger->changeIncidence( oldincidence, incidence, KOGlobals::NOTHING_MODIFIED, this );
01514 mChanger->addIncidence( newInc, p.first, p.second, this );
01515 } else {
01516 KMessageBox::sorry( this, i18n("Dissociating the future occurrences failed."),
01517 i18n("Dissociating Failed") );
01518 }
01519 endMultiModify();
01520 mChanger->endChange( incidence, p.first, p.second );
01521 delete oldincidence;
01522 }
01523
01524
01525
01526
01527
01528 void CalendarView::schedule_publish(Incidence *incidence)
01529 {
01530 if (incidence == 0)
01531 incidence = selectedIncidence();
01532
01533 if (!incidence) {
01534 KMessageBox::information( this, i18n("No item selected."),
01535 "PublishNoEventSelected" );
01536 return;
01537 }
01538
01539 PublishDialog *publishdlg = new PublishDialog();
01540 if (incidence->attendeeCount()>0) {
01541 Attendee::List attendees = incidence->attendees();
01542 Attendee::List::ConstIterator it;
01543 for( it = attendees.begin(); it != attendees.end(); ++it ) {
01544 publishdlg->addAttendee( *it );
01545 }
01546 }
01547 if ( publishdlg->exec() == QDialog::Accepted ) {
01548 Incidence *inc = incidence->clone();
01549 inc->registerObserver( 0 );
01550 inc->clearAttendees();
01551
01552
01553 KCal::MailScheduler scheduler( mCalendar );
01554 if ( scheduler.publish( incidence, publishdlg->addresses() ) ) {
01555 KMessageBox::information( this, i18n("The item information was successfully sent."),
01556 i18n("Publishing"), "IncidencePublishSuccess" );
01557 } else {
01558 KMessageBox::error( this, i18n("Unable to publish the item '%1'").arg( incidence->summary() ) );
01559 }
01560 }
01561 delete publishdlg;
01562 }
01563
01564 void CalendarView::schedule_request(Incidence *incidence)
01565 {
01566 schedule(Scheduler::Request,incidence);
01567 }
01568
01569 void CalendarView::schedule_refresh(Incidence *incidence)
01570 {
01571 schedule(Scheduler::Refresh,incidence);
01572 }
01573
01574 void CalendarView::schedule_cancel(Incidence *incidence)
01575 {
01576 schedule(Scheduler::Cancel,incidence);
01577 }
01578
01579 void CalendarView::schedule_add(Incidence *incidence)
01580 {
01581 schedule(Scheduler::Add,incidence);
01582 }
01583
01584 void CalendarView::schedule_reply(Incidence *incidence)
01585 {
01586 schedule(Scheduler::Reply,incidence);
01587 }
01588
01589 void CalendarView::schedule_counter(Incidence *incidence)
01590 {
01591 schedule(Scheduler::Counter,incidence);
01592 }
01593
01594 void CalendarView::schedule_declinecounter(Incidence *incidence)
01595 {
01596 schedule(Scheduler::Declinecounter,incidence);
01597 }
01598
01599 void CalendarView::schedule_forward( Incidence *incidence )
01600 {
01601 if ( !incidence ) {
01602 incidence = selectedIncidence();
01603 }
01604
01605 if ( !incidence ) {
01606 KMessageBox::information(
01607 this,
01608 i18n( "No item selected." ),
01609 i18n( "Forwarding" ),
01610 "ForwardNoEventSelected" );
01611 return;
01612 }
01613
01614 PublishDialog publishdlg;
01615 if ( publishdlg.exec() == QDialog::Accepted ) {
01616 QString recipients = publishdlg.addresses();
01617 if ( incidence->organizer().isEmpty() ) {
01618 incidence->setOrganizer( Person( KOPrefs::instance()->fullName(),
01619 KOPrefs::instance()->email() ) );
01620 }
01621
01622 ICalFormat format;
01623 QString messageText = format.createScheduleMessage( incidence, Scheduler::Request );
01624 KOMailClient mailer;
01625 if ( mailer.mailTo( incidence, recipients, messageText ) ) {
01626 KMessageBox::information(
01627 this,
01628 i18n( "The item information was successfully sent." ),
01629 i18n( "Forwarding" ),
01630 "IncidenceForwardSuccess" );
01631 } else {
01632 KMessageBox::error(
01633 this,
01634 i18n( "Unable to forward the item '%1'" ).arg( incidence->summary() ),
01635 i18n( "Forwarding Error" ) );
01636 }
01637 }
01638 }
01639
01640 void CalendarView::mailFreeBusy( int daysToPublish )
01641 {
01642 QDateTime start = QDateTime::currentDateTime();
01643 QDateTime end = start.addDays(daysToPublish);
01644
01645 FreeBusy *freebusy = new FreeBusy(mCalendar, start, end);
01646 freebusy->setOrganizer( Person( KOPrefs::instance()->fullName(),
01647 KOPrefs::instance()->email() ) );
01648
01649 kdDebug(5850) << "calendarview: schedule_publish_freebusy: startDate: "
01650 << KGlobal::locale()->formatDateTime( start ) << " End Date: "
01651 << KGlobal::locale()->formatDateTime( end ) << endl;
01652
01653 PublishDialog *publishdlg = new PublishDialog();
01654 if ( publishdlg->exec() == QDialog::Accepted ) {
01655
01656 KCal::MailScheduler scheduler( mCalendar );
01657 if ( scheduler.publish( freebusy, publishdlg->addresses() ) ) {
01658 KMessageBox::information( this, i18n("The free/busy information was successfully sent."),
01659 i18n("Sending Free/Busy"), "FreeBusyPublishSuccess" );
01660 } else {
01661 KMessageBox::error( this, i18n("Unable to publish the free/busy data.") );
01662 }
01663 }
01664 delete freebusy;
01665 delete publishdlg;
01666 }
01667
01668 void CalendarView::uploadFreeBusy()
01669 {
01670 KOGroupware::instance()->freeBusyManager()->publishFreeBusy();
01671 }
01672
01673 void CalendarView::schedule(Scheduler::Method method, Incidence *incidence)
01674 {
01675 if ( !incidence ) {
01676 incidence = selectedIncidence();
01677 }
01678
01679 if ( !incidence ) {
01680 KMessageBox::sorry( this, i18n("No item selected."),
01681 "ScheduleNoEventSelected" );
01682 return;
01683 }
01684
01685 if( incidence->attendeeCount() == 0 && method != Scheduler::Publish ) {
01686 KMessageBox::information( this, i18n("The item has no attendees."),
01687 "ScheduleNoIncidences" );
01688 return;
01689 }
01690
01691 Incidence *inc = incidence->clone();
01692 inc->registerObserver( 0 );
01693 inc->clearAttendees();
01694
01695
01696 KCal::MailScheduler scheduler( mCalendar );
01697 if ( scheduler.performTransaction( incidence, method ) ) {
01698 KMessageBox::information( this, i18n("The groupware message for item '%1'"
01699 "was successfully sent.\nMethod: %2")
01700 .arg( incidence->summary() )
01701 .arg( Scheduler::methodName( method ) ),
01702 i18n("Sending Free/Busy"),
01703 "FreeBusyPublishSuccess" );
01704 } else {
01705 KMessageBox::error( this, i18n("Groupware message sending failed. "
01706 "%2 is request/reply/add/cancel/counter/etc.",
01707 "Unable to send the item '%1'.\nMethod: %2")
01708 .arg( incidence->summary() )
01709 .arg( Scheduler::methodName( method ) ) );
01710 }
01711 }
01712
01713 void CalendarView::openAddressbook()
01714 {
01715 KRun::runCommand("kaddressbook");
01716 }
01717
01718 void CalendarView::setModified(bool modified)
01719 {
01720 if (mModified != modified) {
01721 mModified = modified;
01722 emit modifiedChanged(mModified);
01723 }
01724 }
01725
01726 bool CalendarView::isReadOnly()
01727 {
01728 return mReadOnly;
01729 }
01730
01731 void CalendarView::setReadOnly(bool readOnly)
01732 {
01733 if (mReadOnly != readOnly) {
01734 mReadOnly = readOnly;
01735 emit readOnlyChanged(mReadOnly);
01736 }
01737 }
01738
01739 bool CalendarView::isModified()
01740 {
01741 return mModified;
01742 }
01743
01744 void CalendarView::print()
01745 {
01746 #ifndef KORG_NOPRINTER
01747 KOCoreHelper helper;
01748 CalPrinter printer( this, mCalendar, &helper );
01749 connect( this, SIGNAL(configChanged()), &printer, SLOT(updateConfig()) );
01750
01751 KOrg::BaseView *currentView = mViewManager->currentView();
01752
01753 CalPrinterBase::PrintType printType = CalPrinterBase::Month;
01754 if ( currentView ) printType = currentView->printType();
01755
01756 DateList tmpDateList = mDateNavigator->selectedDates();
01757 Incidence::List selectedIncidences;
01758 if ( mViewManager->currentView() ) {
01759 selectedIncidences = mViewManager->currentView()->selectedIncidences();
01760 }
01761 printer.print( printType, tmpDateList.first(), tmpDateList.last(), selectedIncidences );
01762 #endif
01763 }
01764
01765 void CalendarView::exportWeb()
01766 {
01767
01768 HTMLExportSettings *settings = new HTMLExportSettings( "KOrganizer" );
01769
01770
01771 if ( settings ) settings->readConfig();
01772 ExportWebDialog *dlg = new ExportWebDialog( settings, this );
01773 connect( dlg, SIGNAL( exportHTML( HTMLExportSettings* ) ),
01774 this, SIGNAL( exportHTML( HTMLExportSettings* ) ) );
01775 dlg->show();
01776 }
01777
01778 void CalendarView::exportICalendar()
01779 {
01780 QString filename = KFileDialog::getSaveFileName("icalout.ics",i18n("*.ics|ICalendars"),this);
01781 if ( !filename.isEmpty() )
01782 {
01783
01784 if (filename.right(4) != ".ics") filename += ".ics";
01785 if ( QFile( filename ).exists() ) {
01786 if ( KMessageBox::No == KMessageBox::warningYesNo(
01787 this,
01788 i18n( "Do you want to overwrite %1?").arg(filename) ) ) {
01789 return;
01790 }
01791 }
01792 FileStorage storage( mCalendar, filename, new ICalFormat );
01793 storage.save();
01794 }
01795 }
01796
01797 void CalendarView::exportVCalendar()
01798 {
01799 if (mCalendar->journals().count() > 0) {
01800 int result = KMessageBox::warningContinueCancel(this,
01801 i18n("The journal entries can not be exported to a vCalendar file."),
01802 i18n("Data Loss Warning"),i18n("Proceed"),"dontaskVCalExport",
01803 true);
01804 if (result != KMessageBox::Continue) return;
01805 }
01806
01807 QString filename = KFileDialog::getSaveFileName("vcalout.vcs",i18n("*.vcs|vCalendars"),this);
01808 if ( !filename.isEmpty() )
01809 {
01810
01811
01812 if (filename.right(4) != ".vcs") filename += ".vcs";
01813 if ( QFile( filename ).exists() ) {
01814 if ( KMessageBox::No == KMessageBox::warningYesNo(
01815 this,
01816 i18n( "Do you want to overwrite %1?").arg(filename ) ) ) {
01817 return;
01818 }
01819 }
01820 FileStorage storage( mCalendar, filename, new VCalFormat );
01821 storage.save();
01822 }
01823 }
01824
01825 void CalendarView::eventUpdated(Incidence *)
01826 {
01827 setModified();
01828
01829
01830
01831 }
01832
01833 void CalendarView::adaptNavigationUnits()
01834 {
01835 if (mViewManager->currentView()->isEventView()) {
01836 int days = mViewManager->currentView()->currentDateCount();
01837 if (days == 1) {
01838 emit changeNavStringPrev(i18n("&Previous Day"));
01839 emit changeNavStringNext(i18n("&Next Day"));
01840 } else {
01841 emit changeNavStringPrev(i18n("&Previous Week"));
01842 emit changeNavStringNext(i18n("&Next Week"));
01843 }
01844 }
01845 }
01846
01847 void CalendarView::processMainViewSelection( Incidence *incidence, const QDate &date )
01848 {
01849 if ( incidence ) mTodoList->clearSelection();
01850 processIncidenceSelection( incidence, date );
01851 }
01852
01853 void CalendarView::processTodoListSelection( Incidence *incidence, const QDate &date )
01854 {
01855 if ( incidence && mViewManager->currentView() ) {
01856 mViewManager->currentView()->clearSelection();
01857 }
01858 processIncidenceSelection( incidence, date );
01859 }
01860
01861 void CalendarView::processIncidenceSelection( Incidence *incidence, const QDate &date )
01862 {
01863 if ( incidence != mSelectedIncidence ) {
01864
01865 emit incidenceSelected( incidence, date );
01866 }
01867
01868 if ( !incidence ) {
01869 mSelectedIncidence = incidence;
01870 return;
01871 }
01872 if ( incidence == mSelectedIncidence ) {
01873 if ( !incidence->doesRecur() || mSaveDate == date ) {
01874 return;
01875 }
01876 }
01877
01878 mSelectedIncidence = incidence;
01879 mSaveDate = date;
01880
01881 emit incidenceSelected( mSelectedIncidence, date );
01882 bool organizerEvents = false;
01883 bool groupEvents = false;
01884 bool todo = false;
01885 bool subtodo = false;
01886
01887 organizerEvents = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
01888 groupEvents = incidence->attendeeByMails( KOPrefs::instance()->allEmails() );
01889
01890 if ( incidence->type() == "Todo" ) {
01891 todo = true;
01892 subtodo = ( incidence->relatedTo() != 0 );
01893 }
01894
01895 emit todoSelected( todo );
01896 emit subtodoSelected( subtodo );
01897 emit organizerEventsSelected( organizerEvents );
01898 emit groupEventsSelected( groupEvents );
01899 }
01900
01901
01902 void CalendarView::checkClipboard()
01903 {
01904 #ifndef KORG_NODND
01905 if (ICalDrag::canDecode(QApplication::clipboard()->data())) {
01906 kdDebug(5850) << "CalendarView::checkClipboard() true" << endl;
01907 emit pasteEnabled(true);
01908 } else {
01909 kdDebug(5850) << "CalendarView::checkClipboard() false" << endl;
01910 emit pasteEnabled(false);
01911 }
01912 #endif
01913 }
01914
01915 void CalendarView::showDates( const DateList &selectedDates, const QDate &preferredMonth )
01916 {
01917 mDateNavigatorContainer->selectDates( selectedDates, preferredMonth );
01918 mNavigatorBar->selectDates( selectedDates );
01919
01920 if ( mViewManager->currentView() ) {
01921 updateView( selectedDates.first(), selectedDates.last() );
01922 } else {
01923 mViewManager->showAgendaView();
01924 }
01925 }
01926
01927 void CalendarView::editFilters()
01928 {
01929 kdDebug(5850) << "CalendarView::editFilters()" << endl;
01930
01931 CalFilter *filter = mFilters.first();
01932 while( filter ) {
01933 kdDebug(5850) << " Filter: " << filter->name() << endl;
01934 filter = mFilters.next();
01935 }
01936
01937 mDialogManager->showFilterEditDialog(&mFilters);
01938 }
01939
01942 void CalendarView::updateFilter()
01943 {
01944 QStringList filters;
01945 CalFilter *filter;
01946
01947 int pos = mFilters.find( mCurrentFilter );
01948 if ( pos < 0 ) {
01949 mCurrentFilter = 0;
01950 }
01951
01952 filters << i18n("No filter");
01953 for ( filter = mFilters.first(); filter; filter = mFilters.next() ) {
01954 filters << filter->name();
01955 }
01956
01957 emit newFilterListSignal( filters );
01958
01959
01960 emit selectFilterSignal( pos+1 );
01961 mCalendar->setFilter( mCurrentFilter );
01962 updateView();
01963 }
01964
01967 void CalendarView::filterActivated( int filterNo )
01968 {
01969 CalFilter *newFilter = 0;
01970 if ( filterNo > 0 && filterNo <= int(mFilters.count()) ) {
01971 newFilter = mFilters.at( filterNo-1 );
01972 }
01973 if ( newFilter != mCurrentFilter ) {
01974 mCurrentFilter = newFilter;
01975 mCalendar->setFilter( mCurrentFilter );
01976 updateView();
01977 }
01978 emit filterChanged();
01979 }
01980
01981 QString CalendarView::currentFilterName() const
01982 {
01983 if ( mCurrentFilter) {
01984 return mCurrentFilter->name();
01985 } else return i18n("No filter");
01986 }
01987
01988 void CalendarView::takeOverEvent()
01989 {
01990 Incidence *incidence = currentSelection();
01991
01992 if (!incidence) return;
01993
01994 incidence->setOrganizer( Person( KOPrefs::instance()->fullName(),
01995 KOPrefs::instance()->email() ) );
01996 incidence->recreate();
01997 incidence->setReadOnly(false);
01998
01999 updateView();
02000 }
02001
02002 void CalendarView::takeOverCalendar()
02003 {
02004 Incidence::List incidences = mCalendar->rawIncidences();
02005 Incidence::List::Iterator it;
02006
02007 for ( it = incidences.begin(); it != incidences.end(); ++it ) {
02008 (*it)->setOrganizer( Person( KOPrefs::instance()->fullName(),
02009 KOPrefs::instance()->email() ) );
02010 (*it)->recreate();
02011 (*it)->setReadOnly(false);
02012 }
02013 updateView();
02014 }
02015
02016 void CalendarView::showIntro()
02017 {
02018 kdDebug(5850) << "To be implemented." << endl;
02019 }
02020
02021 void CalendarView::showDateNavigator( bool show )
02022 {
02023 if( show )
02024 mDateNavigatorContainer->show();
02025 else
02026 mDateNavigatorContainer->hide();
02027 }
02028
02029 void CalendarView::showTodoView( bool show )
02030 {
02031 if( show )
02032 mTodoList->show();
02033 else
02034 mTodoList->hide();
02035 }
02036
02037 void CalendarView::showEventViewer( bool show )
02038 {
02039 if( show )
02040 mEventViewer->show();
02041 else
02042 mEventViewer->hide();
02043 }
02044
02045
02046 void CalendarView::addView(KOrg::BaseView *view)
02047 {
02048 mViewManager->addView(view);
02049 }
02050
02051 void CalendarView::showView(KOrg::BaseView *view)
02052 {
02053 mViewManager->showView(view);
02054 }
02055
02056 void CalendarView::addExtension( CalendarViewExtension::Factory *factory )
02057 {
02058 CalendarViewExtension *extension = factory->create( mLeftSplitter );
02059
02060 mExtensions.append( extension );
02061 }
02062
02063 void CalendarView::toggleExpand()
02064 {
02065 showLeftFrame( mLeftFrame->isHidden() );
02066 }
02067
02068 void CalendarView::showLeftFrame(bool show)
02069 {
02070 if (show) {
02071 mLeftFrame->show();
02072 emit calendarViewExpanded( false );
02073 } else {
02074 mLeftFrame->hide();
02075 emit calendarViewExpanded( true );
02076 }
02077 }
02078
02079 void CalendarView::calendarModified( bool modified, Calendar * )
02080 {
02081 setModified( modified );
02082 }
02083
02084 Todo *CalendarView::selectedTodo()
02085 {
02086 Incidence *incidence = currentSelection();
02087 if ( incidence && incidence->type() == "Todo" ) {
02088 return static_cast<Todo *>( incidence );
02089 }
02090 incidence = 0;
02091
02092 Incidence::List selectedIncidences = mTodoList->selectedIncidences();
02093 if ( !selectedIncidences.isEmpty() ) incidence = selectedIncidences.first();
02094 if ( incidence && incidence->type() == "Todo" ) {
02095 return static_cast<Todo *>( incidence );
02096 }
02097
02098 return 0;
02099 }
02100
02101 void CalendarView::dialogClosing( Incidence *in )
02102 {
02103
02104 mChanger->endChange( in, 0, QString() );
02105 mDialogList.remove( in );
02106 }
02107
02108 Incidence *CalendarView::currentSelection()
02109 {
02110 return mViewManager->currentSelection();
02111 }
02112
02113 Incidence* CalendarView::selectedIncidence()
02114 {
02115 Incidence *incidence = currentSelection();
02116 if ( !incidence ) {
02117 Incidence::List selectedIncidences = mTodoList->selectedIncidences();
02118 if ( !selectedIncidences.isEmpty() )
02119 incidence = selectedIncidences.first();
02120 }
02121 return incidence;
02122 }
02123
02124 void CalendarView::showIncidence()
02125 {
02126 showIncidence( selectedIncidence(), activeIncidenceDate() );
02127 }
02128
02129 void CalendarView::editIncidence()
02130 {
02131 editIncidence( selectedIncidence(), activeIncidenceDate() );
02132 }
02133
02134 bool CalendarView::editIncidence( const QString &uid )
02135 {
02136 return editIncidence( mCalendar->incidence( uid ), QDate() );
02137 }
02138
02139 bool CalendarView::editIncidence( const QString &uid, const QDate &date )
02140 {
02141 return editIncidence( mCalendar->incidence( uid ), date );
02142 }
02143
02144 void CalendarView::deleteIncidence()
02145 {
02146 deleteIncidence( selectedIncidence() );
02147 }
02148
02149 void CalendarView::cutIncidence(Incidence *)
02150 {
02151 edit_cut();
02152 }
02153
02154 void CalendarView::copyIncidence(Incidence *)
02155 {
02156 edit_copy();
02157 }
02158
02159 void CalendarView::pasteIncidence()
02160 {
02161 edit_paste();
02162 }
02163
02164 void CalendarView::showIncidence( Incidence *incidence, const QDate &date )
02165 {
02166 if ( !incidence ) {
02167 return;
02168 }
02169
02170 KOEventViewerDialog *eventViewer = new KOEventViewerDialog( calendar(), this );
02171 eventViewer->setIncidence( incidence, date );
02172 eventViewer->show();
02173 }
02174
02175 bool CalendarView::editIncidence( Incidence *incidence, const QDate &date, bool isCounter )
02176 {
02177 kdDebug(5850) << "CalendarView::editEvent()" << endl;
02178
02179 CalendarResources *stdcal = dynamic_cast<CalendarResources *>( mCalendar );
02180 if( stdcal && !stdcal->hasCalendarResources() ) {
02181 KMessageBox::sorry(
02182 this,
02183 i18n( "No resources found. We can not edit the item." ) );
02184 return false;
02185 }
02186
02187
02188
02189
02190
02191 QWidget *tmpparent = 0;
02192 if ( stdcal ) {
02193 tmpparent = stdcal->dialogParentWidget();
02194 stdcal->setDialogParentWidget( this );
02195 }
02196
02197 if ( !incidence ) {
02198 kdDebug(5850) << "Empty Incidence" << endl;
02199 KNotifyClient::beep();
02200 return false;
02201 }
02202
02203 if ( !mChanger ) {
02204 kdDebug(5850) << "Empty Changer" << endl;
02205 KNotifyClient::beep();
02206 return false;
02207 }
02208
02209 KOIncidenceEditor *tmp = editorDialog( incidence );
02210 if ( tmp ) {
02211 kdDebug(5850) << "CalendarView::editIncidence() in List" << endl;
02212 tmp->reload();
02213 tmp->raise();
02214 tmp->show();
02215 return true;
02216 }
02217
02218 if ( incidence->isReadOnly() ) {
02219 showIncidence( incidence, date );
02220 return true;
02221 }
02222
02223 QPair<ResourceCalendar *, QString>p =
02224 CalHelper::incSubResourceCalendar( calendar(), incidence );
02225
02226 Incidence *savedIncidence = incidence->clone();
02227 Incidence *incToChange;
02228
02229 if ( incidence->doesRecur() ) {
02230 KOGlobals::WhichOccurrences chosenOption;
02231 incToChange = singleOccurrenceOrAll( incidence, KOGlobals::EDIT, chosenOption, date );
02232 } else {
02233 incToChange = incidence;
02234 }
02235
02236
02237 if ( incToChange ) {
02238 if ( !isCounter && !mChanger->beginChange( incToChange, p.first, p.second ) ) {
02239 warningChangeFailed( incToChange );
02240 showIncidence( incToChange, date );
02241
02242 return false;
02243 }
02244
02245 kdDebug(5850) << "CalendarView::editIncidence() new IncidenceEditor" << endl;
02246 KOIncidenceEditor *incidenceEditor = mDialogManager->getEditor( incToChange );
02247 connectIncidenceEditor( incidenceEditor );
02248
02249 mDialogList.insert( incToChange, incidenceEditor );
02250 if ( incidence != incToChange ) {
02251 incidenceEditor->setRecurringIncidence( savedIncidence, incidence );
02252 }
02253 incidenceEditor->setResource( p.first, p.second );
02254 incidenceEditor->editIncidence( incToChange, date, mCalendar );
02255 incidenceEditor->show();
02256 return true;
02257 } else {
02258 return false;
02259 }
02260 }
02261
02262 void CalendarView::deleteSubTodosIncidence ( Todo *todo )
02263 {
02264 if( !todo ) return;
02265
02266 Incidence::List subTodos( todo->relations() );
02267 Incidence::List::Iterator it;
02268 Incidence *aIncidence;
02269 Todo *aTodo;
02270
02271 for ( it= subTodos.begin(); it != subTodos.end(); ++it ) {
02272 aIncidence = *it;
02273 if( aIncidence && aIncidence->type() == "Todo" ) {
02274 aTodo = static_cast<Todo*>( aIncidence );
02275 deleteSubTodosIncidence ( aTodo );
02276 }
02277 }
02278 mChanger->deleteIncidence ( todo, this );
02279 }
02280
02281 void CalendarView::deleteTodoIncidence ( Todo *todo, bool force )
02282 {
02283 if ( !todo ) return ;
02284
02285
02286 if (todo->relations().isEmpty() ) {
02287 bool doDelete = true;
02288 if ( !force && KOPrefs::instance()->mConfirm ) {
02289 doDelete = ( msgItemDelete( todo ) == KMessageBox::Continue );
02290 }
02291 if ( doDelete )
02292 mChanger->deleteIncidence( todo, this );
02293 return;
02294 }
02295
02296
02297 int km = KMessageBox::No;
02298 if ( !force ) {
02299 km = KMessageBox::questionYesNoCancel(
02300 this,
02301 i18n("The item \"%1\" has sub-to-dos. "
02302 "Do you want to delete just this item and "
02303 "make all its sub-to-dos independent, or "
02304 "delete the to-do with all its sub-to-dos?"
02305 ).arg( todo->summary() ),
02306 i18n("KOrganizer Confirmation"),
02307 i18n("Delete Only This"),
02308 i18n("Delete All"));
02309 }
02310 startMultiModify( i18n("Deleting sub-to-dos" ) );
02311
02312 if( km == KMessageBox::Yes ) {
02313
02314
02315 makeChildrenIndependent ( todo );
02316 mChanger->deleteIncidence( todo, this );
02317 } else if ( km == KMessageBox::No ) {
02318
02319
02320 deleteSubTodosIncidence ( todo );
02321 }
02322 endMultiModify();
02323 }
02324
02325 void CalendarView::deleteIncidence(Incidence *incidence, bool force)
02326 {
02327 if ( !incidence || !mChanger ) {
02328 if ( !force ) {
02329 KNotifyClient::beep();
02330 }
02331 return;
02332 }
02333 if ( incidence->isReadOnly() ) {
02334 if ( !force ) {
02335 KMessageBox::information( this, i18n("The item \"%1\" is marked read-only "
02336 "and cannot be deleted; it probably belongs to "
02337 "a read-only calendar resource.")
02338 .arg(incidence->summary()),
02339 i18n("Removing not possible"),
02340 "deleteReadOnlyIncidence" );
02341 }
02342 return;
02343 }
02344
02345 CanDeleteIncidenceVisitor v;
02346
02347
02348
02349 if ( !v.act( incidence, this ) )
02350 return;
02351
02352
02353 if ( incidence && incidence->type()=="Todo" ) {
02354 deleteTodoIncidence( static_cast<Todo*>(incidence), force );
02355 return;
02356 }
02357
02358 if ( incidence->doesRecur() ) {
02359 QDate itemDate = mViewManager->currentSelectionDate();
02360 kdDebug(5850) << "Recurrence-Date: " << itemDate.toString() << endl;
02361 int km = KMessageBox::Ok;
02362 if ( !force ) {
02363 if ( !itemDate.isValid() ) {
02364 kdDebug(5850) << "Date Not Valid" << endl;
02365 km = KMessageBox::warningContinueCancel(this,
02366 i18n("The calendar item \"%1\" recurs over multiple dates; "
02367 "are you sure you want to delete it "
02368 "and all its recurrences?").arg( incidence->summary() ),
02369 i18n("KOrganizer Confirmation"), i18n("Delete All") );
02370 } else {
02371 km = KOMessageBox::fourBtnMsgBox( this, QMessageBox::Warning,
02372 i18n("The calendar item \"%1\" recurs over multiple dates. "
02373 "Do you want to delete only the current one on %2, only all "
02374 "future recurrences, or all its recurrences?" )
02375 .arg( incidence->summary() )
02376 .arg( KGlobal::locale()->formatDate(itemDate)),
02377 i18n("KOrganizer Confirmation"), i18n("Delete C&urrent"),
02378 i18n("Delete &Future"),
02379 i18n("Delete &All"));
02380 }
02381 }
02382
02383 QPair<ResourceCalendar *, QString>p =
02384 CalHelper::incSubResourceCalendar( calendar(), incidence );
02385
02386 switch(km) {
02387 case KMessageBox::Ok:
02388 case KMessageBox::Continue:
02389 mChanger->deleteIncidence( incidence, this );
02390 break;
02391
02392 case KMessageBox::Yes:
02393 if ( mChanger->beginChange( incidence, p.first, p.second ) ) {
02394 Incidence *oldIncidence = incidence->clone();
02395 incidence->recurrence()->addExDate( itemDate );
02396 mChanger->changeIncidence( oldIncidence, incidence,
02397 KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY, this );
02398 mChanger->endChange( incidence, p.first, p.second );
02399 delete oldIncidence;
02400 }
02401 break;
02402 case KMessageBox::No:
02403 if ( mChanger->beginChange( incidence, p.first, p.second ) ) {
02404 Incidence *oldIncidence = incidence->clone();
02405 Recurrence *recur = incidence->recurrence();
02406 recur->setEndDate( itemDate.addDays(-1) );
02407 mChanger->changeIncidence( oldIncidence, incidence,
02408 KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE, this );
02409 mChanger->endChange( incidence, p.first, p.second );
02410 delete oldIncidence;
02411 }
02412 break;
02413 }
02414 } else {
02415 bool doDelete = true;
02416 if ( !force && KOPrefs::instance()->mConfirm ) {
02417 doDelete = ( msgItemDelete( incidence ) == KMessageBox::Continue );
02418 }
02419 if ( doDelete ) {
02420 mChanger->deleteIncidence( incidence, this );
02421 processIncidenceSelection( 0, QDate() );
02422 }
02423 }
02424 }
02425
02426 void CalendarView::connectIncidenceEditor( KOIncidenceEditor *editor )
02427 {
02428 connect( this, SIGNAL( newIncidenceChanger( IncidenceChangerBase* ) ),
02429 editor, SLOT( setIncidenceChanger( IncidenceChangerBase* ) ) );
02430 editor->setIncidenceChanger( mChanger );
02431 }
02432
02433 bool CalendarView::purgeCompletedSubTodos( Todo* todo, bool &allPurged )
02434 {
02435 if ( !todo ) return true;
02436 bool deleteThisTodo = true;
02437 Incidence::List subTodos( todo->relations() );
02438 Incidence *aIncidence;
02439 Todo *aTodo;
02440 Incidence::List::Iterator it;
02441 for ( it = subTodos.begin(); it != subTodos.end(); ++it ) {
02442 aIncidence = *it;
02443 if ( aIncidence && aIncidence->type()=="Todo" ) {
02444 aTodo = static_cast<Todo*>( aIncidence );
02445 deleteThisTodo &= purgeCompletedSubTodos( aTodo, allPurged );
02446 }
02447 }
02448
02449 if ( deleteThisTodo ) {
02450 if ( todo->isCompleted() ) {
02451 if ( !mChanger->deleteIncidence( todo, this ) )
02452 allPurged = false;
02453 } else {
02454 deleteThisTodo = false;
02455 }
02456 } else {
02457 if ( todo->isCompleted() ) {
02458 allPurged = false;
02459 }
02460 }
02461 return deleteThisTodo;
02462 }
02463
02464 void CalendarView::purgeCompleted()
02465 {
02466 int result = KMessageBox::warningContinueCancel(this,
02467 i18n("Delete all completed to-dos?"),i18n("Purge To-dos"),i18n("Purge"));
02468
02469 if (result == KMessageBox::Continue) {
02470 bool allDeleted = true;
02471 startMultiModify( i18n("Purging completed to-dos") );
02472 Todo::List todos = calendar()->rawTodos();
02473 Todo::List rootTodos;
02474 Todo::List::ConstIterator it;
02475 for ( it = todos.begin(); it != todos.end(); ++it ) {
02476 Todo *aTodo = *it;
02477 if ( aTodo && !aTodo->relatedTo() )
02478 rootTodos.append( aTodo );
02479 }
02480
02481 for ( it = rootTodos.begin(); it != rootTodos.end(); ++it ) {
02482 purgeCompletedSubTodos( *it, allDeleted );
02483 }
02484 endMultiModify();
02485 if ( !allDeleted ) {
02486 KMessageBox::information( this, i18n("Unable to purge to-dos with "
02487 "uncompleted children."), i18n("Delete To-do"),
02488 "UncompletedChildrenPurgeTodos" );
02489 }
02490 }
02491 }
02492
02493 void CalendarView::warningChangeFailed( Incidence *incidence )
02494 {
02495 if ( incidence ) {
02496 KMessageBox::sorry(
02497 this,
02498 i18n( "Unable to edit \"%1\" because it is locked by another process." ).
02499 arg( incidence->summary() ) );
02500 }
02501 }
02502
02503 void CalendarView::editCanceled( Incidence *incidence )
02504 {
02505 mCalendar->endChange( incidence );
02506 }
02507
02508 void CalendarView::showErrorMessage( const QString &msg )
02509 {
02510 KMessageBox::error( this, msg );
02511 }
02512
02513 void CalendarView::updateCategories()
02514 {
02515 QStringList allCats( calendar()->categories() );
02516 allCats.sort();
02517 QStringList categories( KOPrefs::instance()->mCustomCategories );
02518 for ( QStringList::ConstIterator si = allCats.constBegin(); si != allCats.constEnd(); ++si ) {
02519 if ( categories.find( *si ) == categories.end() ) {
02520 categories.append( *si );
02521 }
02522 }
02523 KOPrefs::instance()->mCustomCategories = categories;
02524 KOPrefs::instance()->writeConfig();
02525
02526 emit categoriesChanged();
02527 }
02528
02529 void CalendarView::addIncidenceOn( Incidence *incadd, const QDate &dt )
02530 {
02531 if ( !incadd || !mChanger ) {
02532 KMessageBox::sorry(this, i18n("Unable to copy the item to %1.")
02533 .arg( dt.toString() ), i18n("Copying Failed") );
02534 return;
02535 }
02536 Incidence *incidence = mCalendar->incidence( incadd->uid() );
02537 if ( !incidence ) incidence = incadd;
02538
02539 incidence = incidence->clone();
02540 incidence->recreate();
02541
02542 if ( incidence->type() == "Event" ) {
02543 Event *event = static_cast<Event*>(incidence);
02544
02545
02546 QDateTime start = event->dtStart();
02547 QDateTime end = event->dtEnd();
02548
02549 int duration = start.daysTo( end );
02550 start.setDate( dt );
02551 end.setDate( dt.addDays( duration ) );
02552
02553 event->setDtStart( start );
02554 event->setDtEnd( end );
02555
02556 } else if ( incidence->type() == "Todo" ) {
02557 Todo *todo = static_cast<Todo*>(incidence);
02558 QDateTime due = todo->dtDue();
02559 due.setDate( dt );
02560
02561 todo->setDtDue( due );
02562 todo->setHasDueDate( true );
02563 }
02564
02565 QPair<ResourceCalendar *, QString>p = viewSubResourceCalendar();
02566
02567 if ( !mChanger->addIncidence( incidence, p.first, p.second, this ) ) {
02568 KODialogManager::errorSaveIncidence( this, incidence );
02569 delete incidence;
02570 }
02571 }
02572
02573 void CalendarView::moveIncidenceTo( Incidence *incmove, const QDate &dt )
02574 {
02575 if ( !incmove || !mChanger ) {
02576 KMessageBox::sorry( this, i18n("Unable to move the item to %1.")
02577 .arg( dt.toString() ), i18n("Moving Failed") );
02578 return;
02579 }
02580 Incidence *incidence = mCalendar->incidence( incmove->uid() );
02581 if ( !incidence ) {
02582 addIncidenceOn( incidence, dt );
02583 return;
02584 }
02585
02586 Incidence *oldIncidence = incidence->clone();
02587 QPair<ResourceCalendar *, QString>p = viewSubResourceCalendar();
02588
02589 if ( !mChanger->beginChange( incidence, p.first, p.second ) ) {
02590 delete oldIncidence;
02591 return;
02592 }
02593
02594 if ( incidence->type() == "Event" ) {
02595 Event *event = static_cast<Event*>(incidence);
02596
02597
02598 QDateTime start = event->dtStart();
02599 QDateTime end = event->dtEnd();
02600
02601 int duration = start.daysTo( end );
02602 start.setDate( dt );
02603 end.setDate( dt.addDays( duration ) );
02604
02605 event->setDtStart( start );
02606 event->setDtEnd( end );
02607
02608 } else if ( incidence->type() == "Todo" ) {
02609 Todo *todo = static_cast<Todo*>(incidence);
02610 QDateTime due = todo->dtDue();
02611 due.setDate( dt );
02612
02613 todo->setDtDue( due );
02614 todo->setHasDueDate( true );
02615 }
02616 mChanger->changeIncidence( oldIncidence, incidence, KOGlobals::DATE_MODIFIED,this );
02617 mChanger->endChange( incidence, p.first, p.second );
02618 delete oldIncidence;
02619 }
02620
02621 void CalendarView::resourcesChanged()
02622 {
02623 mViewManager->resourcesChanged();
02624 mDateNavigatorContainer->setUpdateNeeded();
02625 updateView();
02626 }
02627
02628 Incidence* CalendarView::singleOccurrenceOrAll( Incidence *inc,
02629 KOGlobals::OccurrenceAction userAction,
02630 KOGlobals::WhichOccurrences &chosenOption,
02631 const QDate &itemDate,
02632 const bool commitToCalendar )
02633 {
02634
02635
02636 if ( inc->type() != "Event" ) {
02637 chosenOption = KOGlobals::ALL;
02638 return inc;
02639 }
02640
02641 Incidence *incToReturn = 0;
02642 Incidence *incSaved = 0;
02643 KOGlobals::WhatChanged whatChanged;
02644
02645 bool dissociationOccurred = false;
02646 const QDate &dt = itemDate.isValid() ? itemDate : activeIncidenceDate();
02647
02648 QString dialogTitle;
02649 QString dialogText;
02650
02651 if ( userAction == KOGlobals::CUT ) {
02652 dialogTitle = i18n( "Cutting Recurring Item" );
02653
02654 dialogText = i18n("The item you try to cut is a recurring item. Do you want to cut "
02655 "only this single occurrence, only future items, "
02656 "or all items in the recurrence?");
02657
02658 } else if ( userAction == KOGlobals::COPY ) {
02659 dialogTitle = i18n( "Copying Recurring Item" );
02660
02661 dialogText = i18n("The item you try to copy is a recurring item. Do you want to copy "
02662 "only this single occurrence, only future items, "
02663 "or all items in the recurrence?");
02664 } else {
02665 dialogTitle = i18n( "Changing Recurring Item" );
02666
02667 dialogText = i18n( "The item you try to change is a recurring item. Shall the changes "
02668 "be applied only to this single occurrence, only to the future items, "
02669 "or to all items in the recurrence?" );
02670 }
02671
02672 int res = KOMessageBox::fourBtnMsgBox( this, QMessageBox::Question,
02673 dialogText,
02674 dialogTitle,
02675 i18n("Only &This Item"), i18n("Only &Future Items"), i18n("&All Occurrences") );
02676 switch ( res ) {
02677 case KMessageBox::Ok:
02678 incToReturn = inc;
02679 chosenOption = KOGlobals::ALL;
02680 break;
02681 case KMessageBox::Yes: {
02682
02683
02684
02685
02686
02687
02688
02689 chosenOption = KOGlobals::ONLY_THIS_ONE;
02690 whatChanged = KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY;
02691 startMultiModify( i18n("Dissociate event from recurrence") );
02692 incSaved = inc->clone();
02693 incToReturn = mCalendar->dissociateOccurrence( inc, dt );
02694 if ( incToReturn ) {
02695 dissociationOccurred = true;
02696 } else {
02697 KMessageBox::sorry( this, i18n("Unable to add the exception item to the "
02698 "calendar. No change will be done."), i18n("Error Occurred") );
02699 incToReturn = 0;
02700 }
02701
02702 break; }
02703 case KMessageBox::No: {
02704
02705
02706
02707
02708
02709
02710 chosenOption = KOGlobals::ONLY_FUTURE;
02711 whatChanged = KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE;
02712 startMultiModify( i18n("Split future recurrences") );
02713 incSaved = inc->clone();
02714 incToReturn = mCalendar->dissociateOccurrence( inc, dt, false );
02715 if ( incToReturn ) {
02716 dissociationOccurred = true;
02717 } else {
02718 KMessageBox::sorry( this, i18n("Unable to add the future items to the "
02719 "calendar. No change will be done."), i18n("Error Occurred") );
02720
02721 incToReturn = 0;
02722 }
02723
02724 break; }
02725 default:
02726 chosenOption = KOGlobals::NONE;
02727 }
02728
02729 if ( dissociationOccurred && commitToCalendar ) {
02730 QPair<ResourceCalendar *, QString>p = viewSubResourceCalendar();
02731 mChanger->addIncidence( incToReturn, p.first, p.second, this );
02732 mChanger->changeIncidence( incSaved, inc, whatChanged, this );
02733 }
02734
02735 return incToReturn;
02736 }
02737
02738 void CalendarView::selectWeek( const QDate &date )
02739 {
02740 if ( KOPrefs::instance()->mWeekNumbersShowWork &&
02741 mViewManager->agendaIsSelected() &&
02742 mViewManager->agendaMode() == KOViewManager::AGENDA_WORK_WEEK ) {
02743 mDateNavigator->selectWorkWeek( date );
02744 } else {
02745 mDateNavigator->selectWeek( date );
02746 }
02747 }
02748
02749 void CalendarView::getIncidenceHierarchy( Incidence *inc,
02750 Incidence::List &children )
02751 {
02752
02753 if ( inc && !children.contains( inc ) ) {
02754 Incidence::List::ConstIterator it;
02755 Incidence::List immediateChildren = inc->relations();
02756 for ( it = immediateChildren.constBegin(); it != immediateChildren.constEnd(); ++it ) {
02757 getIncidenceHierarchy( *it, children );
02758 }
02759 children.append( inc );
02760 }
02761 }
02762
02763 #include "calendarview.moc"