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 #include <qhbox.h>
00026 #include <qvbox.h>
00027 #include <qlabel.h>
00028 #include <qframe.h>
00029 #include <qlayout.h>
00030 #ifndef KORG_NOSPLITTER
00031 #include <qsplitter.h>
00032 #endif
00033 #include <qfont.h>
00034 #include <qfontmetrics.h>
00035 #include <qpopupmenu.h>
00036 #include <qtooltip.h>
00037 #include <qpainter.h>
00038 #include <qpushbutton.h>
00039 #include <qcursor.h>
00040 #include <qbitarray.h>
00041
00042 #include <kapplication.h>
00043 #include <kdebug.h>
00044 #include <kstandarddirs.h>
00045 #include <kiconloader.h>
00046 #include <klocale.h>
00047 #include <kconfig.h>
00048 #include <kglobal.h>
00049 #include <kglobalsettings.h>
00050 #include <kholidays.h>
00051
00052 #include <libkcal/calendar.h>
00053 #include <libkcal/icaldrag.h>
00054 #include <libkcal/dndfactory.h>
00055 #include <libkcal/calfilter.h>
00056
00057 #include <kcalendarsystem.h>
00058
00059 #include "koglobals.h"
00060 #ifndef KORG_NOPLUGINS
00061 #include "kocore.h"
00062 #endif
00063 #include "koprefs.h"
00064 #include "koagenda.h"
00065 #include "koagendaitem.h"
00066 #include "timelabels.h"
00067
00068 #include "koincidencetooltip.h"
00069 #include "kogroupware.h"
00070 #include "kodialogmanager.h"
00071 #include "koeventpopupmenu.h"
00072
00073 #include "koagendaview.h"
00074 #include "koagendaview.moc"
00075
00076 using namespace KOrg;
00077
00078
00079 EventIndicator::EventIndicator(Location loc,QWidget *parent,const char *name)
00080 : QFrame(parent,name)
00081 {
00082 mColumns = 1;
00083 mEnabled.resize( mColumns );
00084 mLocation = loc;
00085
00086 if (mLocation == Top) mPixmap = KOGlobals::self()->smallIcon("upindicator");
00087 else mPixmap = KOGlobals::self()->smallIcon("downindicator");
00088
00089 setMinimumHeight(mPixmap.height());
00090 }
00091
00092 EventIndicator::~EventIndicator()
00093 {
00094 }
00095
00096 void EventIndicator::drawContents(QPainter *p)
00097 {
00098
00099
00100
00101
00102 int i;
00103 for(i=0;i<mColumns;++i) {
00104 if (mEnabled[i]) {
00105 int cellWidth = contentsRect().right()/mColumns;
00106 int xOffset = KOGlobals::self()->reverseLayout() ?
00107 (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 :
00108 i*cellWidth + cellWidth/2 -mPixmap.width()/2;
00109 p->drawPixmap(QPoint(xOffset,0),mPixmap);
00110 }
00111 }
00112 }
00113
00114 void EventIndicator::changeColumns(int columns)
00115 {
00116 mColumns = columns;
00117 mEnabled.resize(mColumns);
00118
00119 update();
00120 }
00121
00122 void EventIndicator::enableColumn(int column, bool enable)
00123 {
00124 mEnabled[column] = enable;
00125 }
00126
00127
00128 #include <libkcal/incidence.h>
00129
00133
00134
00135 KOAlternateLabel::KOAlternateLabel(const QString &shortlabel, const QString &longlabel,
00136 const QString &extensivelabel, QWidget *parent, const char *name )
00137 : QLabel(parent, name), mTextTypeFixed(false), mShortText(shortlabel),
00138 mLongText(longlabel), mExtensiveText(extensivelabel)
00139 {
00140 setSizePolicy(QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
00141 if (mExtensiveText.isEmpty()) mExtensiveText = mLongText;
00142 squeezeTextToLabel();
00143 }
00144
00145 KOAlternateLabel::~KOAlternateLabel()
00146 {
00147 }
00148
00149 void KOAlternateLabel::useShortText()
00150 {
00151 mTextTypeFixed = true;
00152 QLabel::setText( mShortText );
00153 QToolTip::remove( this );
00154 QToolTip::add( this, mExtensiveText );
00155 }
00156
00157 void KOAlternateLabel::useLongText()
00158 {
00159 mTextTypeFixed = true;
00160 QLabel::setText( mLongText );
00161 QToolTip::remove( this );
00162 QToolTip::add( this, mExtensiveText );
00163 }
00164
00165 void KOAlternateLabel::useExtensiveText()
00166 {
00167 mTextTypeFixed = true;
00168 QLabel::setText( mExtensiveText );
00169 QToolTip::remove( this );
00170 QToolTip::hide();
00171 }
00172
00173 void KOAlternateLabel::useDefaultText()
00174 {
00175 mTextTypeFixed = false;
00176 squeezeTextToLabel();
00177 }
00178
00179 void KOAlternateLabel::squeezeTextToLabel()
00180 {
00181 if (mTextTypeFixed) return;
00182
00183 QFontMetrics fm(fontMetrics());
00184 int labelWidth = size().width();
00185 int textWidth = fm.width(mLongText);
00186 int longTextWidth = fm.width(mExtensiveText);
00187 if (longTextWidth <= labelWidth) {
00188 QLabel::setText( mExtensiveText );
00189 QToolTip::remove( this );
00190 QToolTip::hide();
00191 } else if (textWidth <= labelWidth) {
00192 QLabel::setText( mLongText );
00193 QToolTip::remove( this );
00194 QToolTip::add( this, mExtensiveText );
00195 } else {
00196 QLabel::setText( mShortText );
00197 QToolTip::remove( this );
00198 QToolTip::add( this, mExtensiveText );
00199 }
00200 }
00201
00202 void KOAlternateLabel::resizeEvent( QResizeEvent * )
00203 {
00204 squeezeTextToLabel();
00205 }
00206
00207 QSize KOAlternateLabel::minimumSizeHint() const
00208 {
00209 QSize sh = QLabel::minimumSizeHint();
00210 sh.setWidth(-1);
00211 return sh;
00212 }
00213
00214 void KOAlternateLabel::setText( const QString &text ) {
00215 mLongText = text;
00216 squeezeTextToLabel();
00217 }
00218
00219
00223
00224 KOAgendaView::KOAgendaView(Calendar *cal,QWidget *parent,const char *name, bool isSideBySide ) :
00225 KOrg::AgendaView (cal,parent,name), mExpandButton( 0 ), mAllowAgendaUpdate( true ),
00226 mUpdateItem( 0 ),
00227 mResource( 0 ),
00228 mIsSideBySide( isSideBySide ),
00229 mPendingChanges( true )
00230 {
00231 mSelectedDates.append(QDate::currentDate());
00232
00233 mLayoutDayLabels = 0;
00234 mDayLabelsFrame = 0;
00235 mDayLabels = 0;
00236
00237 bool isRTL = KOGlobals::self()->reverseLayout();
00238
00239 if ( KOPrefs::instance()->compactDialogs() ) {
00240 if ( KOPrefs::instance()->mVerticalScreen ) {
00241 mExpandedPixmap = KOGlobals::self()->smallIcon( "1downarrow" );
00242 mNotExpandedPixmap = KOGlobals::self()->smallIcon( "1uparrow" );
00243 } else {
00244 mExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1leftarrow" : "1rightarrow" );
00245 mNotExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1rightarrow" : "1leftarrow" );
00246 }
00247 }
00248
00249 QBoxLayout *topLayout = new QVBoxLayout(this);
00250
00251
00252 mDayLabelsFrame = new QHBox(this);
00253 topLayout->addWidget(mDayLabelsFrame);
00254
00255
00256 #ifndef KORG_NOSPLITTER
00257 mSplitterAgenda = new QSplitter(Vertical,this);
00258 topLayout->addWidget(mSplitterAgenda);
00259
00260 #if KDE_IS_VERSION( 3, 1, 93 )
00261 mSplitterAgenda->setOpaqueResize( KGlobalSettings::opaqueResize() );
00262 #else
00263 mSplitterAgenda->setOpaqueResize();
00264 #endif
00265
00266 mAllDayFrame = new QHBox(mSplitterAgenda);
00267
00268 QWidget *agendaFrame = new QWidget(mSplitterAgenda);
00269 #else
00270 QVBox *mainBox = new QVBox( this );
00271 topLayout->addWidget( mainBox );
00272
00273 mAllDayFrame = new QHBox(mainBox);
00274
00275 QWidget *agendaFrame = new QWidget(mainBox);
00276 #endif
00277
00278
00279 mDummyAllDayLeft = new QVBox( mAllDayFrame );
00280 if ( isSideBySide )
00281 mDummyAllDayLeft->hide();
00282
00283 if ( KOPrefs::instance()->compactDialogs() ) {
00284 mExpandButton = new QPushButton(mDummyAllDayLeft);
00285 mExpandButton->setPixmap( mNotExpandedPixmap );
00286 mExpandButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
00287 QSizePolicy::Fixed ) );
00288 connect( mExpandButton, SIGNAL( clicked() ), SIGNAL( toggleExpand() ) );
00289 } else {
00290 QLabel *label = new QLabel( i18n("All Day"), mDummyAllDayLeft );
00291 label->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::WordBreak );
00292 }
00293
00294 mAllDayAgenda = new KOAgenda(1,mAllDayFrame);
00295 QWidget *dummyAllDayRight = new QWidget(mAllDayFrame);
00296
00297
00298 QGridLayout *agendaLayout = new QGridLayout(agendaFrame,3,3);
00299
00300
00301
00302 mEventIndicatorTop = new EventIndicator(EventIndicator::Top,agendaFrame);
00303 agendaLayout->addWidget(mEventIndicatorTop,0,1);
00304 mEventIndicatorBottom = new EventIndicator(EventIndicator::Bottom,
00305 agendaFrame);
00306 agendaLayout->addWidget(mEventIndicatorBottom,2,1);
00307 QWidget *dummyAgendaRight = new QWidget(agendaFrame);
00308 agendaLayout->addWidget(dummyAgendaRight,0,2);
00309
00310
00311 mTimeLabels = new TimeLabels(24,agendaFrame);
00312 agendaLayout->addWidget(mTimeLabels,1,0);
00313
00314
00315 mAgenda = new KOAgenda(1,96,KOPrefs::instance()->mHourSize,agendaFrame);
00316 agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
00317 agendaLayout->setColStretch(1,1);
00318
00319
00320 mAgendaPopup = eventPopup();
00321
00322
00323 mAllDayAgendaPopup = eventPopup();
00324
00325
00326 mTimeLabels->setAgenda(mAgenda);
00327 if ( isSideBySide )
00328 mTimeLabels->hide();
00329
00330
00331
00332
00333 createDayLabels();
00334
00335 if ( !isSideBySide ) {
00336
00337 dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00338 dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00339 }
00340
00341 updateTimeBarWidth();
00342
00343
00344 connect(mAgenda->verticalScrollBar(),SIGNAL(valueChanged(int)),
00345 mTimeLabels, SLOT(positionChanged()));
00346
00347 connect( mAgenda,
00348 SIGNAL( zoomView( const int, const QPoint & ,const Qt::Orientation ) ),
00349 SLOT( zoomView( const int, const QPoint &, const Qt::Orientation ) ) );
00350
00351 connect(mTimeLabels->verticalScrollBar(),SIGNAL(valueChanged(int)),
00352 SLOT(setContentsPos(int)));
00353
00354
00355 connect( mAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00356 SLOT(newTimeSpanSelected(const QPoint &, const QPoint &)));
00357 connect( mAllDayAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00358 SLOT(newTimeSpanSelectedAllDay(const QPoint &, const QPoint &)));
00359
00360
00361 connect( mAgenda, SIGNAL(lowerYChanged(int)),
00362 SLOT(updateEventIndicatorTop(int)));
00363 connect( mAgenda, SIGNAL(upperYChanged(int)),
00364 SLOT(updateEventIndicatorBottom(int)));
00365
00366 connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
00367 connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
00368
00369 if ( cal ) {
00370 cal->registerObserver( this );
00371 }
00372 }
00373
00374
00375 KOAgendaView::~KOAgendaView()
00376 {
00377 if ( calendar() )
00378 calendar()->unregisterObserver( this );
00379 delete mAgendaPopup;
00380 delete mAllDayAgendaPopup;
00381 }
00382
00383 void KOAgendaView::connectAgenda( KOAgenda *agenda, QPopupMenu *popup,
00384 KOAgenda *otherAgenda )
00385 {
00386 connect( agenda, SIGNAL( showIncidencePopupSignal( Incidence *, const QDate & ) ),
00387 popup, SLOT( showIncidencePopup( Incidence *, const QDate & ) ) );
00388
00389 connect( agenda, SIGNAL( showNewEventPopupSignal() ),
00390 SLOT( showNewEventPopup() ) );
00391
00392 agenda->setCalendar( calendar() );
00393
00394
00395 connect( agenda, SIGNAL( newEventSignal() ), SIGNAL( newEventSignal() ) );
00396
00397 connect( agenda, SIGNAL( newStartSelectSignal() ),
00398 otherAgenda, SLOT( clearSelection() ) );
00399 connect( agenda, SIGNAL( newStartSelectSignal() ),
00400 SIGNAL( timeSpanSelectionChanged()) );
00401
00402 connect( agenda, SIGNAL( editIncidenceSignal( Incidence * ) ),
00403 SIGNAL( editIncidenceSignal( Incidence * ) ) );
00404 connect( agenda, SIGNAL( showIncidenceSignal( Incidence * ) ),
00405 SIGNAL( showIncidenceSignal( Incidence * ) ) );
00406 connect( agenda, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
00407 SIGNAL( deleteIncidenceSignal( Incidence * ) ) );
00408
00409 connect( agenda, SIGNAL( startMultiModify( const QString & ) ),
00410 SIGNAL( startMultiModify( const QString & ) ) );
00411 connect( agenda, SIGNAL( endMultiModify() ),
00412 SIGNAL( endMultiModify() ) );
00413
00414 connect( agenda, SIGNAL( itemModified( KOAgendaItem * ) ),
00415 SLOT( updateEventDates( KOAgendaItem * ) ) );
00416 connect( agenda, SIGNAL( enableAgendaUpdate( bool ) ),
00417 SLOT( enableAgendaUpdate( bool ) ) );
00418
00419
00420 connect( agenda, SIGNAL( startDragSignal( Incidence * ) ),
00421 SLOT( startDrag( Incidence * ) ) );
00422
00423
00424 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00425 otherAgenda, SLOT( deselectItem() ) );
00426 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00427 SIGNAL( incidenceSelected( Incidence * ) ) );
00428
00429
00430 connect( agenda, SIGNAL( droppedToDo( Todo *, const QPoint &, bool ) ),
00431 SLOT( slotTodoDropped( Todo *, const QPoint &, bool ) ) );
00432
00433 }
00434
00435 void KOAgendaView::zoomInVertically( )
00436 {
00437 if ( !mIsSideBySide )
00438 KOPrefs::instance()->mHourSize++;
00439 mAgenda->updateConfig();
00440 mAgenda->checkScrollBoundaries();
00441
00442 mTimeLabels->updateConfig();
00443 mTimeLabels->positionChanged();
00444 mTimeLabels->repaint();
00445
00446 updateView();
00447 }
00448
00449 void KOAgendaView::zoomOutVertically( )
00450 {
00451
00452 if ( KOPrefs::instance()->mHourSize > 4 || mIsSideBySide ) {
00453
00454 if ( !mIsSideBySide )
00455 KOPrefs::instance()->mHourSize--;
00456 mAgenda->updateConfig();
00457 mAgenda->checkScrollBoundaries();
00458
00459 mTimeLabels->updateConfig();
00460 mTimeLabels->positionChanged();
00461 mTimeLabels->repaint();
00462
00463 updateView();
00464 }
00465 }
00466
00467 void KOAgendaView::zoomInHorizontally( const QDate &date)
00468 {
00469 QDate begin;
00470 QDate newBegin;
00471 QDate dateToZoom = date;
00472 int ndays,count;
00473
00474 begin = mSelectedDates.first();
00475 ndays = begin.daysTo( mSelectedDates.last() );
00476
00477
00478 if ( ! dateToZoom.isValid () )
00479 dateToZoom=mAgenda->selectedIncidenceDate();
00480
00481 if( !dateToZoom.isValid() ) {
00482 if ( ndays > 1 ) {
00483 newBegin=begin.addDays(1);
00484 count = ndays-1;
00485 emit zoomViewHorizontally ( newBegin , count );
00486 }
00487 } else {
00488 if ( ndays <= 2 ) {
00489 newBegin = dateToZoom;
00490 count = 1;
00491 } else {
00492 newBegin = dateToZoom.addDays( -ndays/2 +1 );
00493 count = ndays -1 ;
00494 }
00495 emit zoomViewHorizontally ( newBegin , count );
00496 }
00497 }
00498
00499 void KOAgendaView::zoomOutHorizontally( const QDate &date )
00500 {
00501 QDate begin;
00502 QDate newBegin;
00503 QDate dateToZoom = date;
00504 int ndays,count;
00505
00506 begin = mSelectedDates.first();
00507 ndays = begin.daysTo( mSelectedDates.last() );
00508
00509
00510 if ( ! dateToZoom.isValid () )
00511 dateToZoom=mAgenda->selectedIncidenceDate();
00512
00513 if ( !dateToZoom.isValid() ) {
00514 newBegin = begin.addDays(-1);
00515 count = ndays+3 ;
00516 } else {
00517 newBegin = dateToZoom.addDays( -ndays/2-1 );
00518 count = ndays+3;
00519 }
00520
00521 if ( abs( count ) >= 31 )
00522 kdDebug(5850) << "change to the mounth view?"<<endl;
00523 else
00524
00525 emit zoomViewHorizontally( newBegin, count );
00526 }
00527
00528 void KOAgendaView::zoomView( const int delta, const QPoint &pos,
00529 const Qt::Orientation orient )
00530 {
00531 static QDate zoomDate;
00532 static QTimer *t = new QTimer( this );
00533
00534
00535
00536
00537 if ( orient == Qt::Horizontal ) {
00538 QDate date=mAgenda->selectedIncidenceDate();
00539 if ( date.isValid() )
00540 zoomDate=date;
00541 else{
00542 if ( !t->isActive() ) {
00543 zoomDate= mSelectedDates[pos.x()];
00544 }
00545 t->start ( 1000,true );
00546 }
00547 if ( delta > 0 )
00548 zoomOutHorizontally( zoomDate );
00549 else
00550 zoomInHorizontally( zoomDate );
00551 } else {
00552
00553 QPoint posConstentsOld = mAgenda->gridToContents(pos);
00554 if ( delta > 0 ) {
00555 zoomOutVertically();
00556 } else {
00557 zoomInVertically();
00558 }
00559 QPoint posConstentsNew = mAgenda->gridToContents(pos);
00560 mAgenda->scrollBy( 0, posConstentsNew.y() - posConstentsOld.y() );
00561 }
00562 }
00563
00564 void KOAgendaView::createDayLabels()
00565 {
00566
00567
00568
00569
00570
00571 delete mDayLabels;
00572
00573 mDayLabels = new QFrame (mDayLabelsFrame);
00574 mLayoutDayLabels = new QHBoxLayout(mDayLabels);
00575 if ( !mIsSideBySide )
00576 mLayoutDayLabels->addSpacing(mTimeLabels->width());
00577
00578 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
00579
00580 DateList::ConstIterator dit;
00581 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00582 QDate date = *dit;
00583 QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels);
00584 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
00585
00586
00587 int dW = calsys->dayOfWeek(date);
00588 QString veryLongStr = KGlobal::locale()->formatDate( date );
00589 QString longstr = i18n( "short_weekday date (e.g. Mon 13)","%1 %2" )
00590 .arg( calsys->weekDayName( dW, true ) )
00591 .arg( calsys->day(date) );
00592 QString shortstr = QString::number(calsys->day(date));
00593
00594 KOAlternateLabel *dayLabel = new KOAlternateLabel(shortstr,
00595 longstr, veryLongStr, mDayLabels);
00596 dayLabel->setMinimumWidth(1);
00597 dayLabel->setAlignment(QLabel::AlignHCenter);
00598 if (date == QDate::currentDate()) {
00599 QFont font = dayLabel->font();
00600 font.setBold(true);
00601 dayLabel->setFont(font);
00602 }
00603 dayLayout->addWidget(dayLabel);
00604
00605
00606 QStringList texts = KOGlobals::self()->holiday( date );
00607 QStringList::ConstIterator textit = texts.begin();
00608 for ( ; textit != texts.end(); ++textit ) {
00609
00610 KOAlternateLabel*label = new KOAlternateLabel( (*textit), (*textit), QString::null, mDayLabels );
00611 label->setMinimumWidth(1);
00612 label->setAlignment(AlignCenter);
00613 dayLayout->addWidget(label);
00614 }
00615
00616 #ifndef KORG_NOPLUGINS
00617 CalendarDecoration::List cds = KOCore::self()->calendarDecorations();
00618 CalendarDecoration *it;
00619 for(it = cds.first(); it; it = cds.next()) {
00620 QString text = it->shortText( date );
00621 if ( !text.isEmpty() ) {
00622
00623 KOAlternateLabel*label = new KOAlternateLabel( text, text, QString::null, mDayLabels );
00624 label->setMinimumWidth(1);
00625 label->setAlignment(AlignCenter);
00626 dayLayout->addWidget(label);
00627 }
00628 }
00629
00630 for(it = cds.first(); it; it = cds.next()) {
00631 QWidget *wid = it->smallWidget(mDayLabels,date);
00632 if ( wid ) {
00633
00634 dayLayout->addWidget(wid);
00635 }
00636 }
00637 #endif
00638 }
00639
00640 if ( !mIsSideBySide )
00641 mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
00642 mDayLabels->show();
00643 }
00644
00645 void KOAgendaView::enableAgendaUpdate( bool enable )
00646 {
00647 mAllowAgendaUpdate = enable;
00648 }
00649
00650 int KOAgendaView::maxDatesHint()
00651 {
00652
00653 return 0;
00654 }
00655
00656 int KOAgendaView::currentDateCount()
00657 {
00658 return mSelectedDates.count();
00659 }
00660
00661 Incidence::List KOAgendaView::selectedIncidences()
00662 {
00663 Incidence::List selected;
00664 Incidence *incidence;
00665
00666 incidence = mAgenda->selectedIncidence();
00667 if (incidence) selected.append(incidence);
00668
00669 incidence = mAllDayAgenda->selectedIncidence();
00670 if (incidence) selected.append(incidence);
00671
00672 return selected;
00673 }
00674
00675 DateList KOAgendaView::selectedDates()
00676 {
00677 DateList selected;
00678 QDate qd;
00679
00680 qd = mAgenda->selectedIncidenceDate();
00681 if (qd.isValid()) selected.append(qd);
00682
00683 qd = mAllDayAgenda->selectedIncidenceDate();
00684 if (qd.isValid()) selected.append(qd);
00685
00686 return selected;
00687 }
00688
00689 bool KOAgendaView::eventDurationHint( QDateTime &startDt, QDateTime &endDt,
00690 bool &allDay )
00691 {
00692 if ( selectionStart().isValid() ) {
00693 QDateTime start = selectionStart();
00694 QDateTime end = selectionEnd();
00695
00696 if ( start.secsTo( end ) == 15*60 ) {
00697
00698
00699 QTime defaultDuration( KOPrefs::instance()->mDefaultDuration.time() );
00700 int addSecs = ( defaultDuration.hour()*3600 ) +
00701 ( defaultDuration.minute()*60 );
00702 end = start.addSecs( addSecs );
00703 }
00704
00705 startDt = start;
00706 endDt = end;
00707 allDay = selectedIsAllDay();
00708 return true;
00709 }
00710 return false;
00711 }
00712
00714 bool KOAgendaView::selectedIsSingleCell()
00715 {
00716 if ( !selectionStart().isValid() || !selectionEnd().isValid() ) return false;
00717
00718 if (selectedIsAllDay()) {
00719 int days = selectionStart().daysTo(selectionEnd());
00720 return ( days < 1 );
00721 } else {
00722 int secs = selectionStart().secsTo(selectionEnd());
00723 return ( secs <= 24*60*60/mAgenda->rows() );
00724 }
00725 }
00726
00727
00728 void KOAgendaView::updateView()
00729 {
00730
00731 fillAgenda();
00732 }
00733
00734
00735
00736
00737
00738
00739 void KOAgendaView::updateConfig()
00740 {
00741
00742
00743
00744 mTimeLabels->updateConfig();
00745 mAgenda->updateConfig();
00746 mAllDayAgenda->updateConfig();
00747
00748
00749
00750 mTimeLabels->positionChanged();
00751
00752
00753 mTimeLabels->repaint();
00754
00755 updateTimeBarWidth();
00756
00757
00758 KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance()
00759 ->mEnableToolTips);
00760
00761 setHolidayMasks();
00762
00763 createDayLabels();
00764
00765 updateView();
00766 }
00767
00768 void KOAgendaView::updateTimeBarWidth()
00769 {
00770 int width;
00771
00772 width = mDummyAllDayLeft->fontMetrics().width( i18n("All Day") );
00773 width = QMAX( width, mTimeLabels->width() );
00774
00775 mDummyAllDayLeft->setFixedWidth( width );
00776 mTimeLabels->setFixedWidth( width );
00777 }
00778
00779
00780 void KOAgendaView::updateEventDates( KOAgendaItem *item )
00781 {
00782 kdDebug(5850) << "KOAgendaView::updateEventDates(): " << item->text() << endl;
00783
00784 QDateTime startDt,endDt;
00785
00786
00787
00788
00789
00790 QDate thisDate;
00791 if ( item->cellXLeft() < 0 ) {
00792 thisDate = ( mSelectedDates.first() ).addDays( item->cellXLeft() );
00793 } else {
00794 thisDate = mSelectedDates[ item->cellXLeft() ];
00795 }
00796 QDate oldThisDate( item->itemDate() );
00797 int daysOffset = oldThisDate.daysTo( thisDate );
00798 int daysLength = 0;
00799
00800
00801
00802 Incidence *incidence = item->incidence();
00803 if ( !incidence ) return;
00804 if ( !mChanger || !mChanger->beginChange(incidence) ) return;
00805 Incidence *oldIncidence = incidence->clone();
00806
00807 QTime startTime(0,0,0), endTime(0,0,0);
00808 if ( incidence->doesFloat() ) {
00809 daysLength = item->cellWidth() - 1;
00810 } else {
00811 startTime = mAgenda->gyToTime( item->cellYTop() );
00812 if ( item->lastMultiItem() ) {
00813 endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
00814 daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
00815 } else {
00816 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
00817 }
00818 }
00819
00820
00821
00822 if ( incidence->type() == "Event" ) {
00823 startDt = incidence->dtStart();
00824 startDt = startDt.addDays( daysOffset );
00825 startDt.setTime( startTime );
00826 endDt = startDt.addDays( daysLength );
00827 endDt.setTime( endTime );
00828 Event*ev = static_cast<Event*>(incidence);
00829 if( incidence->dtStart() == startDt && ev->dtEnd() == endDt ) {
00830
00831 delete oldIncidence;
00832 return;
00833 }
00834 incidence->setDtStart( startDt );
00835 ev->setDtEnd( endDt );
00836 } else if ( incidence->type() == "Todo" ) {
00837 Todo *td = static_cast<Todo*>(incidence);
00838 startDt = td->hasStartDate() ? td->dtStart() : td->dtDue();
00839 startDt = thisDate.addDays( td->dtDue().daysTo( startDt ) );
00840 startDt.setTime( startTime );
00841 endDt.setDate( thisDate );
00842 endDt.setTime( endTime );
00843
00844 if( td->dtDue() == endDt ) {
00845
00846 delete oldIncidence;
00847 return;
00848 }
00849 }
00850
00851
00852
00853
00854 Recurrence *recur = incidence->recurrence();
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996 if ( incidence->type() == "Event" ) {
00997 incidence->setDtStart( startDt );
00998 (static_cast<Event*>( incidence ) )->setDtEnd( endDt );
00999 } else if ( incidence->type() == "Todo" ) {
01000 Todo *td = static_cast<Todo*>( incidence );
01001 if ( td->hasStartDate() )
01002 td->setDtStart( startDt );
01003 td->setDtDue( endDt );
01004 }
01005
01006 item->setItemDate( startDt.date() );
01007
01008 KOIncidenceToolTip::remove( item );
01009 KOIncidenceToolTip::add( item, incidence, KOAgendaItem::toolTipGroup() );
01010
01011 const bool result = mChanger->changeIncidence( oldIncidence, incidence );
01012 mChanger->endChange(incidence);
01013 delete oldIncidence;
01014
01015 if ( !result ) {
01016 mPendingChanges = true;
01017 QTimer::singleShot( 0, this, SLOT(updateView()) );
01018 return;
01019 }
01020
01021
01022
01023
01024 enableAgendaUpdate( false );
01025
01026
01027
01028
01029 if ( incidence->doesRecur() ) {
01030 mUpdateItem = incidence;
01031 QTimer::singleShot( 0, this, SLOT( doUpdateItem() ) );
01032 }
01033
01034 enableAgendaUpdate( true );
01035
01036
01037 }
01038
01039 void KOAgendaView::doUpdateItem()
01040 {
01041 if ( mUpdateItem ) {
01042 changeIncidenceDisplay( mUpdateItem, KOGlobals::INCIDENCEEDITED );
01043 mUpdateItem = 0;
01044 }
01045 }
01046
01047
01048
01049 void KOAgendaView::showDates( const QDate &start, const QDate &end )
01050 {
01051
01052 if ( !mSelectedDates.isEmpty() && mSelectedDates.first() == start
01053 && mSelectedDates.last() == end && !mPendingChanges )
01054 return;
01055
01056 mSelectedDates.clear();
01057
01058 QDate d = start;
01059 while (d <= end) {
01060 mSelectedDates.append(d);
01061 d = d.addDays( 1 );
01062 }
01063
01064
01065 fillAgenda();
01066 }
01067
01068
01069 void KOAgendaView::showIncidences( const Incidence::List & )
01070 {
01071 kdDebug(5850) << "KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
01072 }
01073
01074 void KOAgendaView::insertIncidence( Incidence *incidence, const QDate &curDate,
01075 int curCol )
01076 {
01077 if ( !filterByResource( incidence ) )
01078 return;
01079
01080
01081 Event *event = dynamic_cast<Event *>( incidence );
01082 Todo *todo = dynamic_cast<Todo *>( incidence );
01083
01084 if ( curCol < 0 ) {
01085 curCol = mSelectedDates.findIndex( curDate );
01086 }
01087
01088 if ( curCol < 0 || curCol > int( mSelectedDates.size() ) )
01089 return;
01090
01091 int beginX;
01092 int endX;
01093 if ( event ) {
01094 beginX = curDate.daysTo( incidence->dtStart().date() ) + curCol;
01095 endX = curDate.daysTo( event->dateEnd() ) + curCol;
01096 } else if ( todo ) {
01097 if ( ! todo->hasDueDate() ) return;
01098 beginX = curDate.daysTo( todo->dtDue().date() ) + curCol;
01099 endX = beginX;
01100 } else {
01101 return;
01102 }
01103
01104 if ( todo && todo->isOverdue() ) {
01105 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01106 } else if ( incidence->doesFloat() ) {
01107
01108 if ( incidence->recurrence()->doesRecur() ) {
01109 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01110 } else {
01111
01112
01113 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
01114 mAllDayAgenda->insertAllDayItem( incidence, curDate, beginX, endX );
01115 }
01116 }
01117 } else if ( event && event->isMultiDay() ) {
01118 int startY = mAgenda->timeToY( event->dtStart().time() );
01119 QTime endtime( event->dtEnd().time() );
01120 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01121 int endY = mAgenda->timeToY( endtime ) - 1;
01122 if ( (beginX <= 0 && curCol == 0) || beginX == curCol ) {
01123 mAgenda->insertMultiItem( event, curDate, beginX, endX, startY, endY );
01124 }
01125 if ( beginX == curCol ) {
01126 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01127 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01128 } else if ( endX == curCol ) {
01129 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01130 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01131 } else {
01132 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01133 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01134 }
01135 } else {
01136 int startY = 0, endY = 0;
01137 if ( event ) {
01138 startY = mAgenda->timeToY( incidence->dtStart().time() );
01139 QTime endtime( event->dtEnd().time() );
01140 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01141 endY = mAgenda->timeToY( endtime ) - 1;
01142 }
01143 if ( todo ) {
01144 QTime t = todo->dtDue().time();
01145 endY = mAgenda->timeToY( t ) - 1;
01146 startY = mAgenda->timeToY( t.addSecs( -1800 ) );
01147 }
01148 if ( endY < startY ) endY = startY;
01149 mAgenda->insertItem( incidence, curDate, curCol, startY, endY );
01150 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01151 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01152 }
01153 }
01154
01155 void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
01156 {
01157 Todo *todo = dynamic_cast<Todo *>(incidence);
01158 CalFilter *filter = calendar()->filter();
01159 if ( filter && !filter->filterIncidence( incidence ) ||
01160 ( todo && !KOPrefs::instance()->showAllDayTodo() ) )
01161 return;
01162
01163 QDate f = mSelectedDates.first();
01164 QDate l = mSelectedDates.last();
01165 QDate startDt = incidence->dtStart().date();
01166
01167 if ( incidence->doesRecur() ) {
01168 DateList::ConstIterator dit;
01169 QDate curDate;
01170 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01171 curDate = *dit;
01172
01173 if ( incidence->recursOn( curDate ) ) {
01174 insertIncidence( incidence, curDate );
01175 }
01176 }
01177 return;
01178 }
01179
01180 QDate endDt;
01181 if ( incidence->type() == "Event" )
01182 endDt = (static_cast<Event *>(incidence))->dateEnd();
01183 if ( todo ) {
01184 endDt = todo->isOverdue() ? QDate::currentDate()
01185 : todo->dtDue().date();
01186
01187 if ( endDt >= f && endDt <= l ) {
01188 insertIncidence( incidence, endDt );
01189 return;
01190 }
01191 }
01192
01193 if ( startDt >= f && startDt <= l ) {
01194 insertIncidence( incidence, startDt );
01195 }
01196 }
01197
01198 void KOAgendaView::changeIncidenceDisplay( Incidence *incidence, int mode )
01199 {
01200 switch ( mode ) {
01201 case KOGlobals::INCIDENCEADDED: {
01202
01203
01204
01205
01206 if ( mAllowAgendaUpdate )
01207 changeIncidenceDisplayAdded( incidence );
01208 break;
01209 }
01210 case KOGlobals::INCIDENCEEDITED: {
01211 if ( !mAllowAgendaUpdate ) {
01212 updateEventIndicators();
01213 } else {
01214 removeIncidence( incidence );
01215 updateEventIndicators();
01216 changeIncidenceDisplayAdded( incidence );
01217 }
01218 break;
01219 }
01220 case KOGlobals::INCIDENCEDELETED: {
01221 mAgenda->removeIncidence( incidence );
01222 mAllDayAgenda->removeIncidence( incidence );
01223 updateEventIndicators();
01224 break;
01225 }
01226 default:
01227 updateView();
01228 }
01229 }
01230
01231 void KOAgendaView::fillAgenda( const QDate & )
01232 {
01233 fillAgenda();
01234 }
01235
01236 void KOAgendaView::fillAgenda()
01237 {
01238 mPendingChanges = false;
01239
01240
01241
01242 const QString &selectedAgendaUid = mAgenda->lastSelectedUid();
01243 const QString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
01244
01245 enableAgendaUpdate( true );
01246 clearView();
01247
01248 mAllDayAgenda->changeColumns(mSelectedDates.count());
01249 mAgenda->changeColumns(mSelectedDates.count());
01250 mEventIndicatorTop->changeColumns(mSelectedDates.count());
01251 mEventIndicatorBottom->changeColumns(mSelectedDates.count());
01252
01253 createDayLabels();
01254 setHolidayMasks();
01255
01256 mMinY.resize(mSelectedDates.count());
01257 mMaxY.resize(mSelectedDates.count());
01258
01259 Event::List dayEvents;
01260
01261
01262
01263 Todo::List todos = calendar()->todos();
01264
01265 mAgenda->setDateList(mSelectedDates);
01266
01267 QDate today = QDate::currentDate();
01268
01269 bool somethingReselected = false;
01270 DateList::ConstIterator dit;
01271 int curCol = 0;
01272 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01273 QDate currentDate = *dit;
01274
01275
01276
01277 dayEvents = calendar()->events(currentDate,
01278 EventSortStartDate,
01279 SortDirectionAscending);
01280
01281
01282 mMinY[curCol] = mAgenda->timeToY(QTime(23,59)) + 1;
01283 mMaxY[curCol] = mAgenda->timeToY(QTime(0,0)) - 1;
01284
01285 unsigned int numEvent;
01286 for(numEvent=0;numEvent<dayEvents.count();++numEvent) {
01287 Event *event = *dayEvents.at(numEvent);
01288
01289 insertIncidence( event, currentDate, curCol );
01290 if( event->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
01291 mAgenda->selectItemByUID( event->uid() );
01292 somethingReselected = true;
01293 }
01294 if( event->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
01295 mAllDayAgenda->selectItemByUID( event->uid() );
01296 somethingReselected = true;
01297 }
01298
01299 }
01300
01301
01302
01303
01304 if ( KOPrefs::instance()->showAllDayTodo() ) {
01305 unsigned int numTodo;
01306 for (numTodo = 0; numTodo < todos.count(); ++numTodo) {
01307 Todo *todo = *todos.at(numTodo);
01308
01309 if ( ! todo->hasDueDate() ) continue;
01310
01311 if ( !filterByResource( todo ) ) continue;
01312
01313
01314
01315 bool overdue = todo->isOverdue();
01316
01317 if ( (( todo->dtDue().date() == currentDate) && !overdue) ||
01318 (( currentDate == today) && overdue) ||
01319 ( todo->recursOn( currentDate ) ) ) {
01320 if ( todo->doesFloat() || overdue ) {
01321
01322
01323 mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol);
01324 } else {
01325
01326
01327 int endY = mAgenda->timeToY(todo->dtDue().time()) - 1;
01328 int startY = endY - 1;
01329
01330 mAgenda->insertItem(todo,currentDate,curCol,startY,endY);
01331
01332 if (startY < mMinY[curCol]) mMinY[curCol] = startY;
01333 if (endY > mMaxY[curCol]) mMaxY[curCol] = endY;
01334 }
01335 }
01336 }
01337 }
01338
01339
01340 ++curCol;
01341 }
01342
01343 mAgenda->checkScrollBoundaries();
01344 updateEventIndicators();
01345
01346
01347
01348
01349
01350 deleteSelectedDateTime();
01351
01352 if( !somethingReselected ) {
01353 emit incidenceSelected( 0 );
01354 }
01355
01356
01357 }
01358
01359 void KOAgendaView::clearView()
01360 {
01361
01362 mAllDayAgenda->clear();
01363 mAgenda->clear();
01364 }
01365
01366 CalPrinterBase::PrintType KOAgendaView::printType()
01367 {
01368 if ( currentDateCount() == 1 ) return CalPrinterBase::Day;
01369 else return CalPrinterBase::Week;
01370 }
01371
01372 void KOAgendaView::updateEventIndicatorTop( int newY )
01373 {
01374 uint i;
01375 for( i = 0; i < mMinY.size(); ++i ) {
01376 mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
01377 }
01378 mEventIndicatorTop->update();
01379 }
01380
01381 void KOAgendaView::updateEventIndicatorBottom( int newY )
01382 {
01383 uint i;
01384 for( i = 0; i < mMaxY.size(); ++i ) {
01385 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
01386 }
01387 mEventIndicatorBottom->update();
01388 }
01389
01390 void KOAgendaView::slotTodoDropped( Todo *todo, const QPoint &gpos, bool allDay )
01391 {
01392 if ( gpos.x()<0 || gpos.y()<0 ) return;
01393 QDate day = mSelectedDates[gpos.x()];
01394 QTime time = mAgenda->gyToTime( gpos.y() );
01395 QDateTime newTime( day, time );
01396
01397 if ( todo ) {
01398 Todo *existingTodo = calendar()->todo( todo->uid() );
01399 if ( existingTodo ) {
01400 kdDebug(5850) << "Drop existing Todo" << endl;
01401 Todo *oldTodo = existingTodo->clone();
01402 if ( mChanger && mChanger->beginChange( existingTodo ) ) {
01403 existingTodo->setDtDue( newTime );
01404 existingTodo->setFloats( allDay );
01405 existingTodo->setHasDueDate( true );
01406 mChanger->changeIncidence( oldTodo, existingTodo );
01407 mChanger->endChange( existingTodo );
01408 } else {
01409 KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
01410 "because it cannot be locked.") );
01411 }
01412 delete oldTodo;
01413 } else {
01414 kdDebug(5850) << "Drop new Todo" << endl;
01415 todo->setDtDue( newTime );
01416 todo->setFloats( allDay );
01417 todo->setHasDueDate( true );
01418 if ( !mChanger->addIncidence( todo, this ) ) {
01419 KODialogManager::errorSaveIncidence( this, todo );
01420 }
01421 }
01422 }
01423 }
01424
01425 void KOAgendaView::startDrag( Incidence *incidence )
01426 {
01427 #ifndef KORG_NODND
01428 DndFactory factory( calendar() );
01429 ICalDrag *vd = factory.createDrag( incidence, this );
01430 if ( vd->drag() ) {
01431 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01432 }
01433 #endif
01434 }
01435
01436 void KOAgendaView::readSettings()
01437 {
01438 readSettings(KOGlobals::self()->config());
01439 }
01440
01441 void KOAgendaView::readSettings(KConfig *config)
01442 {
01443
01444
01445 config->setGroup("Views");
01446
01447 #ifndef KORG_NOSPLITTER
01448 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01449 if (sizes.count() == 2) {
01450 mSplitterAgenda->setSizes(sizes);
01451 }
01452 #endif
01453
01454 updateConfig();
01455 }
01456
01457 void KOAgendaView::writeSettings(KConfig *config)
01458 {
01459
01460
01461 config->setGroup("Views");
01462
01463 #ifndef KORG_NOSPLITTER
01464 QValueList<int> list = mSplitterAgenda->sizes();
01465 config->writeEntry("Separator AgendaView",list);
01466 #endif
01467 }
01468
01469 void KOAgendaView::setHolidayMasks()
01470 {
01471 mHolidayMask.resize( mSelectedDates.count() + 1 );
01472
01473 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01474 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01475 }
01476
01477
01478
01479 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01480 mHolidayMask[ mSelectedDates.count() ] = showDay;
01481
01482 mAgenda->setHolidayMask( &mHolidayMask );
01483 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01484 }
01485
01486 void KOAgendaView::setContentsPos( int y )
01487 {
01488 mAgenda->setContentsPos( 0, y );
01489 }
01490
01491 void KOAgendaView::setExpandedButton( bool expanded )
01492 {
01493 if ( !mExpandButton ) return;
01494
01495 if ( expanded ) {
01496 mExpandButton->setPixmap( mExpandedPixmap );
01497 } else {
01498 mExpandButton->setPixmap( mNotExpandedPixmap );
01499 }
01500 }
01501
01502 void KOAgendaView::clearSelection()
01503 {
01504 mAgenda->deselectItem();
01505 mAllDayAgenda->deselectItem();
01506 }
01507
01508 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01509 {
01510 newTimeSpanSelected( start, end );
01511 mTimeSpanInAllDay = true;
01512 }
01513
01514 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01515 {
01516 if (!mSelectedDates.count()) return;
01517
01518 mTimeSpanInAllDay = false;
01519
01520 QDate dayStart = mSelectedDates[ kClamp( start.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01521 QDate dayEnd = mSelectedDates[ kClamp( end.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01522
01523 QTime timeStart = mAgenda->gyToTime(start.y());
01524 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01525
01526 QDateTime dtStart(dayStart,timeStart);
01527 QDateTime dtEnd(dayEnd,timeEnd);
01528
01529 mTimeSpanBegin = dtStart;
01530 mTimeSpanEnd = dtEnd;
01531 }
01532
01533 void KOAgendaView::deleteSelectedDateTime()
01534 {
01535 mTimeSpanBegin.setDate(QDate());
01536 mTimeSpanEnd.setDate(QDate());
01537 mTimeSpanInAllDay = false;
01538 }
01539
01540 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01541 {
01542 mAgenda->setTypeAheadReceiver( o );
01543 mAllDayAgenda->setTypeAheadReceiver( o );
01544 }
01545
01546 void KOAgendaView::finishTypeAhead()
01547 {
01548 mAgenda->finishTypeAhead();
01549 mAllDayAgenda->finishTypeAhead();
01550 }
01551
01552 void KOAgendaView::removeIncidence( Incidence *incidence )
01553 {
01554 mAgenda->removeIncidence( incidence );
01555 mAllDayAgenda->removeIncidence( incidence );
01556 }
01557
01558 void KOAgendaView::updateEventIndicators()
01559 {
01560 mMinY = mAgenda->minContentsY();
01561 mMaxY = mAgenda->maxContentsY();
01562
01563 mAgenda->checkScrollBoundaries();
01564 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01565 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01566 }
01567
01568 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01569 {
01570 mChanger = changer;
01571 mAgenda->setIncidenceChanger( changer );
01572 mAllDayAgenda->setIncidenceChanger( changer );
01573 }
01574
01575 void KOAgendaView::clearTimeSpanSelection()
01576 {
01577 mAgenda->clearSelection();
01578 mAllDayAgenda->clearSelection();
01579 deleteSelectedDateTime();
01580 }
01581
01582 void KOAgendaView::setResource(KCal::ResourceCalendar * res, const QString & subResource)
01583 {
01584 mResource = res;
01585 mSubResource = subResource;
01586 }
01587
01588 bool KOAgendaView::filterByResource(Incidence * incidence)
01589 {
01590 if ( !mResource )
01591 return true;
01592 CalendarResources *calRes = dynamic_cast<CalendarResources*>( calendar() );
01593 if ( !calRes )
01594 return true;
01595 if ( calRes->resource( incidence ) != mResource )
01596 return false;
01597 if ( !mSubResource.isEmpty() ) {
01598 if ( mResource->subresourceIdentifier( incidence ) != mSubResource )
01599 return false;
01600 }
01601 return true;
01602 }
01603
01604 void KOAgendaView::resourcesChanged()
01605 {
01606 mPendingChanges = true;
01607 }
01608
01609 void KOAgendaView::calendarIncidenceAdded(Incidence * incidence)
01610 {
01611 Q_UNUSED( incidence );
01612 mPendingChanges = true;
01613 }
01614
01615 void KOAgendaView::calendarIncidenceChanged(Incidence * incidence)
01616 {
01617 Q_UNUSED( incidence );
01618 mPendingChanges = true;
01619 }
01620
01621 void KOAgendaView::calendarIncidenceRemoved(Incidence * incidence)
01622 {
01623 Q_UNUSED( incidence );
01624 mPendingChanges = true;
01625 }