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 Todo *todo = factory.createDropTodo( de );
00452 if ( todo ) {
00453 de->accept();
00454 delete todo;
00455 } else {
00456 de->ignore();
00457 }
00458 return true;
00459 } else return false;
00460 break;
00461 case QEvent::DragLeave:
00462 return false;
00463 break;
00464 case QEvent::Drop:
00465 {
00466 if ( !ICalDrag::canDecode( de ) && !VCalDrag::canDecode( de ) ) {
00467 return false;
00468 }
00469
00470 DndFactory factory( mCalendar );
00471 Todo *todo = factory.createDropTodo( de );
00472
00473 if ( todo ) {
00474 de->acceptAction();
00475 QPoint pos;
00476
00477
00478
00479 if ( object == this ) {
00480 pos = viewportPos + QPoint( contentsX(), contentsY() );
00481 } else {
00482 pos = viewportToContents( viewportPos );
00483 }
00484 QPoint gpos = contentsToGrid( pos );
00485 emit droppedToDo( todo, gpos, mAllDayMode );
00486 return true;
00487 }
00488 }
00489 break;
00490
00491 case QEvent::DragResponse:
00492 default:
00493 break;
00494 }
00495 #endif
00496
00497 return false;
00498 }
00499
00500 bool KOAgenda::eventFilter_key( QObject *, QKeyEvent *ke )
00501 {
00502
00503
00504
00505 if ( ke->key() == Key_Return ) {
00506 if ( ke->type() == QEvent::KeyPress ) mReturnPressed = true;
00507 else if ( ke->type() == QEvent::KeyRelease ) {
00508 if ( mReturnPressed ) {
00509 emitNewEventForSelection();
00510 mReturnPressed = false;
00511 return true;
00512 } else {
00513 mReturnPressed = false;
00514 }
00515 }
00516 }
00517
00518
00519 if ( ke->text().isEmpty() ) return false;
00520
00521 if ( ke->type() == QEvent::KeyPress || ke->type() == QEvent::KeyRelease ) {
00522 switch ( ke->key() ) {
00523 case Key_Escape:
00524 case Key_Return:
00525 case Key_Enter:
00526 case Key_Tab:
00527 case Key_Backtab:
00528 case Key_Left:
00529 case Key_Right:
00530 case Key_Up:
00531 case Key_Down:
00532 case Key_Backspace:
00533 case Key_Delete:
00534 case Key_Prior:
00535 case Key_Next:
00536 case Key_Home:
00537 case Key_End:
00538 case Key_Control:
00539 case Key_Meta:
00540 case Key_Alt:
00541 break;
00542 default:
00543 mTypeAheadEvents.append( new QKeyEvent( ke->type(), ke->key(),
00544 ke->ascii(), ke->state(),
00545 ke->text(), ke->isAutoRepeat(),
00546 ke->count() ) );
00547 if ( !mTypeAhead ) {
00548 mTypeAhead = true;
00549 emitNewEventForSelection();
00550 }
00551 return true;
00552 }
00553 }
00554 return false;
00555 }
00556
00557 void KOAgenda::emitNewEventForSelection()
00558 {
00559 QPair<ResourceCalendar *, QString>p = mCalendarView->viewSubResourceCalendar();
00560 emit newEventSignal( p.first, p.second );
00561 }
00562
00563 void KOAgenda::finishTypeAhead()
00564 {
00565
00566 if ( typeAheadReceiver() ) {
00567 for( QEvent *e = mTypeAheadEvents.first(); e;
00568 e = mTypeAheadEvents.next() ) {
00569
00570 QApplication::sendEvent( typeAheadReceiver(), e );
00571 }
00572 }
00573 mTypeAheadEvents.clear();
00574 mTypeAhead = false;
00575 }
00576 #ifndef QT_NO_WHEELEVENT
00577 bool KOAgenda::eventFilter_wheel ( QObject *object, QWheelEvent *e )
00578 {
00579 QPoint viewportPos;
00580 bool accepted=false;
00581 if ( ( e->state() & ShiftButton) == ShiftButton ) {
00582 if ( object != viewport() ) {
00583 viewportPos = ( (QWidget *) object )->mapToParent( e->pos() );
00584 } else {
00585 viewportPos = e->pos();
00586 }
00587
00588
00589 emit zoomView( -e->delta() ,
00590 contentsToGrid( viewportToContents( viewportPos ) ),
00591 Qt::Horizontal );
00592 accepted=true;
00593 }
00594
00595 if ( ( e->state() & ControlButton ) == ControlButton ){
00596 if ( object != viewport() ) {
00597 viewportPos = ( (QWidget *)object )->mapToParent( e->pos() );
00598 } else {
00599 viewportPos = e->pos();
00600 }
00601 emit zoomView( -e->delta() ,
00602 contentsToGrid( viewportToContents( viewportPos ) ),
00603 Qt::Vertical );
00604 emit mousePosSignal(gridToContents(contentsToGrid(viewportToContents( viewportPos ))));
00605 accepted=true;
00606 }
00607 if (accepted ) e->accept();
00608 return accepted;
00609 }
00610 #endif
00611 bool KOAgenda::eventFilter_mouse(QObject *object, QMouseEvent *me)
00612 {
00613 QPoint viewportPos;
00614 if (object != viewport()) {
00615 viewportPos = ((QWidget *)object)->mapToParent(me->pos());
00616 } else {
00617 viewportPos = me->pos();
00618 }
00619
00620 switch (me->type()) {
00621 case QEvent::MouseButtonPress:
00622
00623 if (object != viewport()) {
00624 if (me->button() == RightButton) {
00625 mClickedItem = dynamic_cast<KOAgendaItem *>(object);
00626 if (mClickedItem) {
00627 selectItem(mClickedItem);
00628 emit showIncidencePopupSignal( mCalendar,
00629 mClickedItem->incidence(),
00630 mClickedItem->itemDate() );
00631 } else {
00632 return QScrollView::eventFilter( object, me );
00633 }
00634 } else {
00635 KOAgendaItem* item = dynamic_cast<KOAgendaItem *>(object);
00636 if (item) {
00637 Incidence *incidence = item->incidence();
00638 if ( incidence->isReadOnly() ) {
00639 mActionItem = 0;
00640 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00641 } else {
00642 mActionItem = item;
00643 mResPair = CalHelper::incSubResourceCalendar( mCalendar, incidence );
00644 startItemAction(viewportPos);
00645 }
00646
00647
00648
00649
00650 selectItem( item );
00651 } else {
00652 return QScrollView::eventFilter( object, me );
00653 }
00654 }
00655 } else {
00656 if ( me->button() == RightButton ) {
00657
00658 QPoint gpos = contentsToGrid( viewportToContents( viewportPos ) );
00659 if ( !ptInSelection( gpos ) ) {
00660 mSelectionStartCell = gpos;
00661 mSelectionEndCell = gpos;
00662 mHasSelection = true;
00663 emit newStartSelectSignal();
00664 emit newTimeSpanSignal( mSelectionStartCell, mSelectionEndCell );
00665 updateContents();
00666 }
00667 showNewEventPopupSignal();
00668 } else {
00669
00670 QPoint gpos = contentsToGrid( viewportToContents( viewportPos ) );
00671 if ( !ptInSelection( gpos ) ) {
00672 selectItem(0);
00673 mActionItem = 0;
00674 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00675 setCursor(arrowCursor);
00676 startSelectAction(viewportPos);
00677 }
00678 }
00679 return QScrollView::eventFilter( object, me );
00680 }
00681 break;
00682
00683 case QEvent::MouseButtonRelease:
00684 if (mActionItem) {
00685 endItemAction();
00686 } else if ( mActionType == SELECT ) {
00687 endSelectAction( viewportPos );
00688 }
00689
00690
00691 emit mousePosSignal( gridToContents(contentsToGrid(
00692 viewportToContents( viewportPos ) ) ));
00693 break;
00694
00695 case QEvent::MouseMove: {
00696
00697
00698 QPoint indicatorPos = gridToContents(contentsToGrid(
00699 viewportToContents( viewportPos )));
00700 if (object != viewport()) {
00701 KOAgendaItem *moveItem = dynamic_cast<KOAgendaItem *>(object);
00702 if (moveItem && !moveItem->incidence()->isReadOnly() ) {
00703 if (!mActionItem)
00704 setNoActionCursor(moveItem,viewportPos);
00705 else {
00706 performItemAction(viewportPos);
00707
00708 if ( mActionType == MOVE ) {
00709
00710 KOAgendaItem *firstItem = mActionItem->firstMultiItem();
00711 if (!firstItem) firstItem = mActionItem;
00712 indicatorPos = gridToContents( QPoint( firstItem->cellXLeft(),
00713 firstItem->cellYTop() ) );
00714
00715 } else if ( mActionType == RESIZEBOTTOM ) {
00716
00717 indicatorPos = gridToContents( QPoint( mActionItem->cellXLeft(),
00718 mActionItem->cellYBottom()+1 ) );
00719 }
00720
00721 }
00722 }
00723 } else {
00724 if ( mActionType == SELECT ) {
00725 performSelectAction( viewportPos );
00726
00727
00728 if ( ((mStartCell.y() < mEndCell.y()) && (mEndCell.x() >= mStartCell.x())) ||
00729 (mEndCell.x() > mStartCell.x()) )
00730 indicatorPos = gridToContents( QPoint(mEndCell.x(), mEndCell.y()+1) );
00731 else
00732 indicatorPos = gridToContents( mEndCell );
00733 }
00734 }
00735 emit mousePosSignal( indicatorPos );
00736 break; }
00737
00738 case QEvent::MouseButtonDblClick:
00739 if (object == viewport()) {
00740 selectItem(0);
00741 QPair<ResourceCalendar *, QString>p = mCalendarView->viewSubResourceCalendar();
00742 emit newEventSignal( p.first, p.second );
00743 } else {
00744 KOAgendaItem *doubleClickedItem = dynamic_cast<KOAgendaItem *>( object );
00745 if ( doubleClickedItem ) {
00746 selectItem( doubleClickedItem );
00747 emit editIncidenceSignal( doubleClickedItem->incidence(), doubleClickedItem->itemDate() );
00748 }
00749 }
00750 break;
00751
00752 default:
00753 break;
00754 }
00755
00756 return true;
00757 }
00758
00759 bool KOAgenda::ptInSelection( QPoint gpos ) const
00760 {
00761 if ( !mHasSelection ) {
00762 return false;
00763 } else if ( gpos.x()<mSelectionStartCell.x() || gpos.x()>mSelectionEndCell.x() ) {
00764 return false;
00765 } else if ( (gpos.x()==mSelectionStartCell.x()) && (gpos.y()<mSelectionStartCell.y()) ) {
00766 return false;
00767 } else if ( (gpos.x()==mSelectionEndCell.x()) && (gpos.y()>mSelectionEndCell.y()) ) {
00768 return false;
00769 }
00770 return true;
00771 }
00772
00773 void KOAgenda::startSelectAction( const QPoint &viewportPos )
00774 {
00775 emit newStartSelectSignal();
00776
00777 mActionType = SELECT;
00778 mSelectionStartPoint = viewportPos;
00779 mHasSelection = true;
00780
00781 QPoint pos = viewportToContents( viewportPos );
00782 QPoint gpos = contentsToGrid( pos );
00783
00784
00785 mStartCell = gpos;
00786 mEndCell = gpos;
00787 mSelectionStartCell = gpos;
00788 mSelectionEndCell = gpos;
00789
00790 updateContents();
00791 }
00792
00793 void KOAgenda::performSelectAction(const QPoint& viewportPos)
00794 {
00795 QPoint pos = viewportToContents( viewportPos );
00796 QPoint gpos = contentsToGrid( pos );
00797
00798 QPoint clipperPos = clipper()->
00799 mapFromGlobal(viewport()->mapToGlobal(viewportPos));
00800
00801
00802 if (clipperPos.y() < mScrollBorderWidth) {
00803 mScrollUpTimer.start(mScrollDelay);
00804 } else if (visibleHeight() - clipperPos.y() <
00805 mScrollBorderWidth) {
00806 mScrollDownTimer.start(mScrollDelay);
00807 } else {
00808 mScrollUpTimer.stop();
00809 mScrollDownTimer.stop();
00810 }
00811
00812 if ( gpos != mEndCell ) {
00813 mEndCell = gpos;
00814 if ( mStartCell.x()>mEndCell.x() ||
00815 ( mStartCell.x()==mEndCell.x() && mStartCell.y()>mEndCell.y() ) ) {
00816
00817 mSelectionStartCell = mEndCell;
00818 mSelectionEndCell = mStartCell;
00819 } else {
00820 mSelectionStartCell = mStartCell;
00821 mSelectionEndCell = mEndCell;
00822 }
00823
00824 updateContents();
00825 }
00826 }
00827
00828 void KOAgenda::endSelectAction( const QPoint ¤tPos )
00829 {
00830 mScrollUpTimer.stop();
00831 mScrollDownTimer.stop();
00832
00833 mActionType = NOP;
00834
00835 emit newTimeSpanSignal( mSelectionStartCell, mSelectionEndCell );
00836
00837 if ( KOPrefs::instance()->mSelectionStartsEditor ) {
00838 if ( ( mSelectionStartPoint - currentPos ).manhattanLength() >
00839 QApplication::startDragDistance() ) {
00840 emitNewEventForSelection();
00841 }
00842 }
00843 }
00844
00845 KOAgenda::MouseActionType KOAgenda::isInResizeArea( bool horizontal,
00846 const QPoint &pos,
00847 KOAgendaItem::GPtr item )
00848 {
00849 if ( !item ) {
00850 return NOP;
00851 }
00852
00853 QPoint gridpos = contentsToGrid( pos );
00854 QPoint contpos = gridToContents( gridpos +
00855 QPoint( (KOGlobals::self()->reverseLayout())?1:0, 0 ) );
00856
00857
00858
00859
00860 if ( horizontal ) {
00861 int clXLeft = item->cellXLeft();
00862 int clXRight = item->cellXRight();
00863 if ( KOGlobals::self()->reverseLayout() ) {
00864 int tmp = clXLeft;
00865 clXLeft = clXRight;
00866 clXRight = tmp;
00867 }
00868 int gridDistanceX = int( pos.x() - contpos.x() );
00869 if (gridDistanceX < mResizeBorderWidth && clXLeft == gridpos.x() ) {
00870 if ( KOGlobals::self()->reverseLayout() ) return RESIZERIGHT;
00871 else return RESIZELEFT;
00872 } else if ((mGridSpacingX - gridDistanceX) < mResizeBorderWidth &&
00873 clXRight == gridpos.x() ) {
00874 if ( KOGlobals::self()->reverseLayout() ) return RESIZELEFT;
00875 else return RESIZERIGHT;
00876 } else {
00877 return MOVE;
00878 }
00879 } else {
00880 int gridDistanceY = int( pos.y() - contpos.y() );
00881 if (gridDistanceY < mResizeBorderWidth &&
00882 item->cellYTop() == gridpos.y() &&
00883 !item->firstMultiItem() ) {
00884 return RESIZETOP;
00885 } else if ((mGridSpacingY - gridDistanceY) < mResizeBorderWidth &&
00886 item->cellYBottom() == gridpos.y() &&
00887 !item->lastMultiItem() ) {
00888 return RESIZEBOTTOM;
00889 } else {
00890 return MOVE;
00891 }
00892 }
00893 }
00894
00895 void KOAgenda::startItemAction(const QPoint& viewportPos)
00896 {
00897 QPoint pos = viewportToContents( viewportPos );
00898 mStartCell = contentsToGrid( pos );
00899 mEndCell = mStartCell;
00900
00901 bool noResize = ( mActionItem->incidence()->type() == "Todo");
00902
00903 mActionType = MOVE;
00904 if ( !noResize ) {
00905 mActionType = isInResizeArea( mAllDayMode, pos, mActionItem );
00906 }
00907
00908
00909 mActionItem->startMove();
00910 setActionCursor( mActionType, true );
00911 }
00912
00913 void KOAgenda::performItemAction(const QPoint& viewportPos)
00914 {
00915
00916
00917
00918
00919
00920
00921 QPoint pos = viewportToContents( viewportPos );
00922
00923 QPoint gpos = contentsToGrid( pos );
00924 QPoint clipperPos = clipper()->
00925 mapFromGlobal(viewport()->mapToGlobal(viewportPos));
00926
00927
00928
00929 if ( clipperPos.y() < 0 || clipperPos.y() > visibleHeight() ||
00930 clipperPos.x() < 0 || clipperPos.x() > visibleWidth() ) {
00931 if ( mActionType == MOVE ) {
00932 mScrollUpTimer.stop();
00933 mScrollDownTimer.stop();
00934 mActionItem->resetMove();
00935 placeSubCells( mActionItem );
00936 emit startDragSignal( mActionItem->incidence() );
00937 setCursor( arrowCursor );
00938 mActionItem = 0;
00939 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00940 mActionType = NOP;
00941 mItemMoved = false;
00942 return;
00943 }
00944 } else {
00945 setActionCursor( mActionType );
00946 }
00947
00948
00949 if (clipperPos.y() < mScrollBorderWidth) {
00950 mScrollUpTimer.start(mScrollDelay);
00951 } else if (visibleHeight() - clipperPos.y() <
00952 mScrollBorderWidth) {
00953 mScrollDownTimer.start(mScrollDelay);
00954 } else {
00955 mScrollUpTimer.stop();
00956 mScrollDownTimer.stop();
00957 }
00958
00959
00960 if ( mEndCell != gpos ) {
00961 if ( !mItemMoved ) {
00962 if ( !mChanger ||
00963 !mChanger->beginChange( mActionItem->incidence(), mResPair.first, mResPair.second ) ) {
00964 KMessageBox::information( this, i18n("Unable to lock item for "
00965 "modification. You cannot make any changes."),
00966 i18n("Locking Failed"), "AgendaLockingFailed" );
00967 mScrollUpTimer.stop();
00968 mScrollDownTimer.stop();
00969 mActionItem->resetMove();
00970 placeSubCells( mActionItem );
00971 setCursor( arrowCursor );
00972 mActionItem = 0;
00973 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
00974 mActionType = NOP;
00975 mItemMoved = false;
00976 return;
00977 }
00978 mItemMoved = true;
00979 }
00980 mActionItem->raise();
00981 if (mActionType == MOVE) {
00982
00983 KOAgendaItem *firstItem = mActionItem->firstMultiItem();
00984 if (!firstItem) firstItem = mActionItem;
00985 KOAgendaItem *lastItem = mActionItem->lastMultiItem();
00986 if (!lastItem) lastItem = mActionItem;
00987 QPoint deltapos = gpos - mEndCell;
00988 KOAgendaItem *moveItem = firstItem;
00989 while (moveItem) {
00990 bool changed=false;
00991 if ( deltapos.x()!=0 ) {
00992 moveItem->moveRelative( deltapos.x(), 0 );
00993 changed=true;
00994 }
00995
00996 if ( moveItem==firstItem && !mAllDayMode ) {
00997 int newY = deltapos.y() + moveItem->cellYTop();
00998
00999 if ( newY<0 ) {
01000 moveItem->expandTop( -moveItem->cellYTop() );
01001
01002 KOAgendaItem *newFirst = firstItem->prevMoveItem();
01003
01004 if (newFirst) {
01005 newFirst->setCellXY(moveItem->cellXLeft()-1, rows()+newY, rows()-1);
01006 mItems.append( newFirst );
01007 moveItem->resize( int( mGridSpacingX * newFirst->cellWidth() ),
01008 int( mGridSpacingY * newFirst->cellHeight() ));
01009 QPoint cpos = gridToContents( QPoint( newFirst->cellXLeft(), newFirst->cellYTop() ) );
01010 addChild( newFirst, cpos.x(), cpos.y() );
01011 } else {
01012 newFirst = insertItem( moveItem->incidence(), moveItem->itemDate(),
01013 moveItem->cellXLeft()-1, rows()+newY, rows()-1, moveItem->itemPos(), moveItem->itemCount() ) ;
01014 }
01015 if (newFirst) newFirst->show();
01016 moveItem->prependMoveItem(newFirst);
01017 firstItem=newFirst;
01018 } else if ( newY>=rows() ) {
01019
01020
01021 firstItem = moveItem->nextMultiItem();
01022 moveItem->hide();
01023 mItems.remove( mItems.find( moveItem ) );
01024 removeChild( moveItem );
01025 mActionItem->removeMoveItem(moveItem);
01026 moveItem=firstItem;
01027
01028 if (moveItem) moveItem->expandTop( rows()-newY );
01029 } else {
01030 moveItem->expandTop(deltapos.y());
01031 }
01032 changed=true;
01033 }
01034 if ( !moveItem->lastMultiItem() && !mAllDayMode ) {
01035 int newY = deltapos.y()+moveItem->cellYBottom();
01036 if (newY<0) {
01037
01038 lastItem = moveItem->prevMultiItem();
01039 moveItem->hide();
01040 mItems.remove( mItems.find(moveItem) );
01041 removeChild( moveItem );
01042 moveItem->removeMoveItem( moveItem );
01043 moveItem = lastItem;
01044 moveItem->expandBottom(newY+1);
01045 } else if (newY>=rows()) {
01046 moveItem->expandBottom( rows()-moveItem->cellYBottom()-1 );
01047
01048 KOAgendaItem *newLast = lastItem->nextMoveItem();
01049 if (newLast) {
01050 newLast->setCellXY( moveItem->cellXLeft()+1, 0, newY-rows()-1 );
01051 mItems.append(newLast);
01052 moveItem->resize( int( mGridSpacingX * newLast->cellWidth() ),
01053 int( mGridSpacingY * newLast->cellHeight() ));
01054 QPoint cpos = gridToContents( QPoint( newLast->cellXLeft(), newLast->cellYTop() ) ) ;
01055 addChild( newLast, cpos.x(), cpos.y() );
01056 } else {
01057 newLast = insertItem( moveItem->incidence(), moveItem->itemDate(),
01058 moveItem->cellXLeft()+1, 0, newY-rows()-1, moveItem->itemPos(), moveItem->itemCount() ) ;
01059 }
01060 moveItem->appendMoveItem( newLast );
01061 newLast->show();
01062 lastItem = newLast;
01063 } else {
01064 moveItem->expandBottom( deltapos.y() );
01065 }
01066 changed=true;
01067 }
01068 if (changed) {
01069 adjustItemPosition( moveItem );
01070 }
01071 moveItem = moveItem->nextMultiItem();
01072 }
01073 } else if (mActionType == RESIZETOP) {
01074 if (mEndCell.y() <= mActionItem->cellYBottom()) {
01075 mActionItem->expandTop(gpos.y() - mEndCell.y());
01076 adjustItemPosition( mActionItem );
01077 }
01078 } else if (mActionType == RESIZEBOTTOM) {
01079 if (mEndCell.y() >= mActionItem->cellYTop()) {
01080 mActionItem->expandBottom(gpos.y() - mEndCell.y());
01081 adjustItemPosition( mActionItem );
01082 }
01083 } else if (mActionType == RESIZELEFT) {
01084 if (mEndCell.x() <= mActionItem->cellXRight()) {
01085 mActionItem->expandLeft( gpos.x() - mEndCell.x() );
01086 adjustItemPosition( mActionItem );
01087 }
01088 } else if (mActionType == RESIZERIGHT) {
01089 if (mEndCell.x() >= mActionItem->cellXLeft()) {
01090 mActionItem->expandRight(gpos.x() - mEndCell.x());
01091 adjustItemPosition( mActionItem );
01092 }
01093 }
01094 mEndCell = gpos;
01095 }
01096 }
01097
01098 void KOAgenda::endItemAction()
01099 {
01100
01101 mActionType = NOP;
01102 mScrollUpTimer.stop();
01103 mScrollDownTimer.stop();
01104 setCursor( arrowCursor );
01105 bool useLastGroupwareDialogAnswer = false;
01106 bool addIncidence = false;
01107 bool multiModify = false;
01108
01109 Incidence *inc = mActionItem->incidence();
01110
01111 if ( mStartCell.x() == mEndCell.x() && mStartCell.y() == mEndCell.y() ) {
01112
01113 if ( mItemMoved ) {
01114 mItemMoved = false;
01115 mChanger->endChange( inc, mResPair.first, mResPair.second );
01116 }
01117 }
01118
01119 if ( mItemMoved ) {
01120 Incidence *incToChange = inc;
01121 if ( mActionItem->incidence()->doesRecur() ) {
01122
01123 kdDebug() << "mActionItem->incidence()->dtStart() is " << inc->dtStart() << endl;
01124
01125 Incidence* oldIncSaved = inc->clone();
01126 KOGlobals::WhichOccurrences chosenOption;
01127 incToChange = mCalendarView->singleOccurrenceOrAll( inc,
01128 KOGlobals::EDIT,
01129 chosenOption,
01130 mActionItem->itemDate() );
01131
01132 if ( chosenOption == KOGlobals::ONLY_THIS_ONE ||
01133 chosenOption == KOGlobals::ONLY_FUTURE ) {
01134 multiModify = true;
01135 mAgendaView->enableAgendaUpdate( false );
01136 useLastGroupwareDialogAnswer = true;
01137 addIncidence = true;
01138 mAgendaView->enableAgendaUpdate( true );
01139 KOGlobals::WhatChanged wc = chosenOption == KOGlobals::ONLY_THIS_ONE ?
01140 KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY :
01141 KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE;
01142
01143 const bool success = mChanger->changeIncidence( oldIncSaved, inc, wc, this );
01144
01145 if ( success ) {
01146 mActionItem->dissociateFromMultiItem();
01147 mActionItem->setIncidence( incToChange );
01148 } else {
01149 incToChange = 0;
01150 }
01151 }
01152 }
01153
01154 if ( incToChange ) {
01155 mActionItem->endMove();
01156 KOAgendaItem *placeItem = mActionItem->firstMultiItem();
01157 if ( !placeItem ) {
01158 placeItem = mActionItem;
01159 }
01160
01161 KOAgendaItem *modif = placeItem;
01162 AgendaItemList oldconflictItems = placeItem->conflictItems();
01163
01164 AgendaItemList::Iterator it;
01165 for ( it = oldconflictItems.begin(); it != oldconflictItems.end(); ++it ) {
01166 if ( *it ) {
01167 placeSubCells( *it );
01168 }
01169 }
01170
01171 while ( placeItem ) {
01172 placeSubCells( placeItem );
01173 placeItem = placeItem->nextMultiItem();
01174 }
01175
01176
01177
01178 mChanger->endChange( inc, mResPair.first, mResPair.second );
01179 kdDebug() << "Modified." << endl;
01180 mAgendaView->updateEventDates( modif, useLastGroupwareDialogAnswer, mResPair.first, mResPair.second, addIncidence );
01181 } else {
01182 mActionItem->resetMove();
01183 placeSubCells( mActionItem );
01184
01185
01186
01187 mChanger->endChange( inc, mResPair.first, mResPair.second );
01188 kdDebug() << "Not modified." << endl;
01189 mAgendaView->updateEventDates( mActionItem,
01190 useLastGroupwareDialogAnswer,
01191 mResPair.first,
01192 mResPair.second,
01193 addIncidence );
01194 }
01195 }
01196
01197 mActionItem = 0;
01198 mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), QString() );
01199 mItemMoved = false;
01200
01201 if ( multiModify ) {
01202 emit endMultiModify();
01203 }
01204
01205 kdDebug(5850) << "KOAgenda::endItemAction() done" << endl;
01206 }
01207
01208 void KOAgenda::setActionCursor( int actionType, bool acting )
01209 {
01210 switch ( actionType ) {
01211 case MOVE:
01212 if (acting) setCursor( sizeAllCursor );
01213 else setCursor( arrowCursor );
01214 break;
01215 case RESIZETOP:
01216 case RESIZEBOTTOM:
01217 setCursor( sizeVerCursor );
01218 break;
01219 case RESIZELEFT:
01220 case RESIZERIGHT:
01221 setCursor( sizeHorCursor );
01222 break;
01223 default:
01224 setCursor( arrowCursor );
01225 }
01226 }
01227
01228 void KOAgenda::setNoActionCursor( KOAgendaItem::GPtr moveItem, const QPoint& viewportPos )
01229 {
01230
01231
01232
01233
01234
01235
01236 if ( !moveItem ) {
01237 return;
01238 }
01239
01240 QPoint pos = viewportToContents( viewportPos );
01241 bool noResize = (moveItem && moveItem->incidence() &&
01242 moveItem->incidence()->type() == "Todo");
01243
01244 KOAgenda::MouseActionType resizeType = MOVE;
01245 if ( !noResize ) resizeType = isInResizeArea( mAllDayMode, pos , moveItem);
01246 setActionCursor( resizeType );
01247 }
01248
01249
01253 double KOAgenda::calcSubCellWidth( KOAgendaItem::GPtr item )
01254 {
01255 if ( !item ) {
01256 return 0;
01257 }
01258
01259 QPoint pt, pt1;
01260 pt = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) );
01261 pt1 = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) +
01262 QPoint( 1, 1 ) );
01263 pt1 -= pt;
01264 int maxSubCells = item->subCells();
01265 double newSubCellWidth;
01266 if ( mAllDayMode ) {
01267 newSubCellWidth = double( pt1.y() ) / maxSubCells;
01268 } else {
01269 newSubCellWidth = double( pt1.x() ) / maxSubCells;
01270 }
01271 return newSubCellWidth;
01272 }
01273
01274 void KOAgenda::adjustItemPosition( KOAgendaItem::GPtr item )
01275 {
01276 if (!item) return;
01277 item->resize( int( mGridSpacingX * item->cellWidth() ),
01278 int( mGridSpacingY * item->cellHeight() ) );
01279 int clXLeft = item->cellXLeft();
01280 if ( KOGlobals::self()->reverseLayout() )
01281 clXLeft = item->cellXRight() + 1;
01282 QPoint cpos = gridToContents( QPoint( clXLeft, item->cellYTop() ) );
01283 moveChild( item, cpos.x(), cpos.y() );
01284 }
01285
01286 void KOAgenda::placeAgendaItem( KOAgendaItem::GPtr item, double subCellWidth )
01287 {
01288
01289
01290
01291 if ( !item ) {
01292 return;
01293 }
01294
01295
01296 const QPoint pt = gridToContents( QPoint( item->cellXLeft(), item->cellYTop() ) );
01297
01298
01299 const QPoint pt1 = gridToContents( QPoint( item->cellXLeft() + item->cellWidth(),
01300 item->cellYBottom()+1 ) );
01301
01302 const double subCellPos = item->subCell() * subCellWidth;
01303
01304
01305
01306 const double delta = subCellWidth < 0 ? -0.01 : 0.01;
01307
01308 int height, width, xpos, ypos;
01309 if ( mAllDayMode ) {
01310 width = pt1.x()-pt.x();
01311 height = int( subCellPos + subCellWidth + delta ) - int( subCellPos );
01312 xpos = pt.x();
01313 ypos = pt.y() + int( subCellPos );
01314 } else {
01315 width = int( subCellPos + subCellWidth + delta ) - int( subCellPos );
01316 height = pt1.y()-pt.y();
01317 xpos = pt.x() + int( subCellPos );
01318 ypos = pt.y();
01319 }
01320 if ( KOGlobals::self()->reverseLayout() ) {
01321 xpos += width;
01322 width = -width;
01323 }
01324 if ( height<0 ) {
01325 ypos += height;
01326 height = -height;
01327 }
01328 item->resize( width, height );
01329 moveChild( item, xpos, ypos );
01330 }
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345 void KOAgenda::placeSubCells( KOAgendaItem::GPtr placeItem )
01346 {
01347 #if 0
01348 kdDebug(5850) << "KOAgenda::placeSubCells()" << endl;
01349 if ( placeItem ) {
01350 Incidence *event = placeItem->incidence();
01351 if ( !event ) {
01352 kdDebug(5850) << " event is 0" << endl;
01353 } else {
01354 kdDebug(5850) << " event: " << event->summary() << endl;
01355 }
01356 } else {
01357 kdDebug(5850) << " placeItem is 0" << endl;
01358 }
01359 kdDebug(5850) << "KOAgenda::placeSubCells()..." << endl;
01360 #endif
01361
01362 if ( !placeItem ) {
01363 return;
01364 }
01365
01366 QPtrList<KOrg::CellItem> cells;
01367 AgendaItemList::Iterator it;
01368 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01369 if ( *it ) {
01370 cells.append( *it );
01371 }
01372 }
01373
01374 QPtrList<KOrg::CellItem> items = KOrg::CellItem::placeItem( cells,
01375 placeItem );
01376 QPtrList<KOAgendaItem> updatedCells;
01377
01378 KOrg::CellItem *i;
01379 placeItem->setConflictItems( AgendaItemList() );
01380 const double newSubCellWidth = calcSubCellWidth( placeItem );
01381 for ( i = items.first(); i; i = items.next() ) {
01382 KOAgendaItem *item = static_cast<KOAgendaItem *>( i );
01383 placeAgendaItem( item, newSubCellWidth );
01384 item->addConflictItem( placeItem );
01385
01386 if ( placeItem->incidence() && placeItem->incidence()->doesFloat() ) {
01387
01388 updateWidthsRecursivley( item, updatedCells, placeItem->subCells() );
01389 }
01390
01391 placeItem->addConflictItem( item );
01392 }
01393 if ( items.isEmpty() ) {
01394 placeAgendaItem( placeItem, newSubCellWidth );
01395 }
01396 placeItem->update();
01397 }
01398
01400 bool KOAgenda::updateWidthsRecursivley( KOAgendaItem *item,
01401 QPtrList<KOAgendaItem> &itemsAlreadyUpdated,
01402 int numSubCells )
01403 {
01404 bool result = false;
01405 if ( !itemsAlreadyUpdated.contains( item ) ) {
01406 item->setSubCells( numSubCells );
01407
01408
01409 itemsAlreadyUpdated.append( item );
01410
01411
01412 AgendaItemList list = item->conflictItems();
01413
01414 for ( int i = 0; i < list.count(); ++i ) {
01415 KOAgendaItem::GPtr it = list[i];
01416 if ( it && numSubCells > it->subCells() ) {
01417 updateWidthsRecursivley( it, itemsAlreadyUpdated, numSubCells );
01418 result = true;
01419 }
01420 }
01421 }
01422
01423 return result;
01424 }
01425
01426 int KOAgenda::columnWidth( int column )
01427 {
01428 const int start = gridToContents( QPoint( column, 0 ) ).x();
01429 if (KOGlobals::self()->reverseLayout() )
01430 column--;
01431 else
01432 column++;
01433 const int end = gridToContents( QPoint( column, 0 ) ).x();
01434 return end - start;
01435 }
01436
01437
01438
01439 void KOAgenda::drawContents(QPainter* p, int cx, int cy, int cw, int ch)
01440 {
01441 QPixmap db(cw, ch);
01442 db.fill(KOPrefs::instance()->mAgendaBgColor);
01443 QPainter dbp(&db);
01444 dbp.translate(-cx,-cy);
01445
01446 double lGridSpacingY = mGridSpacingY*2;
01447
01448
01449
01450
01451
01452 const QMemArray<bool> busyDayMask = mAgendaView->busyDayMask();
01453
01454 if ( KOPrefs::instance()->mColorBusyDaysEnabled && !mAllDayMode ) {
01455 for ( int i = 0; i < busyDayMask.count(); ++i ) {
01456 if ( busyDayMask[i] ) {
01457 const QPoint pt1( cx + mGridSpacingX * i, 0 );
01458
01459 dbp.fillRect( pt1.x(), pt1.y(), mGridSpacingX, cy + ch, KOPrefs::instance()->mAgendaMonthBgBusyColor );
01460 }
01461 }
01462 }
01463
01464 if ( mWorkingHoursEnable ) {
01465
01466 QColor workAndBusyColor;
01467
01468 if ( KOPrefs::instance()->mColorBusyDaysEnabled ) {
01469 workAndBusyColor = KOHelper::mixColors( KOPrefs::instance()->mAgendaMonthBgBusyColor, 0.60, KOPrefs::instance()->mWorkingHoursColor );
01470 } else {
01471 workAndBusyColor = KOPrefs::instance()->mWorkingHoursColor;
01472 }
01473
01474 const QPoint pt1( cx, mWorkingHoursYTop );
01475 const QPoint pt2( cx+cw, mWorkingHoursYBottom );
01476 if ( pt2.x() >= pt1.x() ) {
01477 int gxStart = contentsToGrid( pt1 ).x();
01478 int gxEnd = contentsToGrid( pt2 ).x();
01479
01480 if ( gxStart > gxEnd ) {
01481 const int tmp = gxStart;
01482 gxStart = gxEnd;
01483 gxEnd = tmp;
01484 }
01485 const int xoffset = ( KOGlobals::self()->reverseLayout() ? 1 : 0 );
01486 while( gxStart <= gxEnd ) {
01487 const int xStart = gridToContents( QPoint( gxStart+xoffset, 0 ) ).x();
01488 const int xWidth = columnWidth( gxStart ) + 1;
01489 QColor color;
01490 if ( gxStart < busyDayMask.count() && busyDayMask[gxStart] ) {
01491 color = workAndBusyColor;
01492 } else {
01493 color = KOPrefs::instance()->mWorkingHoursColor;
01494 }
01495 if ( pt2.y() < pt1.y() ) {
01496
01497 if ( ( (gxStart==0) && !mHolidayMask->at(mHolidayMask->count()-1) ) ||
01498 ( (gxStart>0) && (gxStart<int(mHolidayMask->count())) && (!mHolidayMask->at(gxStart-1) ) ) ) {
01499 if ( pt2.y() > cy ) {
01500 dbp.fillRect( xStart, cy, xWidth, pt2.y() - cy + 1, color );
01501 }
01502 }
01503 if ( (gxStart < int(mHolidayMask->count()-1)) && (!mHolidayMask->at(gxStart)) ) {
01504 if ( pt1.y() < cy + ch - 1 ) {
01505 dbp.fillRect( xStart, pt1.y(), xWidth, cy + ch - pt1.y() + 1,
01506 color );
01507 }
01508 }
01509 } else {
01510
01511 if ( gxStart < int(mHolidayMask->count()-1) && !mHolidayMask->at(gxStart)) {
01512 dbp.fillRect( xStart, pt1.y(), xWidth, pt2.y() - pt1.y() + 1,
01513 color );
01514 }
01515 }
01516 ++gxStart;
01517 }
01518 }
01519 }
01520
01521
01522
01523
01524 if ( mHasSelection ) {
01525 QPoint pt, pt1;
01526
01527 if ( mSelectionEndCell.x() > mSelectionStartCell.x() ) {
01528
01529 pt = gridToContents( mSelectionStartCell );
01530 pt1 = gridToContents( QPoint( mSelectionStartCell.x() + 1, mRows + 1 ) );
01531 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01532
01533 for ( int c = mSelectionStartCell.x() + 1; c < mSelectionEndCell.x(); ++c ) {
01534 pt = gridToContents( QPoint( c, 0 ) );
01535 pt1 = gridToContents( QPoint( c + 1, mRows + 1 ) );
01536 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01537 }
01538
01539 pt = gridToContents( QPoint( mSelectionEndCell.x(), 0 ) );
01540 pt1 = gridToContents( mSelectionEndCell + QPoint(1,1) );
01541 dbp.fillRect( QRect( pt, pt1), KOPrefs::instance()->mHighlightColor );
01542 } else {
01543 pt = gridToContents( mSelectionStartCell );
01544 pt1 = gridToContents( mSelectionEndCell + QPoint(1,1) );
01545 dbp.fillRect( QRect( pt, pt1 ), KOPrefs::instance()->mHighlightColor );
01546 }
01547 }
01548
01549 QPen hourPen( KOPrefs::instance()->mAgendaBgColor.dark( 150 ) );
01550 QPen halfHourPen( KOPrefs::instance()->mAgendaBgColor.dark( 125 ) );
01551 dbp.setPen( hourPen );
01552
01553
01554
01555 double x = ( int( cx / mGridSpacingX ) ) * mGridSpacingX;
01556 while (x < cx + cw) {
01557 dbp.drawLine( int( x ), cy, int( x ), cy + ch );
01558 x+=mGridSpacingX;
01559 }
01560
01561
01562 double y = ( int( cy / (2*lGridSpacingY) ) ) * 2 * lGridSpacingY;
01563 while (y < cy + ch) {
01564
01565 dbp.drawLine( cx, int( y ), cx + cw, int( y ) );
01566 y += 2 * lGridSpacingY;
01567 }
01568 y = ( 2 * int( cy / (2*lGridSpacingY) ) + 1) * lGridSpacingY;
01569 dbp.setPen( halfHourPen );
01570 while (y < cy + ch) {
01571
01572 dbp.drawLine( cx, int( y ), cx + cw, int( y ) );
01573 y+=2*lGridSpacingY;
01574 }
01575 p->drawPixmap(cx,cy, db);
01576 }
01577
01578
01579
01580
01581 QPoint KOAgenda::contentsToGrid ( const QPoint &pos ) const
01582 {
01583 int gx = int( KOGlobals::self()->reverseLayout() ?
01584 mColumns - pos.x()/mGridSpacingX : pos.x()/mGridSpacingX );
01585 int gy = int( pos.y()/mGridSpacingY );
01586 return QPoint( gx, gy );
01587 }
01588
01589
01590
01591
01592 QPoint KOAgenda::gridToContents( const QPoint &gpos ) const
01593 {
01594 int x = int( KOGlobals::self()->reverseLayout() ?
01595 (mColumns - gpos.x())*mGridSpacingX : gpos.x()*mGridSpacingX );
01596 int y = int( gpos.y()*mGridSpacingY );
01597 return QPoint( x, y );
01598 }
01599
01600
01601
01602
01603
01604
01605 int KOAgenda::timeToY(const QTime &time)
01606 {
01607
01608 int minutesPerCell = 24 * 60 / mRows;
01609
01610 int timeMinutes = time.hour() * 60 + time.minute();
01611
01612 int Y = (timeMinutes + (minutesPerCell / 2)) / minutesPerCell;
01613
01614
01615 return Y;
01616 }
01617
01618
01619
01620
01621
01622
01623 QTime KOAgenda::gyToTime(int gy)
01624 {
01625
01626 int secondsPerCell = 24 * 60 * 60/ mRows;
01627
01628 int timeSeconds = secondsPerCell * gy;
01629
01630 QTime time( 0, 0, 0 );
01631 if ( timeSeconds < 24 * 60 * 60 ) {
01632 time = time.addSecs(timeSeconds);
01633 } else {
01634 time.setHMS( 23, 59, 59 );
01635 }
01636
01637
01638 return time;
01639 }
01640
01641 QMemArray<int> KOAgenda::minContentsY()
01642 {
01643 QMemArray<int> minArray;
01644 minArray.fill( timeToY( QTime(23, 59) ), mSelectedDates.count() );
01645
01646 AgendaItemList::Iterator it;
01647 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01648 if ( *it ) {
01649 const int ymin = (*it)->cellYTop();
01650 const int index = (*it)->cellXLeft();
01651 if ( index >= 0 && index < static_cast<int>( mSelectedDates.count() ) ) {
01652 if ( ymin < minArray[index] && !mItemsToDelete.contains( *it ) )
01653 minArray[index] = ymin;
01654 }
01655 }
01656 }
01657
01658 return minArray;
01659 }
01660
01661 QMemArray<int> KOAgenda::maxContentsY()
01662 {
01663 QMemArray<int> maxArray;
01664 maxArray.fill( timeToY( QTime(0, 0) ), mSelectedDates.count() );
01665 AgendaItemList::Iterator it;
01666 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01667 if ( *it ) {
01668 const int ymax = (*it)->cellYBottom();
01669 const int index = (*it)->cellXLeft();
01670 if ( index >= 0 && index < static_cast<int>( mSelectedDates.count() ) ) {
01671 if ( ymax > maxArray[index] && !mItemsToDelete.contains( *it ) )
01672 maxArray[index] = ymax;
01673 }
01674 }
01675 }
01676
01677 return maxArray;
01678 }
01679
01680 void KOAgenda::setStartTime( const QTime &startHour )
01681 {
01682 const double startPos = ( startHour.hour()/24. + startHour.minute()/1440. +
01683 startHour.second()/86400. ) * mRows * gridSpacingY();
01684 setContentsPos( 0, static_cast<int>( startPos ) );
01685 }
01686
01687
01688
01689
01690
01691 KOAgendaItem *KOAgenda::insertItem( Incidence *incidence, const QDate &qd, int X,
01692 int YTop, int YBottom, int itemPos, int itemCount )
01693 {
01694 if ( mAllDayMode ) {
01695 kdDebug(5850) << "KOAgenda: calling insertItem in all-day mode is illegal." << endl;
01696 return 0;
01697 }
01698
01699 mActionType = NOP;
01700
01701 KOAgendaItem *agendaItem = new KOAgendaItem( mCalendar, incidence, qd, viewport(), itemPos, itemCount );
01702 connect( agendaItem, SIGNAL( removeAgendaItem( KOAgendaItem::GPtr ) ),
01703 SLOT( removeAgendaItem( KOAgendaItem::GPtr ) ) );
01704 connect( agendaItem, SIGNAL( showAgendaItem( KOAgendaItem::GPtr ) ),
01705 SLOT( showAgendaItem( KOAgendaItem::GPtr ) ) );
01706
01707 if ( YBottom <= YTop ) {
01708 kdDebug(5850) << "KOAgenda::insertItem(): Text: " << agendaItem->text() << " YSize<0" << endl;
01709 YBottom = YTop;
01710 }
01711
01712 agendaItem->resize( int( ( X + 1 ) * mGridSpacingX ) -
01713 int( X * mGridSpacingX ),
01714 int( YTop * mGridSpacingY ) -
01715 int( ( YBottom + 1 ) * mGridSpacingY ) );
01716 agendaItem->setCellXY( X, YTop, YBottom );
01717 agendaItem->setCellXRight( X );
01718 agendaItem->setResourceColor( KOHelper::resourceColor( mCalendar, incidence ) );
01719 agendaItem->installEventFilter( this );
01720
01721 addChild( agendaItem, int( X * mGridSpacingX ), int( YTop * mGridSpacingY ) );
01722 mItems.append( agendaItem );
01723
01724 placeSubCells( agendaItem );
01725
01726 agendaItem->show();
01727
01728 marcus_bains();
01729
01730 return agendaItem;
01731 }
01732
01733
01734
01735
01736 KOAgendaItem *KOAgenda::insertAllDayItem( Incidence *event, const QDate &qd,
01737 int XBegin, int XEnd )
01738 {
01739 if ( !mAllDayMode ) {
01740 kdWarning(5850) << "KOAgenda: calling insertAllDayItem in non all-day mode is illegal." << endl;
01741 return 0;
01742 }
01743
01744 mActionType = NOP;
01745
01746 KOAgendaItem *agendaItem = new KOAgendaItem( mCalendar, event, qd, viewport(), 1, 1 );
01747 connect( agendaItem, SIGNAL( removeAgendaItem( KOAgendaItem::GPtr ) ),
01748 SLOT( removeAgendaItem( KOAgendaItem::GPtr ) ) );
01749 connect( agendaItem, SIGNAL( showAgendaItem( KOAgendaItem::GPtr ) ),
01750 SLOT( showAgendaItem( KOAgendaItem::GPtr ) ) );
01751
01752 {
01753
01754
01755
01756
01757 if ( event->doesFloat() && XBegin * mGridSpacingX <= -32767 + mGridSpacingX ) {
01758
01759
01760
01761
01762
01763 XBegin = -1;
01764 }
01765 }
01766
01767 agendaItem->setCellXY( XBegin, 0, 0 );
01768 agendaItem->setCellXRight( XEnd );
01769
01770 const double startIt = mGridSpacingX * ( agendaItem->cellXLeft() );
01771 const double endIt = mGridSpacingX * ( agendaItem->cellWidth() +
01772 agendaItem->cellXLeft() );
01773
01774 agendaItem->resize( int( endIt ) - int( startIt ), int( mGridSpacingY ) );
01775
01776 agendaItem->installEventFilter( this );
01777 agendaItem->setResourceColor( KOHelper::resourceColor( mCalendar, event ) );
01778 addChild( agendaItem, int( XBegin * mGridSpacingX ), 0 );
01779 mItems.append( agendaItem );
01780
01781 placeSubCells( agendaItem );
01782
01783 agendaItem->show();
01784
01785 return agendaItem;
01786 }
01787
01788
01789 void KOAgenda::insertMultiItem( Event *event, const QDate &qd, int XBegin, int XEnd,
01790 int YTop, int YBottom )
01791 {
01792 if ( mAllDayMode ) {
01793 kdDebug(5850) << "KOAgenda: calling insertMultiItem in all-day mode is illegal." << endl;
01794 return;
01795 }
01796 mActionType = NOP;
01797
01798 int cellX,cellYTop,cellYBottom;
01799 QString newtext;
01800 int width = XEnd - XBegin + 1;
01801 int count = 0;
01802 KOAgendaItem *current = 0;
01803 QPtrList<KOAgendaItem> multiItems;
01804 const int visibleCount = mSelectedDates.first().daysTo( mSelectedDates.last() );
01805 for ( cellX = XBegin; cellX <= XEnd; ++cellX ) {
01806 ++count;
01807
01808 if( cellX >= 0 && cellX <= visibleCount ) {
01809 if ( cellX == XBegin ) {
01810 cellYTop = YTop;
01811 } else {
01812 cellYTop = 0;
01813 }
01814
01815 if ( cellX == XEnd ) {
01816 cellYBottom = YBottom;
01817 } else {
01818 cellYBottom = rows() - 1;
01819 }
01820
01821 newtext = QString("(%1/%2): ").arg( count ).arg( width );
01822 newtext.append( event->summary() );
01823
01824 current = insertItem( event, qd, cellX, cellYTop, cellYBottom, count, width );
01825 current->setText( newtext );
01826 multiItems.append( current );
01827 }
01828 }
01829 QPtrList<KOAgendaItem>::iterator it = multiItems.begin();
01830 QPtrList<KOAgendaItem>::iterator e = multiItems.end();
01831
01832 if ( it != e ) {
01833 KOAgendaItem *first = multiItems.first();
01834 KOAgendaItem *last = multiItems.last();
01835 KOAgendaItem *prev = 0, *next = 0;
01836
01837 while ( it != e ) {
01838 KOAgendaItem *item = *it;
01839 ++it;
01840 next = ( it == e ) ? 0 : (*it);
01841 if ( item ) {
01842 item->setMultiItem( ( item == first ) ? 0 : first,
01843 prev, next,
01844 ( item == last ) ? 0 : last );
01845 }
01846 prev = item;
01847 }
01848 }
01849
01850 marcus_bains();
01851 }
01852
01853 void KOAgenda::removeIncidence( Incidence *incidence, bool relayoutNeighbours )
01854 {
01855
01856
01857
01858 QValueList<KOAgendaItem::GPtr > itemsToRemove;
01859
01860 AgendaItemList::Iterator it;
01861 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01862 if ( *it ) {
01863 if ( (*it)->incidence() == incidence ) {
01864 itemsToRemove.append( *it );
01865 }
01866 }
01867 }
01868
01869 for ( it = itemsToRemove.begin(); it != itemsToRemove.end(); ++it ) {
01870 removeAgendaItem( *it, relayoutNeighbours );
01871 }
01872 }
01873
01874 void KOAgenda::showAgendaItem( KOAgendaItem::GPtr agendaItem )
01875 {
01876 if ( !agendaItem ) {
01877 return;
01878 }
01879
01880 agendaItem->hide();
01881 addChild( agendaItem );
01882 if ( !mItems.contains( agendaItem ) ) {
01883 mItems.append( agendaItem );
01884 }
01885 placeSubCells( agendaItem );
01886
01887 agendaItem->show();
01888 }
01889
01890 bool KOAgenda::removeAgendaItem( KOAgendaItem::GPtr item, bool relayoutNeighbours )
01891 {
01892
01893 bool taken = false;
01894 KOAgendaItem::GPtr thisItem = item;
01895 AgendaItemList conflictItems = thisItem->conflictItems();
01896 removeChild( thisItem );
01897
01898 AgendaItemList::Iterator it = mItems.find( thisItem );
01899 if ( it != mItems.end() ) {
01900 mItems.remove( it );
01901 taken = true;
01902 }
01903
01904 if ( relayoutNeighbours ) {
01905 for ( it = conflictItems.begin(); it != conflictItems.end(); ++it ) {
01906
01907 if ( *it != thisItem ) {
01908 placeSubCells( *it );
01909 }
01910 }
01911 }
01912
01913 mItemsToDelete.append( thisItem );
01914 QTimer::singleShot( 0, this, SLOT( deleteItemsToDelete() ) );
01915 return taken;
01916 }
01917
01918 void KOAgenda::deleteItemsToDelete()
01919 {
01920 freeItemList( mItemsToDelete );
01921 mItemsToDelete.clear();
01922 }
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942 void KOAgenda::resizeEvent ( QResizeEvent *ev )
01943 {
01944
01945
01946 QSize newSize( ev->size() );
01947 if (mAllDayMode) {
01948 mGridSpacingX = double( newSize.width() - 2 * frameWidth() ) / (double)mColumns;
01949 mGridSpacingY = newSize.height() - 2 * frameWidth();
01950 } else {
01951 int scrollbarWidth = vScrollBarMode() != AlwaysOff ? verticalScrollBar()->width() : 0;
01952 mGridSpacingX = double( newSize.width() - scrollbarWidth - 2 * frameWidth()) / double(mColumns);
01953
01954 mGridSpacingY = double(newSize.height() - 2 * frameWidth()) / double(mRows);
01955 if ( mGridSpacingY < mDesiredGridSpacingY )
01956 mGridSpacingY = mDesiredGridSpacingY;
01957 }
01958 calculateWorkingHours();
01959 QTimer::singleShot( 0, this, SLOT( resizeAllContents() ) );
01960 emit gridSpacingYChanged( mGridSpacingY * 4 );
01961 QScrollView::resizeEvent(ev);
01962 }
01963
01964 void KOAgenda::resizeAllContents()
01965 {
01966
01967 double subCellWidth;
01968
01969 if ( mItems.count() > 0 ) {
01970 KOAgendaItem::GPtr item;
01971 if ( mAllDayMode ) {
01972 AgendaItemList::Iterator it;
01973 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01974 if ( *it ) {
01975 subCellWidth = calcSubCellWidth( *it );
01976 placeAgendaItem( *it, subCellWidth );
01977 }
01978 }
01979 } else {
01980 AgendaItemList::Iterator it;
01981 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
01982 if ( *it ) {
01983 subCellWidth = calcSubCellWidth( *it );
01984 placeAgendaItem( *it, subCellWidth );
01985 }
01986 }
01987 }
01988 }
01989 checkScrollBoundaries();
01990 marcus_bains();
01991 }
01992
01993 void KOAgenda::scrollUp()
01994 {
01995 scrollBy(0,-mScrollOffset);
01996 }
01997
01998
01999 void KOAgenda::scrollDown()
02000 {
02001 scrollBy(0,mScrollOffset);
02002 }
02003
02004
02005
02006
02007
02008 int KOAgenda::minimumWidth() const
02009 {
02010
02011 int min = 100;
02012
02013 return min;
02014 }
02015
02016 void KOAgenda::updateConfig()
02017 {
02018 double oldGridSpacingY = mGridSpacingY;
02019
02020 mDesiredGridSpacingY = KOPrefs::instance()->mHourSize;
02021 if ( mDesiredGridSpacingY < 4 || mDesiredGridSpacingY > 30 ) {
02022 mDesiredGridSpacingY = 10;
02023 }
02024
02025
02026 mGridSpacingY = (double)height() / (double)mRows;
02027 if ( mGridSpacingY < mDesiredGridSpacingY ) {
02028 mGridSpacingY = mDesiredGridSpacingY;
02029 }
02030
02031
02032 if ( fabs( oldGridSpacingY - mGridSpacingY ) > 0.1 ) {
02033 resizeContents( int( mGridSpacingX * mColumns ),
02034 int( mGridSpacingY * mRows ) );
02035 }
02036
02037 calculateWorkingHours();
02038
02039 marcus_bains();
02040 }
02041
02042 void KOAgenda::checkScrollBoundaries()
02043 {
02044
02045 mOldLowerScrollValue = -1;
02046 mOldUpperScrollValue = -1;
02047
02048 checkScrollBoundaries(verticalScrollBar()->value());
02049 }
02050
02051 void KOAgenda::checkScrollBoundaries( int v )
02052 {
02053 int yMin = int( (v) / mGridSpacingY );
02054 int yMax = int( ( v + visibleHeight() ) / mGridSpacingY );
02055
02056
02057
02058 if ( yMin != mOldLowerScrollValue ) {
02059 mOldLowerScrollValue = yMin;
02060 emit lowerYChanged(yMin);
02061 }
02062 if ( yMax != mOldUpperScrollValue ) {
02063 mOldUpperScrollValue = yMax;
02064 emit upperYChanged(yMax);
02065 }
02066 }
02067
02068 int KOAgenda::visibleContentsYMin()
02069 {
02070 int v = verticalScrollBar()->value();
02071 return int( v / mGridSpacingY );
02072 }
02073
02074 int KOAgenda::visibleContentsYMax()
02075 {
02076 int v = verticalScrollBar()->value();
02077 return int( ( v + visibleHeight() ) / mGridSpacingY );
02078 }
02079
02080 void KOAgenda::deselectItem()
02081 {
02082 if ( mSelectedItem.isNull() ) {
02083 return;
02084 }
02085 mSelectedItem->select(false);
02086 mSelectedItem = 0;
02087 }
02088
02089 void KOAgenda::selectItem( KOAgendaItem::GPtr item )
02090 {
02091 if ((KOAgendaItem *)mSelectedItem == item) return;
02092 deselectItem();
02093 if ( !item ) {
02094 emit incidenceSelected( 0, QDate() );
02095 return;
02096 }
02097 mSelectedItem = item;
02098 mSelectedItem->select();
02099 assert( mSelectedItem->incidence() );
02100 mSelectedUid = mSelectedItem->incidence()->uid();
02101 emit incidenceSelected( mSelectedItem->incidence(), mSelectedItem->itemDate() );
02102 }
02103
02104 void KOAgenda::selectItemByUID( const QString& uid )
02105 {
02106 KOAgendaItem::GPtr item;
02107 AgendaItemList::Iterator it;
02108 for ( it = mItems.begin(); it != mItems.end(); ++it ) {
02109 if ( *it && (*it)->incidence() && (*it)->incidence()->uid() == uid ) {
02110 selectItem( *it );
02111 break;
02112 }
02113 }
02114 }
02115
02116
02117 void KOAgenda::keyPressEvent( QKeyEvent *kev )
02118 {
02119 switch(kev->key()) {
02120 case Key_PageDown:
02121 verticalScrollBar()->addPage();
02122 break;
02123 case Key_PageUp:
02124 verticalScrollBar()->subtractPage();
02125 break;
02126 case Key_Down:
02127 verticalScrollBar()->addLine();
02128 break;
02129 case Key_Up:
02130 verticalScrollBar()->subtractLine();
02131 break;
02132 default:
02133 ;
02134 }
02135 }
02136
02137 void KOAgenda::calculateWorkingHours()
02138 {
02139 mWorkingHoursEnable = !mAllDayMode;
02140
02141 QTime tmp = KOPrefs::instance()->mWorkingHoursStart.time();
02142 mWorkingHoursYTop = int( 4 * mGridSpacingY *
02143 ( tmp.hour() + tmp.minute() / 60. +
02144 tmp.second() / 3600. ) );
02145 tmp = KOPrefs::instance()->mWorkingHoursEnd.time();
02146 mWorkingHoursYBottom = int( 4 * mGridSpacingY *
02147 ( tmp.hour() + tmp.minute() / 60. +
02148 tmp.second() / 3600. ) - 1 );
02149 }
02150
02151
02152 DateList KOAgenda::dateList() const
02153 {
02154 return mSelectedDates;
02155 }
02156
02157 void KOAgenda::setDateList(const DateList &selectedDates)
02158 {
02159 mSelectedDates = selectedDates;
02160 marcus_bains();
02161 }
02162
02163 void KOAgenda::contentsMousePressEvent ( QMouseEvent *event )
02164 {
02165 kdDebug(5850) << "KOagenda::contentsMousePressEvent(): type: " << event->type() << endl;
02166 QScrollView::contentsMousePressEvent(event);
02167 }
02168
02169 void KOAgenda::setTypeAheadReceiver( QObject *o )
02170 {
02171 mTypeAheadReceiver = o;
02172 }
02173
02174 QObject *KOAgenda::typeAheadReceiver() const
02175 {
02176 return mTypeAheadReceiver;
02177 }
02178
02179 void KOAgenda::setHolidayMask(QMemArray<bool> *mask)
02180 {
02181 mHolidayMask = mask;
02182 }