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(double 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 connect(mAgenda, SIGNAL(gridSpacingYChanged( double ) ), this, SLOT( setCellHeight( double ) ) );
00255 }
00256
00257
00259 void TimeLabels::paintEvent(QPaintEvent*)
00260 {
00261
00262
00263
00264
00265 repaintContents(contentsX(), contentsY(), visibleWidth(), visibleHeight());
00266 }
00267
00269
00270 EventIndicator::EventIndicator(Location loc,QWidget *parent,const char *name)
00271 : QFrame(parent,name)
00272 {
00273 mColumns = 1;
00274 mTopBox = 0;
00275 mLocation = loc;
00276 mTopLayout = 0;
00277
00278 if (mLocation == Top) mPixmap = KOGlobals::self()->smallIcon("upindicator");
00279 else mPixmap = KOGlobals::self()->smallIcon("downindicator");
00280
00281 setMinimumHeight(mPixmap.height());
00282 }
00283
00284 EventIndicator::~EventIndicator()
00285 {
00286 }
00287
00288 void EventIndicator::drawContents(QPainter *p)
00289 {
00290
00291
00292
00293
00294 int i;
00295 for(i=0;i<mColumns;++i) {
00296 if (mEnabled[i]) {
00297 int cellWidth = contentsRect().right()/mColumns;
00298 int xOffset = KOGlobals::self()->reverseLayout() ?
00299 (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 :
00300 i*cellWidth + cellWidth/2 -mPixmap.width()/2;
00301 p->drawPixmap(QPoint(xOffset,0),mPixmap);
00302 }
00303 }
00304 }
00305
00306 void EventIndicator::changeColumns(int columns)
00307 {
00308 mColumns = columns;
00309 mEnabled.resize(mColumns);
00310
00311 update();
00312 }
00313
00314 void EventIndicator::enableColumn(int column, bool enable)
00315 {
00316 mEnabled[column] = enable;
00317 }
00318
00319
00320 #include <libkcal/incidence.h>
00321
00325
00326
00327 KOAlternateLabel::KOAlternateLabel(const QString &shortlabel, const QString &longlabel,
00328 const QString &extensivelabel, QWidget *parent, const char *name )
00329 : QLabel(parent, name), mTextTypeFixed(false), mShortText(shortlabel),
00330 mLongText(longlabel), mExtensiveText(extensivelabel)
00331 {
00332 setSizePolicy(QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
00333 if (mExtensiveText.isEmpty()) mExtensiveText = mLongText;
00334 squeezeTextToLabel();
00335 }
00336
00337 KOAlternateLabel::~KOAlternateLabel()
00338 {
00339 }
00340
00341 void KOAlternateLabel::useShortText()
00342 {
00343 mTextTypeFixed = true;
00344 QLabel::setText( mShortText );
00345 QToolTip::remove( this );
00346 QToolTip::add( this, mExtensiveText );
00347 }
00348
00349 void KOAlternateLabel::useLongText()
00350 {
00351 mTextTypeFixed = true;
00352 QLabel::setText( mLongText );
00353 QToolTip::remove( this );
00354 QToolTip::add( this, mExtensiveText );
00355 }
00356
00357 void KOAlternateLabel::useExtensiveText()
00358 {
00359 mTextTypeFixed = true;
00360 QLabel::setText( mExtensiveText );
00361 QToolTip::remove( this );
00362 QToolTip::hide();
00363 }
00364
00365 void KOAlternateLabel::useDefaultText()
00366 {
00367 mTextTypeFixed = false;
00368 squeezeTextToLabel();
00369 }
00370
00371 void KOAlternateLabel::squeezeTextToLabel()
00372 {
00373 if (mTextTypeFixed) return;
00374
00375 QFontMetrics fm(fontMetrics());
00376 int labelWidth = size().width();
00377 int textWidth = fm.width(mLongText);
00378 int longTextWidth = fm.width(mExtensiveText);
00379 if (longTextWidth <= labelWidth) {
00380 QLabel::setText( mExtensiveText );
00381 QToolTip::remove( this );
00382 QToolTip::hide();
00383 } else if (textWidth <= labelWidth) {
00384 QLabel::setText( mLongText );
00385 QToolTip::remove( this );
00386 QToolTip::add( this, mExtensiveText );
00387 } else {
00388 QLabel::setText( mShortText );
00389 QToolTip::remove( this );
00390 QToolTip::add( this, mExtensiveText );
00391 }
00392 }
00393
00394 void KOAlternateLabel::resizeEvent( QResizeEvent * )
00395 {
00396 squeezeTextToLabel();
00397 }
00398
00399 QSize KOAlternateLabel::minimumSizeHint() const
00400 {
00401 QSize sh = QLabel::minimumSizeHint();
00402 sh.setWidth(-1);
00403 return sh;
00404 }
00405
00406 void KOAlternateLabel::setText( const QString &text ) {
00407 mLongText = text;
00408 squeezeTextToLabel();
00409 }
00410
00411
00415
00416 KOAgendaView::KOAgendaView(Calendar *cal,QWidget *parent,const char *name) :
00417 KOEventView (cal,parent,name), mExpandButton( 0 ), mAllowAgendaUpdate( true ),
00418 mUpdateItem( 0 )
00419 {
00420 mSelectedDates.append(QDate::currentDate());
00421
00422 mLayoutDayLabels = 0;
00423 mDayLabelsFrame = 0;
00424 mDayLabels = 0;
00425
00426 bool isRTL = KOGlobals::self()->reverseLayout();
00427
00428 if ( KOPrefs::instance()->compactDialogs() ) {
00429 if ( KOPrefs::instance()->mVerticalScreen ) {
00430 mExpandedPixmap = KOGlobals::self()->smallIcon( "1downarrow" );
00431 mNotExpandedPixmap = KOGlobals::self()->smallIcon( "1uparrow" );
00432 } else {
00433 mExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1leftarrow" : "1rightarrow" );
00434 mNotExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1rightarrow" : "1leftarrow" );
00435 }
00436 }
00437
00438 QBoxLayout *topLayout = new QVBoxLayout(this);
00439
00440
00441 mDayLabelsFrame = new QHBox(this);
00442 topLayout->addWidget(mDayLabelsFrame);
00443
00444
00445 #ifndef KORG_NOSPLITTER
00446 mSplitterAgenda = new QSplitter(Vertical,this);
00447 topLayout->addWidget(mSplitterAgenda);
00448
00449 #if KDE_IS_VERSION( 3, 1, 93 )
00450 mSplitterAgenda->setOpaqueResize( KGlobalSettings::opaqueResize() );
00451 #else
00452 mSplitterAgenda->setOpaqueResize();
00453 #endif
00454
00455 mAllDayFrame = new QHBox(mSplitterAgenda);
00456
00457 QWidget *agendaFrame = new QWidget(mSplitterAgenda);
00458 #else
00459 QVBox *mainBox = new QVBox( this );
00460 topLayout->addWidget( mainBox );
00461
00462 mAllDayFrame = new QHBox(mainBox);
00463
00464 QWidget *agendaFrame = new QWidget(mainBox);
00465 #endif
00466
00467
00468 mDummyAllDayLeft = new QVBox( mAllDayFrame );
00469
00470 if ( KOPrefs::instance()->compactDialogs() ) {
00471 mExpandButton = new QPushButton(mDummyAllDayLeft);
00472 mExpandButton->setPixmap( mNotExpandedPixmap );
00473 mExpandButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
00474 QSizePolicy::Fixed ) );
00475 connect( mExpandButton, SIGNAL( clicked() ), SIGNAL( toggleExpand() ) );
00476 } else {
00477 QLabel *label = new QLabel( i18n("All Day"), mDummyAllDayLeft );
00478 label->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::WordBreak );
00479 }
00480
00481 mAllDayAgenda = new KOAgenda(1,mAllDayFrame);
00482 QWidget *dummyAllDayRight = new QWidget(mAllDayFrame);
00483
00484
00485 QGridLayout *agendaLayout = new QGridLayout(agendaFrame,3,3);
00486
00487
00488
00489 mEventIndicatorTop = new EventIndicator(EventIndicator::Top,agendaFrame);
00490 agendaLayout->addWidget(mEventIndicatorTop,0,1);
00491 mEventIndicatorBottom = new EventIndicator(EventIndicator::Bottom,
00492 agendaFrame);
00493 agendaLayout->addWidget(mEventIndicatorBottom,2,1);
00494 QWidget *dummyAgendaRight = new QWidget(agendaFrame);
00495 agendaLayout->addWidget(dummyAgendaRight,0,2);
00496
00497
00498 mTimeLabels = new TimeLabels(24,agendaFrame);
00499 agendaLayout->addWidget(mTimeLabels,1,0);
00500
00501
00502 mAgenda = new KOAgenda(1,96,KOPrefs::instance()->mHourSize,agendaFrame);
00503 agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
00504 agendaLayout->setColStretch(1,1);
00505
00506
00507 mAgendaPopup = eventPopup();
00508
00509
00510 mAllDayAgendaPopup = eventPopup();
00511
00512
00513 mTimeLabels->setAgenda(mAgenda);
00514
00515
00516
00517
00518 createDayLabels();
00519
00520
00521 dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00522 dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00523
00524 updateTimeBarWidth();
00525
00526
00527 connect(mAgenda->verticalScrollBar(),SIGNAL(valueChanged(int)),
00528 mTimeLabels, SLOT(positionChanged()));
00529
00530 connect( mAgenda,
00531 SIGNAL( zoomView( const int, const QPoint & ,const Qt::Orientation ) ),
00532 SLOT( zoomView( const int, const QPoint &, const Qt::Orientation ) ) );
00533
00534 connect(mTimeLabels->verticalScrollBar(),SIGNAL(valueChanged(int)),
00535 SLOT(setContentsPos(int)));
00536
00537
00538 connect( mAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00539 SLOT(newTimeSpanSelected(const QPoint &, const QPoint &)));
00540 connect( mAllDayAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00541 SLOT(newTimeSpanSelectedAllDay(const QPoint &, const QPoint &)));
00542
00543
00544 connect( mAgenda, SIGNAL(lowerYChanged(int)),
00545 SLOT(updateEventIndicatorTop(int)));
00546 connect( mAgenda, SIGNAL(upperYChanged(int)),
00547 SLOT(updateEventIndicatorBottom(int)));
00548
00549 connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
00550 connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
00551 }
00552
00553
00554 KOAgendaView::~KOAgendaView()
00555 {
00556 delete mAgendaPopup;
00557 delete mAllDayAgendaPopup;
00558 }
00559
00560 void KOAgendaView::connectAgenda( KOAgenda *agenda, QPopupMenu *popup,
00561 KOAgenda *otherAgenda )
00562 {
00563 connect( agenda, SIGNAL( showIncidencePopupSignal( Incidence *, const QDate & ) ),
00564 popup, SLOT( showIncidencePopup( Incidence *, const QDate & ) ) );
00565
00566 connect( agenda, SIGNAL( showNewEventPopupSignal() ),
00567 SLOT( showNewEventPopup() ) );
00568
00569 agenda->setCalendar( calendar() );
00570
00571
00572 connect( agenda, SIGNAL( newEventSignal() ), SIGNAL( newEventSignal() ) );
00573
00574 connect( agenda, SIGNAL( newStartSelectSignal() ),
00575 otherAgenda, SLOT( clearSelection() ) );
00576
00577 connect( agenda, SIGNAL( editIncidenceSignal( Incidence * ) ),
00578 SIGNAL( editIncidenceSignal( Incidence * ) ) );
00579 connect( agenda, SIGNAL( showIncidenceSignal( Incidence * ) ),
00580 SIGNAL( showIncidenceSignal( Incidence * ) ) );
00581 connect( agenda, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
00582 SIGNAL( deleteIncidenceSignal( Incidence * ) ) );
00583
00584 connect( agenda, SIGNAL( startMultiModify( const QString & ) ),
00585 SIGNAL( startMultiModify( const QString & ) ) );
00586 connect( agenda, SIGNAL( endMultiModify() ),
00587 SIGNAL( endMultiModify() ) );
00588
00589 connect( agenda, SIGNAL( itemModified( KOAgendaItem * ) ),
00590 SLOT( updateEventDates( KOAgendaItem * ) ) );
00591 connect( agenda, SIGNAL( enableAgendaUpdate( bool ) ),
00592 SLOT( enableAgendaUpdate( bool ) ) );
00593
00594
00595 connect( agenda, SIGNAL( startDragSignal( Incidence * ) ),
00596 SLOT( startDrag( Incidence * ) ) );
00597
00598
00599 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00600 otherAgenda, SLOT( deselectItem() ) );
00601 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00602 SIGNAL( incidenceSelected( Incidence * ) ) );
00603
00604
00605 connect( agenda, SIGNAL( droppedToDo( Todo *, const QPoint &, bool ) ),
00606 SLOT( slotTodoDropped( Todo *, const QPoint &, bool ) ) );
00607
00608 }
00609
00610 void KOAgendaView::zoomInVertically( )
00611 {
00612 KOPrefs::instance()->mHourSize++;
00613 mAgenda->updateConfig();
00614 mAgenda->checkScrollBoundaries();
00615
00616 mTimeLabels->updateConfig();
00617 mTimeLabels->positionChanged();
00618 mTimeLabels->repaint();
00619
00620 updateView();
00621 }
00622
00623 void KOAgendaView::zoomOutVertically( )
00624 {
00625
00626 if ( KOPrefs::instance()->mHourSize > 4 ) {
00627
00628 KOPrefs::instance()->mHourSize--;
00629 mAgenda->updateConfig();
00630 mAgenda->checkScrollBoundaries();
00631
00632 mTimeLabels->updateConfig();
00633 mTimeLabels->positionChanged();
00634 mTimeLabels->repaint();
00635
00636 updateView();
00637 }
00638 }
00639
00640 void KOAgendaView::zoomInHorizontally( const QDate &date)
00641 {
00642 QDate begin;
00643 QDate newBegin;
00644 QDate dateToZoom = date;
00645 int ndays,count;
00646
00647 begin = mSelectedDates.first();
00648 ndays = begin.daysTo( mSelectedDates.last() );
00649
00650
00651 if ( ! dateToZoom.isValid () )
00652 dateToZoom=mAgenda->selectedIncidenceDate();
00653
00654 if( !dateToZoom.isValid() ) {
00655 if ( ndays > 1 ) {
00656 newBegin=begin.addDays(1);
00657 count = ndays-1;
00658 emit zoomViewHorizontally ( newBegin , count );
00659 }
00660 } else {
00661 if ( ndays <= 2 ) {
00662 newBegin = dateToZoom;
00663 count = 1;
00664 } else {
00665 newBegin = dateToZoom.addDays( -ndays/2 +1 );
00666 count = ndays -1 ;
00667 }
00668 emit zoomViewHorizontally ( newBegin , count );
00669 }
00670 }
00671
00672 void KOAgendaView::zoomOutHorizontally( const QDate &date )
00673 {
00674 QDate begin;
00675 QDate newBegin;
00676 QDate dateToZoom = date;
00677 int ndays,count;
00678
00679 begin = mSelectedDates.first();
00680 ndays = begin.daysTo( mSelectedDates.last() );
00681
00682
00683 if ( ! dateToZoom.isValid () )
00684 dateToZoom=mAgenda->selectedIncidenceDate();
00685
00686 if ( !dateToZoom.isValid() ) {
00687 newBegin = begin.addDays(-1);
00688 count = ndays+3 ;
00689 } else {
00690 newBegin = dateToZoom.addDays( -ndays/2-1 );
00691 count = ndays+3;
00692 }
00693
00694 if ( abs( count ) >= 31 )
00695 kdDebug(5850) << "change to the mounth view?"<<endl;
00696 else
00697
00698 emit zoomViewHorizontally( newBegin, count );
00699 }
00700
00701 void KOAgendaView::zoomView( const int delta, const QPoint &pos,
00702 const Qt::Orientation orient )
00703 {
00704 static QDate zoomDate;
00705 static QTimer t( this );
00706
00707
00708
00709
00710 if ( orient == Qt::Horizontal ) {
00711 QDate date=mAgenda->selectedIncidenceDate();
00712 if ( date.isValid() )
00713 zoomDate=date;
00714 else{
00715 if ( !t.isActive() ) {
00716 zoomDate= mSelectedDates[pos.x()];
00717 }
00718 t.start ( 1000,true );
00719 }
00720 if ( delta > 0 )
00721 zoomOutHorizontally( zoomDate );
00722 else
00723 zoomInHorizontally( zoomDate );
00724 } else {
00725
00726 QPoint posConstentsOld = mAgenda->gridToContents(pos);
00727 if ( delta > 0 ) {
00728 zoomOutVertically();
00729 } else {
00730 zoomInVertically();
00731 }
00732 QPoint posConstentsNew = mAgenda->gridToContents(pos);
00733 mAgenda->scrollBy( 0, posConstentsNew.y() - posConstentsOld.y() );
00734 }
00735 }
00736
00737 void KOAgendaView::createDayLabels()
00738 {
00739
00740
00741
00742
00743
00744 delete mDayLabels;
00745
00746 mDayLabels = new QFrame (mDayLabelsFrame);
00747 mLayoutDayLabels = new QHBoxLayout(mDayLabels);
00748 mLayoutDayLabels->addSpacing(mTimeLabels->width());
00749
00750 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
00751
00752 DateList::ConstIterator dit;
00753 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00754 QDate date = *dit;
00755 QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels);
00756 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
00757
00758
00759 int dW = calsys->dayOfWeek(date);
00760 QString veryLongStr = KGlobal::locale()->formatDate( date );
00761 QString longstr = i18n( "short_weekday date (e.g. Mon 13)","%1 %2" )
00762 .arg( calsys->weekDayName( dW, true ) )
00763 .arg( calsys->day(date) );
00764 QString shortstr = QString::number(calsys->day(date));
00765
00766 KOAlternateLabel *dayLabel = new KOAlternateLabel(shortstr,
00767 longstr, veryLongStr, mDayLabels);
00768 dayLabel->setMinimumWidth(1);
00769 dayLabel->setAlignment(QLabel::AlignHCenter);
00770 if (date == QDate::currentDate()) {
00771 QFont font = dayLabel->font();
00772 font.setBold(true);
00773 dayLabel->setFont(font);
00774 }
00775 dayLayout->addWidget(dayLabel);
00776
00777
00778 QStringList texts = KOGlobals::self()->holiday( date );
00779 QStringList::ConstIterator textit = texts.begin();
00780 for ( ; textit != texts.end(); ++textit ) {
00781
00782 KOAlternateLabel*label = new KOAlternateLabel( (*textit), (*textit), QString::null, mDayLabels );
00783 label->setMinimumWidth(1);
00784 label->setAlignment(AlignCenter);
00785 dayLayout->addWidget(label);
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 }