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