korganizer Library API Documentation

calendarview.cpp

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