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