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