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