korganizer

calendarview.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 1997, 1998, 1999
00005     Preston Brown (preston.brown@yale.edu)
00006     Fester Zigterman (F.J.F.ZigtermanRustenburg@student.utwente.nl)
00007     Ian Dawes (iadawes@globalserve.net)
00008     Laszlo Boloni (boloni@cs.purdue.edu)
00009 
00010     Copyright (c) 2000, 2001, 2002, 2003, 2004
00011     Cornelius Schumacher <schumacher@kde.org>
00012     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00013 
00014     This program is free software; you can redistribute it and/or modify
00015     it under the terms of the GNU General Public License as published by
00016     the Free Software Foundation; either version 2 of the License, or
00017     (at your option) any later version.
00018 
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00022     GNU General Public License for more details.
00023 
00024     You should have received a copy of the GNU General Public License
00025     along with this program; if not, write to the Free Software
00026     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00027 
00028     As a special exception, permission is given to link this program
00029     with any edition of Qt, and distribute the resulting executable,
00030     without including the source code for Qt in the source distribution.
00031 */
00032 
00033 #include "calendarview.h"
00034 
00035 #ifndef KORG_NOPRINTER
00036 #include "calprinter.h"
00037 #endif
00038 #include "koeventeditor.h"
00039 #include "kotodoeditor.h"
00040 #include "kojournaleditor.h"
00041 #include "koprefs.h"
00042 #include "koeventviewerdialog.h"
00043 #include "publishdialog.h"
00044 #include "koglobals.h"
00045 #include "koviewmanager.h"
00046 #include "koagendaview.h"
00047 #include "kodialogmanager.h"
00048 #include "statusdialog.h"
00049 #include "datenavigatorcontainer.h"
00050 #include "kotodoview.h"
00051 #include "datenavigator.h"
00052 #include "resourceview.h"
00053 #include "navigatorbar.h"
00054 #include "history.h"
00055 #include "kogroupware.h"
00056 #include "freebusymanager.h"
00057 #include "komonthview.h"
00058 #include "datechecker.h"
00059 #include "komessagebox.h"
00060 #include "exportwebdialog.h"
00061 #include "kocorehelper.h"
00062 #include "incidencechanger.h"
00063 #include "kholidays.h"
00064 #include "mailscheduler.h"
00065 #include "komailclient.h"
00066 #include "multiagendaview.h"
00067 
00068 #include <libkcal/calhelper.h>
00069 #include <libkcal/vcaldrag.h>
00070 #include <libkcal/icaldrag.h>
00071 #include <libkcal/icalformat.h>
00072 #include <libkcal/vcalformat.h>
00073 #include <libkcal/scheduler.h>
00074 #include <libkcal/calendarlocal.h>
00075 #include <libkcal/journal.h>
00076 #include <libkcal/calfilter.h>
00077 #include <libkcal/attendee.h>
00078 #include <libkcal/dndfactory.h>
00079 #include <libkcal/freebusy.h>
00080 #include <libkcal/filestorage.h>
00081 #include <libkcal/calendarresources.h>
00082 #include <libkcal/calendarnull.h>
00083 #include <libkcal/htmlexportsettings.h>
00084 
00085 #include <kglobal.h>
00086 #include <kdebug.h>
00087 #include <kstandarddirs.h>
00088 #include <kfiledialog.h>
00089 #include <kmessagebox.h>
00090 #include <knotifyclient.h>
00091 #include <kconfig.h>
00092 #include <krun.h>
00093 #include <kdirwatch.h>
00094 
00095 #include <qapplication.h>
00096 #include <qclipboard.h>
00097 #include <qcursor.h>
00098 #include <qmultilineedit.h>
00099 #include <qtimer.h>
00100 #include <qwidgetstack.h>
00101 #include <qptrlist.h>
00102 #include <qfile.h>
00103 #include <qlayout.h>
00104 #ifndef KORG_NOSPLITTER
00105 #include <qsplitter.h>
00106 #endif
00107 #include <qvbox.h>
00108 #include <qwhatsthis.h>
00109 
00110 #include <stdlib.h>
00111 #include <assert.h>
00112 
00113 using namespace KOrg;
00114 
00115 CalendarView::CalendarView( QWidget *parent, const char *name )
00116   : CalendarViewBase( parent, name ),
00117     mHistory( 0 ),
00118     mCalendar( CalendarNull::self() ),
00119     mChanger( 0 )
00120 {
00121   kdDebug(5850) << "CalendarView::CalendarView( Calendar )" << endl;
00122 
00123   mViewManager = new KOViewManager( this );
00124   mDialogManager = new KODialogManager( this );
00125 
00126   mModified = false;
00127   mReadOnly = false;
00128   mSelectedIncidence = 0;
00129 
00130   mFilters.setAutoDelete( true );
00131 
00132   mExtensions.setAutoDelete( true );
00133 
00134   mNavigator = new DateNavigator( this );
00135   mDateChecker = new DateChecker( this );
00136 
00137   QBoxLayout *topLayout = new QVBoxLayout( this );
00138 
00139 #ifndef KORG_NOSPLITTER
00140   // create the main layout frames.
00141   mPanner = new QSplitter( QSplitter::Horizontal, this,
00142                            "CalendarView::Panner" );
00143   topLayout->addWidget( mPanner );
00144 
00145   mLeftSplitter = new QSplitter( QSplitter::Vertical, mPanner,
00146                                  "CalendarView::LeftFrame" );
00147 //  mPanner->setResizeMode( mLeftSplitter, QSplitter::Stretch );
00148 
00149   mDateNavigator = new DateNavigatorContainer( mLeftSplitter,
00150                                                "CalendarView::DateNavigator" );
00151 
00152 //  mLeftSplitter->setResizeMode( mDateNavigator, QSplitter::Stretch );
00153   mLeftSplitter->setCollapsible( mDateNavigator, true );
00154   mTodoList = new KOTodoView( CalendarNull::self(), mLeftSplitter, "todolist" );
00155 
00156   mEventViewer = new KOEventViewer( CalendarNull::self(), mLeftSplitter,"EventViewer" );
00157 
00158   QVBox *rightBox = new QVBox( mPanner );
00159   mNavigatorBar = new NavigatorBar( rightBox );
00160   mRightFrame = new QWidgetStack( rightBox );
00161   rightBox->setStretchFactor( mRightFrame, 1 );
00162 
00163   mLeftFrame = mLeftSplitter;
00164 #else
00165   QWidget *mainBox;
00166   QWidget *leftFrame;
00167 
00168   if ( KOPrefs::instance()->mVerticalScreen ) {
00169     mainBox = new QVBox( this );
00170     leftFrame = new QHBox( mainBox );
00171   } else {
00172     mainBox = new QHBox( this );
00173     leftFrame = new QVBox( mainBox );
00174   }
00175 
00176   topLayout->addWidget( mainBox );
00177 
00178   mDateNavigator = new KDateNavigator( leftFrame, true,
00179                                        "CalendarView::DateNavigator",
00180                                        QDate::currentDate() );
00181   mTodoList = new KOTodoView( CalendarNull::self(), leftFrame, "todolist" );
00182 
00183   mEventViewer = new KOEventViewer ( CalendarNull::self(), leftFrame, "EventViewer" );
00184 
00185   QWidget *rightBox = new QWidget( mainBox );
00186   QBoxLayout *rightLayout = new QVBoxLayout( rightBox );
00187 
00188   mNavigatorBar = new NavigatorBar( QDate::currentDate(), rightBox );
00189   rightLayout->addWidget( mNavigatorBar );
00190 
00191   mRightFrame = new QWidgetStack( rightBox );
00192   rightLayout->addWidget( mRightFrame );
00193 
00194   mLeftFrame = leftFrame;
00195 
00196   if ( KOPrefs::instance()->mVerticalScreen ) {
00197 //    mTodoList->setFixedHeight( 60 );
00198     mTodoList->setFixedHeight( mDateNavigator->sizeHint().height() );
00199   }
00200 #endif
00201 
00202   connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ),
00203            SLOT( showDates( const KCal::DateList & ) ) );
00204   connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ),
00205            mDateNavigator, SLOT( selectDates( const KCal::DateList & ) ) );
00206 
00207   connect( mNavigatorBar, SIGNAL( goPrevYear() ),
00208            mNavigator, SLOT( selectPreviousYear() ) );
00209   connect( mNavigatorBar, SIGNAL( goNextYear() ),
00210            mNavigator, SLOT( selectNextYear() ) );
00211   connect( mNavigatorBar, SIGNAL( goPrevMonth() ),
00212            mNavigator, SLOT( selectPreviousMonth() ) );
00213   connect( mNavigatorBar, SIGNAL( goNextMonth() ),
00214            mNavigator, SLOT( selectNextMonth() ) );
00215   connect( mNavigatorBar, SIGNAL( goMonth(int) ),
00216            mNavigator, SLOT( selectMonth(int) ) );
00217 
00218   connect( mNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ),
00219            mNavigatorBar, SLOT( selectDates( const KCal::DateList & ) ) );
00220 
00221   connect( mDateNavigator, SIGNAL( weekClicked( const QDate & ) ),
00222            this, SLOT( selectWeek( const QDate & ) ) );
00223 
00224   connect( mDateNavigator, SIGNAL( goPrevYear() ),
00225            mNavigator, SLOT( selectPreviousYear() ) );
00226   connect( mDateNavigator, SIGNAL( goNextYear() ),
00227            mNavigator, SLOT( selectNextYear() ) );
00228   connect( mDateNavigator, SIGNAL( goPrevMonth() ),
00229            mNavigator, SLOT( selectPreviousMonth() ) );
00230   connect( mDateNavigator, SIGNAL( goNextMonth() ),
00231            mNavigator, SLOT( selectNextMonth() ) );
00232   connect( mDateNavigator, SIGNAL( goMonth(int) ),
00233            mNavigator, SLOT( selectMonth(int) ) );
00234 
00235   connect( mDateNavigator, SIGNAL( goPrevious() ),
00236            mNavigator, SLOT( selectPrevious() ) );
00237   connect( mDateNavigator, SIGNAL( goNext() ),
00238            mNavigator, SLOT( selectNext() ) );
00239 
00240   connect( mDateNavigator, SIGNAL( datesSelected( const KCal::DateList & ) ),
00241            mNavigator, SLOT( selectDates( const KCal::DateList & ) ) );
00242 
00243   connect( mDateNavigator, SIGNAL(incidenceDropped(Incidence*, const QDate&)),
00244            SLOT( addIncidenceOn( Incidence *, const QDate & ) ) );
00245   connect( mDateNavigator, SIGNAL(incidenceDroppedMove(Incidence*,const QDate&)),
00246            SLOT( moveIncidenceTo( Incidence *, const QDate & ) ) );
00247 
00248   connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00249            mTodoList, SLOT( dayPassed( const QDate & ) ) );
00250   connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00251            SIGNAL( dayPassed( const QDate & ) ) );
00252   connect( mDateChecker, SIGNAL( dayPassed( const QDate & ) ),
00253            mDateNavigator, SLOT( updateToday() ) );
00254 
00255   connect( this, SIGNAL( configChanged() ),
00256            mDateNavigator, SLOT( updateConfig() ) );
00257 
00258   connect( this, SIGNAL( incidenceSelected(Incidence *, const QDate &) ),
00259            mEventViewer, SLOT ( setIncidence (Incidence *, const QDate &) ) );
00260 
00261   //TODO: do a pretty Summary,
00262   QString s;
00263   s = i18n( "<p><em>No Item Selected</em></p>"
00264            "<p>Select an event, to-do or journal entry to view its details "
00265            "here.</p>");
00266 
00267   mEventViewer->setDefaultText( s );
00268   QWhatsThis::add( mEventViewer,
00269                    i18n( "View the details of events, journal entries or to-dos "
00270                          "selected in KOrganizer's main view here." ) );
00271   mEventViewer->setIncidence( 0, QDate() );
00272 
00273   mViewManager->connectTodoView( mTodoList );
00274   mViewManager->connectView( mTodoList );
00275 
00276   KOGlobals::self()->
00277       setHolidays( new KHolidays( KOPrefs::instance()->mHolidays ) );
00278 
00279   connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00280            SLOT( checkClipboard() ) );
00281 
00282   connect( mTodoList, SIGNAL( incidenceSelected( Incidence *,const QDate & ) ),
00283            SLOT( processTodoListSelection( Incidence *,const QDate & ) ) );
00284   disconnect( mTodoList, SIGNAL( incidenceSelected( Incidence *,const QDate & ) ),
00285            this, SLOT( processMainViewSelection( Incidence *,const QDate & ) ) );
00286 
00287   kdDebug(5850) << "CalendarView::CalendarView() done" << endl;
00288 }
00289 
00290 CalendarView::~CalendarView()
00291 {
00292   kdDebug(5850) << "~CalendarView()" << endl;
00293 
00294   mCalendar->unregisterObserver( this );
00295 
00296   delete mDialogManager;
00297   delete mViewManager;
00298   delete mEventViewer;
00299   kdDebug(5850) << "~CalendarView() done" << endl;
00300 }
00301 
00302 void CalendarView::setCalendar( Calendar *cal )
00303 {
00304   kdDebug(5850)<<"CalendarView::setCalendar"<<endl;
00305   mCalendar = cal;
00306 
00307   delete mHistory;
00308   mHistory = new History( mCalendar );
00309   connect( mHistory, SIGNAL( undone() ), SLOT( updateView() ) );
00310   connect( mHistory, SIGNAL( redone() ), SLOT( updateView() ) );
00311 
00312   if ( mChanger ) delete mChanger;
00313   setIncidenceChanger( new IncidenceChanger( mCalendar, this ) );
00314 
00315   mCalendar->registerObserver( this );
00316 
00317   mDateNavigator->setCalendar( mCalendar );
00318 
00319   mTodoList->setCalendar( mCalendar );
00320 
00321   mEventViewer->setCalendar( mCalendar );
00322 }
00323 
00324 void CalendarView::setIncidenceChanger( IncidenceChangerBase *changer )
00325 {
00326   mChanger = changer;
00327   emit newIncidenceChanger( mChanger );
00328   connect( mChanger, SIGNAL( incidenceAdded( Incidence* ) ),
00329            this, SLOT( incidenceAdded( Incidence* ) ) );
00330   connect( mChanger, SIGNAL( incidenceChanged( Incidence*, Incidence*, KOGlobals::WhatChanged ) ),
00331            this, SLOT( incidenceChanged( Incidence*, Incidence*, KOGlobals::WhatChanged ) ) );
00332   connect( mChanger, SIGNAL( incidenceToBeDeleted( Incidence * ) ),
00333            this, SLOT( incidenceToBeDeleted( Incidence * ) ) );
00334   connect( mChanger, SIGNAL( incidenceDeleted( Incidence * ) ),
00335            this, SLOT( incidenceDeleted( Incidence * ) ) );
00336 
00337   connect( mChanger, SIGNAL( schedule( Scheduler::Method, Incidence*) ),
00338            this, SLOT( schedule( Scheduler::Method, Incidence*) ) );
00339 
00340 
00341   connect( this, SIGNAL( cancelAttendees( Incidence * ) ),
00342            mChanger, SLOT( cancelAttendees( Incidence * ) ) );
00343 }
00344 
00345 Calendar *CalendarView::calendar()
00346 {
00347   if ( mCalendar ) return mCalendar;
00348   else return CalendarNull::self();
00349 }
00350 
00351 QPair<ResourceCalendar *, QString> CalendarView::viewSubResourceCalendar()
00352 {
00353   QPair<ResourceCalendar *, QString> p( 0, QString() );
00354   KOrg::BaseView *cV = mViewManager->currentView();
00355   if ( cV && cV == mViewManager->multiAgendaView() ) {
00356     cV = mViewManager->multiAgendaView()->selectedAgendaView();
00357   }
00358   if ( cV ) {
00359     p = qMakePair( cV->resourceCalendar(), cV->subResourceCalendar() );
00360   }
00361   return p;
00362 }
00363 
00364 KOIncidenceEditor *CalendarView::editorDialog( Incidence *incidence ) const
00365 {
00366   if (mDialogList.find(incidence) != mDialogList.end ())
00367     return mDialogList[incidence];
00368   else return 0;
00369 }
00370 
00371 QDate CalendarView::activeDate( bool fallbackToToday )
00372 {
00373   KOrg::BaseView *curView = mViewManager->currentView();
00374   if ( curView ) {
00375     if ( curView->selectionStart().isValid() ) {
00376       return curView->selectionStart().date();
00377     }
00378 
00379     // Try the view's selectedDates()
00380     if ( !curView->selectedDates().isEmpty() ) {
00381       if ( curView->selectedDates().first().isValid() ) {
00382         return curView->selectedDates().first();
00383       }
00384     }
00385   }
00386 
00387   // When all else fails, use the navigator start date, or today.
00388   if ( fallbackToToday ) {
00389     return QDate::currentDate();
00390   } else {
00391     return mNavigator->selectedDates().first();
00392   }
00393 }
00394 
00395 QDate CalendarView::activeIncidenceDate()
00396 {
00397   KOrg::BaseView *curView = mViewManager->currentView();
00398   if ( curView ) {
00399     DateList dates = curView->selectedDates();
00400     if ( !dates.isEmpty() ) {
00401       return dates.first();
00402     }
00403   }
00404 
00405   return QDate();
00406 }
00407 
00408 QDate CalendarView::startDate()
00409 {
00410   DateList dates = mNavigator->selectedDates();
00411 
00412   return dates.first();
00413 }
00414 
00415 QDate CalendarView::endDate()
00416 {
00417   DateList dates = mNavigator->selectedDates();
00418 
00419   return dates.last();
00420 }
00421 
00422 
00423 bool CalendarView::openCalendar(const QString& filename, bool merge)
00424 {
00425   kdDebug(5850) << "CalendarView::openCalendar(): " << filename << endl;
00426 
00427   if (filename.isEmpty()) {
00428     kdDebug(5850) << "CalendarView::openCalendar(): Error! Empty filename." << endl;
00429     return false;
00430   }
00431 
00432   if (!QFile::exists(filename)) {
00433     kdDebug(5850) << "CalendarView::openCalendar(): Error! File '" << filename
00434               << "' doesn't exist." << endl;
00435   }
00436 
00437   bool loadedSuccesfully = true;
00438   if ( !merge ) {
00439     mCalendar->close();
00440     CalendarLocal *cl = dynamic_cast<CalendarLocal*>( mCalendar );
00441     if ( cl ) {
00442       loadedSuccesfully = cl->load( filename );
00443     } else {
00444       CalendarResources *cr = dynamic_cast<CalendarResources*>( mCalendar );
00445       assert( cr ); // otherwise something is majorly wrong
00446       // openCalendar called without merge and a filename, what should we do?
00447       return false;
00448     }
00449   } else {
00450     // merge in a file
00451     FileStorage storage( mCalendar );
00452     storage.setFileName( filename );
00453     loadedSuccesfully = storage.load();
00454   }
00455 
00456   if ( loadedSuccesfully ) {
00457     if ( merge )
00458       setModified( true );
00459     else {
00460       setModified( false );
00461       mViewManager->setDocumentId( filename );
00462       mTodoList->setDocumentId( filename );
00463     }
00464     updateCategories();
00465     updateView();
00466     return true;
00467   } else {
00468     // while failing to load, the calendar object could
00469     // have become partially populated.  Clear it out.
00470     if ( !merge ) mCalendar->close();
00471 
00472     KMessageBox::error(this,i18n("Could not load calendar '%1'.").arg(filename));
00473 
00474     return false;
00475   }
00476 }
00477 
00478 bool CalendarView::saveCalendar( const QString& filename )
00479 {
00480   kdDebug(5850) << "CalendarView::saveCalendar(): " << filename << endl;
00481 
00482   // Store back all unsaved data into calendar object
00483   mViewManager->currentView()->flushView();
00484 
00485   FileStorage storage( mCalendar );
00486   storage.setFileName( filename );
00487   storage.setSaveFormat( new ICalFormat );
00488 
00489   bool success = storage.save();
00490 
00491   if ( !success ) {
00492     return false;
00493   }
00494 
00495   return true;
00496 }
00497 
00498 void CalendarView::closeCalendar()
00499 {
00500   kdDebug(5850) << "CalendarView::closeCalendar()" << endl;
00501 
00502   // child windows no longer valid
00503   emit closingDown();
00504 
00505   mCalendar->close();
00506   setModified( false );
00507   updateView();
00508 }
00509 
00510 void CalendarView::archiveCalendar()
00511 {
00512   mDialogManager->showArchiveDialog();
00513 }
00514 
00515 
00516 void CalendarView::readSettings()
00517 {
00518 //  kdDebug(5850) << "CalendarView::readSettings()" << endl;
00519 
00520   QString str;
00521 
00522   // read settings from the KConfig, supplying reasonable
00523   // defaults where none are to be found
00524 
00525   KConfig *config = KOGlobals::self()->config();
00526 
00527 #ifndef KORG_NOSPLITTER
00528   config->setGroup( "KOrganizer Geometry" );
00529 
00530   QValueList<int> sizes = config->readIntListEntry( "Separator1" );
00531   if ( sizes.count() != 2 ) {
00532     sizes << mDateNavigator->minimumSizeHint().width();
00533     sizes << 300;
00534   }
00535   mPanner->setSizes( sizes );
00536 
00537   sizes = config->readIntListEntry( "Separator2" );
00538   mLeftSplitter->setSizes( sizes );
00539 #endif
00540 
00541   mEventViewer->readSettings( config );
00542 
00543   mViewManager->readSettings( config );
00544   mTodoList->restoreLayout( config, QString( "Todo Layout" ) );
00545 
00546   readFilterSettings( config );
00547 
00548   config->setGroup( "Views" );
00549   int dateCount = config->readNumEntry( "ShownDatesCount", 7 );
00550   if ( dateCount == 7 ) mNavigator->selectWeek();
00551   else mNavigator->selectDates( mNavigator->selectedDates().first(), dateCount );
00552 }
00553 
00554 
00555 void CalendarView::writeSettings()
00556 {
00557 //  kdDebug(5850) << "CalendarView::writeSettings" << endl;
00558 
00559   KConfig *config = KOGlobals::self()->config();
00560 
00561 #ifndef KORG_NOSPLITTER
00562   config->setGroup( "KOrganizer Geometry" );
00563 
00564   QValueList<int> list = mPanner->sizes();
00565   config->writeEntry( "Separator1", list );
00566 
00567   list = mLeftSplitter->sizes();
00568   config->writeEntry( "Separator2", list );
00569 #endif
00570   mEventViewer->writeSettings( config );
00571   mViewManager->writeSettings( config );
00572   mTodoList->saveLayout( config, QString( "Todo Layout" ) );
00573 
00574   KOPrefs::instance()->writeConfig();
00575 
00576   writeFilterSettings( config );
00577 
00578   config->setGroup( "Views" );
00579   config->writeEntry( "ShownDatesCount", mNavigator->selectedDates().count() );
00580 
00581   config->sync();
00582 }
00583 
00584 void CalendarView::readFilterSettings( KConfig *config )
00585 {
00586 //  kdDebug(5850) << "CalendarView::readFilterSettings()" << endl;
00587 
00588   mFilters.clear();
00589 
00590   config->setGroup( "General" );
00591   // FIXME: Move the filter loading and saving to the CalFilter class in libkcal
00592   QStringList filterList = config->readListEntry ("CalendarFilters" );
00593   QString currentFilter = config->readEntry( "Current Filter" );
00594 
00595   QStringList::ConstIterator it = filterList.begin();
00596   QStringList::ConstIterator end = filterList.end();
00597   while( it != end ) {
00598 //    kdDebug(5850) << "  filter: " << (*it) << endl;
00599     CalFilter *filter;
00600     filter = new CalFilter( *it );
00601     config->setGroup( "Filter_" + (*it) );
00602     filter->setCriteria( config->readNumEntry( "Criteria", 0 ) );
00603     filter->setCategoryList( config->readListEntry( "CategoryList" ) );
00604     if ( filter->criteria() & KCal::CalFilter::HideTodosWithoutAttendeeInEmailList )
00605       filter->setEmailList( KOPrefs::instance()->allEmails() );
00606     filter->setCompletedTimeSpan( config->readNumEntry( "HideTodoDays", 0 ) );
00607     mFilters.append( filter );
00608 
00609     ++it;
00610   }
00611 
00612   config->setGroup( "General" );
00613   int pos = filterList.findIndex( currentFilter );
00614   mCurrentFilter = 0;
00615   if ( pos>=0 ) {
00616     mCurrentFilter = mFilters.at( pos );
00617   }
00618   updateFilter();
00619 }
00620 
00621 void CalendarView::writeFilterSettings( KConfig *config )
00622 {
00623 //  kdDebug(5850) << "CalendarView::writeFilterSettings()" << endl;
00624 
00625   QStringList filterList;
00626 
00627   CalFilter *filter = mFilters.first();
00628   while( filter ) {
00629 //    kdDebug(5850) << " fn: " << filter->name() << endl;
00630     filterList << filter->name();
00631     config->setGroup( "Filter_" + filter->name() );
00632     config->writeEntry( "Criteria", filter->criteria() );
00633     config->writeEntry( "CategoryList", filter->categoryList() );
00634     config->writeEntry( "HideTodoDays", filter->completedTimeSpan() );
00635     filter = mFilters.next();
00636   }
00637   config->setGroup( "General" );
00638   config->writeEntry( "CalendarFilters", filterList );
00639   if ( mCurrentFilter ) {
00640     config->writeEntry( "Current Filter", mCurrentFilter->name() );
00641   } else {
00642     config->writeEntry( "Current Filter", QString::null );
00643   }
00644 }
00645 
00646 
00647 void CalendarView::goDate( const QDate& date )
00648 {
00649   mNavigator->selectDate( date );
00650 }
00651 
00652 void CalendarView::showDate(const QDate & date)
00653 {
00654   int dateCount = mNavigator->datesCount();
00655   if ( dateCount == 7 )
00656     mNavigator->selectWeek( date );
00657   else
00658     mNavigator->selectDates( date, dateCount );
00659 }
00660 
00661 void CalendarView::goToday()
00662 {
00663   mNavigator->selectToday();
00664 }
00665 
00666 void CalendarView::goNext()
00667 {
00668   if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) )
00669     mNavigator->selectNextMonth();
00670   else
00671     mNavigator->selectNext();
00672 }
00673 
00674 void CalendarView::goPrevious()
00675 {
00676   if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) )
00677     mNavigator->selectPreviousMonth();
00678   else
00679     mNavigator->selectPrevious();
00680 }
00681 
00682 void CalendarView::updateConfig( const QCString& receiver)
00683 {
00684   if ( receiver != "korganizer" ) return;
00685   kdDebug(5850) << "CalendarView::updateConfig()" << endl;
00686 
00687   KOGlobals::self()->
00688     setHolidays( new KHolidays( KOPrefs::instance()->mHolidays ) );
00689 
00690   QString tz(  mCalendar->timeZoneId() );
00691   // Only set a new time zone if it changed. This prevents the window
00692   // from being modified on start
00693   if ( tz != KOPrefs::instance()->mTimeZoneId ) {
00694 
00695     const QString question( i18n("The timezone setting was changed. Do you want to keep the absolute time of "
00696                                 "the items in your calendar, which will show them to be at a different time than "
00697                                 "before, or move them to be at the old time also in the new timezone?") );
00698     int rc = KMessageBox::questionYesNo( this, question,
00699                               i18n("Keep Absolute Times?"),
00700                               KGuiItem(i18n("Keep Times")),
00701                               KGuiItem(i18n("Move Times")),
00702                               "calendarKeepAbsoluteTimes");
00703     if ( rc == KMessageBox::Yes ) {
00704       // user wants us to shift
00705       mCalendar->setTimeZoneIdViewOnly( KOPrefs::instance()->mTimeZoneId );
00706     } else {
00707       // only set the new timezone, wihtout shifting events, they will be
00708       // interpreted as being in the new timezone now
00709       mCalendar->setTimeZoneId( KOPrefs::instance()->mTimeZoneId );
00710     }
00711   }
00712   emit configChanged();
00713 
00714   //switch beetween merged, side by side and tabbed agenda if needed
00715   mViewManager->updateMultiCalendarDisplay();
00716 
00717   // To make the "fill window" configurations work
00718   mViewManager->raiseCurrentView();
00719 }
00720 
00721 
00722 void CalendarView::incidenceAdded( Incidence *incidence )
00723 {
00724   setModified( true );
00725   history()->recordAdd( incidence );
00726   changeIncidenceDisplay( incidence, KOGlobals::INCIDENCEADDED );
00727   updateUnmanagedViews();
00728   checkForFilteredChange( incidence );
00729 }
00730 
00731 void CalendarView::incidenceChanged( Incidence *oldIncidence,
00732                                      Incidence *newIncidence,
00733                                      KOGlobals::WhatChanged modification )
00734 {
00735   KOIncidenceEditor *tmp = editorDialog( newIncidence );
00736   if ( tmp ) {
00737     kdDebug(5850) << "Incidence modified and open" << endl;
00738     tmp->modified();
00739   }
00740   setModified( true );
00741   history()->recordEdit( oldIncidence, newIncidence );
00742 
00743   // Record completed todos in journals, if enabled. we should to this here in
00744   // favour of the todolist. users can mark a task as completed in an editor
00745   // as well.
00746   if ( newIncidence->type() == "Todo" &&
00747        KOPrefs::instance()->recordTodosInJournals() &&
00748        ( modification == KOGlobals::COMPLETION_MODIFIED ||
00749          modification == KOGlobals::COMPLETION_MODIFIED_WITH_RECURRENCE ) ) {
00750 
00751       Todo *todo = static_cast<Todo *>(newIncidence);
00752       if ( todo->isCompleted() ||
00753            modification == KOGlobals::COMPLETION_MODIFIED_WITH_RECURRENCE ) {
00754         QString timeStr = KGlobal::locale()->formatTime( QTime::currentTime() );
00755         QString description = i18n( "To-do completed: %1 (%2)" ).arg(
00756           newIncidence->summary() ).arg( timeStr );
00757 
00758         Journal::List journals = calendar()->journals( QDate::currentDate() );
00759         Journal *journal;
00760 
00761         if ( journals.isEmpty() ) {
00762           journal = new Journal();
00763           journal->setDtStart( QDateTime::currentDateTime() );
00764 
00765           QString dateStr = KGlobal::locale()->formatDate( QDate::currentDate() );
00766           journal->setSummary( i18n("Journal of %1").arg( dateStr ) );
00767           journal->setDescription( description );
00768 
00769           //TODO: recorded to-dos should save into the standard resource always
00770           if ( !mChanger->addIncidence( journal, 0, QString(), this ) ) {
00771             KODialogManager::errorSaveIncidence( this, journal );
00772             delete journal;
00773             return;
00774           }
00775 
00776         } else { // journal list is not empty
00777           journal = *(journals.at(0));
00778           Journal *oldJournal = journal->clone();
00779           journal->setDescription( journal->description().append( "\n" + description ) );
00780 
00781           if ( !mChanger->changeIncidence( oldJournal, journal,
00782                                            KOGlobals::DESCRIPTION_MODIFIED, this ) ) {
00783             KODialogManager::errorSaveIncidence( this, journal );
00784             delete journal;
00785             return;
00786           }
00787         }
00788       }
00789   }
00790 
00791   changeIncidenceDisplay( newIncidence, KOGlobals::INCIDENCEEDITED );
00792   updateUnmanagedViews();
00793   checkForFilteredChange( newIncidence );
00794 }
00795 
00796 void CalendarView::incidenceToBeDeleted( Incidence *incidence )
00797 {
00798   KOIncidenceEditor *tmp = editorDialog( incidence );
00799   if (tmp) {
00800     kdDebug(5850) << "Incidence to be deleted and open in editor" << endl;
00801     tmp->delayedDestruct();
00802   }
00803   setModified( true );
00804   history()->recordDelete( incidence );
00805 //  changeIncidenceDisplay( incidence, KOGlobals::INCIDENCEDELETED );
00806   updateUnmanagedViews();
00807 }
00808 
00809 void CalendarView::incidenceDeleted( Incidence *incidence )
00810 {
00811   changeIncidenceDisplay( incidence, KOGlobals::INCIDENCEDELETED );
00812   updateUnmanagedViews();
00813 }
00814 
00815 void CalendarView::checkForFilteredChange( Incidence *incidence )
00816 {
00817   CalFilter *filter = calendar()->filter();
00818   if ( filter && !filter->filterIncidence( incidence ) ) {
00819     // Incidence is filtered and thus not shown in the view, tell the
00820     // user so that he isn't surprised if his new event doesn't show up
00821     KMessageBox::information( this, i18n("The item \"%1\" is filtered by "
00822                  "your current filter rules, so it will be hidden and not "
00823                  "appear in the view.").arg( incidence->summary() ),
00824                  i18n("Filter Applied"), "ChangedIncidenceFiltered" );
00825   }
00826 }
00827 
00828 void CalendarView::startMultiModify( const QString &text )
00829 {
00830   history()->startMultiModify( text );
00831 }
00832 
00833 void CalendarView::endMultiModify()
00834 {
00835   history()->endMultiModify();
00836 }
00837 
00838 
00839 void CalendarView::changeIncidenceDisplay( Incidence *incidence, int action )
00840 {
00841   mDateNavigator->updateView();
00842   mDialogManager->updateSearchDialog();
00843 
00844   if ( incidence ) {
00845     // If there is an event view visible update the display
00846     mViewManager->currentView()->changeIncidenceDisplay( incidence, action );
00847     if ( mTodoList ) mTodoList->changeIncidenceDisplay( incidence, action );
00848     mEventViewer->changeIncidenceDisplay( incidence, activeDate( true ), action );
00849   } else {
00850     mViewManager->currentView()->updateView();
00851     if ( mTodoList ) mTodoList->updateView();
00852   }
00853 }
00854 
00855 
00856 void CalendarView::updateView(const QDate &start, const QDate &end)
00857 {
00858   mTodoList->updateView();
00859   mViewManager->updateView(start, end);
00860   mDateNavigator->updateView();
00861 }
00862 
00863 void CalendarView::updateView()
00864 {
00865   DateList tmpList = mNavigator->selectedDates();
00866 
00867   // We assume that the navigator only selects consecutive days.
00868   updateView( tmpList.first(), tmpList.last() );
00869 }
00870 
00871 void CalendarView::updateUnmanagedViews()
00872 {
00873   mDateNavigator->updateDayMatrix();
00874 }
00875 
00876 int CalendarView::msgItemDelete( Incidence *incidence )
00877 {
00878   return KMessageBox::warningContinueCancel(this,
00879       i18n("The item \"%1\" will be permanently deleted.").arg( incidence->summary() ),
00880       i18n("KOrganizer Confirmation"), KGuiItem(i18n("&Delete"),"editdelete"));
00881 }
00882 
00883 
00884 void CalendarView::edit_cut()
00885 {
00886   Incidence *incidence = incToSendToClipboard( true );
00887 
00888   if ( !incidence || !mChanger ) {
00889     KNotifyClient::beep();
00890     return;
00891   }
00892   mChanger->cutIncidence( incidence, this );
00893 }
00894 
00895 void CalendarView::edit_copy()
00896 {
00897   Incidence *incidence = incToSendToClipboard( false );
00898 
00899   if (!incidence) {
00900     KNotifyClient::beep();
00901     return;
00902   }
00903   DndFactory factory( mCalendar );
00904   if ( !factory.copyIncidence( incidence ) ) {
00905     KNotifyClient::beep();
00906   }
00907 }
00908 
00909 Incidence* CalendarView::incToSendToClipboard( bool cut )
00910 {
00911   Incidence *originalInc = selectedIncidence();
00912 
00913   if ( originalInc && originalInc->doesRecur() &&
00914        originalInc->type() == "Event" ) { // temporary, until recurring to-dos are fixed
00915 
00916     Incidence *inc;
00917     KOGlobals::WhichOccurrences chosenOption;
00918     if ( cut ) {
00919       inc = singleOccurrenceOrAll( originalInc, KOGlobals::CUT, chosenOption, QDate(), true );
00920     } else {
00921       // The user is copying, the original incidence can't be changed
00922       // we can only dissociate a copy
00923       Incidence *originalIncSaved = originalInc->clone();
00924       inc = singleOccurrenceOrAll( originalIncSaved, KOGlobals::COPY, chosenOption, QDate(), false );
00925 
00926       // no dissociation, no need to leak our clone
00927       if ( chosenOption == KOGlobals::ALL ) {
00928         inc = originalInc;
00929         delete originalIncSaved;
00930       }
00931 
00932       // no need to leak our clone
00933       if ( chosenOption == KOGlobals::NONE ) {
00934         delete originalIncSaved;
00935       }
00936     }
00937 
00938     return inc;
00939   } else {
00940     return originalInc;
00941   }
00942 }
00943 
00944 void CalendarView::edit_paste()
00945 {
00946 // If in agenda and month view, use the selected time and date from there.
00947 // In all other cases, use the navigator's selected date.
00948 
00949   QDate date;          // null dates are invalid, that's what we want
00950   QTime time( -1, -1 );// create an invalid time, that's what we want
00951   QDateTime endDT;     // null datetimes are invalid, that's what we want
00952   bool useEndTime = false;
00953 
00954   KOrg::BaseView *curView = mViewManager->currentView();
00955   if ( !curView ) {
00956     return;
00957   }
00958 
00959   KOAgendaView *aView = mViewManager->agendaView();
00960   KOMonthView *mView = mViewManager->monthView();
00961   if ( curView == mViewManager->multiAgendaView() ) {
00962     aView = mViewManager->multiAgendaView()->selectedAgendaView();
00963     curView = aView;
00964   }
00965 
00966   if ( curView == aView && aView->selectionStart().isValid() ) {
00967     date = aView->selectionStart().date();
00968     endDT = aView->selectionEnd();
00969     useEndTime = !aView->selectedIsSingleCell();
00970     if ( !aView->selectedIsAllDay() ) {
00971       time = aView->selectionStart().time();
00972     }
00973   } else if ( curView == mView && !mView->selectedDates().isEmpty() ) {
00974     date = mView->selectedDates().first();
00975   } else {
00976     // default to the selected date from the navigator
00977     if ( !mNavigator->selectedDates().isEmpty() ) {
00978       date = mNavigator->selectedDates().first();
00979     }
00980   }
00981 
00982   if ( !date.isValid() ) {
00983     KMessageBox::sorry(
00984       this,
00985       i18n( "Paste failed: unable to determine a valid target date." ) );
00986     return;
00987   }
00988 
00989   DndFactory factory( mCalendar );
00990   Incidence *pastedIncidence;
00991   if ( time.isValid() ) {
00992     pastedIncidence = factory.pasteIncidence( date, &time );
00993   } else {
00994     pastedIncidence = factory.pasteIncidence( date );
00995   }
00996   if ( !pastedIncidence ) {
00997     return;
00998   }
00999 
01000   QPair<ResourceCalendar *, QString>p = viewSubResourceCalendar();
01001 
01002   // FIXME: use a visitor here
01003   if ( pastedIncidence->type() == "Event" ) {
01004     Event *pastedEvent = static_cast<Event*>( pastedIncidence );
01005     // only use selected area if event is of the same type
01006     // (all-day or non-all-day) as the current selection is
01007     if ( aView && endDT.isValid() && useEndTime ) {
01008       if ( ( pastedEvent->doesFloat() && aView->selectedIsAllDay() ) ||
01009            ( !pastedEvent->doesFloat() && !aView->selectedIsAllDay() ) ) {
01010         pastedEvent->setDtEnd( endDT );
01011       }
01012     }
01013     mChanger->addIncidence( pastedEvent, p.first, p.second, this );
01014 
01015   } else if ( pastedIncidence->type() == "Todo" ) {
01016     Todo *pastedTodo = static_cast<Todo*>( pastedIncidence );
01017     Todo *_selectedTodo = selectedTodo();
01018     if ( _selectedTodo ) {
01019       pastedTodo->setRelatedTo( _selectedTodo );
01020     }
01021     mChanger->addIncidence( pastedTodo, p.first, p.second, this );
01022   }
01023 }
01024 
01025 void CalendarView::edit_options()
01026 {
01027   mDialogManager->showOptionsDialog();
01028 }
01029 
01030 void CalendarView::dateTimesForNewEvent( QDateTime &startDt, QDateTime &endDt, bool &allDay )
01031 {
01032   if ( !startDt.isValid() ) {
01033     startDt.setDate( activeDate() );
01034     startDt.setTime( KOPrefs::instance()->mStartTime.time() );
01035   }
01036   if ( !endDt.isValid() ) {
01037     int addSecs =
01038       ( KOPrefs::instance()->mDefaultDuration.time().hour() * 3600 ) +
01039       ( KOPrefs::instance()->mDefaultDuration.time().minute() * 60 );
01040     endDt = startDt.addSecs( addSecs );
01041   }
01042   mViewManager->currentView()->eventDurationHint( startDt, endDt, allDay );
01043 }
01044 
01045 KOEventEditor *CalendarView::newEventEditor( ResourceCalendar *res, const QString &subRes,
01046                                              const QDateTime &startDtParam,
01047                                              const QDateTime &endDtParam, bool allDayParam )
01048 {
01049   // let the current view change the default start/end datetime
01050   bool allDay = allDayParam;
01051   QDateTime startDt( startDtParam ), endDt( endDtParam );
01052   // Adjust the start/end date times (i.e. replace invalid values by defaults,
01053   // and let the view adjust the type.
01054   dateTimesForNewEvent( startDt, endDt, allDay );
01055 
01056   KOEventEditor *eventEditor = mDialogManager->getEventEditor();
01057   eventEditor->newEvent();
01058   connectIncidenceEditor( eventEditor );
01059   eventEditor->setResource( res, subRes );
01060   eventEditor->setDates( startDt, endDt, allDay );
01061   mDialogManager->connectTypeAhead( eventEditor, dynamic_cast<KOrg::AgendaView*>(viewManager()->currentView()) );
01062   return eventEditor;
01063 }
01064 
01065 void CalendarView::newEvent()
01066 {
01067   KOrg::BaseView *currentView = mViewManager->currentView();
01068   if ( currentView == mViewManager->multiAgendaView() ) {
01069     currentView = mViewManager->multiAgendaView()->selectedAgendaView();
01070   }
01071 
01072   newEvent( currentView->resourceCalendar(),
01073             currentView->subResourceCalendar() );
01074 }
01075 
01076 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes )
01077 {
01078   kdDebug(5850) << "CalendarView::newEvent()" << endl;
01079   newEvent( res, subRes, QDateTime(), QDateTime() );
01080 }
01081 
01082 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes,
01083                              const QDate &dt )
01084 {
01085   QDateTime startDt( dt, KOPrefs::instance()->mStartTime.time() );
01086   newEvent( res, subRes, QDateTime( dt ), QDateTime() );
01087 }
01088 
01089 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes,
01090                              const QDateTime &startDt )
01091 {
01092   newEvent( res, subRes, startDt, QDateTime() );
01093 }
01094 
01095 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes,
01096                              const QDateTime &startDt, const QDateTime &endDt,
01097                              bool allDay )
01098 {
01099   KOEventEditor *eventEditor = newEventEditor( res, subRes,
01100                                                startDt, endDt, allDay );
01101   eventEditor->show();
01102 }
01103 
01104 void CalendarView::newEvent( ResourceCalendar *res, const QString &subRes,
01105                              const QString &summary, const QString &description,
01106                              const QStringList &attachments, const QStringList &attendees,
01107                              const QStringList &attachmentMimetypes, bool inlineAttachment )
01108 {
01109   KOEventEditor *eventEditor = newEventEditor( res, subRes );
01110   eventEditor->setTexts( summary, description );
01111   // if attach or attendee list is empty, these methods don't do anything, so
01112   // it's safe to call them in every case
01113   eventEditor->addAttachments( attachments, attachmentMimetypes, inlineAttachment );
01114   eventEditor->addAttendees( attendees );
01115   eventEditor->show();
01116 }
01117 
01118 void CalendarView::newTodo( ResourceCalendar *res, const QString &subRes,
01119                             const QString &summary, const QString &description,
01120                             const QStringList &attachments, const QStringList &attendees,
01121                             const QStringList &attachmentMimetypes,
01122                             bool inlineAttachment, bool isTask )
01123 {
01124   kdDebug(5850) << k_funcinfo << endl;
01125   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01126   connectIncidenceEditor( todoEditor );
01127   todoEditor->newTodo();
01128   todoEditor->setResource( res, subRes );
01129   todoEditor->setTexts( summary, description );
01130   todoEditor->addAttachments( attachments, attachmentMimetypes, inlineAttachment );
01131   todoEditor->addAttendees( attendees );
01132   todoEditor->selectCreateTask( isTask );
01133   todoEditor->show();
01134 }
01135 
01136 void CalendarView::newTodo()
01137 {
01138   KOrg::BaseView *currentView = mViewManager->currentView();
01139   if ( currentView == mViewManager->multiAgendaView() ) {
01140     currentView = mViewManager->multiAgendaView()->selectedAgendaView();
01141   }
01142 
01143   newTodo( currentView->resourceCalendar(),
01144            currentView->subResourceCalendar() );
01145 }
01146 
01147 void CalendarView::newTodo( ResourceCalendar *res, const QString &subRes )
01148 {
01149   kdDebug(5850) << k_funcinfo << endl;
01150   QDateTime dtDue;
01151   bool allday = true;
01152   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01153   connectIncidenceEditor( todoEditor );
01154   todoEditor->newTodo();
01155   todoEditor->setResource( res, subRes );
01156   if ( mViewManager->currentView()->isEventView() ) {
01157     dtDue.setDate( mNavigator->selectedDates().first() );
01158     QDateTime dtDummy = QDateTime::currentDateTime();
01159     mViewManager->currentView()->eventDurationHint( dtDue, dtDummy, allday );
01160     todoEditor->setDates( dtDue, allday );
01161   }
01162   todoEditor->show();
01163 }
01164 
01165 void CalendarView::newTodo( ResourceCalendar *res, const QString &subRes,
01166                             const QDate &date )
01167 {
01168   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01169   connectIncidenceEditor( todoEditor );
01170   todoEditor->newTodo();
01171   todoEditor->setResource( res, subRes );
01172   todoEditor->setDates( QDateTime( date, QTime::currentTime() ), true );
01173   todoEditor->show();
01174 }
01175 
01176 void CalendarView::newJournal()
01177 {
01178   KOrg::BaseView *currentView = mViewManager->currentView();
01179   if ( currentView == mViewManager->multiAgendaView() ) {
01180     currentView = mViewManager->multiAgendaView()->selectedAgendaView();
01181   }
01182 
01183   newJournal( currentView->resourceCalendar(),
01184               currentView->subResourceCalendar() );
01185 }
01186 
01187 void CalendarView::newJournal( ResourceCalendar *res, const QString &subRes )
01188 {
01189   kdDebug(5850) << "CalendarView::newJournal()" << endl;
01190   newJournal( res, subRes, QString::null, QDate() );
01191 }
01192 
01193 void CalendarView::newJournal( ResourceCalendar *res, const QString &subRes,
01194                                const QDate &date)
01195 {
01196   newJournal( res, subRes, QString::null, date );
01197 }
01198 
01199 void CalendarView::newJournal( ResourceCalendar *res, const QString &subRes,
01200                                const QString &text, const QDate &date )
01201 {
01202   KOJournalEditor *journalEditor = mDialogManager->getJournalEditor();
01203   connectIncidenceEditor( journalEditor );
01204   journalEditor->newJournal();
01205   journalEditor->setResource( res, subRes );
01206   journalEditor->setTexts( text );
01207   if ( !date.isValid() ) {
01208     journalEditor->setDate( mNavigator->selectedDates().first() );
01209   } else {
01210     journalEditor->setDate( date );
01211   }
01212   journalEditor->show();
01213 }
01214 
01215 void CalendarView::newSubTodo()
01216 {
01217   Todo *todo = selectedTodo();
01218   if ( todo ) newSubTodo( todo );
01219 }
01220 
01221 void CalendarView::newSubTodo(Todo *parentEvent)
01222 {
01223   KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01224   connectIncidenceEditor( todoEditor );
01225   todoEditor->newTodo();
01226   todoEditor->setDates( QDateTime(), false, parentEvent );
01227   todoEditor->show();
01228 }
01229 
01230 bool CalendarView::addIncidence( const QString &ical )
01231 {
01232   kdDebug(5850) << "CalendarView::addIncidence:\n" << ical << endl;
01233   ICalFormat format;
01234   format.setTimeZone( mCalendar->timeZoneId(), true );
01235   Incidence *incidence = format.fromString( ical );
01236   if ( !incidence ) return false;
01237   if ( !mChanger->addIncidence( incidence, 0, QString(), this ) ) {
01238     delete incidence;
01239     return false;
01240   }
01241   return true;
01242 }
01243 
01244 void CalendarView::appointment_show()
01245 {
01246   Incidence *incidence = selectedIncidence();
01247   if (incidence)
01248     showIncidence( incidence );
01249   else
01250     KNotifyClient::beep();
01251 }
01252 
01253 void CalendarView::appointment_edit()
01254 {
01255   Incidence *incidence = selectedIncidence();
01256   if ( incidence ) {
01257     editIncidence( incidence, activeIncidenceDate() );
01258   } else {
01259     KNotifyClient::beep();
01260   }
01261 }
01262 
01263 void CalendarView::appointment_delete()
01264 {
01265   Incidence *incidence = selectedIncidence();
01266   if (incidence)
01267     deleteIncidence( incidence );
01268   else
01269     KNotifyClient::beep();
01270 }
01271 
01272 void CalendarView::todo_unsub()
01273 {
01274   Todo *anTodo = selectedTodo();
01275   if( todo_unsub (anTodo ) ) {
01276     updateView();
01277   }
01278 }
01279 
01280 bool CalendarView::todo_unsub( Todo *todo )
01281 {
01282   bool status= false;
01283   if ( !todo || !todo->relatedTo() ) return false;
01284 
01285   if ( mChanger->beginChange( todo ) ) {
01286       Todo *oldTodo = todo->clone();
01287       todo->setRelatedTo(0);
01288       mChanger->changeIncidence( oldTodo, todo, KOGlobals::RELATION_MODIFIED, this );
01289       mChanger->endChange( todo );
01290       delete oldTodo;
01291       setModified(true);
01292       status = true;
01293   }
01294   if ( ! status ) {
01295     KMessageBox::sorry( this, i18n("Unable to turn sub-to-do into a top-level "
01296         "to-do, because it cannot be locked.") );
01297   }
01298 
01299   return status;
01300 }
01301 
01302 bool CalendarView::makeSubTodosIndependents ( )
01303 {
01304   bool  status = false;
01305   Todo *anTodo = selectedTodo();
01306 
01307   if( makeSubTodosIndependents( anTodo ) ) {
01308     updateView();
01309     status = true;
01310   }
01311   return status;
01312 }
01313 
01314 bool CalendarView::makeSubTodosIndependents ( Todo *todo )
01315 {
01316   if( !todo || todo->relations().isEmpty() ) return false;
01317 
01318   startMultiModify ( i18n( "Make sub-to-dos independent" ) );
01319   Incidence::List subTodos( todo->relations() );
01320   Incidence::List::Iterator it;
01321   Incidence *aIncidence;
01322   Todo *aTodo;
01323 
01324   for ( it= subTodos.begin(); it != subTodos.end(); ++it ) {
01325     aIncidence = *it;
01326     if( aIncidence && aIncidence->type() == "Todo" ) {
01327       aTodo = static_cast<Todo*>( aIncidence );
01328       todo_unsub ( aTodo );
01329     }
01330   }
01331   endMultiModify();
01332   return true;
01333 }
01334 
01335 bool CalendarView::deleteIncidence( const QString &uid, bool force )
01336 {
01337   Incidence *inc = mCalendar->incidence( uid );
01338   if ( inc ) {
01339     deleteIncidence( inc, force );
01340     return true;
01341   } else {
01342     return false;
01343   }
01344 }
01345 
01346 void CalendarView::toggleAlarm( Incidence *incidence )
01347 {
01348   if ( !incidence || !mChanger ) {
01349     kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01350     return;
01351   }
01352   Incidence*oldincidence = incidence->clone();
01353   if ( !mChanger->beginChange( incidence ) ) {
01354     kdDebug(5850) << "Unable to lock incidence " << endl;
01355     delete oldincidence;
01356     return;
01357   }
01358 
01359   Alarm::List alarms = incidence->alarms();
01360   Alarm::List::ConstIterator it;
01361   for( it = alarms.begin(); it != alarms.end(); ++it )
01362     (*it)->toggleAlarm();
01363   if (alarms.isEmpty()) {
01364     // Add an alarm if it didn't have one
01365     Alarm*alm = incidence->newAlarm();
01366     alm->setEnabled(true);
01367   }
01368   mChanger->changeIncidence( oldincidence, incidence, KOGlobals::ALARM_MODIFIED, this );
01369   mChanger->endChange( incidence );
01370   delete oldincidence;
01371 
01372 //  mClickedItem->updateIcons();
01373 }
01374 
01375 void CalendarView::dissociateOccurrence( Incidence *incidence, const QDate &date )
01376 {
01377   if ( !incidence || !mChanger ) {
01378     kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01379     return;
01380   }
01381   if ( !mChanger->beginChange( incidence ) ) {
01382     kdDebug(5850) << "Unable to lock incidence " << endl;
01383     return;
01384   }
01385   startMultiModify( i18n("Dissociate occurrence") );
01386   Incidence*oldincidence = incidence->clone();
01387 
01388   Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
01389 
01390   if ( newInc ) {
01391     QPair<ResourceCalendar *, QString>p =
01392       CalHelper::incSubResourceCalendar( calendar(), incidence );
01393 
01394     mChanger->changeIncidence( oldincidence, incidence, KOGlobals::NOTHING_MODIFIED, this );
01395     mChanger->addIncidence( newInc, p.first, p.second, this );
01396   } else {
01397     KMessageBox::sorry( this, i18n("Dissociating the occurrence failed."),
01398       i18n("Dissociating Failed") );
01399   }
01400   mChanger->endChange( incidence );
01401   endMultiModify();
01402   delete oldincidence;
01403 }
01404 
01405 void CalendarView::dissociateFutureOccurrence( Incidence *incidence, const QDate &date )
01406 {
01407   if ( !incidence || !mChanger ) {
01408     kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01409     return;
01410   }
01411   if ( !mChanger->beginChange( incidence ) ) {
01412     kdDebug(5850) << "Unable to lock incidence " << endl;
01413     return;
01414   }
01415   startMultiModify( i18n("Dissociate future occurrences") );
01416   Incidence*oldincidence = incidence->clone();
01417 
01418   Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
01419   if ( newInc ) {
01420     QPair<ResourceCalendar *, QString>p =
01421       CalHelper::incSubResourceCalendar( calendar(), incidence );
01422 
01423     mChanger->changeIncidence( oldincidence, incidence, KOGlobals::NOTHING_MODIFIED, this );
01424     mChanger->addIncidence( newInc, p.first, p.second, this );
01425   } else {
01426     KMessageBox::sorry( this, i18n("Dissociating the future occurrences failed."),
01427       i18n("Dissociating Failed") );
01428   }
01429   endMultiModify();
01430   mChanger->endChange( incidence );
01431   delete oldincidence;
01432 }
01433 
01434 
01435 /*****************************************************************************/
01436 
01437 
01438 void CalendarView::schedule_publish(Incidence *incidence)
01439 {
01440   if (incidence == 0)
01441     incidence = selectedIncidence();
01442 
01443   if (!incidence) {
01444     KMessageBox::information( this, i18n("No item selected."),
01445                               "PublishNoEventSelected" );
01446     return;
01447   }
01448 
01449   PublishDialog *publishdlg = new PublishDialog();
01450   if (incidence->attendeeCount()>0) {
01451     Attendee::List attendees = incidence->attendees();
01452     Attendee::List::ConstIterator it;
01453     for( it = attendees.begin(); it != attendees.end(); ++it ) {
01454       publishdlg->addAttendee( *it );
01455     }
01456   }
01457   if ( publishdlg->exec() == QDialog::Accepted ) {
01458     Incidence *inc = incidence->clone();
01459     inc->registerObserver( 0 );
01460     inc->clearAttendees();
01461 
01462     // Send the mail
01463     KCal::MailScheduler scheduler( mCalendar );
01464     if ( scheduler.publish( incidence, publishdlg->addresses() ) ) {
01465       KMessageBox::information( this, i18n("The item information was successfully sent."),
01466                                 i18n("Publishing"), "IncidencePublishSuccess" );
01467     } else {
01468       KMessageBox::error( this, i18n("Unable to publish the item '%1'").arg( incidence->summary() ) );
01469     }
01470   }
01471   delete publishdlg;
01472 }
01473 
01474 void CalendarView::schedule_request(Incidence *incidence)
01475 {
01476   schedule(Scheduler::Request,incidence);
01477 }
01478 
01479 void CalendarView::schedule_refresh(Incidence *incidence)
01480 {
01481   schedule(Scheduler::Refresh,incidence);
01482 }
01483 
01484 void CalendarView::schedule_cancel(Incidence *incidence)
01485 {
01486   schedule(Scheduler::Cancel,incidence);
01487 }
01488 
01489 void CalendarView::schedule_add(Incidence *incidence)
01490 {
01491   schedule(Scheduler::Add,incidence);
01492 }
01493 
01494 void CalendarView::schedule_reply(Incidence *incidence)
01495 {
01496   schedule(Scheduler::Reply,incidence);
01497 }
01498 
01499 void CalendarView::schedule_counter(Incidence *incidence)
01500 {
01501   schedule(Scheduler::Counter,incidence);
01502 }
01503 
01504 void CalendarView::schedule_declinecounter(Incidence *incidence)
01505 {
01506   schedule(Scheduler::Declinecounter,incidence);
01507 }
01508 
01509 void CalendarView::schedule_forward( Incidence *incidence )
01510 {
01511   if ( !incidence ) {
01512     incidence = selectedIncidence();
01513   }
01514 
01515   if ( !incidence ) {
01516     KMessageBox::information(
01517       this,
01518       i18n( "No item selected." ),
01519       i18n( "Forwarding" ),
01520       "ForwardNoEventSelected" );
01521     return;
01522   }
01523 
01524   PublishDialog publishdlg;
01525   if ( publishdlg.exec() == QDialog::Accepted ) {
01526     QString recipients = publishdlg.addresses();
01527     if ( incidence->organizer().isEmpty() ) {
01528       incidence->setOrganizer( Person( KOPrefs::instance()->fullName(),
01529                                        KOPrefs::instance()->email() ) );
01530     }
01531 
01532     ICalFormat format;
01533     QString messageText = format.createScheduleMessage( incidence, Scheduler::Request );
01534     KOMailClient mailer;
01535     if ( mailer.mailTo( incidence, recipients, messageText ) ) {
01536       KMessageBox::information(
01537         this,
01538         i18n( "The item information was successfully sent." ),
01539         i18n( "Forwarding" ),
01540         "IncidenceForwardSuccess" );
01541     } else {
01542       KMessageBox::error(
01543         this,
01544         i18n( "Unable to forward the item '%1'" ).arg( incidence->summary() ),
01545         i18n( "Forwarding Error" ) );
01546     }
01547   }
01548 }
01549 
01550 void CalendarView::mailFreeBusy( int daysToPublish )
01551 {
01552   QDateTime start = QDateTime::currentDateTime();
01553   QDateTime end = start.addDays(daysToPublish);
01554 
01555   FreeBusy *freebusy = new FreeBusy(mCalendar, start, end);
01556   freebusy->setOrganizer( Person( KOPrefs::instance()->fullName(),
01557                       KOPrefs::instance()->email() ) );
01558 
01559   kdDebug(5850) << "calendarview: schedule_publish_freebusy: startDate: "
01560      << KGlobal::locale()->formatDateTime( start ) << " End Date: "
01561      << KGlobal::locale()->formatDateTime( end ) << endl;
01562 
01563   PublishDialog *publishdlg = new PublishDialog();
01564   if ( publishdlg->exec() == QDialog::Accepted ) {
01565     // Send the mail
01566     KCal::MailScheduler scheduler( mCalendar );
01567     if ( scheduler.publish( freebusy, publishdlg->addresses() ) ) {
01568       KMessageBox::information( this, i18n("The free/busy information was successfully sent."),
01569                                 i18n("Sending Free/Busy"), "FreeBusyPublishSuccess" );
01570     } else {
01571       KMessageBox::error( this, i18n("Unable to publish the free/busy data.") );
01572     }
01573   }
01574   delete freebusy;
01575   delete publishdlg;
01576 }
01577 
01578 void CalendarView::uploadFreeBusy()
01579 {
01580   KOGroupware::instance()->freeBusyManager()->publishFreeBusy();
01581 }
01582 
01583 void CalendarView::schedule(Scheduler::Method method, Incidence *incidence)
01584 {
01585   if ( !incidence ) {
01586     incidence = selectedIncidence();
01587   }
01588 
01589   if ( !incidence ) {
01590     KMessageBox::sorry( this, i18n("No item selected."),
01591                         "ScheduleNoEventSelected" );
01592     return;
01593   }
01594 
01595   if( incidence->attendeeCount() == 0 && method != Scheduler::Publish ) {
01596     KMessageBox::information( this, i18n("The item has no attendees."),
01597                               "ScheduleNoIncidences" );
01598     return;
01599   }
01600 
01601   Incidence *inc = incidence->clone();
01602   inc->registerObserver( 0 );
01603   inc->clearAttendees();
01604 
01605   // Send the mail
01606   KCal::MailScheduler scheduler( mCalendar );
01607   if ( scheduler.performTransaction( incidence, method ) ) {
01608     KMessageBox::information( this, i18n("The groupware message for item '%1'"
01609                                 "was successfully sent.\nMethod: %2")
01610                                 .arg( incidence->summary() )
01611                                 .arg( Scheduler::methodName( method ) ),
01612                               i18n("Sending Free/Busy"),
01613                               "FreeBusyPublishSuccess" );
01614   } else {
01615     KMessageBox::error( this, i18n("Groupware message sending failed. "
01616                         "%2 is request/reply/add/cancel/counter/etc.",
01617                         "Unable to send the item '%1'.\nMethod: %2")
01618                         .arg( incidence->summary() )
01619                         .arg( Scheduler::methodName( method ) ) );
01620   }
01621 }
01622 
01623 void CalendarView::openAddressbook()
01624 {
01625   KRun::runCommand("kaddressbook");
01626 }
01627 
01628 void CalendarView::setModified(bool modified)
01629 {
01630   if (mModified != modified) {
01631     mModified = modified;
01632     emit modifiedChanged(mModified);
01633   }
01634 }
01635 
01636 bool CalendarView::isReadOnly()
01637 {
01638   return mReadOnly;
01639 }
01640 
01641 void CalendarView::setReadOnly(bool readOnly)
01642 {
01643   if (mReadOnly != readOnly) {
01644     mReadOnly = readOnly;
01645     emit readOnlyChanged(mReadOnly);
01646   }
01647 }
01648 
01649 bool CalendarView::isModified()
01650 {
01651   return mModified;
01652 }
01653 
01654 void CalendarView::print()
01655 {
01656 #ifndef KORG_NOPRINTER
01657   KOCoreHelper helper;
01658   CalPrinter printer( this, mCalendar, &helper );
01659   connect( this, SIGNAL(configChanged()), &printer, SLOT(updateConfig()) );
01660 
01661   KOrg::BaseView *currentView = mViewManager->currentView();
01662 
01663   CalPrinterBase::PrintType printType = CalPrinterBase::Month;
01664   if ( currentView ) printType = currentView->printType();
01665 
01666   DateList tmpDateList = mNavigator->selectedDates();
01667   Incidence::List selectedIncidences;
01668   if ( mViewManager->currentView() ) {
01669     selectedIncidences = mViewManager->currentView()->selectedIncidences();
01670   }
01671   printer.print( printType, tmpDateList.first(), tmpDateList.last(), selectedIncidences );
01672 #endif
01673 }
01674 
01675 void CalendarView::exportWeb()
01676 {
01677   // FIXME: Get rid of the settings object. When can I delete it???
01678   HTMLExportSettings *settings = new HTMLExportSettings( "KOrganizer" );
01679   // Manually read in the config, because parametrized kconfigxt objects don't
01680   // seem to load the config theirselves
01681   if ( settings ) settings->readConfig();
01682   ExportWebDialog *dlg = new ExportWebDialog( settings, this );
01683   connect( dlg,  SIGNAL( exportHTML( HTMLExportSettings* ) ),
01684            this, SIGNAL( exportHTML( HTMLExportSettings* ) ) );
01685   dlg->show();
01686 }
01687 
01688 void CalendarView::exportICalendar()
01689 {
01690   QString filename = KFileDialog::getSaveFileName("icalout.ics",i18n("*.ics|ICalendars"),this);
01691   if ( !filename.isEmpty() )
01692   {
01693     // Force correct extension
01694     if (filename.right(4) != ".ics") filename += ".ics";
01695     if ( QFile( filename ).exists() ) {
01696       if ( KMessageBox::No == KMessageBox::warningYesNo(
01697              this,
01698              i18n( "Do you want to overwrite %1?").arg(filename) ) ) {
01699           return;
01700       }
01701     }
01702     FileStorage storage( mCalendar, filename, new ICalFormat );
01703     storage.save();
01704   }
01705 }
01706 
01707 void CalendarView::exportVCalendar()
01708 {
01709   if (mCalendar->journals().count() > 0) {
01710     int result = KMessageBox::warningContinueCancel(this,
01711         i18n("The journal entries can not be exported to a vCalendar file."),
01712         i18n("Data Loss Warning"),i18n("Proceed"),"dontaskVCalExport",
01713         true);
01714     if (result != KMessageBox::Continue) return;
01715   }
01716 
01717   QString filename = KFileDialog::getSaveFileName("vcalout.vcs",i18n("*.vcs|vCalendars"),this);
01718   if ( !filename.isEmpty() )
01719   {
01720     // TODO: I don't like forcing extensions:
01721     // Force correct extension
01722     if (filename.right(4) != ".vcs") filename += ".vcs";
01723     if ( QFile( filename ).exists() ) {
01724       if ( KMessageBox::No == KMessageBox::warningYesNo(
01725              this,
01726              i18n( "Do you want to overwrite %1?").arg(filename ) ) ) {
01727              return;
01728       }
01729     }
01730     FileStorage storage( mCalendar, filename, new VCalFormat );
01731     storage.save();
01732   }
01733 }
01734 
01735 void CalendarView::eventUpdated(Incidence *)
01736 {
01737   setModified();
01738   // Don't call updateView here. The code, which has caused the update of the
01739   // event is responsible for updating the view.
01740 //  updateView();
01741 }
01742 
01743 void CalendarView::adaptNavigationUnits()
01744 {
01745   if (mViewManager->currentView()->isEventView()) {
01746     int days = mViewManager->currentView()->currentDateCount();
01747     if (days == 1) {
01748       emit changeNavStringPrev(i18n("&Previous Day"));
01749       emit changeNavStringNext(i18n("&Next Day"));
01750     } else {
01751       emit changeNavStringPrev(i18n("&Previous Week"));
01752       emit changeNavStringNext(i18n("&Next Week"));
01753     }
01754   }
01755 }
01756 
01757 void CalendarView::processMainViewSelection( Incidence *incidence, const QDate &date )
01758 {
01759   if ( incidence ) mTodoList->clearSelection();
01760   processIncidenceSelection( incidence, date );
01761 }
01762 
01763 void CalendarView::processTodoListSelection( Incidence *incidence, const QDate &date )
01764 {
01765   if ( incidence && mViewManager->currentView() ) {
01766     mViewManager->currentView()->clearSelection();
01767   }
01768   processIncidenceSelection( incidence, date );
01769 }
01770 
01771 void CalendarView::processIncidenceSelection( Incidence *incidence, const QDate &date )
01772 {
01773   if ( incidence != mSelectedIncidence ) {
01774     // This signal also must be emitted if incidence is 0
01775     emit incidenceSelected( incidence, date );
01776   }
01777 
01778   if ( !incidence ) {
01779    mSelectedIncidence = incidence;
01780    return;
01781   }
01782   if ( incidence == mSelectedIncidence ) {
01783     if ( !incidence->doesRecur() || mSaveDate == date ) {
01784       return;
01785     }
01786   }
01787 
01788   mSelectedIncidence = incidence;
01789   mSaveDate = date;
01790 
01791   emit incidenceSelected( mSelectedIncidence, date );
01792   bool organizerEvents = false;
01793   bool groupEvents = false;
01794   bool todo = false;
01795   bool subtodo = false;
01796 
01797   organizerEvents = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
01798   groupEvents = incidence->attendeeByMails( KOPrefs::instance()->allEmails() );
01799 
01800   if ( incidence->type() == "Todo" ) {
01801     todo = true;
01802     subtodo = ( incidence->relatedTo() != 0 );
01803   }
01804 
01805   emit todoSelected( todo );
01806   emit subtodoSelected( subtodo );
01807   emit organizerEventsSelected( organizerEvents );
01808   emit groupEventsSelected( groupEvents );
01809 }
01810 
01811 
01812 void CalendarView::checkClipboard()
01813 {
01814 #ifndef KORG_NODND
01815   if (ICalDrag::canDecode(QApplication::clipboard()->data())) {
01816     kdDebug(5850) << "CalendarView::checkClipboard() true" << endl;
01817     emit pasteEnabled(true);
01818   } else {
01819     kdDebug(5850) << "CalendarView::checkClipboard() false" << endl;
01820     emit pasteEnabled(false);
01821   }
01822 #endif
01823 }
01824 
01825 void CalendarView::showDates(const DateList &selectedDates)
01826 {
01827 //  kdDebug(5850) << "CalendarView::selectDates()" << endl;
01828 
01829   if ( mViewManager->currentView() ) {
01830     updateView( selectedDates.first(), selectedDates.last() );
01831   } else {
01832     mViewManager->showAgendaView();
01833   }
01834 }
01835 
01836 void CalendarView::editFilters()
01837 {
01838   kdDebug(5850) << "CalendarView::editFilters()" << endl;
01839 
01840   CalFilter *filter = mFilters.first();
01841   while(filter) {
01842     kdDebug(5850) << " Filter: " << filter->name() << endl;
01843     filter = mFilters.next();
01844   }
01845 
01846   mDialogManager->showFilterEditDialog(&mFilters);
01847 }
01848 
01851 void CalendarView::updateFilter()
01852 {
01853   QStringList filters;
01854   CalFilter *filter;
01855 
01856   int pos = mFilters.find( mCurrentFilter );
01857   if ( pos < 0 ) {
01858     mCurrentFilter = 0;
01859   }
01860 
01861   filters << i18n("No filter");
01862   for ( filter = mFilters.first(); filter; filter = mFilters.next() ) {
01863     filters << filter->name();
01864   }
01865 
01866   emit newFilterListSignal( filters );
01867   // account for the additional "No filter" at the beginning! if the
01868   // filter is not in the list, pos == -1...
01869   emit selectFilterSignal( pos+1 );
01870   mCalendar->setFilter( mCurrentFilter );
01871   updateView();
01872 }
01873 
01876 void CalendarView::filterActivated( int filterNo )
01877 {
01878   CalFilter *newFilter = 0;
01879   if ( filterNo > 0 && filterNo <= int(mFilters.count()) ) {
01880     newFilter = mFilters.at( filterNo-1 );
01881   }
01882   if ( newFilter != mCurrentFilter ) {
01883     mCurrentFilter = newFilter;
01884     mCalendar->setFilter( mCurrentFilter );
01885     updateView();
01886   }
01887   emit filterChanged();
01888 }
01889 
01890 QString CalendarView::currentFilterName() const
01891 {
01892   if ( mCurrentFilter) {
01893     return mCurrentFilter->name();
01894   } else return i18n("No filter");
01895 }
01896 
01897 void CalendarView::takeOverEvent()
01898 {
01899   Incidence *incidence = currentSelection();
01900 
01901   if (!incidence) return;
01902 
01903   incidence->setOrganizer( Person( KOPrefs::instance()->fullName(),
01904                            KOPrefs::instance()->email() ) );
01905   incidence->recreate();
01906   incidence->setReadOnly(false);
01907 
01908   updateView();
01909 }
01910 
01911 void CalendarView::takeOverCalendar()
01912 {
01913   Incidence::List incidences = mCalendar->rawIncidences();
01914   Incidence::List::Iterator it;
01915 
01916   for ( it = incidences.begin(); it != incidences.end(); ++it ) {
01917     (*it)->setOrganizer( Person( KOPrefs::instance()->fullName(),
01918                          KOPrefs::instance()->email() ) );
01919     (*it)->recreate();
01920     (*it)->setReadOnly(false);
01921   }
01922   updateView();
01923 }
01924 
01925 void CalendarView::showIntro()
01926 {
01927   kdDebug(5850) << "To be implemented." << endl;
01928 }
01929 
01930 void CalendarView::showDateNavigator( bool show )
01931 {
01932   if( show )
01933     mDateNavigator->show();
01934   else
01935     mDateNavigator->hide();
01936 }
01937 
01938 void CalendarView::showTodoView( bool show )
01939 {
01940   if( show )
01941     mTodoList->show();
01942   else
01943     mTodoList->hide();
01944 }
01945 
01946 void CalendarView::showEventViewer( bool show )
01947 {
01948   if( show )
01949     mEventViewer->show();
01950   else
01951     mEventViewer->hide();
01952 }
01953 
01954 
01955 void CalendarView::addView(KOrg::BaseView *view)
01956 {
01957   mViewManager->addView(view);
01958 }
01959 
01960 void CalendarView::showView(KOrg::BaseView *view)
01961 {
01962   mViewManager->showView(view);
01963 }
01964 
01965 void CalendarView::addExtension( CalendarViewExtension::Factory *factory )
01966 {
01967   CalendarViewExtension *extension = factory->create( mLeftSplitter );
01968 
01969   mExtensions.append( extension );
01970 }
01971 
01972 void CalendarView::toggleExpand()
01973 {
01974   showLeftFrame( mLeftFrame->isHidden() );
01975 }
01976 
01977 void CalendarView::showLeftFrame(bool show)
01978 {
01979   if (show) {
01980     mLeftFrame->show();
01981     emit calendarViewExpanded( false );
01982   } else {
01983     mLeftFrame->hide();
01984     emit calendarViewExpanded( true );
01985   }
01986 }
01987 
01988 void CalendarView::calendarModified( bool modified, Calendar * )
01989 {
01990   setModified( modified );
01991 }
01992 
01993 Todo *CalendarView::selectedTodo()
01994 {
01995   Incidence *incidence = currentSelection();
01996   if ( incidence && incidence->type() == "Todo" ) {
01997     return static_cast<Todo *>( incidence );
01998   }
01999   incidence = 0;
02000 
02001   Incidence::List selectedIncidences = mTodoList->selectedIncidences();
02002   if ( !selectedIncidences.isEmpty() ) incidence = selectedIncidences.first();
02003   if ( incidence && incidence->type() == "Todo" ) {
02004     return static_cast<Todo *>( incidence );
02005   }
02006 
02007   return 0;
02008 }
02009 
02010 void CalendarView::dialogClosing( Incidence *in )
02011 {
02012   // FIXME: this doesn't work, because if it's a new incidence, it's not locked!
02013   mChanger->endChange( in );
02014   mDialogList.remove( in );
02015 }
02016 
02017 Incidence *CalendarView::currentSelection()
02018 {
02019   return mViewManager->currentSelection();
02020 }
02021 
02022 Incidence* CalendarView::selectedIncidence()
02023 {
02024   Incidence *incidence = currentSelection();
02025   if ( !incidence ) {
02026     Incidence::List selectedIncidences = mTodoList->selectedIncidences();
02027     if ( !selectedIncidences.isEmpty() )
02028       incidence = selectedIncidences.first();
02029   }
02030   return incidence;
02031 }
02032 
02033 void CalendarView::showIncidence()
02034 {
02035   showIncidence( selectedIncidence() );
02036 }
02037 
02038 void CalendarView::editIncidence()
02039 {
02040   editIncidence( selectedIncidence(), activeIncidenceDate() );
02041 }
02042 
02043 bool CalendarView::editIncidence( const QString &uid )
02044 {
02045   return editIncidence( mCalendar->incidence( uid ), QDate() );
02046 }
02047 
02048 bool CalendarView::editIncidence( const QString &uid, const QDate &date )
02049 {
02050   return editIncidence( mCalendar->incidence( uid ), date );
02051 }
02052 
02053 void CalendarView::deleteIncidence()
02054 {
02055   deleteIncidence( selectedIncidence() );
02056 }
02057 
02058 void CalendarView::cutIncidence(Incidence *)
02059 {
02060   edit_cut();
02061 }
02062 
02063 void CalendarView::copyIncidence(Incidence *)
02064 {
02065   edit_copy();
02066 }
02067 
02068 void CalendarView::pasteIncidence()
02069 {
02070   edit_paste();
02071 }
02072 
02073 void CalendarView::showIncidence( Incidence *incidence )
02074 {
02075   KOEventViewerDialog *eventViewer = new KOEventViewerDialog( calendar(), this );
02076   eventViewer->setIncidence( incidence, QDate() );
02077   eventViewer->show();
02078 }
02079 
02080 bool CalendarView::editIncidence( Incidence *incidence )
02081 {
02082   return editIncidence( incidence, QDate(), false );
02083 }
02084 
02085 bool CalendarView::editIncidence( Incidence *incidence, const QDate &date, bool isCounter )
02086 {
02087   kdDebug(5850) << "CalendarView::editEvent()" << endl;
02088 
02089   CalendarResources *stdcal = dynamic_cast<CalendarResources *>( mCalendar );
02090   if( stdcal && !stdcal->hasCalendarResources() ) {
02091     KMessageBox::sorry(
02092       this,
02093       i18n( "No resources found. We can not edit the item." ) );
02094     return false;
02095   }
02096 
02097   // FIXME: This is a nasty hack, since we need to set a parent for the
02098   //        resource selection dialog. However, we don't have any UI methods
02099   //        in the calendar, only in the CalendarResources::DestinationPolicy
02100   //        So we need to type-cast it and extract it from the CalendarResources
02101   QWidget *tmpparent = 0;
02102   if ( stdcal ) {
02103     tmpparent = stdcal->dialogParentWidget();
02104     stdcal->setDialogParentWidget( this );
02105   }
02106 
02107   if ( !incidence ) {
02108     kdDebug(5850) << "Empty Incidence" << endl;
02109     KNotifyClient::beep();
02110     return false;
02111   }
02112 
02113   if ( !mChanger ) {
02114     kdDebug(5850) << "Empty Changer" << endl;
02115     KNotifyClient::beep();
02116     return false;
02117   }
02118 
02119   KOIncidenceEditor *tmp = editorDialog( incidence );
02120   if ( tmp ) {
02121     kdDebug(5850) << "CalendarView::editIncidence() in List" << endl;
02122     tmp->reload();
02123     tmp->raise();
02124     tmp->show();
02125     return true;
02126   }
02127 
02128   if ( incidence->isReadOnly() ) {
02129     showIncidence( incidence );
02130     return true;
02131   }
02132   Incidence *savedIncidence = incidence->clone();
02133   Incidence *incToChange;
02134 
02135   if ( incidence->doesRecur() ) {
02136     KOGlobals::WhichOccurrences chosenOption;
02137     incToChange = singleOccurrenceOrAll( incidence, KOGlobals::EDIT, chosenOption, date );
02138   } else {
02139     incToChange = incidence;
02140   }
02141 
02142   // If the user pressed cancel incToChange is 0
02143   if ( incToChange ) {
02144     if ( !isCounter && !mChanger->beginChange( incToChange ) ) {
02145       warningChangeFailed( incToChange );
02146       showIncidence( incToChange );
02147 
02148       return false;
02149     }
02150 
02151     kdDebug(5850) << "CalendarView::editIncidence() new IncidenceEditor" << endl;
02152     KOIncidenceEditor *incidenceEditor = mDialogManager->getEditor( incToChange );
02153     connectIncidenceEditor( incidenceEditor );
02154 
02155     mDialogList.insert( incToChange, incidenceEditor );
02156     if ( incidence != incToChange ) {
02157       incidenceEditor->setRecurringIncidence( savedIncidence, incidence );
02158     }
02159     QPair<ResourceCalendar *, QString>p = viewSubResourceCalendar();
02160     incidenceEditor->setResource( p.first, p.second );
02161     incidenceEditor->editIncidence( incToChange, date, mCalendar );
02162     incidenceEditor->show();
02163     return true;
02164   } else {
02165     return false;
02166   }
02167 }
02168 
02169 void CalendarView::deleteSubTodosIncidence ( Todo *todo )
02170 {
02171   if( !todo ) return;
02172 
02173   Incidence::List subTodos( todo->relations() );
02174   Incidence::List::Iterator it;
02175   Incidence *aIncidence;
02176   Todo *aTodo;
02177 
02178   for ( it= subTodos.begin(); it != subTodos.end(); ++it ) {
02179     aIncidence = *it;
02180     if( aIncidence && aIncidence->type() == "Todo" ) {
02181       aTodo = static_cast<Todo*>( aIncidence );
02182       deleteSubTodosIncidence ( aTodo );
02183     }
02184   }
02185   mChanger->deleteIncidence ( todo, this );
02186 }
02187 
02188 void CalendarView::deleteTodoIncidence ( Todo *todo, bool force )
02189 {
02190   if ( !todo ) return ;
02191 
02192   // it a simple todo, ask and delete it.
02193   if (todo->relations().isEmpty() ) {
02194     bool doDelete = true;
02195     if ( !force && KOPrefs::instance()->mConfirm ) {
02196       doDelete = ( msgItemDelete( todo ) == KMessageBox::Continue );
02197     }
02198     if ( doDelete )
02199       mChanger->deleteIncidence( todo, this );
02200     return;
02201   }
02202 
02203   /* Ok, this to-do has sub-to-dos, ask what to do */
02204   int km = KMessageBox::No;
02205   if ( !force ) {
02206     km = KMessageBox::questionYesNoCancel(
02207       this,
02208       i18n("The item \"%1\" has sub-to-dos. "
02209            "Do you want to delete just this item and "
02210            "make all its sub-to-dos independent, or "
02211            "delete the to-do with all its sub-to-dos?"
02212         ).arg( todo->summary() ),
02213       i18n("KOrganizer Confirmation"),
02214       i18n("Delete Only This"),
02215       i18n("Delete All"));
02216   }
02217   startMultiModify( i18n("Deleting sub-to-dos" ) );
02218   // Delete only the father
02219   if( km == KMessageBox::Yes ) {
02220 
02221     makeSubTodosIndependents ( todo );
02222     mChanger->deleteIncidence( todo, this );
02223   } else if ( km == KMessageBox::No ) {
02224     // Delete all
02225     // we have to hide the delete confirmation for each itemDate
02226     deleteSubTodosIncidence ( todo );
02227   }
02228   endMultiModify();
02229 }
02230 
02231 void CalendarView::deleteIncidence(Incidence *incidence, bool force)
02232 {
02233   if ( !incidence || !mChanger ) {
02234     if ( !force ) {
02235       KNotifyClient::beep();
02236     }
02237     return;
02238   }
02239   if ( incidence->isReadOnly() ) {
02240     if ( !force ) {
02241       KMessageBox::information( this, i18n("The item \"%1\" is marked read-only "
02242                                 "and cannot be deleted; it probably belongs to "
02243                                 "a read-only calendar resource.")
02244                                 .arg(incidence->summary()),
02245                                 i18n("Removing not possible"),
02246                                 "deleteReadOnlyIncidence" );
02247     }
02248     return;
02249   }
02250 
02251   CanDeleteIncidenceVisitor v;
02252 
02253   // Let the visitor do special things for special incidence types.
02254   // e.g. todos with children cannot be deleted, so act(..) returns false
02255   if ( !v.act( incidence, this ) )
02256     return;
02257   //If it is a todo, there are specific delete function
02258 
02259   if ( incidence && incidence->type()=="Todo" ) {
02260     deleteTodoIncidence( static_cast<Todo*>(incidence), force );
02261     return;
02262   }
02263 
02264   if ( incidence->doesRecur() ) {
02265     QDate itemDate = mViewManager->currentSelectionDate();
02266     kdDebug(5850) << "Recurrence-Date: " << itemDate.toString() << endl;
02267     int km = KMessageBox::Ok;
02268     if ( !force ) {
02269       if ( !itemDate.isValid() ) {
02270         kdDebug(5850) << "Date Not Valid" << endl;
02271         km = KMessageBox::warningContinueCancel(this,
02272           i18n("The calendar item \"%1\" recurs over multiple dates; "
02273                "are you sure you want to delete it "
02274                "and all its recurrences?").arg( incidence->summary() ),
02275                i18n("KOrganizer Confirmation"), i18n("Delete All") );
02276       } else {
02277         km = KOMessageBox::fourBtnMsgBox( this, QMessageBox::Warning,
02278           i18n("The calendar item \"%1\" recurs over multiple dates. "
02279                "Do you want to delete only the current one on %2, only all "
02280                "future recurrences, or all its recurrences?" )
02281                .arg( incidence->summary() )
02282                .arg( KGlobal::locale()->formatDate(itemDate)),
02283                i18n("KOrganizer Confirmation"), i18n("Delete C&urrent"),
02284                i18n("Delete &Future"),
02285                i18n("Delete &All"));
02286       }
02287     }
02288     switch(km) {
02289       case KMessageBox::Ok: // Continue // all
02290       case KMessageBox::Continue:
02291         mChanger->deleteIncidence( incidence, this );
02292         break;
02293 
02294       case KMessageBox::Yes: // just this one
02295         if ( mChanger->beginChange( incidence ) ) {
02296           Incidence *oldIncidence = incidence->clone();
02297           incidence->recurrence()->addExDate( itemDate );
02298           mChanger->changeIncidence( oldIncidence, incidence,
02299                                      KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY, this );
02300           mChanger->endChange( incidence );
02301           delete oldIncidence;
02302         }
02303         break;
02304       case KMessageBox::No: // all future items
02305         if ( mChanger->beginChange( incidence ) ) {
02306           Incidence *oldIncidence = incidence->clone();
02307           Recurrence *recur = incidence->recurrence();
02308           recur->setEndDate( itemDate.addDays(-1) );
02309           mChanger->changeIncidence( oldIncidence, incidence,
02310                                      KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE,  this );
02311           mChanger->endChange( incidence );
02312           delete oldIncidence;
02313         }
02314         break;
02315     }
02316   } else {
02317     bool doDelete = true;
02318     if ( !force && KOPrefs::instance()->mConfirm ) {
02319       doDelete = ( msgItemDelete( incidence ) == KMessageBox::Continue );
02320     }
02321     if ( doDelete ) {
02322       mChanger->deleteIncidence( incidence, this );
02323       processIncidenceSelection( 0, QDate() );
02324     }
02325   }
02326 }
02327 
02328 void CalendarView::connectIncidenceEditor( KOIncidenceEditor *editor )
02329 {
02330   connect( this, SIGNAL( newIncidenceChanger( IncidenceChangerBase* ) ),
02331            editor, SLOT( setIncidenceChanger( IncidenceChangerBase* ) ) );
02332   editor->setIncidenceChanger( mChanger );
02333 }
02334 
02335 bool CalendarView::purgeCompletedSubTodos( Todo* todo, bool &allPurged )
02336 {
02337   if ( !todo ) return true;
02338   bool deleteThisTodo = true;
02339   Incidence::List subTodos( todo->relations() );
02340   Incidence *aIncidence;
02341   Todo *aTodo;
02342   Incidence::List::Iterator it;
02343   for ( it = subTodos.begin(); it != subTodos.end(); ++it ) {
02344     aIncidence = *it;
02345     if ( aIncidence && aIncidence->type()=="Todo" ) {
02346       aTodo = static_cast<Todo*>( aIncidence );
02347       deleteThisTodo &= purgeCompletedSubTodos( aTodo, allPurged );
02348     }
02349   }
02350 
02351   if ( deleteThisTodo ) {
02352     if ( todo->isCompleted() ) {
02353       if ( !mChanger->deleteIncidence( todo, this ) )
02354         allPurged = false;
02355     } else {
02356       deleteThisTodo = false;
02357     }
02358   } else {
02359     if ( todo->isCompleted() ) {
02360       allPurged = false;
02361     }
02362   }
02363   return deleteThisTodo;
02364 }
02365 
02366 void CalendarView::purgeCompleted()
02367 {
02368   int result = KMessageBox::warningContinueCancel(this,
02369       i18n("Delete all completed to-dos?"),i18n("Purge To-dos"),i18n("Purge"));
02370 
02371   if (result == KMessageBox::Continue) {
02372     bool allDeleted = true;
02373     startMultiModify( i18n("Purging completed to-dos") );
02374     Todo::List todos = calendar()->rawTodos();
02375     Todo::List rootTodos;
02376     Todo::List::ConstIterator it;
02377     for ( it = todos.begin(); it != todos.end(); ++it ) {
02378       Todo *aTodo = *it;
02379       if ( aTodo && !aTodo->relatedTo() )
02380         rootTodos.append( aTodo );
02381     }
02382     // now that we have a list of all root todos, check them and their children
02383     for ( it = rootTodos.begin(); it != rootTodos.end(); ++it ) {
02384       purgeCompletedSubTodos( *it, allDeleted );
02385     }
02386     endMultiModify();
02387     if ( !allDeleted ) {
02388       KMessageBox::information( this, i18n("Unable to purge to-dos with "
02389                                 "uncompleted children."), i18n("Delete To-do"),
02390                                 "UncompletedChildrenPurgeTodos" );
02391     }
02392   }
02393 }
02394 
02395 void CalendarView::warningChangeFailed( Incidence *incidence )
02396 {
02397   if ( incidence ) {
02398     KMessageBox::sorry(
02399       this,
02400       i18n( "Unable to edit \"%1\" because it is locked by another process." ).
02401       arg( incidence->summary() ) );
02402   }
02403 }
02404 
02405 void CalendarView::editCanceled( Incidence *incidence )
02406 {
02407   mCalendar->endChange( incidence );
02408 }
02409 
02410 void CalendarView::showErrorMessage( const QString &msg )
02411 {
02412   KMessageBox::error( this, msg );
02413 }
02414 
02415 void CalendarView::updateCategories()
02416 {
02417   QStringList allCats( calendar()->categories() );
02418   allCats.sort();
02419   QStringList categories( KOPrefs::instance()->mCustomCategories );
02420   for ( QStringList::ConstIterator si = allCats.constBegin(); si != allCats.constEnd(); ++si ) {
02421     if ( categories.find( *si ) == categories.end() ) {
02422       categories.append( *si );
02423     }
02424   }
02425   KOPrefs::instance()->mCustomCategories = categories;
02426   KOPrefs::instance()->writeConfig();
02427   // Make the category editor update the list!
02428   emit categoriesChanged();
02429 }
02430 
02431 void CalendarView::addIncidenceOn( Incidence *incadd, const QDate &dt )
02432 {
02433   if ( !incadd || !mChanger ) {
02434     KMessageBox::sorry(this, i18n("Unable to copy the item to %1.")
02435                        .arg( dt.toString() ), i18n("Copying Failed") );
02436     return;
02437   }
02438   Incidence *incidence = mCalendar->incidence( incadd->uid() );
02439   if ( !incidence ) incidence = incadd;
02440   // Create a copy of the incidence, since the incadd doesn't belong to us.
02441   incidence = incidence->clone();
02442   incidence->recreate();
02443 
02444   if ( incidence->type() == "Event" ) {
02445     Event *event = static_cast<Event*>(incidence);
02446 
02447     // Adjust date
02448     QDateTime start = event->dtStart();
02449     QDateTime end = event->dtEnd();
02450 
02451     int duration = start.daysTo( end );
02452     start.setDate( dt );
02453     end.setDate( dt.addDays( duration ) );
02454 
02455     event->setDtStart( start );
02456     event->setDtEnd( end );
02457 
02458   } else if ( incidence->type() == "Todo" ) {
02459     Todo *todo = static_cast<Todo*>(incidence);
02460     QDateTime due = todo->dtDue();
02461     due.setDate( dt );
02462 
02463     todo->setDtDue( due );
02464     todo->setHasDueDate( true );
02465   }
02466 
02467   QPair<ResourceCalendar *, QString>p = viewSubResourceCalendar();
02468 
02469   if ( !mChanger->addIncidence( incidence, p.first, p.second, this ) ) {
02470     KODialogManager::errorSaveIncidence( this, incidence );
02471     delete incidence;
02472   }
02473 }
02474 
02475 void CalendarView::moveIncidenceTo( Incidence *incmove, const QDate &dt )
02476 {
02477   if ( !incmove || !mChanger ) {
02478     KMessageBox::sorry( this, i18n("Unable to move the item to %1.")
02479                         .arg( dt.toString() ), i18n("Moving Failed") );
02480     return;
02481   }
02482   Incidence *incidence = mCalendar->incidence( incmove->uid() );
02483   if ( !incidence ) {
02484     addIncidenceOn( incidence, dt );
02485     return;
02486   }
02487   Incidence *oldIncidence = incidence->clone();
02488   if ( !mChanger->beginChange( incidence ) ) {
02489     delete oldIncidence;
02490     return;
02491   }
02492 
02493   if ( incidence->type() == "Event" ) {
02494     Event *event = static_cast<Event*>(incidence);
02495 
02496     // Adjust date
02497     QDateTime start = event->dtStart();
02498     QDateTime end = event->dtEnd();
02499 
02500     int duration = start.daysTo( end );
02501     start.setDate( dt );
02502     end.setDate( dt.addDays( duration ) );
02503 
02504     event->setDtStart( start );
02505     event->setDtEnd( end );
02506 
02507   } else if ( incidence->type() == "Todo" ) {
02508     Todo *todo = static_cast<Todo*>(incidence);
02509     QDateTime due = todo->dtDue();
02510     due.setDate( dt );
02511 
02512     todo->setDtDue( due );
02513     todo->setHasDueDate( true );
02514   }
02515   mChanger->changeIncidence( oldIncidence, incidence, KOGlobals::DATE_MODIFIED,this );
02516   mChanger->endChange( incidence );
02517   delete oldIncidence;
02518 }
02519 
02520 void CalendarView::resourcesChanged()
02521 {
02522   mViewManager->resourcesChanged();
02523   mDateNavigator->setUpdateNeeded();
02524   updateView();
02525 }
02526 
02527 Incidence* CalendarView::singleOccurrenceOrAll( Incidence *inc,
02528                                                 KOGlobals::OccurrenceAction userAction,
02529                                                 KOGlobals::WhichOccurrences &chosenOption,
02530                                                 const QDate &itemDate,
02531                                                 const bool commitToCalendar )
02532 {
02533 
02534   // temporary, until recurring to-dos are fixed
02535   if ( inc->type() != "Event" ) {
02536     chosenOption = KOGlobals::ALL;
02537     return inc;
02538   }
02539 
02540   Incidence *incToReturn = 0;
02541   Incidence *incSaved = 0;
02542   KOGlobals::WhatChanged whatChanged;
02543 
02544   bool dissociationOccurred = false;
02545   const QDate &dt = itemDate.isValid() ? itemDate : activeIncidenceDate();
02546 
02547   QString dialogTitle;
02548   QString dialogText;
02549 
02550   if ( userAction == KOGlobals::CUT ) {
02551     dialogTitle = i18n( "Cutting Recurring Item" );
02552 
02553     dialogText = i18n("The item you try to cut is a recurring item. Do you want to cut "
02554                        "only this single occurrence, only future items, "
02555                        "or all items in the recurrence?");
02556 
02557   } else if ( userAction == KOGlobals::COPY ) {
02558     dialogTitle = i18n( "Copying Recurring Item" );
02559 
02560     dialogText = i18n("The item you try to copy is a recurring item. Do you want to copy "
02561                        "only this single occurrence, only future items, "
02562                        "or all items in the recurrence?");
02563   } else {
02564     dialogTitle = i18n( "Changing Recurring Item" );
02565 
02566     dialogText = i18n( "The item you try to change is a recurring item. Shall the changes "
02567                        "be applied only to this single occurrence, only to the future items, "
02568                        "or to all items in the recurrence?" );
02569   }
02570 
02571   int res = KOMessageBox::fourBtnMsgBox( this, QMessageBox::Question,
02572             dialogText,
02573             dialogTitle,
02574             i18n("Only &This Item"), i18n("Only &Future Items"), i18n("&All Occurrences") );
02575   switch ( res ) {
02576     case KMessageBox::Ok: // All occurrences
02577       incToReturn = inc;
02578       chosenOption = KOGlobals::ALL;
02579       break;
02580     case KMessageBox::Yes: { // Just this occurrence
02581       // Dissociate this occurrence:
02582       // create clone of event, set relation to old event, set cloned event
02583       // for mActionItem, add exception date to old event, changeIncidence
02584       // for the old event, remove the recurrence from the new copy and then just
02585       // go on with the newly adjusted mActionItem and let the usual code take
02586       // care of the new time!
02587 
02588       chosenOption = KOGlobals::ONLY_THIS_ONE;
02589       whatChanged  = KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY;
02590       startMultiModify( i18n("Dissociate event from recurrence") );
02591       incSaved = inc->clone();
02592       incToReturn = mCalendar->dissociateOccurrence( inc, dt );
02593       if ( incToReturn ) {
02594         dissociationOccurred = true;
02595       } else {
02596         KMessageBox::sorry( this, i18n("Unable to add the exception item to the "
02597             "calendar. No change will be done."), i18n("Error Occurred") );
02598         incToReturn = 0;
02599       }
02600 
02601       break; }
02602     case KMessageBox::No/*Future*/: { // All future occurrences
02603       // Dissociate this occurrence:
02604       // create clone of event, set relation to old event, set cloned event
02605       // for mActionItem, add recurrence end date to old event, changeIncidence
02606       // for the old event, adjust the recurrence for the new copy and then just
02607       // go on with the newly adjusted mActionItem and let the usual code take
02608       // care of the new time!
02609       chosenOption = KOGlobals::ONLY_FUTURE;
02610       whatChanged  = KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE;
02611       startMultiModify( i18n("Split future recurrences") );
02612       incSaved = inc->clone();
02613       incToReturn = mCalendar->dissociateOccurrence( inc, dt, false );
02614       if ( incToReturn ) {
02615         dissociationOccurred = true;
02616       } else {
02617         // por aqui controlo de erros
02618         KMessageBox::sorry( this, i18n("Unable to add the future items to the "
02619             "calendar. No change will be done."), i18n("Error Occurred") );
02620 
02621         incToReturn = 0;
02622       }
02623 
02624       break; }
02625     default:
02626       chosenOption = KOGlobals::NONE;
02627   }
02628 
02629   if ( dissociationOccurred && commitToCalendar ) {
02630     QPair<ResourceCalendar *, QString>p = viewSubResourceCalendar();
02631     mChanger->addIncidence( incToReturn, p.first, p.second, this );
02632     mChanger->changeIncidence( incSaved, inc, whatChanged, this );
02633   }
02634 
02635   return incToReturn;
02636 }
02637 
02638 void CalendarView::selectWeek( const QDate &date )
02639 {
02640   if ( KOPrefs::instance()->mWeekNumbersShowWork                 &&
02641        mViewManager->currentView() == mViewManager->agendaView() &&
02642        mViewManager->agendaMode()  == KOViewManager::AGENDA_WORK_WEEK ) {
02643     mNavigator->selectWorkWeek( date );
02644   } else {
02645     mNavigator->selectWeek( date );
02646   }
02647 }
02648 
02649 #include "calendarview.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys