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
00066 #include <libkcal/vcaldrag.h>
00067 #include <libkcal/icaldrag.h>
00068 #include <libkcal/icalformat.h>
00069 #include <libkcal/vcalformat.h>
00070 #include <libkcal/scheduler.h>
00071 #include <libkcal/calendarlocal.h>
00072 #include <libkcal/journal.h>
00073 #include <libkcal/calfilter.h>
00074 #include <libkcal/attendee.h>
00075 #include <libkcal/dndfactory.h>
00076 #include <libkcal/freebusy.h>
00077 #include <libkcal/filestorage.h>
00078 #include <libkcal/calendarresources.h>
00079 #include <libkcal/qtopiaformat.h>
00080 #include <libkcal/calendarnull.h>
00081 #include <libkcal/htmlexportsettings.h>
00082
00083 #include <kglobal.h>
00084 #include <kdebug.h>
00085 #include <kstandarddirs.h>
00086 #include <kfiledialog.h>
00087 #include <kmessagebox.h>
00088 #include <knotifyclient.h>
00089 #include <kconfig.h>
00090 #include <krun.h>
00091 #include <kdirwatch.h>
00092
00093 #include <qapplication.h>
00094 #include <qclipboard.h>
00095 #include <qcursor.h>
00096 #include <qmultilineedit.h>
00097 #include <qtimer.h>
00098 #include <qwidgetstack.h>
00099 #include <qptrlist.h>
00100 #include <qfile.h>
00101 #include <qlayout.h>
00102 #ifndef KORG_NOSPLITTER
00103 #include <qsplitter.h>
00104 #endif
00105 #include <qvbox.h>
00106 #include <qwhatsthis.h>
00107
00108 #include <stdlib.h>
00109 #include <assert.h>
00110
00111 using namespace KOrg;
00112
00113 CalendarView::CalendarView( QWidget *parent, const char *name )
00114 : CalendarViewBase( parent, name ),
00115 mHistory( 0 ),
00116 mCalendar( CalendarNull::self() ),
00117 mChanger( 0 )
00118 {
00119 kdDebug(5850) << "CalendarView::CalendarView( Calendar )" << endl;
00120
00121 mViewManager = new KOViewManager( this );
00122 mDialogManager = new KODialogManager( this );
00123
00124 mModified = false;
00125 mReadOnly = false;
00126 mSelectedIncidence = 0;
00127
00128 mCalPrinter = 0;
00129
00130 mFilters.setAutoDelete( true );
00131
00132 mExtensions.setAutoDelete( true );
00133
00134 mNavigator = 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 mDateNavigator = new DateNavigatorContainer( mLeftSplitter,
00150 "CalendarView::DateNavigator" );
00151
00152
00153 mLeftSplitter->setCollapsible( mDateNavigator, true );
00154 mTodoList = new KOTodoView( CalendarNull::self(), mLeftSplitter, "todolist" );
00155
00156 mEventViewer = new KOEventViewer( 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 mDateNavigator = new KDateNavigator( leftFrame, true,
00179 "CalendarView::DateNavigator",
00180 QDate::currentDate() );
00181 mTodoList = new KOTodoView( CalendarNull::self(), leftFrame, "todolist" );
00182
00183 mEventViewer = new KOEventViewer ( 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( mDateNavigator->sizeHint().height() );
00199 }
00200 #endif
00201
00202 connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ),
00203 SLOT( showDates( const KCal::DateList & ) ) );
00204 connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ),
00205 mDateNavigator, SLOT( selectDates( const KCal::DateList & ) ) );
00206
00207 connect( mNavigatorBar, SIGNAL( goPrevYear() ),
00208 mNavigator, SLOT( selectPreviousYear() ) );
00209 connect( mNavigatorBar, SIGNAL( goNextYear() ),
00210 mNavigator, SLOT( selectNextYear() ) );
00211 connect( mNavigatorBar, SIGNAL( goPrevMonth() ),
00212 mNavigator, SLOT( selectPreviousMonth() ) );
00213 connect( mNavigatorBar, SIGNAL( goNextMonth() ),
00214 mNavigator, SLOT( selectNextMonth() ) );
00215 connect( mNavigatorBar, SIGNAL( goMonth(int) ),
00216 mNavigator, SLOT( selectMonth(int) ) );
00217
00218 connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ),
00219 mNavigatorBar, SLOT( selectDates( const KCal::DateList & ) ) );
00220
00221 connect( mDateNavigator, SIGNAL( weekClicked( const QDate & ) ),
00222 mNavigator, SLOT( selectWeek( const QDate & ) ) );
00223
00224 connect( mDateNavigator, SIGNAL( goPrevYear() ),
00225 mNavigator, SLOT( selectPreviousYear() ) );
00226 connect( mDateNavigator, SIGNAL( goNextYear() ),
00227 mNavigator, SLOT( selectNextYear() ) );
00228 connect( mDateNavigator, SIGNAL( goPrevMonth() ),
00229 mNavigator, SLOT( selectPreviousMonth() ) );
00230 connect( mDateNavigator, SIGNAL( goNextMonth() ),
00231 mNavigator, SLOT( selectNextMonth() ) );
00232 connect( mDateNavigator, SIGNAL( goMonth(int) ),
00233 mNavigator, SLOT( selectMonth(int) ) );
00234
00235 connect( mDateNavigator, SIGNAL( goPrevious() ),
00236 mNavigator, SLOT( selectPrevious() ) );
00237 connect( mDateNavigator, SIGNAL( goNext() ),
00238 mNavigator, SLOT( selectNext() ) );
00239
00240 connect( mDateNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ),
00241 mNavigator, SLOT( selectDates( const KCal::DateList & ) ) );
00242
00243 connect( mDateNavigator, SIGNAL(incidenceDropped(Incidence*, const QDate&)),
00244 SLOT( addIncidenceOn( Incidence *, const QDate & ) ) );
00245 connect( mDateNavigator, SIGNAL(incidenceDroppedMove(Incidence*,const QDate&)),
00246 SLOT( moveIncidenceTo( Incidence *, const QDate & ) ) );
00247
00248 connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00249 mTodoList, SLOT( dayPassed( const QDate & ) ) );
00250 connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00251 SIGNAL( dayPassed( const QDate & ) ) );
00252 connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00253 mDateNavigator, SLOT( updateToday() ) );
00254
00255 connect( this, SIGNAL( configChanged() ),
00256 mDateNavigator, SLOT( updateConfig() ) );
00257
00258 connect( this, SIGNAL( incidenceSelected(Incidence *) ),
00259 mEventViewer, SLOT ( setIncidence (Incidence *) ) );
00260
00261
00262 QString s;
00263 s = i18n( "<p><em>No Item Selected</em></p>"
00264 "<p>Select an event, to-do or journal entry to view its details "
00265 "here.</p>");
00266
00267 mEventViewer->setDefaultText( s );
00268 QWhatsThis::add( mEventViewer,
00269 i18n( "View the details of events, journal entries or to-dos "
00270 "selected in KOrganizer's main view here." ) );
00271 mEventViewer->setIncidence( 0 );
00272
00273 mViewManager->connectTodoView( mTodoList );
00274 mViewManager->connectView( mTodoList );
00275
00276 KOGlobals::self()->
00277 setHolidays( new KHolidays( KOPrefs::instance()->mHolidays ) );
00278
00279 connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00280 SLOT( checkClipboard() ) );
00281
00282 connect( mTodoList, SIGNAL( incidenceSelected( Incidence * ) ),
00283 SLOT( processTodoListSelection( Incidence * ) ) );
00284 disconnect( mTodoList, SIGNAL( incidenceSelected( Incidence * ) ),
00285 this, SLOT( processMainViewSelection( Incidence * ) ) );
00286
00287 kdDebug(5850) << "CalendarView::CalendarView() done" << endl;
00288 }
00289
00290 CalendarView::~CalendarView()
00291 {
00292 kdDebug(5850) << "~CalendarView()" << endl;
00293
00294 mCalendar->unregisterObserver( this );
00295
00296 delete mDialogManager;
00297 delete mViewManager;
00298 delete mEventViewer;
00299 kdDebug(5850) << "~CalendarView() done" << endl;
00300 }
00301
00302 void CalendarView::setCalendar( Calendar *cal )
00303 {
00304 kdDebug(5850)<<"CalendarView::setCalendar"<<endl;
00305 mCalendar = cal;
00306
00307 delete mHistory;
00308 mHistory = new History( mCalendar );
00309 connect( mHistory, SIGNAL( undone() ), SLOT( updateView() ) );
00310 connect( mHistory, SIGNAL( redone() ), SLOT( updateView() ) );
00311
00312 if ( mChanger ) delete mChanger;
00313 setIncidenceChanger( new IncidenceChanger( mCalendar, this ) );
00314
00315 mCalendar->registerObserver( this );
00316
00317 mDateNavigator->setCalendar( mCalendar );
00318
00319 mTodoList->setCalendar( mCalendar );
00320 }
00321
00322 void CalendarView::setIncidenceChanger( IncidenceChangerBase *changer )
00323 {
00324 mChanger = changer;
00325 emit newIncidenceChanger( mChanger );
00326 connect( mChanger, SIGNAL( incidenceAdded( Incidence* ) ),
00327 this, SLOT( incidenceAdded( Incidence* ) ) );
00328 connect( mChanger, SIGNAL( incidenceChanged( Incidence*, Incidence*, int ) ),
00329 this, SLOT( incidenceChanged( Incidence*, Incidence*, int ) ) );
00330 connect( mChanger, SIGNAL( incidenceChanged( Incidence*, Incidence* ) ),
00331 this, SLOT( incidenceChanged( Incidence*, Incidence* ) ) );
00332 connect( mChanger, SIGNAL( incidenceToBeDeleted( Incidence * ) ),
00333 this, SLOT( incidenceToBeDeleted( Incidence * ) ) );
00334 connect( mChanger, SIGNAL( incidenceDeleted( Incidence * ) ),
00335 this, SLOT( incidenceDeleted( Incidence * ) ) );
00336
00337 connect( mChanger, SIGNAL( schedule( Scheduler::Method, Incidence*) ),
00338 this, SLOT( schedule( Scheduler::Method, Incidence*) ) );
00339
00340
00341 connect( this, SIGNAL( cancelAttendees( Incidence * ) ),
00342 mChanger, SLOT( cancelAttendees( Incidence * ) ) );
00343 }
00344
00345 Calendar *CalendarView::calendar()
00346 {
00347 if ( mCalendar ) return mCalendar;
00348 else return CalendarNull::self();
00349 }
00350
00351 KOIncidenceEditor *CalendarView::editorDialog( Incidence *incidence ) const
00352 {
00353 if (mDialogList.find(incidence) != mDialogList.end ())
00354 return mDialogList[incidence];
00355 else return 0;
00356 }
00357
00358 QDate CalendarView::startDate()
00359 {
00360 DateList dates = mNavigator->selectedDates();
00361
00362 return dates.first();
00363 }
00364
00365 QDate CalendarView::endDate()
00366 {
00367 DateList dates = mNavigator->selectedDates();
00368
00369 return dates.last();
00370 }
00371
00372
00373 void CalendarView::createPrinter()
00374 {
00375 #ifndef KORG_NOPRINTER
00376 if (!mCalPrinter) {
00377 mCalPrinter = new CalPrinter( this, mCalendar, new KOCoreHelper() );
00378 connect(this, SIGNAL(configChanged()), mCalPrinter, SLOT(updateConfig()));
00379 }
00380 #endif
00381 }
00382
00383
00384 bool CalendarView::openCalendar(const QString& filename, bool merge)
00385 {
00386 kdDebug(5850) << "CalendarView::openCalendar(): " << filename << endl;
00387
00388 if (filename.isEmpty()) {
00389 kdDebug(5850) << "CalendarView::openCalendar(): Error! Empty filename." << endl;
00390 return false;
00391 }
00392
00393 if (!QFile::exists(filename)) {
00394 kdDebug(5850) << "CalendarView::openCalendar(): Error! File '" << filename
00395 << "' doesn't exist." << endl;
00396 }
00397
00398 bool loadedSuccesfully = true;
00399 if ( !merge ) {
00400 mCalendar->close();
00401 CalendarLocal *cl = dynamic_cast<CalendarLocal*>( mCalendar );
00402 if ( cl ) {
00403 loadedSuccesfully = cl->load( filename );
00404 } else {
00405 CalendarResources *cr = dynamic_cast<CalendarResources*>( mCalendar );
00406 assert( cr );
00407
00408 return false;
00409 }
00410 } else {
00411
00412 FileStorage storage( mCalendar );
00413 storage.setFileName( filename );
00414 loadedSuccesfully = storage.load();
00415 }
00416
00417 if ( loadedSuccesfully ) {
00418 if ( merge )
00419 setModified( true );
00420 else {
00421 setModified( false );
00422 mViewManager->setDocumentId( filename );
00423 mTodoList->setDocumentId( filename );
00424 }
00425 updateCategories();
00426 updateView();
00427 return true;
00428 } else {
00429
00430
00431 if ( !merge ) mCalendar->close();
00432
00433 KMessageBox::error(this,i18n("Could not load calendar '%1'.").arg(filename));
00434
00435 return false;
00436 }
00437 }
00438
00439 bool CalendarView::saveCalendar( const QString& filename )
00440 {
00441 kdDebug(5850) << "CalendarView::saveCalendar(): " << filename << endl;
00442
00443
00444 mViewManager->currentView()->flushView();
00445
00446 FileStorage storage( mCalendar );
00447 storage.setFileName( filename );
00448 storage.setSaveFormat( new ICalFormat );
00449
00450 bool success = storage.save();
00451
00452 if ( !success ) {
00453 return false;
00454 }
00455
00456 return true;
00457 }
00458
00459 void CalendarView::closeCalendar()
00460 {
00461 kdDebug(5850) << "CalendarView::closeCalendar()" << endl;
00462
00463
00464 emit closingDown();
00465
00466 mCalendar->close();
00467 setModified( false );
00468 updateView();
00469 }
00470
00471 void CalendarView::archiveCalendar()
00472 {
00473 mDialogManager->showArchiveDialog();
00474 }
00475
00476
00477 void CalendarView::readSettings()
00478 {
00479
00480
00481 QString str;
00482
00483
00484
00485
00486 KConfig *config = KOGlobals::self()->config();
00487
00488 #ifndef KORG_NOSPLITTER
00489 config->setGroup( "KOrganizer Geometry" );
00490
00491 QValueList<int> sizes = config->readIntListEntry( "Separator1" );
00492 if ( sizes.count() != 2 ) {
00493 sizes << mDateNavigator->minimumSizeHint().width();
00494 sizes << 300;
00495 }
00496 mPanner->setSizes( sizes );
00497
00498 sizes = config->readIntListEntry( "Separator2" );
00499 mLeftSplitter->setSizes( sizes );
00500 #endif
00501
00502 mEventViewer->readSettings( config );
00503
00504 mViewManager->readSettings( config );
00505 mTodoList->restoreLayout( config, QString( "Todo Layout" ) );
00506
00507 readFilterSettings( config );
00508
00509 config->setGroup( "Views" );
00510 int dateCount = config->readNumEntry( "ShownDatesCount", 7 );
00511 if ( dateCount == 5 ) mNavigator->selectWorkWeek();
00512 else if ( dateCount == 7 ) mNavigator->selectWeek();
00513 else mNavigator->selectDates( dateCount );
00514 }
00515
00516
00517 void CalendarView::writeSettings()
00518 {
00519
00520
00521 KConfig *config = KOGlobals::self()->config();
00522
00523 #ifndef KORG_NOSPLITTER
00524 config->setGroup( "KOrganizer Geometry" );
00525
00526 QValueList<int> list = mPanner->sizes();
00527 config->writeEntry( "Separator1", list );
00528
00529 list = mLeftSplitter->sizes();
00530 config->writeEntry( "Separator2", list );
00531 #endif
00532 mEventViewer->writeSettings( config );
00533 mViewManager->writeSettings( config );
00534 mTodoList->saveLayout( config, QString( "Todo Layout" ) );
00535
00536 KOPrefs::instance()->writeConfig();
00537
00538 writeFilterSettings( config );
00539
00540 config->setGroup( "Views" );
00541 config->writeEntry( "ShownDatesCount", mNavigator->selectedDates().count() );
00542
00543 config->sync();
00544 }
00545
00546 void CalendarView::readFilterSettings( KConfig *config )
00547 {
00548
00549
00550 mFilters.clear();
00551
00552 config->setGroup( "General" );
00553
00554 QStringList filterList = config->readListEntry ("CalendarFilters" );
00555 QString currentFilter = config->readEntry( "Current Filter" );
00556
00557 QStringList::ConstIterator it = filterList.begin();
00558 QStringList::ConstIterator end = filterList.end();
00559 while( it != end ) {
00560
00561 CalFilter *filter;
00562 filter = new CalFilter( *it );
00563 config->setGroup( "Filter_" + (*it) );
00564 filter->setCriteria( config->readNumEntry( "Criteria", 0 ) );
00565 filter->setCategoryList( config->readListEntry( "CategoryList" ) );
00566 if ( filter->criteria() & KCal::CalFilter::HideTodosWithoutAttendeeInEmailList )
00567 filter->setEmailList( KOPrefs::instance()->allEmails() );
00568 filter->setCompletedTimeSpan( config->readNumEntry( "HideTodoDays", 0 ) );
00569 mFilters.append( filter );
00570
00571 ++it;
00572 }
00573
00574 config->setGroup( "General" );
00575 int pos = filterList.findIndex( currentFilter );
00576 mCurrentFilter = 0;
00577 if ( pos>=0 ) {
00578 mCurrentFilter = mFilters.at( pos );
00579 }
00580 updateFilter();
00581 }
00582
00583 void CalendarView::writeFilterSettings( KConfig *config )
00584 {
00585
00586
00587 QStringList filterList;
00588
00589 CalFilter *filter = mFilters.first();
00590 while( filter ) {
00591
00592 filterList << filter->name();
00593 config->setGroup( "Filter_" + filter->name() );
00594 config->writeEntry( "Criteria", filter->criteria() );
00595 config->writeEntry( "CategoryList", filter->categoryList() );
00596 config->writeEntry( "HideTodoDays", filter->completedTimeSpan() );
00597 filter = mFilters.next();
00598 }
00599 config->setGroup( "General" );
00600 config->writeEntry( "CalendarFilters", filterList );
00601 if ( mCurrentFilter ) {
00602 config->writeEntry( "Current Filter", mCurrentFilter->name() );
00603 } else {
00604 config->writeEntry( "Current Filter", QString::null );
00605 }
00606 }
00607
00608
00609 void CalendarView::goDate( const QDate& date )
00610 {
00611 mNavigator->selectDate( date );
00612 }
00613
00614 void CalendarView::goToday()
00615 {
00616 mNavigator->selectToday();
00617 }
00618
00619 void CalendarView::goNext()
00620 {
00621 if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) )
00622 mNavigator->selectNextMonth();
00623 else
00624 mNavigator->selectNext();
00625 }
00626
00627 void CalendarView::goPrevious()
00628 {
00629 if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) )
00630 mNavigator->selectPreviousMonth();
00631 else
00632 mNavigator->selectPrevious();
00633 }
00634
00635 void CalendarView::updateConfig( const QCString& receiver)
00636 {
00637 if ( receiver != "korganizer" ) return;
00638 kdDebug(5850) << "CalendarView::updateConfig()" << endl;
00639
00640 KOGlobals::self()->
00641 setHolidays( new KHolidays( KOPrefs::instance()->mHolidays ) );
00642
00643 QString tz( mCalendar->timeZoneId() );
00644
00645
00646 if ( tz != KOPrefs::instance()->mTimeZoneId ) {
00647
00648 const QString question( i18n("The timezone setting was changed. Do you want to keep the absolute time of "
00649 "the items in your calendar, which will show them to be at a different time than "
00650 "before, or move them to be at the old time also in the new timezone?") );
00651 int rc = KMessageBox::questionYesNo( this, question,
00652 i18n("Keep Absolute Times?"),
00653 KGuiItem(i18n("Keep Times")),
00654 KGuiItem(i18n("Move Times")),
00655 "calendarKeepAbsoluteTimes");
00656 if ( rc == KMessageBox::Yes ) {
00657
00658 mCalendar->setTimeZoneIdViewOnly( KOPrefs::instance()->mTimeZoneId );
00659 } else {
00660
00661
00662 mCalendar->setTimeZoneId( KOPrefs::instance()->mTimeZoneId );
00663 }
00664 }
00665 emit configChanged();
00666
00667 mViewManager->raiseCurrentView();
00668 }
00669
00670
00671 void CalendarView::incidenceAdded( Incidence *incidence )
00672 {
00673 setModified( true );
00674 history()->recordAdd( incidence );
00675 changeIncidenceDisplay( incidence, KOGlobals::INCIDENCEADDED );
00676 updateUnmanagedViews();
00677 checkForFilteredChange( incidence );
00678 }
00679
00680 void CalendarView::incidenceChanged( Incidence *oldIncidence,
00681 Incidence *newIncidence )
00682 {
00683 incidenceChanged( oldIncidence, newIncidence, KOGlobals::UNKNOWN_MODIFIED );
00684 }
00685
00686 void CalendarView::incidenceChanged( Incidence *oldIncidence,
00687 Incidence *newIncidence, int what )
00688 {
00689
00690 KOIncidenceEditor *tmp = editorDialog( newIncidence );
00691 if ( tmp ) {
00692 kdDebug(5850) << "Incidence modified and open" << endl;
00693 tmp->modified( what );
00694 }
00695 setModified( true );
00696 history()->recordEdit( oldIncidence, newIncidence );
00697
00698
00699
00700
00701 if ( newIncidence->type() == "Todo"
00702 && KOPrefs::instance()->recordTodosInJournals()
00703 && what == KOGlobals::COMPLETION_MODIFIED ) {
00704
00705 Todo *todo = static_cast<Todo *>(newIncidence);
00706 if ( todo->isCompleted() ) {
00707 QString timeStr = KGlobal::locale()->formatTime( QTime::currentTime() );
00708 QString description = i18n( "To-do completed: %1 (%2)" ).arg(
00709 newIncidence->summary() ).arg( timeStr );
00710
00711 Journal::List journals = calendar()->journals( QDate::currentDate() );
00712 Journal *journal;
00713
00714 if ( journals.isEmpty() ) {
00715 journal = new Journal();
00716 journal->setDtStart( QDateTime::currentDateTime() );
00717
00718 QString dateStr = KGlobal::locale()->formatDate( QDate::currentDate() );
00719 journal->setSummary( i18n("Journal of %1").arg( dateStr ) );
00720 journal->setDescription( description );
00721
00722 if ( !mChanger->addIncidence( journal ) ) {
00723 KODialogManager::errorSaveIncidence( this, journal );
00724 delete journal;
00725 return;
00726 }
00727
00728 } else {
00729 journal = *(journals.at(0));
00730 Journal *oldJournal = journal->clone();
00731 journal->setDescription( journal->description().append( "\n" + description ) );
00732
00733 if ( !mChanger->changeIncidence( oldJournal, journal ) ) {
00734 KODialogManager::errorSaveIncidence( this, journal );
00735 delete journal;
00736 return;
00737 }
00738 }
00739 }
00740 }
00741
00742 changeIncidenceDisplay( newIncidence, KOGlobals::INCIDENCEEDITED );
00743 updateUnmanagedViews();
00744 checkForFilteredChange( newIncidence );
00745 }
00746
00747 void CalendarView::incidenceToBeDeleted( Incidence *incidence )
00748 {
00749 KOIncidenceEditor *tmp = editorDialog( incidence );
00750 if (tmp) {
00751 kdDebug(5850) << "Incidence to be deleted and open in editor" << endl;
00752 tmp->delayedDestruct();
00753 }
00754 setModified( true );
00755 history()->recordDelete( incidence );
00756
00757 updateUnmanagedViews();
00758 }
00759
00760 void CalendarView::incidenceDeleted( Incidence *incidence )
00761 {
00762 changeIncidenceDisplay( incidence, KOGlobals::INCIDENCEDELETED );
00763 updateUnmanagedViews();
00764 }
00765
00766 void CalendarView::checkForFilteredChange( Incidence *incidence )
00767 {
00768 CalFilter *filter = calendar()->filter();
00769 if ( filter && !filter->filterIncidence( incidence ) ) {
00770
00771
00772 KMessageBox::information( this, i18n("The item \"%1\" is filtered by "
00773 "your current filter rules, so it will be hidden and not "
00774 "appear in the view.").arg( incidence->summary() ),
00775 i18n("Filter Applied"), "ChangedIncidenceFiltered" );
00776 }
00777 }
00778
00779 void CalendarView::startMultiModify( const QString &text )
00780 {
00781 history()->startMultiModify( text );
00782 }
00783
00784 void CalendarView::endMultiModify()
00785 {
00786 history()->endMultiModify();
00787 }
00788
00789
00790 void CalendarView::changeIncidenceDisplay( Incidence *incidence, int action )
00791 {
00792 mDateNavigator->updateView();
00793 mDialogManager->updateSearchDialog();
00794
00795 if ( incidence ) {
00796
00797 mViewManager->currentView()->changeIncidenceDisplay( incidence, action );
00798 if ( mTodoList ) mTodoList->changeIncidenceDisplay( incidence, action );
00799 mEventViewer->changeIncidenceDisplay( incidence, action );
00800 } else {
00801 mViewManager->currentView()->updateView();
00802 if ( mTodoList ) mTodoList->updateView();
00803 }
00804 }
00805
00806
00807 void CalendarView::updateView(const QDate &start, const QDate &end)
00808 {
00809 mTodoList->updateView();
00810 mViewManager->updateView(start, end);
00811 mDateNavigator->updateView();
00812 }
00813
00814 void CalendarView::updateView()
00815 {
00816 DateList tmpList = mNavigator->selectedDates();
00817
00818
00819 updateView( tmpList.first(), tmpList.last() );
00820 }
00821
00822 void CalendarView::updateUnmanagedViews()
00823 {
00824 mDateNavigator->updateDayMatrix();
00825 }
00826
00827 int CalendarView::msgItemDelete( Incidence *incidence )
00828 {
00829 return KMessageBox::warningContinueCancel(this,
00830 i18n("The item \"%1\" will be permanently deleted.").arg( incidence->summary() ),
00831 i18n("KOrganizer Confirmation"), KGuiItem(i18n("&Delete"),"editdelete"));
00832 }
00833
00834
00835 void CalendarView::edit_cut()
00836 {
00837 Incidence *incidence = selectedIncidence();
00838
00839 if ( !incidence || !mChanger ) {
00840 KNotifyClient::beep();
00841 return;
00842 }
00843 mChanger->cutIncidence( incidence );
00844 }
00845
00846 void CalendarView::edit_copy()
00847 {
00848 Incidence *incidence = selectedIncidence();
00849
00850 if (!incidence) {
00851 KNotifyClient::beep();
00852 return;
00853 }
00854 DndFactory factory( mCalendar );
00855 if ( !factory.copyIncidence( incidence ) ) {
00856 KNotifyClient::beep();
00857 }
00858 }
00859
00860 void CalendarView::edit_paste()
00861 {
00862
00863
00864
00865
00866 QDate date;
00867
00868 QTime time(-1,-1);
00869 QDateTime startDT, endDT;
00870 bool useEndTime = false;
00871
00872 KOAgendaView *aView = mViewManager->agendaView();
00873 if (aView && aView->selectionStart().isValid()) {
00874 date = aView->selectionStart().date();
00875 startDT = aView->selectionStart();
00876 endDT = aView->selectionEnd();
00877 useEndTime = !aView->selectedIsSingleCell();
00878 if (!aView->selectedIsAllDay()) {
00879 time = aView->selectionStart().time();
00880 }
00881
00882 } else {
00883 date = mNavigator->selectedDates().first();
00884 }
00885
00886 DndFactory factory( mCalendar );
00887 Incidence *pastedIncidence;
00888 if (time.isValid())
00889 pastedIncidence = factory.pasteIncidence( date, &time );
00890 else
00891 pastedIncidence = factory.pasteIncidence( date );
00892 if ( !pastedIncidence ) return;
00893
00894
00895 if (pastedIncidence->type() == "Event" ) {
00896
00897 Event* pastedEvent = static_cast<Event*>(pastedIncidence);
00898
00899
00900 if ( aView && endDT.isValid() && useEndTime ) {
00901 if ( (pastedEvent->doesFloat() && aView->selectedIsAllDay()) ||
00902 (!pastedEvent->doesFloat() && ! aView->selectedIsAllDay()) ) {
00903 pastedEvent->setDtEnd(endDT);
00904 }
00905 }
00906 mChanger->addIncidence( pastedEvent );
00907
00908 } else if ( pastedIncidence->type() == "Todo" ) {
00909 Todo* pastedTodo = static_cast<Todo*>(pastedIncidence);
00910 Todo* _selectedTodo = selectedTodo();
00911 if ( _selectedTodo )
00912 pastedTodo->setRelatedTo( _selectedTodo );
00913 mChanger->addIncidence( pastedTodo );
00914 }
00915 }
00916
00917 void CalendarView::edit_options()
00918 {
00919 mDialogManager->showOptionsDialog();
00920 }
00921
00922
00923 void CalendarView::newEvent()
00924 {
00925 kdDebug(5850) << "CalendarView::newEvent()" << endl;
00926 QDate date = mNavigator->selectedDates().first();
00927 QTime startTime = KOPrefs::instance()->mStartTime.time();
00928 QDateTime startDt( date, startTime );
00929 int addSecs = ( KOPrefs::instance()->mDefaultDuration.time().hour()*3600 ) +
00930 ( KOPrefs::instance()->mDefaultDuration.time().minute()*60 );
00931 QDateTime endDt = ( startDt.addSecs( addSecs ) );
00932 bool allDay = false;
00933
00934
00935 mViewManager->currentView()->eventDurationHint( startDt, endDt, allDay );
00936
00937 if ( allDay ) {
00938 newEvent( startDt, endDt, true );
00939 } else {
00940 newEvent( startDt, endDt );
00941 }
00942 }
00943
00944 void CalendarView::newEvent( const QDateTime &fh )
00945 {
00946 int addSecs = ( KOPrefs::instance()->mDefaultDuration.time().hour()*3600 ) +
00947 ( KOPrefs::instance()->mDefaultDuration.time().minute()*60 );
00948 QDateTime endTime ( fh.addSecs( addSecs ) );
00949 newEvent( fh, endTime );
00950 }
00951
00952 void CalendarView::newEvent( const QDate &dt )
00953 {
00954 QTime startTime = KOPrefs::instance()->mStartTime.time();
00955 int addSecs = ( KOPrefs::instance()->mDefaultDuration.time().hour()*3600 ) +
00956 ( KOPrefs::instance()->mDefaultDuration.time().minute()*60 );
00957 QTime endTime ( startTime.addSecs( addSecs ) );
00958 newEvent(QDateTime(dt, startTime),
00959 QDateTime(dt, endTime), true);
00960 }
00961
00962 void CalendarView::newEvent( const QString &text )
00963 {
00964 KOEventEditor *eventEditor = mDialogManager->getEventEditor();
00965 connectIncidenceEditor( eventEditor );
00966 eventEditor->newEvent( text );
00967 mDialogManager->connectTypeAhead( eventEditor, viewManager()->agendaView() );
00968 eventEditor->show();
00969 }
00970
00971 void CalendarView::newEvent( const QString &summary, const QString &description,
00972 const QString &attachment )
00973 {
00974 KOEventEditor *eventEditor = mDialogManager->getEventEditor();
00975 connectIncidenceEditor( eventEditor );
00976 eventEditor->newEvent( summary, description, attachment );
00977 eventEditor->show();
00978 }
00979
00980 void CalendarView::newEvent( const QString &summary, const QString &description,
00981 const QString &attachment, const QStringList &attendees )
00982 {
00983 KOEventEditor *eventEditor = mDialogManager->getEventEditor();
00984 connectIncidenceEditor( eventEditor );
00985 eventEditor->newEvent( summary, description, attachment, attendees );
00986 eventEditor->show();
00987 }
00988
00989 void CalendarView::newEvent( const QDateTime &fromHint, const QDateTime &toHint,
00990 bool allDay)
00991 {
00992 KOEventEditor *eventEditor = mDialogManager->getEventEditor();
00993 connectIncidenceEditor( eventEditor );
00994 eventEditor->newEvent(fromHint,toHint,allDay);
00995 mDialogManager->connectTypeAhead( eventEditor, viewManager()->agendaView() );
00996 eventEditor->show();
00997 }
00998
00999 void CalendarView::newTodo( const QString &text )
01000 {
01001 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01002 connectIncidenceEditor( todoEditor );
01003 todoEditor->newTodo( text );
01004 todoEditor->show();
01005 }
01006
01007 void CalendarView::newTodo( const QString &summary, const QString &description,
01008 const QString &attachment )
01009 {
01010 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01011 connectIncidenceEditor( todoEditor );
01012 todoEditor->newTodo( summary, description, attachment );
01013 todoEditor->show();
01014 }
01015
01016 void CalendarView::newTodo( const QString &summary, const QString &description,
01017 const QString &attachment, const QStringList &attendees )
01018 {
01019 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01020 connectIncidenceEditor( todoEditor );
01021 todoEditor->newTodo( summary, description, attachment, attendees );
01022 todoEditor->show();
01023 }
01024
01025 void CalendarView::newTodo()
01026 {
01027 kdDebug(5850) << "CalendarView::newTodo()" << endl;
01028 QDateTime dtDue;
01029 bool allday = true;
01030 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01031 connectIncidenceEditor( todoEditor );
01032 if ( mViewManager->currentView()->isEventView() ) {
01033 dtDue.setDate( mNavigator->selectedDates().first() );
01034 QDateTime dtDummy = QDateTime::currentDateTime();
01035 mViewManager->currentView()->
01036 eventDurationHint( dtDue , dtDummy , allday );
01037 }
01038 else
01039 dtDue = QDateTime::currentDateTime().addDays( 7 );
01040 todoEditor->newTodo(dtDue,0,allday);
01041 todoEditor->show();
01042 }
01043
01044 void CalendarView::newTodo( const QDate &date )
01045 {
01046 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01047 connectIncidenceEditor( todoEditor );
01048 todoEditor->newTodo( QDateTime( date, QTime::currentTime() ), 0, true );
01049 todoEditor->show();
01050 }
01051
01052 void CalendarView::newJournal()
01053 {
01054 kdDebug(5850) << "CalendarView::newJournal()" << endl;
01055 QDate date = mNavigator->selectedDates().first();
01056 newJournal( date );
01057 }
01058
01059 void CalendarView::newJournal( const QDate &date )
01060 {
01061 KOJournalEditor *journalEditor = mDialogManager->getJournalEditor();
01062 connectIncidenceEditor( journalEditor );
01063 journalEditor->newJournal( date );
01064 journalEditor->show();
01065 }
01066
01067 void CalendarView::newJournal( const QString &text, const QDate &date )
01068 {
01069 KOJournalEditor *journalEditor = mDialogManager->getJournalEditor();
01070 connectIncidenceEditor( journalEditor );
01071 journalEditor->newJournal( text, date );
01072 journalEditor->show();
01073 }
01074
01075 void CalendarView::newJournal( const QString &text )
01076 {
01077 KOJournalEditor *journalEditor = mDialogManager->getJournalEditor();
01078 connectIncidenceEditor( journalEditor );
01079 journalEditor->newJournal( text );
01080 journalEditor->show();
01081 }
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 void CalendarView::newSubTodo()
01095 {
01096 Todo *todo = selectedTodo();
01097 if ( todo ) newSubTodo( todo );
01098 }
01099
01100 void CalendarView::newSubTodo(Todo *parentEvent)
01101 {
01102 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01103 connectIncidenceEditor( todoEditor );
01104 todoEditor->newTodo(QDateTime::currentDateTime().addDays(7),parentEvent,true);
01105 todoEditor->show();
01106 }
01107
01108 void CalendarView::newFloatingEvent()
01109 {
01110 DateList tmpList = mNavigator->selectedDates();
01111 QDate date = tmpList.first();
01112
01113 newEvent( QDateTime( date, QTime( 12, 0, 0 ) ),
01114 QDateTime( date, QTime( 12, 0, 0 ) ), true );
01115 }
01116
01117 bool CalendarView::addIncidence( const QString &ical )
01118 {
01119 kdDebug(5850) << "CalendarView::addIncidence:\n" << ical << endl;
01120 ICalFormat format;
01121 format.setTimeZone( mCalendar->timeZoneId(), true );
01122 Incidence *incidence = format.fromString( ical );
01123 if ( !incidence ) return false;
01124 if ( !mChanger->addIncidence( incidence ) ) {
01125 delete incidence;
01126 return false;
01127 }
01128 return true;
01129 }
01130
01131 void CalendarView::appointment_show()
01132 {
01133 Incidence *incidence = selectedIncidence();
01134 if (incidence)
01135 showIncidence( incidence );
01136 else
01137 KNotifyClient::beep();
01138 }
01139
01140 void CalendarView::appointment_edit()
01141 {
01142 Incidence *incidence = selectedIncidence();
01143 if (incidence)
01144 editIncidence( incidence );
01145 else
01146 KNotifyClient::beep();
01147 }
01148
01149 void CalendarView::appointment_delete()
01150 {
01151 Incidence *incidence = selectedIncidence();
01152 if (incidence)
01153 deleteIncidence( incidence );
01154 else
01155 KNotifyClient::beep();
01156 }
01157
01158 void CalendarView::todo_unsub()
01159 {
01160 Todo *anTodo = selectedTodo();
01161 if( todo_unsub (anTodo ) ) {
01162 updateView();
01163 }
01164 }
01165
01166 bool CalendarView::todo_unsub( Todo *todo )
01167 {
01168 bool status= false;
01169 if ( !todo || !todo->relatedTo() ) return false;
01170
01171 if ( mChanger->beginChange( todo ) ) {
01172 Todo *oldTodo = todo->clone();
01173 todo->setRelatedTo(0);
01174 mChanger->changeIncidence( oldTodo, todo, KOGlobals::RELATION_MODIFIED );
01175 mChanger->endChange( todo );
01176 delete oldTodo;
01177 setModified(true);
01178 status = true;
01179 }
01180 if ( ! status ) {
01181 KMessageBox::sorry( this, i18n("Unable to turn sub-to-do into a top-level "
01182 "to-do, because it cannot be locked.") );
01183 }
01184
01185 return status;
01186 }
01187
01188 bool CalendarView::makeSubTodosIndependents ( )
01189 {
01190 bool status = false;
01191 Todo *anTodo = selectedTodo();
01192
01193 if( makeSubTodosIndependents( anTodo ) ) {
01194 updateView();
01195 status = true;
01196 }
01197 return status;
01198 }
01199
01200 bool CalendarView::makeSubTodosIndependents ( Todo *todo )
01201 {
01202 if( !todo || todo->relations().isEmpty() ) return false;
01203
01204 startMultiModify ( i18n( "Make sub-to-dos independent" ) );
01205 Incidence::List subTodos( todo->relations() );
01206 Incidence::List::Iterator it;
01207 Incidence *aIncidence;
01208 Todo *aTodo;
01209
01210 for ( it= subTodos.begin(); it != subTodos.end(); ++it ) {
01211 aIncidence = *it;
01212 if( aIncidence && aIncidence->type() == "Todo" ) {
01213 aTodo = static_cast<Todo*>( aIncidence );
01214 todo_unsub ( aTodo );
01215 }
01216 }
01217 endMultiModify();
01218 return true;
01219 }
01220
01221 bool CalendarView::deleteIncidence( const QString &uid, bool force )
01222 {
01223 Incidence *inc = mCalendar->incidence( uid );
01224 if ( inc ) {
01225 deleteIncidence( inc, force );
01226 return true;
01227 } else {
01228 return false;
01229 }
01230 }
01231
01232 void CalendarView::toggleAlarm( Incidence *incidence )
01233 {
01234 if ( !incidence || !mChanger ) {
01235 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01236 return;
01237 }
01238 Incidence*oldincidence = incidence->clone();
01239 if ( !mChanger->beginChange( incidence ) ) {
01240 kdDebug(5850) << "Unable to lock incidence " << endl;
01241 delete oldincidence;
01242 return;
01243 }
01244
01245 Alarm::List alarms = incidence->alarms();
01246 Alarm::List::ConstIterator it;
01247 for( it = alarms.begin(); it != alarms.end(); ++it )
01248 (*it)->toggleAlarm();
01249 if (alarms.isEmpty()) {
01250
01251 Alarm*alm = incidence->newAlarm();
01252 alm->setEnabled(true);
01253 }
01254 mChanger->changeIncidence( oldincidence, incidence, KOGlobals::ALARM_MODIFIED );
01255 mChanger->endChange( incidence );
01256 delete oldincidence;
01257
01258
01259 }
01260
01261 void CalendarView::dissociateOccurrence( Incidence *incidence, const QDate &date )
01262 {
01263 if ( !incidence || !mChanger ) {
01264 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01265 return;
01266 }
01267 if ( !mChanger->beginChange( incidence ) ) {
01268 kdDebug(5850) << "Unable to lock incidence " << endl;
01269 return;
01270 }
01271 startMultiModify( i18n("Dissociate occurrence") );
01272 Incidence*oldincidence = incidence->clone();
01273
01274 Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
01275
01276 if ( newInc ) {
01277 mChanger->changeIncidence( oldincidence, incidence );
01278 mChanger->addIncidence( newInc );
01279 } else {
01280 KMessageBox::sorry( this, i18n("Dissociating the occurrence failed."),
01281 i18n("Dissociating Failed") );
01282 }
01283 mChanger->endChange( incidence );
01284 endMultiModify();
01285 delete oldincidence;
01286 }
01287
01288 void CalendarView::dissociateFutureOccurrence( Incidence *incidence, const QDate &date )
01289 {
01290 if ( !incidence || !mChanger ) {
01291 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01292 return;
01293 }
01294 if ( !mChanger->beginChange( incidence ) ) {
01295 kdDebug(5850) << "Unable to lock incidence " << endl;
01296 return;
01297 }
01298 startMultiModify( i18n("Dissociate future occurrences") );
01299 Incidence*oldincidence = incidence->clone();
01300
01301 Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
01302 if ( newInc ) {
01303 mChanger->changeIncidence( oldincidence, incidence );
01304 mChanger->addIncidence( newInc );
01305 } else {
01306 KMessageBox::sorry( this, i18n("Dissociating the future occurrences failed."),
01307 i18n("Dissociating Failed") );
01308 }
01309 endMultiModify();
01310 mChanger->endChange( incidence );
01311 delete oldincidence;
01312 }
01313
01314
01315
01316
01317
01318 void CalendarView::schedule_publish(Incidence *incidence)
01319 {
01320 if (incidence == 0)
01321 incidence = selectedIncidence();
01322
01323 if (!incidence) {
01324 KMessageBox::information( this, i18n("No item selected."),
01325 "PublishNoEventSelected" );
01326 return;
01327 }
01328
01329 PublishDialog *publishdlg = new PublishDialog();
01330 if (incidence->attendeeCount()>0) {
01331 Attendee::List attendees = incidence->attendees();
01332 Attendee::List::ConstIterator it;
01333 for( it = attendees.begin(); it != attendees.end(); ++it ) {
01334 publishdlg->addAttendee( *it );
01335 }
01336 }
01337 if ( publishdlg->exec() == QDialog::Accepted ) {
01338 Incidence *inc = incidence->clone();
01339 inc->registerObserver( 0 );
01340 inc->clearAttendees();
01341
01342
01343 KCal::MailScheduler scheduler( mCalendar );
01344 if ( scheduler.publish( incidence, publishdlg->addresses() ) ) {
01345 KMessageBox::information( this, i18n("The item information was successfully sent."),
01346 i18n("Publishing"), "IncidencePublishSuccess" );
01347 } else {
01348 KMessageBox::error( this, i18n("Unable to publish the item '%1'").arg( incidence->summary() ) );
01349 }
01350 }
01351 delete publishdlg;
01352 }
01353
01354 void CalendarView::schedule_request(Incidence *incidence)
01355 {
01356 schedule(Scheduler::Request,incidence);
01357 }
01358
01359 void CalendarView::schedule_refresh(Incidence *incidence)
01360 {
01361 schedule(Scheduler::Refresh,incidence);
01362 }
01363
01364 void CalendarView::schedule_cancel(Incidence *incidence)
01365 {
01366 schedule(Scheduler::Cancel,incidence);
01367 }
01368
01369 void CalendarView::schedule_add(Incidence *incidence)
01370 {
01371 schedule(Scheduler::Add,incidence);
01372 }
01373
01374 void CalendarView::schedule_reply(Incidence *incidence)
01375 {
01376 schedule(Scheduler::Reply,incidence);
01377 }
01378
01379 void CalendarView::schedule_counter(Incidence *incidence)
01380 {
01381 schedule(Scheduler::Counter,incidence);
01382 }
01383
01384 void CalendarView::schedule_declinecounter(Incidence *incidence)
01385 {
01386 schedule(Scheduler::Declinecounter,incidence);
01387 }
01388
01389 void CalendarView::mailFreeBusy( int daysToPublish )
01390 {
01391 QDateTime start = QDateTime::currentDateTime();
01392 QDateTime end = start.addDays(daysToPublish);
01393
01394 FreeBusy *freebusy = new FreeBusy(mCalendar, start, end);
01395 freebusy->setOrganizer( Person( KOPrefs::instance()->fullName(),
01396 KOPrefs::instance()->email() ) );
01397
01398 kdDebug(5850) << "calendarview: schedule_publish_freebusy: startDate: "
01399 << KGlobal::locale()->formatDateTime( start ) << " End Date: "
01400 << KGlobal::locale()->formatDateTime( end ) << endl;
01401
01402 PublishDialog *publishdlg = new PublishDialog();
01403 if ( publishdlg->exec() == QDialog::Accepted ) {
01404
01405 KCal::MailScheduler scheduler( mCalendar );
01406 if ( scheduler.publish( freebusy, publishdlg->addresses() ) ) {
01407 KMessageBox::information( this, i18n("The free/busy information was successfully sent."),
01408 i18n("Sending Free/Busy"), "FreeBusyPublishSuccess" );
01409 } else {
01410 KMessageBox::error( this, i18n("Unable to publish the free/busy data.") );
01411 }
01412 }
01413 delete freebusy;
01414 delete publishdlg;
01415 }
01416
01417 void CalendarView::uploadFreeBusy()
01418 {
01419 KOGroupware::instance()->freeBusyManager()->publishFreeBusy();
01420 }
01421
01422 void CalendarView::schedule(Scheduler::Method method, Incidence *incidence)
01423 {
01424 if ( !incidence ) {
01425 incidence = selectedIncidence();
01426 }
01427
01428 if ( !incidence ) {
01429 KMessageBox::sorry( this, i18n("No item selected."),
01430 "ScheduleNoEventSelected" );
01431 return;
01432 }
01433
01434 if( incidence->attendeeCount() == 0 && method != Scheduler::Publish ) {
01435 KMessageBox::information( this, i18n("The item has no attendees."),
01436 "ScheduleNoIncidences" );
01437 return;
01438 }
01439
01440 Incidence *inc = incidence->clone();
01441 inc->registerObserver( 0 );
01442 inc->clearAttendees();
01443
01444
01445 KCal::MailScheduler scheduler( mCalendar );
01446 if ( !scheduler.performTransaction( incidence, method ) ) {
01447 KMessageBox::information( this, i18n("The groupware message for item '%1'"
01448 "was successfully sent.\nMethod: %2")
01449 .arg( incidence->summary() )
01450 .arg( Scheduler::methodName( method ) ),
01451 i18n("Sending Free/Busy"),
01452 "FreeBusyPublishSuccess" );
01453 } else {
01454 KMessageBox::error( this, i18n("Groupware message sending failed. "
01455 "%2 is request/reply/add/cancel/counter/etc.",
01456 "Unable to send the item '%1'.\nMethod: %2")
01457 .arg( incidence->summary() )
01458 .arg( Scheduler::methodName( method ) ) );
01459 }
01460 }
01461
01462 void CalendarView::openAddressbook()
01463 {
01464 KRun::runCommand("kaddressbook");
01465 }
01466
01467 void CalendarView::setModified(bool modified)
01468 {
01469 if (mModified != modified) {
01470 mModified = modified;
01471 emit modifiedChanged(mModified);
01472 }
01473 }
01474
01475 bool CalendarView::isReadOnly()
01476 {
01477 return mReadOnly;
01478 }
01479
01480 void CalendarView::setReadOnly(bool readOnly)
01481 {
01482 if (mReadOnly != readOnly) {
01483 mReadOnly = readOnly;
01484 emit readOnlyChanged(mReadOnly);
01485 }
01486 }
01487
01488 bool CalendarView::isModified()
01489 {
01490 return mModified;
01491 }
01492
01493 void CalendarView::print()
01494 {
01495 #ifndef KORG_NOPRINTER
01496 createPrinter();
01497
01498 KOrg::BaseView *currentView = mViewManager->currentView();
01499
01500 CalPrinter::PrintType printType = CalPrinter::Month;
01501
01502 if ( currentView ) printType = currentView->printType();
01503
01504 DateList tmpDateList = mNavigator->selectedDates();
01505 mCalPrinter->print( printType, tmpDateList.first(), tmpDateList.last() );
01506 #endif
01507 }
01508
01509 void CalendarView::exportWeb()
01510 {
01511
01512 HTMLExportSettings *settings = new HTMLExportSettings( "KOrganizer" );
01513
01514
01515 if ( settings ) settings->readConfig();
01516 ExportWebDialog *dlg = new ExportWebDialog( settings, this );
01517 connect( dlg, SIGNAL( exportHTML( HTMLExportSettings* ) ),
01518 this, SIGNAL( exportHTML( HTMLExportSettings* ) ) );
01519 dlg->show();
01520 }
01521
01522 void CalendarView::exportICalendar()
01523 {
01524 QString filename = KFileDialog::getSaveFileName("icalout.ics",i18n("*.ics|ICalendars"),this);
01525
01526
01527 if (filename.right(4) != ".ics") filename += ".ics";
01528
01529 FileStorage storage( mCalendar, filename, new ICalFormat );
01530 storage.save();
01531 }
01532
01533 void CalendarView::exportVCalendar()
01534 {
01535 if (mCalendar->journals().count() > 0) {
01536 int result = KMessageBox::warningContinueCancel(this,
01537 i18n("The journal entries can not be exported to a vCalendar file."),
01538 i18n("Data Loss Warning"),i18n("Proceed"),"dontaskVCalExport",
01539 true);
01540 if (result != KMessageBox::Continue) return;
01541 }
01542
01543 QString filename = KFileDialog::getSaveFileName("vcalout.vcs",i18n("*.vcs|vCalendars"),this);
01544
01545
01546
01547 if (filename.right(4) != ".vcs") filename += ".vcs";
01548
01549 FileStorage storage( mCalendar, filename, new VCalFormat );
01550 storage.save();
01551 }
01552
01553 void CalendarView::eventUpdated(Incidence *)
01554 {
01555 setModified();
01556
01557
01558
01559 }
01560
01561 void CalendarView::adaptNavigationUnits()
01562 {
01563 if (mViewManager->currentView()->isEventView()) {
01564 int days = mViewManager->currentView()->currentDateCount();
01565 if (days == 1) {
01566 emit changeNavStringPrev(i18n("&Previous Day"));
01567 emit changeNavStringNext(i18n("&Next Day"));
01568 } else {
01569 emit changeNavStringPrev(i18n("&Previous Week"));
01570 emit changeNavStringNext(i18n("&Next Week"));
01571 }
01572 }
01573 }
01574
01575 void CalendarView::processMainViewSelection( Incidence *incidence )
01576 {
01577 if ( incidence ) mTodoList->clearSelection();
01578 processIncidenceSelection( incidence );
01579 }
01580
01581 void CalendarView::processTodoListSelection( Incidence *incidence )
01582 {
01583 if ( incidence && mViewManager->currentView() ) {
01584 mViewManager->currentView()->clearSelection();
01585 }
01586 processIncidenceSelection( incidence );
01587 }
01588
01589 void CalendarView::processIncidenceSelection( Incidence *incidence )
01590 {
01591 if ( incidence == mSelectedIncidence ) return;
01592
01593 mSelectedIncidence = incidence;
01594
01595 emit incidenceSelected( mSelectedIncidence );
01596 bool organizerEvents = false;
01597 bool groupEvents = false;
01598 bool todo = false;
01599 bool subtodo = false;
01600
01601 if ( incidence ) {
01602 organizerEvents = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
01603 groupEvents = incidence->attendeeByMails( KOPrefs::instance()->allEmails() );
01604
01605 if ( incidence && incidence->type() == "Todo" ) {
01606 todo = true;
01607 subtodo = ( incidence->relatedTo() != 0 );
01608 }
01609 }
01610 emit todoSelected( todo );
01611 emit subtodoSelected( subtodo );
01612 emit organizerEventsSelected( organizerEvents );
01613 emit groupEventsSelected( groupEvents );
01614 }
01615
01616
01617 void CalendarView::checkClipboard()
01618 {
01619 #ifndef KORG_NODND
01620 if (ICalDrag::canDecode(QApplication::clipboard()->data())) {
01621 kdDebug(5850) << "CalendarView::checkClipboard() true" << endl;
01622 emit pasteEnabled(true);
01623 } else {
01624 kdDebug(5850) << "CalendarView::checkClipboard() false" << endl;
01625 emit pasteEnabled(false);
01626 }
01627 #endif
01628 }
01629
01630 void CalendarView::showDates(const DateList &selectedDates)
01631 {
01632
01633
01634 if ( mViewManager->currentView() ) {
01635 updateView( selectedDates.first(), selectedDates.last() );
01636 } else {
01637 mViewManager->showAgendaView();
01638 }
01639 }
01640
01641 void CalendarView::editFilters()
01642 {
01643 kdDebug(5850) << "CalendarView::editFilters()" << endl;
01644
01645 CalFilter *filter = mFilters.first();
01646 while(filter) {
01647 kdDebug(5850) << " Filter: " << filter->name() << endl;
01648 filter = mFilters.next();
01649 }
01650
01651 mDialogManager->showFilterEditDialog(&mFilters);
01652 }
01653
01656 void CalendarView::updateFilter()
01657 {
01658 QStringList filters;
01659 CalFilter *filter;
01660
01661 int pos = mFilters.find( mCurrentFilter );
01662 if ( pos < 0 ) {
01663 mCurrentFilter = 0;
01664 }
01665
01666 filters << i18n("No filter");
01667 for ( filter = mFilters.first(); filter; filter = mFilters.next() ) {
01668 filters << filter->name();
01669 }
01670
01671 emit newFilterListSignal( filters );
01672
01673
01674 emit selectFilterSignal( pos+1 );
01675 mCalendar->setFilter( mCurrentFilter );
01676 updateView();
01677 }
01678
01681 void CalendarView::filterActivated( int filterNo )
01682 {
01683 CalFilter *newFilter = 0;
01684 if ( filterNo > 0 && filterNo <= int(mFilters.count()) ) {
01685 newFilter = mFilters.at( filterNo-1 );
01686 }
01687 if ( newFilter != mCurrentFilter ) {
01688 mCurrentFilter = newFilter;
01689 mCalendar->setFilter( mCurrentFilter );
01690 updateView();
01691 }
01692 emit filterChanged();
01693 }
01694
01695 QString CalendarView::currentFilterName() const
01696 {
01697 if ( mCurrentFilter) {
01698 return mCurrentFilter->name();
01699 } else return i18n("No filter");
01700 }
01701
01702 void CalendarView::takeOverEvent()
01703 {
01704 Incidence *incidence = currentSelection();
01705
01706 if (!incidence) return;
01707
01708 incidence->setOrganizer( Person( KOPrefs::instance()->fullName(),
01709 KOPrefs::instance()->email() ) );
01710 incidence->recreate();
01711 incidence->setReadOnly(false);
01712
01713 updateView();
01714 }
01715
01716 void CalendarView::takeOverCalendar()
01717 {
01718 Incidence::List incidences = mCalendar->rawIncidences();
01719 Incidence::List::Iterator it;
01720
01721 for ( it = incidences.begin(); it != incidences.end(); ++it ) {
01722 (*it)->setOrganizer( Person( KOPrefs::instance()->fullName(),
01723 KOPrefs::instance()->email() ) );
01724 (*it)->recreate();
01725 (*it)->setReadOnly(false);
01726 }
01727 updateView();
01728 }
01729
01730 void CalendarView::showIntro()
01731 {
01732 kdDebug(5850) << "To be implemented." << endl;
01733 }
01734
01735 void CalendarView::showDateNavigator( bool show )
01736 {
01737 if( show )
01738 mDateNavigator->show();
01739 else
01740 mDateNavigator->hide();
01741 }
01742
01743 void CalendarView::showTodoView( bool show )
01744 {
01745 if( show )
01746 mTodoList->show();
01747 else
01748 mTodoList->hide();
01749 }
01750
01751 void CalendarView::showEventViewer( bool show )
01752 {
01753 if( show )
01754 mEventViewer->show();
01755 else
01756 mEventViewer->hide();
01757 }
01758
01759
01760 void CalendarView::addView(KOrg::BaseView *view)
01761 {
01762 mViewManager->addView(view);
01763 }
01764
01765 void CalendarView::showView(KOrg::BaseView *view)
01766 {
01767 mViewManager->showView(view);
01768 }
01769
01770 void CalendarView::addExtension( CalendarViewExtension::Factory *factory )
01771 {
01772 CalendarViewExtension *extension = factory->create( mLeftSplitter );
01773
01774 mExtensions.append( extension );
01775 }
01776
01777 void CalendarView::toggleExpand()
01778 {
01779 showLeftFrame( mLeftFrame->isHidden() );
01780 }
01781
01782 void CalendarView::showLeftFrame(bool show)
01783 {
01784 if (show) {
01785 mLeftFrame->show();
01786 emit calendarViewExpanded( false );
01787 } else {
01788 mLeftFrame->hide();
01789 emit calendarViewExpanded( true );
01790 }
01791 }
01792
01793 void CalendarView::calendarModified( bool modified, Calendar * )
01794 {
01795 setModified( modified );
01796 }
01797
01798 Todo *CalendarView::selectedTodo()
01799 {
01800 Incidence *incidence = currentSelection();
01801 if ( incidence && incidence->type() == "Todo" ) {
01802 return static_cast<Todo *>( incidence );
01803 }
01804 incidence = 0;
01805
01806 Incidence::List selectedIncidences = mTodoList->selectedIncidences();
01807 if ( !selectedIncidences.isEmpty() ) incidence = selectedIncidences.first();
01808 if ( incidence && incidence->type() == "Todo" ) {
01809 return static_cast<Todo *>( incidence );
01810 }
01811
01812 return 0;
01813 }
01814
01815 void CalendarView::dialogClosing( Incidence *in )
01816 {
01817
01818 mChanger->endChange( in );
01819 mDialogList.remove( in );
01820 }
01821
01822 Incidence *CalendarView::currentSelection()
01823 {
01824 return mViewManager->currentSelection();
01825 }
01826
01827 Incidence* CalendarView::selectedIncidence()
01828 {
01829 Incidence *incidence = currentSelection();
01830 if ( !incidence ) {
01831 Incidence::List selectedIncidences = mTodoList->selectedIncidences();
01832 if ( !selectedIncidences.isEmpty() )
01833 incidence = selectedIncidences.first();
01834 }
01835 return incidence;
01836 }
01837
01838 void CalendarView::showIncidence()
01839 {
01840 showIncidence( selectedIncidence() );
01841 }
01842
01843 void CalendarView::editIncidence()
01844 {
01845 editIncidence( selectedIncidence() );
01846 }
01847
01848 bool CalendarView::editIncidence( const QString& uid )
01849 {
01850 kdDebug(5850) << "CalendarView::editIncidence()" << endl;
01851 return editIncidence( mCalendar->incidence( uid ) );
01852 }
01853
01854 void CalendarView::deleteIncidence()
01855 {
01856 deleteIncidence( selectedIncidence() );
01857 }
01858
01859 void CalendarView::cutIncidence(Incidence *)
01860 {
01861 edit_cut();
01862 }
01863
01864 void CalendarView::copyIncidence(Incidence *)
01865 {
01866 edit_copy();
01867 }
01868
01869 void CalendarView::showIncidence( Incidence *incidence )
01870 {
01871 KOEventViewerDialog *eventViewer = new KOEventViewerDialog( this );
01872 eventViewer->setIncidence( incidence );
01873 eventViewer->show();
01874 }
01875
01876 bool CalendarView::editIncidence( Incidence *incidence )
01877 {
01878 kdDebug(5850) << "CalendarView::editEvent()" << endl;
01879
01880 if ( !incidence || !mChanger ) {
01881 KNotifyClient::beep();
01882 return false;
01883 }
01884 KOIncidenceEditor *tmp = editorDialog( incidence );
01885 if ( tmp ) {
01886 kdDebug(5850) << "CalendarView::editIncidence() in List" << endl;
01887 tmp->reload();
01888 tmp->raise();
01889 tmp->show();
01890 return true;
01891 }
01892
01893 if ( incidence->isReadOnly() ) {
01894 showIncidence( incidence );
01895 return true;
01896 }
01897
01898 if ( !mChanger->beginChange( incidence ) ) {
01899 warningChangeFailed( incidence );
01900 showIncidence( incidence );
01901 return false;
01902 }
01903
01904 kdDebug(5850) << "CalendarView::editIncidence() new IncidenceEditor" << endl;
01905 KOIncidenceEditor *incidenceEditor = mDialogManager->getEditor( incidence );
01906 connectIncidenceEditor( incidenceEditor );
01907
01908 mDialogList.insert( incidence, incidenceEditor );
01909 incidenceEditor->editIncidence( incidence );
01910 incidenceEditor->show();
01911 return true;
01912 }
01913
01914 void CalendarView::deleteSubTodosIncidence ( Todo *todo )
01915 {
01916 if( !todo ) return;
01917
01918 Incidence::List subTodos( todo->relations() );
01919 Incidence::List::Iterator it;
01920 Incidence *aIncidence;
01921 Todo *aTodo;
01922
01923 for ( it= subTodos.begin(); it != subTodos.end(); ++it ) {
01924 aIncidence = *it;
01925 if( aIncidence && aIncidence->type() == "Todo" ) {
01926 aTodo = static_cast<Todo*>( aIncidence );
01927 deleteSubTodosIncidence ( aTodo );
01928 }
01929 }
01930 mChanger->deleteIncidence ( todo );
01931 }
01932
01933 void CalendarView::deleteTodoIncidence ( Todo *todo, bool force )
01934 {
01935 if ( !todo ) return ;
01936
01937
01938 if (todo->relations().isEmpty() ) {
01939 bool doDelete = true;
01940 if ( !force && KOPrefs::instance()->mConfirm ) {
01941 doDelete = ( msgItemDelete( todo ) == KMessageBox::Continue );
01942 }
01943 if ( doDelete )
01944 mChanger->deleteIncidence( todo );
01945 return;
01946 }
01947
01948
01949 int km = KMessageBox::No;
01950 if ( !force ) {
01951 km=KMessageBox::questionYesNoCancel( this,
01952 i18n("The item \"%1\" has sub-to-dos. "
01953 "Do you want to delete just this item and "
01954 "make all its sub-to-dos independent, or "
01955 "delete the to-do with all its sub-to-dos?"
01956 ).arg( todo->summary() ),
01957 i18n("KOrganizer Confirmation"),
01958 i18n("Delete Only This"),
01959 i18n("Delete All"));
01960 }
01961 startMultiModify( i18n("Deleting sub-to-dos" ) );
01962
01963 if( km == KMessageBox::Yes ) {
01964
01965 makeSubTodosIndependents ( todo );
01966 mChanger->deleteIncidence( todo );
01967 } else if ( km == KMessageBox::No ) {
01968
01969
01970 deleteSubTodosIncidence ( todo );
01971 }
01972 endMultiModify();
01973 }
01974
01975 void CalendarView::deleteIncidence(Incidence *incidence, bool force)
01976 {
01977 if ( !incidence || !mChanger ) {
01978 if ( !force ) {
01979 KNotifyClient::beep();
01980 }
01981 return;
01982 }
01983 if ( incidence->isReadOnly() ) {
01984 if ( !force ) {
01985 KMessageBox::information( this, i18n("The item \"%1\" is marked read-only "
01986 "and cannot be deleted; it probably belongs to "
01987 "a read-only calendar resource.")
01988 .arg(incidence->summary()),
01989 i18n("Removing not possible"),
01990 "deleteReadOnlyIncidence" );
01991 }
01992 return;
01993 }
01994
01995 CanDeleteIncidenceVisitor v;
01996
01997
01998
01999 if ( !v.act( incidence, this ) )
02000 return;
02001
02002
02003 if ( incidence && incidence->type()=="Todo" ) {
02004 deleteTodoIncidence( static_cast<Todo*>(incidence), force );
02005 return;
02006 }
02007
02008 if ( incidence->doesRecur() ) {
02009 QDate itemDate = mViewManager->currentSelectionDate();
02010 kdDebug(5850) << "Recurrence-Date: " << itemDate.toString() << endl;
02011 int km = KMessageBox::Ok;
02012 if ( !force ) {
02013 if ( !itemDate.isValid() ) {
02014 kdDebug(5850) << "Date Not Valid" << endl;
02015 km = KMessageBox::warningContinueCancel(this,
02016 i18n("The calendar item \"%1\" recurs over multiple dates; "
02017 "are you sure you want to delete it "
02018 "and all its recurrences?").arg( incidence->summary() ),
02019 i18n("KOrganizer Confirmation"), i18n("Delete All") );
02020 } else {
02021 km = KOMessageBox::fourBtnMsgBox( this, QMessageBox::Warning,
02022 i18n("The calendar item \"%1\" recurs over multiple dates. "
02023 "Do you want to delete only the current one on %2, only all "
02024 "future recurrences, or all its recurrences?" )
02025 .arg( incidence->summary() )
02026 .arg( KGlobal::locale()->formatDate(itemDate)),
02027 i18n("KOrganizer Confirmation"), i18n("Delete C&urrent"),
02028 i18n("Delete &Future"),
02029 i18n("Delete &All"));
02030 }
02031 }
02032 switch(km) {
02033 case KMessageBox::Ok:
02034 case KMessageBox::Continue:
02035 mChanger->deleteIncidence( incidence );
02036 break;
02037
02038 case KMessageBox::Yes:
02039 if ( mChanger->beginChange( incidence ) ) {
02040 Incidence *oldIncidence = incidence->clone();
02041 incidence->recurrence()->addExDate( itemDate );
02042 mChanger->changeIncidence( oldIncidence, incidence );
02043 mChanger->endChange( incidence );
02044 delete oldIncidence;
02045 }
02046 break;
02047 case KMessageBox::No:
02048 if ( mChanger->beginChange( incidence ) ) {
02049 Incidence *oldIncidence = incidence->clone();
02050 Recurrence *recur = incidence->recurrence();
02051 recur->setEndDate( itemDate.addDays(-1) );
02052 mChanger->changeIncidence( oldIncidence, incidence );
02053 mChanger->endChange( incidence );
02054 delete oldIncidence;
02055 }
02056 break;
02057 }
02058 } else {
02059 bool doDelete = true;
02060 if ( !force && KOPrefs::instance()->mConfirm ) {
02061 doDelete = ( msgItemDelete( incidence ) == KMessageBox::Continue );
02062 }
02063 if ( doDelete ) {
02064 mChanger->deleteIncidence( incidence );
02065 processIncidenceSelection( 0 );
02066 }
02067 }
02068 }
02069
02070 void CalendarView::connectIncidenceEditor( KOIncidenceEditor *editor )
02071 {
02072 connect( this, SIGNAL( newIncidenceChanger( IncidenceChangerBase* ) ),
02073 editor, SLOT( setIncidenceChanger( IncidenceChangerBase* ) ) );
02074 editor->setIncidenceChanger( mChanger );
02075 }
02076
02077 bool CalendarView::purgeCompletedSubTodos( Todo* todo, bool &allPurged )
02078 {
02079 if ( !todo ) return true;
02080 bool deleteThisTodo = true;
02081 Incidence::List subTodos( todo->relations() );
02082 Incidence *aIncidence;
02083 Todo *aTodo;
02084 Incidence::List::Iterator it;
02085 for ( it = subTodos.begin(); it != subTodos.end(); ++it ) {
02086 aIncidence = *it;
02087 if ( aIncidence && aIncidence->type()=="Todo" ) {
02088 aTodo = static_cast<Todo*>( aIncidence );
02089 deleteThisTodo &= purgeCompletedSubTodos( aTodo, allPurged );
02090 }
02091 }
02092
02093 if ( deleteThisTodo ) {
02094 if ( todo->isCompleted() ) {
02095 if ( !mChanger->deleteIncidence( todo ) )
02096 allPurged = false;
02097 } else {
02098 deleteThisTodo = false;
02099 }
02100 } else {
02101 if ( todo->isCompleted() ) {
02102 allPurged = false;
02103 }
02104 }
02105 return deleteThisTodo;
02106 }
02107
02108 void CalendarView::purgeCompleted()
02109 {
02110 int result = KMessageBox::warningContinueCancel(this,
02111 i18n("Delete all completed to-dos?"),i18n("Purge To-dos"),i18n("Purge"));
02112
02113 if (result == KMessageBox::Continue) {
02114 bool allDeleted = true;
02115 startMultiModify( i18n("Purging completed to-dos") );
02116 Todo::List todos = calendar()->rawTodos();
02117 Todo::List rootTodos;
02118 Todo::List::ConstIterator it;
02119 for ( it = todos.begin(); it != todos.end(); ++it ) {
02120 Todo *aTodo = *it;
02121 if ( aTodo && !aTodo->relatedTo() )
02122 rootTodos.append( aTodo );
02123 }
02124
02125 for ( it = rootTodos.begin(); it != rootTodos.end(); ++it ) {
02126 purgeCompletedSubTodos( *it, allDeleted );
02127 }
02128 endMultiModify();
02129 if ( !allDeleted ) {
02130 KMessageBox::information( this, i18n("Unable to purge to-dos with "
02131 "uncompleted children."), i18n("Delete To-do"),
02132 "UncompletedChildrenPurgeTodos" );
02133 }
02134 }
02135 }
02136
02137 void CalendarView::slotCalendarChanged()
02138 {
02139 kdDebug(5850) << "CalendarView::slotCalendarChanged()" << endl;
02140
02141 updateView();
02142 }
02143
02144 void CalendarView::importQtopia( const QString &categories,
02145 const QString &datebook,
02146 const QString &todolist )
02147 {
02148 QtopiaFormat qtopiaFormat;
02149 if ( !categories.isEmpty() ) qtopiaFormat.load( mCalendar, categories );
02150 if ( !datebook.isEmpty() ) qtopiaFormat.load( mCalendar, datebook );
02151 if ( !todolist.isEmpty() ) qtopiaFormat.load( mCalendar, todolist );
02152 updateView();
02153 }
02154
02155 void CalendarView::warningChangeFailed( Incidence * )
02156 {
02157 KMessageBox::sorry( this, i18n("Unable to edit item: "
02158 "it is locked by another process.") );
02159 }
02160
02161 void CalendarView::editCanceled( Incidence *i )
02162 {
02163 mCalendar->endChange( i );
02164 }
02165
02166 void CalendarView::showErrorMessage( const QString &msg )
02167 {
02168 KMessageBox::error( this, msg );
02169 }
02170
02171 void CalendarView::updateCategories()
02172 {
02173 QStringList allCats( calendar()->categories() );
02174 allCats.sort();
02175 QStringList categories( KOPrefs::instance()->mCustomCategories );
02176 for ( QStringList::ConstIterator si = allCats.constBegin(); si != allCats.constEnd(); ++si ) {
02177 if ( categories.find( *si ) == categories.end() ) {
02178 categories.append( *si );
02179 }
02180 }
02181 KOPrefs::instance()->mCustomCategories = categories;
02182 KOPrefs::instance()->writeConfig();
02183
02184 emit categoriesChanged();
02185 }
02186
02187 void CalendarView::addIncidenceOn( Incidence *incadd, const QDate &dt )
02188 {
02189 if ( !incadd || !mChanger ) {
02190 KMessageBox::sorry(this, i18n("Unable to copy the item to %1.")
02191 .arg( dt.toString() ), i18n("Copying Failed") );
02192 return;
02193 }
02194 Incidence *incidence = mCalendar->incidence( incadd->uid() );
02195 if ( !incidence ) incidence = incadd;
02196
02197 incidence = incidence->clone();
02198 incidence->recreate();
02199
02200 if ( incidence->type() == "Event" ) {
02201 Event *event = static_cast<Event*>(incidence);
02202
02203
02204 QDateTime start = event->dtStart();
02205 QDateTime end = event->dtEnd();
02206
02207 int duration = start.daysTo( end );
02208 start.setDate( dt );
02209 end.setDate( dt.addDays( duration ) );
02210
02211 event->setDtStart( start );
02212 event->setDtEnd( end );
02213
02214 } else if ( incidence->type() == "Todo" ) {
02215 Todo *todo = static_cast<Todo*>(incidence);
02216 QDateTime due = todo->dtDue();
02217 due.setDate( dt );
02218
02219 todo->setDtDue( due );
02220 todo->setHasDueDate( true );
02221 }
02222
02223 if ( !mChanger->addIncidence( incidence ) ) {
02224 KODialogManager::errorSaveIncidence( this, incidence );
02225 delete incidence;
02226 }
02227 }
02228
02229 void CalendarView::moveIncidenceTo( Incidence *incmove, const QDate &dt )
02230 {
02231 if ( !incmove || !mChanger ) {
02232 KMessageBox::sorry( this, i18n("Unable to move the item to %1.")
02233 .arg( dt.toString() ), i18n("Moving Failed") );
02234 return;
02235 }
02236 Incidence *incidence = mCalendar->incidence( incmove->uid() );
02237 if ( !incidence ) {
02238 addIncidenceOn( incidence, dt );
02239 return;
02240 }
02241 Incidence *oldIncidence = incidence->clone();
02242 if ( !mChanger->beginChange( incidence ) ) {
02243 delete oldIncidence;
02244 return;
02245 }
02246
02247 if ( incidence->type() == "Event" ) {
02248 Event *event = static_cast<Event*>(incidence);
02249
02250
02251 QDateTime start = event->dtStart();
02252 QDateTime end = event->dtEnd();
02253
02254 int duration = start.daysTo( end );
02255 start.setDate( dt );
02256 end.setDate( dt.addDays( duration ) );
02257
02258 event->setDtStart( start );
02259 event->setDtEnd( end );
02260
02261 } else if ( incidence->type() == "Todo" ) {
02262 Todo *todo = static_cast<Todo*>(incidence);
02263 QDateTime due = todo->dtDue();
02264 due.setDate( dt );
02265
02266 todo->setDtDue( due );
02267 todo->setHasDueDate( true );
02268 }
02269 mChanger->changeIncidence( oldIncidence, incidence );
02270 mChanger->endChange( incidence );
02271 delete oldIncidence;
02272 }
02273
02274 #include "calendarview.moc"