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