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 connect( cal, SIGNAL(calendarChanged()), SLOT(resourcesChanged()) );
00372 }
00373 }
00374
00375
00376 KOAgendaView::~KOAgendaView()
00377 {
00378 if ( calendar() )
00379 calendar()->unregisterObserver( this );
00380 delete mAgendaPopup;
00381 delete mAllDayAgendaPopup;
00382 }
00383
00384 void KOAgendaView::connectAgenda( KOAgenda *agenda, QPopupMenu *popup,
00385 KOAgenda *otherAgenda )
00386 {
00387 connect( agenda, SIGNAL( showIncidencePopupSignal( Incidence *, const QDate & ) ),
00388 popup, SLOT( showIncidencePopup( Incidence *, const QDate & ) ) );
00389
00390 connect( agenda, SIGNAL( showNewEventPopupSignal() ),
00391 SLOT( showNewEventPopup() ) );
00392
00393 agenda->setCalendar( calendar() );
00394
00395
00396 connect( agenda, SIGNAL( newEventSignal() ), SIGNAL( newEventSignal() ) );
00397
00398 connect( agenda, SIGNAL( newStartSelectSignal() ),
00399 otherAgenda, SLOT( clearSelection() ) );
00400 connect( agenda, SIGNAL( newStartSelectSignal() ),
00401 SIGNAL( timeSpanSelectionChanged()) );
00402
00403 connect( agenda, SIGNAL( editIncidenceSignal( Incidence * ) ),
00404 SIGNAL( editIncidenceSignal( Incidence * ) ) );
00405 connect( agenda, SIGNAL( showIncidenceSignal( Incidence * ) ),
00406 SIGNAL( showIncidenceSignal( Incidence * ) ) );
00407 connect( agenda, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
00408 SIGNAL( deleteIncidenceSignal( Incidence * ) ) );
00409
00410 connect( agenda, SIGNAL( startMultiModify( const QString & ) ),
00411 SIGNAL( startMultiModify( const QString & ) ) );
00412 connect( agenda, SIGNAL( endMultiModify() ),
00413 SIGNAL( endMultiModify() ) );
00414
00415 connect( agenda, SIGNAL( itemModified( KOAgendaItem * ) ),
00416 SLOT( updateEventDates( KOAgendaItem * ) ) );
00417 connect( agenda, SIGNAL( enableAgendaUpdate( bool ) ),
00418 SLOT( enableAgendaUpdate( bool ) ) );
00419
00420
00421 connect( agenda, SIGNAL( startDragSignal( Incidence * ) ),
00422 SLOT( startDrag( Incidence * ) ) );
00423
00424
00425 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00426 otherAgenda, SLOT( deselectItem() ) );
00427 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00428 SIGNAL( incidenceSelected( Incidence * ) ) );
00429
00430
00431 connect( agenda, SIGNAL( droppedToDo( Todo *, const QPoint &, bool ) ),
00432 SLOT( slotTodoDropped( Todo *, const QPoint &, bool ) ) );
00433
00434 }
00435
00436 void KOAgendaView::zoomInVertically( )
00437 {
00438 if ( !mIsSideBySide )
00439 KOPrefs::instance()->mHourSize++;
00440 mAgenda->updateConfig();
00441 mAgenda->checkScrollBoundaries();
00442
00443 mTimeLabels->updateConfig();
00444 mTimeLabels->positionChanged();
00445 mTimeLabels->repaint();
00446
00447 updateView();
00448 }
00449
00450 void KOAgendaView::zoomOutVertically( )
00451 {
00452
00453 if ( KOPrefs::instance()->mHourSize > 4 || mIsSideBySide ) {
00454
00455 if ( !mIsSideBySide )
00456 KOPrefs::instance()->mHourSize--;
00457 mAgenda->updateConfig();
00458 mAgenda->checkScrollBoundaries();
00459
00460 mTimeLabels->updateConfig();
00461 mTimeLabels->positionChanged();
00462 mTimeLabels->repaint();
00463
00464 updateView();
00465 }
00466 }
00467
00468 void KOAgendaView::zoomInHorizontally( const QDate &date)
00469 {
00470 QDate begin;
00471 QDate newBegin;
00472 QDate dateToZoom = date;
00473 int ndays,count;
00474
00475 begin = mSelectedDates.first();
00476 ndays = begin.daysTo( mSelectedDates.last() );
00477
00478
00479 if ( ! dateToZoom.isValid () )
00480 dateToZoom=mAgenda->selectedIncidenceDate();
00481
00482 if( !dateToZoom.isValid() ) {
00483 if ( ndays > 1 ) {
00484 newBegin=begin.addDays(1);
00485 count = ndays-1;
00486 emit zoomViewHorizontally ( newBegin , count );
00487 }
00488 } else {
00489 if ( ndays <= 2 ) {
00490 newBegin = dateToZoom;
00491 count = 1;
00492 } else {
00493 newBegin = dateToZoom.addDays( -ndays/2 +1 );
00494 count = ndays -1 ;
00495 }
00496 emit zoomViewHorizontally ( newBegin , count );
00497 }
00498 }
00499
00500 void KOAgendaView::zoomOutHorizontally( const QDate &date )
00501 {
00502 QDate begin;
00503 QDate newBegin;
00504 QDate dateToZoom = date;
00505 int ndays,count;
00506
00507 begin = mSelectedDates.first();
00508 ndays = begin.daysTo( mSelectedDates.last() );
00509
00510
00511 if ( ! dateToZoom.isValid () )
00512 dateToZoom=mAgenda->selectedIncidenceDate();
00513
00514 if ( !dateToZoom.isValid() ) {
00515 newBegin = begin.addDays(-1);
00516 count = ndays+3 ;
00517 } else {
00518 newBegin = dateToZoom.addDays( -ndays/2-1 );
00519 count = ndays+3;
00520 }
00521
00522 if ( abs( count ) >= 31 )
00523 kdDebug(5850) << "change to the mounth view?"<<endl;
00524 else
00525
00526 emit zoomViewHorizontally( newBegin, count );
00527 }
00528
00529 void KOAgendaView::zoomView( const int delta, const QPoint &pos,
00530 const Qt::Orientation orient )
00531 {
00532 static QDate zoomDate;
00533 static QTimer *t = new QTimer( this );
00534
00535
00536
00537
00538 if ( orient == Qt::Horizontal ) {
00539 QDate date=mAgenda->selectedIncidenceDate();
00540 if ( date.isValid() )
00541 zoomDate=date;
00542 else{
00543 if ( !t->isActive() ) {
00544 zoomDate= mSelectedDates[pos.x()];
00545 }
00546 t->start ( 1000,true );
00547 }
00548 if ( delta > 0 )
00549 zoomOutHorizontally( zoomDate );
00550 else
00551 zoomInHorizontally( zoomDate );
00552 } else {
00553
00554 QPoint posConstentsOld = mAgenda->gridToContents(pos);
00555 if ( delta > 0 ) {
00556 zoomOutVertically();
00557 } else {
00558 zoomInVertically();
00559 }
00560 QPoint posConstentsNew = mAgenda->gridToContents(pos);
00561 mAgenda->scrollBy( 0, posConstentsNew.y() - posConstentsOld.y() );
00562 }
00563 }
00564
00565 void KOAgendaView::createDayLabels()
00566 {
00567
00568
00569
00570
00571
00572 delete mDayLabels;
00573
00574 mDayLabels = new QFrame (mDayLabelsFrame);
00575 mLayoutDayLabels = new QHBoxLayout(mDayLabels);
00576 if ( !mIsSideBySide )
00577 mLayoutDayLabels->addSpacing(mTimeLabels->width());
00578
00579 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
00580
00581 DateList::ConstIterator dit;
00582 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00583 QDate date = *dit;
00584 QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels);
00585 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
00586
00587
00588 int dW = calsys->dayOfWeek(date);
00589 QString veryLongStr = KGlobal::locale()->formatDate( date );
00590 QString longstr = i18n( "short_weekday date (e.g. Mon 13)","%1 %2" )
00591 .arg( calsys->weekDayName( dW, true ) )
00592 .arg( calsys->day(date) );
00593 QString shortstr = QString::number(calsys->day(date));
00594
00595 KOAlternateLabel *dayLabel = new KOAlternateLabel(shortstr,
00596 longstr, veryLongStr, mDayLabels);
00597 dayLabel->setMinimumWidth(1);
00598 dayLabel->setAlignment(QLabel::AlignHCenter);
00599 if (date == QDate::currentDate()) {
00600 QFont font = dayLabel->font();
00601 font.setBold(true);
00602 dayLabel->setFont(font);
00603 }
00604 dayLayout->addWidget(dayLabel);
00605
00606
00607 QStringList texts = KOGlobals::self()->holiday( date );
00608 QStringList::ConstIterator textit = texts.begin();
00609 for ( ; textit != texts.end(); ++textit ) {
00610
00611 KOAlternateLabel*label = new KOAlternateLabel( (*textit), (*textit), QString::null, mDayLabels );
00612 label->setMinimumWidth(1);
00613 label->setAlignment(AlignCenter);
00614 dayLayout->addWidget(label);
00615 }
00616
00617 #ifndef KORG_NOPLUGINS
00618 CalendarDecoration::List cds = KOCore::self()->calendarDecorations();
00619 CalendarDecoration *it;
00620 for(it = cds.first(); it; it = cds.next()) {
00621 QString text = it->shortText( date );
00622 if ( !text.isEmpty() ) {
00623
00624 KOAlternateLabel*label = new KOAlternateLabel( text, text, QString::null, mDayLabels );
00625 label->setMinimumWidth(1);
00626 label->setAlignment(AlignCenter);
00627 dayLayout->addWidget(label);
00628 }
00629 }
00630
00631 for(it = cds.first(); it; it = cds.next()) {
00632 QWidget *wid = it->smallWidget(mDayLabels,date);
00633 if ( wid ) {
00634
00635 dayLayout->addWidget(wid);
00636 }
00637 }
00638 #endif
00639 }
00640
00641 if ( !mIsSideBySide )
00642 mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
00643 mDayLabels->show();
00644 }
00645
00646 void KOAgendaView::enableAgendaUpdate( bool enable )
00647 {
00648 mAllowAgendaUpdate = enable;
00649 }
00650
00651 int KOAgendaView::maxDatesHint()
00652 {
00653
00654 return 0;
00655 }
00656
00657 int KOAgendaView::currentDateCount()
00658 {
00659 return mSelectedDates.count();
00660 }
00661
00662 Incidence::List KOAgendaView::selectedIncidences()
00663 {
00664 Incidence::List selected;
00665 Incidence *incidence;
00666
00667 incidence = mAgenda->selectedIncidence();
00668 if (incidence) selected.append(incidence);
00669
00670 incidence = mAllDayAgenda->selectedIncidence();
00671 if (incidence) selected.append(incidence);
00672
00673 return selected;
00674 }
00675
00676 DateList KOAgendaView::selectedDates()
00677 {
00678 DateList selected;
00679 QDate qd;
00680
00681 qd = mAgenda->selectedIncidenceDate();
00682 if (qd.isValid()) selected.append(qd);
00683
00684 qd = mAllDayAgenda->selectedIncidenceDate();
00685 if (qd.isValid()) selected.append(qd);
00686
00687 return selected;
00688 }
00689
00690 bool KOAgendaView::eventDurationHint( QDateTime &startDt, QDateTime &endDt,
00691 bool &allDay )
00692 {
00693 if ( selectionStart().isValid() ) {
00694 QDateTime start = selectionStart();
00695 QDateTime end = selectionEnd();
00696
00697 if ( start.secsTo( end ) == 15*60 ) {
00698
00699
00700 QTime defaultDuration( KOPrefs::instance()->mDefaultDuration.time() );
00701 int addSecs = ( defaultDuration.hour()*3600 ) +
00702 ( defaultDuration.minute()*60 );
00703 end = start.addSecs( addSecs );
00704 }
00705
00706 startDt = start;
00707 endDt = end;
00708 allDay = selectedIsAllDay();
00709 return true;
00710 }
00711 return false;
00712 }
00713
00715 bool KOAgendaView::selectedIsSingleCell()
00716 {
00717 if ( !selectionStart().isValid() || !selectionEnd().isValid() ) return false;
00718
00719 if (selectedIsAllDay()) {
00720 int days = selectionStart().daysTo(selectionEnd());
00721 return ( days < 1 );
00722 } else {
00723 int secs = selectionStart().secsTo(selectionEnd());
00724 return ( secs <= 24*60*60/mAgenda->rows() );
00725 }
00726 }
00727
00728
00729 void KOAgendaView::updateView()
00730 {
00731
00732 fillAgenda();
00733 }
00734
00735
00736
00737
00738
00739
00740 void KOAgendaView::updateConfig()
00741 {
00742
00743
00744
00745 mTimeLabels->updateConfig();
00746 mAgenda->updateConfig();
00747 mAllDayAgenda->updateConfig();
00748
00749
00750
00751 mTimeLabels->positionChanged();
00752
00753
00754 mTimeLabels->repaint();
00755
00756 updateTimeBarWidth();
00757
00758
00759 KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance()
00760 ->mEnableToolTips);
00761
00762 setHolidayMasks();
00763
00764 createDayLabels();
00765
00766 updateView();
00767 }
00768
00769 void KOAgendaView::updateTimeBarWidth()
00770 {
00771 int width;
00772
00773 width = mDummyAllDayLeft->fontMetrics().width( i18n("All Day") );
00774 width = QMAX( width, mTimeLabels->width() );
00775
00776 mDummyAllDayLeft->setFixedWidth( width );
00777 mTimeLabels->setFixedWidth( width );
00778 }
00779
00780
00781 void KOAgendaView::updateEventDates( KOAgendaItem *item )
00782 {
00783 kdDebug(5850) << "KOAgendaView::updateEventDates(): " << item->text() << endl;
00784
00785 QDateTime startDt,endDt;
00786
00787
00788
00789
00790
00791 QDate thisDate;
00792 if ( item->cellXLeft() < 0 ) {
00793 thisDate = ( mSelectedDates.first() ).addDays( item->cellXLeft() );
00794 } else {
00795 thisDate = mSelectedDates[ item->cellXLeft() ];
00796 }
00797 QDate oldThisDate( item->itemDate() );
00798 int daysOffset = oldThisDate.daysTo( thisDate );
00799 int daysLength = 0;
00800
00801
00802
00803 Incidence *incidence = item->incidence();
00804 if ( !incidence ) return;
00805 if ( !mChanger || !mChanger->beginChange(incidence) ) return;
00806 Incidence *oldIncidence = incidence->clone();
00807
00808 QTime startTime(0,0,0), endTime(0,0,0);
00809 if ( incidence->doesFloat() ) {
00810 daysLength = item->cellWidth() - 1;
00811 } else {
00812 startTime = mAgenda->gyToTime( item->cellYTop() );
00813 if ( item->lastMultiItem() ) {
00814 endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
00815 daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
00816 } else {
00817 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
00818 }
00819 }
00820
00821
00822
00823 if ( incidence->type() == "Event" ) {
00824 startDt = incidence->dtStart();
00825 startDt = startDt.addDays( daysOffset );
00826 startDt.setTime( startTime );
00827 endDt = startDt.addDays( daysLength );
00828 endDt.setTime( endTime );
00829 Event*ev = static_cast<Event*>(incidence);
00830 if( incidence->dtStart() == startDt && ev->dtEnd() == endDt ) {
00831
00832 delete oldIncidence;
00833 return;
00834 }
00835 incidence->setDtStart( startDt );
00836 ev->setDtEnd( endDt );
00837 } else if ( incidence->type() == "Todo" ) {
00838 Todo *td = static_cast<Todo*>(incidence);
00839 startDt = td->hasStartDate() ? td->dtStart() : td->dtDue();
00840 startDt = thisDate.addDays( td->dtDue().daysTo( startDt ) );
00841 startDt.setTime( startTime );
00842 endDt.setDate( thisDate );
00843 endDt.setTime( endTime );
00844
00845 if( td->dtDue() == endDt ) {
00846
00847 delete oldIncidence;
00848 return;
00849 }
00850 }
00851
00852
00853
00854
00855 Recurrence *recur = incidence->recurrence();
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, 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 mHolidayMask.resize( mSelectedDates.count() + 1 );
01473
01474 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01475 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01476 }
01477
01478
01479
01480 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01481 mHolidayMask[ mSelectedDates.count() ] = showDay;
01482
01483 mAgenda->setHolidayMask( &mHolidayMask );
01484 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01485 }
01486
01487 void KOAgendaView::setContentsPos( int y )
01488 {
01489 mAgenda->setContentsPos( 0, y );
01490 }
01491
01492 void KOAgendaView::setExpandedButton( bool expanded )
01493 {
01494 if ( !mExpandButton ) return;
01495
01496 if ( expanded ) {
01497 mExpandButton->setPixmap( mExpandedPixmap );
01498 } else {
01499 mExpandButton->setPixmap( mNotExpandedPixmap );
01500 }
01501 }
01502
01503 void KOAgendaView::clearSelection()
01504 {
01505 mAgenda->deselectItem();
01506 mAllDayAgenda->deselectItem();
01507 }
01508
01509 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01510 {
01511 newTimeSpanSelected( start, end );
01512 mTimeSpanInAllDay = true;
01513 }
01514
01515 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01516 {
01517 if (!mSelectedDates.count()) return;
01518
01519 mTimeSpanInAllDay = false;
01520
01521 QDate dayStart = mSelectedDates[ kClamp( start.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01522 QDate dayEnd = mSelectedDates[ kClamp( end.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01523
01524 QTime timeStart = mAgenda->gyToTime(start.y());
01525 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01526
01527 QDateTime dtStart(dayStart,timeStart);
01528 QDateTime dtEnd(dayEnd,timeEnd);
01529
01530 mTimeSpanBegin = dtStart;
01531 mTimeSpanEnd = dtEnd;
01532 }
01533
01534 void KOAgendaView::deleteSelectedDateTime()
01535 {
01536 mTimeSpanBegin.setDate(QDate());
01537 mTimeSpanEnd.setDate(QDate());
01538 mTimeSpanInAllDay = false;
01539 }
01540
01541 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01542 {
01543 mAgenda->setTypeAheadReceiver( o );
01544 mAllDayAgenda->setTypeAheadReceiver( o );
01545 }
01546
01547 void KOAgendaView::finishTypeAhead()
01548 {
01549 mAgenda->finishTypeAhead();
01550 mAllDayAgenda->finishTypeAhead();
01551 }
01552
01553 void KOAgendaView::removeIncidence( Incidence *incidence )
01554 {
01555 mAgenda->removeIncidence( incidence );
01556 mAllDayAgenda->removeIncidence( incidence );
01557 }
01558
01559 void KOAgendaView::updateEventIndicators()
01560 {
01561 mMinY = mAgenda->minContentsY();
01562 mMaxY = mAgenda->maxContentsY();
01563
01564 mAgenda->checkScrollBoundaries();
01565 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01566 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01567 }
01568
01569 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01570 {
01571 mChanger = changer;
01572 mAgenda->setIncidenceChanger( changer );
01573 mAllDayAgenda->setIncidenceChanger( changer );
01574 }
01575
01576 void KOAgendaView::clearTimeSpanSelection()
01577 {
01578 mAgenda->clearSelection();
01579 mAllDayAgenda->clearSelection();
01580 deleteSelectedDateTime();
01581 }
01582
01583 void KOAgendaView::setResource(KCal::ResourceCalendar * res, const QString & subResource)
01584 {
01585 mResource = res;
01586 mSubResource = subResource;
01587 }
01588
01589 bool KOAgendaView::filterByResource(Incidence * incidence)
01590 {
01591 if ( !mResource )
01592 return true;
01593 CalendarResources *calRes = dynamic_cast<CalendarResources*>( calendar() );
01594 if ( !calRes )
01595 return true;
01596 if ( calRes->resource( incidence ) != mResource )
01597 return false;
01598 if ( !mSubResource.isEmpty() ) {
01599 if ( mResource->subresourceIdentifier( incidence ) != mSubResource )
01600 return false;
01601 }
01602 return true;
01603 }
01604
01605 void KOAgendaView::resourcesChanged()
01606 {
01607 mPendingChanges = true;
01608 }
01609
01610 void KOAgendaView::calendarIncidenceAdded(Incidence * incidence)
01611 {
01612 Q_UNUSED( incidence );
01613 mPendingChanges = true;
01614 }
01615
01616 void KOAgendaView::calendarIncidenceChanged(Incidence * incidence)
01617 {
01618 Q_UNUSED( incidence );
01619 mPendingChanges = true;
01620 }
01621
01622 void KOAgendaView::calendarIncidenceRemoved(Incidence * incidence)
01623 {
01624 Q_UNUSED( incidence );
01625 mPendingChanges = true;
01626 }