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