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