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 if ( !mChanger || !mChanger->beginChange(incidence) ) return;
00976 Incidence *oldIncidence = incidence->clone();
00977
00978 QTime startTime(0,0,0), endTime(0,0,0);
00979 if ( incidence->doesFloat() ) {
00980 daysLength = item->cellWidth() - 1;
00981 } else {
00982 startTime = mAgenda->gyToTime( item->cellYTop() );
00983 if ( item->lastMultiItem() ) {
00984 endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
00985 daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
00986 } else {
00987 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
00988 }
00989 }
00990
00991
00992
00993 if ( incidence->type() == "Event" ) {
00994 startDt = incidence->dtStart();
00995 startDt = startDt.addDays( daysOffset );
00996 startDt.setTime( startTime );
00997 endDt = startDt.addDays( daysLength );
00998 endDt.setTime( endTime );
00999 Event*ev = static_cast<Event*>(incidence);
01000 if( incidence->dtStart() == startDt && ev->dtEnd() == endDt ) {
01001
01002 delete oldIncidence;
01003 return;
01004 }
01005 incidence->setDtStart( startDt );
01006 ev->setDtEnd( endDt );
01007 } else if ( incidence->type() == "Todo" ) {
01008 Todo *td = static_cast<Todo*>(incidence);
01009 startDt = td->hasStartDate() ? td->dtStart() : td->dtDue();
01010 startDt = thisDate.addDays( td->dtDue().daysTo( startDt ) );
01011 startDt.setTime( startTime );
01012 endDt.setDate( thisDate );
01013 endDt.setTime( endTime );
01014
01015 if( td->dtDue() == endDt ) {
01016
01017 delete oldIncidence;
01018 return;
01019 }
01020 }
01021
01022
01023
01024
01025 Recurrence *recur = incidence->recurrence();
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
01164
01165
01166
01167 if ( incidence->type() == "Event" ) {
01168 incidence->setDtStart( startDt );
01169 (static_cast<Event*>( incidence ) )->setDtEnd( endDt );
01170 } else if ( incidence->type() == "Todo" ) {
01171 Todo *td = static_cast<Todo*>( incidence );
01172 if ( td->hasStartDate() )
01173 td->setDtStart( startDt );
01174 td->setDtDue( endDt );
01175 }
01176
01177 mChanger->changeIncidence( oldIncidence, incidence );
01178 mChanger->endChange(incidence);
01179 delete oldIncidence;
01180
01181 item->setItemDate( startDt.date() );
01182
01183 KOIncidenceToolTip::remove( item );
01184 KOIncidenceToolTip::add( item, incidence, KOAgendaItem::toolTipGroup() );
01185
01186
01187
01188
01189 enableAgendaUpdate( false );
01190
01191
01192
01193
01194 if ( incidence->doesRecur() ) {
01195 mUpdateItem = incidence;
01196 QTimer::singleShot( 0, this, SLOT( doUpdateItem() ) );
01197 }
01198
01199 enableAgendaUpdate( true );
01200
01201
01202 }
01203
01204 void KOAgendaView::doUpdateItem()
01205 {
01206 if ( mUpdateItem ) {
01207 changeIncidenceDisplay( mUpdateItem, KOGlobals::INCIDENCEEDITED );
01208 mUpdateItem = 0;
01209 }
01210 }
01211
01212
01213
01214 void KOAgendaView::showDates( const QDate &start, const QDate &end )
01215 {
01216
01217
01218 mSelectedDates.clear();
01219
01220 QDate d = start;
01221 while (d <= end) {
01222 mSelectedDates.append(d);
01223 d = d.addDays( 1 );
01224 }
01225
01226
01227 fillAgenda();
01228 }
01229
01230
01231 void KOAgendaView::showIncidences( const Incidence::List & )
01232 {
01233 kdDebug(5850) << "KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
01234 }
01235
01236 void KOAgendaView::insertIncidence( Incidence *incidence, const QDate &curDate,
01237 int curCol )
01238 {
01239
01240 Event *event = dynamic_cast<Event *>( incidence );
01241 Todo *todo = dynamic_cast<Todo *>( incidence );
01242
01243 if ( curCol < 0 ) {
01244 curCol = mSelectedDates.findIndex( curDate );
01245 }
01246
01247 if ( curCol < 0 || curCol > int( mSelectedDates.size() ) )
01248 return;
01249
01250 int beginX;
01251 int endX;
01252 if ( event ) {
01253 beginX = curDate.daysTo( incidence->dtStart().date() ) + curCol;
01254 endX = curDate.daysTo( event->dateEnd() ) + curCol;
01255 } else if ( todo ) {
01256 if ( ! todo->hasDueDate() ) return;
01257 beginX = curDate.daysTo( todo->dtDue().date() ) + curCol;
01258 endX = beginX;
01259 } else {
01260 return;
01261 }
01262
01263 if ( todo && todo->isOverdue() ) {
01264 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01265 } else if ( incidence->doesFloat() ) {
01266
01267 if ( incidence->recurrence()->doesRecur() ) {
01268 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01269 } else {
01270
01271
01272 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
01273 mAllDayAgenda->insertAllDayItem( incidence, curDate, beginX, endX );
01274 }
01275 }
01276 } else if ( event && event->isMultiDay() ) {
01277 int startY = mAgenda->timeToY( event->dtStart().time() );
01278 QTime endtime( event->dtEnd().time() );
01279 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01280 int endY = mAgenda->timeToY( endtime ) - 1;
01281 if ( (beginX <= 0 && curCol == 0) || beginX == curCol ) {
01282 mAgenda->insertMultiItem( event, curDate, beginX, endX, startY, endY );
01283 }
01284 if ( beginX == curCol ) {
01285 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01286 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01287 } else if ( endX == curCol ) {
01288 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01289 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01290 } else {
01291 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01292 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01293 }
01294 } else {
01295 int startY = 0, endY = 0;
01296 if ( event ) {
01297 startY = mAgenda->timeToY( incidence->dtStart().time() );
01298 QTime endtime( event->dtEnd().time() );
01299 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01300 endY = mAgenda->timeToY( endtime ) - 1;
01301 }
01302 if ( todo ) {
01303 QTime t = todo->dtDue().time();
01304 endY = mAgenda->timeToY( t ) - 1;
01305 startY = mAgenda->timeToY( t.addSecs( -1800 ) );
01306 }
01307 if ( endY < startY ) endY = startY;
01308 mAgenda->insertItem( incidence, curDate, curCol, startY, endY );
01309 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01310 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01311 }
01312 }
01313
01314 void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
01315 {
01316 Todo *todo = dynamic_cast<Todo *>(incidence);
01317 CalFilter *filter = calendar()->filter();
01318 if ( filter && !filter->filterIncidence( incidence ) ||
01319 ( todo && !KOPrefs::instance()->showAllDayTodo() ) )
01320 return;
01321
01322 QDate f = mSelectedDates.first();
01323 QDate l = mSelectedDates.last();
01324 QDate startDt = incidence->dtStart().date();
01325
01326 if ( incidence->doesRecur() ) {
01327 DateList::ConstIterator dit;
01328 QDate curDate;
01329 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01330 curDate = *dit;
01331
01332 if ( incidence->recursOn( curDate ) ) {
01333 insertIncidence( incidence, curDate );
01334 }
01335 }
01336 return;
01337 }
01338
01339 QDate endDt;
01340 if ( incidence->type() == "Event" )
01341 endDt = (static_cast<Event *>(incidence))->dateEnd();
01342 if ( todo ) {
01343 endDt = todo->isOverdue() ? QDate::currentDate()
01344 : todo->dtDue().date();
01345
01346 if ( endDt >= f && endDt <= l ) {
01347 insertIncidence( incidence, endDt );
01348 return;
01349 }
01350 }
01351
01352 if ( startDt >= f && startDt <= l ) {
01353 insertIncidence( incidence, startDt );
01354 }
01355 }
01356
01357 void KOAgendaView::changeIncidenceDisplay( Incidence *incidence, int mode )
01358 {
01359 switch ( mode ) {
01360 case KOGlobals::INCIDENCEADDED: {
01361
01362
01363
01364
01365 if ( mAllowAgendaUpdate )
01366 changeIncidenceDisplayAdded( incidence );
01367 break;
01368 }
01369 case KOGlobals::INCIDENCEEDITED: {
01370 if ( !mAllowAgendaUpdate ) {
01371 updateEventIndicators();
01372 } else {
01373 removeIncidence( incidence );
01374 updateEventIndicators();
01375 changeIncidenceDisplayAdded( incidence );
01376 }
01377 break;
01378 }
01379 case KOGlobals::INCIDENCEDELETED: {
01380 mAgenda->removeIncidence( incidence );
01381 mAllDayAgenda->removeIncidence( incidence );
01382 updateEventIndicators();
01383 break;
01384 }
01385 default:
01386 updateView();
01387 }
01388 }
01389
01390 void KOAgendaView::fillAgenda( const QDate & )
01391 {
01392 fillAgenda();
01393 }
01394
01395 void KOAgendaView::fillAgenda()
01396 {
01397
01398
01399 const QString &selectedAgendaUid = mAgenda->lastSelectedUid();
01400 const QString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
01401
01402 enableAgendaUpdate( true );
01403 clearView();
01404
01405 mAllDayAgenda->changeColumns(mSelectedDates.count());
01406 mAgenda->changeColumns(mSelectedDates.count());
01407 mEventIndicatorTop->changeColumns(mSelectedDates.count());
01408 mEventIndicatorBottom->changeColumns(mSelectedDates.count());
01409
01410 createDayLabels();
01411 setHolidayMasks();
01412
01413 mMinY.resize(mSelectedDates.count());
01414 mMaxY.resize(mSelectedDates.count());
01415
01416 Event::List dayEvents;
01417
01418
01419
01420 Todo::List todos = calendar()->todos();
01421
01422 mAgenda->setDateList(mSelectedDates);
01423
01424 QDate today = QDate::currentDate();
01425
01426 bool somethingReselected = false;
01427 DateList::ConstIterator dit;
01428 int curCol = 0;
01429 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01430 QDate currentDate = *dit;
01431
01432
01433
01434 dayEvents = calendar()->events(currentDate,
01435 EventSortStartDate,
01436 SortDirectionAscending);
01437
01438
01439 mMinY[curCol] = mAgenda->timeToY(QTime(23,59)) + 1;
01440 mMaxY[curCol] = mAgenda->timeToY(QTime(0,0)) - 1;
01441
01442 unsigned int numEvent;
01443 for(numEvent=0;numEvent<dayEvents.count();++numEvent) {
01444 Event *event = *dayEvents.at(numEvent);
01445
01446 insertIncidence( event, currentDate, curCol );
01447 if( event->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
01448 mAgenda->selectItemByUID( event->uid() );
01449 somethingReselected = true;
01450 }
01451 if( event->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
01452 mAllDayAgenda->selectItemByUID( event->uid() );
01453 somethingReselected = true;
01454 }
01455
01456 }
01457
01458
01459
01460
01461 if ( KOPrefs::instance()->showAllDayTodo() ) {
01462 unsigned int numTodo;
01463 for (numTodo = 0; numTodo < todos.count(); ++numTodo) {
01464 Todo *todo = *todos.at(numTodo);
01465
01466 if ( ! todo->hasDueDate() ) continue;
01467
01468
01469
01470 bool overdue = todo->isOverdue();
01471
01472 if ( (( todo->dtDue().date() == currentDate) && !overdue) ||
01473 (( currentDate == today) && overdue) ||
01474 ( todo->recursOn( currentDate ) ) ) {
01475 if ( todo->doesFloat() || overdue ) {
01476
01477
01478 mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol);
01479 } else {
01480
01481
01482 int endY = mAgenda->timeToY(todo->dtDue().time()) - 1;
01483 int startY = endY - 1;
01484
01485 mAgenda->insertItem(todo,currentDate,curCol,startY,endY);
01486
01487 if (startY < mMinY[curCol]) mMinY[curCol] = startY;
01488 if (endY > mMaxY[curCol]) mMaxY[curCol] = endY;
01489 }
01490 }
01491 }
01492 }
01493
01494
01495 ++curCol;
01496 }
01497
01498 mAgenda->checkScrollBoundaries();
01499 updateEventIndicators();
01500
01501
01502
01503
01504
01505 deleteSelectedDateTime();
01506
01507 if( !somethingReselected ) {
01508 emit incidenceSelected( 0 );
01509 }
01510
01511
01512 }
01513
01514 void KOAgendaView::clearView()
01515 {
01516
01517 mAllDayAgenda->clear();
01518 mAgenda->clear();
01519 }
01520
01521 CalPrinterBase::PrintType KOAgendaView::printType()
01522 {
01523 if ( currentDateCount() == 1 ) return CalPrinterBase::Day;
01524 else return CalPrinterBase::Week;
01525 }
01526
01527 void KOAgendaView::updateEventIndicatorTop( int newY )
01528 {
01529 uint i;
01530 for( i = 0; i < mMinY.size(); ++i ) {
01531 mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
01532 }
01533 mEventIndicatorTop->update();
01534 }
01535
01536 void KOAgendaView::updateEventIndicatorBottom( int newY )
01537 {
01538 uint i;
01539 for( i = 0; i < mMaxY.size(); ++i ) {
01540 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
01541 }
01542 mEventIndicatorBottom->update();
01543 }
01544
01545 void KOAgendaView::slotTodoDropped( Todo *todo, const QPoint &gpos, bool allDay )
01546 {
01547 if ( gpos.x()<0 || gpos.y()<0 ) return;
01548 QDate day = mSelectedDates[gpos.x()];
01549 QTime time = mAgenda->gyToTime( gpos.y() );
01550 QDateTime newTime( day, time );
01551
01552 if ( todo ) {
01553 Todo *existingTodo = calendar()->todo( todo->uid() );
01554 if ( existingTodo ) {
01555 kdDebug(5850) << "Drop existing Todo" << endl;
01556 Todo *oldTodo = existingTodo->clone();
01557 if ( mChanger && mChanger->beginChange( existingTodo ) ) {
01558 existingTodo->setDtDue( newTime );
01559 existingTodo->setFloats( allDay );
01560 existingTodo->setHasDueDate( true );
01561 mChanger->changeIncidence( oldTodo, existingTodo );
01562 mChanger->endChange( existingTodo );
01563 } else {
01564 KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
01565 "because it cannot be locked.") );
01566 }
01567 delete oldTodo;
01568 } else {
01569 kdDebug(5850) << "Drop new Todo" << endl;
01570 todo->setDtDue( newTime );
01571 todo->setFloats( allDay );
01572 todo->setHasDueDate( true );
01573 if ( !mChanger->addIncidence( todo, this ) ) {
01574 KODialogManager::errorSaveIncidence( this, todo );
01575 }
01576 }
01577 }
01578 }
01579
01580 void KOAgendaView::startDrag( Incidence *incidence )
01581 {
01582 #ifndef KORG_NODND
01583 DndFactory factory( calendar() );
01584 ICalDrag *vd = factory.createDrag( incidence, this );
01585 if ( vd->drag() ) {
01586 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01587 }
01588 #endif
01589 }
01590
01591 void KOAgendaView::readSettings()
01592 {
01593 readSettings(KOGlobals::self()->config());
01594 }
01595
01596 void KOAgendaView::readSettings(KConfig *config)
01597 {
01598
01599
01600 config->setGroup("Views");
01601
01602 #ifndef KORG_NOSPLITTER
01603 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01604 if (sizes.count() == 2) {
01605 mSplitterAgenda->setSizes(sizes);
01606 }
01607 #endif
01608
01609 updateConfig();
01610 }
01611
01612 void KOAgendaView::writeSettings(KConfig *config)
01613 {
01614
01615
01616 config->setGroup("Views");
01617
01618 #ifndef KORG_NOSPLITTER
01619 QValueList<int> list = mSplitterAgenda->sizes();
01620 config->writeEntry("Separator AgendaView",list);
01621 #endif
01622 }
01623
01624 void KOAgendaView::setHolidayMasks()
01625 {
01626 mHolidayMask.resize( mSelectedDates.count() + 1 );
01627
01628 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01629 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01630 }
01631
01632
01633
01634 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01635 mHolidayMask[ mSelectedDates.count() ] = showDay;
01636
01637 mAgenda->setHolidayMask( &mHolidayMask );
01638 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01639 }
01640
01641 void KOAgendaView::setContentsPos( int y )
01642 {
01643 mAgenda->setContentsPos( 0, y );
01644 }
01645
01646 void KOAgendaView::setExpandedButton( bool expanded )
01647 {
01648 if ( !mExpandButton ) return;
01649
01650 if ( expanded ) {
01651 mExpandButton->setPixmap( mExpandedPixmap );
01652 } else {
01653 mExpandButton->setPixmap( mNotExpandedPixmap );
01654 }
01655 }
01656
01657 void KOAgendaView::clearSelection()
01658 {
01659 mAgenda->deselectItem();
01660 mAllDayAgenda->deselectItem();
01661 }
01662
01663 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01664 {
01665 newTimeSpanSelected( start, end );
01666 mTimeSpanInAllDay = true;
01667 }
01668
01669 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01670 {
01671 if (!mSelectedDates.count()) return;
01672
01673 mTimeSpanInAllDay = false;
01674
01675 QDate dayStart = mSelectedDates[start.x()];
01676 QDate dayEnd = mSelectedDates[end.x()];
01677
01678 QTime timeStart = mAgenda->gyToTime(start.y());
01679 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01680
01681 QDateTime dtStart(dayStart,timeStart);
01682 QDateTime dtEnd(dayEnd,timeEnd);
01683
01684 mTimeSpanBegin = dtStart;
01685 mTimeSpanEnd = dtEnd;
01686 }
01687
01688 void KOAgendaView::deleteSelectedDateTime()
01689 {
01690 mTimeSpanBegin.setDate(QDate());
01691 mTimeSpanEnd.setDate(QDate());
01692 mTimeSpanInAllDay = false;
01693 }
01694
01695 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01696 {
01697 mAgenda->setTypeAheadReceiver( o );
01698 mAllDayAgenda->setTypeAheadReceiver( o );
01699 }
01700
01701 void KOAgendaView::finishTypeAhead()
01702 {
01703 mAgenda->finishTypeAhead();
01704 mAllDayAgenda->finishTypeAhead();
01705 }
01706
01707 void KOAgendaView::removeIncidence( Incidence *incidence )
01708 {
01709 mAgenda->removeIncidence( incidence );
01710 mAllDayAgenda->removeIncidence( incidence );
01711 }
01712
01713 void KOAgendaView::updateEventIndicators()
01714 {
01715 mMinY = mAgenda->minContentsY();
01716 mMaxY = mAgenda->maxContentsY();
01717
01718 mAgenda->checkScrollBoundaries();
01719 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01720 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01721 }
01722
01723 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01724 {
01725 mChanger = changer;
01726 mAgenda->setIncidenceChanger( changer );
01727 mAllDayAgenda->setIncidenceChanger( changer );
01728 }