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 *,const QDate &)),
00411 SIGNAL(editIncidenceSignal(Incidence *,const QDate &)) );
00412 connect( agenda, SIGNAL(showIncidenceSignal(Incidence *,const QDate &)),
00413 SIGNAL(showIncidenceSignal(Incidence *,const QDate &)) );
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::selectedIncidenceDates()
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().isValid() ) ) {
01144 mAllDayAgenda->insertAllDayItem( incidence, columnDate, beginX, endX );
01145 } else if ( event && event->isMultiDay() ) {
01146 int startY = mAgenda->timeToY( event->dtStart().time() );
01147 QTime endtime = event->dtEnd().time();
01148 if ( endtime == QTime( 0, 0, 0 ) ) {
01149 endtime = QTime( 23, 59, 59 );
01150 }
01151 int endY = mAgenda->timeToY( endtime ) - 1;
01152 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
01153 mAgenda->insertMultiItem( event, columnDate, beginX, endX, startY, endY );
01154
01155 }
01156 if ( beginX == curCol ) {
01157 mMaxY[curCol] = mAgenda->timeToY( QTime( 23, 59 ) );
01158 if ( startY < mMinY[curCol] ) {
01159 mMinY[curCol] = startY;
01160 }
01161 } else if ( endX == curCol ) {
01162 mMinY[curCol] = mAgenda->timeToY( QTime( 0, 0 ) );
01163 if ( endY > mMaxY[curCol] ) {
01164 mMaxY[curCol] = endY;
01165 }
01166 } else {
01167 mMinY[curCol] = mAgenda->timeToY( QTime( 0, 0 ) );
01168 mMaxY[curCol] = mAgenda->timeToY( QTime( 23, 59 ) );
01169 }
01170 } else {
01171 int startY = 0, endY = 0;
01172 if ( event ) {
01173 startY = mAgenda->timeToY( incidence->dtStart().time() );
01174 QTime endtime = event->dtEnd().time();
01175 if ( endtime == QTime( 0, 0, 0 ) ) {
01176 endtime = QTime( 23, 59, 59 );
01177 }
01178 endY = mAgenda->timeToY( endtime ) - 1;
01179 }
01180 if ( todo ) {
01181 QTime t = todo->dtDue().time();
01182
01183 if ( t == QTime( 0, 0 ) ) {
01184 t = QTime( 23, 59 );
01185 }
01186
01187 int halfHour = 1800;
01188 if ( t.addSecs( -halfHour ) < t ) {
01189 startY = mAgenda->timeToY( t.addSecs( -halfHour ) );
01190 endY = mAgenda->timeToY( t ) - 1;
01191 } else {
01192 startY = 0;
01193 endY = mAgenda->timeToY( t.addSecs( halfHour ) ) - 1;
01194 }
01195 }
01196 if ( endY < startY ) {
01197 endY = startY;
01198 }
01199 mAgenda->insertItem( incidence, columnDate, curCol, startY, endY );
01200 if ( startY < mMinY[curCol] ) {
01201 mMinY[curCol] = startY;
01202 }
01203 if ( endY > mMaxY[curCol] ) {
01204 mMaxY[curCol] = endY;
01205 }
01206 }
01207 }
01208
01209 void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
01210 {
01211 Todo *todo = dynamic_cast<Todo *>(incidence);
01212 CalFilter *filter = calendar()->filter();
01213 if ( ( filter && !filter->filterIncidence( incidence ) ) ||
01214 ( ( todo && !KOPrefs::instance()->showAllDayTodo() ) ) ) {
01215 return;
01216 }
01217
01218 displayIncidence( incidence );
01219 }
01220
01221 void KOAgendaView::changeIncidenceDisplay( Incidence *incidence, int mode )
01222 {
01223 switch ( mode ) {
01224 case KOGlobals::INCIDENCEADDED:
01225 {
01226
01227
01228
01229
01230
01231 changeIncidenceDisplayAdded( incidence );
01232 updateEventIndicators();
01233 break;
01234 }
01235 case KOGlobals::INCIDENCEEDITED:
01236 {
01237 if ( mAllowAgendaUpdate ) {
01238 removeIncidence( incidence );
01239 changeIncidenceDisplayAdded( incidence );
01240 }
01241 updateEventIndicators();
01242 break;
01243 }
01244 case KOGlobals::INCIDENCEDELETED:
01245 {
01246 mAgenda->removeIncidence( incidence );
01247 mAllDayAgenda->removeIncidence( incidence );
01248 updateEventIndicators();
01249 break;
01250 }
01251 default:
01252 updateView();
01253 }
01254 }
01255
01256 void KOAgendaView::fillAgenda( const QDate & )
01257 {
01258 fillAgenda();
01259 }
01260
01261 void KOAgendaView::fillAgenda()
01262 {
01263 mPendingChanges = false;
01264
01265
01266
01267 const QString &selectedAgendaUid = mAgenda->lastSelectedUid();
01268 const QString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
01269
01270 enableAgendaUpdate( true );
01271 clearView();
01272
01273 mAllDayAgenda->changeColumns( mSelectedDates.count() );
01274 mAgenda->changeColumns( mSelectedDates.count() );
01275 mEventIndicatorTop->changeColumns( mSelectedDates.count() );
01276 mEventIndicatorBottom->changeColumns( mSelectedDates.count() );
01277
01278 createDayLabels();
01279 setHolidayMasks();
01280
01281 mMinY.resize( mSelectedDates.count() );
01282 mMaxY.resize( mSelectedDates.count() );
01283
01284 mAgenda->setDateList( mSelectedDates );
01285
01286 bool somethingReselected = false;
01287 Incidence::List incidences = calendar()->incidences();
01288
01289 for ( Incidence::List::ConstIterator it = incidences.begin(); it!=incidences.constEnd(); ++it ) {
01290 Incidence *incidence = (*it);
01291 displayIncidence( incidence );
01292
01293 if( incidence->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
01294 mAgenda->selectItemByUID( incidence->uid() );
01295 somethingReselected = true;
01296 }
01297
01298 if( incidence->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
01299 mAllDayAgenda->selectItemByUID( incidence->uid() );
01300 somethingReselected = true;
01301 }
01302
01303 }
01304
01305 mAgenda->checkScrollBoundaries();
01306 updateEventIndicators();
01307
01308
01309
01310
01311
01312 deleteSelectedDateTime();
01313
01314 if( !somethingReselected ) {
01315 emit incidenceSelected( 0, QDate() );
01316 }
01317 }
01318
01319 void KOAgendaView::displayIncidence( Incidence *incidence )
01320 {
01321 QDate today = QDate::currentDate();
01322 DateTimeList::iterator t;
01323
01324
01325 Todo *todo = dynamic_cast<Todo *>( incidence );
01326 Event *event = dynamic_cast<Event *>( incidence );
01327
01328 QDateTime firstVisibleDateTime = mSelectedDates.first();
01329 QDateTime lastVisibleDateTime = mSelectedDates.last();
01330
01331 lastVisibleDateTime.setTime( QTime( 23, 59 ) );
01332 firstVisibleDateTime.setTime( QTime( 0, 0 ) );
01333 DateTimeList dateTimeList;
01334
01335 QDateTime incDtStart = incidence->dtStart();
01336 QDateTime incDtEnd = incidence->dtEnd();
01337
01338 if ( todo &&
01339 ( !KOPrefs::instance()->showAllDayTodo() || !todo->hasDueDate() ) ) {
01340 return;
01341 }
01342
01343 if ( incidence->doesRecur() ) {
01344 int eventDuration = event ? incDtStart.daysTo( incDtEnd ) : 0;
01345
01346
01347
01348
01349 QDateTime startDateTimeWithOffset = firstVisibleDateTime.addDays( -eventDuration );
01350 dateTimeList =
01351 incidence->recurrence()->timesInInterval( startDateTimeWithOffset,
01352 lastVisibleDateTime );
01353 } else {
01354 QDateTime dateToAdd;
01355 QDateTime incidenceStart;
01356 QDateTime incidenceEnd;
01357
01358 if ( todo && todo->hasDueDate() && !todo->isOverdue() ) {
01359
01360 dateToAdd = todo->dtDue();
01361
01362
01363
01364 if ( dateToAdd.time() == QTime( 0, 0 ) ) {
01365 dateToAdd = dateToAdd.addSecs( -1 );
01366 }
01367
01368 incidenceEnd = dateToAdd;
01369 } else if ( event ) {
01370 dateToAdd = incDtStart;
01371 incidenceEnd = incDtEnd;
01372
01373 if ( !dateToAdd.time().isValid() ) {
01374
01375 dateToAdd.setTime( QTime( 0, 0 ) );
01376 }
01377
01378 if ( event->doesFloat() ) {
01379 incidenceEnd.setTime( QTime( 23, 59 ) );
01380 }
01381 }
01382
01383 if ( dateToAdd <= lastVisibleDateTime && incidenceEnd > firstVisibleDateTime ) {
01384 dateTimeList += dateToAdd;
01385 }
01386 }
01387
01388
01389 QDateTime dateTimeToday = today;
01390 if ( todo &&
01391 todo->isOverdue() &&
01392 dateTimeToday >= firstVisibleDateTime &&
01393 dateTimeToday <= lastVisibleDateTime ) {
01394
01395 bool doAdd = true;
01396
01397 if ( todo->doesRecur() ) {
01398
01399
01400 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
01401 if ( (*t).date() == today ) {
01402 doAdd = false;
01403 break;
01404 }
01405 }
01406 }
01407
01408 if ( doAdd ) {
01409 dateTimeList += dateTimeToday;
01410 }
01411 }
01412
01413 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
01414 insertIncidence( incidence, (*t).date() );
01415 }
01416 }
01417
01418 void KOAgendaView::clearView()
01419 {
01420
01421 mAllDayAgenda->clear();
01422 mAgenda->clear();
01423 }
01424
01425 CalPrinterBase::PrintType KOAgendaView::printType()
01426 {
01427 if ( currentDateCount() == 1 ) return CalPrinterBase::Day;
01428 else return CalPrinterBase::Week;
01429 }
01430
01431 void KOAgendaView::updateEventIndicatorTop( int newY )
01432 {
01433 uint i;
01434 for( i = 0; i < mMinY.size(); ++i ) {
01435 mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
01436 }
01437 mEventIndicatorTop->update();
01438 }
01439
01440 void KOAgendaView::updateEventIndicatorBottom( int newY )
01441 {
01442 uint i;
01443 for( i = 0; i < mMaxY.size(); ++i ) {
01444 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
01445 }
01446 mEventIndicatorBottom->update();
01447 }
01448
01449 void KOAgendaView::slotTodoDropped( Todo *todo, const QPoint &gpos, bool allDay )
01450 {
01451 if ( gpos.x()<0 || gpos.y()<0 ) return;
01452 QDate day = mSelectedDates[gpos.x()];
01453 QTime time = mAgenda->gyToTime( gpos.y() );
01454 QDateTime newTime( day, time );
01455
01456 if ( todo ) {
01457 Todo *existingTodo = calendar()->todo( todo->uid() );
01458 if ( existingTodo ) {
01459 kdDebug(5850) << "Drop existing Todo" << endl;
01460 Todo *oldTodo = existingTodo->clone();
01461 if ( mChanger &&
01462 mChanger->beginChange( existingTodo, resourceCalendar(), subResourceCalendar() ) ) {
01463 existingTodo->setDtDue( newTime );
01464 existingTodo->setFloats( allDay );
01465 existingTodo->setHasDueDate( true );
01466 mChanger->changeIncidence( oldTodo, existingTodo,
01467 KOGlobals::DATE_MODIFIED, this );
01468 mChanger->endChange( existingTodo, resourceCalendar(), subResourceCalendar() );
01469 } else {
01470 KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
01471 "because it cannot be locked.") );
01472 }
01473 delete oldTodo;
01474 } else {
01475 kdDebug(5850) << "Drop new Todo" << endl;
01476 todo->setDtDue( newTime );
01477 todo->setFloats( allDay );
01478 todo->setHasDueDate( true );
01479 if ( !mChanger->addIncidence( todo, 0, QString(), this ) ) {
01480 KODialogManager::errorSaveIncidence( this, todo );
01481 }
01482 }
01483 }
01484 }
01485
01486 void KOAgendaView::startDrag( Incidence *incidence )
01487 {
01488 #ifndef KORG_NODND
01489 DndFactory factory( calendar() );
01490 ICalDrag *vd = factory.createDrag( incidence, this );
01491 if ( vd->drag() ) {
01492 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01493 }
01494 #endif
01495 }
01496
01497 void KOAgendaView::readSettings()
01498 {
01499 readSettings(KOGlobals::self()->config());
01500 }
01501
01502 void KOAgendaView::readSettings(KConfig *config)
01503 {
01504
01505
01506 config->setGroup("Views");
01507
01508 #ifndef KORG_NOSPLITTER
01509 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01510 if (sizes.count() == 2) {
01511 mSplitterAgenda->setSizes(sizes);
01512 }
01513 #endif
01514
01515 updateConfig();
01516 }
01517
01518 void KOAgendaView::writeSettings(KConfig *config)
01519 {
01520
01521
01522 config->setGroup("Views");
01523
01524 #ifndef KORG_NOSPLITTER
01525 QValueList<int> list = mSplitterAgenda->sizes();
01526 config->writeEntry("Separator AgendaView",list);
01527 #endif
01528 }
01529
01530 void KOAgendaView::setHolidayMasks()
01531 {
01532 if ( mSelectedDates.isEmpty() || !mSelectedDates[0].isValid() ) {
01533 return;
01534 }
01535
01536 mHolidayMask.resize( mSelectedDates.count() + 1 );
01537
01538 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01539 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01540 }
01541
01542
01543
01544 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01545 mHolidayMask[ mSelectedDates.count() ] = showDay;
01546
01547 mAgenda->setHolidayMask( &mHolidayMask );
01548 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01549 }
01550
01551 void KOAgendaView::setContentsPos( int y )
01552 {
01553 mAgenda->setContentsPos( 0, y );
01554 }
01555
01556 void KOAgendaView::setExpandedButton( bool expanded )
01557 {
01558 if ( !mExpandButton ) return;
01559
01560 if ( expanded ) {
01561 mExpandButton->setPixmap( mExpandedPixmap );
01562 } else {
01563 mExpandButton->setPixmap( mNotExpandedPixmap );
01564 }
01565 }
01566
01567 void KOAgendaView::clearSelection()
01568 {
01569 mAgenda->deselectItem();
01570 mAllDayAgenda->deselectItem();
01571 }
01572
01573 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01574 {
01575 newTimeSpanSelected( start, end );
01576 mTimeSpanInAllDay = true;
01577 }
01578
01579 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01580 {
01581 if (!mSelectedDates.count()) return;
01582
01583 mTimeSpanInAllDay = false;
01584
01585 QDate dayStart = mSelectedDates[ kClamp( start.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01586 QDate dayEnd = mSelectedDates[ kClamp( end.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01587
01588 QTime timeStart = mAgenda->gyToTime(start.y());
01589 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01590
01591 QDateTime dtStart(dayStart,timeStart);
01592 QDateTime dtEnd(dayEnd,timeEnd);
01593
01594 mTimeSpanBegin = dtStart;
01595 mTimeSpanEnd = dtEnd;
01596 }
01597
01598 void KOAgendaView::deleteSelectedDateTime()
01599 {
01600 mTimeSpanBegin.setDate(QDate());
01601 mTimeSpanEnd.setDate(QDate());
01602 mTimeSpanInAllDay = false;
01603 }
01604
01605 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01606 {
01607 mAgenda->setTypeAheadReceiver( o );
01608 mAllDayAgenda->setTypeAheadReceiver( o );
01609 }
01610
01611 void KOAgendaView::finishTypeAhead()
01612 {
01613 mAgenda->finishTypeAhead();
01614 mAllDayAgenda->finishTypeAhead();
01615 }
01616
01617 void KOAgendaView::removeIncidence( Incidence *incidence )
01618 {
01619 mAgenda->removeIncidence( incidence );
01620 mAllDayAgenda->removeIncidence( incidence );
01621 }
01622
01623 void KOAgendaView::updateEventIndicators()
01624 {
01625 mMinY = mAgenda->minContentsY();
01626 mMaxY = mAgenda->maxContentsY();
01627
01628 mAgenda->checkScrollBoundaries();
01629 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01630 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01631 }
01632
01633 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01634 {
01635 mChanger = changer;
01636 mAgenda->setIncidenceChanger( changer );
01637 mAllDayAgenda->setIncidenceChanger( changer );
01638 }
01639
01640 void KOAgendaView::clearTimeSpanSelection()
01641 {
01642 mAgenda->clearSelection();
01643 mAllDayAgenda->clearSelection();
01644 deleteSelectedDateTime();
01645 }
01646
01647 bool KOAgendaView::filterByResource( Incidence *incidence )
01648 {
01649
01650
01651
01652
01653 if ( resourceCalendar() && incidence->type() == "Todo" ) {
01654 QString subRes = resourceCalendar()->subresourceIdentifier( incidence );
01655 if ( resourceCalendar()->subresourceType( subRes ) == "todo" ) {
01656 QString calmatch = "/.INBOX.directory/Calendar";
01657 QString i18nmatch = "/.INBOX.directory/" + i18n( "Calendar" );
01658 if ( subResourceCalendar().contains( calmatch ) ||
01659 subResourceCalendar().contains( i18nmatch ) ) {
01660 return true;
01661 }
01662 }
01663 }
01664
01665
01666 if ( !resourceCalendar() )
01667 return true;
01668 CalendarResources *calRes = dynamic_cast<CalendarResources*>( calendar() );
01669 if ( !calRes )
01670 return true;
01671 if ( calRes->resource( incidence ) != resourceCalendar() )
01672 return false;
01673 if ( !subResourceCalendar().isEmpty() ) {
01674 if ( resourceCalendar()->subresourceIdentifier( incidence ) != subResourceCalendar() )
01675 return false;
01676 }
01677 return true;
01678 }
01679
01680 void KOAgendaView::resourcesChanged()
01681 {
01682 mPendingChanges = true;
01683 }
01684
01685 void KOAgendaView::calendarIncidenceAdded(Incidence * incidence)
01686 {
01687 Q_UNUSED( incidence );
01688 mPendingChanges = true;
01689 }
01690
01691 void KOAgendaView::calendarIncidenceChanged(Incidence * incidence)
01692 {
01693 Q_UNUSED( incidence );
01694 mPendingChanges = true;
01695 }
01696
01697 void KOAgendaView::calendarIncidenceDeleted(Incidence * incidence)
01698 {
01699 Q_UNUSED( incidence );
01700 mPendingChanges = true;
01701 }