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