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