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
00067 #include "koincidencetooltip.h"
00068 #include "kogroupware.h"
00069 #include "kodialogmanager.h"
00070 #include "koeventpopupmenu.h"
00071
00072 #include "koagendaview.h"
00073 #include "koagendaview.moc"
00074
00075 using namespace KOrg;
00076
00077 TimeLabels::TimeLabels(int rows,QWidget *parent,const char *name,WFlags f) :
00078 QScrollView(parent,name,f)
00079 {
00080 mRows = rows;
00081 mMiniWidth = 0;
00082
00083 mCellHeight = KOPrefs::instance()->mHourSize*4;
00084
00085 enableClipper(true);
00086
00087 setHScrollBarMode(AlwaysOff);
00088 setVScrollBarMode(AlwaysOff);
00089
00090 resizeContents(50, int(mRows * mCellHeight) );
00091
00092 viewport()->setBackgroundMode( PaletteBackground );
00093
00094 mMousePos = new QFrame(this);
00095 mMousePos->setLineWidth(0);
00096 mMousePos->setMargin(0);
00097 mMousePos->setBackgroundColor(Qt::red);
00098 mMousePos->setFixedSize(width(), 1);
00099 addChild(mMousePos, 0, 0);
00100 }
00101
00102 void TimeLabels::mousePosChanged(const QPoint &pos)
00103 {
00104 moveChild(mMousePos, 0, pos.y());
00105 }
00106
00107 void TimeLabels::showMousePos()
00108 {
00109 mMousePos->show();
00110 }
00111
00112 void TimeLabels::hideMousePos()
00113 {
00114 mMousePos->hide();
00115 }
00116
00117 void TimeLabels::setCellHeight(int height)
00118 {
00119 mCellHeight = height;
00120 }
00121
00122
00123
00124
00125
00126 void TimeLabels::drawContents(QPainter *p,int cx, int cy, int cw, int ch)
00127 {
00128
00129
00130
00131
00132
00133 cx = contentsX() + frameWidth()*2;
00134 cw = contentsWidth() ;
00135
00136
00137 int cell = ((int)(cy/mCellHeight));
00138 double y = cell * mCellHeight;
00139 QFontMetrics fm = fontMetrics();
00140 QString hour;
00141 QString suffix = "am";
00142 int timeHeight = fm.ascent();
00143 QFont nFont = font();
00144 p->setFont( font() );
00145
00146 if (!KGlobal::locale()->use12Clock()) {
00147 suffix = "00";
00148 } else
00149 if (cell > 11) suffix = "pm";
00150
00151 if ( timeHeight > mCellHeight ) {
00152 timeHeight = int(mCellHeight-1);
00153 int pointS = nFont.pointSize();
00154 while ( pointS > 4 ) {
00155 nFont.setPointSize( pointS );
00156 fm = QFontMetrics( nFont );
00157 if ( fm.ascent() < mCellHeight )
00158 break;
00159 -- pointS;
00160 }
00161 fm = QFontMetrics( nFont );
00162 timeHeight = fm.ascent();
00163 }
00164
00165 QFont sFont = nFont;
00166 sFont.setPointSize( sFont.pointSize()/2 );
00167 QFontMetrics fmS( sFont );
00168 int startW = mMiniWidth - frameWidth()-2 ;
00169 int tw2 = fmS.width(suffix);
00170 int divTimeHeight = (timeHeight-1) /2 - 1;
00171
00172
00173 while (y < cy + ch+mCellHeight) {
00174
00175 p->drawLine( cx, int(y), cw+2, int(y) );
00176 hour.setNum(cell);
00177
00178 if (KGlobal::locale()->use12Clock()) {
00179 if (cell == 12) suffix = "pm";
00180 if (cell == 0) hour.setNum(12);
00181 if (cell > 12) hour.setNum(cell - 12);
00182 }
00183
00184
00185 int timeWidth = fm.width(hour);
00186 int offset = startW - timeWidth - tw2 -1 ;
00187 p->setFont( nFont );
00188 p->drawText( offset, int(y+timeHeight), hour);
00189 p->setFont( sFont );
00190 offset = startW - tw2;
00191 p->drawText( offset, int(y+timeHeight-divTimeHeight), suffix);
00192
00193
00194 y += mCellHeight;
00195 cell++;
00196 }
00197
00198 }
00199
00203 int TimeLabels::minimumWidth() const
00204 {
00205 return mMiniWidth;
00206 }
00207
00209 void TimeLabels::updateConfig()
00210 {
00211 setFont(KOPrefs::instance()->mTimeBarFont);
00212
00213 QString test = "20";
00214 if ( KGlobal::locale()->use12Clock() )
00215 test = "12";
00216 mMiniWidth = fontMetrics().width( test );
00217 if ( KGlobal::locale()->use12Clock() )
00218 test = "pm";
00219 else {
00220 test = "00";
00221 }
00222 QFont sFont = font();
00223 sFont.setPointSize( sFont.pointSize()/2 );
00224 QFontMetrics fmS( sFont );
00225 mMiniWidth += fmS.width( test ) + frameWidth()*2+4 ;
00226
00227 setFixedWidth( mMiniWidth );
00228
00229
00230 mCellHeight = KOPrefs::instance()->mHourSize*4;
00231
00232
00233
00234 if ( mCellHeight < 4*mAgenda->gridSpacingY() )
00235 mCellHeight = 4*mAgenda->gridSpacingY();
00236 resizeContents( mMiniWidth, int(mRows * mCellHeight+1) );
00237 }
00238
00240 void TimeLabels::positionChanged()
00241 {
00242 int adjustment = mAgenda->contentsY();
00243 setContentsPos(0, adjustment);
00244 }
00245
00247 void TimeLabels::setAgenda(KOAgenda* agenda)
00248 {
00249 mAgenda = agenda;
00250
00251 connect(mAgenda, SIGNAL(mousePosSignal(const QPoint &)), this, SLOT(mousePosChanged(const QPoint &)));
00252 connect(mAgenda, SIGNAL(enterAgenda()), this, SLOT(showMousePos()));
00253 connect(mAgenda, SIGNAL(leaveAgenda()), this, SLOT(hideMousePos()));
00254 }
00255
00256
00258 void TimeLabels::paintEvent(QPaintEvent*)
00259 {
00260
00261
00262
00263
00264 repaintContents(contentsX(), contentsY(), visibleWidth(), visibleHeight());
00265 }
00266
00268
00269 EventIndicator::EventIndicator(Location loc,QWidget *parent,const char *name)
00270 : QFrame(parent,name)
00271 {
00272 mColumns = 1;
00273 mTopBox = 0;
00274 mLocation = loc;
00275 mTopLayout = 0;
00276
00277 if (mLocation == Top) mPixmap = KOGlobals::self()->smallIcon("upindicator");
00278 else mPixmap = KOGlobals::self()->smallIcon("downindicator");
00279
00280 setMinimumHeight(mPixmap.height());
00281 }
00282
00283 EventIndicator::~EventIndicator()
00284 {
00285 }
00286
00287 void EventIndicator::drawContents(QPainter *p)
00288 {
00289
00290
00291
00292
00293 int i;
00294 for(i=0;i<mColumns;++i) {
00295 if (mEnabled[i]) {
00296 int cellWidth = contentsRect().right()/mColumns;
00297 int xOffset = KOGlobals::self()->reverseLayout() ?
00298 (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 :
00299 i*cellWidth + cellWidth/2 -mPixmap.width()/2;
00300 p->drawPixmap(QPoint(xOffset,0),mPixmap);
00301 }
00302 }
00303 }
00304
00305 void EventIndicator::changeColumns(int columns)
00306 {
00307 mColumns = columns;
00308 mEnabled.resize(mColumns);
00309
00310 update();
00311 }
00312
00313 void EventIndicator::enableColumn(int column, bool enable)
00314 {
00315 mEnabled[column] = enable;
00316 }
00317
00318
00319 #include <libkcal/incidence.h>
00320
00324
00325
00326 KOAlternateLabel::KOAlternateLabel(const QString &shortlabel, const QString &longlabel,
00327 const QString &extensivelabel, QWidget *parent, const char *name )
00328 : QLabel(parent, name), mTextTypeFixed(false), mShortText(shortlabel),
00329 mLongText(longlabel), mExtensiveText(extensivelabel)
00330 {
00331 setSizePolicy(QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
00332 if (mExtensiveText.isEmpty()) mExtensiveText = mLongText;
00333 squeezeTextToLabel();
00334 }
00335
00336 KOAlternateLabel::~KOAlternateLabel()
00337 {
00338 }
00339
00340 void KOAlternateLabel::useShortText()
00341 {
00342 mTextTypeFixed = true;
00343 QLabel::setText( mShortText );
00344 QToolTip::remove( this );
00345 QToolTip::add( this, mExtensiveText );
00346 }
00347
00348 void KOAlternateLabel::useLongText()
00349 {
00350 mTextTypeFixed = true;
00351 QLabel::setText( mLongText );
00352 QToolTip::remove( this );
00353 QToolTip::add( this, mExtensiveText );
00354 }
00355
00356 void KOAlternateLabel::useExtensiveText()
00357 {
00358 mTextTypeFixed = true;
00359 QLabel::setText( mExtensiveText );
00360 QToolTip::remove( this );
00361 QToolTip::hide();
00362 }
00363
00364 void KOAlternateLabel::useDefaultText()
00365 {
00366 mTextTypeFixed = false;
00367 squeezeTextToLabel();
00368 }
00369
00370 void KOAlternateLabel::squeezeTextToLabel()
00371 {
00372 if (mTextTypeFixed) return;
00373
00374 QFontMetrics fm(fontMetrics());
00375 int labelWidth = size().width();
00376 int textWidth = fm.width(mLongText);
00377 int longTextWidth = fm.width(mExtensiveText);
00378 if (longTextWidth <= labelWidth) {
00379 QLabel::setText( mExtensiveText );
00380 QToolTip::remove( this );
00381 QToolTip::hide();
00382 } else if (textWidth <= labelWidth) {
00383 QLabel::setText( mLongText );
00384 QToolTip::remove( this );
00385 QToolTip::add( this, mExtensiveText );
00386 } else {
00387 QLabel::setText( mShortText );
00388 QToolTip::remove( this );
00389 QToolTip::add( this, mExtensiveText );
00390 }
00391 }
00392
00393 void KOAlternateLabel::resizeEvent( QResizeEvent * )
00394 {
00395 squeezeTextToLabel();
00396 }
00397
00398 QSize KOAlternateLabel::minimumSizeHint() const
00399 {
00400 QSize sh = QLabel::minimumSizeHint();
00401 sh.setWidth(-1);
00402 return sh;
00403 }
00404
00405 void KOAlternateLabel::setText( const QString &text ) {
00406 mLongText = text;
00407 squeezeTextToLabel();
00408 }
00409
00410
00414
00415 KOAgendaView::KOAgendaView(Calendar *cal,QWidget *parent,const char *name) :
00416 KOEventView (cal,parent,name), mExpandButton( 0 ), mAllowAgendaUpdate( true ),
00417 mUpdateItem( 0 )
00418 {
00419 mSelectedDates.append(QDate::currentDate());
00420
00421 mLayoutDayLabels = 0;
00422 mDayLabelsFrame = 0;
00423 mDayLabels = 0;
00424
00425 bool isRTL = KOGlobals::self()->reverseLayout();
00426
00427 if ( KOPrefs::instance()->compactDialogs() ) {
00428 if ( KOPrefs::instance()->mVerticalScreen ) {
00429 mExpandedPixmap = KOGlobals::self()->smallIcon( "1downarrow" );
00430 mNotExpandedPixmap = KOGlobals::self()->smallIcon( "1uparrow" );
00431 } else {
00432 mExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1leftarrow" : "1rightarrow" );
00433 mNotExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1rightarrow" : "1leftarrow" );
00434 }
00435 }
00436
00437 QBoxLayout *topLayout = new QVBoxLayout(this);
00438
00439
00440 mDayLabelsFrame = new QHBox(this);
00441 topLayout->addWidget(mDayLabelsFrame);
00442
00443
00444 #ifndef KORG_NOSPLITTER
00445 mSplitterAgenda = new QSplitter(Vertical,this);
00446 topLayout->addWidget(mSplitterAgenda);
00447
00448 #if KDE_IS_VERSION( 3, 1, 93 )
00449 mSplitterAgenda->setOpaqueResize( KGlobalSettings::opaqueResize() );
00450 #else
00451 mSplitterAgenda->setOpaqueResize();
00452 #endif
00453
00454 mAllDayFrame = new QHBox(mSplitterAgenda);
00455
00456 QWidget *agendaFrame = new QWidget(mSplitterAgenda);
00457 #else
00458 QVBox *mainBox = new QVBox( this );
00459 topLayout->addWidget( mainBox );
00460
00461 mAllDayFrame = new QHBox(mainBox);
00462
00463 QWidget *agendaFrame = new QWidget(mainBox);
00464 #endif
00465
00466
00467 mDummyAllDayLeft = new QVBox( mAllDayFrame );
00468
00469 if ( KOPrefs::instance()->compactDialogs() ) {
00470 mExpandButton = new QPushButton(mDummyAllDayLeft);
00471 mExpandButton->setPixmap( mNotExpandedPixmap );
00472 mExpandButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
00473 QSizePolicy::Fixed ) );
00474 connect( mExpandButton, SIGNAL( clicked() ), SIGNAL( toggleExpand() ) );
00475 } else {
00476 QLabel *label = new QLabel( i18n("All Day"), mDummyAllDayLeft );
00477 label->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::WordBreak );
00478 }
00479
00480 mAllDayAgenda = new KOAgenda(1,mAllDayFrame);
00481 QWidget *dummyAllDayRight = new QWidget(mAllDayFrame);
00482
00483
00484 QGridLayout *agendaLayout = new QGridLayout(agendaFrame,3,3);
00485
00486
00487
00488 mEventIndicatorTop = new EventIndicator(EventIndicator::Top,agendaFrame);
00489 agendaLayout->addWidget(mEventIndicatorTop,0,1);
00490 mEventIndicatorBottom = new EventIndicator(EventIndicator::Bottom,
00491 agendaFrame);
00492 agendaLayout->addWidget(mEventIndicatorBottom,2,1);
00493 QWidget *dummyAgendaRight = new QWidget(agendaFrame);
00494 agendaLayout->addWidget(dummyAgendaRight,0,2);
00495
00496
00497 mTimeLabels = new TimeLabels(24,agendaFrame);
00498 agendaLayout->addWidget(mTimeLabels,1,0);
00499
00500
00501 mAgenda = new KOAgenda(1,96,KOPrefs::instance()->mHourSize,agendaFrame);
00502 agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
00503 agendaLayout->setColStretch(1,1);
00504
00505
00506 mAgendaPopup = eventPopup();
00507
00508
00509 mAllDayAgendaPopup = eventPopup();
00510
00511
00512 mTimeLabels->setAgenda(mAgenda);
00513
00514
00515
00516
00517 createDayLabels();
00518
00519
00520 dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00521 dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00522
00523 updateTimeBarWidth();
00524
00525
00526 connect(mAgenda->verticalScrollBar(),SIGNAL(valueChanged(int)),
00527 mTimeLabels, SLOT(positionChanged()));
00528
00529 connect( mAgenda,
00530 SIGNAL( zoomView( const int, const QPoint & ,const Qt::Orientation ) ),
00531 SLOT( zoomView( const int, const QPoint &, const Qt::Orientation ) ) );
00532
00533 connect(mTimeLabels->verticalScrollBar(),SIGNAL(valueChanged(int)),
00534 SLOT(setContentsPos(int)));
00535
00536
00537 connect( mAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00538 SLOT(newTimeSpanSelected(const QPoint &, const QPoint &)));
00539 connect( mAllDayAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00540 SLOT(newTimeSpanSelectedAllDay(const QPoint &, const QPoint &)));
00541
00542
00543 connect( mAgenda, SIGNAL(lowerYChanged(int)),
00544 SLOT(updateEventIndicatorTop(int)));
00545 connect( mAgenda, SIGNAL(upperYChanged(int)),
00546 SLOT(updateEventIndicatorBottom(int)));
00547
00548 connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
00549 connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
00550 }
00551
00552
00553 KOAgendaView::~KOAgendaView()
00554 {
00555 delete mAgendaPopup;
00556 delete mAllDayAgendaPopup;
00557 }
00558
00559 void KOAgendaView::connectAgenda( KOAgenda *agenda, QPopupMenu *popup,
00560 KOAgenda *otherAgenda )
00561 {
00562 connect( agenda, SIGNAL( showIncidencePopupSignal( Incidence *, const QDate & ) ),
00563 popup, SLOT( showIncidencePopup( Incidence *, const QDate & ) ) );
00564
00565 connect( agenda, SIGNAL( showNewEventPopupSignal() ),
00566 SLOT( showNewEventPopup() ) );
00567
00568 agenda->setCalendar( calendar() );
00569
00570
00571 connect( agenda, SIGNAL( newEventSignal() ), SIGNAL( newEventSignal() ) );
00572
00573 connect( agenda, SIGNAL( newStartSelectSignal() ),
00574 otherAgenda, SLOT( clearSelection() ) );
00575
00576 connect( agenda, SIGNAL( editIncidenceSignal( Incidence * ) ),
00577 SIGNAL( editIncidenceSignal( Incidence * ) ) );
00578 connect( agenda, SIGNAL( showIncidenceSignal( Incidence * ) ),
00579 SIGNAL( showIncidenceSignal( Incidence * ) ) );
00580 connect( agenda, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
00581 SIGNAL( deleteIncidenceSignal( Incidence * ) ) );
00582
00583 connect( agenda, SIGNAL( startMultiModify( const QString & ) ),
00584 SIGNAL( startMultiModify( const QString & ) ) );
00585 connect( agenda, SIGNAL( endMultiModify() ),
00586 SIGNAL( endMultiModify() ) );
00587
00588 connect( agenda, SIGNAL( itemModified( KOAgendaItem * ) ),
00589 SLOT( updateEventDates( KOAgendaItem * ) ) );
00590 connect( agenda, SIGNAL( enableAgendaUpdate( bool ) ),
00591 SLOT( enableAgendaUpdate( bool ) ) );
00592
00593
00594 connect( agenda, SIGNAL( startDragSignal( Incidence * ) ),
00595 SLOT( startDrag( Incidence * ) ) );
00596
00597
00598 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00599 otherAgenda, SLOT( deselectItem() ) );
00600 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00601 SIGNAL( incidenceSelected( Incidence * ) ) );
00602
00603
00604 connect( agenda, SIGNAL( droppedToDo( Todo *, const QPoint &, bool ) ),
00605 SLOT( slotTodoDropped( Todo *, const QPoint &, bool ) ) );
00606
00607 }
00608
00609 void KOAgendaView::zoomInVertically( )
00610 {
00611 KOPrefs::instance()->mHourSize++;
00612 mAgenda->updateConfig();
00613 mAgenda->checkScrollBoundaries();
00614
00615 mTimeLabels->updateConfig();
00616 mTimeLabels->positionChanged();
00617 mTimeLabels->repaint();
00618
00619 updateView();
00620 }
00621
00622 void KOAgendaView::zoomOutVertically( )
00623 {
00624
00625 if ( KOPrefs::instance()->mHourSize > 4 ) {
00626
00627 KOPrefs::instance()->mHourSize--;
00628 mAgenda->updateConfig();
00629 mAgenda->checkScrollBoundaries();
00630
00631 mTimeLabels->updateConfig();
00632 mTimeLabels->positionChanged();
00633 mTimeLabels->repaint();
00634
00635 updateView();
00636 }
00637 }
00638
00639 void KOAgendaView::zoomInHorizontally( const QDate &date)
00640 {
00641 QDate begin;
00642 QDate newBegin;
00643 QDate dateToZoom = date;
00644 int ndays,count;
00645
00646 begin = mSelectedDates.first();
00647 ndays = begin.daysTo( mSelectedDates.last() );
00648
00649
00650 if ( ! dateToZoom.isValid () )
00651 dateToZoom=mAgenda->selectedIncidenceDate();
00652
00653 if( !dateToZoom.isValid() ) {
00654 if ( ndays > 1 ) {
00655 newBegin=begin.addDays(1);
00656 count = ndays-1;
00657 emit zoomViewHorizontally ( newBegin , count );
00658 }
00659 } else {
00660 if ( ndays <= 2 ) {
00661 newBegin = dateToZoom;
00662 count = 1;
00663 } else {
00664 newBegin = dateToZoom.addDays( -ndays/2 +1 );
00665 count = ndays -1 ;
00666 }
00667 emit zoomViewHorizontally ( newBegin , count );
00668 }
00669 }
00670
00671 void KOAgendaView::zoomOutHorizontally( const QDate &date )
00672 {
00673 QDate begin;
00674 QDate newBegin;
00675 QDate dateToZoom = date;
00676 int ndays,count;
00677
00678 begin = mSelectedDates.first();
00679 ndays = begin.daysTo( mSelectedDates.last() );
00680
00681
00682 if ( ! dateToZoom.isValid () )
00683 dateToZoom=mAgenda->selectedIncidenceDate();
00684
00685 if ( !dateToZoom.isValid() ) {
00686 newBegin = begin.addDays(-1);
00687 count = ndays+3 ;
00688 } else {
00689 newBegin = dateToZoom.addDays( -ndays/2-1 );
00690 count = ndays+3;
00691 }
00692
00693 if ( abs( count ) >= 31 )
00694 kdDebug(5850) << "change to the mounth view?"<<endl;
00695 else
00696
00697 emit zoomViewHorizontally( newBegin, count );
00698 }
00699
00700 void KOAgendaView::zoomView( const int delta, const QPoint &pos,
00701 const Qt::Orientation orient )
00702 {
00703 static QDate zoomDate;
00704 static QTimer t( this );
00705
00706
00707
00708
00709 if ( orient == Qt::Horizontal ) {
00710 QDate date=mAgenda->selectedIncidenceDate();
00711 if ( date.isValid() )
00712 zoomDate=date;
00713 else{
00714 if ( !t.isActive() ) {
00715 zoomDate= mSelectedDates[pos.x()];
00716 }
00717 t.start ( 1000,true );
00718 }
00719 if ( delta > 0 )
00720 zoomOutHorizontally( zoomDate );
00721 else
00722 zoomInHorizontally( zoomDate );
00723 } else {
00724
00725 QPoint posConstentsOld = mAgenda->gridToContents(pos);
00726 if ( delta > 0 ) {
00727 zoomOutVertically();
00728 } else {
00729 zoomInVertically();
00730 }
00731 QPoint posConstentsNew = mAgenda->gridToContents(pos);
00732 mAgenda->scrollBy( 0, posConstentsNew.y() - posConstentsOld.y() );
00733 }
00734 }
00735
00736 void KOAgendaView::createDayLabels()
00737 {
00738
00739
00740
00741
00742
00743 delete mDayLabels;
00744
00745 mDayLabels = new QFrame (mDayLabelsFrame);
00746 mLayoutDayLabels = new QHBoxLayout(mDayLabels);
00747 mLayoutDayLabels->addSpacing(mTimeLabels->width());
00748
00749 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
00750
00751 DateList::ConstIterator dit;
00752 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00753 QDate date = *dit;
00754 QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels);
00755 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
00756
00757
00758 int dW = calsys->dayOfWeek(date);
00759 QString veryLongStr = KGlobal::locale()->formatDate( date );
00760 QString longstr = i18n( "short_weekday date (e.g. Mon 13)","%1 %2" )
00761 .arg( calsys->weekDayName( dW, true ) )
00762 .arg( calsys->day(date) );
00763 QString shortstr = QString::number(calsys->day(date));
00764
00765 KOAlternateLabel *dayLabel = new KOAlternateLabel(shortstr,
00766 longstr, veryLongStr, mDayLabels);
00767 dayLabel->setMinimumWidth(1);
00768 dayLabel->setAlignment(QLabel::AlignHCenter);
00769 if (date == QDate::currentDate()) {
00770 QFont font = dayLabel->font();
00771 font.setBold(true);
00772 dayLabel->setFont(font);
00773 }
00774 dayLayout->addWidget(dayLabel);
00775
00776
00777 if ( KOGlobals::self()->holidays() ) {
00778 QString text = KOGlobals::self()->holidays()->shortText( date );
00779 if ( !text.isEmpty() ) {
00780
00781 KOAlternateLabel*label = new KOAlternateLabel( text, text, QString::null, mDayLabels );
00782 label->setMinimumWidth(1);
00783 label->setAlignment(AlignCenter);
00784 dayLayout->addWidget(label);
00785 }
00786 }
00787
00788 #ifndef KORG_NOPLUGINS
00789 CalendarDecoration::List cds = KOCore::self()->calendarDecorations();
00790 CalendarDecoration *it;
00791 for(it = cds.first(); it; it = cds.next()) {
00792 QString text = it->shortText( date );
00793 if ( !text.isEmpty() ) {
00794
00795 KOAlternateLabel*label = new KOAlternateLabel( text, text, QString::null, mDayLabels );
00796 label->setMinimumWidth(1);
00797 label->setAlignment(AlignCenter);
00798 dayLayout->addWidget(label);
00799 }
00800 }
00801
00802 for(it = cds.first(); it; it = cds.next()) {
00803 QWidget *wid = it->smallWidget(mDayLabels,date);
00804 if ( wid ) {
00805
00806 dayLayout->addWidget(wid);
00807 }
00808 }
00809 #endif
00810 }
00811
00812 mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
00813 mDayLabels->show();
00814 }
00815
00816 void KOAgendaView::enableAgendaUpdate( bool enable )
00817 {
00818 mAllowAgendaUpdate = enable;
00819 }
00820
00821 int KOAgendaView::maxDatesHint()
00822 {
00823
00824 return 0;
00825 }
00826
00827 int KOAgendaView::currentDateCount()
00828 {
00829 return mSelectedDates.count();
00830 }
00831
00832 Incidence::List KOAgendaView::selectedIncidences()
00833 {
00834 Incidence::List selected;
00835 Incidence *incidence;
00836
00837 incidence = mAgenda->selectedIncidence();
00838 if (incidence) selected.append(incidence);
00839
00840 incidence = mAllDayAgenda->selectedIncidence();
00841 if (incidence) selected.append(incidence);
00842
00843 return selected;
00844 }
00845
00846 DateList KOAgendaView::selectedDates()
00847 {
00848 DateList selected;
00849 QDate qd;
00850
00851 qd = mAgenda->selectedIncidenceDate();
00852 if (qd.isValid()) selected.append(qd);
00853
00854 qd = mAllDayAgenda->selectedIncidenceDate();
00855 if (qd.isValid()) selected.append(qd);
00856
00857 return selected;
00858 }
00859
00860 bool KOAgendaView::eventDurationHint( QDateTime &startDt, QDateTime &endDt,
00861 bool &allDay )
00862 {
00863 if ( selectionStart().isValid() ) {
00864 QDateTime start = selectionStart();
00865 QDateTime end = selectionEnd();
00866
00867 if ( start.secsTo( end ) == 15*60 ) {
00868
00869
00870 QTime defaultDuration( KOPrefs::instance()->mDefaultDuration.time() );
00871 int addSecs = ( defaultDuration.hour()*3600 ) +
00872 ( defaultDuration.minute()*60 );
00873 end = start.addSecs( addSecs );
00874 }
00875
00876 startDt = start;
00877 endDt = end;
00878 allDay = selectedIsAllDay();
00879 return true;
00880 }
00881 return false;
00882 }
00883
00885 bool KOAgendaView::selectedIsSingleCell()
00886 {
00887 if ( !selectionStart().isValid() || !selectionEnd().isValid() ) return false;
00888
00889 if (selectedIsAllDay()) {
00890 int days = selectionStart().daysTo(selectionEnd());
00891 return ( days < 1 );
00892 } else {
00893 int secs = selectionStart().secsTo(selectionEnd());
00894 return ( secs <= 24*60*60/mAgenda->rows() );
00895 }
00896 }
00897
00898
00899 void KOAgendaView::updateView()
00900 {
00901
00902 fillAgenda();
00903 }
00904
00905
00906
00907
00908
00909
00910 void KOAgendaView::updateConfig()
00911 {
00912
00913
00914
00915 mTimeLabels->updateConfig();
00916 mAgenda->updateConfig();
00917 mAllDayAgenda->updateConfig();
00918
00919
00920
00921 mTimeLabels->positionChanged();
00922
00923
00924 mTimeLabels->repaint();
00925
00926 updateTimeBarWidth();
00927
00928
00929 KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance()
00930 ->mEnableToolTips);
00931
00932 setHolidayMasks();
00933
00934 createDayLabels();
00935
00936 updateView();
00937 }
00938
00939 void KOAgendaView::updateTimeBarWidth()
00940 {
00941 int width;
00942
00943 width = mDummyAllDayLeft->fontMetrics().width( i18n("All Day") );
00944 width = QMAX( width, mTimeLabels->width() );
00945
00946 mDummyAllDayLeft->setFixedWidth( width );
00947 mTimeLabels->setFixedWidth( width );
00948 }
00949
00950
00951 void KOAgendaView::updateEventDates( KOAgendaItem *item )
00952 {
00953 kdDebug(5850) << "KOAgendaView::updateEventDates(): " << item->text() << endl;
00954
00955 QDateTime startDt,endDt;
00956
00957
00958
00959
00960
00961 QDate thisDate;
00962 if ( item->cellXLeft() < 0 ) {
00963 thisDate = ( mSelectedDates.first() ).addDays( item->cellXLeft() );
00964 } else {
00965 thisDate = mSelectedDates[ item->cellXLeft() ];
00966 }
00967 QDate oldThisDate( item->itemDate() );
00968 int daysOffset = oldThisDate.daysTo( thisDate );
00969 int daysLength = 0;
00970
00971
00972
00973 Incidence *incidence = item->incidence();
00974 if ( !incidence ) return;
00975
00976 QTime startTime(0,0,0), endTime(0,0,0);
00977 if ( incidence->doesFloat() ) {
00978 daysLength = item->cellWidth() - 1;
00979 } else {
00980 startTime = mAgenda->gyToTime( item->cellYTop() );
00981 if ( item->lastMultiItem() ) {
00982 endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
00983 daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
00984 } else {
00985 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
00986 }
00987 }
00988
00989
00990
00991 if ( incidence->type() == "Event" ) {
00992 startDt = incidence->dtStart();
00993 startDt = startDt.addDays( daysOffset );
00994 startDt.setTime( startTime );
00995 endDt = startDt.addDays( daysLength );
00996 endDt.setTime( endTime );
00997 Event*ev = static_cast<Event*>(incidence);
00998 if( incidence->dtStart() == startDt && ev->dtEnd() == endDt ) {
00999
01000 return;
01001 }
01002 incidence->setDtStart( startDt );
01003 ev->setDtEnd( endDt );
01004 } else if ( incidence->type() == "Todo" ) {
01005 Todo *td = static_cast<Todo*>(incidence);
01006 startDt = td->hasStartDate() ? td->dtStart() : td->dtDue();
01007 startDt = thisDate.addDays( td->dtDue().daysTo( startDt ) );
01008 startDt.setTime( startTime );
01009 endDt.setDate( thisDate );
01010 endDt.setTime( endTime );
01011
01012 if( td->dtDue() == endDt ) {
01013
01014 return;
01015 }
01016 }
01017
01018
01019
01020
01021 Recurrence *recur = incidence->recurrence();
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
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 if ( incidence->type() == "Event" ) {
01164 incidence->setDtStart( startDt );
01165 (static_cast<Event*>( incidence ) )->setDtEnd( endDt );
01166 } else if ( incidence->type() == "Todo" ) {
01167 Todo *td = static_cast<Todo*>( incidence );
01168 if ( td->hasStartDate() )
01169 td->setDtStart( startDt );
01170 td->setDtDue( endDt );
01171 }
01172
01173 item->setItemDate( startDt.date() );
01174
01175 KOIncidenceToolTip::remove( item );
01176 KOIncidenceToolTip::add( item, incidence, KOAgendaItem::toolTipGroup() );
01177
01178
01179
01180
01181 enableAgendaUpdate( false );
01182
01183
01184
01185
01186 if ( incidence->doesRecur() ) {
01187 mUpdateItem = incidence;
01188 QTimer::singleShot( 0, this, SLOT( doUpdateItem() ) );
01189 }
01190
01191 enableAgendaUpdate( true );
01192
01193
01194 }
01195
01196 void KOAgendaView::doUpdateItem()
01197 {
01198 if ( mUpdateItem ) {
01199 changeIncidenceDisplay( mUpdateItem, KOGlobals::INCIDENCEEDITED );
01200 mUpdateItem = 0;
01201 }
01202 }
01203
01204
01205
01206 void KOAgendaView::showDates( const QDate &start, const QDate &end )
01207 {
01208
01209
01210 mSelectedDates.clear();
01211
01212 QDate d = start;
01213 while (d <= end) {
01214 mSelectedDates.append(d);
01215 d = d.addDays( 1 );
01216 }
01217
01218
01219 fillAgenda();
01220 }
01221
01222
01223 void KOAgendaView::showIncidences( const Incidence::List & )
01224 {
01225 kdDebug(5850) << "KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
01226 }
01227
01228 void KOAgendaView::insertIncidence( Incidence *incidence, const QDate &curDate,
01229 int curCol )
01230 {
01231
01232 Event *event = dynamic_cast<Event *>( incidence );
01233 Todo *todo = dynamic_cast<Todo *>( incidence );
01234
01235 if ( curCol < 0 ) {
01236 curCol = mSelectedDates.findIndex( curDate );
01237 }
01238
01239 if ( curCol < 0 || curCol > int( mSelectedDates.size() ) )
01240 return;
01241
01242 int beginX;
01243 int endX;
01244 if ( event ) {
01245 beginX = curDate.daysTo( incidence->dtStart().date() ) + curCol;
01246 endX = curDate.daysTo( event->dateEnd() ) + curCol;
01247 } else if ( todo ) {
01248 if ( ! todo->hasDueDate() ) return;
01249 beginX = curDate.daysTo( todo->dtDue().date() ) + curCol;
01250 endX = beginX;
01251 } else {
01252 return;
01253 }
01254
01255 if ( todo && todo->isOverdue() ) {
01256 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01257 } else if ( incidence->doesFloat() ) {
01258
01259 if ( incidence->recurrence()->doesRecur() ) {
01260 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01261 } else {
01262
01263
01264 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
01265 mAllDayAgenda->insertAllDayItem( incidence, curDate, beginX, endX );
01266 }
01267 }
01268 } else if ( event && event->isMultiDay() ) {
01269 int startY = mAgenda->timeToY( event->dtStart().time() );
01270 QTime endtime( event->dtEnd().time() );
01271 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01272 int endY = mAgenda->timeToY( endtime ) - 1;
01273 if ( (beginX <= 0 && curCol == 0) || beginX == curCol ) {
01274 mAgenda->insertMultiItem( event, curDate, beginX, endX, startY, endY );
01275 }
01276 if ( beginX == curCol ) {
01277 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01278 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01279 } else if ( endX == curCol ) {
01280 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01281 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01282 } else {
01283 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01284 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01285 }
01286 } else {
01287 int startY = 0, endY = 0;
01288 if ( event ) {
01289 startY = mAgenda->timeToY( incidence->dtStart().time() );
01290 QTime endtime( event->dtEnd().time() );
01291 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01292 endY = mAgenda->timeToY( endtime ) - 1;
01293 }
01294 if ( todo ) {
01295 QTime t = todo->dtDue().time();
01296 endY = mAgenda->timeToY( t ) - 1;
01297 startY = mAgenda->timeToY( t.addSecs( -1800 ) );
01298 }
01299 if ( endY < startY ) endY = startY;
01300 mAgenda->insertItem( incidence, curDate, curCol, startY, endY );
01301 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01302 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01303 }
01304 }
01305
01306 void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
01307 {
01308 Todo *todo = dynamic_cast<Todo *>(incidence);
01309 CalFilter *filter = calendar()->filter();
01310 if ( filter && !filter->filterIncidence( incidence ) ||
01311 ( todo && !KOPrefs::instance()->showAllDayTodo() ) )
01312 return;
01313
01314 QDate f = mSelectedDates.first();
01315 QDate l = mSelectedDates.last();
01316 QDate startDt = incidence->dtStart().date();
01317
01318 if ( incidence->doesRecur() ) {
01319 DateList::ConstIterator dit;
01320 QDate curDate;
01321 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01322 curDate = *dit;
01323
01324 if ( incidence->recursOn( curDate ) ) {
01325 insertIncidence( incidence, curDate );
01326 }
01327 }
01328 return;
01329 }
01330
01331 QDate endDt;
01332 if ( incidence->type() == "Event" )
01333 endDt = (static_cast<Event *>(incidence))->dateEnd();
01334 if ( todo ) {
01335 endDt = todo->isOverdue() ? QDate::currentDate()
01336 : todo->dtDue().date();
01337
01338 if ( endDt >= f && endDt <= l ) {
01339 insertIncidence( incidence, endDt );
01340 return;
01341 }
01342 }
01343
01344 if ( startDt >= f && startDt <= l ) {
01345 insertIncidence( incidence, startDt );
01346 }
01347 }
01348
01349 void KOAgendaView::changeIncidenceDisplay( Incidence *incidence, int mode )
01350 {
01351 switch ( mode ) {
01352 case KOGlobals::INCIDENCEADDED: {
01353
01354
01355
01356
01357 if ( mAllowAgendaUpdate )
01358 changeIncidenceDisplayAdded( incidence );
01359 break;
01360 }
01361 case KOGlobals::INCIDENCEEDITED: {
01362 if ( !mAllowAgendaUpdate ) {
01363 updateEventIndicators();
01364 } else {
01365 removeIncidence( incidence );
01366 updateEventIndicators();
01367 changeIncidenceDisplayAdded( incidence );
01368 }
01369 break;
01370 }
01371 case KOGlobals::INCIDENCEDELETED: {
01372 mAgenda->removeIncidence( incidence );
01373 mAllDayAgenda->removeIncidence( incidence );
01374 updateEventIndicators();
01375 break;
01376 }
01377 default:
01378 updateView();
01379 }
01380 }
01381
01382 void KOAgendaView::fillAgenda( const QDate & )
01383 {
01384 fillAgenda();
01385 }
01386
01387 void KOAgendaView::fillAgenda()
01388 {
01389
01390
01391 const QString &selectedAgendaUid = mAgenda->lastSelectedUid();
01392 const QString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
01393
01394 enableAgendaUpdate( true );
01395 clearView();
01396
01397 mAllDayAgenda->changeColumns(mSelectedDates.count());
01398 mAgenda->changeColumns(mSelectedDates.count());
01399 mEventIndicatorTop->changeColumns(mSelectedDates.count());
01400 mEventIndicatorBottom->changeColumns(mSelectedDates.count());
01401
01402 createDayLabels();
01403 setHolidayMasks();
01404
01405 mMinY.resize(mSelectedDates.count());
01406 mMaxY.resize(mSelectedDates.count());
01407
01408 Event::List dayEvents;
01409
01410
01411
01412 Todo::List todos = calendar()->todos();
01413
01414 mAgenda->setDateList(mSelectedDates);
01415
01416 QDate today = QDate::currentDate();
01417
01418 bool somethingReselected = false;
01419 DateList::ConstIterator dit;
01420 int curCol = 0;
01421 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01422 QDate currentDate = *dit;
01423
01424
01425
01426 dayEvents = calendar()->events(currentDate,
01427 EventSortStartDate,
01428 SortDirectionAscending);
01429
01430
01431 mMinY[curCol] = mAgenda->timeToY(QTime(23,59)) + 1;
01432 mMaxY[curCol] = mAgenda->timeToY(QTime(0,0)) - 1;
01433
01434 unsigned int numEvent;
01435 for(numEvent=0;numEvent<dayEvents.count();++numEvent) {
01436 Event *event = *dayEvents.at(numEvent);
01437
01438 insertIncidence( event, currentDate, curCol );
01439 if( event->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
01440 mAgenda->selectItemByUID( event->uid() );
01441 somethingReselected = true;
01442 }
01443 if( event->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
01444 mAllDayAgenda->selectItemByUID( event->uid() );
01445 somethingReselected = true;
01446 }
01447
01448 }
01449
01450
01451
01452
01453 if ( KOPrefs::instance()->showAllDayTodo() ) {
01454 unsigned int numTodo;
01455 for (numTodo = 0; numTodo < todos.count(); ++numTodo) {
01456 Todo *todo = *todos.at(numTodo);
01457
01458 if ( ! todo->hasDueDate() ) continue;
01459
01460
01461
01462 bool overdue = todo->isOverdue();
01463
01464 if ( (( todo->dtDue().date() == currentDate) && !overdue) ||
01465 (( currentDate == today) && overdue) ||
01466 ( todo->recursOn( currentDate ) ) ) {
01467 if ( todo->doesFloat() || overdue ) {
01468
01469
01470 mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol);
01471 } else {
01472
01473
01474 int endY = mAgenda->timeToY(todo->dtDue().time()) - 1;
01475 int startY = endY - 1;
01476
01477 mAgenda->insertItem(todo,currentDate,curCol,startY,endY);
01478
01479 if (startY < mMinY[curCol]) mMinY[curCol] = startY;
01480 if (endY > mMaxY[curCol]) mMaxY[curCol] = endY;
01481 }
01482 }
01483 }
01484 }
01485
01486
01487 ++curCol;
01488 }
01489
01490 mAgenda->checkScrollBoundaries();
01491 updateEventIndicators();
01492
01493
01494
01495
01496
01497 deleteSelectedDateTime();
01498
01499 if( !somethingReselected ) {
01500 emit incidenceSelected( 0 );
01501 }
01502
01503
01504 }
01505
01506 void KOAgendaView::clearView()
01507 {
01508
01509 mAllDayAgenda->clear();
01510 mAgenda->clear();
01511 }
01512
01513 CalPrinter::PrintType KOAgendaView::printType()
01514 {
01515 if ( currentDateCount() == 1 ) return CalPrinter::Day;
01516 else return CalPrinter::Week;
01517 }
01518
01519 void KOAgendaView::updateEventIndicatorTop( int newY )
01520 {
01521 uint i;
01522 for( i = 0; i < mMinY.size(); ++i ) {
01523 mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
01524 }
01525 mEventIndicatorTop->update();
01526 }
01527
01528 void KOAgendaView::updateEventIndicatorBottom( int newY )
01529 {
01530 uint i;
01531 for( i = 0; i < mMaxY.size(); ++i ) {
01532 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
01533 }
01534 mEventIndicatorBottom->update();
01535 }
01536
01537 void KOAgendaView::slotTodoDropped( Todo *todo, const QPoint &gpos, bool allDay )
01538 {
01539 if ( gpos.x()<0 || gpos.y()<0 ) return;
01540 QDate day = mSelectedDates[gpos.x()];
01541 QTime time = mAgenda->gyToTime( gpos.y() );
01542 QDateTime newTime( day, time );
01543
01544 if ( todo ) {
01545 Todo *existingTodo = calendar()->todo( todo->uid() );
01546 if ( existingTodo ) {
01547 kdDebug(5850) << "Drop existing Todo" << endl;
01548 Todo *oldTodo = existingTodo->clone();
01549 if ( mChanger && mChanger->beginChange( existingTodo ) ) {
01550 existingTodo->setDtDue( newTime );
01551 existingTodo->setFloats( allDay );
01552 existingTodo->setHasDueDate( true );
01553 mChanger->changeIncidence( oldTodo, existingTodo );
01554 mChanger->endChange( existingTodo );
01555 } else {
01556 KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
01557 "because it cannot be locked.") );
01558 }
01559 delete oldTodo;
01560 } else {
01561 kdDebug(5850) << "Drop new Todo" << endl;
01562 todo->setDtDue( newTime );
01563 todo->setFloats( allDay );
01564 todo->setHasDueDate( true );
01565 if ( !mChanger->addIncidence( todo ) ) {
01566 KODialogManager::errorSaveIncidence( this, todo );
01567 }
01568 }
01569 }
01570 }
01571
01572 void KOAgendaView::startDrag( Incidence *incidence )
01573 {
01574 #ifndef KORG_NODND
01575 DndFactory factory( calendar() );
01576 ICalDrag *vd = factory.createDrag( incidence, this );
01577 if ( vd->drag() ) {
01578 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01579 }
01580 #endif
01581 }
01582
01583 void KOAgendaView::readSettings()
01584 {
01585 readSettings(KOGlobals::self()->config());
01586 }
01587
01588 void KOAgendaView::readSettings(KConfig *config)
01589 {
01590
01591
01592 config->setGroup("Views");
01593
01594 #ifndef KORG_NOSPLITTER
01595 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01596 if (sizes.count() == 2) {
01597 mSplitterAgenda->setSizes(sizes);
01598 }
01599 #endif
01600
01601 updateConfig();
01602 }
01603
01604 void KOAgendaView::writeSettings(KConfig *config)
01605 {
01606
01607
01608 config->setGroup("Views");
01609
01610 #ifndef KORG_NOSPLITTER
01611 QValueList<int> list = mSplitterAgenda->sizes();
01612 config->writeEntry("Separator AgendaView",list);
01613 #endif
01614 }
01615
01616 void KOAgendaView::setHolidayMasks()
01617 {
01618 mHolidayMask.resize( mSelectedDates.count() + 1 );
01619
01620 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01621 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01622 }
01623
01624
01625
01626 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01627 mHolidayMask[ mSelectedDates.count() ] = showDay;
01628
01629 mAgenda->setHolidayMask( &mHolidayMask );
01630 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01631 }
01632
01633 void KOAgendaView::setContentsPos( int y )
01634 {
01635 mAgenda->setContentsPos( 0, y );
01636 }
01637
01638 void KOAgendaView::setExpandedButton( bool expanded )
01639 {
01640 if ( !mExpandButton ) return;
01641
01642 if ( expanded ) {
01643 mExpandButton->setPixmap( mExpandedPixmap );
01644 } else {
01645 mExpandButton->setPixmap( mNotExpandedPixmap );
01646 }
01647 }
01648
01649 void KOAgendaView::clearSelection()
01650 {
01651 mAgenda->deselectItem();
01652 mAllDayAgenda->deselectItem();
01653 }
01654
01655 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01656 {
01657 newTimeSpanSelected( start, end );
01658 mTimeSpanInAllDay = true;
01659 }
01660
01661 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01662 {
01663 if (!mSelectedDates.count()) return;
01664
01665 mTimeSpanInAllDay = false;
01666
01667 QDate dayStart = mSelectedDates[start.x()];
01668 QDate dayEnd = mSelectedDates[end.x()];
01669
01670 QTime timeStart = mAgenda->gyToTime(start.y());
01671 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01672
01673 QDateTime dtStart(dayStart,timeStart);
01674 QDateTime dtEnd(dayEnd,timeEnd);
01675
01676 mTimeSpanBegin = dtStart;
01677 mTimeSpanEnd = dtEnd;
01678 }
01679
01680 void KOAgendaView::deleteSelectedDateTime()
01681 {
01682 mTimeSpanBegin.setDate(QDate());
01683 mTimeSpanEnd.setDate(QDate());
01684 mTimeSpanInAllDay = false;
01685 }
01686
01687 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01688 {
01689 mAgenda->setTypeAheadReceiver( o );
01690 mAllDayAgenda->setTypeAheadReceiver( o );
01691 }
01692
01693 void KOAgendaView::finishTypeAhead()
01694 {
01695 mAgenda->finishTypeAhead();
01696 mAllDayAgenda->finishTypeAhead();
01697 }
01698
01699 void KOAgendaView::removeIncidence( Incidence *incidence )
01700 {
01701 mAgenda->removeIncidence( incidence );
01702 mAllDayAgenda->removeIncidence( incidence );
01703 }
01704
01705 void KOAgendaView::updateEventIndicators()
01706 {
01707 mMinY = mAgenda->minContentsY();
01708 mMaxY = mAgenda->maxContentsY();
01709
01710 mAgenda->checkScrollBoundaries();
01711 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01712 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01713 }
01714
01715 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01716 {
01717 mChanger = changer;
01718 mAgenda->setIncidenceChanger( changer );
01719 mAllDayAgenda->setIncidenceChanger( changer );
01720 }