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 KOrg::AgendaView (cal,parent,name), mExpandButton( 0 ), mAllowAgendaUpdate( true ),
00418 mUpdateItem( 0 ),
00419 mResource( 0 )
00420 {
00421 mSelectedDates.append(QDate::currentDate());
00422
00423 mLayoutDayLabels = 0;
00424 mDayLabelsFrame = 0;
00425 mDayLabels = 0;
00426
00427 bool isRTL = KOGlobals::self()->reverseLayout();
00428
00429 if ( KOPrefs::instance()->compactDialogs() ) {
00430 if ( KOPrefs::instance()->mVerticalScreen ) {
00431 mExpandedPixmap = KOGlobals::self()->smallIcon( "1downarrow" );
00432 mNotExpandedPixmap = KOGlobals::self()->smallIcon( "1uparrow" );
00433 } else {
00434 mExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1leftarrow" : "1rightarrow" );
00435 mNotExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ? "1rightarrow" : "1leftarrow" );
00436 }
00437 }
00438
00439 QBoxLayout *topLayout = new QVBoxLayout(this);
00440
00441
00442 mDayLabelsFrame = new QHBox(this);
00443 topLayout->addWidget(mDayLabelsFrame);
00444
00445
00446 #ifndef KORG_NOSPLITTER
00447 mSplitterAgenda = new QSplitter(Vertical,this);
00448 topLayout->addWidget(mSplitterAgenda);
00449
00450 #if KDE_IS_VERSION( 3, 1, 93 )
00451 mSplitterAgenda->setOpaqueResize( KGlobalSettings::opaqueResize() );
00452 #else
00453 mSplitterAgenda->setOpaqueResize();
00454 #endif
00455
00456 mAllDayFrame = new QHBox(mSplitterAgenda);
00457
00458 QWidget *agendaFrame = new QWidget(mSplitterAgenda);
00459 #else
00460 QVBox *mainBox = new QVBox( this );
00461 topLayout->addWidget( mainBox );
00462
00463 mAllDayFrame = new QHBox(mainBox);
00464
00465 QWidget *agendaFrame = new QWidget(mainBox);
00466 #endif
00467
00468
00469 mDummyAllDayLeft = new QVBox( mAllDayFrame );
00470
00471 if ( KOPrefs::instance()->compactDialogs() ) {
00472 mExpandButton = new QPushButton(mDummyAllDayLeft);
00473 mExpandButton->setPixmap( mNotExpandedPixmap );
00474 mExpandButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed,
00475 QSizePolicy::Fixed ) );
00476 connect( mExpandButton, SIGNAL( clicked() ), SIGNAL( toggleExpand() ) );
00477 } else {
00478 QLabel *label = new QLabel( i18n("All Day"), mDummyAllDayLeft );
00479 label->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::WordBreak );
00480 }
00481
00482 mAllDayAgenda = new KOAgenda(1,mAllDayFrame);
00483 QWidget *dummyAllDayRight = new QWidget(mAllDayFrame);
00484
00485
00486 QGridLayout *agendaLayout = new QGridLayout(agendaFrame,3,3);
00487
00488
00489
00490 mEventIndicatorTop = new EventIndicator(EventIndicator::Top,agendaFrame);
00491 agendaLayout->addWidget(mEventIndicatorTop,0,1);
00492 mEventIndicatorBottom = new EventIndicator(EventIndicator::Bottom,
00493 agendaFrame);
00494 agendaLayout->addWidget(mEventIndicatorBottom,2,1);
00495 QWidget *dummyAgendaRight = new QWidget(agendaFrame);
00496 agendaLayout->addWidget(dummyAgendaRight,0,2);
00497
00498
00499 mTimeLabels = new TimeLabels(24,agendaFrame);
00500 agendaLayout->addWidget(mTimeLabels,1,0);
00501
00502
00503 mAgenda = new KOAgenda(1,96,KOPrefs::instance()->mHourSize,agendaFrame);
00504 agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
00505 agendaLayout->setColStretch(1,1);
00506
00507
00508 mAgendaPopup = eventPopup();
00509
00510
00511 mAllDayAgendaPopup = eventPopup();
00512
00513
00514 mTimeLabels->setAgenda(mAgenda);
00515
00516
00517
00518
00519 createDayLabels();
00520
00521
00522 dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00523 dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
00524
00525 updateTimeBarWidth();
00526
00527
00528 connect(mAgenda->verticalScrollBar(),SIGNAL(valueChanged(int)),
00529 mTimeLabels, SLOT(positionChanged()));
00530
00531 connect( mAgenda,
00532 SIGNAL( zoomView( const int, const QPoint & ,const Qt::Orientation ) ),
00533 SLOT( zoomView( const int, const QPoint &, const Qt::Orientation ) ) );
00534
00535 connect(mTimeLabels->verticalScrollBar(),SIGNAL(valueChanged(int)),
00536 SLOT(setContentsPos(int)));
00537
00538
00539 connect( mAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00540 SLOT(newTimeSpanSelected(const QPoint &, const QPoint &)));
00541 connect( mAllDayAgenda, SIGNAL(newTimeSpanSignal(const QPoint &, const QPoint &)),
00542 SLOT(newTimeSpanSelectedAllDay(const QPoint &, const QPoint &)));
00543
00544
00545 connect( mAgenda, SIGNAL(lowerYChanged(int)),
00546 SLOT(updateEventIndicatorTop(int)));
00547 connect( mAgenda, SIGNAL(upperYChanged(int)),
00548 SLOT(updateEventIndicatorBottom(int)));
00549
00550 connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
00551 connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
00552 }
00553
00554
00555 KOAgendaView::~KOAgendaView()
00556 {
00557 delete mAgendaPopup;
00558 delete mAllDayAgendaPopup;
00559 }
00560
00561 void KOAgendaView::connectAgenda( KOAgenda *agenda, QPopupMenu *popup,
00562 KOAgenda *otherAgenda )
00563 {
00564 connect( agenda, SIGNAL( showIncidencePopupSignal( Incidence *, const QDate & ) ),
00565 popup, SLOT( showIncidencePopup( Incidence *, const QDate & ) ) );
00566
00567 connect( agenda, SIGNAL( showNewEventPopupSignal() ),
00568 SLOT( showNewEventPopup() ) );
00569
00570 agenda->setCalendar( calendar() );
00571
00572
00573 connect( agenda, SIGNAL( newEventSignal() ), SIGNAL( newEventSignal() ) );
00574
00575 connect( agenda, SIGNAL( newStartSelectSignal() ),
00576 otherAgenda, SLOT( clearSelection() ) );
00577 connect( agenda, SIGNAL( newStartSelectSignal() ),
00578 SIGNAL( timeSpanSelectionChanged()) );
00579
00580 connect( agenda, SIGNAL( editIncidenceSignal( Incidence * ) ),
00581 SIGNAL( editIncidenceSignal( Incidence * ) ) );
00582 connect( agenda, SIGNAL( showIncidenceSignal( Incidence * ) ),
00583 SIGNAL( showIncidenceSignal( Incidence * ) ) );
00584 connect( agenda, SIGNAL( deleteIncidenceSignal( Incidence * ) ),
00585 SIGNAL( deleteIncidenceSignal( Incidence * ) ) );
00586
00587 connect( agenda, SIGNAL( startMultiModify( const QString & ) ),
00588 SIGNAL( startMultiModify( const QString & ) ) );
00589 connect( agenda, SIGNAL( endMultiModify() ),
00590 SIGNAL( endMultiModify() ) );
00591
00592 connect( agenda, SIGNAL( itemModified( KOAgendaItem * ) ),
00593 SLOT( updateEventDates( KOAgendaItem * ) ) );
00594 connect( agenda, SIGNAL( enableAgendaUpdate( bool ) ),
00595 SLOT( enableAgendaUpdate( bool ) ) );
00596
00597
00598 connect( agenda, SIGNAL( startDragSignal( Incidence * ) ),
00599 SLOT( startDrag( Incidence * ) ) );
00600
00601
00602 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00603 otherAgenda, SLOT( deselectItem() ) );
00604 connect( agenda, SIGNAL( incidenceSelected( Incidence * ) ),
00605 SIGNAL( incidenceSelected( Incidence * ) ) );
00606
00607
00608 connect( agenda, SIGNAL( droppedToDo( Todo *, const QPoint &, bool ) ),
00609 SLOT( slotTodoDropped( Todo *, const QPoint &, bool ) ) );
00610
00611 }
00612
00613 void KOAgendaView::zoomInVertically( )
00614 {
00615 KOPrefs::instance()->mHourSize++;
00616 mAgenda->updateConfig();
00617 mAgenda->checkScrollBoundaries();
00618
00619 mTimeLabels->updateConfig();
00620 mTimeLabels->positionChanged();
00621 mTimeLabels->repaint();
00622
00623 updateView();
00624 }
00625
00626 void KOAgendaView::zoomOutVertically( )
00627 {
00628
00629 if ( KOPrefs::instance()->mHourSize > 4 ) {
00630
00631 KOPrefs::instance()->mHourSize--;
00632 mAgenda->updateConfig();
00633 mAgenda->checkScrollBoundaries();
00634
00635 mTimeLabels->updateConfig();
00636 mTimeLabels->positionChanged();
00637 mTimeLabels->repaint();
00638
00639 updateView();
00640 }
00641 }
00642
00643 void KOAgendaView::zoomInHorizontally( const QDate &date)
00644 {
00645 QDate begin;
00646 QDate newBegin;
00647 QDate dateToZoom = date;
00648 int ndays,count;
00649
00650 begin = mSelectedDates.first();
00651 ndays = begin.daysTo( mSelectedDates.last() );
00652
00653
00654 if ( ! dateToZoom.isValid () )
00655 dateToZoom=mAgenda->selectedIncidenceDate();
00656
00657 if( !dateToZoom.isValid() ) {
00658 if ( ndays > 1 ) {
00659 newBegin=begin.addDays(1);
00660 count = ndays-1;
00661 emit zoomViewHorizontally ( newBegin , count );
00662 }
00663 } else {
00664 if ( ndays <= 2 ) {
00665 newBegin = dateToZoom;
00666 count = 1;
00667 } else {
00668 newBegin = dateToZoom.addDays( -ndays/2 +1 );
00669 count = ndays -1 ;
00670 }
00671 emit zoomViewHorizontally ( newBegin , count );
00672 }
00673 }
00674
00675 void KOAgendaView::zoomOutHorizontally( const QDate &date )
00676 {
00677 QDate begin;
00678 QDate newBegin;
00679 QDate dateToZoom = date;
00680 int ndays,count;
00681
00682 begin = mSelectedDates.first();
00683 ndays = begin.daysTo( mSelectedDates.last() );
00684
00685
00686 if ( ! dateToZoom.isValid () )
00687 dateToZoom=mAgenda->selectedIncidenceDate();
00688
00689 if ( !dateToZoom.isValid() ) {
00690 newBegin = begin.addDays(-1);
00691 count = ndays+3 ;
00692 } else {
00693 newBegin = dateToZoom.addDays( -ndays/2-1 );
00694 count = ndays+3;
00695 }
00696
00697 if ( abs( count ) >= 31 )
00698 kdDebug(5850) << "change to the mounth view?"<<endl;
00699 else
00700
00701 emit zoomViewHorizontally( newBegin, count );
00702 }
00703
00704 void KOAgendaView::zoomView( const int delta, const QPoint &pos,
00705 const Qt::Orientation orient )
00706 {
00707 static QDate zoomDate;
00708 static QTimer t( this );
00709
00710
00711
00712
00713 if ( orient == Qt::Horizontal ) {
00714 QDate date=mAgenda->selectedIncidenceDate();
00715 if ( date.isValid() )
00716 zoomDate=date;
00717 else{
00718 if ( !t.isActive() ) {
00719 zoomDate= mSelectedDates[pos.x()];
00720 }
00721 t.start ( 1000,true );
00722 }
00723 if ( delta > 0 )
00724 zoomOutHorizontally( zoomDate );
00725 else
00726 zoomInHorizontally( zoomDate );
00727 } else {
00728
00729 QPoint posConstentsOld = mAgenda->gridToContents(pos);
00730 if ( delta > 0 ) {
00731 zoomOutVertically();
00732 } else {
00733 zoomInVertically();
00734 }
00735 QPoint posConstentsNew = mAgenda->gridToContents(pos);
00736 mAgenda->scrollBy( 0, posConstentsNew.y() - posConstentsOld.y() );
00737 }
00738 }
00739
00740 void KOAgendaView::createDayLabels()
00741 {
00742
00743
00744
00745
00746
00747 delete mDayLabels;
00748
00749 mDayLabels = new QFrame (mDayLabelsFrame);
00750 mLayoutDayLabels = new QHBoxLayout(mDayLabels);
00751 mLayoutDayLabels->addSpacing(mTimeLabels->width());
00752
00753 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
00754
00755 DateList::ConstIterator dit;
00756 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
00757 QDate date = *dit;
00758 QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels);
00759 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
00760
00761
00762 int dW = calsys->dayOfWeek(date);
00763 QString veryLongStr = KGlobal::locale()->formatDate( date );
00764 QString longstr = i18n( "short_weekday date (e.g. Mon 13)","%1 %2" )
00765 .arg( calsys->weekDayName( dW, true ) )
00766 .arg( calsys->day(date) );
00767 QString shortstr = QString::number(calsys->day(date));
00768
00769 KOAlternateLabel *dayLabel = new KOAlternateLabel(shortstr,
00770 longstr, veryLongStr, mDayLabels);
00771 dayLabel->setMinimumWidth(1);
00772 dayLabel->setAlignment(QLabel::AlignHCenter);
00773 if (date == QDate::currentDate()) {
00774 QFont font = dayLabel->font();
00775 font.setBold(true);
00776 dayLabel->setFont(font);
00777 }
00778 dayLayout->addWidget(dayLabel);
00779
00780
00781 QStringList texts = KOGlobals::self()->holiday( date );
00782 QStringList::ConstIterator textit = texts.begin();
00783 for ( ; textit != texts.end(); ++textit ) {
00784
00785 KOAlternateLabel*label = new KOAlternateLabel( (*textit), (*textit), QString::null, mDayLabels );
00786 label->setMinimumWidth(1);
00787 label->setAlignment(AlignCenter);
00788 dayLayout->addWidget(label);
00789 }
00790
00791 #ifndef KORG_NOPLUGINS
00792 CalendarDecoration::List cds = KOCore::self()->calendarDecorations();
00793 CalendarDecoration *it;
00794 for(it = cds.first(); it; it = cds.next()) {
00795 QString text = it->shortText( date );
00796 if ( !text.isEmpty() ) {
00797
00798 KOAlternateLabel*label = new KOAlternateLabel( text, text, QString::null, mDayLabels );
00799 label->setMinimumWidth(1);
00800 label->setAlignment(AlignCenter);
00801 dayLayout->addWidget(label);
00802 }
00803 }
00804
00805 for(it = cds.first(); it; it = cds.next()) {
00806 QWidget *wid = it->smallWidget(mDayLabels,date);
00807 if ( wid ) {
00808
00809 dayLayout->addWidget(wid);
00810 }
00811 }
00812 #endif
00813 }
00814
00815 mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
00816 mDayLabels->show();
00817 }
00818
00819 void KOAgendaView::enableAgendaUpdate( bool enable )
00820 {
00821 mAllowAgendaUpdate = enable;
00822 }
00823
00824 int KOAgendaView::maxDatesHint()
00825 {
00826
00827 return 0;
00828 }
00829
00830 int KOAgendaView::currentDateCount()
00831 {
00832 return mSelectedDates.count();
00833 }
00834
00835 Incidence::List KOAgendaView::selectedIncidences()
00836 {
00837 Incidence::List selected;
00838 Incidence *incidence;
00839
00840 incidence = mAgenda->selectedIncidence();
00841 if (incidence) selected.append(incidence);
00842
00843 incidence = mAllDayAgenda->selectedIncidence();
00844 if (incidence) selected.append(incidence);
00845
00846 return selected;
00847 }
00848
00849 DateList KOAgendaView::selectedDates()
00850 {
00851 DateList selected;
00852 QDate qd;
00853
00854 qd = mAgenda->selectedIncidenceDate();
00855 if (qd.isValid()) selected.append(qd);
00856
00857 qd = mAllDayAgenda->selectedIncidenceDate();
00858 if (qd.isValid()) selected.append(qd);
00859
00860 return selected;
00861 }
00862
00863 bool KOAgendaView::eventDurationHint( QDateTime &startDt, QDateTime &endDt,
00864 bool &allDay )
00865 {
00866 if ( selectionStart().isValid() ) {
00867 QDateTime start = selectionStart();
00868 QDateTime end = selectionEnd();
00869
00870 if ( start.secsTo( end ) == 15*60 ) {
00871
00872
00873 QTime defaultDuration( KOPrefs::instance()->mDefaultDuration.time() );
00874 int addSecs = ( defaultDuration.hour()*3600 ) +
00875 ( defaultDuration.minute()*60 );
00876 end = start.addSecs( addSecs );
00877 }
00878
00879 startDt = start;
00880 endDt = end;
00881 allDay = selectedIsAllDay();
00882 return true;
00883 }
00884 return false;
00885 }
00886
00888 bool KOAgendaView::selectedIsSingleCell()
00889 {
00890 if ( !selectionStart().isValid() || !selectionEnd().isValid() ) return false;
00891
00892 if (selectedIsAllDay()) {
00893 int days = selectionStart().daysTo(selectionEnd());
00894 return ( days < 1 );
00895 } else {
00896 int secs = selectionStart().secsTo(selectionEnd());
00897 return ( secs <= 24*60*60/mAgenda->rows() );
00898 }
00899 }
00900
00901
00902 void KOAgendaView::updateView()
00903 {
00904
00905 fillAgenda();
00906 }
00907
00908
00909
00910
00911
00912
00913 void KOAgendaView::updateConfig()
00914 {
00915
00916
00917
00918 mTimeLabels->updateConfig();
00919 mAgenda->updateConfig();
00920 mAllDayAgenda->updateConfig();
00921
00922
00923
00924 mTimeLabels->positionChanged();
00925
00926
00927 mTimeLabels->repaint();
00928
00929 updateTimeBarWidth();
00930
00931
00932 KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance()
00933 ->mEnableToolTips);
00934
00935 setHolidayMasks();
00936
00937 createDayLabels();
00938
00939 updateView();
00940 }
00941
00942 void KOAgendaView::updateTimeBarWidth()
00943 {
00944 int width;
00945
00946 width = mDummyAllDayLeft->fontMetrics().width( i18n("All Day") );
00947 width = QMAX( width, mTimeLabels->width() );
00948
00949 mDummyAllDayLeft->setFixedWidth( width );
00950 mTimeLabels->setFixedWidth( width );
00951 }
00952
00953
00954 void KOAgendaView::updateEventDates( KOAgendaItem *item )
00955 {
00956 kdDebug(5850) << "KOAgendaView::updateEventDates(): " << item->text() << endl;
00957
00958 QDateTime startDt,endDt;
00959
00960
00961
00962
00963
00964 QDate thisDate;
00965 if ( item->cellXLeft() < 0 ) {
00966 thisDate = ( mSelectedDates.first() ).addDays( item->cellXLeft() );
00967 } else {
00968 thisDate = mSelectedDates[ item->cellXLeft() ];
00969 }
00970 QDate oldThisDate( item->itemDate() );
00971 int daysOffset = oldThisDate.daysTo( thisDate );
00972 int daysLength = 0;
00973
00974
00975
00976 Incidence *incidence = item->incidence();
00977 if ( !incidence ) return;
00978 if ( !mChanger || !mChanger->beginChange(incidence) ) return;
00979 Incidence *oldIncidence = incidence->clone();
00980
00981 QTime startTime(0,0,0), endTime(0,0,0);
00982 if ( incidence->doesFloat() ) {
00983 daysLength = item->cellWidth() - 1;
00984 } else {
00985 startTime = mAgenda->gyToTime( item->cellYTop() );
00986 if ( item->lastMultiItem() ) {
00987 endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
00988 daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
00989 } else {
00990 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
00991 }
00992 }
00993
00994
00995
00996 if ( incidence->type() == "Event" ) {
00997 startDt = incidence->dtStart();
00998 startDt = startDt.addDays( daysOffset );
00999 startDt.setTime( startTime );
01000 endDt = startDt.addDays( daysLength );
01001 endDt.setTime( endTime );
01002 Event*ev = static_cast<Event*>(incidence);
01003 if( incidence->dtStart() == startDt && ev->dtEnd() == endDt ) {
01004
01005 delete oldIncidence;
01006 return;
01007 }
01008 incidence->setDtStart( startDt );
01009 ev->setDtEnd( endDt );
01010 } else if ( incidence->type() == "Todo" ) {
01011 Todo *td = static_cast<Todo*>(incidence);
01012 startDt = td->hasStartDate() ? td->dtStart() : td->dtDue();
01013 startDt = thisDate.addDays( td->dtDue().daysTo( startDt ) );
01014 startDt.setTime( startTime );
01015 endDt.setDate( thisDate );
01016 endDt.setTime( endTime );
01017
01018 if( td->dtDue() == endDt ) {
01019
01020 delete oldIncidence;
01021 return;
01022 }
01023 }
01024
01025
01026
01027
01028 Recurrence *recur = incidence->recurrence();
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
01168
01169
01170 if ( incidence->type() == "Event" ) {
01171 incidence->setDtStart( startDt );
01172 (static_cast<Event*>( incidence ) )->setDtEnd( endDt );
01173 } else if ( incidence->type() == "Todo" ) {
01174 Todo *td = static_cast<Todo*>( incidence );
01175 if ( td->hasStartDate() )
01176 td->setDtStart( startDt );
01177 td->setDtDue( endDt );
01178 }
01179
01180 item->setItemDate( startDt.date() );
01181
01182 KOIncidenceToolTip::remove( item );
01183 KOIncidenceToolTip::add( item, incidence, KOAgendaItem::toolTipGroup() );
01184
01185 mChanger->changeIncidence( oldIncidence, incidence );
01186 mChanger->endChange(incidence);
01187 delete oldIncidence;
01188
01189
01190
01191
01192 enableAgendaUpdate( false );
01193
01194
01195
01196
01197 if ( incidence->doesRecur() ) {
01198 mUpdateItem = incidence;
01199 QTimer::singleShot( 0, this, SLOT( doUpdateItem() ) );
01200 }
01201
01202 enableAgendaUpdate( true );
01203
01204
01205 }
01206
01207 void KOAgendaView::doUpdateItem()
01208 {
01209 if ( mUpdateItem ) {
01210 changeIncidenceDisplay( mUpdateItem, KOGlobals::INCIDENCEEDITED );
01211 mUpdateItem = 0;
01212 }
01213 }
01214
01215
01216
01217 void KOAgendaView::showDates( const QDate &start, const QDate &end )
01218 {
01219
01220
01221 mSelectedDates.clear();
01222
01223 QDate d = start;
01224 while (d <= end) {
01225 mSelectedDates.append(d);
01226 d = d.addDays( 1 );
01227 }
01228
01229
01230 fillAgenda();
01231 }
01232
01233
01234 void KOAgendaView::showIncidences( const Incidence::List & )
01235 {
01236 kdDebug(5850) << "KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
01237 }
01238
01239 void KOAgendaView::insertIncidence( Incidence *incidence, const QDate &curDate,
01240 int curCol )
01241 {
01242 if ( !filterByResource( incidence ) )
01243 return;
01244
01245
01246 Event *event = dynamic_cast<Event *>( incidence );
01247 Todo *todo = dynamic_cast<Todo *>( incidence );
01248
01249 if ( curCol < 0 ) {
01250 curCol = mSelectedDates.findIndex( curDate );
01251 }
01252
01253 if ( curCol < 0 || curCol > int( mSelectedDates.size() ) )
01254 return;
01255
01256 int beginX;
01257 int endX;
01258 if ( event ) {
01259 beginX = curDate.daysTo( incidence->dtStart().date() ) + curCol;
01260 endX = curDate.daysTo( event->dateEnd() ) + curCol;
01261 } else if ( todo ) {
01262 if ( ! todo->hasDueDate() ) return;
01263 beginX = curDate.daysTo( todo->dtDue().date() ) + curCol;
01264 endX = beginX;
01265 } else {
01266 return;
01267 }
01268
01269 if ( todo && todo->isOverdue() ) {
01270 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01271 } else if ( incidence->doesFloat() ) {
01272
01273 if ( incidence->recurrence()->doesRecur() ) {
01274 mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
01275 } else {
01276
01277
01278 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
01279 mAllDayAgenda->insertAllDayItem( incidence, curDate, beginX, endX );
01280 }
01281 }
01282 } else if ( event && event->isMultiDay() ) {
01283 int startY = mAgenda->timeToY( event->dtStart().time() );
01284 QTime endtime( event->dtEnd().time() );
01285 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01286 int endY = mAgenda->timeToY( endtime ) - 1;
01287 if ( (beginX <= 0 && curCol == 0) || beginX == curCol ) {
01288 mAgenda->insertMultiItem( event, curDate, beginX, endX, startY, endY );
01289 }
01290 if ( beginX == curCol ) {
01291 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01292 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01293 } else if ( endX == curCol ) {
01294 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01295 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01296 } else {
01297 mMinY[curCol] = mAgenda->timeToY( QTime(0,0) );
01298 mMaxY[curCol] = mAgenda->timeToY( QTime(23,59) );
01299 }
01300 } else {
01301 int startY = 0, endY = 0;
01302 if ( event ) {
01303 startY = mAgenda->timeToY( incidence->dtStart().time() );
01304 QTime endtime( event->dtEnd().time() );
01305 if ( endtime == QTime( 0, 0, 0 ) ) endtime = QTime( 23, 59, 59 );
01306 endY = mAgenda->timeToY( endtime ) - 1;
01307 }
01308 if ( todo ) {
01309 QTime t = todo->dtDue().time();
01310 endY = mAgenda->timeToY( t ) - 1;
01311 startY = mAgenda->timeToY( t.addSecs( -1800 ) );
01312 }
01313 if ( endY < startY ) endY = startY;
01314 mAgenda->insertItem( incidence, curDate, curCol, startY, endY );
01315 if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
01316 if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
01317 }
01318 }
01319
01320 void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
01321 {
01322 Todo *todo = dynamic_cast<Todo *>(incidence);
01323 CalFilter *filter = calendar()->filter();
01324 if ( filter && !filter->filterIncidence( incidence ) ||
01325 ( todo && !KOPrefs::instance()->showAllDayTodo() ) )
01326 return;
01327
01328 QDate f = mSelectedDates.first();
01329 QDate l = mSelectedDates.last();
01330 QDate startDt = incidence->dtStart().date();
01331
01332 if ( incidence->doesRecur() ) {
01333 DateList::ConstIterator dit;
01334 QDate curDate;
01335 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01336 curDate = *dit;
01337
01338 if ( incidence->recursOn( curDate ) ) {
01339 insertIncidence( incidence, curDate );
01340 }
01341 }
01342 return;
01343 }
01344
01345 QDate endDt;
01346 if ( incidence->type() == "Event" )
01347 endDt = (static_cast<Event *>(incidence))->dateEnd();
01348 if ( todo ) {
01349 endDt = todo->isOverdue() ? QDate::currentDate()
01350 : todo->dtDue().date();
01351
01352 if ( endDt >= f && endDt <= l ) {
01353 insertIncidence( incidence, endDt );
01354 return;
01355 }
01356 }
01357
01358 if ( startDt >= f && startDt <= l ) {
01359 insertIncidence( incidence, startDt );
01360 }
01361 }
01362
01363 void KOAgendaView::changeIncidenceDisplay( Incidence *incidence, int mode )
01364 {
01365 switch ( mode ) {
01366 case KOGlobals::INCIDENCEADDED: {
01367
01368
01369
01370
01371 if ( mAllowAgendaUpdate )
01372 changeIncidenceDisplayAdded( incidence );
01373 break;
01374 }
01375 case KOGlobals::INCIDENCEEDITED: {
01376 if ( !mAllowAgendaUpdate ) {
01377 updateEventIndicators();
01378 } else {
01379 removeIncidence( incidence );
01380 updateEventIndicators();
01381 changeIncidenceDisplayAdded( incidence );
01382 }
01383 break;
01384 }
01385 case KOGlobals::INCIDENCEDELETED: {
01386 mAgenda->removeIncidence( incidence );
01387 mAllDayAgenda->removeIncidence( incidence );
01388 updateEventIndicators();
01389 break;
01390 }
01391 default:
01392 updateView();
01393 }
01394 }
01395
01396 void KOAgendaView::fillAgenda( const QDate & )
01397 {
01398 fillAgenda();
01399 }
01400
01401 void KOAgendaView::fillAgenda()
01402 {
01403
01404
01405 const QString &selectedAgendaUid = mAgenda->lastSelectedUid();
01406 const QString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
01407
01408 enableAgendaUpdate( true );
01409 clearView();
01410
01411 mAllDayAgenda->changeColumns(mSelectedDates.count());
01412 mAgenda->changeColumns(mSelectedDates.count());
01413 mEventIndicatorTop->changeColumns(mSelectedDates.count());
01414 mEventIndicatorBottom->changeColumns(mSelectedDates.count());
01415
01416 createDayLabels();
01417 setHolidayMasks();
01418
01419 mMinY.resize(mSelectedDates.count());
01420 mMaxY.resize(mSelectedDates.count());
01421
01422 Event::List dayEvents;
01423
01424
01425
01426 Todo::List todos = calendar()->todos();
01427
01428 mAgenda->setDateList(mSelectedDates);
01429
01430 QDate today = QDate::currentDate();
01431
01432 bool somethingReselected = false;
01433 DateList::ConstIterator dit;
01434 int curCol = 0;
01435 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
01436 QDate currentDate = *dit;
01437
01438
01439
01440 dayEvents = calendar()->events(currentDate,
01441 EventSortStartDate,
01442 SortDirectionAscending);
01443
01444
01445 mMinY[curCol] = mAgenda->timeToY(QTime(23,59)) + 1;
01446 mMaxY[curCol] = mAgenda->timeToY(QTime(0,0)) - 1;
01447
01448 unsigned int numEvent;
01449 for(numEvent=0;numEvent<dayEvents.count();++numEvent) {
01450 Event *event = *dayEvents.at(numEvent);
01451
01452 insertIncidence( event, currentDate, curCol );
01453 if( event->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
01454 mAgenda->selectItemByUID( event->uid() );
01455 somethingReselected = true;
01456 }
01457 if( event->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
01458 mAllDayAgenda->selectItemByUID( event->uid() );
01459 somethingReselected = true;
01460 }
01461
01462 }
01463
01464
01465
01466
01467 if ( KOPrefs::instance()->showAllDayTodo() ) {
01468 unsigned int numTodo;
01469 for (numTodo = 0; numTodo < todos.count(); ++numTodo) {
01470 Todo *todo = *todos.at(numTodo);
01471
01472 if ( ! todo->hasDueDate() ) continue;
01473
01474 if ( !filterByResource( todo ) ) continue;
01475
01476
01477
01478 bool overdue = todo->isOverdue();
01479
01480 if ( (( todo->dtDue().date() == currentDate) && !overdue) ||
01481 (( currentDate == today) && overdue) ||
01482 ( todo->recursOn( currentDate ) ) ) {
01483 if ( todo->doesFloat() || overdue ) {
01484
01485
01486 mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol);
01487 } else {
01488
01489
01490 int endY = mAgenda->timeToY(todo->dtDue().time()) - 1;
01491 int startY = endY - 1;
01492
01493 mAgenda->insertItem(todo,currentDate,curCol,startY,endY);
01494
01495 if (startY < mMinY[curCol]) mMinY[curCol] = startY;
01496 if (endY > mMaxY[curCol]) mMaxY[curCol] = endY;
01497 }
01498 }
01499 }
01500 }
01501
01502
01503 ++curCol;
01504 }
01505
01506 mAgenda->checkScrollBoundaries();
01507 updateEventIndicators();
01508
01509
01510
01511
01512
01513 deleteSelectedDateTime();
01514
01515 if( !somethingReselected ) {
01516 emit incidenceSelected( 0 );
01517 }
01518
01519
01520 }
01521
01522 void KOAgendaView::clearView()
01523 {
01524
01525 mAllDayAgenda->clear();
01526 mAgenda->clear();
01527 }
01528
01529 CalPrinterBase::PrintType KOAgendaView::printType()
01530 {
01531 if ( currentDateCount() == 1 ) return CalPrinterBase::Day;
01532 else return CalPrinterBase::Week;
01533 }
01534
01535 void KOAgendaView::updateEventIndicatorTop( int newY )
01536 {
01537 uint i;
01538 for( i = 0; i < mMinY.size(); ++i ) {
01539 mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
01540 }
01541 mEventIndicatorTop->update();
01542 }
01543
01544 void KOAgendaView::updateEventIndicatorBottom( int newY )
01545 {
01546 uint i;
01547 for( i = 0; i < mMaxY.size(); ++i ) {
01548 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
01549 }
01550 mEventIndicatorBottom->update();
01551 }
01552
01553 void KOAgendaView::slotTodoDropped( Todo *todo, const QPoint &gpos, bool allDay )
01554 {
01555 if ( gpos.x()<0 || gpos.y()<0 ) return;
01556 QDate day = mSelectedDates[gpos.x()];
01557 QTime time = mAgenda->gyToTime( gpos.y() );
01558 QDateTime newTime( day, time );
01559
01560 if ( todo ) {
01561 Todo *existingTodo = calendar()->todo( todo->uid() );
01562 if ( existingTodo ) {
01563 kdDebug(5850) << "Drop existing Todo" << endl;
01564 Todo *oldTodo = existingTodo->clone();
01565 if ( mChanger && mChanger->beginChange( existingTodo ) ) {
01566 existingTodo->setDtDue( newTime );
01567 existingTodo->setFloats( allDay );
01568 existingTodo->setHasDueDate( true );
01569 mChanger->changeIncidence( oldTodo, existingTodo );
01570 mChanger->endChange( existingTodo );
01571 } else {
01572 KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
01573 "because it cannot be locked.") );
01574 }
01575 delete oldTodo;
01576 } else {
01577 kdDebug(5850) << "Drop new Todo" << endl;
01578 todo->setDtDue( newTime );
01579 todo->setFloats( allDay );
01580 todo->setHasDueDate( true );
01581 if ( !mChanger->addIncidence( todo, this ) ) {
01582 KODialogManager::errorSaveIncidence( this, todo );
01583 }
01584 }
01585 }
01586 }
01587
01588 void KOAgendaView::startDrag( Incidence *incidence )
01589 {
01590 #ifndef KORG_NODND
01591 DndFactory factory( calendar() );
01592 ICalDrag *vd = factory.createDrag( incidence, this );
01593 if ( vd->drag() ) {
01594 kdDebug(5850) << "KOAgendaView::startDrag(): Delete drag source" << endl;
01595 }
01596 #endif
01597 }
01598
01599 void KOAgendaView::readSettings()
01600 {
01601 readSettings(KOGlobals::self()->config());
01602 }
01603
01604 void KOAgendaView::readSettings(KConfig *config)
01605 {
01606
01607
01608 config->setGroup("Views");
01609
01610 #ifndef KORG_NOSPLITTER
01611 QValueList<int> sizes = config->readIntListEntry("Separator AgendaView");
01612 if (sizes.count() == 2) {
01613 mSplitterAgenda->setSizes(sizes);
01614 }
01615 #endif
01616
01617 updateConfig();
01618 }
01619
01620 void KOAgendaView::writeSettings(KConfig *config)
01621 {
01622
01623
01624 config->setGroup("Views");
01625
01626 #ifndef KORG_NOSPLITTER
01627 QValueList<int> list = mSplitterAgenda->sizes();
01628 config->writeEntry("Separator AgendaView",list);
01629 #endif
01630 }
01631
01632 void KOAgendaView::setHolidayMasks()
01633 {
01634 mHolidayMask.resize( mSelectedDates.count() + 1 );
01635
01636 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
01637 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
01638 }
01639
01640
01641
01642 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
01643 mHolidayMask[ mSelectedDates.count() ] = showDay;
01644
01645 mAgenda->setHolidayMask( &mHolidayMask );
01646 mAllDayAgenda->setHolidayMask( &mHolidayMask );
01647 }
01648
01649 void KOAgendaView::setContentsPos( int y )
01650 {
01651 mAgenda->setContentsPos( 0, y );
01652 }
01653
01654 void KOAgendaView::setExpandedButton( bool expanded )
01655 {
01656 if ( !mExpandButton ) return;
01657
01658 if ( expanded ) {
01659 mExpandButton->setPixmap( mExpandedPixmap );
01660 } else {
01661 mExpandButton->setPixmap( mNotExpandedPixmap );
01662 }
01663 }
01664
01665 void KOAgendaView::clearSelection()
01666 {
01667 mAgenda->deselectItem();
01668 mAllDayAgenda->deselectItem();
01669 }
01670
01671 void KOAgendaView::newTimeSpanSelectedAllDay( const QPoint &start, const QPoint &end )
01672 {
01673 newTimeSpanSelected( start, end );
01674 mTimeSpanInAllDay = true;
01675 }
01676
01677 void KOAgendaView::newTimeSpanSelected( const QPoint &start, const QPoint &end )
01678 {
01679 if (!mSelectedDates.count()) return;
01680
01681 mTimeSpanInAllDay = false;
01682
01683 QDate dayStart = mSelectedDates[start.x()];
01684 QDate dayEnd = mSelectedDates[end.x()];
01685
01686 QTime timeStart = mAgenda->gyToTime(start.y());
01687 QTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
01688
01689 QDateTime dtStart(dayStart,timeStart);
01690 QDateTime dtEnd(dayEnd,timeEnd);
01691
01692 mTimeSpanBegin = dtStart;
01693 mTimeSpanEnd = dtEnd;
01694 }
01695
01696 void KOAgendaView::deleteSelectedDateTime()
01697 {
01698 mTimeSpanBegin.setDate(QDate());
01699 mTimeSpanEnd.setDate(QDate());
01700 mTimeSpanInAllDay = false;
01701 }
01702
01703 void KOAgendaView::setTypeAheadReceiver( QObject *o )
01704 {
01705 mAgenda->setTypeAheadReceiver( o );
01706 mAllDayAgenda->setTypeAheadReceiver( o );
01707 }
01708
01709 void KOAgendaView::finishTypeAhead()
01710 {
01711 mAgenda->finishTypeAhead();
01712 mAllDayAgenda->finishTypeAhead();
01713 }
01714
01715 void KOAgendaView::removeIncidence( Incidence *incidence )
01716 {
01717 mAgenda->removeIncidence( incidence );
01718 mAllDayAgenda->removeIncidence( incidence );
01719 }
01720
01721 void KOAgendaView::updateEventIndicators()
01722 {
01723 mMinY = mAgenda->minContentsY();
01724 mMaxY = mAgenda->maxContentsY();
01725
01726 mAgenda->checkScrollBoundaries();
01727 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
01728 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
01729 }
01730
01731 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
01732 {
01733 mChanger = changer;
01734 mAgenda->setIncidenceChanger( changer );
01735 mAllDayAgenda->setIncidenceChanger( changer );
01736 }
01737
01738 void KOAgendaView::clearTimeSpanSelection()
01739 {
01740 mAgenda->clearSelection();
01741 mAllDayAgenda->clearSelection();
01742 deleteSelectedDateTime();
01743 }
01744
01745 void KOAgendaView::setResource(KCal::ResourceCalendar * res, const QString & subResource)
01746 {
01747 mResource = res;
01748 mSubResource = subResource;
01749 }
01750
01751 bool KOAgendaView::filterByResource(Incidence * incidence)
01752 {
01753 if ( !mResource )
01754 return true;
01755 CalendarResources *calRes = dynamic_cast<CalendarResources*>( calendar() );
01756 if ( !calRes )
01757 return true;
01758 if ( calRes->resource( incidence ) != mResource )
01759 return false;
01760 if ( !mSubResource.isEmpty() ) {
01761 if ( mResource->subresourceIdentifier( incidence ) != mSubResource )
01762 return false;
01763 }
01764 return true;
01765 }