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, 59, 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 ( !todo->doesFloat() && 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
01374 if ( incidence->doesFloat() ) {
01375
01376 dateToAdd.setTime( QTime( 0, 0 ) );
01377 incidenceEnd.setTime( QTime( 23, 59, 59, 59 ) );
01378 }
01379
01380 if ( dateToAdd <= lastVisibleDateTime && incidenceEnd > firstVisibleDateTime ) {
01381 dateTimeList += dateToAdd;
01382 }
01383 }
01384
01385
01386 QDateTime dateTimeToday = today;
01387 if ( todo &&
01388 todo->isOverdue() &&
01389 dateTimeToday >= firstVisibleDateTime &&
01390 dateTimeToday <= lastVisibleDateTime ) {
01391
01392 bool doAdd = true;
01393
01394 if ( todo->doesRecur() ) {
01395
01396
01397 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
01398 if ( (*t).date() == today ) {
01399 doAdd = false;
01400 break;
01401 }
01402 }
01403 }
01404
01405 if ( doAdd ) {
01406 dateTimeList += dateTimeToday;
01407 }
01408 }
01409
01410 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
01411 insertIncidence( incidence, (*t).date() );
01412 }
01413 }
01414
01415 void KOAgendaView::clearView()
01416 {
01417
01418 mAllDayAgenda->clear();
01419 mAgenda->clear();
01420 }
01421
01422 CalPrinterBase::PrintType KOAgendaView::printType()
01423 {
01424 if ( currentDateCount() == 1 ) return CalPrinterBase::Day;
01425 else return CalPrinterBase::Week;
01426 }
01427
01428 void KOAgendaView::updateEventIndicatorTop( int newY )
01429 {
01430 uint i;
01431 for( i = 0; i < mMinY.size(); ++i ) {
01432 mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
01433 }
01434 mEventIndicatorTop->update();
01435 }
01436
01437 void KOAgendaView::updateEventIndicatorBottom( int newY )
01438 {
01439 uint i;
01440 for( i = 0; i < mMaxY.size(); ++i ) {
01441 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
01442 }
01443 mEventIndicatorBottom->update();
01444 }
01445
01446 void KOAgendaView::slotTodoDropped( Todo *todo, const QPoint &gpos, bool allDay )
01447 {
01448 if ( gpos.x()<0 || gpos.y()<0 ) return;
01449 QDate day = mSelectedDates[gpos.x()];
01450 QTime time = mAgenda->gyToTime( gpos.y() );
01451 QDateTime newTime( day, time );
01452
01453 if ( todo ) {
01454 Todo *existingTodo = calendar()->todo( todo->uid() );
01455 if ( existingTodo ) {
01456 kdDebug(5850) << "Drop existing Todo" << endl;
01457 Todo *oldTodo = existingTodo->clone();
01458 if ( mChanger &&
01459 mChanger->beginChange( existingTodo, resourceCalendar(), subResourceCalendar() ) ) {
01460 existingTodo->setDtDue( newTime );
01461 existingTodo->setFloats( allDay );
01462 existingTodo->setHasDueDate( true );
01463 mChanger->changeIncidence( oldTodo, existingTodo,
01464 KOGlobals::DATE_MODIFIED, this );
01465 mChanger->endChange( existingTodo, resourceCalendar(), subResourceCalendar() );
01466 } else {
01467 KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
01468 "because it cannot be locked.") );
01469 }
01470 delete oldTodo;
01471 } else {
01472 kdDebug(5850) << "Drop new Todo" << endl;
01473 todo->setDtDue( newTime );
01474 todo->setFloats( allDay );
01475 todo->setHasDueDate( true );
01476 if ( !mChanger->addIncidence( todo, 0, QString(), this ) ) {
01477 KODialogManager::errorSaveIncidence( this, todo );
01478 }
01479 }
01480 }
01481 }
01482
01483 void KOAgendaView::startDrag( Incidence *incidence )
01484 {
01485 #ifndef KORG_NODND
01486 DndFactory factory( calendar() );
01487 ICalDrag *vd = factory.createDrag( incidence, this );
01488 if ( vd->drag() ) {
01489 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01490 }
01491 #endif
01492 }
01493
01494 void KOAgendaView::readSettings()
01495 {
01496 readSettings(KOGlobals::self()->config());
01497 }
01498
01499 void KOAgendaView::readSettings(KConfig *config)
01500 {
01501
01502
01503 config->setGroup("Views");
01504
01505 #ifndef KORG_NOSPLITTER
01506 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01507 if (sizes.count() == 2) {
01508 mSplitterAgenda->setSizes(sizes);
01509 }
01510 #endif
01511
01512 updateConfig();
01513 }
01514
01515 void KOAgendaView::writeSettings(KConfig *config)
01516 {
01517
01518
01519 config->setGroup("Views");
01520
01521 #ifndef KORG_NOSPLITTER
01522 QValueList<int> list = mSplitterAgenda->sizes();
01523 config->writeEntry("Separator AgendaView",list);
01524 #endif
01525 }
01526
01527 void KOAgendaView::setHolidayMasks()
01528 {
01529 if ( mSelectedDates.isEmpty() || !mSelectedDates[0].isValid() ) {
01530 return;
01531 }
01532
01533 mHolidayMask.resize( mSelectedDates.count() + 1 );
01534
01535 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01536 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01537 }
01538
01539
01540
01541 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01542 mHolidayMask[ mSelectedDates.count() ] = showDay;
01543
01544 mAgenda->setHolidayMask( &mHolidayMask );
01545 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01546 }
01547
01548 void KOAgendaView::setContentsPos( int y )
01549 {
01550 mAgenda->setContentsPos( 0, y );
01551 }
01552
01553 void KOAgendaView::setExpandedButton( bool expanded )
01554 {
01555 if ( !mExpandButton ) return;
01556
01557 if ( expanded ) {
01558 mExpandButton->setPixmap( mExpandedPixmap );
01559 } else {
01560 mExpandButton->setPixmap( mNotExpandedPixmap );
01561 }
01562 }
01563
01564 void KOAgendaView::clearSelection()
01565 {
01566 mAgenda->deselectItem();
01567 mAllDayAgenda->deselectItem();
01568 }
01569
01570 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01571 {
01572 newTimeSpanSelected( start, end );
01573 mTimeSpanInAllDay = true;
01574 }
01575
01576 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01577 {
01578 if (!mSelectedDates.count()) return;
01579
01580 mTimeSpanInAllDay = false;
01581
01582 QDate dayStart = mSelectedDates[ kClamp( start.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01583 QDate dayEnd = mSelectedDates[ kClamp( end.x(), 0, (int)mSelectedDates.size() - 1 ) ];
01584
01585 QTime timeStart = mAgenda->gyToTime(start.y());
01586 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01587
01588 QDateTime dtStart(dayStart,timeStart);
01589 QDateTime dtEnd(dayEnd,timeEnd);
01590
01591 mTimeSpanBegin = dtStart;
01592 mTimeSpanEnd = dtEnd;
01593 }
01594
01595 void KOAgendaView::deleteSelectedDateTime()
01596 {
01597 mTimeSpanBegin.setDate(QDate());
01598 mTimeSpanEnd.setDate(QDate());
01599 mTimeSpanInAllDay = false;
01600 }
01601
01602 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01603 {
01604 mAgenda->setTypeAheadReceiver( o );
01605 mAllDayAgenda->setTypeAheadReceiver( o );
01606 }
01607
01608 void KOAgendaView::finishTypeAhead()
01609 {
01610 mAgenda->finishTypeAhead();
01611 mAllDayAgenda->finishTypeAhead();
01612 }
01613
01614 void KOAgendaView::removeIncidence( Incidence *incidence )
01615 {
01616 mAgenda->removeIncidence( incidence );
01617 mAllDayAgenda->removeIncidence( incidence );
01618 }
01619
01620 void KOAgendaView::updateEventIndicators()
01621 {
01622 mMinY = mAgenda->minContentsY();
01623 mMaxY = mAgenda->maxContentsY();
01624
01625 mAgenda->checkScrollBoundaries();
01626 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01627 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01628 }
01629
01630 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01631 {
01632 mChanger = changer;
01633 mAgenda->setIncidenceChanger( changer );
01634 mAllDayAgenda->setIncidenceChanger( changer );
01635 }
01636
01637 void KOAgendaView::clearTimeSpanSelection()
01638 {
01639 mAgenda->clearSelection();
01640 mAllDayAgenda->clearSelection();
01641 deleteSelectedDateTime();
01642 }
01643
01644 bool KOAgendaView::filterByResource( Incidence *incidence )
01645 {
01646
01647
01648
01649
01650 if ( resourceCalendar() && incidence->type() == "Todo" ) {
01651 QString subRes = resourceCalendar()->subresourceIdentifier( incidence );
01652 if ( resourceCalendar()->subresourceType( subRes ) == "todo" ) {
01653 QString calmatch = "/.INBOX.directory/Calendar";
01654 QString i18nmatch = "/.INBOX.directory/" + i18n( "Calendar" );
01655 if ( subResourceCalendar().contains( calmatch ) ||
01656 subResourceCalendar().contains( i18nmatch ) ) {
01657 return true;
01658 }
01659 }
01660 }
01661
01662
01663 if ( !resourceCalendar() )
01664 return true;
01665 CalendarResources *calRes = dynamic_cast<CalendarResources*>( calendar() );
01666 if ( !calRes )
01667 return true;
01668 if ( calRes->resource( incidence ) != resourceCalendar() )
01669 return false;
01670 if ( !subResourceCalendar().isEmpty() ) {
01671 if ( resourceCalendar()->subresourceIdentifier( incidence ) != subResourceCalendar() )
01672 return false;
01673 }
01674 return true;
01675 }
01676
01677 void KOAgendaView::resourcesChanged()
01678 {
01679 mPendingChanges = true;
01680 }
01681
01682 void KOAgendaView::calendarIncidenceAdded(Incidence * incidence)
01683 {
01684 Q_UNUSED( incidence );
01685 mPendingChanges = true;
01686 }
01687
01688 void KOAgendaView::calendarIncidenceChanged(Incidence * incidence)
01689 {
01690 Q_UNUSED( incidence );
01691 mPendingChanges = true;
01692 }
01693
01694 void KOAgendaView::calendarIncidenceDeleted(Incidence * incidence)
01695 {
01696 Q_UNUSED( incidence );
01697 mPendingChanges = true;
01698 }