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