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