korganizer Library API Documentation

calendarview.cpp

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