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::add( this, "" );
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::add( this, "" );
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,
00225 CalendarView *calendarView,
00226 QWidget *parent,
00227 const char *name,
00228 bool isSideBySide ) :
00229 KOrg::AgendaView (cal, parent,name), mExpandButton( 0 ),
00230 mAllowAgendaUpdate( true ),
00231 mUpdateItem( 0 ),
00232 mIsSideBySide( isSideBySide ),
00233 mPendingChanges( true )
00234 {
00235 mSelectedDates.append(QDate::currentDate());
00236
00237 mLayoutDayLabels = 0;
00238 mDayLabelsFrame = 0;
00239 mDayLabels = 0;
00240
00241 bool isRTL = KOGlobals::self()->reverseLayout();
00242
00243 if ( KOPrefs::instance()->compactDialogs() ) {
00244 if ( KOPrefs::instance()->mVerticalScreen ) {
00245 mExpandedPixmap = KOGlobals::self()->smallIcon( "1downarrow" );
00246 mNotExpandedPixmap = KOGlobals::self()->smallIcon( "1uparrow" );
00247 } else {
00248 mExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1leftarrow" : "1rightarrow" );
00249 mNotExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1rightarrow" : "1leftarrow" );
00250 }
00251 }
00252
00253 QBoxLayout *topLayout = new QVBoxLayout(this);
00254
00255
00256 mDayLabelsFrame = new QHBox(this);
00257 topLayout->addWidget(mDayLabelsFrame);
00258
00259
00260 #ifndef KORG_NOSPLITTER
00261 mSplitterAgenda = new QSplitter(Vertical,this);
00262 topLayout->addWidget(mSplitterAgenda);
00263
00264 #if KDE_IS_VERSION( 3, 1, 93 )
00265 mSplitterAgenda->setOpaqueResize( KGlobalSettings::opaqueResize() );
00266 #else
00267 mSplitterAgenda->setOpaqueResize();
00268 #endif
00269
00270 mAllDayFrame = new QHBox(mSplitterAgenda);
00271
00272 QWidget *agendaFrame = new QWidget(mSplitterAgenda);
00273 #else
00274 QVBox *mainBox = new QVBox( this );
00275 topLayout->addWidget( mainBox );
00276
00277 mAllDayFrame = new QHBox(mainBox);
00278
00279 QWidget *agendaFrame = new QWidget(mainBox);
00280 #endif
00281
00282
00283 mDummyAllDayLeft = new QVBox( mAllDayFrame );
00284 if ( isSideBySide )
00285 mDummyAllDayLeft->hide();
00286
00287 if ( KOPrefs::instance()->compactDialogs() ) {
00288 mExpandButton = new QPushButton(mDummyAllDayLeft);
00289 mExpandButton->setPixmap( mNotExpandedPixmap );
00290 mExpandButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
00291 QSizePolicy::Fixed ) );
00292 connect( mExpandButton, SIGNAL( clicked() ), SIGNAL( toggleExpand() ) );
00293 } else {
00294 QLabel *label = new QLabel( i18n("All Day"), mDummyAllDayLeft );
00295 label->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::WordBreak );
00296 }
00297
00298 mAllDayAgenda = new KOAgenda( 1, calendarView, mAllDayFrame );
00299 mAllDayAgenda->setCalendar( calendar() );
00300 QWidget *dummyAllDayRight = new QWidget(mAllDayFrame);
00301
00302
00303 QGridLayout *agendaLayout = new QGridLayout(agendaFrame,3,3);
00304
00305
00306
00307 mEventIndicatorTop = new EventIndicator(EventIndicator::Top,agendaFrame);
00308 agendaLayout->addWidget(mEventIndicatorTop,0,1);
00309 mEventIndicatorBottom = new EventIndicator(EventIndicator::Bottom,
00310 agendaFrame);
00311 agendaLayout->addWidget(mEventIndicatorBottom,2,1);
00312 QWidget *dummyAgendaRight = new QWidget(agendaFrame);
00313 agendaLayout->addWidget(dummyAgendaRight,0,2);
00314
00315
00316 mTimeLabels = new TimeLabels(24,agendaFrame);
00317 agendaLayout->addWidget(mTimeLabels,1,0);
00318
00319
00320 mAgenda = new KOAgenda( 1, 96, KOPrefs::instance()->mHourSize, calendarView, agendaFrame );
00321 mAgenda->setCalendar( calendar() );
00322 agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
00323 agendaLayout->setColStretch(1,1);
00324
00325
00326 mAgendaPopup = eventPopup();
00327
00328
00329 mAllDayAgendaPopup = eventPopup();
00330
00331
00332 mTimeLabels->setAgenda(mAgenda);
00333 if ( isSideBySide )
00334 mTimeLabels->hide();
00335
00336
00337
00338
00339 createDayLabels();
00340
00341 if ( !isSideBySide ) {
00342
00343 dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00344 dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00345 }
00346
00347 updateTimeBarWidth();
00348
00349
00350 connect(mAgenda->verticalScrollBar(),SIGNAL(valueChanged(int)),
00351 mTimeLabels, SLOT(positionChanged()));
00352
00353 connect( mAgenda,
00354 SIGNAL( zoomView( const int, const QPoint & ,const Qt::Orientation ) ),
00355 SLOT( zoomView( const int, const QPoint &, const Qt::Orientation ) ) );
00356
00357 connect(mTimeLabels->verticalScrollBar(),SIGNAL(valueChanged(int)),
00358 SLOT(setContentsPos(int)));
00359
00360
00361 connect( mAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00362 SLOT(newTimeSpanSelected(const QPoint &, const QPoint &)));
00363 connect( mAllDayAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00364 SLOT(newTimeSpanSelectedAllDay(const QPoint &, const QPoint &)));
00365
00366
00367 connect( mAgenda, SIGNAL(lowerYChanged(int)),
00368 SLOT(updateEventIndicatorTop(int)));
00369 connect( mAgenda, SIGNAL(upperYChanged(int)),
00370 SLOT(updateEventIndicatorBottom(int)));
00371
00372 if ( !readOnly() ) {
00373 connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
00374 connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
00375 }
00376
00377 if ( cal ) {
00378 cal->registerObserver( this );
00379 }
00380 }
00381
00382
00383 KOAgendaView::~KOAgendaView()
00384 {
00385 if ( calendar() )
00386 calendar()->unregisterObserver( this );
00387 delete mAgendaPopup;
00388 delete mAllDayAgendaPopup;
00389 }
00390
00391 void KOAgendaView::connectAgenda( KOAgenda *agenda, QPopupMenu *popup,
00392 KOAgenda *otherAgenda )
00393 {
00394 connect( agenda, SIGNAL(showIncidencePopupSignal(Calendar *,Incidence *,const QDate &)),
00395 popup, SLOT(showIncidencePopup(Calendar *,Incidence *,const QDate &)) );
00396
00397 connect( agenda, SIGNAL(showNewEventPopupSignal()),
00398 SLOT(showNewEventPopup()) );
00399
00400
00401
00402 connect( agenda, SIGNAL(newEventSignal(ResourceCalendar *,const QString &)),
00403 SIGNAL(newEventSignal(ResourceCalendar *,const QString &)) );
00404
00405 connect( agenda, SIGNAL( newStartSelectSignal() ),
00406 otherAgenda, SLOT( clearSelection() ) );
00407 connect( agenda, SIGNAL( newStartSelectSignal() ),
00408 SIGNAL( timeSpanSelectionChanged()) );
00409
00410 connect( agenda, SIGNAL( editIncidenceSignal( Incidence * ) ),
00411 SIGNAL( editIncidenceSignal( Incidence * ) ) );
00412 connect( agenda, SIGNAL( showIncidenceSignal( Incidence * ) ),
00413 SIGNAL( showIncidenceSignal( Incidence * ) ) );
00414 connect( agenda, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
00415 SIGNAL( deleteIncidenceSignal( Incidence * ) ) );
00416
00417 connect( agenda, SIGNAL( startMultiModify( const QString & ) ),
00418 SIGNAL( startMultiModify( const QString & ) ) );
00419 connect( agenda, SIGNAL( endMultiModify() ),
00420 SIGNAL( endMultiModify() ) );
00421
00422 connect( agenda, SIGNAL( itemModified( KOAgendaItem * ) ),
00423 SLOT( updateEventDates( KOAgendaItem * ) ) );
00424
00425 connect( agenda, SIGNAL( enableAgendaUpdate( bool ) ),
00426 SLOT( enableAgendaUpdate( bool ) ) );
00427
00428
00429 connect( agenda, SIGNAL( startDragSignal( Incidence * ) ),
00430 SLOT( startDrag( Incidence * ) ) );
00431
00432
00433 connect( agenda, SIGNAL( incidenceSelected( Incidence *,const QDate & ) ),
00434 otherAgenda, SLOT( deselectItem() ) );
00435 connect( agenda, SIGNAL( incidenceSelected( Incidence *,const QDate & ) ),
00436 SIGNAL( incidenceSelected( Incidence *, const QDate & ) ) );
00437
00438
00439 connect( agenda, SIGNAL( droppedToDo( Todo *, const QPoint &, bool ) ),
00440 SLOT( slotTodoDropped( Todo *, const QPoint &, bool ) ) );
00441
00442 }
00443
00444 void KOAgendaView::zoomInVertically( )
00445 {
00446 if ( !mIsSideBySide )
00447 KOPrefs::instance()->mHourSize++;
00448 mAgenda->updateConfig();
00449 mAgenda->checkScrollBoundaries();
00450
00451 mTimeLabels->updateConfig();
00452 mTimeLabels->positionChanged();
00453 mTimeLabels->repaint();
00454
00455 updateView();
00456 }
00457
00458 void KOAgendaView::zoomOutVertically( )
00459 {
00460
00461 if ( KOPrefs::instance()->mHourSize > 4 || mIsSideBySide ) {
00462
00463 if ( !mIsSideBySide )
00464 KOPrefs::instance()->mHourSize--;
00465 mAgenda->updateConfig();
00466 mAgenda->checkScrollBoundaries();
00467
00468 mTimeLabels->updateConfig();
00469 mTimeLabels->positionChanged();
00470 mTimeLabels->repaint();
00471
00472 updateView();
00473 }
00474 }
00475
00476 void KOAgendaView::zoomInHorizontally( const QDate &date)
00477 {
00478 QDate begin;
00479 QDate newBegin;
00480 QDate dateToZoom = date;
00481 int ndays,count;
00482
00483 begin = mSelectedDates.first();
00484 ndays = begin.daysTo( mSelectedDates.last() );
00485
00486
00487 if ( ! dateToZoom.isValid () )
00488 dateToZoom=mAgenda->selectedIncidenceDate();
00489
00490 if( !dateToZoom.isValid() ) {
00491 if ( ndays > 1 ) {
00492 newBegin=begin.addDays(1);
00493 count = ndays-1;
00494 emit zoomViewHorizontally ( newBegin , count );
00495 }
00496 } else {
00497 if ( ndays <= 2 ) {
00498 newBegin = dateToZoom;
00499 count = 1;
00500 } else {
00501 newBegin = dateToZoom.addDays( -ndays/2 +1 );
00502 count = ndays -1 ;
00503 }
00504 emit zoomViewHorizontally ( newBegin , count );
00505 }
00506 }
00507
00508 void KOAgendaView::zoomOutHorizontally( const QDate &date )
00509 {
00510 QDate begin;
00511 QDate newBegin;
00512 QDate dateToZoom = date;
00513 int ndays,count;
00514
00515 begin = mSelectedDates.first();
00516 ndays = begin.daysTo( mSelectedDates.last() );
00517
00518
00519 if ( ! dateToZoom.isValid () )
00520 dateToZoom=mAgenda->selectedIncidenceDate();
00521
00522 if ( !dateToZoom.isValid() ) {
00523 newBegin = begin.addDays(-1);
00524 count = ndays+3 ;
00525 } else {
00526 newBegin = dateToZoom.addDays( -ndays/2-1 );
00527 count = ndays+3;
00528 }
00529
00530 if ( abs( count ) >= 31 )
00531 kdDebug(5850) << "change to the mounth view?"<<endl;
00532 else
00533
00534 emit zoomViewHorizontally( newBegin, count );
00535 }
00536
00537 void KOAgendaView::zoomView( const int delta, const QPoint &pos,
00538 const Qt::Orientation orient )
00539 {
00540 static QDate zoomDate;
00541 static QTimer *t = new QTimer( this );
00542
00543
00544
00545
00546 if ( orient == Qt::Horizontal ) {
00547 QDate date=mAgenda->selectedIncidenceDate();
00548 if ( date.isValid() )
00549 zoomDate=date;
00550 else{
00551 if ( !t->isActive() ) {
00552 zoomDate= mSelectedDates[pos.x()];
00553 }
00554 t->start ( 1000,true );
00555 }
00556 if ( delta > 0 )
00557 zoomOutHorizontally( zoomDate );
00558 else
00559 zoomInHorizontally( zoomDate );
00560 } else {
00561
00562 QPoint posConstentsOld = mAgenda->gridToContents(pos);
00563 if ( delta > 0 ) {
00564 zoomOutVertically();
00565 } else {
00566 zoomInVertically();
00567 }
00568 QPoint posConstentsNew = mAgenda->gridToContents(pos);
00569 mAgenda->scrollBy( 0, posConstentsNew.y() - posConstentsOld.y() );
00570 }
00571 }
00572
00573 void KOAgendaView::createDayLabels()
00574 {
00575
00576
00577
00578
00579
00580 delete mDayLabels;
00581
00582 mDayLabels = new QFrame (mDayLabelsFrame);
00583 mLayoutDayLabels = new QHBoxLayout(mDayLabels);
00584 if ( !mIsSideBySide )
00585 mLayoutDayLabels->addSpacing(mTimeLabels->width());
00586
00587 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
00588
00589 DateList::ConstIterator dit;
00590 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00591 QDate date = *dit;
00592 QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels);
00593 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
00594
00595
00596 int dW = calsys->dayOfWeek(date);
00597 QString veryLongStr = KGlobal::locale()->formatDate( date );
00598 QString longstr = i18n( "short_weekday date (e.g. Mon 13)","%1 %2" )
00599 .arg( calsys->weekDayName( dW, true ) )
00600 .arg( calsys->day(date) );
00601 QString shortstr = QString::number(calsys->day(date));
00602
00603 KOAlternateLabel *dayLabel = new KOAlternateLabel(shortstr,
00604 longstr, veryLongStr, mDayLabels);
00605 dayLabel->setMinimumWidth(1);
00606 dayLabel->setAlignment(QLabel::AlignHCenter);
00607 if (date == QDate::currentDate()) {
00608 QFont font = dayLabel->font();
00609 font.setBold(true);
00610 dayLabel->setFont(font);
00611 }
00612 dayLayout->addWidget(dayLabel);
00613
00614
00615 QStringList texts = KOGlobals::self()->holiday( date );
00616 QStringList::ConstIterator textit = texts.begin();
00617 for ( ; textit != texts.end(); ++textit ) {
00618
00619 KOAlternateLabel*label = new KOAlternateLabel( (*textit), (*textit), QString::null, mDayLabels );
00620 label->setMinimumWidth(1);
00621 label->setAlignment(AlignCenter);
00622 dayLayout->addWidget(label);
00623 }
00624
00625 #ifndef KORG_NOPLUGINS
00626 CalendarDecoration::List cds = KOCore::self()->calendarDecorations();
00627 CalendarDecoration *it;
00628 for(it = cds.first(); it; it = cds.next()) {
00629 QString text = it->shortText( date );
00630 if ( !text.isEmpty() ) {
00631
00632 KOAlternateLabel*label = new KOAlternateLabel( text, text, QString::null, mDayLabels );
00633 label->setMinimumWidth(1);
00634 label->setAlignment(AlignCenter);
00635 dayLayout->addWidget(label);
00636 }
00637 }
00638
00639 for(it = cds.first(); it; it = cds.next()) {
00640 QWidget *wid = it->smallWidget(mDayLabels,date);
00641 if ( wid ) {
00642
00643 dayLayout->addWidget(wid);
00644 }
00645 }
00646 #endif
00647 }
00648
00649 if ( !mIsSideBySide )
00650 mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
00651 mDayLabels->show();
00652 }
00653
00654 void KOAgendaView::enableAgendaUpdate( bool enable )
00655 {
00656 mAllowAgendaUpdate = enable;
00657 }
00658
00659 int KOAgendaView::maxDatesHint()
00660 {
00661
00662 return 0;
00663 }
00664
00665 int KOAgendaView::currentDateCount()
00666 {
00667 return mSelectedDates.count();
00668 }
00669
00670 Incidence::List KOAgendaView::selectedIncidences()
00671 {
00672 Incidence::List selected;
00673 Incidence *incidence;
00674
00675 incidence = mAgenda->selectedIncidence();
00676 if (incidence) selected.append(incidence);
00677
00678 incidence = mAllDayAgenda->selectedIncidence();
00679 if (incidence) selected.append(incidence);
00680
00681 return selected;
00682 }
00683
00684 DateList KOAgendaView::selectedDates()
00685 {
00686 DateList selected;
00687 QDate qd;
00688
00689 qd = mAgenda->selectedIncidenceDate();
00690 if (qd.isValid()) selected.append(qd);
00691
00692 qd = mAllDayAgenda->selectedIncidenceDate();
00693 if (qd.isValid()) selected.append(qd);
00694
00695 return selected;
00696 }
00697
00698 bool KOAgendaView::eventDurationHint( QDateTime &startDt, QDateTime &endDt,
00699 bool &allDay )
00700 {
00701 if ( selectionStart().isValid() ) {
00702 QDateTime start = selectionStart();
00703 QDateTime end = selectionEnd();
00704
00705 if ( start.secsTo( end ) == 15*60 ) {
00706
00707
00708 QTime defaultDuration( KOPrefs::instance()->mDefaultDuration.time() );
00709 int addSecs = ( defaultDuration.hour()*3600 ) +
00710 ( defaultDuration.minute()*60 );
00711 end = start.addSecs( addSecs );
00712 }
00713
00714 startDt = start;
00715 endDt = end;
00716 allDay = selectedIsAllDay();
00717 return true;
00718 }
00719 return false;
00720 }
00721
00723 bool KOAgendaView::selectedIsSingleCell()
00724 {
00725 if ( !selectionStart().isValid() || !selectionEnd().isValid() ) return false;
00726
00727 if (selectedIsAllDay()) {
00728 int days = selectionStart().daysTo(selectionEnd());
00729 return ( days < 1 );
00730 } else {
00731 int secs = selectionStart().secsTo(selectionEnd());
00732 return ( secs <= 24*60*60/mAgenda->rows() );
00733 }
00734 }
00735
00736
00737 void KOAgendaView::updateView()
00738 {
00739
00740 fillAgenda();
00741 }
00742
00743
00744
00745
00746
00747
00748 void KOAgendaView::updateConfig()
00749 {
00750
00751
00752
00753 mTimeLabels->updateConfig();
00754 mAgenda->updateConfig();
00755 mAllDayAgenda->updateConfig();
00756
00757
00758
00759 mTimeLabels->positionChanged();
00760
00761
00762 mTimeLabels->repaint();
00763
00764 updateTimeBarWidth();
00765
00766
00767 KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance()
00768 ->mEnableToolTips);
00769
00770 setHolidayMasks();
00771
00772 createDayLabels();
00773
00774 updateView();
00775 }
00776
00777 void KOAgendaView::updateTimeBarWidth()
00778 {
00779 int width;
00780
00781 width = mDummyAllDayLeft->fontMetrics().width( i18n("All Day") );
00782 width = QMAX( width, mTimeLabels->width() );
00783
00784 mDummyAllDayLeft->setFixedWidth( width );
00785 mTimeLabels->setFixedWidth( width );
00786 }
00787
00788
00789 void KOAgendaView::updateEventDates( KOAgendaItem *item )
00790 {
00791 kdDebug(5850) << "KOAgendaView::updateEventDates(): " << item->text() << endl;
00792
00793 QDateTime startDt,endDt;
00794
00795
00796
00797
00798
00799 QDate thisDate;
00800 if ( item->cellXLeft() < 0 ) {
00801 thisDate = ( mSelectedDates.first() ).addDays( item->cellXLeft() );
00802 } else {
00803 thisDate = mSelectedDates[ item->cellXLeft() ];
00804 }
00805 QDate oldThisDate( item->itemDate() );
00806 int daysOffset = oldThisDate.daysTo( thisDate );
00807 int daysLength = 0;
00808
00809
00810
00811 Incidence *incidence = item->incidence();
00812 if ( !incidence ) return;
00813 if ( !mChanger || !mChanger->beginChange(incidence) ) return;
00814 Incidence *oldIncidence = incidence->clone();
00815
00816 QTime startTime(0,0,0), endTime(0,0,0);
00817 if ( incidence->doesFloat() ) {
00818 daysLength = item->cellWidth() - 1;
00819 } else {
00820 startTime = mAgenda->gyToTime( item->cellYTop() );
00821 if ( item->lastMultiItem() ) {
00822 endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
00823 daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
00824 } else {
00825 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
00826 }
00827 }
00828
00829
00830
00831 if ( incidence->type() == "Event" ) {
00832 startDt = incidence->dtStart();
00833 startDt = startDt.addDays( daysOffset );
00834 startDt.setTime( startTime );
00835 endDt = startDt.addDays( daysLength );
00836 endDt.setTime( endTime );
00837 Event*ev = static_cast<Event*>(incidence);
00838 if( incidence->dtStart() == startDt && ev->dtEnd() == endDt ) {
00839
00840 delete oldIncidence;
00841 return;
00842 }
00843 incidence->setDtStart( startDt );
00844 ev->setDtEnd( endDt );
00845 } else if ( incidence->type() == "Todo" ) {
00846 Todo *td = static_cast<Todo*>(incidence);
00847 startDt = td->hasStartDate() ? td->dtStart() : td->dtDue();
00848 startDt = thisDate.addDays( td->dtDue().daysTo( startDt ) );
00849 startDt.setTime( startTime );
00850 endDt.setDate( thisDate );
00851 endDt.setTime( endTime );
00852
00853 if( td->dtDue() == endDt ) {
00854
00855 delete oldIncidence;
00856 return;
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
00998
00999
01000
01001
01002
01003
01004
01005
01006 if ( incidence->type() == "Event" ) {
01007 incidence->setDtStart( startDt );
01008 (static_cast<Event*>( incidence ) )->setDtEnd( endDt );
01009 } else if ( incidence->type() == "Todo" ) {
01010 Todo *td = static_cast<Todo*>( incidence );
01011 if ( td->hasStartDate() )
01012 td->setDtStart( startDt );
01013 td->setDtDue( endDt );
01014 }
01015
01016 item->setItemDate( startDt.date() );
01017
01018 KOIncidenceToolTip::remove( item );
01019 KOIncidenceToolTip::add( item, calendar(), incidence, thisDate, KOAgendaItem::toolTipGroup() );
01020
01021 const bool result = mChanger->changeIncidence( oldIncidence, incidence,
01022 KOGlobals::DATE_MODIFIED, this );
01023 mChanger->endChange( incidence );
01024 delete oldIncidence;
01025
01026 if ( !result ) {
01027 mPendingChanges = true;
01028 QTimer::singleShot( 0, this, SLOT(updateView()) );
01029 return;
01030 }
01031
01032
01033
01034
01035 enableAgendaUpdate( false );
01036
01037
01038
01039
01040 if ( incidence->doesRecur() ) {
01041 mUpdateItem = incidence;
01042 QTimer::singleShot( 0, this, SLOT( doUpdateItem() ) );
01043 }
01044
01045 enableAgendaUpdate( true );
01046
01047
01048 }
01049
01050 void KOAgendaView::doUpdateItem()
01051 {
01052 if ( mUpdateItem ) {
01053 changeIncidenceDisplay( mUpdateItem, KOGlobals::INCIDENCEEDITED );
01054 mUpdateItem = 0;
01055 }
01056 }
01057
01058
01059
01060 void KOAgendaView::showDates( const QDate &start, const QDate &end )
01061 {
01062
01063 if ( !mSelectedDates.isEmpty() && mSelectedDates.first() == start
01064 && mSelectedDates.last() == end && !mPendingChanges )
01065 return;
01066
01067 mSelectedDates.clear();
01068
01069 QDate d = start;
01070 while (d <= end) {
01071 mSelectedDates.append(d);
01072 d = d.addDays( 1 );
01073 }
01074
01075
01076 fillAgenda();
01077 }
01078
01079
01080 void KOAgendaView::showIncidences( const Incidence::List &, const QDate & )
01081 {
01082 kdDebug(5850) << "KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
01083 }
01084
01085 void KOAgendaView::insertIncidence( Incidence *incidence, const QDate &curDate )
01086 {
01087 if ( !filterByResource( incidence ) ) {
01088 return;
01089 }
01090
01091
01092 Event *event = dynamic_cast<Event *>( incidence );
01093 Todo *todo = dynamic_cast<Todo *>( incidence );
01094
01095 int curCol = mSelectedDates.first().daysTo( curDate );
01096
01097
01098 if ( curCol < 0 ) {
01099 curCol = 0;
01100 }
01101
01102
01103 if ( curCol >= int( mSelectedDates.count() ) ) {
01104 return;
01105 }
01106
01107
01108 mMinY[curCol] = mAgenda->timeToY( QTime( 23, 59 ) ) + 1;
01109 mMaxY[curCol] = mAgenda->timeToY( QTime( 0, 0 ) ) - 1;
01110
01111 int beginX;
01112 int endX;
01113 QDate columnDate;
01114 if ( event ) {
01115 QDate firstVisibleDate = mSelectedDates.first();
01116
01117 if ( curDate < firstVisibleDate ) {
01118 beginX = curCol + firstVisibleDate.daysTo( curDate );
01119 endX = beginX + event->dtStart().daysTo( event->dtEnd() );
01120 columnDate = firstVisibleDate;
01121 } else {
01122 beginX = curCol;
01123 endX = beginX + event->dtStart().daysTo( event->dtEnd() );
01124 columnDate = curDate;
01125 }
01126 } else if ( todo ) {
01127 if ( !todo->hasDueDate() ) {
01128 return;
01129 }
01130 columnDate = curDate;
01131 beginX = endX = curCol;
01132
01133 } else {
01134 return;
01135 }
01136 if ( todo && todo->isOverdue() ) {
01137 mAllDayAgenda->insertAllDayItem( incidence, columnDate, curCol, curCol );
01138 } else if ( incidence->doesFloat() ||
01139 ( todo &&
01140 ( todo->dtDue().time() == QTime( 0, 0 ) ||
01141 !todo->dtDue().isValid() ) ) ) {
01142 mAllDayAgenda->insertAllDayItem( incidence, columnDate, beginX, endX );
01143 } else if ( event && event->isMultiDay() ) {
01144 int startY = mAgenda->timeToY( event->dtStart().time() );
01145 QTime endtime = event->dtEnd().time();
01146 if ( endtime == QTime( 0, 0, 0 ) ) {
01147 endtime = QTime( 23, 59, 59 );
01148 }
01149 int endY = mAgenda->timeToY( endtime ) - 1;
01150 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
01151 mAgenda->insertMultiItem( event, columnDate, beginX, endX, startY, endY );
01152
01153 }
01154 if ( beginX == curCol ) {
01155 mMaxY[curCol] = mAgenda->timeToY( QTime( 23, 59 ) );
01156 if ( startY < mMinY[curCol] ) {
01157 mMinY[curCol] = startY;
01158 }
01159 } else if ( endX == curCol ) {
01160 mMinY[curCol] = mAgenda->timeToY( QTime( 0, 0 ) );
01161 if ( endY > mMaxY[curCol] ) {
01162 mMaxY[curCol] = endY;
01163 }
01164 } else {
01165 mMinY[curCol] = mAgenda->timeToY( QTime( 0, 0 ) );
01166 mMaxY[curCol] = mAgenda->timeToY( QTime( 23, 59 ) );
01167 }
01168 } else {
01169 int startY = 0, endY = 0;
01170 if ( event ) {
01171 startY = mAgenda->timeToY( incidence->dtStart().time() );
01172 QTime endtime = event->dtEnd().time();
01173 if ( endtime == QTime( 0, 0, 0 ) ) {
01174 endtime = QTime( 23, 59, 59 );
01175 }
01176 endY = mAgenda->timeToY( endtime ) - 1;
01177 }
01178 if ( todo ) {
01179 QTime t = todo->dtDue().time();
01180
01181 int halfHour = 1800;
01182 if ( t.addSecs( -halfHour ) < t ) {
01183 startY = mAgenda->timeToY( t.addSecs( -halfHour ) );
01184 endY = mAgenda->timeToY( t ) - 1;
01185 } else {
01186 startY = 0;
01187 endY = mAgenda->timeToY( t.addSecs( halfHour ) ) - 1;
01188 }
01189 }
01190 if ( endY < startY ) {
01191 endY = startY;
01192 }
01193 mAgenda->insertItem( incidence, columnDate, curCol, startY, endY );
01194 if ( startY < mMinY[curCol] ) {
01195 mMinY[curCol] = startY;
01196 }
01197 if ( endY > mMaxY[curCol] ) {
01198 mMaxY[curCol] = endY;
01199 }
01200 }
01201 }
01202
01203 void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
01204 {
01205 Todo *todo = dynamic_cast<Todo *>(incidence);
01206 CalFilter *filter = calendar()->filter();
01207 if ( ( filter && !filter->filterIncidence( incidence ) ) ||
01208 ( ( todo && !KOPrefs::instance()->showAllDayTodo() ) ) ) {
01209 return;
01210 }
01211
01212 displayIncidence( incidence );
01213 }
01214
01215 void KOAgendaView::changeIncidenceDisplay( Incidence *incidence, int mode )
01216 {
01217 switch ( mode ) {
01218 case KOGlobals::INCIDENCEADDED:
01219 {
01220
01221
01222
01223
01224
01225 changeIncidenceDisplayAdded( incidence );
01226 updateEventIndicators();
01227 break;
01228 }
01229 case KOGlobals::INCIDENCEEDITED:
01230 {
01231 if ( mAllowAgendaUpdate ) {
01232 removeIncidence( incidence );
01233 changeIncidenceDisplayAdded( incidence );
01234 }
01235 updateEventIndicators();
01236 break;
01237 }
01238 case KOGlobals::INCIDENCEDELETED:
01239 {
01240 mAgenda->removeIncidence( incidence );
01241 mAllDayAgenda->removeIncidence( incidence );
01242 updateEventIndicators();
01243 break;
01244 }
01245 default:
01246 updateView();
01247 }
01248 }
01249
01250 void KOAgendaView::fillAgenda( const QDate & )
01251 {
01252 fillAgenda();
01253 }
01254
01255 void KOAgendaView::fillAgenda()
01256 {
01257 mPendingChanges = false;
01258
01259
01260
01261 const QString &selectedAgendaUid = mAgenda->lastSelectedUid();
01262 const QString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
01263
01264 enableAgendaUpdate( true );
01265 clearView();
01266
01267 mAllDayAgenda->changeColumns( mSelectedDates.count() );
01268 mAgenda->changeColumns( mSelectedDates.count() );
01269 mEventIndicatorTop->changeColumns( mSelectedDates.count() );
01270 mEventIndicatorBottom->changeColumns( mSelectedDates.count() );
01271
01272 createDayLabels();
01273 setHolidayMasks();
01274
01275 mMinY.resize( mSelectedDates.count() );
01276 mMaxY.resize( mSelectedDates.count() );
01277
01278 mAgenda->setDateList( mSelectedDates );
01279
01280 bool somethingReselected = false;
01281 Incidence::List incidences = calendar()->incidences();
01282
01283 for ( Incidence::List::ConstIterator it = incidences.begin(); it!=incidences.constEnd(); ++it ) {
01284 Incidence *incidence = (*it);
01285 displayIncidence( incidence );
01286
01287 if( incidence->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
01288 mAgenda->selectItemByUID( incidence->uid() );
01289 somethingReselected = true;
01290 }
01291
01292 if( incidence->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
01293 mAllDayAgenda->selectItemByUID( incidence->uid() );
01294 somethingReselected = true;
01295 }
01296
01297 }
01298
01299 mAgenda->checkScrollBoundaries();
01300 updateEventIndicators();
01301
01302
01303
01304
01305
01306 deleteSelectedDateTime();
01307
01308 if( !somethingReselected ) {
01309 emit incidenceSelected( 0, QDate() );
01310 }
01311 }
01312
01313 void KOAgendaView::displayIncidence( Incidence *incidence )
01314 {
01315 QDate today = QDate::currentDate();
01316 DateTimeList::iterator t;
01317
01318
01319 Todo *todo = dynamic_cast<Todo *>( incidence );
01320 Event *event = dynamic_cast<Event *>( incidence );
01321
01322 QDateTime firstVisibleDateTime = mSelectedDates.first();
01323 QDateTime lastVisibleDateTime = mSelectedDates.last();
01324
01325 lastVisibleDateTime.setTime( QTime( 23, 59 ) );
01326 firstVisibleDateTime.setTime( QTime( 0, 0 ) );
01327 DateTimeList dateTimeList;
01328
01329 QDateTime incDtStart = incidence->dtStart();
01330 QDateTime incDtEnd = incidence->dtEnd();
01331
01332 if ( todo &&
01333 ( !KOPrefs::instance()->showAllDayTodo() || !todo->hasDueDate() ) ) {
01334 return;
01335 }
01336
01337 if ( incidence->doesRecur() ) {
01338 int eventDuration = incDtStart.daysTo( incDtEnd );
01339
01340
01341
01342
01343 QDateTime startDateTimeWithOffset = firstVisibleDateTime.addDays( -eventDuration );
01344 dateTimeList =
01345 incidence->recurrence()->timesInInterval( startDateTimeWithOffset,
01346 lastVisibleDateTime );
01347 } else {
01348 QDateTime dateToAdd;
01349 QDateTime incidenceStart;
01350 QDateTime incidenceEnd;
01351
01352 if ( todo && todo->hasDueDate() && !todo->isOverdue() ) {
01353
01354 dateToAdd = todo->dtDue();
01355 incidenceEnd = dateToAdd;
01356 } else if ( event ) {
01357 dateToAdd = incDtStart;
01358 incidenceEnd = incDtEnd;
01359
01360 if ( !dateToAdd.time().isValid() ) {
01361
01362 dateToAdd.setTime( QTime( 0, 0 ) );
01363 }
01364 }
01365
01366 if ( dateToAdd <= lastVisibleDateTime && incidenceEnd >= firstVisibleDateTime ) {
01367 dateTimeList += dateToAdd;
01368 }
01369 }
01370
01371
01372 QDateTime dateTimeToday = today;
01373 if ( todo &&
01374 todo->isOverdue() &&
01375 dateTimeToday >= firstVisibleDateTime &&
01376 dateTimeToday <= lastVisibleDateTime ) {
01377
01378 bool doAdd = true;
01379
01380 if ( todo->doesRecur() ) {
01381
01382
01383 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
01384 if ( (*t).date() == today ) {
01385 doAdd = false;
01386 break;
01387 }
01388 }
01389 }
01390
01391 if ( doAdd ) {
01392 dateTimeList += dateTimeToday;
01393 }
01394 }
01395
01396 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
01397 insertIncidence( incidence, (*t).date() );
01398 }
01399 }
01400
01401 void KOAgendaView::clearView()
01402 {
01403
01404 mAllDayAgenda->clear();
01405 mAgenda->clear();
01406 }
01407
01408 CalPrinterBase::PrintType KOAgendaView::printType()
01409 {
01410 if ( currentDateCount() == 1 ) return CalPrinterBase::Day;
01411 else return CalPrinterBase::Week;
01412 }
01413
01414 void KOAgendaView::updateEventIndicatorTop( int newY )
01415 {
01416 uint i;
01417 for( i = 0; i < mMinY.size(); ++i ) {
01418 mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
01419 }
01420 mEventIndicatorTop->update();
01421 }
01422
01423 void KOAgendaView::updateEventIndicatorBottom( int newY )
01424 {
01425 uint i;
01426 for( i = 0; i < mMaxY.size(); ++i ) {
01427 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
01428 }
01429 mEventIndicatorBottom->update();
01430 }
01431
01432 void KOAgendaView::slotTodoDropped( Todo *todo, const QPoint &gpos, bool allDay )
01433 {
01434 if ( gpos.x()<0 || gpos.y()<0 ) return;
01435 QDate day = mSelectedDates[gpos.x()];
01436 QTime time = mAgenda->gyToTime( gpos.y() );
01437 QDateTime newTime( day, time );
01438
01439 if ( todo ) {
01440 Todo *existingTodo = calendar()->todo( todo->uid() );
01441 if ( existingTodo ) {
01442 kdDebug(5850) << "Drop existing Todo" << endl;
01443 Todo *oldTodo = existingTodo->clone();
01444 if ( mChanger && mChanger->beginChange( existingTodo ) ) {
01445 existingTodo->setDtDue( newTime );
01446 existingTodo->setFloats( allDay );
01447 existingTodo->setHasDueDate( true );
01448 mChanger->changeIncidence( oldTodo, existingTodo,
01449 KOGlobals::DATE_MODIFIED, this );
01450 mChanger->endChange( existingTodo );
01451 } else {
01452 KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
01453 "because it cannot be locked.") );
01454 }
01455 delete oldTodo;
01456 } else {
01457 kdDebug(5850) << "Drop new Todo" << endl;
01458 todo->setDtDue( newTime );
01459 todo->setFloats( allDay );
01460 todo->setHasDueDate( true );
01461 if ( !mChanger->addIncidence( todo, 0, QString(), this ) ) {
01462 KODialogManager::errorSaveIncidence( this, todo );
01463 }
01464 }
01465 }
01466 }
01467
01468 void KOAgendaView::startDrag( Incidence *incidence )
01469 {
01470 #ifndef KORG_NODND
01471 DndFactory factory( calendar() );
01472 ICalDrag *vd = factory.createDrag( incidence, this );
01473 if ( vd->drag() ) {
01474 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01475 }
01476 #endif
01477 }
01478
01479 void KOAgendaView::readSettings()
01480 {
01481 readSettings(KOGlobals::self()->config());
01482 }
01483
01484 void KOAgendaView::readSettings(KConfig *config)
01485 {
01486
01487
01488 config->setGroup("Views");
01489
01490 #ifndef KORG_NOSPLITTER
01491 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01492 if (sizes.count() == 2) {
01493 mSplitterAgenda->setSizes(sizes);
01494 }
01495 #endif
01496
01497 updateConfig();
01498 }
01499
01500 void KOAgendaView::writeSettings(KConfig *config)
01501 {
01502
01503
01504 config->setGroup("Views");
01505
01506 #ifndef KORG_NOSPLITTER
01507 QValueList<int> list = mSplitterAgenda->sizes();
01508 config->writeEntry("Separator AgendaView",list);
01509 #endif
01510 }
01511
01512 void KOAgendaView::setHolidayMasks()
01513 {
01514 if ( mSelectedDates.isEmpty() || !mSelectedDates[0].isValid() ) {
01515 return;
01516 }
01517
01518 mHolidayMask.resize( mSelectedDates.count() + 1 );
01519
01520 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01521 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01522 }
01523
01524
01525
01526 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01527 mHolidayMask[ mSelectedDates.count() ] = showDay;
01528
01529 mAgenda->setHolidayMask( &mHolidayMask );
01530 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01531 }
01532
01533 void KOAgendaView::setContentsPos( int y )
01534 {
01535 mAgenda->setContentsPos( 0, y );
01536 }
01537
01538 void KOAgendaView::setExpandedButton( bool expanded )
01539 {
01540 if ( !mExpandButton ) return;
01541
01542 if ( expanded ) {
01543 mExpandButton->setPixmap( mExpandedPixmap );
01544 } else {
01545 mExpandButton->setPixmap( mNotExpandedPixmap );
01546 }
01547 }
01548
01549 void KOAgendaView::clearSelection()
01550 {
01551 mAgenda->deselectItem();
01552 mAllDayAgenda->deselectItem();
01553 }
01554
01555 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01556 {
01557 newTimeSpanSelected( start, end );
01558 mTimeSpanInAllDay = true;
01559 }
01560
01561 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01562 {
01563 if (!mSelectedDates.count()) return;
01564
01565 mTimeSpanInAllDay = false;
01566
01567 QDate dayStart = mSelectedDates[ kClamp( start.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01568 QDate dayEnd = mSelectedDates[ kClamp( end.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01569
01570 QTime timeStart = mAgenda->gyToTime(start.y());
01571 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01572
01573 QDateTime dtStart(dayStart,timeStart);
01574 QDateTime dtEnd(dayEnd,timeEnd);
01575
01576 mTimeSpanBegin = dtStart;
01577 mTimeSpanEnd = dtEnd;
01578 }
01579
01580 void KOAgendaView::deleteSelectedDateTime()
01581 {
01582 mTimeSpanBegin.setDate(QDate());
01583 mTimeSpanEnd.setDate(QDate());
01584 mTimeSpanInAllDay = false;
01585 }
01586
01587 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01588 {
01589 mAgenda->setTypeAheadReceiver( o );
01590 mAllDayAgenda->setTypeAheadReceiver( o );
01591 }
01592
01593 void KOAgendaView::finishTypeAhead()
01594 {
01595 mAgenda->finishTypeAhead();
01596 mAllDayAgenda->finishTypeAhead();
01597 }
01598
01599 void KOAgendaView::removeIncidence( Incidence *incidence )
01600 {
01601 mAgenda->removeIncidence( incidence );
01602 mAllDayAgenda->removeIncidence( incidence );
01603 }
01604
01605 void KOAgendaView::updateEventIndicators()
01606 {
01607 mMinY = mAgenda->minContentsY();
01608 mMaxY = mAgenda->maxContentsY();
01609
01610 mAgenda->checkScrollBoundaries();
01611 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01612 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01613 }
01614
01615 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01616 {
01617 mChanger = changer;
01618 mAgenda->setIncidenceChanger( changer );
01619 mAllDayAgenda->setIncidenceChanger( changer );
01620 }
01621
01622 void KOAgendaView::clearTimeSpanSelection()
01623 {
01624 mAgenda->clearSelection();
01625 mAllDayAgenda->clearSelection();
01626 deleteSelectedDateTime();
01627 }
01628
01629 bool KOAgendaView::filterByResource( Incidence *incidence )
01630 {
01631
01632
01633
01634
01635 if ( resourceCalendar() && incidence->type() == "Todo" ) {
01636 QString subRes = resourceCalendar()->subresourceIdentifier( incidence );
01637 if ( resourceCalendar()->subresourceType( subRes ) == "todo" ) {
01638 QString calmatch = "/.INBOX.directory/" + i18n( "Calendar" );
01639 if ( subResourceCalendar().contains( calmatch ) ) {
01640 return true;
01641 }
01642 }
01643 }
01644
01645
01646 if ( !resourceCalendar() )
01647 return true;
01648 CalendarResources *calRes = dynamic_cast<CalendarResources*>( calendar() );
01649 if ( !calRes )
01650 return true;
01651 if ( calRes->resource( incidence ) != resourceCalendar() )
01652 return false;
01653 if ( !subResourceCalendar().isEmpty() ) {
01654 if ( resourceCalendar()->subresourceIdentifier( incidence ) != subResourceCalendar() )
01655 return false;
01656 }
01657 return true;
01658 }
01659
01660 void KOAgendaView::resourcesChanged()
01661 {
01662 mPendingChanges = true;
01663 }
01664
01665 void KOAgendaView::calendarIncidenceAdded(Incidence * incidence)
01666 {
01667 Q_UNUSED( incidence );
01668 mPendingChanges = true;
01669 }
01670
01671 void KOAgendaView::calendarIncidenceChanged(Incidence * incidence)
01672 {
01673 Q_UNUSED( incidence );
01674 mPendingChanges = true;
01675 }
01676
01677 void KOAgendaView::calendarIncidenceDeleted(Incidence * incidence)
01678 {
01679 Q_UNUSED( incidence );
01680 mPendingChanges = true;
01681 }