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
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
00997 if ( incidence->type() == "Event" ) {
00998 incidence->setDtStart( startDt );
00999 (static_cast<Event*>( incidence ) )->setDtEnd( endDt );
01000 } else if ( incidence->type() == "Todo" ) {
01001 Todo *td = static_cast<Todo*>( incidence );
01002 if ( td->hasStartDate() )
01003 td->setDtStart( startDt );
01004 td->setDtDue( endDt );
01005 }
01006
01007 item->setItemDate( startDt.date() );
01008
01009 KOIncidenceToolTip::remove( item );
01010 KOIncidenceToolTip::add( item, calendar(), incidence, KOAgendaItem::toolTipGroup() );
01011
01012 const bool result = mChanger->changeIncidence( oldIncidence, incidence );
01013 mChanger->endChange(incidence);
01014 delete oldIncidence;
01015
01016 if ( !result ) {
01017 mPendingChanges = true;
01018 QTimer::singleShot( 0, this, SLOT(updateView()) );
01019 return;
01020 }
01021
01022
01023
01024
01025 enableAgendaUpdate( false );
01026
01027
01028
01029
01030 if ( incidence->doesRecur() ) {
01031 mUpdateItem = incidence;
01032 QTimer::singleShot( 0, this, SLOT( doUpdateItem() ) );
01033 }
01034
01035 enableAgendaUpdate( true );
01036
01037
01038 }
01039
01040 void KOAgendaView::doUpdateItem()
01041 {
01042 if ( mUpdateItem ) {
01043 changeIncidenceDisplay( mUpdateItem, KOGlobals::INCIDENCEEDITED );
01044 mUpdateItem = 0;
01045 }
01046 }
01047
01048
01049
01050 void KOAgendaView::showDates( const QDate &start, const QDate &end )
01051 {
01052
01053 if ( !mSelectedDates.isEmpty() && mSelectedDates.first() == start
01054 && mSelectedDates.last() == end && !mPendingChanges )
01055 return;
01056
01057 mSelectedDates.clear();
01058
01059 QDate d = start;
01060 while (d <= end) {
01061 mSelectedDates.append(d);
01062 d = d.addDays( 1 );
01063 }
01064
01065
01066 fillAgenda();
01067 }
01068
01069
01070 void KOAgendaView::showIncidences( const Incidence::List & )
01071 {
01072 kdDebug(5850) << "KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
01073 }
01074
01075 void KOAgendaView::insertIncidence( Incidence *incidence, const QDate &curDate,
01076 int curCol )
01077 {
01078 if ( !filterByResource( incidence ) )
01079 return;
01080
01081
01082 Event *event = dynamic_cast<Event *>( incidence );
01083 Todo *todo = dynamic_cast<Todo *>( incidence );
01084
01085 if ( curCol < 0 ) {
01086 curCol = mSelectedDates.findIndex( curDate );
01087 }
01088
01089 if ( curCol < 0 || curCol > int( mSelectedDates.size() ) )
01090 return;
01091
01092 int beginX;
01093 int endX;
01094 if ( event ) {
01095 beginX = curDate.daysTo( incidence->dtStart().date() ) + curCol;
01096 endX = curDate.daysTo( event->dateEnd() ) + curCol;
01097 } else if ( todo ) {
01098 if ( ! todo->hasDueDate() ) return;
01099 beginX = curDate.daysTo( todo->dtDue().date() ) + curCol;
01100 endX = beginX;
01101 } else {
01102 return;
01103 }
01104
01105 if ( todo && todo->isOverdue() ) {
01106 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01107 } else if ( incidence->doesFloat() ) {
01108
01109 if ( incidence->recurrence()->doesRecur() ) {
01110 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01111 } else {
01112
01113
01114 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
01115 mAllDayAgenda->insertAllDayItem( incidence, curDate, beginX, endX );
01116 }
01117 }
01118 } else if ( event && event->isMultiDay() ) {
01119 int startY = mAgenda->timeToY( event->dtStart().time() );
01120 QTime endtime( event->dtEnd().time() );
01121 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01122 int endY = mAgenda->timeToY( endtime ) - 1;
01123 if ( (beginX <= 0 && curCol == 0) || beginX == curCol ) {
01124 mAgenda->insertMultiItem( event, curDate, beginX, endX, startY, endY );
01125 }
01126 if ( beginX == curCol ) {
01127 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01128 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01129 } else if ( endX == curCol ) {
01130 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01131 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01132 } else {
01133 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01134 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01135 }
01136 } else {
01137 int startY = 0, endY = 0;
01138 if ( event ) {
01139 startY = mAgenda->timeToY( incidence->dtStart().time() );
01140 QTime endtime( event->dtEnd().time() );
01141 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01142 endY = mAgenda->timeToY( endtime ) - 1;
01143 }
01144 if ( todo ) {
01145 QTime t = todo->dtDue().time();
01146 endY = mAgenda->timeToY( t ) - 1;
01147 startY = mAgenda->timeToY( t.addSecs( -1800 ) );
01148 }
01149 if ( endY < startY ) endY = startY;
01150 mAgenda->insertItem( incidence, curDate, curCol, startY, endY );
01151 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01152 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01153 }
01154 }
01155
01156 void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
01157 {
01158 Todo *todo = dynamic_cast<Todo *>(incidence);
01159 CalFilter *filter = calendar()->filter();
01160 if ( ( filter && !filter->filterIncidence( incidence ) ) ||
01161 ( todo && !KOPrefs::instance()->showAllDayTodo() ) )
01162 return;
01163
01164 QDate f = mSelectedDates.first();
01165 QDate l = mSelectedDates.last();
01166 QDate startDt = incidence->dtStart().date();
01167
01168 if ( incidence->doesRecur() ) {
01169 DateList::ConstIterator dit;
01170 QDate curDate;
01171 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01172 curDate = *dit;
01173
01174 if ( incidence->recursOn( curDate ) ) {
01175 insertIncidence( incidence, curDate );
01176 }
01177 }
01178 return;
01179 }
01180
01181 QDate endDt;
01182 if ( incidence->type() == "Event" )
01183 endDt = (static_cast<Event *>(incidence))->dateEnd();
01184 if ( todo ) {
01185 endDt = todo->isOverdue() ? QDate::currentDate()
01186 : todo->dtDue().date();
01187
01188 if ( endDt >= f && endDt <= l ) {
01189 insertIncidence( incidence, endDt );
01190 return;
01191 }
01192 }
01193
01194 if ( startDt >= f && startDt <= l ) {
01195 insertIncidence( incidence, startDt );
01196 }
01197 }
01198
01199 void KOAgendaView::changeIncidenceDisplay( Incidence *incidence, int mode )
01200 {
01201 switch ( mode ) {
01202 case KOGlobals::INCIDENCEADDED: {
01203
01204
01205
01206
01207 if ( mAllowAgendaUpdate )
01208 changeIncidenceDisplayAdded( incidence );
01209 break;
01210 }
01211 case KOGlobals::INCIDENCEEDITED: {
01212 if ( !mAllowAgendaUpdate ) {
01213 updateEventIndicators();
01214 } else {
01215 removeIncidence( incidence );
01216 updateEventIndicators();
01217 changeIncidenceDisplayAdded( incidence );
01218 }
01219 break;
01220 }
01221 case KOGlobals::INCIDENCEDELETED: {
01222 mAgenda->removeIncidence( incidence );
01223 mAllDayAgenda->removeIncidence( incidence );
01224 updateEventIndicators();
01225 break;
01226 }
01227 default:
01228 updateView();
01229 }
01230 }
01231
01232 void KOAgendaView::fillAgenda( const QDate & )
01233 {
01234 fillAgenda();
01235 }
01236
01237 void KOAgendaView::fillAgenda()
01238 {
01239 mPendingChanges = false;
01240
01241
01242
01243 const QString &selectedAgendaUid = mAgenda->lastSelectedUid();
01244 const QString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
01245
01246 enableAgendaUpdate( true );
01247 clearView();
01248
01249 mAllDayAgenda->changeColumns(mSelectedDates.count());
01250 mAgenda->changeColumns(mSelectedDates.count());
01251 mEventIndicatorTop->changeColumns(mSelectedDates.count());
01252 mEventIndicatorBottom->changeColumns(mSelectedDates.count());
01253
01254 createDayLabels();
01255 setHolidayMasks();
01256
01257 mMinY.resize(mSelectedDates.count());
01258 mMaxY.resize(mSelectedDates.count());
01259
01260 Event::List dayEvents;
01261
01262
01263
01264 Todo::List todos = calendar()->todos();
01265
01266 mAgenda->setDateList(mSelectedDates);
01267
01268 QDate today = QDate::currentDate();
01269
01270 bool somethingReselected = false;
01271 DateList::ConstIterator dit;
01272 int curCol = 0;
01273 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01274 QDate currentDate = *dit;
01275
01276
01277
01278 dayEvents = calendar()->events(currentDate,
01279 EventSortStartDate,
01280 SortDirectionAscending);
01281
01282
01283 mMinY[curCol] = mAgenda->timeToY(QTime(23,59)) + 1;
01284 mMaxY[curCol] = mAgenda->timeToY(QTime(0,0)) - 1;
01285
01286 unsigned int numEvent;
01287 for(numEvent=0;numEvent<dayEvents.count();++numEvent) {
01288 Event *event = *dayEvents.at(numEvent);
01289
01290 insertIncidence( event, currentDate, curCol );
01291 if( event->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
01292 mAgenda->selectItemByUID( event->uid() );
01293 somethingReselected = true;
01294 }
01295 if( event->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
01296 mAllDayAgenda->selectItemByUID( event->uid() );
01297 somethingReselected = true;
01298 }
01299
01300 }
01301
01302
01303
01304
01305 if ( KOPrefs::instance()->showAllDayTodo() ) {
01306 unsigned int numTodo;
01307 for (numTodo = 0; numTodo < todos.count(); ++numTodo) {
01308 Todo *todo = *todos.at(numTodo);
01309
01310 if ( ! todo->hasDueDate() ) continue;
01311
01312 if ( !filterByResource( todo ) ) continue;
01313
01314
01315
01316 bool overdue = todo->isOverdue();
01317
01318 if ( (( todo->dtDue().date() == currentDate) && !overdue) ||
01319 (( currentDate == today) && overdue) ||
01320 ( todo->recursOn( currentDate ) ) ) {
01321 if ( todo->doesFloat() || overdue ) {
01322
01323
01324 mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol);
01325 } else {
01326
01327
01328 int endY = mAgenda->timeToY(todo->dtDue().time()) - 1;
01329 int startY = endY - 1;
01330
01331 mAgenda->insertItem(todo,currentDate,curCol,startY,endY);
01332
01333 if (startY < mMinY[curCol]) mMinY[curCol] = startY;
01334 if (endY > mMaxY[curCol]) mMaxY[curCol] = endY;
01335 }
01336 }
01337 }
01338 }
01339
01340
01341 ++curCol;
01342 }
01343
01344 mAgenda->checkScrollBoundaries();
01345 updateEventIndicators();
01346
01347
01348
01349
01350
01351 deleteSelectedDateTime();
01352
01353 if( !somethingReselected ) {
01354 emit incidenceSelected( 0 );
01355 }
01356
01357
01358 }
01359
01360 void KOAgendaView::clearView()
01361 {
01362
01363 mAllDayAgenda->clear();
01364 mAgenda->clear();
01365 }
01366
01367 CalPrinterBase::PrintType KOAgendaView::printType()
01368 {
01369 if ( currentDateCount() == 1 ) return CalPrinterBase::Day;
01370 else return CalPrinterBase::Week;
01371 }
01372
01373 void KOAgendaView::updateEventIndicatorTop( int newY )
01374 {
01375 uint i;
01376 for( i = 0; i < mMinY.size(); ++i ) {
01377 mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
01378 }
01379 mEventIndicatorTop->update();
01380 }
01381
01382 void KOAgendaView::updateEventIndicatorBottom( int newY )
01383 {
01384 uint i;
01385 for( i = 0; i < mMaxY.size(); ++i ) {
01386 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
01387 }
01388 mEventIndicatorBottom->update();
01389 }
01390
01391 void KOAgendaView::slotTodoDropped( Todo *todo, const QPoint &gpos, bool allDay )
01392 {
01393 if ( gpos.x()<0 || gpos.y()<0 ) return;
01394 QDate day = mSelectedDates[gpos.x()];
01395 QTime time = mAgenda->gyToTime( gpos.y() );
01396 QDateTime newTime( day, time );
01397
01398 if ( todo ) {
01399 Todo *existingTodo = calendar()->todo( todo->uid() );
01400 if ( existingTodo ) {
01401 kdDebug(5850) << "Drop existing Todo" << endl;
01402 Todo *oldTodo = existingTodo->clone();
01403 if ( mChanger && mChanger->beginChange( existingTodo ) ) {
01404 existingTodo->setDtDue( newTime );
01405 existingTodo->setFloats( allDay );
01406 existingTodo->setHasDueDate( true );
01407 mChanger->changeIncidence( oldTodo, existingTodo );
01408 mChanger->endChange( existingTodo );
01409 } else {
01410 KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
01411 "because it cannot be locked.") );
01412 }
01413 delete oldTodo;
01414 } else {
01415 kdDebug(5850) << "Drop new Todo" << endl;
01416 todo->setDtDue( newTime );
01417 todo->setFloats( allDay );
01418 todo->setHasDueDate( true );
01419 if ( !mChanger->addIncidence( todo, this ) ) {
01420 KODialogManager::errorSaveIncidence( this, todo );
01421 }
01422 }
01423 }
01424 }
01425
01426 void KOAgendaView::startDrag( Incidence *incidence )
01427 {
01428 #ifndef KORG_NODND
01429 DndFactory factory( calendar() );
01430 ICalDrag *vd = factory.createDrag( incidence, this );
01431 if ( vd->drag() ) {
01432 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01433 }
01434 #endif
01435 }
01436
01437 void KOAgendaView::readSettings()
01438 {
01439 readSettings(KOGlobals::self()->config());
01440 }
01441
01442 void KOAgendaView::readSettings(KConfig *config)
01443 {
01444
01445
01446 config->setGroup("Views");
01447
01448 #ifndef KORG_NOSPLITTER
01449 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01450 if (sizes.count() == 2) {
01451 mSplitterAgenda->setSizes(sizes);
01452 }
01453 #endif
01454
01455 updateConfig();
01456 }
01457
01458 void KOAgendaView::writeSettings(KConfig *config)
01459 {
01460
01461
01462 config->setGroup("Views");
01463
01464 #ifndef KORG_NOSPLITTER
01465 QValueList<int> list = mSplitterAgenda->sizes();
01466 config->writeEntry("Separator AgendaView",list);
01467 #endif
01468 }
01469
01470 void KOAgendaView::setHolidayMasks()
01471 {
01472 if ( mSelectedDates.isEmpty() || !mSelectedDates[0].isValid() ) {
01473 return;
01474 }
01475
01476 mHolidayMask.resize( mSelectedDates.count() + 1 );
01477
01478 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01479 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01480 }
01481
01482
01483
01484 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01485 mHolidayMask[ mSelectedDates.count() ] = showDay;
01486
01487 mAgenda->setHolidayMask( &mHolidayMask );
01488 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01489 }
01490
01491 void KOAgendaView::setContentsPos( int y )
01492 {
01493 mAgenda->setContentsPos( 0, y );
01494 }
01495
01496 void KOAgendaView::setExpandedButton( bool expanded )
01497 {
01498 if ( !mExpandButton ) return;
01499
01500 if ( expanded ) {
01501 mExpandButton->setPixmap( mExpandedPixmap );
01502 } else {
01503 mExpandButton->setPixmap( mNotExpandedPixmap );
01504 }
01505 }
01506
01507 void KOAgendaView::clearSelection()
01508 {
01509 mAgenda->deselectItem();
01510 mAllDayAgenda->deselectItem();
01511 }
01512
01513 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01514 {
01515 newTimeSpanSelected( start, end );
01516 mTimeSpanInAllDay = true;
01517 }
01518
01519 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01520 {
01521 if (!mSelectedDates.count()) return;
01522
01523 mTimeSpanInAllDay = false;
01524
01525 QDate dayStart = mSelectedDates[ kClamp( start.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01526 QDate dayEnd = mSelectedDates[ kClamp( end.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01527
01528 QTime timeStart = mAgenda->gyToTime(start.y());
01529 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01530
01531 QDateTime dtStart(dayStart,timeStart);
01532 QDateTime dtEnd(dayEnd,timeEnd);
01533
01534 mTimeSpanBegin = dtStart;
01535 mTimeSpanEnd = dtEnd;
01536 }
01537
01538 void KOAgendaView::deleteSelectedDateTime()
01539 {
01540 mTimeSpanBegin.setDate(QDate());
01541 mTimeSpanEnd.setDate(QDate());
01542 mTimeSpanInAllDay = false;
01543 }
01544
01545 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01546 {
01547 mAgenda->setTypeAheadReceiver( o );
01548 mAllDayAgenda->setTypeAheadReceiver( o );
01549 }
01550
01551 void KOAgendaView::finishTypeAhead()
01552 {
01553 mAgenda->finishTypeAhead();
01554 mAllDayAgenda->finishTypeAhead();
01555 }
01556
01557 void KOAgendaView::removeIncidence( Incidence *incidence )
01558 {
01559 mAgenda->removeIncidence( incidence );
01560 mAllDayAgenda->removeIncidence( incidence );
01561 }
01562
01563 void KOAgendaView::updateEventIndicators()
01564 {
01565 mMinY = mAgenda->minContentsY();
01566 mMaxY = mAgenda->maxContentsY();
01567
01568 mAgenda->checkScrollBoundaries();
01569 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01570 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01571 }
01572
01573 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01574 {
01575 mChanger = changer;
01576 mAgenda->setIncidenceChanger( changer );
01577 mAllDayAgenda->setIncidenceChanger( changer );
01578 }
01579
01580 void KOAgendaView::clearTimeSpanSelection()
01581 {
01582 mAgenda->clearSelection();
01583 mAllDayAgenda->clearSelection();
01584 deleteSelectedDateTime();
01585 }
01586
01587 void KOAgendaView::setResource(KCal::ResourceCalendar * res, const QString & subResource)
01588 {
01589 mResource = res;
01590 mSubResource = subResource;
01591 }
01592
01593 bool KOAgendaView::filterByResource(Incidence * incidence)
01594 {
01595 if ( !mResource )
01596 return true;
01597 CalendarResources *calRes = dynamic_cast<CalendarResources*>( calendar() );
01598 if ( !calRes )
01599 return true;
01600 if ( calRes->resource( incidence ) != mResource )
01601 return false;
01602 if ( !mSubResource.isEmpty() ) {
01603 if ( mResource->subresourceIdentifier( incidence ) != mSubResource )
01604 return false;
01605 }
01606 return true;
01607 }
01608
01609 void KOAgendaView::resourcesChanged()
01610 {
01611 mPendingChanges = true;
01612 }
01613
01614 void KOAgendaView::calendarIncidenceAdded(Incidence * incidence)
01615 {
01616 Q_UNUSED( incidence );
01617 mPendingChanges = true;
01618 }
01619
01620 void KOAgendaView::calendarIncidenceChanged(Incidence * incidence)
01621 {
01622 Q_UNUSED( incidence );
01623 mPendingChanges = true;
01624 }
01625
01626 void KOAgendaView::calendarIncidenceRemoved(Incidence * incidence)
01627 {
01628 Q_UNUSED( incidence );
01629 mPendingChanges = true;
01630 }