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