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"),i18n("Delete"));
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 
00761 void CalendarView::edit_paste()
00762 {
00763 // If in agenda view, use the selected time and date from there.
00764 // In all other cases, paste the event on the first day of the
00765 // selection in the day matrix on the left
00766 
00767   QDate date;
00768   // create an invalid time to check if we got a new time for the eevent
00769   QTime time(-1,-1);
00770   QDateTime startDT, endDT;
00771   bool useEndTime = false;
00772 
00773   KOAgendaView *aView = mViewManager->agendaView();
00774   if (aView && aView->selectionStart().isValid()) {
00775       date = aView->selectionStart().date();
00776     startDT = aView->selectionStart();
00777     endDT = aView->selectionEnd();
00778     useEndTime = !aView->selectedIsSingleCell();
00779     if (!aView->selectedIsAllDay()) {
00780         time = aView->selectionStart().time();
00781     }
00782 
00783   } else {
00784     date = mNavigator->selectedDates().first();
00785   }
00786 
00787   DndFactory factory( mCalendar );
00788   Incidence *pastedIncidence;
00789   if (time.isValid())
00790     pastedIncidence = factory.pasteIncidence( date, &time );
00791   else
00792     pastedIncidence = factory.pasteIncidence( date );
00793   if ( !pastedIncidence ) return;
00794 
00795   if (pastedIncidence->type() == "Event" ) {
00796 
00797     Event* pastedEvent = static_cast<Event*>(pastedIncidence);
00798     // only use selected area if event is of the same type (all-day or non-all-day
00799     // as the current selection is
00800     if ( aView && endDT.isValid() && useEndTime ) {
00801       if ( (pastedEvent->doesFloat() && aView->selectedIsAllDay()) ||
00802            (!pastedEvent->doesFloat() && ! aView->selectedIsAllDay()) ) {
00803         pastedEvent->setDtEnd(endDT);
00804       }
00805     }
00806     eventAdded( pastedEvent );
00807 
00808   } else if ( pastedIncidence->type() == "Todo" ) {
00809     Todo* pastedTodo = static_cast<Todo*>(pastedIncidence);
00810     todoAdded( pastedTodo );
00811   }
00812 }
00813 
00814 void CalendarView::edit_options()
00815 {
00816   mDialogManager->showOptionsDialog();
00817 }
00818 
00819 
00820 void CalendarView::newEvent()
00821 {
00822   kdDebug() << "CalendarView::newEvent()" << endl;
00823 
00824   // TODO: Replace this code by a common eventDurationHint of KOBaseView.
00825   KOAgendaView *aView = mViewManager->agendaView();
00826   if (aView) {
00827     if (aView->selectionStart().isValid()) {
00828       if (aView->selectedIsAllDay()) {
00829         newEvent(aView->selectionStart(),aView->selectionEnd(),true);
00830       } else {
00831         newEvent(aView->selectionStart(),aView->selectionEnd());
00832       }
00833       return;
00834     }
00835   }
00836 
00837   QDate date = mNavigator->selectedDates().first();
00838 
00839   newEvent( QDateTime( date, QTime( KOPrefs::instance()->mStartTime, 0, 0 ) ),
00840             QDateTime( date, QTime( KOPrefs::instance()->mStartTime +
00841                        KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) );
00842 }
00843 
00844 void CalendarView::newEvent(QDateTime fh)
00845 {
00846   newEvent(fh,
00847            QDateTime(fh.addSecs(3600*KOPrefs::instance()->mDefaultDuration)));
00848 }
00849 
00850 void CalendarView::newEvent(QDate dt)
00851 {
00852   newEvent(QDateTime(dt, QTime(0,0,0)),
00853            QDateTime(dt, QTime(0,0,0)), true);
00854 }
00855 
00856 void CalendarView::newEvent( const QString &text )
00857 {
00858   KOEventEditor *eventEditor = mDialogManager->getEventEditor();
00859   eventEditor->newEvent( text );
00860   mDialogManager->connectTypeAhead( eventEditor, viewManager()->agendaView() );
00861   eventEditor->show();
00862 }
00863 
00864 void CalendarView::newEvent( const QString &summary, const QString &description,
00865                              const QString &attachment )
00866 {
00867   KOEventEditor *eventEditor = mDialogManager->getEventEditor();
00868   eventEditor->newEvent( summary, description, attachment );
00869   eventEditor->show();
00870 }
00871 
00872 void CalendarView::newTodo( const QString &text )
00873 {
00874   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
00875   todoEditor->newTodo( text );
00876   todoEditor->show();
00877 }
00878 
00879 void CalendarView::newTodo( const QString &summary, const QString &description,
00880                              const QString &attachment )
00881 {
00882   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
00883   todoEditor->newTodo( summary, description, attachment );
00884   todoEditor->show();
00885 }
00886 
00887 void CalendarView::newEvent(QDateTime fromHint, QDateTime toHint, bool allDay)
00888 {
00889   KOEventEditor *eventEditor = mDialogManager->getEventEditor();
00890   eventEditor->newEvent(fromHint,toHint,allDay);
00891   mDialogManager->connectTypeAhead( eventEditor, viewManager()->agendaView() );
00892   eventEditor->show();
00893 }
00894 
00895 void CalendarView::newTodo()
00896 {
00897   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
00898   todoEditor->newTodo(QDateTime::currentDateTime().addDays(7),0,true);
00899   todoEditor->show();
00900 }
00901 
00902 void CalendarView::newSubTodo()
00903 {
00904   Todo *todo = selectedTodo();
00905   if ( todo ) newSubTodo( todo );
00906 }
00907 
00908 void CalendarView::newSubTodo(Todo *parentEvent)
00909 {
00910   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
00911   todoEditor->newTodo(QDateTime::currentDateTime().addDays(7),parentEvent,true);
00912   todoEditor->show();
00913 }
00914 
00915 void CalendarView::newFloatingEvent()
00916 {
00917   DateList tmpList = mNavigator->selectedDates();
00918   QDate date = tmpList.first();
00919 
00920   newEvent( QDateTime( date, QTime( 12, 0, 0 ) ),
00921             QDateTime( date, QTime( 12, 0, 0 ) ), true );
00922 }
00923 
00924 
00925 void CalendarView::editEvent( Event *event )
00926 {
00927   kdDebug(5850) << "CalendarView::editEvent()" << endl;
00928 
00929   if ( !event ) return;
00930 
00931   if ( mDialogList.find( event ) != mDialogList.end() ) {
00932     kdDebug(5850) << "CalendarView::editEvent() in List" << endl;
00933     mDialogList[ event ]->reload();
00934     mDialogList[ event ]->raise();
00935     mDialogList[ event ]->show();
00936     return;
00937   }
00938 
00939   if ( event->isReadOnly() ) {
00940     showEvent( event );
00941     return;
00942   }
00943 
00944   if ( !mCalendar->beginChange( event ) ) {
00945     warningChangeFailed( event );
00946     return;
00947   }
00948 
00949   kdDebug(5850) << "CalendarView::editEvent() new EventEditor" << endl;
00950   KOEventEditor *eventEditor = mDialogManager->getEventEditor();
00951   mDialogList.insert( event, eventEditor );
00952   eventEditor->editEvent( event );
00953   eventEditor->show();
00954 }
00955 
00956 void CalendarView::editTodo( Todo *todo )
00957 {
00958   if ( !todo ) return;
00959   kdDebug(5850) << "CalendarView::editTodo" << endl;
00960 
00961   if ( mDialogList.find( todo ) != mDialogList.end() ) {
00962     kdDebug(5850) << "Already in the list " << endl;
00963     mDialogList[todo]->reload();
00964     mDialogList[todo]->raise();
00965     mDialogList[todo]->show();
00966     return;
00967   }
00968 
00969   if ( todo->isReadOnly() ) {
00970     showTodo( todo );
00971     return;
00972   }
00973 
00974   if ( !mCalendar->beginChange( todo ) ) {
00975     warningChangeFailed( todo );
00976     return;
00977   }
00978 
00979   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
00980   kdDebug(5850) << "New editor" << endl;
00981   mDialogList.insert( todo, todoEditor );
00982   todoEditor->editTodo( todo );
00983   todoEditor->show();
00984 }
00985 
00986 void CalendarView::showEvent(Event *event)
00987 {
00988   KOEventViewerDialog *eventViewer = new KOEventViewerDialog(this);
00989   eventViewer->setEvent(event);
00990   eventViewer->show();
00991 }
00992 
00993 void CalendarView::showTodo(Todo *event)
00994 {
00995   KOEventViewerDialog *eventViewer = new KOEventViewerDialog(this);
00996   eventViewer->setTodo(event);
00997   eventViewer->show();
00998 }
00999 
01000 void CalendarView::todoModified (Todo *event, Todo *oldEvent, int changed)
01001 {
01002   if (mDialogList.find (event) != mDialogList.end ()) {
01003     kdDebug(5850) << "Todo modified and open" << endl;
01004     KOTodoEditor* temp = (KOTodoEditor *) mDialogList[event];
01005     temp->modified (changed);
01006   }
01007   if (oldEvent) todoChanged( oldEvent, event );
01008 
01009   mViewManager->updateView();
01010 }
01011 
01012 void CalendarView::appointment_show()
01013 {
01014   Incidence *incidence = selectedIncidence();
01015   if (incidence)
01016     showIncidence( incidence );
01017   else
01018     KNotifyClient::beep();
01019 }
01020 
01021 void CalendarView::appointment_edit()
01022 {
01023   Incidence *incidence = selectedIncidence();
01024   if (incidence)
01025     editIncidence( incidence );
01026   else
01027     KNotifyClient::beep();
01028 }
01029 
01030 void CalendarView::appointment_delete()
01031 {
01032   Incidence *incidence = selectedIncidence();
01033   if (incidence)
01034     deleteIncidence( incidence );
01035   else
01036     KNotifyClient::beep();
01037 }
01038 
01039 void CalendarView::todo_unsub()
01040 {
01041   Todo *anTodo = selectedTodo();
01042   if (!anTodo) return;
01043   if (!anTodo->relatedTo()) return;
01044   Todo *oldTodo = anTodo->clone();
01045   anTodo->relatedTo()->removeRelation(anTodo);
01046   anTodo->setRelatedTo(0);
01047   anTodo->setRelatedToUid("");
01048   todoChanged( oldTodo, anTodo );
01049   delete oldTodo;
01050   setModified(true);
01051   updateView();
01052 }
01053 
01054 void CalendarView::deleteTodo(Todo *todo)
01055 {
01056   if (!todo) {
01057     KNotifyClient::beep();
01058     return;
01059   }
01060   if (KOPrefs::instance()->mConfirm && (!KOPrefs::instance()->mUseGroupwareCommunication ||
01061                                         KOPrefs::instance()->email() == todo->organizer())) {
01062     switch (msgItemDelete()) {
01063       case KMessageBox::Continue: // OK
01064         if (!todo->relations().isEmpty()) {
01065           KMessageBox::sorry(this,i18n("Cannot delete To-Do which has children."),
01066                          i18n("Delete To-Do"));
01067         } else {
01068           bool doDelete = true;
01069           if( KOPrefs::instance()->mUseGroupwareCommunication ) {
01070             doDelete = KOGroupware::instance()->sendICalMessage( this, KCal::Scheduler::Cancel, todo, true );
01071           }
01072           if( doDelete ) {
01073             calendar()->deleteTodo(todo);
01074             todoDeleted( todo );
01075           }
01076         }
01077         break;
01078     } // switch
01079   } else {
01080     if (!todo->relations().isEmpty()) {
01081         KMessageBox::sorry(this,i18n("Cannot delete To-Do which has children."),
01082                          i18n("Delete To-Do"));
01083     } else {
01084             bool doDelete = true;
01085       if( KOPrefs::instance()->mUseGroupwareCommunication ) {
01086         doDelete = KOGroupware::instance()->sendICalMessage( this, KCal::Scheduler::Cancel, todo, true );
01087       }
01088       if( doDelete ) {
01089         calendar()->deleteTodo(todo);
01090         todoDeleted( todo );
01091       }
01092     }
01093   }
01094 }
01095 
01096 void CalendarView::deleteEvent(Event *anEvent)
01097 {
01098   if (!anEvent) {
01099     KNotifyClient::beep();
01100     return;
01101   }
01102 
01103   if (anEvent->doesRecur()) {
01104     QDate itemDate = mViewManager->currentSelectionDate();
01105     kdDebug(5850) << "Recurrence-Date: " << itemDate.toString() << endl;
01106     int km;
01107     if (!itemDate.isValid()) {
01108       kdDebug(5850) << "Date Not Valid" << endl;
01109       km = KMessageBox::warningContinueCancel(this,
01110         i18n("This event recurs over multiple dates. "
01111              "Are you sure you want to delete this event "
01112              "and all its recurrences?"),
01113              i18n("KOrganizer Confirmation"),i18n("Delete All"));
01114     } else {
01115       km = KMessageBox::warningYesNoCancel(this,
01116         i18n("This event recurs over multiple dates. "
01117              "Do you want to delete all it's recurrences, "
01118              "or only the current one on %1?" )
01119              .arg( KGlobal::locale()->formatDate(itemDate)),
01120              i18n("KOrganizer Confirmation"),i18n("Delete Current"),
01121              i18n("Delete All"));
01122     }
01123     bool doDelete = true;
01124     switch(km) {
01125       case KMessageBox::No: // Continue // all
01126       case KMessageBox::Continue:
01127         eventToBeDeleted( anEvent );
01128         if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0
01129             && !KOPrefs::instance()->mUseGroupwareCommunication) {
01130           schedule(Scheduler::Cancel,anEvent);
01131         } else if( KOPrefs::instance()->mUseGroupwareCommunication ) {
01132           doDelete = KOGroupware::instance()->sendICalMessage( this, KCal::Scheduler::Cancel, anEvent, true );
01133         }
01134         if( doDelete ) {
01135           mCalendar->deleteEvent(anEvent);
01136           eventDeleted( anEvent );
01137         }
01138         break;
01139 
01140 // Disabled because it does not work (doesn't seem to be true anymore)
01141 #if 1
01142       case KMessageBox::Yes: // just this one
01143         //QDate qd = mNavigator->selectedDates().first();
01144         //if (!qd.isValid()) {
01145         //  kdDebug(5850) << "no date selected, or invalid date" << endl;
01146         //  KNotifyClient::beep();
01147         //  return;
01148         //}
01149         //while (!anEvent->recursOn(qd)) qd = qd.addDays(1);
01150         if (itemDate!=QDate(1,1,1) || itemDate.isValid()) {
01151           Event*oldEvent = anEvent->clone();
01152           anEvent->addExDate(itemDate);
01153           int duration = anEvent->recurrence()->duration();
01154           if ( duration > 0 ) {
01155             anEvent->recurrence()->setDuration( duration - 1 );
01156           }
01157           eventChanged( oldEvent, anEvent );
01158         }
01159         break;
01160 #endif
01161     }
01162   } else {
01163     if (KOPrefs::instance()->mConfirm && (!KOPrefs::instance()->mUseGroupwareCommunication ||
01164                                           KOPrefs::instance()->email() == anEvent->organizer())) {
01165       bool doDelete = true;
01166       switch (msgItemDelete()) {
01167         case KMessageBox::Continue: // OK
01168           eventToBeDeleted( anEvent );
01169           if ( anEvent->organizer() == KOPrefs::instance()->email() &&
01170                anEvent->attendeeCount() > 0 &&
01171                !KOPrefs::instance()->mUseGroupwareCommunication ) {
01172             schedule( Scheduler::Cancel,anEvent );
01173           } else if( KOPrefs::instance()->mUseGroupwareCommunication ) {
01174             doDelete = KOGroupware::instance()->sendICalMessage( this, KCal::Scheduler::Cancel, anEvent, true );
01175           }
01176           if( doDelete ) {
01177             mCalendar->deleteEvent( anEvent );
01178             eventDeleted( anEvent );
01179           }
01180           break;
01181       }
01182     } else {
01183       eventToBeDeleted( anEvent );
01184       bool doDelete = true;
01185       if ( anEvent->organizer() == KOPrefs::instance()->email() &&
01186            anEvent->attendeeCount() > 0 &&
01187            !KOPrefs::instance()->mUseGroupwareCommunication ) {
01188         schedule(Scheduler::Cancel,anEvent);
01189       }else if( KOPrefs::instance()->mUseGroupwareCommunication ) {
01190         doDelete = KOGroupware::instance()->sendICalMessage( this, KCal::Scheduler::Cancel, anEvent, true );
01191       }
01192       if( doDelete ) {
01193         mCalendar->deleteEvent( anEvent );
01194         eventDeleted( anEvent );
01195       }
01196     }
01197   }
01198 }
01199 
01200 bool CalendarView::deleteEvent(const QString &uid)
01201 {
01202     Event *ev = mCalendar->event(uid);
01203     if (ev) {
01204         deleteEvent(ev);
01205         return true;
01206     } else {
01207         return false;
01208     }
01209 }
01210 
01211 /*****************************************************************************/
01212 
01213 void CalendarView::action_mail()
01214 {
01215 #ifndef KORG_NOMAIL
01216   KOMailClient mailClient;
01217 
01218   Incidence *incidence = currentSelection();
01219 
01220   if (!incidence) {
01221     KMessageBox::sorry(this,i18n("Can't generate mail:\nNo event selected."));
01222     return;
01223   }
01224   if(incidence->attendeeCount() == 0 ) {
01225     KMessageBox::sorry(this,
01226                        i18n("Can't generate mail:\nNo attendees defined.\n"));
01227     return;
01228   }
01229 
01230   CalendarLocal cal_tmp;
01231   Event *event = 0;
01232   Event *ev = 0;
01233   if ( incidence && incidence->type() == "Event" ) {
01234     event = static_cast<Event *>(incidence);
01235     ev = new Event(*event);
01236     cal_tmp.addEvent(ev);
01237   }
01238   ICalFormat mForm;
01239   QString attachment = mForm.toString( &cal_tmp );
01240   delete(ev);
01241 
01242   mailClient.mailAttendees(currentSelection(), attachment);
01243 
01244 #endif
01245 
01246 #if 0
01247   Event *anEvent = 0;
01248   if (mViewManager->currentView()->isEventView()) {
01249     anEvent = dynamic_cast<Event *>((mViewManager->currentView()->selectedIncidences()).first());
01250   }
01251 
01252   if (!anEvent) {
01253     KMessageBox::sorry(this,i18n("Can't generate mail:\nNo event selected."));
01254     return;
01255   }
01256   if(anEvent->attendeeCount() == 0 ) {
01257     KMessageBox::sorry(this,
01258                        i18n("Can't generate mail:\nNo attendees defined.\n"));
01259     return;
01260   }
01261 
01262   mailobject.emailEvent(anEvent);
01263 #endif
01264 }
01265 
01266 
01267 void CalendarView::schedule_publish(Incidence *incidence)
01268 {
01269   Event *event = 0;
01270   Todo *todo = 0;
01271   if (incidence == 0)
01272     incidence = selectedIncidence();
01273 
01274   if ( incidence && incidence->type() == "Event" ) {
01275     event = static_cast<Event *>(incidence);
01276   } else {
01277     if ( incidence && incidence->type() == "Todo" ) {
01278       todo = static_cast<Todo *>(incidence);
01279     }
01280   }
01281 
01282   if (!event && !todo) {
01283     KMessageBox::sorry(this,i18n("No event selected."));
01284     return;
01285   }
01286 
01287   PublishDialog *publishdlg = new PublishDialog();
01288   if (incidence->attendeeCount()>0) {
01289     Attendee::List attendees = incidence->attendees();
01290     Attendee::List::ConstIterator it;
01291     for( it = attendees.begin(); it != attendees.end(); ++it ) {
01292       publishdlg->addAttendee( *it );
01293     }
01294   }
01295   bool send = true;
01296   if ( KOPrefs::instance()->mMailClient == KOPrefs::MailClientSendmail ) {
01297     if ( publishdlg->exec() != QDialog::Accepted )
01298       send = false;
01299   }
01300   if ( send ) {
01301     OutgoingDialog *dlg = mDialogManager->outgoingDialog();
01302     if ( event ) {
01303       Event *ev = new Event(*event);
01304       ev->registerObserver(0);
01305       ev->clearAttendees();
01306       if (!dlg->addMessage(ev,Scheduler::Publish,publishdlg->addresses())) {
01307         delete(ev);
01308       }
01309     } else  if ( todo ) {
01310       Todo *ev = new Todo(*todo);
01311       ev->registerObserver(0);
01312       ev->clearAttendees();
01313       if (!dlg->addMessage(ev,Scheduler::Publish,publishdlg->addresses())) {
01314         delete(ev);
01315       }
01316     }
01317   }
01318   delete publishdlg;
01319 }
01320 
01321 void CalendarView::schedule_request(Incidence *incidence)
01322 {
01323   schedule(Scheduler::Request,incidence);
01324 }
01325 
01326 void CalendarView::schedule_refresh(Incidence *incidence)
01327 {
01328   schedule(Scheduler::Refresh,incidence);
01329 }
01330 
01331 void CalendarView::schedule_cancel(Incidence *incidence)
01332 {
01333   schedule(Scheduler::Cancel,incidence);
01334 }
01335 
01336 void CalendarView::schedule_add(Incidence *incidence)
01337 {
01338   schedule(Scheduler::Add,incidence);
01339 }
01340 
01341 void CalendarView::schedule_reply(Incidence *incidence)
01342 {
01343   schedule(Scheduler::Reply,incidence);
01344 }
01345 
01346 void CalendarView::schedule_counter(Incidence *incidence)
01347 {
01348   schedule(Scheduler::Counter,incidence);
01349 }
01350 
01351 void CalendarView::schedule_declinecounter(Incidence *incidence)
01352 {
01353   schedule(Scheduler::Declinecounter,incidence);
01354 }
01355 
01356 void CalendarView::schedule_publish_freebusy(int daysToPublish)
01357 {
01358   QDateTime start = QDateTime::currentDateTime();
01359   QDateTime end = start.addDays(daysToPublish);
01360 
01361   FreeBusy *freebusy = new FreeBusy(mCalendar, start, end);
01362   freebusy->setOrganizer(KOPrefs::instance()->email());
01363 
01364   kdDebug(5850) << "calendarview: schedule_publish_freebusy: startDate: "
01365      << KGlobal::locale()->formatDateTime( start ) << " End Date: "
01366      << KGlobal::locale()->formatDateTime( end ) << endl;
01367 
01368   PublishDialog *publishdlg = new PublishDialog();
01369   if ( publishdlg->exec() == QDialog::Accepted ) {
01370     OutgoingDialog *dlg = mDialogManager->outgoingDialog();
01371     if (!dlg->addMessage(freebusy,Scheduler::Publish,publishdlg->addresses())) {
01372          delete(freebusy);
01373     }
01374   }
01375   delete publishdlg;
01376 }
01377 
01378 void CalendarView::schedule(Scheduler::Method method, Incidence *incidence)
01379 {
01380   Event *event = 0;
01381   Todo *todo = 0;
01382   if (incidence == 0) {
01383     incidence = selectedIncidence();
01384   }
01385   if ( incidence && incidence->type() == "Event" ) {
01386     event = static_cast<Event *>(incidence);
01387   }
01388   if ( incidence && incidence->type() == "Todo" ) {
01389     todo = static_cast<Todo *>(incidence);
01390   }
01391 
01392   if (!event && !todo) {
01393     KMessageBox::sorry(this,i18n("No event selected."));
01394     return;
01395   }
01396 
01397   if( incidence->attendeeCount() == 0 && method != Scheduler::Publish ) {
01398     KMessageBox::sorry(this,i18n("The event has no attendees."));
01399     return;
01400   }
01401 
01402   Event *ev = 0;
01403   if (event) ev = new Event(*event);
01404   Todo *to = 0;
01405   if (todo) to = new Todo(*todo);
01406 
01407   if (method == Scheduler::Reply || method == Scheduler::Refresh) {
01408     Attendee *me = incidence->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email());
01409     if (!me) {
01410       KMessageBox::sorry(this,i18n("Could not find your attendee entry. Please check the emails."));
01411       return;
01412     }
01413     if (me->status()==Attendee::NeedsAction && me->RSVP() && method==Scheduler::Reply) {
01414       StatusDialog *statdlg = new StatusDialog(this);
01415       if (!statdlg->exec()==QDialog::Accepted) return;
01416       me->setStatus( statdlg->status() );
01417       delete(statdlg);
01418     }
01419     Attendee *menew = new Attendee(*me);
01420     if (ev) {
01421       ev->clearAttendees();
01422       ev->addAttendee(menew,false);
01423     } else {
01424       if (to) {
01425         todo->clearAttendees();
01426         todo->addAttendee(menew,false);
01427       }
01428     }
01429   }
01430 
01431   OutgoingDialog *dlg = mDialogManager->outgoingDialog();
01432   if (ev) {
01433     if ( !dlg->addMessage(ev,method) ) delete(ev);
01434     if (to) delete(to);
01435   } else {
01436     if (to) {
01437       if ( !dlg->addMessage(to,method) ) delete(to);
01438     }
01439   }
01440 }
01441 
01442 void CalendarView::openAddressbook()
01443 {
01444   KRun::runCommand("kaddressbook");
01445 }
01446 
01447 void CalendarView::setModified(bool modified)
01448 {
01449   if (mModified != modified) {
01450     mModified = modified;
01451     emit modifiedChanged(mModified);
01452   }
01453 }
01454 
01455 bool CalendarView::isReadOnly()
01456 {
01457   return mReadOnly;
01458 }
01459 
01460 void CalendarView::setReadOnly(bool readOnly)
01461 {
01462   if (mReadOnly != readOnly) {
01463     mReadOnly = readOnly;
01464     emit readOnlyChanged(mReadOnly);
01465   }
01466 }
01467 
01468 bool CalendarView::isModified()
01469 {
01470   return mModified;
01471 }
01472 
01473 void CalendarView::printSetup()
01474 {
01475 #ifndef KORG_NOPRINTER
01476   createPrinter();
01477 
01478   mCalPrinter->setupPrinter();
01479 #endif
01480 }
01481 
01482 void CalendarView::print()
01483 {
01484 #ifndef KORG_NOPRINTER
01485   createPrinter();
01486 
01487   KOrg::BaseView *currentView = mViewManager->currentView();
01488   
01489   CalPrinter::PrintType printType = CalPrinter::Month;
01490   
01491   if ( currentView ) printType = currentView->printType();
01492 
01493   DateList tmpDateList = mNavigator->selectedDates();
01494   mCalPrinter->print( printType, tmpDateList.first(), tmpDateList.last() );
01495 #endif
01496 }
01497 
01498 void CalendarView::printPreview()
01499 {
01500 #ifndef KORG_NOPRINTER
01501   kdDebug(5850) << "CalendarView::printPreview()" << endl;
01502 
01503   createPrinter();
01504 
01505   DateList tmpDateList = mNavigator->selectedDates();
01506 
01507   mViewManager->currentView()->printPreview( mCalPrinter, tmpDateList.first(),
01508                                              tmpDateList.last() );
01509 #endif
01510 }
01511 
01512 void CalendarView::exportICalendar()
01513 {
01514   QString filename = KFileDialog::getSaveFileName("icalout.ics",i18n("*.ics|ICalendars"),this);
01515 
01516   // Force correct extension
01517   if (filename.right(4) != ".ics") filename += ".ics";
01518 
01519   FileStorage storage( mCalendar, filename, new ICalFormat );
01520   storage.save();
01521 }
01522 
01523 void CalendarView::exportVCalendar()
01524 {
01525   if (mCalendar->journals().count() > 0) {
01526     int result = KMessageBox::warningContinueCancel(this,
01527         i18n("The journal entries can not be exported to a vCalendar file."),
01528         i18n("Data Loss Warning"),i18n("Proceed"),"dontaskVCalExport",
01529         true);
01530     if (result != KMessageBox::Continue) return;
01531   }
01532 
01533   QString filename = KFileDialog::getSaveFileName("vcalout.vcs",i18n("*.vcs|VCalendars"),this);
01534 
01535   // Force correct extension
01536   if (filename.right(4) != ".vcs") filename += ".vcs";
01537 
01538   FileStorage storage( mCalendar, filename, new VCalFormat );
01539   storage.save();
01540 }
01541 
01542 void CalendarView::eventUpdated(Incidence *)
01543 {
01544   setModified();
01545   // Don't call updateView here. The code, which has caused the update of the
01546   // event is responsible for updating the view.
01547 //  updateView();
01548 }
01549 
01550 void CalendarView::adaptNavigationUnits()
01551 {
01552   if (mViewManager->currentView()->isEventView()) {
01553     int days = mViewManager->currentView()->currentDateCount();
01554     if (days == 1) {
01555       emit changeNavStringPrev(i18n("&Previous Day"));
01556       emit changeNavStringNext(i18n("&Next Day"));
01557     } else {
01558       emit changeNavStringPrev(i18n("&Previous Week"));
01559       emit changeNavStringNext(i18n("&Next Week"));
01560     }
01561   }
01562 }
01563 
01564 void CalendarView::processMainViewSelection( Incidence *incidence )
01565 {
01566   if ( incidence ) mTodoList->clearSelection();
01567   processIncidenceSelection( incidence );
01568 }
01569 
01570 void CalendarView::processTodoListSelection( Incidence *incidence )
01571 {
01572   if ( incidence && mViewManager->currentView() ) {
01573     mViewManager->currentView()->clearSelection();
01574   }
01575   processIncidenceSelection( incidence );
01576 }
01577 
01578 void CalendarView::processIncidenceSelection( Incidence *incidence )
01579 {
01580   if ( incidence == mSelectedIncidence ) return;
01581 
01582   mSelectedIncidence = incidence;
01583 
01584   emit incidenceSelected( mSelectedIncidence );
01585 
01586   if ( incidence && incidence->type() == "Event" ) {
01587     Event *event = static_cast<Event *>( incidence );
01588     if ( event->organizer() == KOPrefs::instance()->email() ) {
01589       emit organizerEventsSelected( true );
01590     } else {
01591       emit organizerEventsSelected(false);
01592     }
01593     if (event->attendeeByMails( KOPrefs::instance()->mAdditionalMails,
01594                                 KOPrefs::instance()->email() ) ) {
01595       emit groupEventsSelected( true );
01596     } else {
01597       emit groupEventsSelected(false);
01598     }
01599     return;
01600   } else {
01601     if  ( incidence && incidence->type() == "Todo" ) {
01602       emit todoSelected( true );
01603       Todo *event = static_cast<Todo *>( incidence );
01604       if ( event->organizer() == KOPrefs::instance()->email() ) {
01605         emit organizerEventsSelected( true );
01606      } else {
01607         emit organizerEventsSelected(false);
01608       }
01609       if (event->attendeeByMails( KOPrefs::instance()->mAdditionalMails,
01610                                   KOPrefs::instance()->email() ) ) {
01611         emit groupEventsSelected( true );
01612       } else {
01613         emit groupEventsSelected(false);
01614       }
01615       return;
01616     } else {
01617      emit todoSelected( false );
01618      emit organizerEventsSelected(false);
01619      emit groupEventsSelected(false);
01620     }
01621     return;
01622   }
01623 
01624 /*  if  ( incidence && incidence->type() == "Todo" ) {
01625     emit todoSelected( true );
01626   } else {
01627     emit todoSelected( false );
01628   }*/
01629 }
01630 
01631 
01632 void CalendarView::checkClipboard()
01633 {
01634 #ifndef KORG_NODND
01635   if (ICalDrag::canDecode(QApplication::clipboard()->data())) {
01636     kdDebug(5850) << "CalendarView::checkClipboard() true" << endl;
01637     emit pasteEnabled(true);
01638   } else {
01639     kdDebug(5850) << "CalendarView::checkClipboard() false" << endl;
01640     emit pasteEnabled(false);
01641   }
01642 #endif
01643 }
01644 
01645 void CalendarView::showDates(const DateList &selectedDates)
01646 {
01647 //  kdDebug(5850) << "CalendarView::selectDates()" << endl;
01648 
01649   if ( mViewManager->currentView() ) {
01650     updateView( selectedDates.first(), selectedDates.last() );
01651   } else {
01652     mViewManager->showAgendaView();
01653   }
01654 }
01655 
01656 void CalendarView::editFilters()
01657 {
01658 //  kdDebug(5850) << "CalendarView::editFilters()" << endl;
01659 
01660   CalFilter *filter = mFilters.first();
01661   while(filter) {
01662     kdDebug(5850) << " Filter: " << filter->name() << endl;
01663     filter = mFilters.next();
01664   }
01665 
01666   mDialogManager->showFilterEditDialog(&mFilters);
01667 }
01668 
01669 void CalendarView::showFilter(bool visible)
01670 {
01671   if (visible) mFilterView->show();
01672   else mFilterView->hide();
01673 }
01674 
01675 void CalendarView::updateFilter()
01676 {
01677   CalFilter *filter = mFilterView->selectedFilter();
01678   if (filter) {
01679     if (mFilterView->filtersEnabled()) filter->setEnabled(true);
01680     else filter->setEnabled(false);
01681     mCalendar->setFilter(filter);
01682     updateView();
01683   }
01684 }
01685 
01686 void CalendarView::filterEdited()
01687 {
01688   mFilterView->updateFilters();
01689   updateFilter();
01690 }
01691 
01692 
01693 void CalendarView::takeOverEvent()
01694 {
01695   Incidence *incidence = currentSelection();
01696 
01697   if (!incidence) return;
01698 
01699   incidence->setOrganizer(KOPrefs::instance()->email());
01700   incidence->recreate();
01701   incidence->setReadOnly(false);
01702 
01703   updateView();
01704 }
01705 
01706 void CalendarView::takeOverCalendar()
01707 {
01708   Incidence::List incidences = mCalendar->rawIncidences();
01709   Incidence::List::Iterator it;
01710   
01711   for ( it = incidences.begin(); it != incidences.end(); it++ ) {
01712     (*it)->setOrganizer(KOPrefs::instance()->email());
01713     (*it)->recreate();
01714     (*it)->setReadOnly(false);
01715   }
01716   updateView();
01717 }
01718 
01719 void CalendarView::showIntro()
01720 {
01721   kdDebug(5850) << "To be implemented." << endl;
01722 }
01723 
01724 QWidgetStack *CalendarView::viewStack()
01725 {
01726   return mRightFrame;
01727 }
01728 
01729 QWidget *CalendarView::leftFrame()
01730 {
01731   return mLeftFrame;
01732 }
01733 
01734 DateNavigator *CalendarView::dateNavigator()
01735 {
01736   return mNavigator;
01737 }
01738 
01739 void CalendarView::addView(KOrg::BaseView *view)
01740 {
01741   mViewManager->addView(view);
01742 }
01743 
01744 void CalendarView::showView(KOrg::BaseView *view)
01745 {
01746   mViewManager->showView(view);
01747 }
01748 
01749 void CalendarView::addExtension( CalendarViewExtension::Factory *factory )
01750 {
01751   CalendarViewExtension *extension = factory->create( mLeftSplitter );
01752 
01753   mExtensions.append( extension );
01754 }
01755 
01756 Incidence *CalendarView::currentSelection()
01757 {
01758   return mViewManager->currentSelection();
01759 }
01760 
01761 void CalendarView::toggleExpand()
01762 {
01763   showLeftFrame( mLeftFrame->isHidden() );
01764 }
01765 
01766 void CalendarView::showLeftFrame(bool show)
01767 {
01768   if (show) {
01769     mLeftFrame->show();
01770     emit calendarViewExpanded( false );
01771   } else {
01772     mLeftFrame->hide();
01773     emit calendarViewExpanded( true );
01774   }
01775 }
01776 
01777 void CalendarView::calendarModified( bool modified, Calendar * )
01778 {
01779   setModified( modified );
01780 }
01781 
01782 Todo *CalendarView::selectedTodo()
01783 {
01784   Incidence *incidence = currentSelection();
01785   if ( incidence && incidence->type() == "Todo" ) {
01786     return static_cast<Todo *>( incidence );
01787   }
01788   incidence = 0;
01789 
01790   Incidence::List selectedIncidences = mTodoList->selectedIncidences();
01791   if ( !selectedIncidences.isEmpty() ) incidence = selectedIncidences.first();
01792   if ( incidence && incidence->type() == "Todo" ) {
01793     return static_cast<Todo *>( incidence );
01794   }
01795 
01796   return 0;
01797 }
01798 
01799 void CalendarView::dialogClosing(Incidence *in)
01800 {
01801   mDialogList.remove(in);
01802 }
01803 
01804 Incidence* CalendarView::selectedIncidence()
01805 {
01806   Incidence *incidence = currentSelection();
01807   if ( !incidence ) {
01808     Incidence::List selectedIncidences = mTodoList->selectedIncidences();
01809     if ( !selectedIncidences.isEmpty() )
01810       incidence = selectedIncidences.first();
01811   }
01812   return incidence;
01813 }
01814 
01815 void CalendarView::showIncidence()
01816 {
01817   showIncidence( selectedIncidence() );
01818 }
01819 
01820 void CalendarView::editIncidence()
01821 {
01822   editIncidence( selectedIncidence() );
01823 }
01824 
01825 void CalendarView::deleteIncidence()
01826 {
01827   deleteIncidence( selectedIncidence() );
01828 }
01829 
01830 void CalendarView::showIncidence(Incidence *incidence)
01831 {
01832   if ( incidence ) {
01833     ShowIncidenceVisitor v;
01834     v.act( incidence, this );
01835   }
01836 }
01837 
01838 void CalendarView::editIncidence(Incidence *incidence)
01839 {
01840   if ( incidence ) {
01841     EditIncidenceVisitor v;
01842     v.act( incidence, this );
01843   }
01844 }
01845 
01846 void CalendarView::deleteIncidence(Incidence *incidence)
01847 {
01848   if ( incidence ) {
01849     DeleteIncidenceVisitor v;
01850     v.act( incidence, this );
01851   }
01852 }
01853 
01854 
01855 void CalendarView::lookForOutgoingMessages()
01856 {
01857   OutgoingDialog *ogd = mDialogManager->outgoingDialog();
01858   ogd->loadMessages();
01859 }
01860 
01861 void CalendarView::lookForIncomingMessages()
01862 {
01863   IncomingDialog *icd = mDialogManager->incomingDialog();
01864   icd->retrieve();
01865 }
01866 
01867 void CalendarView::purgeCompleted()
01868 {
01869   int result = KMessageBox::warningContinueCancel(this,
01870       i18n("Delete all completed To-Dos?"),i18n("Purge To-Dos"),i18n("Purge"));
01871 
01872   if (result == KMessageBox::Continue) {
01873     Todo::List todoCal;
01874     Incidence::List rel;
01875     bool childDelete = false;
01876     bool deletedOne = true;
01877     while (deletedOne) {
01878       todoCal.clear();
01879       todoCal = calendar()->todos();
01880       deletedOne = false;
01881       Todo::List::ConstIterator it;
01882       for ( it = todoCal.begin(); it != todoCal.end(); ++it ) {
01883         Todo *aTodo = *it;
01884         if (aTodo->isCompleted()) {
01885           rel = aTodo->relations();
01886           if (!rel.isEmpty()) {
01887             Incidence::List::ConstIterator it2;
01888             for ( it2 = rel.begin(); it2 != rel.end(); ++it2 ) {
01889               Incidence *rIncidence = *it2;
01890               if (rIncidence->type()=="Todo") {
01891                 Todo *rTodo = static_cast<Todo*>(rIncidence);
01892                 if (!rTodo->isCompleted()) childDelete = true;
01893               }
01894             }
01895           }
01896           else {
01897             calendar()->deleteTodo(aTodo);
01898             deletedOne = true;
01899           }
01900         }
01901       }
01902     }
01903     if (childDelete) {
01904       KMessageBox::sorry(this,i18n("Cannot purge To-Do which has uncompleted children."),
01905                          i18n("Delete To-Do"));
01906     }
01907     updateView();
01908   }
01909 }
01910 
01911 void CalendarView::slotCalendarChanged()
01912 {
01913   kdDebug(5850) << "CalendarView::slotCalendarChanged()" << endl;
01914 
01915   updateView();
01916 }
01917 
01918 NavigatorBar *CalendarView::navigatorBar()
01919 {
01920   return mNavigatorBar;
01921 }
01922 
01923 void CalendarView::importQtopia( const QString &categories,
01924                                  const QString &datebook,
01925                                  const QString &todolist )
01926 {
01927   QtopiaFormat qtopiaFormat;
01928   if ( !categories.isEmpty() ) qtopiaFormat.load( mCalendar, categories );
01929   if ( !datebook.isEmpty() ) qtopiaFormat.load( mCalendar, datebook );
01930   if ( !todolist.isEmpty() ) qtopiaFormat.load( mCalendar, todolist );
01931   updateView();
01932 }
01933 
01934 void CalendarView::warningChangeFailed( Incidence * )
01935 {
01936   KMessageBox::sorry( this, i18n("Unable to edit incidence. "
01937                                  "It's locked by another process.") );
01938 }
01939 
01940 void CalendarView::editCanceled( Incidence *i )
01941 {
01942   mCalendar->endChange( i );
01943 }
01944 
01945 #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 Sat May 1 11:38:26 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003