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
00026
00027 #include <assert.h>
00028
00029 #include <qintdict.h>
00030 #include <qdatetime.h>
00031 #include <qapplication.h>
00032 #include <qpopupmenu.h>
00033 #include <qcursor.h>
00034 #include <qpainter.h>
00035 #include <qlabel.h>
00036
00037 #include <kdebug.h>
00038 #include <klocale.h>
00039 #include <kiconloader.h>
00040 #include <kglobal.h>
00041 #include <kmessagebox.h>
00042
00043 #include "koagendaitem.h"
00044 #include "koprefs.h"
00045 #include "koglobals.h"
00046 #include "komessagebox.h"
00047 #include "incidencechanger.h"
00048 #include "kohelper.h"
00049
00050 #include "koagendaview.h"
00051 #include "koagenda.h"
00052 #include "koagenda.moc"
00053 #include <korganizer/baseview.h>
00054
00055 #include <libkcal/event.h>
00056 #include <libkcal/todo.h>
00057 #include <libkcal/dndfactory.h>
00058 #include <libkcal/icaldrag.h>
00059 #include <libkcal/vcaldrag.h>
00060 #include <libkcal/calendar.h>
00061 #include <libkcal/calendarresources.h>
00062 #include <libkcal/calhelper.h>
00063 #include <math.h>
00064
00065 static void freeItemList( const AgendaItemList &list )
00066 {
00067 AgendaItemList::ConstIterator it;
00068 for ( it = list.begin(); it != list.end(); ++it ) {
00069 delete static_cast<KOAgendaItem*>( *it );
00070 }
00071 }
00072
00074 MarcusBains::MarcusBains(KOAgenda *_agenda,const char *name )
00075 : QFrame(_agenda->viewport(), name), agenda(_agenda)
00076 {
00077 setLineWidth(0);
00078 setMargin(0);
00079 setBackgroundColor(Qt::red);
00080 minutes = new QTimer(this);
00081 connect(minutes, SIGNAL(timeout()), this, SLOT(updateLocation()));
00082 minutes->start(0, true);
00083
00084 mTimeBox = new QLabel(this);
00085 mTimeBox->setAlignment(Qt::AlignRight | Qt::AlignBottom);
00086 QPalette pal = mTimeBox->palette();
00087 pal.setColor(QColorGroup::Foreground, Qt::red);
00088 mTimeBox->setPalette(pal);
00089 mTimeBox->setAutoMask(true);
00090
00091 agenda->addChild(mTimeBox);
00092
00093 mOldTime = QTime( 0, 0 );
00094 mOldToday = -1;
00095 }
00096
00097 MarcusBains::~MarcusBains()
00098 {
00099 delete minutes;
00100 }
00101
00102 int MarcusBains::todayColumn()
00103 {
00104 QDate currentDate = QDate::currentDate();
00105
00106 DateList dateList = agenda->dateList();
00107 DateList::ConstIterator it;
00108 int col = 0;
00109 for(it = dateList.begin(); it != dateList.end(); ++it) {
00110 if((*it) == currentDate)
00111 return KOGlobals::self()->reverseLayout() ?
00112 agenda->columns() - 1 - col : col;
00113 ++col;
00114 }
00115
00116 return -1;
00117 }
00118
00119 void MarcusBains::updateLocation()
00120 {
00121 updateLocationRecalc();
00122 }
00123
00124 void MarcusBains::updateLocationRecalc( bool recalculate )
00125 {
00126 QTime tim = QTime::currentTime();
00127 if((tim.hour() == 0) && (mOldTime.hour()==23))
00128 recalculate = true;
00129
00130 const int mins = tim.hour()*60 + tim.minute();
00131 const int minutesPerCell = 24 * 60 / agenda->rows();
00132 int y = int( mins * agenda->gridSpacingY() / minutesPerCell );
00133 const int today = recalculate ? todayColumn() : mOldToday;
00134 int x = int( agenda->gridSpacingX() * today );
00135
00136 mOldTime = tim;
00137 mOldToday = today;
00138
00139 const bool hideIt = !( KOPrefs::instance()->mMarcusBainsEnabled );
00140
00141 if ( !isHidden() && ( hideIt || ( today < 0 ) ) ) {
00142 hide();
00143 mTimeBox->hide();
00144 return;
00145 }
00146
00147 if ( isHidden() && !hideIt ) {
00148 show();
00149 mTimeBox->show();
00150 }
00151
00152 if ( recalculate ) setFixedSize( int( agenda->gridSpacingX() ), 1 );
00153 agenda->moveChild( this, x, y );
00154 raise();
00155
00156 if(recalculate)
00157 mTimeBox->setFont(KOPrefs::instance()->mMarcusBainsFont);
00158
00159 QString timeStr = KGlobal::locale()->formatTime(tim, KOPrefs::instance()->mMarcusBainsShowSeconds);
00160 QFontMetrics fm = fontMetrics();
00161 mTimeBox->setText( timeStr );
00162 const QSize sz( fm.width( timeStr + ' ' ), fm.height() );
00163 mTimeBox->setFixedSize( sz );
00164
00165 if (y-mTimeBox->height()>=0) y-=mTimeBox->height(); else y++;
00166 if (x-mTimeBox->width()+agenda->gridSpacingX() > 0)
00167 x += int( agenda->gridSpacingX() - mTimeBox->width() - 1 );
00168 else x++;
00169 agenda->moveChild(mTimeBox,x,y);
00170 mTimeBox->raise();
00171 mTimeBox->setAutoMask(true);
00172
00173 minutes->start(1000,true);
00174 }
00175
00176
00178
00179
00180
00181
00182
00183 KOAgenda::KOAgenda( int columns, int rows, int rowSize, CalendarView *calendarView,
00184 KOAgendaView *agendaView, QWidget *parent, const char *name,
00185 WFlags f )
00186 : QScrollView( parent, name, f ), mChanger( 0 ), mAgendaView( agendaView )
00187 {
00188 mColumns = columns;
00189 mRows = rows;
00190 mGridSpacingY = rowSize;
00191 if ( mGridSpacingY < 4 || mGridSpacingY > 30 ) {
00192 mGridSpacingY = 10;
00193 }
00194
00195 mCalendarView = calendarView;
00196
00197 mAllDayMode = false;
00198
00199 init();
00200
00201 viewport()->setMouseTracking(true);
00202 }
00203
00204
00205
00206
00207
00208 KOAgenda::KOAgenda( int columns, CalendarView *calendarView, KOAgendaView *agendaView,
00209 QWidget *parent, const char *name,
00210 WFlags f ) : QScrollView( parent, name, f ), mAgendaView( agendaView )
00211 {
00212 mColumns = columns;
00213 mRows = 1;
00214 mGridSpacingY = 24;
00215 mAllDayMode = true;
00216 mCalendarView = calendarView;
00217 setVScrollBarMode( AlwaysOff );
00218
00219 init();
00220 }
00221
00222
00223 KOAgenda::~KOAgenda()
00224 {
00225 delete mMarcusBains;
00226 }
00227
00228
00229 Incidence *KOAgenda::selectedIncidence() const
00230 {
00231 return ( mSelectedItem ? mSelectedItem->incidence() : 0 );
00232 }
00233
00234
00235 QDate KOAgenda::selectedIncidenceDate() const
00236 {
00237 return ( mSelectedItem ? mSelectedItem->itemDate() : QDate() );
00238 }
00239
00240 const QString KOAgenda::lastSelectedUid() const
00241 {
00242 return mSelectedUid;
00243 }
00244
00245
00246 void KOAgenda::init()
00247 {
00248 mGridSpacingX = 100;
00249 mDesiredGridSpacingY = KOPrefs::instance()->mHourSize;
00250 if ( mDesiredGridSpacingY < 4 || mDesiredGridSpacingY > 30 ) {
00251 mDesiredGridSpacingY = 10;
00252 }
00253
00254
00255 mGridSpacingY = (double)height() / (double)mRows;
00256 if ( mGridSpacingY < mDesiredGridSpacingY ) {
00257 mGridSpacingY = mDesiredGridSpacingY;
00258 }
00259
00260 mResizeBorderWidth = 8;
00261 mScrollBorderWidth = 8;
00262 mScrollDelay = 30;
00263 mScrollOffset = 10;
00264
00265 enableClipper( true );
00266
00267
00268
00269 setFocusPolicy( WheelFocus );
00270
00271 connect( &mScrollUpTimer, SIGNAL( timeout() ), SLOT( scrollUp() ) );
00272 connect( &mScrollDownTimer, SIGNAL( timeout() ), SLOT( scrollDown() ) );
00273
00274 mStartCell = QPoint( 0, 0 );
00275 mEndCell = QPoint( 0, 0 );
00276
00277 mHasSelection = false;
00278 mSelectionStartPoint = QPoint( 0, 0 );
00279 mSelectionStartCell = QPoint( 0, 0 );
00280 mSelectionEndCell = QPoint( 0, 0 );
00281
00282 mOldLowerScrollValue = -1;
00283 mOldUpperScrollValue = -1;
00284
00285 mClickedItem = 0;
00286
00287 mActionItem = 0;
00288 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00289 mActionType = NOP;
00290 mItemMoved = false;
00291
00292 mSelectedItem = 0;
00293 mSelectedUid = QString::null;
00294
00295 setAcceptDrops( true );
00296 installEventFilter( this );
00297
00298 resizeContents( int( mGridSpacingX * mColumns ),
00299 int( mGridSpacingY * mRows ) );
00300
00301 viewport()->update();
00302 viewport()->setBackgroundMode( NoBackground );
00303 viewport()->setFocusPolicy( WheelFocus );
00304
00305 setMinimumSize( 30, int( mGridSpacingY + 1 ) );
00306
00307
00308
00309
00310
00311 setHScrollBarMode( AlwaysOff );
00312
00313 setStartTime( KOPrefs::instance()->mDayBegins.time() );
00314
00315 calculateWorkingHours();
00316
00317 connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ),
00318 SLOT( checkScrollBoundaries( int ) ) );
00319
00320
00321 if( mAllDayMode ) {
00322 mMarcusBains = 0;
00323 } else {
00324 mMarcusBains = new MarcusBains( this );
00325 addChild( mMarcusBains );
00326 }
00327
00328 mTypeAhead = false;
00329 mTypeAheadReceiver = 0;
00330
00331 mReturnPressed = false;
00332 }
00333
00334
00335 void KOAgenda::clear()
00336 {
00337
00338
00339 AgendaItemList::Iterator it;
00340 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
00341 if ( *it ) {
00342 removeChild( *it );
00343 }
00344 }
00345 freeItemList( mItems );
00346 freeItemList( mItemsToDelete );
00347
00348 mItems.clear();
00349 mItemsToDelete.clear();
00350
00351 mSelectedItem = 0;
00352
00353 clearSelection();
00354 }
00355
00356
00357 void KOAgenda::clearSelection()
00358 {
00359 mHasSelection = false;
00360 mActionType = NOP;
00361 updateContents();
00362 }
00363
00364 void KOAgenda::marcus_bains()
00365 {
00366 if(mMarcusBains) mMarcusBains->updateLocationRecalc( true );
00367 }
00368
00369
00370 void KOAgenda::changeColumns(int columns)
00371 {
00372 if (columns == 0) {
00373 kdDebug(5850) << "KOAgenda::changeColumns() called with argument 0" << endl;
00374 return;
00375 }
00376
00377 clear();
00378 mColumns = columns;
00379
00380
00381
00382
00383 QResizeEvent event( size(), size() );
00384
00385 QApplication::sendEvent( this, &event );
00386 }
00387
00388
00389
00390
00391
00392 bool KOAgenda::eventFilter ( QObject *object, QEvent *event )
00393 {
00394
00395
00396 switch( event->type() ) {
00397 case QEvent::MouseButtonPress:
00398 case QEvent::MouseButtonDblClick:
00399 case QEvent::MouseButtonRelease:
00400 case QEvent::MouseMove:
00401 return eventFilter_mouse( object, static_cast<QMouseEvent *>( event ) );
00402 #ifndef QT_NO_WHEELEVENT
00403 case QEvent::Wheel:
00404 return eventFilter_wheel( object, static_cast<QWheelEvent *>( event ) );
00405 #endif
00406 case QEvent::KeyPress:
00407 case QEvent::KeyRelease:
00408 return eventFilter_key( object, static_cast<QKeyEvent *>( event ) );
00409
00410 case ( QEvent::Leave ):
00411 if ( !mActionItem )
00412 setCursor( arrowCursor );
00413 if ( object == viewport() )
00414 emit leaveAgenda();
00415 return true;
00416
00417 case QEvent::Enter:
00418 emit enterAgenda();
00419 return QScrollView::eventFilter( object, event );
00420
00421 #ifndef KORG_NODND
00422 case QEvent::DragEnter:
00423 case QEvent::DragMove:
00424 case QEvent::DragLeave:
00425 case QEvent::Drop:
00426
00427 return eventFilter_drag(object, static_cast<QDropEvent*>(event));
00428 #endif
00429
00430 default:
00431 return QScrollView::eventFilter( object, event );
00432 }
00433 }
00434
00435 bool KOAgenda::eventFilter_drag( QObject *object, QDropEvent *de )
00436 {
00437 #ifndef KORG_NODND
00438 QPoint viewportPos;
00439 if ( object != viewport() && object != this ) {
00440 viewportPos = static_cast<QWidget *>( object )->mapToParent( de->pos() );
00441 } else {
00442 viewportPos = de->pos();
00443 }
00444
00445 switch ( de->type() ) {
00446 case QEvent::DragEnter:
00447 case QEvent::DragMove:
00448 if ( ICalDrag::canDecode( de ) || VCalDrag::canDecode( de ) ) {
00449
00450 DndFactory factory( mCalendar );
00451 Incidence::List incidences = factory.createDropIncidences( de );
00452 if ( !incidences.isEmpty() ) {
00453 de->accept();
00454 incidences.setAutoDelete( true );
00455 } else {
00456 de->ignore();
00457 return false;
00458 }
00459 return true;
00460 } else return false;
00461 break;
00462 case QEvent::DragLeave:
00463 return false;
00464 break;
00465 case QEvent::Drop:
00466 {
00467 if ( !ICalDrag::canDecode( de ) && !VCalDrag::canDecode( de ) ) {
00468 return false;
00469 }
00470
00471 DndFactory factory( mCalendar );
00472 Incidence::List incidences = factory.createDropIncidences( de );
00473
00474 if ( !incidences.isEmpty() ) {
00475 Incidence *incidence = incidences.first();
00476 for( uint i=1; i<incidences.count(); ++i ) {
00477 delete incidences[i];
00478 }
00479
00480 if ( incidence->type() == "Event" || incidence->type() == "Todo" ) {
00481 de->acceptAction();
00482 QPoint pos;
00483
00484
00485
00486 if ( object == this ) {
00487 pos = viewportPos + QPoint( contentsX(), contentsY() );
00488 } else {
00489 pos = viewportToContents( viewportPos );
00490 }
00491 QPoint gpos = contentsToGrid( pos );
00492 emit droppedIncidence( incidence, gpos, mAllDayMode );
00493 return true;
00494 }
00495 }
00496 }
00497 break;
00498 case QEvent::DragResponse:
00499 default:
00500 break;
00501 }
00502 #endif
00503
00504 return false;
00505 }
00506
00507 bool KOAgenda::eventFilter_key( QObject *, QKeyEvent *ke )
00508 {
00509
00510
00511
00512 if ( ke->key() == Key_Return ) {
00513 if ( ke->type() == QEvent::KeyPress ) mReturnPressed = true;
00514 else if ( ke->type() == QEvent::KeyRelease ) {
00515 if ( mReturnPressed ) {
00516 emitNewEventForSelection();
00517 mReturnPressed = false;
00518 return true;
00519 } else {
00520 mReturnPressed = false;
00521 }
00522 }
00523 }
00524
00525
00526 if ( ke->text().isEmpty() ) return false;
00527
00528 if ( ke->type() == QEvent::KeyPress || ke->type() == QEvent::KeyRelease ) {
00529 switch ( ke->key() ) {
00530 case Key_Escape:
00531 case Key_Return:
00532 case Key_Enter:
00533 case Key_Tab:
00534 case Key_Backtab:
00535 case Key_Left:
00536 case Key_Right:
00537 case Key_Up:
00538 case Key_Down:
00539 case Key_Backspace:
00540 case Key_Delete:
00541 case Key_Prior:
00542 case Key_Next:
00543 case Key_Home:
00544 case Key_End:
00545 case Key_Control:
00546 case Key_Meta:
00547 case Key_Alt:
00548 break;
00549 default:
00550 mTypeAheadEvents.append( new QKeyEvent( ke->type(), ke->key(),
00551 ke->ascii(), ke->state(),
00552 ke->text(), ke->isAutoRepeat(),
00553 ke->count() ) );
00554 if ( !mTypeAhead ) {
00555 mTypeAhead = true;
00556 emitNewEventForSelection();
00557 }
00558 return true;
00559 }
00560 }
00561 return false;
00562 }
00563
00564 void KOAgenda::emitNewEventForSelection()
00565 {
00566 QPair<ResourceCalendar *, QString>p = mCalendarView->viewSubResourceCalendar();
00567 emit newEventSignal( p.first, p.second );
00568 }
00569
00570 void KOAgenda::finishTypeAhead()
00571 {
00572
00573 if ( typeAheadReceiver() ) {
00574 for( QEvent *e = mTypeAheadEvents.first(); e;
00575 e = mTypeAheadEvents.next() ) {
00576
00577 QApplication::sendEvent( typeAheadReceiver(), e );
00578 }
00579 }
00580 mTypeAheadEvents.clear();
00581 mTypeAhead = false;
00582 }
00583 #ifndef QT_NO_WHEELEVENT
00584 bool KOAgenda::eventFilter_wheel ( QObject *object, QWheelEvent *e )
00585 {
00586 QPoint viewportPos;
00587 bool accepted=false;
00588 if ( ( e->state() & ShiftButton) == ShiftButton ) {
00589 if ( object != viewport() ) {
00590 viewportPos = ( (QWidget *) object )->mapToParent( e->pos() );
00591 } else {
00592 viewportPos = e->pos();
00593 }
00594
00595
00596 emit zoomView( -e->delta() ,
00597 contentsToGrid( viewportToContents( viewportPos ) ),
00598 Qt::Horizontal );
00599 accepted=true;
00600 }
00601
00602 if ( ( e->state() & ControlButton ) == ControlButton ){
00603 if ( object != viewport() ) {
00604 viewportPos = ( (QWidget *)object )->mapToParent( e->pos() );
00605 } else {
00606 viewportPos = e->pos();
00607 }
00608 emit zoomView( -e->delta() ,
00609 contentsToGrid( viewportToContents( viewportPos ) ),
00610 Qt::Vertical );
00611 emit mousePosSignal(gridToContents(contentsToGrid(viewportToContents( viewportPos ))));
00612 accepted=true;
00613 }
00614 if (accepted ) e->accept();
00615 return accepted;
00616 }
00617 #endif
00618 bool KOAgenda::eventFilter_mouse(QObject *object, QMouseEvent *me)
00619 {
00620 QPoint viewportPos;
00621 if (object != viewport()) {
00622 viewportPos = ((QWidget *)object)->mapToParent(me->pos());
00623 } else {
00624 viewportPos = me->pos();
00625 }
00626
00627 switch (me->type()) {
00628 case QEvent::MouseButtonPress:
00629
00630 if (object != viewport()) {
00631 if (me->button() == RightButton) {
00632 mClickedItem = dynamic_cast<KOAgendaItem *>(object);
00633 if (mClickedItem) {
00634 selectItem(mClickedItem);
00635 emit showIncidencePopupSignal( mCalendar,
00636 mClickedItem->incidence(),
00637 mClickedItem->itemDate() );
00638 } else {
00639 return QScrollView::eventFilter( object, me );
00640 }
00641 } else {
00642 KOAgendaItem* item = dynamic_cast<KOAgendaItem *>(object);
00643 if (item) {
00644 Incidence *incidence = item->incidence();
00645 if ( incidence->isReadOnly() ) {
00646 mActionItem = 0;
00647 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00648 } else {
00649 mActionItem = item;
00650 mResPair = CalHelper::incSubResourceCalendar( mCalendar, incidence );
00651 startItemAction(viewportPos);
00652 }
00653
00654
00655
00656
00657 selectItem( item );
00658 } else {
00659 return QScrollView::eventFilter( object, me );
00660 }
00661 }
00662 } else {
00663 if ( me->button() == RightButton ) {
00664
00665 QPoint gpos = contentsToGrid( viewportToContents( viewportPos ) );
00666 if ( !ptInSelection( gpos ) ) {
00667 mSelectionStartCell = gpos;
00668 mSelectionEndCell = gpos;
00669 mHasSelection = true;
00670 emit newStartSelectSignal();
00671 emit newTimeSpanSignal( mSelectionStartCell, mSelectionEndCell );
00672 updateContents();
00673 }
00674 showNewEventPopupSignal();
00675 } else {
00676
00677 QPoint gpos = contentsToGrid( viewportToContents( viewportPos ) );
00678 if ( !ptInSelection( gpos ) ) {
00679 selectItem(0);
00680 mActionItem = 0;
00681 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00682 setCursor(arrowCursor);
00683 startSelectAction(viewportPos);
00684 }
00685 }
00686 return QScrollView::eventFilter( object, me );
00687 }
00688 break;
00689
00690 case QEvent::MouseButtonRelease:
00691 if (mActionItem) {
00692 endItemAction();
00693 } else if ( mActionType == SELECT ) {
00694 endSelectAction( viewportPos );
00695 }
00696
00697
00698 emit mousePosSignal( gridToContents(contentsToGrid(
00699 viewportToContents( viewportPos ) ) ));
00700 break;
00701
00702 case QEvent::MouseMove: {
00703
00704
00705 QPoint indicatorPos = gridToContents(contentsToGrid(
00706 viewportToContents( viewportPos )));
00707 if (object != viewport()) {
00708 KOAgendaItem *moveItem = dynamic_cast<KOAgendaItem *>(object);
00709 if (moveItem && !moveItem->incidence()->isReadOnly() ) {
00710 if (!mActionItem)
00711 setNoActionCursor(moveItem,viewportPos);
00712 else {
00713 performItemAction(viewportPos);
00714
00715 if ( mActionType == MOVE ) {
00716
00717 KOAgendaItem *firstItem = mActionItem->firstMultiItem();
00718 if (!firstItem) firstItem = mActionItem;
00719 indicatorPos = gridToContents( QPoint( firstItem->cellXLeft(),
00720 firstItem->cellYTop() ) );
00721
00722 } else if ( mActionType == RESIZEBOTTOM ) {
00723
00724 indicatorPos = gridToContents( QPoint( mActionItem->cellXLeft(),
00725 mActionItem->cellYBottom()+1 ) );
00726 }
00727
00728 }
00729 }
00730 } else {
00731 if ( mActionType == SELECT ) {
00732 performSelectAction( viewportPos );
00733
00734
00735 if ( ((mStartCell.y() < mEndCell.y()) && (mEndCell.x() >= mStartCell.x())) ||
00736 (mEndCell.x() > mStartCell.x()) )
00737 indicatorPos = gridToContents( QPoint(mEndCell.x(), mEndCell.y()+1) );
00738 else
00739 indicatorPos = gridToContents( mEndCell );
00740 }
00741 }
00742 emit mousePosSignal( indicatorPos );
00743 break; }
00744
00745 case QEvent::MouseButtonDblClick:
00746 if (object == viewport()) {
00747 selectItem(0);
00748 QPair<ResourceCalendar *, QString>p = mCalendarView->viewSubResourceCalendar();
00749 emit newEventSignal( p.first, p.second );
00750 } else {
00751 KOAgendaItem *doubleClickedItem = dynamic_cast<KOAgendaItem *>( object );
00752 if ( doubleClickedItem ) {
00753 selectItem( doubleClickedItem );
00754 emit editIncidenceSignal( doubleClickedItem->incidence(), doubleClickedItem->itemDate() );
00755 }
00756 }
00757 break;
00758
00759 default:
00760 break;
00761 }
00762
00763 return true;
00764 }
00765
00766 bool KOAgenda::ptInSelection( QPoint gpos ) const
00767 {
00768 if ( !mHasSelection ) {
00769 return false;
00770 } else if ( gpos.x()<mSelectionStartCell.x() || gpos.x()>mSelectionEndCell.x() ) {
00771 return false;
00772 } else if ( (gpos.x()==mSelectionStartCell.x()) && (gpos.y()<mSelectionStartCell.y()) ) {
00773 return false;
00774 } else if ( (gpos.x()==mSelectionEndCell.x()) && (gpos.y()>mSelectionEndCell.y()) ) {
00775 return false;
00776 }
00777 return true;
00778 }
00779
00780 void KOAgenda::startSelectAction( const QPoint &viewportPos )
00781 {
00782 emit newStartSelectSignal();
00783
00784 mActionType = SELECT;
00785 mSelectionStartPoint = viewportPos;
00786 mHasSelection = true;
00787
00788 QPoint pos = viewportToContents( viewportPos );
00789 QPoint gpos = contentsToGrid( pos );
00790
00791
00792 mStartCell = gpos;
00793 mEndCell = gpos;
00794 mSelectionStartCell = gpos;
00795 mSelectionEndCell = gpos;
00796
00797 updateContents();
00798 }
00799
00800 void KOAgenda::performSelectAction(const QPoint& viewportPos)
00801 {
00802 QPoint pos = viewportToContents( viewportPos );
00803 QPoint gpos = contentsToGrid( pos );
00804
00805 QPoint clipperPos = clipper()->
00806 mapFromGlobal(viewport()->mapToGlobal(viewportPos));
00807
00808
00809 if (clipperPos.y() < mScrollBorderWidth) {
00810 mScrollUpTimer.start(mScrollDelay);
00811 } else if (visibleHeight() - clipperPos.y() <
00812 mScrollBorderWidth) {
00813 mScrollDownTimer.start(mScrollDelay);
00814 } else {
00815 mScrollUpTimer.stop();
00816 mScrollDownTimer.stop();
00817 }
00818
00819 if ( gpos != mEndCell ) {
00820 mEndCell = gpos;
00821 if ( mStartCell.x()>mEndCell.x() ||
00822 ( mStartCell.x()==mEndCell.x() && mStartCell.y()>mEndCell.y() ) ) {
00823
00824 mSelectionStartCell = mEndCell;
00825 mSelectionEndCell = mStartCell;
00826 } else {
00827 mSelectionStartCell = mStartCell;
00828 mSelectionEndCell = mEndCell;
00829 }
00830
00831 updateContents();
00832 }
00833 }
00834
00835 void KOAgenda::endSelectAction( const QPoint ¤tPos )
00836 {
00837 mScrollUpTimer.stop();
00838 mScrollDownTimer.stop();
00839
00840 mActionType = NOP;
00841
00842 emit newTimeSpanSignal( mSelectionStartCell, mSelectionEndCell );
00843
00844 if ( KOPrefs::instance()->mSelectionStartsEditor ) {
00845 if ( ( mSelectionStartPoint - currentPos ).manhattanLength() >
00846 QApplication::startDragDistance() ) {
00847 emitNewEventForSelection();
00848 }
00849 }
00850 }
00851
00852 KOAgenda::MouseActionType KOAgenda::isInResizeArea( bool horizontal,
00853 const QPoint &pos,
00854 KOAgendaItem::GPtr item )
00855 {
00856 if ( !item ) {
00857 return NOP;
00858 }
00859
00860 QPoint gridpos = contentsToGrid( pos );
00861 QPoint contpos = gridToContents( gridpos +
00862 QPoint( (KOGlobals::self()->reverseLayout())?1:0, 0 ) );
00863
00864
00865
00866
00867 if ( horizontal ) {
00868 int clXLeft = item->cellXLeft();
00869 int clXRight = item->cellXRight();
00870 if ( KOGlobals::self()->reverseLayout() ) {
00871 int tmp = clXLeft;
00872 clXLeft = clXRight;
00873 clXRight = tmp;
00874 }
00875 int gridDistanceX = int( pos.x() - contpos.x() );
00876 if (gridDistanceX < mResizeBorderWidth && clXLeft == gridpos.x() ) {
00877 if ( KOGlobals::self()->reverseLayout() ) return RESIZERIGHT;
00878 else return RESIZELEFT;
00879 } else if ((mGridSpacingX - gridDistanceX) < mResizeBorderWidth &&
00880 clXRight == gridpos.x() ) {
00881 if ( KOGlobals::self()->reverseLayout() ) return RESIZELEFT;
00882 else return RESIZERIGHT;
00883 } else {
00884 return MOVE;
00885 }
00886 } else {
00887 int gridDistanceY = int( pos.y() - contpos.y() );
00888 if (gridDistanceY < mResizeBorderWidth &&
00889 item->cellYTop() == gridpos.y() &&
00890 !item->firstMultiItem() ) {
00891 return RESIZETOP;
00892 } else if ((mGridSpacingY - gridDistanceY) < mResizeBorderWidth &&
00893 item->cellYBottom() == gridpos.y() &&
00894 !item->lastMultiItem() ) {
00895 return RESIZEBOTTOM;
00896 } else {
00897 return MOVE;
00898 }
00899 }
00900 }
00901
00902 void KOAgenda::startItemAction(const QPoint& viewportPos)
00903 {
00904 QPoint pos = viewportToContents( viewportPos );
00905 mStartCell = contentsToGrid( pos );
00906 mEndCell = mStartCell;
00907
00908 bool noResize = ( mActionItem->incidence()->type() == "Todo");
00909
00910 mActionType = MOVE;
00911 if ( !noResize ) {
00912 mActionType = isInResizeArea( mAllDayMode, pos, mActionItem );
00913 }
00914
00915
00916 mActionItem->startMove();
00917 setActionCursor( mActionType, true );
00918 }
00919
00920 void KOAgenda::performItemAction(const QPoint& viewportPos)
00921 {
00922
00923
00924
00925
00926
00927
00928 QPoint pos = viewportToContents( viewportPos );
00929
00930 QPoint gpos = contentsToGrid( pos );
00931 QPoint clipperPos = clipper()->
00932 mapFromGlobal(viewport()->mapToGlobal(viewportPos));
00933
00934
00935
00936 if ( clipperPos.y() < 0 || clipperPos.y() > visibleHeight() ||
00937 clipperPos.x() < 0 || clipperPos.x() > visibleWidth() ) {
00938 if ( mActionType == MOVE ) {
00939 mScrollUpTimer.stop();
00940 mScrollDownTimer.stop();
00941 mActionItem->resetMove();
00942 placeSubCells( mActionItem );
00943 emit startDragSignal( mActionItem->incidence() );
00944 setCursor( arrowCursor );
00945 mActionItem = 0;
00946 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00947 mActionType = NOP;
00948 mItemMoved = false;
00949 return;
00950 }
00951 } else {
00952 setActionCursor( mActionType );
00953 }
00954
00955
00956 if (clipperPos.y() < mScrollBorderWidth) {
00957 mScrollUpTimer.start(mScrollDelay);
00958 } else if (visibleHeight() - clipperPos.y() <
00959 mScrollBorderWidth) {
00960 mScrollDownTimer.start(mScrollDelay);
00961 } else {
00962 mScrollUpTimer.stop();
00963 mScrollDownTimer.stop();
00964 }
00965
00966
00967 if ( mEndCell != gpos ) {
00968 if ( !mItemMoved ) {
00969 if ( !mChanger ||
00970 !mChanger->beginChange( mActionItem->incidence(), mResPair.first, mResPair.second ) ) {
00971 KMessageBox::information( this, i18n("Unable to lock item for "
00972 "modification. You cannot make any changes."),
00973 i18n("Locking Failed"), "AgendaLockingFailed" );
00974 mScrollUpTimer.stop();
00975 mScrollDownTimer.stop();
00976 mActionItem->resetMove();
00977 placeSubCells( mActionItem );
00978 setCursor( arrowCursor );
00979 mActionItem = 0;
00980 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00981 mActionType = NOP;
00982 mItemMoved = false;
00983 return;
00984 }
00985 mItemMoved = true;
00986 }
00987 mActionItem->raise();
00988 if (mActionType == MOVE) {
00989
00990 KOAgendaItem *firstItem = mActionItem->firstMultiItem();
00991 if (!firstItem) firstItem = mActionItem;
00992 KOAgendaItem *lastItem = mActionItem->lastMultiItem();
00993 if (!lastItem) lastItem = mActionItem;
00994 QPoint deltapos = gpos - mEndCell;
00995 KOAgendaItem *moveItem = firstItem;
00996 while (moveItem) {
00997 bool changed=false;
00998 if ( deltapos.x()!=0 ) {
00999 moveItem->moveRelative( deltapos.x(), 0 );
01000 changed=true;
01001 }
01002
01003 if ( moveItem==firstItem && !mAllDayMode ) {
01004 int newY = deltapos.y() + moveItem->cellYTop();
01005
01006 if ( newY<0 ) {
01007 moveItem->expandTop( -moveItem->cellYTop() );
01008
01009 KOAgendaItem *newFirst = firstItem->prevMoveItem();
01010
01011 if (newFirst) {
01012 newFirst->setCellXY(moveItem->cellXLeft()-1, rows()+newY, rows()-1);
01013 mItems.append( newFirst );
01014 moveItem->resize( int( mGridSpacingX * newFirst->cellWidth() ),
01015 int( mGridSpacingY * newFirst->cellHeight() ));
01016 QPoint cpos = gridToContents( QPoint( newFirst->cellXLeft(), newFirst->cellYTop() ) );
01017 addChild( newFirst, cpos.x(), cpos.y() );
01018 } else {
01019 newFirst = insertItem( moveItem->incidence(), moveItem->itemDate(),
01020 moveItem->cellXLeft()-1, rows()+newY, rows()-1, moveItem->itemPos(), moveItem->itemCount() ) ;
01021 }
01022 if (newFirst) newFirst->show();
01023 moveItem->prependMoveItem(newFirst);
01024 firstItem=newFirst;
01025 } else if ( newY>=rows() ) {
01026
01027
01028 firstItem = moveItem->nextMultiItem();
01029 moveItem->hide();
01030 mItems.remove( mItems.find( moveItem ) );
01031 removeChild( moveItem );
01032 mActionItem->removeMoveItem(moveItem);
01033 moveItem=firstItem;
01034
01035 if (moveItem) moveItem->expandTop( rows()-newY );
01036 } else {
01037 moveItem->expandTop(deltapos.y());
01038 }
01039 changed=true;
01040 }
01041 if ( !moveItem->lastMultiItem() && !mAllDayMode ) {
01042 int newY = deltapos.y()+moveItem->cellYBottom();
01043 if (newY<0) {
01044
01045 lastItem = moveItem->prevMultiItem();
01046 moveItem->hide();
01047 mItems.remove( mItems.find(moveItem) );
01048 removeChild( moveItem );
01049 moveItem->removeMoveItem( moveItem );
01050 moveItem = lastItem;
01051 moveItem->expandBottom(newY+1);
01052 } else if (newY>=rows()) {
01053 moveItem->expandBottom( rows()-moveItem->cellYBottom()-1 );
01054
01055 KOAgendaItem *newLast = lastItem->nextMoveItem();
01056 if (newLast) {
01057 newLast->setCellXY( moveItem->cellXLeft()+1, 0, newY-rows()-1 );
01058 mItems.append(newLast);
01059 moveItem->resize( int( mGridSpacingX * newLast->cellWidth() ),
01060 int( mGridSpacingY * newLast->cellHeight() ));
01061 QPoint cpos = gridToContents( QPoint( newLast->cellXLeft(), newLast->cellYTop() ) ) ;
01062 addChild( newLast, cpos.x(), cpos.y() );
01063 } else {
01064 newLast = insertItem( moveItem->incidence(), moveItem->itemDate(),
01065 moveItem->cellXLeft()+1, 0, newY-rows()-1, moveItem->itemPos(), moveItem->itemCount() ) ;
01066 }
01067 moveItem->appendMoveItem( newLast );
01068 newLast->show();
01069 lastItem = newLast;
01070 } else {
01071 moveItem->expandBottom( deltapos.y() );
01072 }
01073 changed=true;
01074 }
01075 if (changed) {
01076 adjustItemPosition( moveItem );
01077 }
01078 moveItem = moveItem->nextMultiItem();
01079 }
01080 } else if (mActionType == RESIZETOP) {
01081 if (mEndCell.y() <= mActionItem->cellYBottom()) {
01082 mActionItem->expandTop(gpos.y() - mEndCell.y());
01083 adjustItemPosition( mActionItem );
01084 }
01085 } else if (mActionType == RESIZEBOTTOM) {
01086 if (mEndCell.y() >= mActionItem->cellYTop()) {
01087 mActionItem->expandBottom(gpos.y() - mEndCell.y());
01088 adjustItemPosition( mActionItem );
01089 }
01090 } else if (mActionType == RESIZELEFT) {
01091 if (mEndCell.x() <= mActionItem->cellXRight()) {
01092 mActionItem->expandLeft( gpos.x() - mEndCell.x() );
01093 adjustItemPosition( mActionItem );
01094 }
01095 } else if (mActionType == RESIZERIGHT) {
01096 if (mEndCell.x() >= mActionItem->cellXLeft()) {
01097 mActionItem->expandRight(gpos.x() - mEndCell.x());
01098 adjustItemPosition( mActionItem );
01099 }
01100 }
01101 mEndCell = gpos;
01102 }
01103 }
01104
01105 void KOAgenda::endItemAction()
01106 {
01107
01108 mActionType = NOP;
01109 mScrollUpTimer.stop();
01110 mScrollDownTimer.stop();
01111 setCursor( arrowCursor );
01112 bool useLastGroupwareDialogAnswer = false;
01113 bool addIncidence = false;
01114 bool multiModify = false;
01115
01116 Incidence *inc = mActionItem->incidence();
01117
01118 if ( mStartCell.x() == mEndCell.x() && mStartCell.y() == mEndCell.y() ) {
01119
01120 if ( mItemMoved ) {
01121 mItemMoved = false;
01122 mChanger->endChange( inc, mResPair.first, mResPair.second );
01123 }
01124 }
01125
01126 if ( mItemMoved ) {
01127 Incidence *incToChange = inc;
01128 if ( mActionItem->incidence()->doesRecur() ) {
01129
01130 kdDebug() << "mActionItem->incidence()->dtStart() is " << inc->dtStart() << endl;
01131
01132 Incidence* oldIncSaved = inc->clone();
01133 KOGlobals::WhichOccurrences chosenOption;
01134 inc->startUpdates();
01135 incToChange = mCalendarView->singleOccurrenceOrAll( inc,
01136 KOGlobals::EDIT,
01137 chosenOption,
01138 mActionItem->itemDate() );
01139
01140 if ( chosenOption == KOGlobals::ONLY_THIS_ONE ||
01141 chosenOption == KOGlobals::ONLY_FUTURE ) {
01142 multiModify = true;
01143 mAgendaView->enableAgendaUpdate( false );
01144 useLastGroupwareDialogAnswer = true;
01145 addIncidence = true;
01146 mAgendaView->enableAgendaUpdate( true );
01147 const KOGlobals::WhatChanged whatChanged = chosenOption == KOGlobals::ONLY_THIS_ONE ?
01148 KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY :
01149 KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE;
01150
01151 const bool success = mChanger->changeIncidence( oldIncSaved, inc, whatChanged, this );
01152
01153 if ( success ) {
01154 mActionItem->dissociateFromMultiItem();
01155 mActionItem->setIncidence( incToChange );
01156 inc->endUpdates();
01157 } else {
01158 inc->cancelUpdates();
01159 incToChange = 0;
01160 }
01161 } else {
01162 inc->endUpdates();
01163 }
01164 }
01165
01166 if ( incToChange ) {
01167 mActionItem->endMove();
01168 KOAgendaItem *placeItem = mActionItem->firstMultiItem();
01169 if ( !placeItem ) {
01170 placeItem = mActionItem;
01171 }
01172
01173 KOAgendaItem *modif = placeItem;
01174 AgendaItemList oldconflictItems = placeItem->conflictItems();
01175
01176 AgendaItemList::Iterator it;
01177 for ( it = oldconflictItems.begin(); it != oldconflictItems.end(); ++it ) {
01178 if ( *it ) {
01179 placeSubCells( *it );
01180 }
01181 }
01182
01183 while ( placeItem ) {
01184 placeSubCells( placeItem );
01185 placeItem = placeItem->nextMultiItem();
01186 }
01187
01188
01189
01190 mChanger->endChange( inc, mResPair.first, mResPair.second );
01191 kdDebug() << "Modified." << endl;
01192 mAgendaView->updateEventDates( modif, useLastGroupwareDialogAnswer, mResPair.first, mResPair.second, addIncidence );
01193 } else {
01194 mActionItem->resetMove();
01195 placeSubCells( mActionItem );
01196
01197
01198
01199 mChanger->endChange( inc, mResPair.first, mResPair.second );
01200 kdDebug() << "Not modified." << endl;
01201 mAgendaView->updateEventDates( mActionItem,
01202 useLastGroupwareDialogAnswer,
01203 mResPair.first,
01204 mResPair.second,
01205 addIncidence );
01206 }
01207 }
01208
01209 mActionItem = 0;
01210 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
01211 mItemMoved = false;
01212
01213 if ( multiModify ) {
01214 emit endMultiModify();
01215 }
01216
01217 kdDebug(5850) << "KOAgenda::endItemAction() done" << endl;
01218 }
01219
01220 void KOAgenda::setActionCursor( int actionType, bool acting )
01221 {
01222 switch ( actionType ) {
01223 case MOVE:
01224 if (acting) setCursor( sizeAllCursor );
01225 else setCursor( arrowCursor );
01226 break;
01227 case RESIZETOP:
01228 case RESIZEBOTTOM:
01229 setCursor( sizeVerCursor );
01230 break;
01231 case RESIZELEFT:
01232 case RESIZERIGHT:
01233 setCursor( sizeHorCursor );
01234 break;
01235 default:
01236 setCursor( arrowCursor );
01237 }
01238 }
01239
01240 void KOAgenda::setNoActionCursor( KOAgendaItem::GPtr moveItem, const QPoint& viewportPos )
01241 {
01242
01243
01244
01245
01246
01247
01248 if ( !moveItem ) {
01249 return;
01250 }
01251
01252 QPoint pos = viewportToContents( viewportPos );
01253 bool noResize = (moveItem && moveItem->incidence() &&
01254 moveItem->incidence()->type() == "Todo");
01255
01256 KOAgenda::MouseActionType resizeType = MOVE;
01257 if ( !noResize ) resizeType = isInResizeArea( mAllDayMode, pos , moveItem);
01258 setActionCursor( resizeType );
01259 }
01260
01261
01265 double KOAgenda::calcSubCellWidth( KOAgendaItem::GPtr item )
01266 {
01267 if ( !item ) {
01268 return 0;
01269 }
01270
01271 QPoint pt, pt1;
01272 pt = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) );
01273 pt1 = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) +
01274 QPoint( 1, 1 ) );
01275 pt1 -= pt;
01276 int maxSubCells = item->subCells();
01277 double newSubCellWidth;
01278 if ( mAllDayMode ) {
01279 newSubCellWidth = double( pt1.y() ) / maxSubCells;
01280 } else {
01281 newSubCellWidth = double( pt1.x() ) / maxSubCells;
01282 }
01283 return newSubCellWidth;
01284 }
01285
01286 void KOAgenda::adjustItemPosition( KOAgendaItem::GPtr item )
01287 {
01288 if (!item) return;
01289 item->resize( int( mGridSpacingX * item->cellWidth() ),
01290 int( mGridSpacingY * item->cellHeight() ) );
01291 int clXLeft = item->cellXLeft();
01292 if ( KOGlobals::self()->reverseLayout() )
01293 clXLeft = item->cellXRight() + 1;
01294 QPoint cpos = gridToContents( QPoint( clXLeft, item->cellYTop() ) );
01295 moveChild( item, cpos.x(), cpos.y() );
01296 }
01297
01298 void KOAgenda::placeAgendaItem( KOAgendaItem::GPtr item, double subCellWidth )
01299 {
01300
01301
01302
01303 if ( !item ) {
01304 return;
01305 }
01306
01307
01308 const QPoint pt = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) );
01309
01310
01311 const QPoint pt1 = gridToContents( QPoint( item->cellXLeft() + item->cellWidth(),
01312 item->cellYBottom()+1 ) );
01313
01314 const double subCellPos = item->subCell() * subCellWidth;
01315
01316
01317
01318 const double delta = subCellWidth < 0 ? -0.01 : 0.01;
01319
01320 int height, width, xpos, ypos;
01321 if ( mAllDayMode ) {
01322 width = pt1.x()-pt.x();
01323 height = int( subCellPos + subCellWidth + delta ) - int( subCellPos );
01324 xpos = pt.x();
01325 ypos = pt.y() + int( subCellPos );
01326 } else {
01327 width = int( subCellPos + subCellWidth + delta ) - int( subCellPos );
01328 height = pt1.y()-pt.y();
01329 xpos = pt.x() + int( subCellPos );
01330 ypos = pt.y();
01331 }
01332 if ( KOGlobals::self()->reverseLayout() ) {
01333 xpos += width;
01334 width = -width;
01335 }
01336 if ( height<0 ) {
01337 ypos += height;
01338 height = -height;
01339 }
01340 item->resize( width, height );
01341 moveChild( item, xpos, ypos );
01342 }
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357 void KOAgenda::placeSubCells( KOAgendaItem::GPtr placeItem )
01358 {
01359 #if 0
01360 kdDebug(5850) << "KOAgenda::placeSubCells()" << endl;
01361 if ( placeItem ) {
01362 Incidence *event = placeItem->incidence();
01363 if ( !event ) {
01364 kdDebug(5850) << " event is 0" << endl;
01365 } else {
01366 kdDebug(5850) << " event: " << event->summary() << endl;
01367 }
01368 } else {
01369 kdDebug(5850) << " placeItem is 0" << endl;
01370 }
01371 kdDebug(5850) << "KOAgenda::placeSubCells()..." << endl;
01372 #endif
01373
01374 if ( !placeItem ) {
01375 return;
01376 }
01377
01378 QPtrList<KOrg::CellItem> cells;
01379 AgendaItemList::Iterator it;
01380 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01381 if ( *it ) {
01382 cells.append( *it );
01383 }
01384 }
01385
01386 QPtrList<KOrg::CellItem> items = KOrg::CellItem::placeItem( cells,
01387 placeItem );
01388 QPtrList<KOAgendaItem> updatedCells;
01389
01390 KOrg::CellItem *i;
01391 placeItem->setConflictItems( AgendaItemList() );
01392 const double newSubCellWidth = calcSubCellWidth( placeItem );
01393 for ( i = items.first(); i; i = items.next() ) {
01394 KOAgendaItem *item = static_cast<KOAgendaItem *>( i );
01395 placeAgendaItem( item, newSubCellWidth );
01396 item->addConflictItem( placeItem );
01397
01398 if ( placeItem->incidence() && placeItem->incidence()->doesFloat() ) {
01399
01400 updateWidthsRecursivley( item, updatedCells, placeItem->subCells() );
01401 }
01402
01403 placeItem->addConflictItem( item );
01404 }
01405 if ( items.isEmpty() ) {
01406 placeAgendaItem( placeItem, newSubCellWidth );
01407 }
01408 placeItem->update();
01409 }
01410
01412 bool KOAgenda::updateWidthsRecursivley( KOAgendaItem *item,
01413 QPtrList<KOAgendaItem> &itemsAlreadyUpdated,
01414 int numSubCells )
01415 {
01416 bool result = false;
01417 if ( !itemsAlreadyUpdated.contains( item ) ) {
01418 item->setSubCells( numSubCells );
01419
01420
01421 itemsAlreadyUpdated.append( item );
01422
01423
01424 AgendaItemList list = item->conflictItems();
01425
01426 for ( int i = 0; i < list.count(); ++i ) {
01427 KOAgendaItem::GPtr it = list[i];
01428 if ( it && numSubCells > it->subCells() ) {
01429 updateWidthsRecursivley( it, itemsAlreadyUpdated, numSubCells );
01430 result = true;
01431 }
01432 }
01433 }
01434
01435 return result;
01436 }
01437
01438 int KOAgenda::columnWidth( int column )
01439 {
01440 const int start = gridToContents( QPoint( column, 0 ) ).x();
01441 if (KOGlobals::self()->reverseLayout() )
01442 column--;
01443 else
01444 column++;
01445 const int end = gridToContents( QPoint( column, 0 ) ).x();
01446 return end - start;
01447 }
01448
01449
01450
01451 void KOAgenda::drawContents(QPainter* p, int cx, int cy, int cw, int ch)
01452 {
01453 QPixmap db(cw, ch);
01454 db.fill(KOPrefs::instance()->mAgendaBgColor);
01455 QPainter dbp(&db);
01456 dbp.translate(-cx,-cy);
01457
01458 double lGridSpacingY = mGridSpacingY*2;
01459
01460
01461
01462
01463
01464 const QMemArray<bool> busyDayMask = mAgendaView->busyDayMask();
01465
01466 if ( KOPrefs::instance()->mColorBusyDaysEnabled && !mAllDayMode ) {
01467 for ( int i = 0; i < busyDayMask.count(); ++i ) {
01468 if ( busyDayMask[i] ) {
01469 const QPoint pt1( cx + mGridSpacingX * i, 0 );
01470
01471 dbp.fillRect( pt1.x(), pt1.y(), mGridSpacingX, cy + ch, KOPrefs::instance()->mAgendaMonthBgBusyColor );
01472 }
01473 }
01474 }
01475
01476 if ( mWorkingHoursEnable ) {
01477
01478 QColor workAndBusyColor;
01479
01480 if ( KOPrefs::instance()->mColorBusyDaysEnabled ) {
01481 workAndBusyColor = KOHelper::mixColors( KOPrefs::instance()->mAgendaMonthBgBusyColor, 0.60, KOPrefs::instance()->mWorkingHoursColor );
01482 } else {
01483 workAndBusyColor = KOPrefs::instance()->mWorkingHoursColor;
01484 }
01485
01486 const QPoint pt1( cx, mWorkingHoursYTop );
01487 const QPoint pt2( cx+cw, mWorkingHoursYBottom );
01488 if ( pt2.x() >= pt1.x() ) {
01489 int gxStart = contentsToGrid( pt1 ).x();
01490 int gxEnd = contentsToGrid( pt2 ).x();
01491
01492 if ( gxStart > gxEnd ) {
01493 const int tmp = gxStart;
01494 gxStart = gxEnd;
01495 gxEnd = tmp;
01496 }
01497 const int xoffset = ( KOGlobals::self()->reverseLayout() ? 1 : 0 );
01498 while( gxStart <= gxEnd ) {
01499 const int xStart = gridToContents( QPoint( gxStart+xoffset, 0 ) ).x();
01500 const int xWidth = columnWidth( gxStart ) + 1;
01501 QColor color;
01502 if ( gxStart < busyDayMask.count() && busyDayMask[gxStart] ) {
01503 color = workAndBusyColor;
01504 } else {
01505 color = KOPrefs::instance()->mWorkingHoursColor;
01506 }
01507 if ( pt2.y() < pt1.y() ) {
01508
01509 if ( ( (gxStart==0) && !mHolidayMask->at(mHolidayMask->count()-1) ) ||
01510 ( (gxStart>0) && (gxStart<int(mHolidayMask->count())) && (!mHolidayMask->at(gxStart-1) ) ) ) {
01511 if ( pt2.y() > cy ) {
01512 dbp.fillRect( xStart, cy, xWidth, pt2.y() - cy + 1, color );
01513 }
01514 }
01515 if ( (gxStart < int(mHolidayMask->count()-1)) && (!mHolidayMask->at(gxStart)) ) {
01516 if ( pt1.y() < cy + ch - 1 ) {
01517 dbp.fillRect( xStart, pt1.y(), xWidth, cy + ch - pt1.y() + 1,
01518 color );
01519 }
01520 }
01521 } else {
01522
01523 if ( gxStart < int(mHolidayMask->count()-1) && !mHolidayMask->at(gxStart)) {
01524 dbp.fillRect( xStart, pt1.y(), xWidth, pt2.y() - pt1.y() + 1,
01525 color );
01526 }
01527 }
01528 ++gxStart;
01529 }
01530 }
01531 }
01532
01533
01534
01535
01536 if ( mHasSelection ) {
01537 QPoint pt, pt1;
01538
01539 if ( mSelectionEndCell.x() > mSelectionStartCell.x() ) {
01540
01541 pt = gridToContents( mSelectionStartCell );
01542 pt1 = gridToContents( QPoint( mSelectionStartCell.x() + 1, mRows + 1 ) );
01543 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01544
01545 for ( int c = mSelectionStartCell.x() + 1; c < mSelectionEndCell.x(); ++c ) {
01546 pt = gridToContents( QPoint( c, 0 ) );
01547 pt1 = gridToContents( QPoint( c + 1, mRows + 1 ) );
01548 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01549 }
01550
01551 pt = gridToContents( QPoint( mSelectionEndCell.x(), 0 ) );
01552 pt1 = gridToContents( mSelectionEndCell + QPoint(1,1) );
01553 dbp.fillRect( QRect( pt, pt1), KOPrefs::instance()->mHighlightColor );
01554 } else {
01555 pt = gridToContents( mSelectionStartCell );
01556 pt1 = gridToContents( mSelectionEndCell + QPoint(1,1) );
01557 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01558 }
01559 }
01560
01561 QPen hourPen( KOPrefs::instance()->mAgendaBgColor.dark( 150 ) );
01562 QPen halfHourPen( KOPrefs::instance()->mAgendaBgColor.dark( 125 ) );
01563 dbp.setPen( hourPen );
01564
01565
01566
01567 double x = ( int( cx / mGridSpacingX ) ) * mGridSpacingX;
01568 while (x < cx + cw) {
01569 dbp.drawLine( int( x ), cy, int( x ), cy + ch );
01570 x+=mGridSpacingX;
01571 }
01572
01573
01574 double y = ( int( cy / (2*lGridSpacingY) ) ) * 2 * lGridSpacingY;
01575 while (y < cy + ch) {
01576
01577 dbp.drawLine( cx, int( y ), cx + cw, int( y ) );
01578 y += 2 * lGridSpacingY;
01579 }
01580 y = ( 2 * int( cy / (2*lGridSpacingY) ) + 1) * lGridSpacingY;
01581 dbp.setPen( halfHourPen );
01582 while (y < cy + ch) {
01583
01584 dbp.drawLine( cx, int( y ), cx + cw, int( y ) );
01585 y+=2*lGridSpacingY;
01586 }
01587 p->drawPixmap(cx,cy, db);
01588 }
01589
01590
01591
01592
01593 QPoint KOAgenda::contentsToGrid ( const QPoint &pos ) const
01594 {
01595 int gx = int( KOGlobals::self()->reverseLayout() ?
01596 mColumns - pos.x()/mGridSpacingX : pos.x()/mGridSpacingX );
01597 int gy = int( pos.y()/mGridSpacingY );
01598 return QPoint( gx, gy );
01599 }
01600
01601
01602
01603
01604 QPoint KOAgenda::gridToContents( const QPoint &gpos ) const
01605 {
01606 int x = int( KOGlobals::self()->reverseLayout() ?
01607 (mColumns - gpos.x())*mGridSpacingX : gpos.x()*mGridSpacingX );
01608 int y = int( gpos.y()*mGridSpacingY );
01609 return QPoint( x, y );
01610 }
01611
01612
01613
01614
01615
01616
01617 int KOAgenda::timeToY(const QTime &time)
01618 {
01619
01620 int minutesPerCell = 24 * 60 / mRows;
01621
01622 int timeMinutes = time.hour() * 60 + time.minute();
01623
01624 int Y = (timeMinutes + (minutesPerCell / 2)) / minutesPerCell;
01625
01626
01627 return Y;
01628 }
01629
01630
01631
01632
01633
01634
01635 QTime KOAgenda::gyToTime(int gy)
01636 {
01637
01638 int secondsPerCell = 24 * 60 * 60/ mRows;
01639
01640 int timeSeconds = secondsPerCell * gy;
01641
01642 QTime time( 0, 0, 0 );
01643 if ( timeSeconds < 24 * 60 * 60 ) {
01644 time = time.addSecs(timeSeconds);
01645 } else {
01646 time.setHMS( 23, 59, 59 );
01647 }
01648
01649
01650 return time;
01651 }
01652
01653 QMemArray<int> KOAgenda::minContentsY()
01654 {
01655 QMemArray<int> minArray;
01656 minArray.fill( timeToY( QTime(23, 59) ), mSelectedDates.count() );
01657
01658 AgendaItemList::Iterator it;
01659 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01660 if ( *it ) {
01661 const int ymin = (*it)->cellYTop();
01662 const int index = (*it)->cellXLeft();
01663 if ( index >= 0 && index < static_cast<int>( mSelectedDates.count() ) ) {
01664 if ( ymin < minArray[index] && !mItemsToDelete.contains( *it ) )
01665 minArray[index] = ymin;
01666 }
01667 }
01668 }
01669
01670 return minArray;
01671 }
01672
01673 QMemArray<int> KOAgenda::maxContentsY()
01674 {
01675 QMemArray<int> maxArray;
01676 maxArray.fill( timeToY( QTime(0, 0) ), mSelectedDates.count() );
01677 AgendaItemList::Iterator it;
01678 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01679 if ( *it ) {
01680 const int ymax = (*it)->cellYBottom();
01681 const int index = (*it)->cellXLeft();
01682 if ( index >= 0 && index < static_cast<int>( mSelectedDates.count() ) ) {
01683 if ( ymax > maxArray[index] && !mItemsToDelete.contains( *it ) )
01684 maxArray[index] = ymax;
01685 }
01686 }
01687 }
01688
01689 return maxArray;
01690 }
01691
01692 void KOAgenda::setStartTime( const QTime &startHour )
01693 {
01694 const double startPos = ( startHour.hour()/24. + startHour.minute()/1440. +
01695 startHour.second()/86400. ) * mRows * gridSpacingY();
01696 setContentsPos( 0, static_cast<int>( startPos ) );
01697 }
01698
01699
01700
01701
01702
01703 KOAgendaItem *KOAgenda::insertItem( Incidence *incidence, const QDate &qd, int X,
01704 int YTop, int YBottom, int itemPos, int itemCount )
01705 {
01706 if ( mAllDayMode ) {
01707 kdDebug(5850) << "KOAgenda: calling insertItem in all-day mode is illegal." << endl;
01708 return 0;
01709 }
01710
01711 mActionType = NOP;
01712
01713 KOAgendaItem *agendaItem = new KOAgendaItem( mCalendar, incidence, qd, viewport(), itemPos, itemCount );
01714 connect( agendaItem, SIGNAL( removeAgendaItem( KOAgendaItem::GPtr ) ),
01715 SLOT( removeAgendaItem( KOAgendaItem::GPtr ) ) );
01716 connect( agendaItem, SIGNAL( showAgendaItem( KOAgendaItem::GPtr ) ),
01717 SLOT( showAgendaItem( KOAgendaItem::GPtr ) ) );
01718
01719 if ( YBottom <= YTop ) {
01720 kdDebug(5850) << "KOAgenda::insertItem(): Text: " << agendaItem->text() << " YSize<0" << endl;
01721 YBottom = YTop;
01722 }
01723
01724 agendaItem->resize( int( ( X + 1 ) * mGridSpacingX ) -
01725 int( X * mGridSpacingX ),
01726 int( YTop * mGridSpacingY ) -
01727 int( ( YBottom + 1 ) * mGridSpacingY ) );
01728 agendaItem->setCellXY( X, YTop, YBottom );
01729 agendaItem->setCellXRight( X );
01730 agendaItem->setResourceColor( KOHelper::resourceColor( mCalendar, incidence ) );
01731 agendaItem->installEventFilter( this );
01732
01733 addChild( agendaItem, int( X * mGridSpacingX ), int( YTop * mGridSpacingY ) );
01734 mItems.append( agendaItem );
01735
01736 placeSubCells( agendaItem );
01737
01738 agendaItem->show();
01739
01740 marcus_bains();
01741
01742 return agendaItem;
01743 }
01744
01745
01746
01747
01748 KOAgendaItem *KOAgenda::insertAllDayItem( Incidence *event, const QDate &qd,
01749 int XBegin, int XEnd )
01750 {
01751 if ( !mAllDayMode ) {
01752 kdWarning(5850) << "KOAgenda: calling insertAllDayItem in non all-day mode is illegal." << endl;
01753 return 0;
01754 }
01755
01756 mActionType = NOP;
01757
01758 KOAgendaItem *agendaItem = new KOAgendaItem( mCalendar, event, qd, viewport(), 1, 1 );
01759 connect( agendaItem, SIGNAL( removeAgendaItem( KOAgendaItem::GPtr ) ),
01760 SLOT( removeAgendaItem( KOAgendaItem::GPtr ) ) );
01761 connect( agendaItem, SIGNAL( showAgendaItem( KOAgendaItem::GPtr ) ),
01762 SLOT( showAgendaItem( KOAgendaItem::GPtr ) ) );
01763
01764 {
01765
01766
01767
01768
01769 if ( event->doesFloat() && XBegin * mGridSpacingX <= -32767 + mGridSpacingX ) {
01770
01771
01772
01773
01774
01775 XBegin = -1;
01776 }
01777 }
01778
01779 agendaItem->setCellXY( XBegin, 0, 0 );
01780 agendaItem->setCellXRight( XEnd );
01781
01782 const double startIt = mGridSpacingX * ( agendaItem->cellXLeft() );
01783 const double endIt = mGridSpacingX * ( agendaItem->cellWidth() +
01784 agendaItem->cellXLeft() );
01785
01786 agendaItem->resize( int( endIt ) - int( startIt ), int( mGridSpacingY ) );
01787
01788 agendaItem->installEventFilter( this );
01789 agendaItem->setResourceColor( KOHelper::resourceColor( mCalendar, event ) );
01790 addChild( agendaItem, int( XBegin * mGridSpacingX ), 0 );
01791 mItems.append( agendaItem );
01792
01793 placeSubCells( agendaItem );
01794
01795 agendaItem->show();
01796
01797 return agendaItem;
01798 }
01799
01800
01801 void KOAgenda::insertMultiItem( Event *event, const QDate &qd, int XBegin, int XEnd,
01802 int YTop, int YBottom )
01803 {
01804 if ( mAllDayMode ) {
01805 kdDebug(5850) << "KOAgenda: calling insertMultiItem in all-day mode is illegal." << endl;
01806 return;
01807 }
01808 mActionType = NOP;
01809
01810 int cellX,cellYTop,cellYBottom;
01811 QString newtext;
01812 int width = XEnd - XBegin + 1;
01813 int count = 0;
01814 KOAgendaItem *current = 0;
01815 QPtrList<KOAgendaItem> multiItems;
01816 const int visibleCount = mSelectedDates.first().daysTo( mSelectedDates.last() );
01817 for ( cellX = XBegin; cellX <= XEnd; ++cellX ) {
01818 ++count;
01819
01820 if( cellX >= 0 && cellX <= visibleCount ) {
01821 if ( cellX == XBegin ) {
01822 cellYTop = YTop;
01823 } else {
01824 cellYTop = 0;
01825 }
01826
01827 if ( cellX == XEnd ) {
01828 cellYBottom = YBottom;
01829 } else {
01830 cellYBottom = rows() - 1;
01831 }
01832
01833 newtext = QString("(%1/%2): ").arg( count ).arg( width );
01834 newtext.append( event->summary() );
01835
01836 current = insertItem( event, qd, cellX, cellYTop, cellYBottom, count, width );
01837 current->setText( newtext );
01838 multiItems.append( current );
01839 }
01840 }
01841 QPtrList<KOAgendaItem>::iterator it = multiItems.begin();
01842 QPtrList<KOAgendaItem>::iterator e = multiItems.end();
01843
01844 if ( it != e ) {
01845 KOAgendaItem *first = multiItems.first();
01846 KOAgendaItem *last = multiItems.last();
01847 KOAgendaItem *prev = 0, *next = 0;
01848
01849 while ( it != e ) {
01850 KOAgendaItem *item = *it;
01851 ++it;
01852 next = ( it == e ) ? 0 : (*it);
01853 if ( item ) {
01854 item->setMultiItem( ( item == first ) ? 0 : first,
01855 prev, next,
01856 ( item == last ) ? 0 : last );
01857 }
01858 prev = item;
01859 }
01860 }
01861
01862 marcus_bains();
01863 }
01864
01865 void KOAgenda::removeIncidence( Incidence *incidence, bool relayoutNeighbours )
01866 {
01867
01868
01869
01870 QValueList<KOAgendaItem::GPtr > itemsToRemove;
01871
01872 AgendaItemList::Iterator it;
01873 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01874 if ( *it ) {
01875 if ( (*it)->incidence() == incidence ) {
01876 itemsToRemove.append( *it );
01877 }
01878 }
01879 }
01880
01881 for ( it = itemsToRemove.begin(); it != itemsToRemove.end(); ++it ) {
01882 removeAgendaItem( *it, relayoutNeighbours );
01883 }
01884 }
01885
01886 void KOAgenda::showAgendaItem( KOAgendaItem::GPtr agendaItem )
01887 {
01888 if ( !agendaItem ) {
01889 return;
01890 }
01891
01892 agendaItem->hide();
01893 addChild( agendaItem );
01894 if ( !mItems.contains( agendaItem ) ) {
01895 mItems.append( agendaItem );
01896 }
01897 placeSubCells( agendaItem );
01898
01899 agendaItem->show();
01900 }
01901
01902 bool KOAgenda::removeAgendaItem( KOAgendaItem::GPtr item, bool relayoutNeighbours )
01903 {
01904
01905 bool taken = false;
01906 KOAgendaItem::GPtr thisItem = item;
01907 AgendaItemList conflictItems = thisItem->conflictItems();
01908 removeChild( thisItem );
01909
01910 AgendaItemList::Iterator it = mItems.find( thisItem );
01911 if ( it != mItems.end() ) {
01912 mItems.remove( it );
01913 taken = true;
01914 }
01915
01916 if ( relayoutNeighbours ) {
01917 for ( it = conflictItems.begin(); it != conflictItems.end(); ++it ) {
01918
01919 if ( *it != thisItem ) {
01920 placeSubCells( *it );
01921 }
01922 }
01923 }
01924
01925 mItemsToDelete.append( thisItem );
01926 QTimer::singleShot( 0, this, SLOT( deleteItemsToDelete() ) );
01927 return taken;
01928 }
01929
01930 void KOAgenda::deleteItemsToDelete()
01931 {
01932 freeItemList( mItemsToDelete );
01933 mItemsToDelete.clear();
01934 }
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954 void KOAgenda::resizeEvent ( QResizeEvent *ev )
01955 {
01956
01957
01958 QSize newSize( ev->size() );
01959 if (mAllDayMode) {
01960 mGridSpacingX = double( newSize.width() - 2 * frameWidth() ) / (double)mColumns;
01961 mGridSpacingY = newSize.height() - 2 * frameWidth();
01962 } else {
01963 int scrollbarWidth = vScrollBarMode() != AlwaysOff ? verticalScrollBar()->width() : 0;
01964 mGridSpacingX = double( newSize.width() - scrollbarWidth - 2 * frameWidth()) / double(mColumns);
01965
01966 mGridSpacingY = double(newSize.height() - 2 * frameWidth()) / double(mRows);
01967 if ( mGridSpacingY < mDesiredGridSpacingY )
01968 mGridSpacingY = mDesiredGridSpacingY;
01969 }
01970 calculateWorkingHours();
01971 QTimer::singleShot( 0, this, SLOT( resizeAllContents() ) );
01972 emit gridSpacingYChanged( mGridSpacingY * 4 );
01973 QScrollView::resizeEvent(ev);
01974 }
01975
01976 void KOAgenda::resizeAllContents()
01977 {
01978
01979 double subCellWidth;
01980
01981 if ( mItems.count() > 0 ) {
01982 KOAgendaItem::GPtr item;
01983 if ( mAllDayMode ) {
01984 AgendaItemList::Iterator it;
01985 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01986 if ( *it ) {
01987 subCellWidth = calcSubCellWidth( *it );
01988 placeAgendaItem( *it, subCellWidth );
01989 }
01990 }
01991 } else {
01992 AgendaItemList::Iterator it;
01993 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01994 if ( *it ) {
01995 subCellWidth = calcSubCellWidth( *it );
01996 placeAgendaItem( *it, subCellWidth );
01997 }
01998 }
01999 }
02000 }
02001 checkScrollBoundaries();
02002 marcus_bains();
02003 }
02004
02005 void KOAgenda::scrollUp()
02006 {
02007 scrollBy(0,-mScrollOffset);
02008 }
02009
02010
02011 void KOAgenda::scrollDown()
02012 {
02013 scrollBy(0,mScrollOffset);
02014 }
02015
02016
02017
02018
02019
02020 int KOAgenda::minimumWidth() const
02021 {
02022
02023 int min = 100;
02024
02025 return min;
02026 }
02027
02028 void KOAgenda::updateConfig()
02029 {
02030 double oldGridSpacingY = mGridSpacingY;
02031
02032 mDesiredGridSpacingY = KOPrefs::instance()->mHourSize;
02033 if ( mDesiredGridSpacingY < 4 || mDesiredGridSpacingY > 30 ) {
02034 mDesiredGridSpacingY = 10;
02035 }
02036
02037
02038 mGridSpacingY = (double)height() / (double)mRows;
02039 if ( mGridSpacingY < mDesiredGridSpacingY ) {
02040 mGridSpacingY = mDesiredGridSpacingY;
02041 }
02042
02043
02044 if ( fabs( oldGridSpacingY - mGridSpacingY ) > 0.1 ) {
02045 resizeContents( int( mGridSpacingX * mColumns ),
02046 int( mGridSpacingY * mRows ) );
02047 }
02048
02049 calculateWorkingHours();
02050
02051 marcus_bains();
02052 }
02053
02054 void KOAgenda::checkScrollBoundaries()
02055 {
02056
02057 mOldLowerScrollValue = -1;
02058 mOldUpperScrollValue = -1;
02059
02060 checkScrollBoundaries(verticalScrollBar()->value());
02061 }
02062
02063 void KOAgenda::checkScrollBoundaries( int v )
02064 {
02065 int yMin = int( (v) / mGridSpacingY );
02066 int yMax = int( ( v + visibleHeight() ) / mGridSpacingY );
02067
02068
02069
02070 if ( yMin != mOldLowerScrollValue ) {
02071 mOldLowerScrollValue = yMin;
02072 emit lowerYChanged(yMin);
02073 }
02074 if ( yMax != mOldUpperScrollValue ) {
02075 mOldUpperScrollValue = yMax;
02076 emit upperYChanged(yMax);
02077 }
02078 }
02079
02080 int KOAgenda::visibleContentsYMin()
02081 {
02082 int v = verticalScrollBar()->value();
02083 return int( v / mGridSpacingY );
02084 }
02085
02086 int KOAgenda::visibleContentsYMax()
02087 {
02088 int v = verticalScrollBar()->value();
02089 return int( ( v + visibleHeight() ) / mGridSpacingY );
02090 }
02091
02092 void KOAgenda::deselectItem()
02093 {
02094 if ( mSelectedItem.isNull() ) {
02095 return;
02096 }
02097 mSelectedItem->select(false);
02098 mSelectedItem = 0;
02099 }
02100
02101 void KOAgenda::selectItem( KOAgendaItem::GPtr item )
02102 {
02103 if ((KOAgendaItem *)mSelectedItem == item) return;
02104 deselectItem();
02105 if ( !item ) {
02106 emit incidenceSelected( 0, QDate() );
02107 return;
02108 }
02109 mSelectedItem = item;
02110 mSelectedItem->select();
02111 assert( mSelectedItem->incidence() );
02112 mSelectedUid = mSelectedItem->incidence()->uid();
02113 emit incidenceSelected( mSelectedItem->incidence(), mSelectedItem->itemDate() );
02114 }
02115
02116 void KOAgenda::selectItemByUID( const QString& uid )
02117 {
02118 KOAgendaItem::GPtr item;
02119 AgendaItemList::Iterator it;
02120 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
02121 if ( *it && (*it)->incidence() && (*it)->incidence()->uid() == uid ) {
02122 selectItem( *it );
02123 break;
02124 }
02125 }
02126 }
02127
02128
02129 void KOAgenda::keyPressEvent( QKeyEvent *kev )
02130 {
02131 switch(kev->key()) {
02132 case Key_PageDown:
02133 verticalScrollBar()->addPage();
02134 break;
02135 case Key_PageUp:
02136 verticalScrollBar()->subtractPage();
02137 break;
02138 case Key_Down:
02139 verticalScrollBar()->addLine();
02140 break;
02141 case Key_Up:
02142 verticalScrollBar()->subtractLine();
02143 break;
02144 default:
02145 ;
02146 }
02147 }
02148
02149 void KOAgenda::calculateWorkingHours()
02150 {
02151 mWorkingHoursEnable = !mAllDayMode;
02152
02153 QTime tmp = KOPrefs::instance()->mWorkingHoursStart.time();
02154 mWorkingHoursYTop = int( 4 * mGridSpacingY *
02155 ( tmp.hour() + tmp.minute() / 60. +
02156 tmp.second() / 3600. ) );
02157 tmp = KOPrefs::instance()->mWorkingHoursEnd.time();
02158 mWorkingHoursYBottom = int( 4 * mGridSpacingY *
02159 ( tmp.hour() + tmp.minute() / 60. +
02160 tmp.second() / 3600. ) - 1 );
02161 }
02162
02163
02164 DateList KOAgenda::dateList() const
02165 {
02166 return mSelectedDates;
02167 }
02168
02169 void KOAgenda::setDateList(const DateList &selectedDates)
02170 {
02171 mSelectedDates = selectedDates;
02172 marcus_bains();
02173 }
02174
02175 void KOAgenda::contentsMousePressEvent ( QMouseEvent *event )
02176 {
02177 kdDebug(5850) << "KOagenda::contentsMousePressEvent(): type: " << event->type() << endl;
02178 QScrollView::contentsMousePressEvent(event);
02179 }
02180
02181 void KOAgenda::setTypeAheadReceiver( QObject *o )
02182 {
02183 mTypeAheadReceiver = o;
02184 }
02185
02186 QObject *KOAgenda::typeAheadReceiver() const
02187 {
02188 return mTypeAheadReceiver;
02189 }
02190
02191 void KOAgenda::setHolidayMask(QMemArray<bool> *mask)
02192 {
02193 mHolidayMask = mask;
02194 }