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