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, bool inlineAttachment )
01013 {
01014 kdDebug(5850) << k_funcinfo << endl;
01015 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01016 connectIncidenceEditor( todoEditor );
01017 todoEditor->newTodo();
01018 todoEditor->setTexts( summary, description );
01019 todoEditor->addAttachments( attachments, attachmentMimetypes, inlineAttachment );
01020 todoEditor->addAttendees( attendees );
01021 todoEditor->show();
01022 }
01023
01024 void CalendarView::newTodo()
01025 {
01026 kdDebug(5850) << k_funcinfo << endl;
01027 QDateTime dtDue;
01028 bool allday = true;
01029 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01030 connectIncidenceEditor( todoEditor );
01031 todoEditor->newTodo();
01032 if ( mViewManager->currentView()->isEventView() ) {
01033 dtDue.setDate( mNavigator->selectedDates().first() );
01034 QDateTime dtDummy = QDateTime::currentDateTime();
01035 mViewManager->currentView()->
01036 eventDurationHint( dtDue, dtDummy, allday );
01037 todoEditor->setDates( dtDue, allday );
01038 }
01039 todoEditor->show();
01040 }
01041
01042 void CalendarView::newTodo( const QDate &date )
01043 {
01044 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01045 connectIncidenceEditor( todoEditor );
01046 todoEditor->newTodo();
01047 todoEditor->setDates( QDateTime( date, QTime::currentTime() ), true );
01048 todoEditor->show();
01049 }
01050
01051 void CalendarView::newJournal()
01052 {
01053 kdDebug(5850) << "CalendarView::newJournal()" << endl;
01054 newJournal( QString::null, QDate() );
01055 }
01056
01057 void CalendarView::newJournal( const QDate &date)
01058 {
01059 newJournal( QString::null, date );
01060 }
01061
01062 void CalendarView::newJournal( const QString &text, const QDate &date )
01063 {
01064 KOJournalEditor *journalEditor = mDialogManager->getJournalEditor();
01065 connectIncidenceEditor( journalEditor );
01066 journalEditor->newJournal();
01067 journalEditor->setTexts( text );
01068 if ( !date.isValid() ) {
01069 journalEditor->setDate( mNavigator->selectedDates().first() );
01070 } else {
01071 journalEditor->setDate( date );
01072 }
01073 journalEditor->show();
01074 }
01075
01076 void CalendarView::newSubTodo()
01077 {
01078 Todo *todo = selectedTodo();
01079 if ( todo ) newSubTodo( todo );
01080 }
01081
01082 void CalendarView::newSubTodo(Todo *parentEvent)
01083 {
01084 KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
01085 connectIncidenceEditor( todoEditor );
01086 todoEditor->newTodo();
01087 todoEditor->setDates( QDateTime(), false, parentEvent );
01088 todoEditor->show();
01089 }
01090
01091 void CalendarView::newFloatingEvent()
01092 {
01093 DateList tmpList = mNavigator->selectedDates();
01094 QDate date = tmpList.first();
01095
01096 newEvent( QDateTime( date, QTime( 12, 0, 0 ) ),
01097 QDateTime( date, QTime( 12, 0, 0 ) ), true );
01098 }
01099
01100 bool CalendarView::addIncidence( const QString &ical )
01101 {
01102 kdDebug(5850) << "CalendarView::addIncidence:\n" << ical << endl;
01103 ICalFormat format;
01104 format.setTimeZone( mCalendar->timeZoneId(), true );
01105 Incidence *incidence = format.fromString( ical );
01106 if ( !incidence ) return false;
01107 if ( !mChanger->addIncidence( incidence, this ) ) {
01108 delete incidence;
01109 return false;
01110 }
01111 return true;
01112 }
01113
01114 void CalendarView::appointment_show()
01115 {
01116 Incidence *incidence = selectedIncidence();
01117 if (incidence)
01118 showIncidence( incidence );
01119 else
01120 KNotifyClient::beep();
01121 }
01122
01123 void CalendarView::appointment_edit()
01124 {
01125 Incidence *incidence = selectedIncidence();
01126 if (incidence)
01127 editIncidence( incidence );
01128 else
01129 KNotifyClient::beep();
01130 }
01131
01132 void CalendarView::appointment_delete()
01133 {
01134 Incidence *incidence = selectedIncidence();
01135 if (incidence)
01136 deleteIncidence( incidence );
01137 else
01138 KNotifyClient::beep();
01139 }
01140
01141 void CalendarView::todo_unsub()
01142 {
01143 Todo *anTodo = selectedTodo();
01144 if( todo_unsub (anTodo ) ) {
01145 updateView();
01146 }
01147 }
01148
01149 bool CalendarView::todo_unsub( Todo *todo )
01150 {
01151 bool status= false;
01152 if ( !todo || !todo->relatedTo() ) return false;
01153
01154 if ( mChanger->beginChange( todo ) ) {
01155 Todo *oldTodo = todo->clone();
01156 todo->setRelatedTo(0);
01157 mChanger->changeIncidence( oldTodo, todo, KOGlobals::RELATION_MODIFIED );
01158 mChanger->endChange( todo );
01159 delete oldTodo;
01160 setModified(true);
01161 status = true;
01162 }
01163 if ( ! status ) {
01164 KMessageBox::sorry( this, i18n("Unable to turn sub-to-do into a top-level "
01165 "to-do, because it cannot be locked.") );
01166 }
01167
01168 return status;
01169 }
01170
01171 bool CalendarView::makeSubTodosIndependents ( )
01172 {
01173 bool status = false;
01174 Todo *anTodo = selectedTodo();
01175
01176 if( makeSubTodosIndependents( anTodo ) ) {
01177 updateView();
01178 status = true;
01179 }
01180 return status;
01181 }
01182
01183 bool CalendarView::makeSubTodosIndependents ( Todo *todo )
01184 {
01185 if( !todo || todo->relations().isEmpty() ) return false;
01186
01187 startMultiModify ( i18n( "Make sub-to-dos independent" ) );
01188 Incidence::List subTodos( todo->relations() );
01189 Incidence::List::Iterator it;
01190 Incidence *aIncidence;
01191 Todo *aTodo;
01192
01193 for ( it= subTodos.begin(); it != subTodos.end(); ++it ) {
01194 aIncidence = *it;
01195 if( aIncidence && aIncidence->type() == "Todo" ) {
01196 aTodo = static_cast<Todo*>( aIncidence );
01197 todo_unsub ( aTodo );
01198 }
01199 }
01200 endMultiModify();
01201 return true;
01202 }
01203
01204 bool CalendarView::deleteIncidence( const QString &uid, bool force )
01205 {
01206 Incidence *inc = mCalendar->incidence( uid );
01207 if ( inc ) {
01208 deleteIncidence( inc, force );
01209 return true;
01210 } else {
01211 return false;
01212 }
01213 }
01214
01215 void CalendarView::toggleAlarm( Incidence *incidence )
01216 {
01217 if ( !incidence || !mChanger ) {
01218 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01219 return;
01220 }
01221 Incidence*oldincidence = incidence->clone();
01222 if ( !mChanger->beginChange( incidence ) ) {
01223 kdDebug(5850) << "Unable to lock incidence " << endl;
01224 delete oldincidence;
01225 return;
01226 }
01227
01228 Alarm::List alarms = incidence->alarms();
01229 Alarm::List::ConstIterator it;
01230 for( it = alarms.begin(); it != alarms.end(); ++it )
01231 (*it)->toggleAlarm();
01232 if (alarms.isEmpty()) {
01233
01234 Alarm*alm = incidence->newAlarm();
01235 alm->setEnabled(true);
01236 }
01237 mChanger->changeIncidence( oldincidence, incidence, KOGlobals::ALARM_MODIFIED );
01238 mChanger->endChange( incidence );
01239 delete oldincidence;
01240
01241
01242 }
01243
01244 void CalendarView::dissociateOccurrence( Incidence *incidence, const QDate &date )
01245 {
01246 if ( !incidence || !mChanger ) {
01247 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01248 return;
01249 }
01250 if ( !mChanger->beginChange( incidence ) ) {
01251 kdDebug(5850) << "Unable to lock incidence " << endl;
01252 return;
01253 }
01254 startMultiModify( i18n("Dissociate occurrence") );
01255 Incidence*oldincidence = incidence->clone();
01256
01257 Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
01258
01259 if ( newInc ) {
01260
01261 mChanger->changeIncidence( oldincidence, incidence );
01262 mChanger->addIncidence( newInc, this );
01263 } else {
01264 KMessageBox::sorry( this, i18n("Dissociating the occurrence failed."),
01265 i18n("Dissociating Failed") );
01266 }
01267 mChanger->endChange( incidence );
01268 endMultiModify();
01269 delete oldincidence;
01270 }
01271
01272 void CalendarView::dissociateFutureOccurrence( Incidence *incidence, const QDate &date )
01273 {
01274 if ( !incidence || !mChanger ) {
01275 kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
01276 return;
01277 }
01278 if ( !mChanger->beginChange( incidence ) ) {
01279 kdDebug(5850) << "Unable to lock incidence " << endl;
01280 return;
01281 }
01282 startMultiModify( i18n("Dissociate future occurrences") );
01283 Incidence*oldincidence = incidence->clone();
01284
01285 Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
01286 if ( newInc ) {
01287
01288 mChanger->changeIncidence( oldincidence, incidence );
01289 mChanger->addIncidence( newInc, this );
01290 } else {
01291 KMessageBox::sorry( this, i18n("Dissociating the future occurrences failed."),
01292 i18n("Dissociating Failed") );
01293 }
01294 endMultiModify();
01295 mChanger->endChange( incidence );
01296 delete oldincidence;
01297 }
01298
01299
01300
01301
01302
01303 void CalendarView::schedule_publish(Incidence *incidence)
01304 {
01305 if (incidence == 0)
01306 incidence = selectedIncidence();
01307
01308 if (!incidence) {
01309 KMessageBox::information( this, i18n("No item selected."),
01310 "PublishNoEventSelected" );
01311 return;
01312 }
01313
01314 PublishDialog *publishdlg = new PublishDialog();
01315 if (incidence->attendeeCount()>0) {
01316 Attendee::List attendees = incidence->attendees();
01317 Attendee::List::ConstIterator it;
01318 for( it = attendees.begin(); it != attendees.end(); ++it ) {
01319 publishdlg->addAttendee( *it );
01320 }
01321 }
01322 if ( publishdlg->exec() == QDialog::Accepted ) {
01323 Incidence *inc = incidence->clone();
01324 inc->registerObserver( 0 );
01325 inc->clearAttendees();
01326
01327
01328 KCal::MailScheduler scheduler( mCalendar );
01329 if ( scheduler.publish( incidence, publishdlg->addresses() ) ) {
01330 KMessageBox::information( this, i18n("The item information was successfully sent."),
01331 i18n("Publishing"), "IncidencePublishSuccess" );
01332 } else {
01333 KMessageBox::error( this, i18n("Unable to publish the item '%1'").arg( incidence->summary() ) );
01334 }
01335 }
01336 delete publishdlg;
01337 }
01338
01339 void CalendarView::schedule_request(Incidence *incidence)
01340 {
01341 schedule(Scheduler::Request,incidence);
01342 }
01343
01344 void CalendarView::schedule_refresh(Incidence *incidence)
01345 {
01346 schedule(Scheduler::Refresh,incidence);
01347 }
01348
01349 void CalendarView::schedule_cancel(Incidence *incidence)
01350 {
01351 schedule(Scheduler::Cancel,incidence);
01352 }
01353
01354 void CalendarView::schedule_add(Incidence *incidence)
01355 {
01356 schedule(Scheduler::Add,incidence);
01357 }
01358
01359 void CalendarView::schedule_reply(Incidence *incidence)
01360 {
01361 schedule(Scheduler::Reply,incidence);
01362 }
01363
01364 void CalendarView::schedule_counter(Incidence *incidence)
01365 {
01366 schedule(Scheduler::Counter,incidence);
01367 }
01368
01369 void CalendarView::schedule_declinecounter(Incidence *incidence)
01370 {
01371 schedule(Scheduler::Declinecounter,incidence);
01372 }
01373
01374 void CalendarView::schedule_forward(Incidence * incidence)
01375 {
01376 if (incidence == 0)
01377 incidence = selectedIncidence();
01378
01379 if (!incidence) {
01380 KMessageBox::information( this, i18n("No item selected."),
01381 "ForwardNoEventSelected" );
01382 return;
01383 }
01384
01385 PublishDialog publishdlg;
01386 if ( publishdlg.exec() == QDialog::Accepted ) {
01387 QString recipients = publishdlg.addresses();
01388 ICalFormat format;
01389 QString messageText = format.createScheduleMessage( incidence, Scheduler::Request );
01390 KOMailClient mailer;
01391 if ( mailer.mailTo( incidence, recipients, messageText ) ) {
01392
01393 KMessageBox::information( this, i18n("The item information was successfully sent."),
01394 i18n("Forwarding"), "IncidenceForwardSuccess" );
01395 } else {
01396 KMessageBox::error( this, i18n("Unable to forward the item '%1'").arg( incidence->summary() ) );
01397 }
01398 }
01399 }
01400
01401 void CalendarView::mailFreeBusy( int daysToPublish )
01402 {
01403 QDateTime start = QDateTime::currentDateTime();
01404 QDateTime end = start.addDays(daysToPublish);
01405
01406 FreeBusy *freebusy = new FreeBusy(mCalendar, start, end);
01407 freebusy->setOrganizer( Person( KOPrefs::instance()->fullName(),
01408 KOPrefs::instance()->email() ) );
01409
01410 kdDebug(5850) << "calendarview: schedule_publish_freebusy: startDate: "
01411 << KGlobal::locale()->formatDateTime( start ) << " End Date: "
01412 << KGlobal::locale()->formatDateTime( end ) << endl;
01413
01414 PublishDialog *publishdlg = new PublishDialog();
01415 if ( publishdlg->exec() == QDialog::Accepted ) {
01416
01417 KCal::MailScheduler scheduler( mCalendar );
01418 if ( scheduler.publish( freebusy, publishdlg->addresses() ) ) {
01419 KMessageBox::information( this, i18n("The free/busy information was successfully sent."),
01420 i18n("Sending Free/Busy"), "FreeBusyPublishSuccess" );
01421 } else {
01422 KMessageBox::error( this, i18n("Unable to publish the free/busy data.") );
01423 }
01424 }
01425 delete freebusy;
01426 delete publishdlg;
01427 }
01428
01429 void CalendarView::uploadFreeBusy()
01430 {
01431 KOGroupware::instance()->freeBusyManager()->publishFreeBusy();
01432 }
01433
01434 void CalendarView::schedule(Scheduler::Method method, Incidence *incidence)
01435 {
01436 if ( !incidence ) {
01437 incidence = selectedIncidence();
01438 }
01439
01440 if ( !incidence ) {
01441 KMessageBox::sorry( this, i18n("No item selected."),
01442 "ScheduleNoEventSelected" );
01443 return;
01444 }
01445
01446 if( incidence->attendeeCount() == 0 && method != Scheduler::Publish ) {
01447 KMessageBox::information( this, i18n("The item has no attendees."),
01448 "ScheduleNoIncidences" );
01449 return;
01450 }
01451
01452 Incidence *inc = incidence->clone();
01453 inc->registerObserver( 0 );
01454 inc->clearAttendees();
01455
01456
01457 KCal::MailScheduler scheduler( mCalendar );
01458 if ( scheduler.performTransaction( incidence, method ) ) {
01459 KMessageBox::information( this, i18n("The groupware message for item '%1'"
01460 "was successfully sent.\nMethod: %2")
01461 .arg( incidence->summary() )
01462 .arg( Scheduler::methodName( method ) ),
01463 i18n("Sending Free/Busy"),
01464 "FreeBusyPublishSuccess" );
01465 } else {
01466 KMessageBox::error( this, i18n("Groupware message sending failed. "
01467 "%2 is request/reply/add/cancel/counter/etc.",
01468 "Unable to send the item '%1'.\nMethod: %2")
01469 .arg( incidence->summary() )
01470 .arg( Scheduler::methodName( method ) ) );
01471 }
01472 }
01473
01474 void CalendarView::openAddressbook()
01475 {
01476 KRun::runCommand("kaddressbook");
01477 }
01478
01479 void CalendarView::setModified(bool modified)
01480 {
01481 if (mModified != modified) {
01482 mModified = modified;
01483 emit modifiedChanged(mModified);
01484 }
01485 }
01486
01487 bool CalendarView::isReadOnly()
01488 {
01489 return mReadOnly;
01490 }
01491
01492 void CalendarView::setReadOnly(bool readOnly)
01493 {
01494 if (mReadOnly != readOnly) {
01495 mReadOnly = readOnly;
01496 emit readOnlyChanged(mReadOnly);
01497 }
01498 }
01499
01500 bool CalendarView::isModified()
01501 {
01502 return mModified;
01503 }
01504
01505 void CalendarView::print()
01506 {
01507 #ifndef KORG_NOPRINTER
01508 KOCoreHelper helper;
01509 CalPrinter printer( this, mCalendar, &helper );
01510 connect( this, SIGNAL(configChanged()), &printer, SLOT(updateConfig()) );
01511
01512 KOrg::BaseView *currentView = mViewManager->currentView();
01513
01514 CalPrinterBase::PrintType printType = CalPrinterBase::Month;
01515 if ( currentView ) printType = currentView->printType();
01516
01517 DateList tmpDateList = mNavigator->selectedDates();
01518 Incidence::List selectedIncidences;
01519 if ( mViewManager->currentView() ) {
01520 selectedIncidences = mViewManager->currentView()->selectedIncidences();
01521 }
01522 printer.print( printType, tmpDateList.first(), tmpDateList.last(), selectedIncidences );
01523 #endif
01524 }
01525
01526 void CalendarView::exportWeb()
01527 {
01528
01529 HTMLExportSettings *settings = new HTMLExportSettings( "KOrganizer" );
01530
01531
01532 if ( settings ) settings->readConfig();
01533 ExportWebDialog *dlg = new ExportWebDialog( settings, this );
01534 connect( dlg, SIGNAL( exportHTML( HTMLExportSettings* ) ),
01535 this, SIGNAL( exportHTML( HTMLExportSettings* ) ) );
01536 dlg->show();
01537 }
01538
01539 void CalendarView::exportICalendar()
01540 {
01541 QString filename = KFileDialog::getSaveFileName("icalout.ics",i18n("*.ics|ICalendars"),this);
01542 if ( !filename.isEmpty() )
01543 {
01544
01545 if (filename.right(4) != ".ics") filename += ".ics";
01546 if ( QFile( filename ).exists() ) {
01547 if ( KMessageBox::No == KMessageBox::warningYesNo(
01548 this,
01549 i18n( "Do you want to overwrite %1?").arg(filename) ) ) {
01550 return;
01551 }
01552 }
01553 FileStorage storage( mCalendar, filename, new ICalFormat );
01554 storage.save();
01555 }
01556 }
01557
01558 void CalendarView::exportVCalendar()
01559 {
01560 if (mCalendar->journals().count() > 0) {
01561 int result = KMessageBox::warningContinueCancel(this,
01562 i18n("The journal entries can not be exported to a vCalendar file."),
01563 i18n("Data Loss Warning"),i18n("Proceed"),"dontaskVCalExport",
01564 true);
01565 if (result != KMessageBox::Continue) return;
01566 }
01567
01568 QString filename = KFileDialog::getSaveFileName("vcalout.vcs",i18n("*.vcs|vCalendars"),this);
01569 if ( !filename.isEmpty() )
01570 {
01571
01572
01573 if (filename.right(4) != ".vcs") filename += ".vcs";
01574 if ( QFile( filename ).exists() ) {
01575 if ( KMessageBox::No == KMessageBox::warningYesNo(
01576 this,
01577 i18n( "Do you want to overwrite %1?").arg(filename ) ) ) {
01578 return;
01579 }
01580 }
01581 FileStorage storage( mCalendar, filename, new VCalFormat );
01582 storage.save();
01583 }
01584 }
01585
01586 void CalendarView::eventUpdated(Incidence *)
01587 {
01588 setModified();
01589
01590
01591
01592 }
01593
01594 void CalendarView::adaptNavigationUnits()
01595 {
01596 if (mViewManager->currentView()->isEventView()) {
01597 int days = mViewManager->currentView()->currentDateCount();
01598 if (days == 1) {
01599 emit changeNavStringPrev(i18n("&Previous Day"));
01600 emit changeNavStringNext(i18n("&Next Day"));
01601 } else {
01602 emit changeNavStringPrev(i18n("&Previous Week"));
01603 emit changeNavStringNext(i18n("&Next Week"));
01604 }
01605 }
01606 }
01607
01608 void CalendarView::processMainViewSelection( Incidence *incidence )
01609 {
01610 if ( incidence ) mTodoList->clearSelection();
01611 processIncidenceSelection( incidence );
01612 }
01613
01614 void CalendarView::processTodoListSelection( Incidence *incidence )
01615 {
01616 if ( incidence && mViewManager->currentView() ) {
01617 mViewManager->currentView()->clearSelection();
01618 }
01619 processIncidenceSelection( incidence );
01620 }
01621
01622 void CalendarView::processIncidenceSelection( Incidence *incidence )
01623 {
01624 if ( incidence == mSelectedIncidence ) return;
01625
01626 mSelectedIncidence = incidence;
01627
01628 emit incidenceSelected( mSelectedIncidence );
01629 bool organizerEvents = false;
01630 bool groupEvents = false;
01631 bool todo = false;
01632 bool subtodo = false;
01633
01634 if ( incidence ) {
01635 organizerEvents = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
01636 groupEvents = incidence->attendeeByMails( KOPrefs::instance()->allEmails() );
01637
01638 if ( incidence && incidence->type() == "Todo" ) {
01639 todo = true;
01640 subtodo = ( incidence->relatedTo() != 0 );
01641 }
01642 }
01643 emit todoSelected( todo );
01644 emit subtodoSelected( subtodo );
01645 emit organizerEventsSelected( organizerEvents );
01646 emit groupEventsSelected( groupEvents );
01647 }
01648
01649
01650 void CalendarView::checkClipboard()
01651 {
01652 #ifndef KORG_NODND
01653 if (ICalDrag::canDecode(QApplication::clipboard()->data())) {
01654 kdDebug(5850) << "CalendarView::checkClipboard() true" << endl;
01655 emit pasteEnabled(true);
01656 } else {
01657 kdDebug(5850) << "CalendarView::checkClipboard() false" << endl;
01658 emit pasteEnabled(false);
01659 }
01660 #endif
01661 }
01662
01663 void CalendarView::showDates(const DateList &selectedDates)
01664 {
01665
01666
01667 if ( mViewManager->currentView() ) {
01668 updateView( selectedDates.first(), selectedDates.last() );
01669 } else {
01670 mViewManager->showAgendaView();
01671 }
01672 }
01673
01674 void CalendarView::editFilters()
01675 {
01676 kdDebug(5850) << "CalendarView::editFilters()" << endl;
01677
01678 CalFilter *filter = mFilters.first();
01679 while(filter) {
01680 kdDebug(5850) << " Filter: " << filter->name() << endl;
01681 filter = mFilters.next();
01682 }
01683
01684 mDialogManager->showFilterEditDialog(&mFilters);
01685 }
01686
01689 void CalendarView::updateFilter()
01690 {
01691 QStringList filters;
01692 CalFilter *filter;
01693
01694 int pos = mFilters.find( mCurrentFilter );
01695 if ( pos < 0 ) {
01696 mCurrentFilter = 0;
01697 }
01698
01699 filters << i18n("No filter");
01700 for ( filter = mFilters.first(); filter; filter = mFilters.next() ) {
01701 filters << filter->name();
01702 }
01703
01704 emit newFilterListSignal( filters );
01705
01706
01707 emit selectFilterSignal( pos+1 );
01708 mCalendar->setFilter( mCurrentFilter );
01709 updateView();
01710 }
01711
01714 void CalendarView::filterActivated( int filterNo )
01715 {
01716 CalFilter *newFilter = 0;
01717 if ( filterNo > 0 && filterNo <= int(mFilters.count()) ) {
01718 newFilter = mFilters.at( filterNo-1 );
01719 }
01720 if ( newFilter != mCurrentFilter ) {
01721 mCurrentFilter = newFilter;
01722 mCalendar->setFilter( mCurrentFilter );
01723 updateView();
01724 }
01725 emit filterChanged();
01726 }
01727
01728 QString CalendarView::currentFilterName() const
01729 {
01730 if ( mCurrentFilter) {
01731 return mCurrentFilter->name();
01732 } else return i18n("No filter");
01733 }
01734
01735 void CalendarView::takeOverEvent()
01736 {
01737 Incidence *incidence = currentSelection();
01738
01739 if (!incidence) return;
01740
01741 incidence->setOrganizer( Person( KOPrefs::instance()->fullName(),
01742 KOPrefs::instance()->email() ) );
01743 incidence->recreate();
01744 incidence->setReadOnly(false);
01745
01746 updateView();
01747 }
01748
01749 void CalendarView::takeOverCalendar()
01750 {
01751 Incidence::List incidences = mCalendar->rawIncidences();
01752 Incidence::List::Iterator it;
01753
01754 for ( it = incidences.begin(); it != incidences.end(); ++it ) {
01755 (*it)->setOrganizer( Person( KOPrefs::instance()->fullName(),
01756 KOPrefs::instance()->email() ) );
01757 (*it)->recreate();
01758 (*it)->setReadOnly(false);
01759 }
01760 updateView();
01761 }
01762
01763 void CalendarView::showIntro()
01764 {
01765 kdDebug(5850) << "To be implemented." << endl;
01766 }
01767
01768 void CalendarView::showDateNavigator( bool show )
01769 {
01770 if( show )
01771 mDateNavigator->show();
01772 else
01773 mDateNavigator->hide();
01774 }
01775
01776 void CalendarView::showTodoView( bool show )
01777 {
01778 if( show )
01779 mTodoList->show();
01780 else
01781 mTodoList->hide();
01782 }
01783
01784 void CalendarView::showEventViewer( bool show )
01785 {
01786 if( show )
01787 mEventViewer->show();
01788 else
01789 mEventViewer->hide();
01790 }
01791
01792
01793 void CalendarView::addView(KOrg::BaseView *view)
01794 {
01795 mViewManager->addView(view);
01796 }
01797
01798 void CalendarView::showView(KOrg::BaseView *view)
01799 {
01800 mViewManager->showView(view);
01801 }
01802
01803 void CalendarView::addExtension( CalendarViewExtension::Factory *factory )
01804 {
01805 CalendarViewExtension *extension = factory->create( mLeftSplitter );
01806
01807 mExtensions.append( extension );
01808 }
01809
01810 void CalendarView::toggleExpand()
01811 {
01812 showLeftFrame( mLeftFrame->isHidden() );
01813 }
01814
01815 void CalendarView::showLeftFrame(bool show)
01816 {
01817 if (show) {
01818 mLeftFrame->show();
01819 emit calendarViewExpanded( false );
01820 } else {
01821 mLeftFrame->hide();
01822 emit calendarViewExpanded( true );
01823 }
01824 }
01825
01826 void CalendarView::calendarModified( bool modified, Calendar * )
01827 {
01828 setModified( modified );
01829 }
01830
01831 Todo *CalendarView::selectedTodo()
01832 {
01833 Incidence *incidence = currentSelection();
01834 if ( incidence && incidence->type() == "Todo" ) {
01835 return static_cast<Todo *>( incidence );
01836 }
01837 incidence = 0;
01838
01839 Incidence::List selectedIncidences = mTodoList->selectedIncidences();
01840 if ( !selectedIncidences.isEmpty() ) incidence = selectedIncidences.first();
01841 if ( incidence && incidence->type() == "Todo" ) {
01842 return static_cast<Todo *>( incidence );
01843 }
01844
01845 return 0;
01846 }
01847
01848 void CalendarView::dialogClosing( Incidence *in )
01849 {
01850
01851 mChanger->endChange( in );
01852 mDialogList.remove( in );
01853 }
01854
01855 Incidence *CalendarView::currentSelection()
01856 {
01857 return mViewManager->currentSelection();
01858 }
01859
01860 Incidence* CalendarView::selectedIncidence()
01861 {
01862 Incidence *incidence = currentSelection();
01863 if ( !incidence ) {
01864 Incidence::List selectedIncidences = mTodoList->selectedIncidences();
01865 if ( !selectedIncidences.isEmpty() )
01866 incidence = selectedIncidences.first();
01867 }
01868 return incidence;
01869 }
01870
01871 void CalendarView::showIncidence()
01872 {
01873 showIncidence( selectedIncidence() );
01874 }
01875
01876 void CalendarView::editIncidence()
01877 {
01878 editIncidence( selectedIncidence() );
01879 }
01880
01881 bool CalendarView::editIncidence( const QString& uid )
01882 {
01883 kdDebug(5850) << "CalendarView::editIncidence()" << endl;
01884 return editIncidence( mCalendar->incidence( uid ) );
01885 }
01886
01887 void CalendarView::deleteIncidence()
01888 {
01889 deleteIncidence( selectedIncidence() );
01890 }
01891
01892 void CalendarView::cutIncidence(Incidence *)
01893 {
01894 edit_cut();
01895 }
01896
01897 void CalendarView::copyIncidence(Incidence *)
01898 {
01899 edit_copy();
01900 }
01901
01902 void CalendarView::pasteIncidence()
01903 {
01904 edit_paste();
01905 }
01906
01907 void CalendarView::showIncidence( Incidence *incidence )
01908 {
01909 KOEventViewerDialog *eventViewer = new KOEventViewerDialog( this );
01910 eventViewer->setIncidence( incidence );
01911 eventViewer->show();
01912 }
01913
01914 bool CalendarView::editIncidence( Incidence *incidence, bool isCounter )
01915 {
01916 kdDebug(5850) << "CalendarView::editEvent()" << endl;
01917
01918 if ( !incidence || !mChanger ) {
01919 KNotifyClient::beep();
01920 return false;
01921 }
01922 KOIncidenceEditor *tmp = editorDialog( incidence );
01923 if ( tmp ) {
01924 kdDebug(5850) << "CalendarView::editIncidence() in List" << endl;
01925 tmp->reload();
01926 tmp->raise();
01927 tmp->show();
01928 return true;
01929 }
01930
01931 if ( incidence->isReadOnly() ) {
01932 showIncidence( incidence );
01933 return true;
01934 }
01935
01936 if ( !isCounter && !mChanger->beginChange( incidence ) ) {
01937 warningChangeFailed( incidence );
01938 showIncidence( incidence );
01939 return false;
01940 }
01941
01942 kdDebug(5850) << "CalendarView::editIncidence() new IncidenceEditor" << endl;
01943 KOIncidenceEditor *incidenceEditor = mDialogManager->getEditor( incidence );
01944 connectIncidenceEditor( incidenceEditor );
01945
01946 mDialogList.insert( incidence, incidenceEditor );
01947 incidenceEditor->editIncidence( incidence, mCalendar );
01948 incidenceEditor->show();
01949 return true;
01950 }
01951
01952 void CalendarView::deleteSubTodosIncidence ( Todo *todo )
01953 {
01954 if( !todo ) return;
01955
01956 Incidence::List subTodos( todo->relations() );
01957 Incidence::List::Iterator it;
01958 Incidence *aIncidence;
01959 Todo *aTodo;
01960
01961 for ( it= subTodos.begin(); it != subTodos.end(); ++it ) {
01962 aIncidence = *it;
01963 if( aIncidence && aIncidence->type() == "Todo" ) {
01964 aTodo = static_cast<Todo*>( aIncidence );
01965 deleteSubTodosIncidence ( aTodo );
01966 }
01967 }
01968 mChanger->deleteIncidence ( todo );
01969 }
01970
01971 void CalendarView::deleteTodoIncidence ( Todo *todo, bool force )
01972 {
01973 if ( !todo ) return ;
01974
01975
01976 if (todo->relations().isEmpty() ) {
01977 bool doDelete = true;
01978 if ( !force && KOPrefs::instance()->mConfirm ) {
01979 doDelete = ( msgItemDelete( todo ) == KMessageBox::Continue );
01980 }
01981 if ( doDelete )
01982 mChanger->deleteIncidence( todo );
01983 return;
01984 }
01985
01986
01987 int km = KMessageBox::No;
01988 if ( !force ) {
01989 km=KMessageBox::questionYesNoCancel( this,
01990 i18n("The item \"%1\" has sub-to-dos. "
01991 "Do you want to delete just this item and "
01992 "make all its sub-to-dos independent, or "
01993 "delete the to-do with all its sub-to-dos?"
01994 ).arg( todo->summary() ),
01995 i18n("KOrganizer Confirmation"),
01996 i18n("Delete Only This"),
01997 i18n("Delete All"));
01998 }
01999 startMultiModify( i18n("Deleting sub-to-dos" ) );
02000
02001 if( km == KMessageBox::Yes ) {
02002
02003 makeSubTodosIndependents ( todo );
02004 mChanger->deleteIncidence( todo );
02005 } else if ( km == KMessageBox::No ) {
02006
02007
02008 deleteSubTodosIncidence ( todo );
02009 }
02010 endMultiModify();
02011 }
02012
02013 void CalendarView::deleteIncidence(Incidence *incidence, bool force)
02014 {
02015 if ( !incidence || !mChanger ) {
02016 if ( !force ) {
02017 KNotifyClient::beep();
02018 }
02019 return;
02020 }
02021 if ( incidence->isReadOnly() ) {
02022 if ( !force ) {
02023 KMessageBox::information( this, i18n("The item \"%1\" is marked read-only "
02024 "and cannot be deleted; it probably belongs to "
02025 "a read-only calendar resource.")
02026 .arg(incidence->summary()),
02027 i18n("Removing not possible"),
02028 "deleteReadOnlyIncidence" );
02029 }
02030 return;
02031 }
02032
02033 CanDeleteIncidenceVisitor v;
02034
02035
02036
02037 if ( !v.act( incidence, this ) )
02038 return;
02039
02040
02041 if ( incidence && incidence->type()=="Todo" ) {
02042 deleteTodoIncidence( static_cast<Todo*>(incidence), force );
02043 return;
02044 }
02045
02046 if ( incidence->doesRecur() ) {
02047 QDate itemDate = mViewManager->currentSelectionDate();
02048 kdDebug(5850) << "Recurrence-Date: " << itemDate.toString() << endl;
02049 int km = KMessageBox::Ok;
02050 if ( !force ) {
02051 if ( !itemDate.isValid() ) {
02052 kdDebug(5850) << "Date Not Valid" << endl;
02053 km = KMessageBox::warningContinueCancel(this,
02054 i18n("The calendar item \"%1\" recurs over multiple dates; "
02055 "are you sure you want to delete it "
02056 "and all its recurrences?").arg( incidence->summary() ),
02057 i18n("KOrganizer Confirmation"), i18n("Delete All") );
02058 } else {
02059 km = KOMessageBox::fourBtnMsgBox( this, QMessageBox::Warning,
02060 i18n("The calendar item \"%1\" recurs over multiple dates. "
02061 "Do you want to delete only the current one on %2, only all "
02062 "future recurrences, or all its recurrences?" )
02063 .arg( incidence->summary() )
02064 .arg( KGlobal::locale()->formatDate(itemDate)),
02065 i18n("KOrganizer Confirmation"), i18n("Delete C&urrent"),
02066 i18n("Delete &Future"),
02067 i18n("Delete &All"));
02068 }
02069 }
02070 switch(km) {
02071 case KMessageBox::Ok:
02072 case KMessageBox::Continue:
02073 mChanger->deleteIncidence( incidence );
02074 break;
02075
02076 case KMessageBox::Yes:
02077 if ( mChanger->beginChange( incidence ) ) {
02078 Incidence *oldIncidence = incidence->clone();
02079 incidence->recurrence()->addExDate( itemDate );
02080 mChanger->changeIncidence( oldIncidence, incidence );
02081 mChanger->endChange( incidence );
02082 delete oldIncidence;
02083 }
02084 break;
02085 case KMessageBox::No:
02086 if ( mChanger->beginChange( incidence ) ) {
02087 Incidence *oldIncidence = incidence->clone();
02088 Recurrence *recur = incidence->recurrence();
02089 recur->setEndDate( itemDate.addDays(-1) );
02090 mChanger->changeIncidence( oldIncidence, incidence );
02091 mChanger->endChange( incidence );
02092 delete oldIncidence;
02093 }
02094 break;
02095 }
02096 } else {
02097 bool doDelete = true;
02098 if ( !force && KOPrefs::instance()->mConfirm ) {
02099 doDelete = ( msgItemDelete( incidence ) == KMessageBox::Continue );
02100 }
02101 if ( doDelete ) {
02102 mChanger->deleteIncidence( incidence );
02103 processIncidenceSelection( 0 );
02104 }
02105 }
02106 }
02107
02108 void CalendarView::connectIncidenceEditor( KOIncidenceEditor *editor )
02109 {
02110 connect( this, SIGNAL( newIncidenceChanger( IncidenceChangerBase* ) ),
02111 editor, SLOT( setIncidenceChanger( IncidenceChangerBase* ) ) );
02112 editor->setIncidenceChanger( mChanger );
02113 }
02114
02115 bool CalendarView::purgeCompletedSubTodos( Todo* todo, bool &allPurged )
02116 {
02117 if ( !todo ) return true;
02118 bool deleteThisTodo = true;
02119 Incidence::List subTodos( todo->relations() );
02120 Incidence *aIncidence;
02121 Todo *aTodo;
02122 Incidence::List::Iterator it;
02123 for ( it = subTodos.begin(); it != subTodos.end(); ++it ) {
02124 aIncidence = *it;
02125 if ( aIncidence && aIncidence->type()=="Todo" ) {
02126 aTodo = static_cast<Todo*>( aIncidence );
02127 deleteThisTodo &= purgeCompletedSubTodos( aTodo, allPurged );
02128 }
02129 }
02130
02131 if ( deleteThisTodo ) {
02132 if ( todo->isCompleted() ) {
02133 if ( !mChanger->deleteIncidence( todo ) )
02134 allPurged = false;
02135 } else {
02136 deleteThisTodo = false;
02137 }
02138 } else {
02139 if ( todo->isCompleted() ) {
02140 allPurged = false;
02141 }
02142 }
02143 return deleteThisTodo;
02144 }
02145
02146 void CalendarView::purgeCompleted()
02147 {
02148 int result = KMessageBox::warningContinueCancel(this,
02149 i18n("Delete all completed to-dos?"),i18n("Purge To-dos"),i18n("Purge"));
02150
02151 if (result == KMessageBox::Continue) {
02152 bool allDeleted = true;
02153 startMultiModify( i18n("Purging completed to-dos") );
02154 Todo::List todos = calendar()->rawTodos();
02155 Todo::List rootTodos;
02156 Todo::List::ConstIterator it;
02157 for ( it = todos.begin(); it != todos.end(); ++it ) {
02158 Todo *aTodo = *it;
02159 if ( aTodo && !aTodo->relatedTo() )
02160 rootTodos.append( aTodo );
02161 }
02162
02163 for ( it = rootTodos.begin(); it != rootTodos.end(); ++it ) {
02164 purgeCompletedSubTodos( *it, allDeleted );
02165 }
02166 endMultiModify();
02167 if ( !allDeleted ) {
02168 KMessageBox::information( this, i18n("Unable to purge to-dos with "
02169 "uncompleted children."), i18n("Delete To-do"),
02170 "UncompletedChildrenPurgeTodos" );
02171 }
02172 }
02173 }
02174
02175 void CalendarView::warningChangeFailed( Incidence * )
02176 {
02177 KMessageBox::sorry( this, i18n("Unable to edit item: "
02178 "it is locked by another process.") );
02179 }
02180
02181 void CalendarView::editCanceled( Incidence *i )
02182 {
02183 mCalendar->endChange( i );
02184 }
02185
02186 void CalendarView::showErrorMessage( const QString &msg )
02187 {
02188 KMessageBox::error( this, msg );
02189 }
02190
02191 void CalendarView::updateCategories()
02192 {
02193 QStringList allCats( calendar()->categories() );
02194 allCats.sort();
02195 QStringList categories( KOPrefs::instance()->mCustomCategories );
02196 for ( QStringList::ConstIterator si = allCats.constBegin(); si != allCats.constEnd(); ++si ) {
02197 if ( categories.find( *si ) == categories.end() ) {
02198 categories.append( *si );
02199 }
02200 }
02201 KOPrefs::instance()->mCustomCategories = categories;
02202 KOPrefs::instance()->writeConfig();
02203
02204 emit categoriesChanged();
02205 }
02206
02207 void CalendarView::addIncidenceOn( Incidence *incadd, const QDate &dt )
02208 {
02209 if ( !incadd || !mChanger ) {
02210 KMessageBox::sorry(this, i18n("Unable to copy the item to %1.")
02211 .arg( dt.toString() ), i18n("Copying Failed") );
02212 return;
02213 }
02214 Incidence *incidence = mCalendar->incidence( incadd->uid() );
02215 if ( !incidence ) incidence = incadd;
02216
02217 incidence = incidence->clone();
02218 incidence->recreate();
02219
02220 if ( incidence->type() == "Event" ) {
02221 Event *event = static_cast<Event*>(incidence);
02222
02223
02224 QDateTime start = event->dtStart();
02225 QDateTime end = event->dtEnd();
02226
02227 int duration = start.daysTo( end );
02228 start.setDate( dt );
02229 end.setDate( dt.addDays( duration ) );
02230
02231 event->setDtStart( start );
02232 event->setDtEnd( end );
02233
02234 } else if ( incidence->type() == "Todo" ) {
02235 Todo *todo = static_cast<Todo*>(incidence);
02236 QDateTime due = todo->dtDue();
02237 due.setDate( dt );
02238
02239 todo->setDtDue( due );
02240 todo->setHasDueDate( true );
02241 }
02242
02243 if ( !mChanger->addIncidence( incidence, this ) ) {
02244 KODialogManager::errorSaveIncidence( this, incidence );
02245 delete incidence;
02246 }
02247 }
02248
02249 void CalendarView::moveIncidenceTo( Incidence *incmove, const QDate &dt )
02250 {
02251 if ( !incmove || !mChanger ) {
02252 KMessageBox::sorry( this, i18n("Unable to move the item to %1.")
02253 .arg( dt.toString() ), i18n("Moving Failed") );
02254 return;
02255 }
02256 Incidence *incidence = mCalendar->incidence( incmove->uid() );
02257 if ( !incidence ) {
02258 addIncidenceOn( incidence, dt );
02259 return;
02260 }
02261 Incidence *oldIncidence = incidence->clone();
02262 if ( !mChanger->beginChange( incidence ) ) {
02263 delete oldIncidence;
02264 return;
02265 }
02266
02267 if ( incidence->type() == "Event" ) {
02268 Event *event = static_cast<Event*>(incidence);
02269
02270
02271 QDateTime start = event->dtStart();
02272 QDateTime end = event->dtEnd();
02273
02274 int duration = start.daysTo( end );
02275 start.setDate( dt );
02276 end.setDate( dt.addDays( duration ) );
02277
02278 event->setDtStart( start );
02279 event->setDtEnd( end );
02280
02281 } else if ( incidence->type() == "Todo" ) {
02282 Todo *todo = static_cast<Todo*>(incidence);
02283 QDateTime due = todo->dtDue();
02284 due.setDate( dt );
02285
02286 todo->setDtDue( due );
02287 todo->setHasDueDate( true );
02288 }
02289 mChanger->changeIncidence( oldIncidence, incidence );
02290 mChanger->endChange( incidence );
02291 delete oldIncidence;
02292 }
02293
02294 void CalendarView::resourcesChanged()
02295 {
02296 mViewManager->resourcesChanged();
02297 updateView();
02298 }
02299
02300 #include "calendarview.moc"