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