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