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