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