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 bool endUpdatesPending = false;
01116
01117 Incidence *inc = mActionItem->incidence();
01118
01119 if ( mStartCell.x() == mEndCell.x() && mStartCell.y() == mEndCell.y() ) {
01120
01121 if ( mItemMoved ) {
01122 mItemMoved = false;
01123 mChanger->endChange( inc, mResPair.first, mResPair.second );
01124 }
01125 }
01126
01127 if ( mItemMoved ) {
01128 Incidence *incToChange = inc;
01129 if ( mActionItem->incidence()->doesRecur() ) {
01130
01131 kdDebug() << "mActionItem->incidence()->dtStart() is " << inc->dtStart() << endl;
01132
01133 Incidence* oldIncSaved = inc->clone();
01134 KOGlobals::WhichOccurrences chosenOption;
01135 inc->startUpdates();
01136 incToChange = mCalendarView->singleOccurrenceOrAll( inc,
01137 KOGlobals::EDIT,
01138 chosenOption,
01139 mActionItem->itemDate() );
01140
01141 if ( chosenOption == KOGlobals::ONLY_THIS_ONE ||
01142 chosenOption == KOGlobals::ONLY_FUTURE ) {
01143 multiModify = true;
01144 mAgendaView->enableAgendaUpdate( false );
01145 useLastGroupwareDialogAnswer = true;
01146 addIncidence = true;
01147 mAgendaView->enableAgendaUpdate( true );
01148 const KOGlobals::WhatChanged whatChanged = chosenOption == KOGlobals::ONLY_THIS_ONE ?
01149 KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY :
01150 KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE;
01151
01152 const bool success = mChanger->changeIncidence( oldIncSaved, inc, whatChanged, this );
01153
01154 if ( success ) {
01155 mActionItem->dissociateFromMultiItem();
01156 mActionItem->setIncidence( incToChange );
01157
01158 endUpdatesPending = true;
01159 } else {
01160 inc->cancelUpdates();
01161 incToChange = 0;
01162 }
01163 } else {
01164 endUpdatesPending = true;
01165
01166 }
01167 }
01168
01169 if ( incToChange ) {
01170 mActionItem->endMove();
01171 KOAgendaItem *placeItem = mActionItem->firstMultiItem();
01172 if ( !placeItem ) {
01173 placeItem = mActionItem;
01174 }
01175
01176 KOAgendaItem *modif = placeItem;
01177 AgendaItemList oldconflictItems = placeItem->conflictItems();
01178
01179 AgendaItemList::Iterator it;
01180 for ( it = oldconflictItems.begin(); it != oldconflictItems.end(); ++it ) {
01181 if ( *it ) {
01182 placeSubCells( *it );
01183 }
01184 }
01185
01186 while ( placeItem ) {
01187 placeSubCells( placeItem );
01188 placeItem = placeItem->nextMultiItem();
01189 }
01190
01191
01192
01193 mChanger->endChange( inc, mResPair.first, mResPair.second );
01194 kdDebug() << "Modified." << endl;
01195 mAgendaView->updateEventDates( modif, useLastGroupwareDialogAnswer, mResPair.first, mResPair.second, addIncidence );
01196 } else {
01197 mActionItem->resetMove();
01198 placeSubCells( mActionItem );
01199
01200
01201
01202 mChanger->endChange( inc, mResPair.first, mResPair.second );
01203 kdDebug() << "Not modified." << endl;
01204 mAgendaView->updateEventDates( mActionItem,
01205 useLastGroupwareDialogAnswer,
01206 mResPair.first,
01207 mResPair.second,
01208 addIncidence );
01209 }
01210 }
01211
01212 if ( endUpdatesPending )
01213 inc->endUpdates();
01214
01215 mActionItem = 0;
01216 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
01217 mItemMoved = false;
01218
01219 if ( multiModify ) {
01220 emit endMultiModify();
01221 }
01222
01223 kdDebug(5850) << "KOAgenda::endItemAction() done" << endl;
01224 }
01225
01226 void KOAgenda::setActionCursor( int actionType, bool acting )
01227 {
01228 switch ( actionType ) {
01229 case MOVE:
01230 if (acting) setCursor( sizeAllCursor );
01231 else setCursor( arrowCursor );
01232 break;
01233 case RESIZETOP:
01234 case RESIZEBOTTOM:
01235 setCursor( sizeVerCursor );
01236 break;
01237 case RESIZELEFT:
01238 case RESIZERIGHT:
01239 setCursor( sizeHorCursor );
01240 break;
01241 default:
01242 setCursor( arrowCursor );
01243 }
01244 }
01245
01246 void KOAgenda::setNoActionCursor( KOAgendaItem::GPtr moveItem, const QPoint& viewportPos )
01247 {
01248
01249
01250
01251
01252
01253
01254 if ( !moveItem ) {
01255 return;
01256 }
01257
01258 QPoint pos = viewportToContents( viewportPos );
01259 bool noResize = (moveItem && moveItem->incidence() &&
01260 moveItem->incidence()->type() == "Todo");
01261
01262 KOAgenda::MouseActionType resizeType = MOVE;
01263 if ( !noResize ) resizeType = isInResizeArea( mAllDayMode, pos , moveItem);
01264 setActionCursor( resizeType );
01265 }
01266
01267
01271 double KOAgenda::calcSubCellWidth( KOAgendaItem::GPtr item )
01272 {
01273 if ( !item ) {
01274 return 0;
01275 }
01276
01277 QPoint pt, pt1;
01278 pt = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) );
01279 pt1 = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) +
01280 QPoint( 1, 1 ) );
01281 pt1 -= pt;
01282 int maxSubCells = item->subCells();
01283 double newSubCellWidth;
01284 if ( mAllDayMode ) {
01285 newSubCellWidth = double( pt1.y() ) / maxSubCells;
01286 } else {
01287 newSubCellWidth = double( pt1.x() ) / maxSubCells;
01288 }
01289 return newSubCellWidth;
01290 }
01291
01292 void KOAgenda::adjustItemPosition( KOAgendaItem::GPtr item )
01293 {
01294 if (!item) return;
01295 item->resize( int( mGridSpacingX * item->cellWidth() ),
01296 int( mGridSpacingY * item->cellHeight() ) );
01297 int clXLeft = item->cellXLeft();
01298 if ( KOGlobals::self()->reverseLayout() )
01299 clXLeft = item->cellXRight() + 1;
01300 QPoint cpos = gridToContents( QPoint( clXLeft, item->cellYTop() ) );
01301 moveChild( item, cpos.x(), cpos.y() );
01302 }
01303
01304 void KOAgenda::placeAgendaItem( KOAgendaItem::GPtr item, double subCellWidth )
01305 {
01306
01307
01308
01309 if ( !item ) {
01310 return;
01311 }
01312
01313
01314 const QPoint pt = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) );
01315
01316
01317 const QPoint pt1 = gridToContents( QPoint( item->cellXLeft() + item->cellWidth(),
01318 item->cellYBottom()+1 ) );
01319
01320 const double subCellPos = item->subCell() * subCellWidth;
01321
01322
01323
01324 const double delta = subCellWidth < 0 ? -0.01 : 0.01;
01325
01326 int height, width, xpos, ypos;
01327 if ( mAllDayMode ) {
01328 width = pt1.x()-pt.x();
01329 height = int( subCellPos + subCellWidth + delta ) - int( subCellPos );
01330 xpos = pt.x();
01331 ypos = pt.y() + int( subCellPos );
01332 } else {
01333 width = int( subCellPos + subCellWidth + delta ) - int( subCellPos );
01334 height = pt1.y()-pt.y();
01335 xpos = pt.x() + int( subCellPos );
01336 ypos = pt.y();
01337 }
01338 if ( KOGlobals::self()->reverseLayout() ) {
01339 xpos += width;
01340 width = -width;
01341 }
01342 if ( height<0 ) {
01343 ypos += height;
01344 height = -height;
01345 }
01346 item->resize( width, height );
01347 moveChild( item, xpos, ypos );
01348 }
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 void KOAgenda::placeSubCells( KOAgendaItem::GPtr placeItem )
01364 {
01365 #if 0
01366 kdDebug(5850) << "KOAgenda::placeSubCells()" << endl;
01367 if ( placeItem ) {
01368 Incidence *event = placeItem->incidence();
01369 if ( !event ) {
01370 kdDebug(5850) << " event is 0" << endl;
01371 } else {
01372 kdDebug(5850) << " event: " << event->summary() << endl;
01373 }
01374 } else {
01375 kdDebug(5850) << " placeItem is 0" << endl;
01376 }
01377 kdDebug(5850) << "KOAgenda::placeSubCells()..." << endl;
01378 #endif
01379
01380 if ( !placeItem ) {
01381 return;
01382 }
01383
01384 QPtrList<KOrg::CellItem> cells;
01385 AgendaItemList::Iterator it;
01386 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01387 if ( *it ) {
01388 cells.append( *it );
01389 }
01390 }
01391
01392 QPtrList<KOrg::CellItem> items = KOrg::CellItem::placeItem( cells,
01393 placeItem );
01394 QPtrList<KOAgendaItem> updatedCells;
01395
01396 KOrg::CellItem *i;
01397 placeItem->setConflictItems( AgendaItemList() );
01398 const double newSubCellWidth = calcSubCellWidth( placeItem );
01399 for ( i = items.first(); i; i = items.next() ) {
01400 KOAgendaItem *item = static_cast<KOAgendaItem *>( i );
01401 placeAgendaItem( item, newSubCellWidth );
01402 item->addConflictItem( placeItem );
01403
01404 if ( placeItem->incidence() && placeItem->incidence()->doesFloat() ) {
01405
01406 updateWidthsRecursivley( item, updatedCells, placeItem->subCells() );
01407 }
01408
01409 placeItem->addConflictItem( item );
01410 }
01411 if ( items.isEmpty() ) {
01412 placeAgendaItem( placeItem, newSubCellWidth );
01413 }
01414 placeItem->update();
01415 }
01416
01418 bool KOAgenda::updateWidthsRecursivley( KOAgendaItem *item,
01419 QPtrList<KOAgendaItem> &itemsAlreadyUpdated,
01420 int numSubCells )
01421 {
01422 bool result = false;
01423 if ( !itemsAlreadyUpdated.contains( item ) ) {
01424 item->setSubCells( numSubCells );
01425
01426
01427 itemsAlreadyUpdated.append( item );
01428
01429
01430 AgendaItemList list = item->conflictItems();
01431
01432 for ( int i = 0; i < list.count(); ++i ) {
01433 KOAgendaItem::GPtr it = list[i];
01434 if ( it && numSubCells > it->subCells() ) {
01435 updateWidthsRecursivley( it, itemsAlreadyUpdated, numSubCells );
01436 result = true;
01437 }
01438 }
01439 }
01440
01441 return result;
01442 }
01443
01444 int KOAgenda::columnWidth( int column )
01445 {
01446 const int start = gridToContents( QPoint( column, 0 ) ).x();
01447 if (KOGlobals::self()->reverseLayout() )
01448 column--;
01449 else
01450 column++;
01451 const int end = gridToContents( QPoint( column, 0 ) ).x();
01452 return end - start;
01453 }
01454
01455
01456
01457 void KOAgenda::drawContents(QPainter* p, int cx, int cy, int cw, int ch)
01458 {
01459 QPixmap db(cw, ch);
01460 db.fill(KOPrefs::instance()->mAgendaBgColor);
01461 QPainter dbp(&db);
01462 dbp.translate(-cx,-cy);
01463
01464 double lGridSpacingY = mGridSpacingY*2;
01465
01466
01467
01468
01469
01470 const QMemArray<bool> busyDayMask = mAgendaView->busyDayMask();
01471
01472 if ( KOPrefs::instance()->mColorBusyDaysEnabled && !mAllDayMode ) {
01473 for ( int i = 0; i < busyDayMask.count(); ++i ) {
01474 if ( busyDayMask[i] ) {
01475 const QPoint pt1( cx + mGridSpacingX * i, 0 );
01476
01477 dbp.fillRect( pt1.x(), pt1.y(), mGridSpacingX, cy + ch, KOPrefs::instance()->mAgendaMonthBgBusyColor );
01478 }
01479 }
01480 }
01481
01482 if ( mWorkingHoursEnable ) {
01483
01484 QColor workAndBusyColor;
01485
01486 if ( KOPrefs::instance()->mColorBusyDaysEnabled ) {
01487 workAndBusyColor = KOHelper::mixColors( KOPrefs::instance()->mAgendaMonthBgBusyColor, 0.60, KOPrefs::instance()->mWorkingHoursColor );
01488 } else {
01489 workAndBusyColor = KOPrefs::instance()->mWorkingHoursColor;
01490 }
01491
01492 const QPoint pt1( cx, mWorkingHoursYTop );
01493 const QPoint pt2( cx+cw, mWorkingHoursYBottom );
01494 if ( pt2.x() >= pt1.x() ) {
01495 int gxStart = contentsToGrid( pt1 ).x();
01496 int gxEnd = contentsToGrid( pt2 ).x();
01497
01498 if ( gxStart > gxEnd ) {
01499 const int tmp = gxStart;
01500 gxStart = gxEnd;
01501 gxEnd = tmp;
01502 }
01503 const int xoffset = ( KOGlobals::self()->reverseLayout() ? 1 : 0 );
01504 while( gxStart <= gxEnd ) {
01505 const int xStart = gridToContents( QPoint( gxStart+xoffset, 0 ) ).x();
01506 const int xWidth = columnWidth( gxStart ) + 1;
01507 QColor color;
01508 if ( gxStart < busyDayMask.count() && busyDayMask[gxStart] ) {
01509 color = workAndBusyColor;
01510 } else {
01511 color = KOPrefs::instance()->mWorkingHoursColor;
01512 }
01513 if ( pt2.y() < pt1.y() ) {
01514
01515 if ( ( (gxStart==0) && !mHolidayMask->at(mHolidayMask->count()-1) ) ||
01516 ( (gxStart>0) && (gxStart<int(mHolidayMask->count())) && (!mHolidayMask->at(gxStart-1) ) ) ) {
01517 if ( pt2.y() > cy ) {
01518 dbp.fillRect( xStart, cy, xWidth, pt2.y() - cy + 1, color );
01519 }
01520 }
01521 if ( (gxStart < int(mHolidayMask->count()-1)) && (!mHolidayMask->at(gxStart)) ) {
01522 if ( pt1.y() < cy + ch - 1 ) {
01523 dbp.fillRect( xStart, pt1.y(), xWidth, cy + ch - pt1.y() + 1,
01524 color );
01525 }
01526 }
01527 } else {
01528
01529 if ( gxStart < int(mHolidayMask->count()-1) && !mHolidayMask->at(gxStart)) {
01530 dbp.fillRect( xStart, pt1.y(), xWidth, pt2.y() - pt1.y() + 1,
01531 color );
01532 }
01533 }
01534 ++gxStart;
01535 }
01536 }
01537 }
01538
01539
01540
01541
01542 if ( mHasSelection ) {
01543 QPoint pt, pt1;
01544
01545 if ( mSelectionEndCell.x() > mSelectionStartCell.x() ) {
01546
01547 pt = gridToContents( mSelectionStartCell );
01548 pt1 = gridToContents( QPoint( mSelectionStartCell.x() + 1, mRows + 1 ) );
01549 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01550
01551 for ( int c = mSelectionStartCell.x() + 1; c < mSelectionEndCell.x(); ++c ) {
01552 pt = gridToContents( QPoint( c, 0 ) );
01553 pt1 = gridToContents( QPoint( c + 1, mRows + 1 ) );
01554 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01555 }
01556
01557 pt = gridToContents( QPoint( mSelectionEndCell.x(), 0 ) );
01558 pt1 = gridToContents( mSelectionEndCell + QPoint(1,1) );
01559 dbp.fillRect( QRect( pt, pt1), KOPrefs::instance()->mHighlightColor );
01560 } else {
01561 pt = gridToContents( mSelectionStartCell );
01562 pt1 = gridToContents( mSelectionEndCell + QPoint(1,1) );
01563 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01564 }
01565 }
01566
01567 QPen hourPen( KOPrefs::instance()->mAgendaBgColor.dark( 150 ) );
01568 QPen halfHourPen( KOPrefs::instance()->mAgendaBgColor.dark( 125 ) );
01569 dbp.setPen( hourPen );
01570
01571
01572
01573 double x = ( int( cx / mGridSpacingX ) ) * mGridSpacingX;
01574 while (x < cx + cw) {
01575 dbp.drawLine( int( x ), cy, int( x ), cy + ch );
01576 x+=mGridSpacingX;
01577 }
01578
01579
01580 double y = ( int( cy / (2*lGridSpacingY) ) ) * 2 * lGridSpacingY;
01581 while (y < cy + ch) {
01582
01583 dbp.drawLine( cx, int( y ), cx + cw, int( y ) );
01584 y += 2 * lGridSpacingY;
01585 }
01586 y = ( 2 * int( cy / (2*lGridSpacingY) ) + 1) * lGridSpacingY;
01587 dbp.setPen( halfHourPen );
01588 while (y < cy + ch) {
01589
01590 dbp.drawLine( cx, int( y ), cx + cw, int( y ) );
01591 y+=2*lGridSpacingY;
01592 }
01593 p->drawPixmap(cx,cy, db);
01594 }
01595
01596
01597
01598
01599 QPoint KOAgenda::contentsToGrid ( const QPoint &pos ) const
01600 {
01601 int gx = int( KOGlobals::self()->reverseLayout() ?
01602 mColumns - pos.x()/mGridSpacingX : pos.x()/mGridSpacingX );
01603 int gy = int( pos.y()/mGridSpacingY );
01604 return QPoint( gx, gy );
01605 }
01606
01607
01608
01609
01610 QPoint KOAgenda::gridToContents( const QPoint &gpos ) const
01611 {
01612 int x = int( KOGlobals::self()->reverseLayout() ?
01613 (mColumns - gpos.x())*mGridSpacingX : gpos.x()*mGridSpacingX );
01614 int y = int( gpos.y()*mGridSpacingY );
01615 return QPoint( x, y );
01616 }
01617
01618
01619
01620
01621
01622
01623 int KOAgenda::timeToY(const QTime &time)
01624 {
01625
01626 int minutesPerCell = 24 * 60 / mRows;
01627
01628 int timeMinutes = time.hour() * 60 + time.minute();
01629
01630 int Y = (timeMinutes + (minutesPerCell / 2)) / minutesPerCell;
01631
01632
01633 return Y;
01634 }
01635
01636
01637
01638
01639
01640
01641 QTime KOAgenda::gyToTime(int gy)
01642 {
01643
01644 int secondsPerCell = 24 * 60 * 60/ mRows;
01645
01646 int timeSeconds = secondsPerCell * gy;
01647
01648 QTime time( 0, 0, 0 );
01649 if ( timeSeconds < 24 * 60 * 60 ) {
01650 time = time.addSecs(timeSeconds);
01651 } else {
01652 time.setHMS( 23, 59, 59 );
01653 }
01654
01655
01656 return time;
01657 }
01658
01659 QMemArray<int> KOAgenda::minContentsY()
01660 {
01661 QMemArray<int> minArray;
01662 minArray.fill( timeToY( QTime(23, 59) ), mSelectedDates.count() );
01663
01664 AgendaItemList::Iterator it;
01665 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01666 if ( *it ) {
01667 const int ymin = (*it)->cellYTop();
01668 const int index = (*it)->cellXLeft();
01669 if ( index >= 0 && index < static_cast<int>( mSelectedDates.count() ) ) {
01670 if ( ymin < minArray[index] && !mItemsToDelete.contains( *it ) )
01671 minArray[index] = ymin;
01672 }
01673 }
01674 }
01675
01676 return minArray;
01677 }
01678
01679 QMemArray<int> KOAgenda::maxContentsY()
01680 {
01681 QMemArray<int> maxArray;
01682 maxArray.fill( timeToY( QTime(0, 0) ), mSelectedDates.count() );
01683 AgendaItemList::Iterator it;
01684 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01685 if ( *it ) {
01686 const int ymax = (*it)->cellYBottom();
01687 const int index = (*it)->cellXLeft();
01688 if ( index >= 0 && index < static_cast<int>( mSelectedDates.count() ) ) {
01689 if ( ymax > maxArray[index] && !mItemsToDelete.contains( *it ) )
01690 maxArray[index] = ymax;
01691 }
01692 }
01693 }
01694
01695 return maxArray;
01696 }
01697
01698 void KOAgenda::setStartTime( const QTime &startHour )
01699 {
01700 const double startPos = ( startHour.hour()/24. + startHour.minute()/1440. +
01701 startHour.second()/86400. ) * mRows * gridSpacingY();
01702 setContentsPos( 0, static_cast<int>( startPos ) );
01703 }
01704
01705
01706
01707
01708
01709 KOAgendaItem *KOAgenda::insertItem( Incidence *incidence, const QDate &qd, int X,
01710 int YTop, int YBottom, int itemPos, int itemCount )
01711 {
01712 if ( mAllDayMode ) {
01713 kdDebug(5850) << "KOAgenda: calling insertItem in all-day mode is illegal." << endl;
01714 return 0;
01715 }
01716
01717 mActionType = NOP;
01718
01719 KOAgendaItem *agendaItem = new KOAgendaItem( mCalendar, incidence, qd, viewport(), itemPos, itemCount );
01720 connect( agendaItem, SIGNAL( removeAgendaItem( KOAgendaItem::GPtr ) ),
01721 SLOT( removeAgendaItem( KOAgendaItem::GPtr ) ) );
01722 connect( agendaItem, SIGNAL( showAgendaItem( KOAgendaItem::GPtr ) ),
01723 SLOT( showAgendaItem( KOAgendaItem::GPtr ) ) );
01724
01725 if ( YBottom <= YTop ) {
01726 kdDebug(5850) << "KOAgenda::insertItem(): Text: " << agendaItem->text() << " YSize<0" << endl;
01727 YBottom = YTop;
01728 }
01729
01730 agendaItem->resize( int( ( X + 1 ) * mGridSpacingX ) -
01731 int( X * mGridSpacingX ),
01732 int( YTop * mGridSpacingY ) -
01733 int( ( YBottom + 1 ) * mGridSpacingY ) );
01734 agendaItem->setCellXY( X, YTop, YBottom );
01735 agendaItem->setCellXRight( X );
01736 agendaItem->setResourceColor( KOHelper::resourceColor( mCalendar, incidence ) );
01737 agendaItem->installEventFilter( this );
01738
01739 addChild( agendaItem, int( X * mGridSpacingX ), int( YTop * mGridSpacingY ) );
01740 mItems.append( agendaItem );
01741
01742 placeSubCells( agendaItem );
01743
01744 agendaItem->show();
01745
01746 marcus_bains();
01747
01748 return agendaItem;
01749 }
01750
01751
01752
01753
01754 KOAgendaItem *KOAgenda::insertAllDayItem( Incidence *event, const QDate &qd,
01755 int XBegin, int XEnd )
01756 {
01757 if ( !mAllDayMode ) {
01758 kdWarning(5850) << "KOAgenda: calling insertAllDayItem in non all-day mode is illegal." << endl;
01759 return 0;
01760 }
01761
01762 mActionType = NOP;
01763
01764 KOAgendaItem *agendaItem = new KOAgendaItem( mCalendar, event, qd, viewport(), 1, 1 );
01765 connect( agendaItem, SIGNAL( removeAgendaItem( KOAgendaItem::GPtr ) ),
01766 SLOT( removeAgendaItem( KOAgendaItem::GPtr ) ) );
01767 connect( agendaItem, SIGNAL( showAgendaItem( KOAgendaItem::GPtr ) ),
01768 SLOT( showAgendaItem( KOAgendaItem::GPtr ) ) );
01769
01770 {
01771
01772
01773
01774
01775 if ( event->doesFloat() && XBegin * mGridSpacingX <= -32767 + mGridSpacingX ) {
01776
01777
01778
01779
01780
01781 XBegin = -1;
01782 }
01783 }
01784
01785 agendaItem->setCellXY( XBegin, 0, 0 );
01786 agendaItem->setCellXRight( XEnd );
01787
01788 const double startIt = mGridSpacingX * ( agendaItem->cellXLeft() );
01789 const double endIt = mGridSpacingX * ( agendaItem->cellWidth() +
01790 agendaItem->cellXLeft() );
01791
01792 agendaItem->resize( int( endIt ) - int( startIt ), int( mGridSpacingY ) );
01793
01794 agendaItem->installEventFilter( this );
01795 agendaItem->setResourceColor( KOHelper::resourceColor( mCalendar, event ) );
01796 addChild( agendaItem, int( XBegin * mGridSpacingX ), 0 );
01797 mItems.append( agendaItem );
01798
01799 placeSubCells( agendaItem );
01800
01801 agendaItem->show();
01802
01803 return agendaItem;
01804 }
01805
01806
01807 void KOAgenda::insertMultiItem( Event *event, const QDate &qd, int XBegin, int XEnd,
01808 int YTop, int YBottom )
01809 {
01810 if ( mAllDayMode ) {
01811 kdDebug(5850) << "KOAgenda: calling insertMultiItem in all-day mode is illegal." << endl;
01812 return;
01813 }
01814 mActionType = NOP;
01815
01816 int cellX,cellYTop,cellYBottom;
01817 QString newtext;
01818 int width = XEnd - XBegin + 1;
01819 int count = 0;
01820 KOAgendaItem *current = 0;
01821 QPtrList<KOAgendaItem> multiItems;
01822 const int visibleCount = mSelectedDates.first().daysTo( mSelectedDates.last() );
01823 for ( cellX = XBegin; cellX <= XEnd; ++cellX ) {
01824 ++count;
01825
01826 if( cellX >= 0 && cellX <= visibleCount ) {
01827 if ( cellX == XBegin ) {
01828 cellYTop = YTop;
01829 } else {
01830 cellYTop = 0;
01831 }
01832
01833 if ( cellX == XEnd ) {
01834 cellYBottom = YBottom;
01835 } else {
01836 cellYBottom = rows() - 1;
01837 }
01838
01839 newtext = QString("(%1/%2): ").arg( count ).arg( width );
01840 newtext.append( event->summary() );
01841
01842 current = insertItem( event, qd, cellX, cellYTop, cellYBottom, count, width );
01843 current->setText( newtext );
01844 multiItems.append( current );
01845 }
01846 }
01847 QPtrList<KOAgendaItem>::iterator it = multiItems.begin();
01848 QPtrList<KOAgendaItem>::iterator e = multiItems.end();
01849
01850 if ( it != e ) {
01851 KOAgendaItem *first = multiItems.first();
01852 KOAgendaItem *last = multiItems.last();
01853 KOAgendaItem *prev = 0, *next = 0;
01854
01855 while ( it != e ) {
01856 KOAgendaItem *item = *it;
01857 ++it;
01858 next = ( it == e ) ? 0 : (*it);
01859 if ( item ) {
01860 item->setMultiItem( ( item == first ) ? 0 : first,
01861 prev, next,
01862 ( item == last ) ? 0 : last );
01863 }
01864 prev = item;
01865 }
01866 }
01867
01868 marcus_bains();
01869 }
01870
01871 void KOAgenda::removeIncidence( Incidence *incidence, bool relayoutNeighbours )
01872 {
01873
01874
01875
01876 QValueList<KOAgendaItem::GPtr > itemsToRemove;
01877
01878 AgendaItemList::Iterator it;
01879 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01880 if ( *it ) {
01881 if ( (*it)->incidence() == incidence ) {
01882 itemsToRemove.append( *it );
01883 }
01884 }
01885 }
01886
01887 for ( it = itemsToRemove.begin(); it != itemsToRemove.end(); ++it ) {
01888 removeAgendaItem( *it, relayoutNeighbours );
01889 }
01890 }
01891
01892 void KOAgenda::showAgendaItem( KOAgendaItem::GPtr agendaItem )
01893 {
01894 if ( !agendaItem ) {
01895 return;
01896 }
01897
01898 agendaItem->hide();
01899 addChild( agendaItem );
01900 if ( !mItems.contains( agendaItem ) ) {
01901 mItems.append( agendaItem );
01902 }
01903 placeSubCells( agendaItem );
01904
01905 agendaItem->show();
01906 }
01907
01908 bool KOAgenda::removeAgendaItem( KOAgendaItem::GPtr item, bool relayoutNeighbours )
01909 {
01910
01911 bool taken = false;
01912 KOAgendaItem::GPtr thisItem = item;
01913 AgendaItemList conflictItems = thisItem->conflictItems();
01914 removeChild( thisItem );
01915
01916 AgendaItemList::Iterator it = mItems.find( thisItem );
01917 if ( it != mItems.end() ) {
01918 mItems.remove( it );
01919 taken = true;
01920 }
01921
01922 if ( relayoutNeighbours ) {
01923 for ( it = conflictItems.begin(); it != conflictItems.end(); ++it ) {
01924
01925 if ( *it != thisItem ) {
01926 placeSubCells( *it );
01927 }
01928 }
01929 }
01930
01931 mItemsToDelete.append( thisItem );
01932 QTimer::singleShot( 0, this, SLOT( deleteItemsToDelete() ) );
01933 return taken;
01934 }
01935
01936 void KOAgenda::deleteItemsToDelete()
01937 {
01938 freeItemList( mItemsToDelete );
01939 mItemsToDelete.clear();
01940 }
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960 void KOAgenda::resizeEvent ( QResizeEvent *ev )
01961 {
01962
01963
01964 QSize newSize( ev->size() );
01965 if (mAllDayMode) {
01966 mGridSpacingX = double( newSize.width() - 2 * frameWidth() ) / (double)mColumns;
01967 mGridSpacingY = newSize.height() - 2 * frameWidth();
01968 } else {
01969 int scrollbarWidth = vScrollBarMode() != AlwaysOff ? verticalScrollBar()->width() : 0;
01970 mGridSpacingX = double( newSize.width() - scrollbarWidth - 2 * frameWidth()) / double(mColumns);
01971
01972 mGridSpacingY = double(newSize.height() - 2 * frameWidth()) / double(mRows);
01973 if ( mGridSpacingY < mDesiredGridSpacingY )
01974 mGridSpacingY = mDesiredGridSpacingY;
01975 }
01976 calculateWorkingHours();
01977 QTimer::singleShot( 0, this, SLOT( resizeAllContents() ) );
01978 emit gridSpacingYChanged( mGridSpacingY * 4 );
01979 QScrollView::resizeEvent(ev);
01980 }
01981
01982 void KOAgenda::resizeAllContents()
01983 {
01984
01985 double subCellWidth;
01986
01987 if ( mItems.count() > 0 ) {
01988 KOAgendaItem::GPtr item;
01989 if ( mAllDayMode ) {
01990 AgendaItemList::Iterator it;
01991 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01992 if ( *it ) {
01993 subCellWidth = calcSubCellWidth( *it );
01994 placeAgendaItem( *it, subCellWidth );
01995 }
01996 }
01997 } else {
01998 AgendaItemList::Iterator it;
01999 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
02000 if ( *it ) {
02001 subCellWidth = calcSubCellWidth( *it );
02002 placeAgendaItem( *it, subCellWidth );
02003 }
02004 }
02005 }
02006 }
02007 checkScrollBoundaries();
02008 marcus_bains();
02009 }
02010
02011 void KOAgenda::scrollUp()
02012 {
02013 scrollBy(0,-mScrollOffset);
02014 }
02015
02016
02017 void KOAgenda::scrollDown()
02018 {
02019 scrollBy(0,mScrollOffset);
02020 }
02021
02022
02023
02024
02025
02026 int KOAgenda::minimumWidth() const
02027 {
02028
02029 int min = 100;
02030
02031 return min;
02032 }
02033
02034 void KOAgenda::updateConfig()
02035 {
02036 double oldGridSpacingY = mGridSpacingY;
02037
02038 mDesiredGridSpacingY = KOPrefs::instance()->mHourSize;
02039 if ( mDesiredGridSpacingY < 4 || mDesiredGridSpacingY > 30 ) {
02040 mDesiredGridSpacingY = 10;
02041 }
02042
02043
02044 mGridSpacingY = (double)height() / (double)mRows;
02045 if ( mGridSpacingY < mDesiredGridSpacingY ) {
02046 mGridSpacingY = mDesiredGridSpacingY;
02047 }
02048
02049
02050 if ( fabs( oldGridSpacingY - mGridSpacingY ) > 0.1 ) {
02051 resizeContents( int( mGridSpacingX * mColumns ),
02052 int( mGridSpacingY * mRows ) );
02053 }
02054
02055 calculateWorkingHours();
02056
02057 marcus_bains();
02058 }
02059
02060 void KOAgenda::checkScrollBoundaries()
02061 {
02062
02063 mOldLowerScrollValue = -1;
02064 mOldUpperScrollValue = -1;
02065
02066 checkScrollBoundaries(verticalScrollBar()->value());
02067 }
02068
02069 void KOAgenda::checkScrollBoundaries( int v )
02070 {
02071 int yMin = int( (v) / mGridSpacingY );
02072 int yMax = int( ( v + visibleHeight() ) / mGridSpacingY );
02073
02074
02075
02076 if ( yMin != mOldLowerScrollValue ) {
02077 mOldLowerScrollValue = yMin;
02078 emit lowerYChanged(yMin);
02079 }
02080 if ( yMax != mOldUpperScrollValue ) {
02081 mOldUpperScrollValue = yMax;
02082 emit upperYChanged(yMax);
02083 }
02084 }
02085
02086 int KOAgenda::visibleContentsYMin()
02087 {
02088 int v = verticalScrollBar()->value();
02089 return int( v / mGridSpacingY );
02090 }
02091
02092 int KOAgenda::visibleContentsYMax()
02093 {
02094 int v = verticalScrollBar()->value();
02095 return int( ( v + visibleHeight() ) / mGridSpacingY );
02096 }
02097
02098 void KOAgenda::deselectItem()
02099 {
02100 if ( mSelectedItem.isNull() ) {
02101 return;
02102 }
02103 mSelectedItem->select(false);
02104 mSelectedItem = 0;
02105 }
02106
02107 void KOAgenda::selectItem( KOAgendaItem::GPtr item )
02108 {
02109 if ((KOAgendaItem *)mSelectedItem == item) return;
02110 deselectItem();
02111 if ( !item ) {
02112 emit incidenceSelected( 0, QDate() );
02113 return;
02114 }
02115 mSelectedItem = item;
02116 mSelectedItem->select();
02117 assert( mSelectedItem->incidence() );
02118 mSelectedUid = mSelectedItem->incidence()->uid();
02119 emit incidenceSelected( mSelectedItem->incidence(), mSelectedItem->itemDate() );
02120 }
02121
02122 void KOAgenda::selectItemByUID( const QString& uid )
02123 {
02124 KOAgendaItem::GPtr item;
02125 AgendaItemList::Iterator it;
02126 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
02127 if ( *it && (*it)->incidence() && (*it)->incidence()->uid() == uid ) {
02128 selectItem( *it );
02129 break;
02130 }
02131 }
02132 }
02133
02134
02135 void KOAgenda::keyPressEvent( QKeyEvent *kev )
02136 {
02137 switch(kev->key()) {
02138 case Key_PageDown:
02139 verticalScrollBar()->addPage();
02140 break;
02141 case Key_PageUp:
02142 verticalScrollBar()->subtractPage();
02143 break;
02144 case Key_Down:
02145 verticalScrollBar()->addLine();
02146 break;
02147 case Key_Up:
02148 verticalScrollBar()->subtractLine();
02149 break;
02150 default:
02151 ;
02152 }
02153 }
02154
02155 void KOAgenda::calculateWorkingHours()
02156 {
02157 mWorkingHoursEnable = !mAllDayMode;
02158
02159 QTime tmp = KOPrefs::instance()->mWorkingHoursStart.time();
02160 mWorkingHoursYTop = int( 4 * mGridSpacingY *
02161 ( tmp.hour() + tmp.minute() / 60. +
02162 tmp.second() / 3600. ) );
02163 tmp = KOPrefs::instance()->mWorkingHoursEnd.time();
02164 mWorkingHoursYBottom = int( 4 * mGridSpacingY *
02165 ( tmp.hour() + tmp.minute() / 60. +
02166 tmp.second() / 3600. ) - 1 );
02167 }
02168
02169
02170 DateList KOAgenda::dateList() const
02171 {
02172 return mSelectedDates;
02173 }
02174
02175 void KOAgenda::setDateList(const DateList &selectedDates)
02176 {
02177 mSelectedDates = selectedDates;
02178 marcus_bains();
02179 }
02180
02181 void KOAgenda::contentsMousePressEvent ( QMouseEvent *event )
02182 {
02183 kdDebug(5850) << "KOagenda::contentsMousePressEvent(): type: " << event->type() << endl;
02184 QScrollView::contentsMousePressEvent(event);
02185 }
02186
02187 void KOAgenda::setTypeAheadReceiver( QObject *o )
02188 {
02189 mTypeAheadReceiver = o;
02190 }
02191
02192 QObject *KOAgenda::typeAheadReceiver() const
02193 {
02194 return mTypeAheadReceiver;
02195 }
02196
02197 void KOAgenda::setHolidayMask(QMemArray<bool> *mask)
02198 {
02199 mHolidayMask = mask;
02200 }