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 <qintdict.h>
00028 #include <qdatetime.h>
00029 #include <qapplication.h>
00030 #include <qpopupmenu.h>
00031 #include <qcursor.h>
00032 #include <qpainter.h>
00033
00034 #include <kdebug.h>
00035 #include <klocale.h>
00036 #include <kiconloader.h>
00037 #include <kglobal.h>
00038
00039 #include "koagendaitem.h"
00040 #include "koprefs.h"
00041 #include "koglobals.h"
00042
00043 #include "koagenda.h"
00044 #include "koagenda.moc"
00045
00046 #include <libkcal/event.h>
00047 #include <libkcal/todo.h>
00048 #include <libkcal/dndfactory.h>
00049 #include <libkcal/icaldrag.h>
00050 #include <libkcal/vcaldrag.h>
00051
00053 MarcusBains::MarcusBains(KOAgenda *_agenda,const char *name)
00054 : QFrame(_agenda->viewport(),name), agenda(_agenda)
00055 {
00056 setLineWidth(0);
00057 setMargin(0);
00058 setBackgroundColor(Qt::red);
00059 minutes = new QTimer(this);
00060 connect(minutes, SIGNAL(timeout()), this, SLOT(updateLocation()));
00061 minutes->start(0, true);
00062
00063 mTimeBox = new QLabel(this);
00064 mTimeBox->setAlignment(Qt::AlignRight | Qt::AlignBottom);
00065 QPalette pal = mTimeBox->palette();
00066 pal.setColor(QColorGroup::Foreground, Qt::red);
00067 mTimeBox->setPalette(pal);
00068 mTimeBox->setAutoMask(true);
00069
00070 agenda->addChild(mTimeBox);
00071
00072 oldToday = -1;
00073 }
00074
00075 MarcusBains::~MarcusBains()
00076 {
00077 delete minutes;
00078 }
00079
00080 int MarcusBains::todayColumn()
00081 {
00082 QDate currentDate = QDate::currentDate();
00083
00084 DateList dateList = agenda->dateList();
00085 DateList::ConstIterator it;
00086 int col = 0;
00087 for(it = dateList.begin(); it != dateList.end(); ++it) {
00088 if((*it) == currentDate)
00089 return KOGlobals::self()->reverseLayout() ?
00090 agenda->columns() - 1 - col : col;
00091 ++col;
00092 }
00093
00094 return -1;
00095 }
00096
00097 void MarcusBains::updateLocation(bool recalculate)
00098 {
00099 QTime tim = QTime::currentTime();
00100 if((tim.hour() == 0) && (oldTime.hour()==23))
00101 recalculate = true;
00102
00103 int mins = tim.hour()*60 + tim.minute();
00104 int minutesPerCell = 24 * 60 / agenda->rows();
00105 int y = (int)(mins*agenda->gridSpacingY()/minutesPerCell);
00106 int today = recalculate ? todayColumn() : oldToday;
00107 int x = (int)( agenda->gridSpacingX()*today );
00108 bool disabled = !(KOPrefs::instance()->mMarcusBainsEnabled);
00109
00110 oldTime = tim;
00111 oldToday = today;
00112
00113 if(disabled || (today<0)) {
00114 hide();
00115 mTimeBox->hide();
00116 return;
00117 } else {
00118 show();
00119 mTimeBox->show();
00120 }
00121
00122 if(recalculate)
00123 setFixedSize((int)(agenda->gridSpacingX()),1);
00124 agenda->moveChild(this, x, y);
00125 raise();
00126
00127 if(recalculate)
00128 mTimeBox->setFont(KOPrefs::instance()->mMarcusBainsFont);
00129
00130 mTimeBox->setText(KGlobal::locale()->formatTime(tim, KOPrefs::instance()->mMarcusBainsShowSeconds));
00131 mTimeBox->adjustSize();
00132 agenda->moveChild(mTimeBox,
00133 (int)(x+agenda->gridSpacingX()-mTimeBox->width()-1),
00134 y-mTimeBox->height());
00135 mTimeBox->raise();
00136 mTimeBox->setAutoMask(true);
00137
00138 minutes->start(1000,true);
00139 }
00140
00141
00143
00144
00145
00146
00147
00148 KOAgenda::KOAgenda( int columns, int rows, int rowSize, QWidget *parent,
00149 const char *name, WFlags f )
00150 : QScrollView( parent, name, f )
00151 {
00152 mColumns = columns;
00153 mRows = rows;
00154 mGridSpacingY = rowSize;
00155 mAllDayMode = false;
00156
00157 init();
00158 }
00159
00160
00161
00162
00163
00164 KOAgenda::KOAgenda( int columns, QWidget *parent, const char *name, WFlags f )
00165 : QScrollView( parent, name, f )
00166 {
00167 mColumns = columns;
00168 mRows = 1;
00169 mGridSpacingY = 24;
00170 mAllDayMode = true;
00171
00172 init();
00173 }
00174
00175
00176 KOAgenda::~KOAgenda()
00177 {
00178 delete mMarcusBains;
00179 }
00180
00181
00182 Incidence *KOAgenda::selectedIncidence() const
00183 {
00184 return ( mSelectedItem ? mSelectedItem->incidence() : 0 );
00185 }
00186
00187
00188 QDate KOAgenda::selectedIncidenceDate() const
00189 {
00190 return ( mSelectedItem ? mSelectedItem->itemDate() : QDate() );
00191 }
00192
00193
00194 void KOAgenda::init()
00195 {
00196 mGridSpacingX = 100;
00197
00198 mResizeBorderWidth = 8;
00199 mScrollBorderWidth = 8;
00200 mScrollDelay = 30;
00201 mScrollOffset = 10;
00202
00203 enableClipper( true );
00204
00205
00206
00207 setFocusPolicy( WheelFocus );
00208
00209 connect( &mScrollUpTimer, SIGNAL( timeout() ), SLOT( scrollUp() ) );
00210 connect( &mScrollDownTimer, SIGNAL( timeout() ), SLOT( scrollDown() ) );
00211
00212 mStartCellX = 0;
00213 mStartCellY = 0;
00214 mCurrentCellX = 0;
00215 mCurrentCellY = 0;
00216
00217 mSelectionCellX = 0;
00218 mSelectionYTop = 0;
00219 mSelectionHeight = 0;
00220
00221 mOldLowerScrollValue = -1;
00222 mOldUpperScrollValue = -1;
00223
00224 mClickedItem = 0;
00225
00226 mActionItem = 0;
00227 mActionType = NOP;
00228 mItemMoved = false;
00229
00230 mSelectedItem = 0;
00231
00232 setAcceptDrops( true );
00233 installEventFilter( this );
00234 mItems.setAutoDelete( true );
00235 mItemsToDelete.setAutoDelete( true );
00236
00237
00238 resizeContents( int( mGridSpacingX * mColumns ),
00239 int( mGridSpacingY * mRows ) );
00240
00241 viewport()->update();
00242 viewport()->setBackgroundMode( NoBackground );
00243 viewport()->setFocusPolicy( WheelFocus );
00244
00245 setMinimumSize( 30, int( mGridSpacingY + 1 ) );
00246
00247
00248
00249
00250
00251 setHScrollBarMode( AlwaysOff );
00252
00253 setStartHour( KOPrefs::instance()->mDayBegins );
00254
00255 calculateWorkingHours();
00256
00257 connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ),
00258 SLOT( checkScrollBoundaries( int ) ) );
00259
00260
00261 if( mAllDayMode ) {
00262 mMarcusBains = 0;
00263 } else {
00264 mMarcusBains = new MarcusBains( this );
00265 addChild( mMarcusBains );
00266 }
00267
00268 mTypeAhead = false;
00269 mTypeAheadReceiver = 0;
00270
00271 mReturnPressed = false;
00272 }
00273
00274
00275 void KOAgenda::clear()
00276 {
00277
00278
00279 KOAgendaItem *item;
00280 for ( item=mItems.first(); item != 0; item=mItems.next() ) {
00281 removeChild(item);
00282 }
00283 mItems.clear();
00284 mItemsToDelete.clear();
00285
00286 mSelectedItem = 0;
00287
00288 clearSelection();
00289 }
00290
00291
00292 void KOAgenda::clearSelection()
00293 {
00294 mSelectionCellX = 0;
00295 mSelectionYTop = 0;
00296 mSelectionHeight = 0;
00297 }
00298
00299 void KOAgenda::marcus_bains()
00300 {
00301 if(mMarcusBains) mMarcusBains->updateLocation(true);
00302 }
00303
00304
00305 void KOAgenda::changeColumns(int columns)
00306 {
00307 if (columns == 0) {
00308 kdDebug(5850) << "KOAgenda::changeColumns() called with argument 0" << endl;
00309 return;
00310 }
00311
00312 clear();
00313 mColumns = columns;
00314
00315
00316
00317
00318 QResizeEvent event( size(), size() );
00319
00320 QApplication::sendEvent( this, &event );
00321 }
00322
00323
00324
00325
00326
00327 bool KOAgenda::eventFilter ( QObject *object, QEvent *event )
00328 {
00329
00330
00331 switch( event->type() ) {
00332 case QEvent::MouseButtonPress:
00333 case QEvent::MouseButtonDblClick:
00334 case QEvent::MouseButtonRelease:
00335 case QEvent::MouseMove:
00336 return eventFilter_mouse( object, static_cast<QMouseEvent *>( event ) );
00337
00338 case QEvent::KeyPress:
00339 case QEvent::KeyRelease:
00340 return eventFilter_key( object, static_cast<QKeyEvent *>( event ) );
00341
00342 case ( QEvent::Leave ):
00343 if ( !mActionItem )
00344 setCursor( arrowCursor );
00345 return true;
00346
00347 #ifndef KORG_NODND
00348 case QEvent::DragEnter:
00349 case QEvent::DragMove:
00350 case QEvent::DragLeave:
00351 case QEvent::Drop:
00352
00353 return eventFilter_drag(object, static_cast<QDropEvent*>(event));
00354 #endif
00355
00356 default:
00357 return QScrollView::eventFilter( object, event );
00358 }
00359 }
00360
00361 bool KOAgenda::eventFilter_drag( QObject *object, QDropEvent *de )
00362 {
00363 #ifndef KORG_NODND
00364 QPoint viewportPos;
00365 if ( object != viewport() && object != this ) {
00366 viewportPos = static_cast<QWidget *>( object )->mapToParent( de->pos() );
00367 } else {
00368 viewportPos = de->pos();
00369 }
00370
00371 switch ( de->type() ) {
00372 case QEvent::DragEnter:
00373 case QEvent::DragMove:
00374 if ( ICalDrag::canDecode( de ) || VCalDrag::canDecode( de ) ) {
00375
00376 DndFactory factory( mCalendar );
00377 Todo *todo = factory.createDropTodo( de );
00378 if ( todo ) {
00379 de->accept();
00380 delete todo;
00381 } else {
00382 de->ignore();
00383 }
00384 return true;
00385 } else return false;
00386 break;
00387 case QEvent::DragLeave:
00388 return false;
00389 break;
00390 case QEvent::Drop:
00391 {
00392 if ( !ICalDrag::canDecode( de ) && !VCalDrag::canDecode( de ) ) {
00393 return false;
00394 }
00395
00396 DndFactory factory( mCalendar );
00397 Todo *todo = factory.createDropTodo( de );
00398
00399 if ( todo ) {
00400 de->acceptAction();
00401 int x, y;
00402
00403
00404
00405 if ( object == this ) {
00406 x = viewportPos.x() + contentsX();
00407 y = viewportPos.y() + contentsY();
00408 } else {
00409 viewportToContents( viewportPos.x(), viewportPos.y(), x, y );
00410 }
00411 int gx, gy;
00412 contentsToGrid( x, y, gx, gy );
00413 emit droppedToDo( todo, gx, gy, mAllDayMode );
00414 return true;
00415 }
00416 }
00417 break;
00418
00419 case QEvent::DragResponse:
00420 default:
00421 break;
00422 }
00423 #endif
00424
00425 return false;
00426 }
00427
00428 bool KOAgenda::eventFilter_key( QObject *, QKeyEvent *ke )
00429 {
00430
00431
00432
00433 if ( ke->key() == Key_Return ) {
00434 if ( ke->type() == QEvent::KeyPress ) mReturnPressed = true;
00435 else if ( ke->type() == QEvent::KeyRelease ) {
00436 if ( mReturnPressed ) {
00437 emitNewEventForSelection();
00438 mReturnPressed = false;
00439 return true;
00440 } else {
00441 mReturnPressed = false;
00442 }
00443 }
00444 }
00445
00446
00447 if ( ke->text().isEmpty() ) return false;
00448
00449 if ( ke->type() == QEvent::KeyPress || ke->type() == QEvent::KeyRelease ) {
00450 switch ( ke->key() ) {
00451 case Key_Escape:
00452 case Key_Return:
00453 case Key_Enter:
00454 case Key_Tab:
00455 case Key_Backtab:
00456 case Key_Left:
00457 case Key_Right:
00458 case Key_Up:
00459 case Key_Down:
00460 case Key_Backspace:
00461 case Key_Delete:
00462 case Key_Prior:
00463 case Key_Next:
00464 case Key_Home:
00465 case Key_End:
00466 case Key_Control:
00467 case Key_Meta:
00468 case Key_Alt:
00469 break;
00470 default:
00471 mTypeAheadEvents.append( new QKeyEvent( ke->type(), ke->key(),
00472 ke->ascii(), ke->state(),
00473 ke->text(), ke->isAutoRepeat(),
00474 ke->count() ) );
00475 if ( !mTypeAhead ) {
00476 mTypeAhead = true;
00477 emitNewEventForSelection();
00478 return true;
00479 }
00480 break;
00481 }
00482 }
00483 return false;
00484 }
00485
00486 void KOAgenda::emitNewEventForSelection()
00487 {
00488 if ( mSelectionHeight > 0 ) {
00489
00490
00491 emit newEventSignal( mSelectionCellX, (int)(mSelectionYTop / mGridSpacingY),
00492 mSelectionCellX,
00493 (int)( ( mSelectionYTop + mSelectionHeight ) /
00494 mGridSpacingY ) -1 );
00495 } else {
00496 emit newEventSignal();
00497 }
00498 }
00499
00500 void KOAgenda::finishTypeAhead()
00501 {
00502
00503 if ( typeAheadReceiver() ) {
00504 for( QEvent *e = mTypeAheadEvents.first(); e;
00505 e = mTypeAheadEvents.next() ) {
00506
00507 QApplication::postEvent( typeAheadReceiver(), e );
00508 }
00509 }
00510 mTypeAheadEvents.clear();
00511 mTypeAhead = false;
00512 }
00513
00514 bool KOAgenda::eventFilter_mouse(QObject *object, QMouseEvent *me)
00515 {
00516 QPoint viewportPos;
00517 if (object != viewport()) {
00518 viewportPos = ((QWidget *)object)->mapToParent(me->pos());
00519 } else {
00520 viewportPos = me->pos();
00521 }
00522
00523 switch (me->type()) {
00524 case QEvent::MouseButtonPress:
00525
00526 if (object != viewport()) {
00527 if (me->button() == RightButton) {
00528 mClickedItem = (KOAgendaItem *)object;
00529 if (mClickedItem) {
00530 selectItem(mClickedItem);
00531 emit showIncidencePopupSignal(mClickedItem->incidence());
00532 }
00533
00534 } else {
00535 mActionItem = (KOAgendaItem *)object;
00536 if (mActionItem) {
00537 selectItem(mActionItem);
00538 Incidence *incidence = mActionItem->incidence();
00539 if ( incidence->isReadOnly() || incidence->doesRecur() ) {
00540 mActionItem = 0;
00541 } else {
00542 startItemAction(viewportPos);
00543 }
00544 }
00545 }
00546 } else {
00547 if (me->button() == RightButton)
00548 {
00549 showNewEventPopupSignal();
00550 }
00551 else
00552 {
00553 selectItem(0);
00554 mActionItem = 0;
00555 setCursor(arrowCursor);
00556 startSelectAction(viewportPos);
00557 }
00558 }
00559 break;
00560
00561 case QEvent::MouseButtonRelease:
00562 if (mActionItem) {
00563 endItemAction();
00564 } else if ( mActionType == SELECT ) {
00565 endSelectAction( viewportPos );
00566 }
00567 break;
00568
00569 case QEvent::MouseMove:
00570 if (object != viewport()) {
00571 KOAgendaItem *moveItem = (KOAgendaItem *)object;
00572 if (!moveItem->incidence()->isReadOnly() &&
00573 !moveItem->incidence()->recurrence()->doesRecur() )
00574 if (!mActionItem)
00575 setNoActionCursor(moveItem,viewportPos);
00576 else
00577 performItemAction(viewportPos);
00578 } else {
00579 if ( mActionType == SELECT ) {
00580 performSelectAction( viewportPos );
00581 }
00582 }
00583 break;
00584
00585 case QEvent::MouseButtonDblClick:
00586 if (object == viewport()) {
00587 selectItem(0);
00588 int x,y;
00589 viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
00590 int gx,gy;
00591 contentsToGrid(x,y,gx,gy);
00592 emit newEventSignal(gx,gy);
00593 } else {
00594 KOAgendaItem *doubleClickedItem = (KOAgendaItem *)object;
00595 selectItem(doubleClickedItem);
00596 emit editIncidenceSignal(doubleClickedItem->incidence());
00597 }
00598 break;
00599
00600 default:
00601 break;
00602 }
00603
00604 return true;
00605 }
00606
00607 void KOAgenda::startSelectAction( const QPoint &viewportPos )
00608 {
00609 emit newStartSelectSignal();
00610
00611 mActionType = SELECT;
00612 mSelectionStartPoint = viewportPos;
00613
00614 int x,y;
00615 viewportToContents( viewportPos.x(), viewportPos.y(), x, y );
00616 int gx,gy;
00617 contentsToGrid( x, y, gx, gy );
00618
00619 mStartCellX = gx;
00620 mStartCellY = gy;
00621 mCurrentCellX = gx;
00622 mCurrentCellY = gy;
00623
00624
00625 int selectionX = mSelectionCellX;
00626 int selectionYTop = mSelectionYTop;
00627 int selectionHeight = mSelectionHeight;
00628
00629
00630 mSelectionCellX = gx;
00631 mSelectionYTop = int( gy * mGridSpacingY );
00632 mSelectionHeight = int( mGridSpacingY );
00633
00634
00635 repaintContents( int( selectionX*mGridSpacingX ), selectionYTop,
00636 int( (selectionX+1)*mGridSpacingX ) - int( selectionX*mGridSpacingX ), selectionHeight );
00637
00638
00639 repaintContents( int( mSelectionCellX * mGridSpacingX ), mSelectionYTop,
00640 int( (mSelectionCellX+1)*mGridSpacingX ) - int( mSelectionCellX*mGridSpacingX ),
00641 mSelectionHeight );
00642
00643 }
00644
00645 void KOAgenda::performSelectAction(const QPoint& viewportPos)
00646 {
00647 int x,y;
00648 viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
00649 int gx,gy;
00650 contentsToGrid(x,y,gx,gy);
00651
00652 QPoint clipperPos = clipper()->
00653 mapFromGlobal(viewport()->mapToGlobal(viewportPos));
00654
00655
00656 if (clipperPos.y() < mScrollBorderWidth) {
00657 mScrollUpTimer.start(mScrollDelay);
00658 } else if (visibleHeight() - clipperPos.y() <
00659 mScrollBorderWidth) {
00660 mScrollDownTimer.start(mScrollDelay);
00661 } else {
00662 mScrollUpTimer.stop();
00663 mScrollDownTimer.stop();
00664 }
00665
00666 if ( gy != mCurrentCellY && gy >= mStartCellY) {
00667 int selectionHeight = mSelectionHeight;
00668
00669
00670 int x, x1, y;
00671 gridToContents( mSelectionCellX, 0, x, y );
00672 gridToContents( mSelectionCellX + 1, gy+1, x1, y );
00673 mSelectionHeight = y - mSelectionYTop;
00674 repaintContents( x, mSelectionYTop, x1-x,
00675 (mSelectionHeight>selectionHeight)?mSelectionHeight:selectionHeight );
00676
00677 mCurrentCellY = gy;
00678 }
00679 }
00680
00681 void KOAgenda::endSelectAction( const QPoint ¤tPos )
00682 {
00683 mActionType = NOP;
00684 mScrollUpTimer.stop();
00685 mScrollDownTimer.stop();
00686
00687 emit newTimeSpanSignal(mStartCellX,mStartCellY,mCurrentCellX,mCurrentCellY);
00688
00689 if ( KOPrefs::instance()->mSelectionStartsEditor ) {
00690 if ( ( mSelectionStartPoint - currentPos ).manhattanLength() >
00691 QApplication::startDragDistance() ) {
00692 emitNewEventForSelection();
00693 }
00694 }
00695 }
00696
00697 void KOAgenda::startItemAction(const QPoint& viewportPos)
00698 {
00699 int x,y;
00700 viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
00701 int gx,gy;
00702 contentsToGrid(x,y,gx,gy);
00703
00704 mStartCellX = gx;
00705 mStartCellY = gy;
00706 mCurrentCellX = gx;
00707 mCurrentCellY = gy;
00708 bool noResize = ( mActionItem->incidence()->type() == "Todo");
00709
00710
00711 if (mAllDayMode) {
00712 int gridDistanceX = (int)(x - gx * mGridSpacingX);
00713 if (gridDistanceX < mResizeBorderWidth &&
00714 mActionItem->cellXLeft() == mCurrentCellX &&
00715 !noResize ) {
00716 mActionType = RESIZELEFT;
00717 setCursor(sizeHorCursor);
00718 } else if ((mGridSpacingX - gridDistanceX) < mResizeBorderWidth &&
00719 mActionItem->cellXRight() == mCurrentCellX &&
00720 !noResize ) {
00721 mActionType = RESIZERIGHT;
00722 setCursor(sizeHorCursor);
00723 } else {
00724 mActionType = MOVE;
00725 mActionItem->startMove();
00726 setCursor(sizeAllCursor);
00727 }
00728 } else {
00729 int gridDistanceY = (int)(y - gy * mGridSpacingY);
00730 if (gridDistanceY < mResizeBorderWidth &&
00731 mActionItem->cellYTop() == mCurrentCellY &&
00732 !mActionItem->firstMultiItem() &&
00733 !noResize ) {
00734 mActionType = RESIZETOP;
00735 setCursor(sizeVerCursor);
00736 } else if ((mGridSpacingY - gridDistanceY) < mResizeBorderWidth &&
00737 mActionItem->cellYBottom() == mCurrentCellY &&
00738 !mActionItem->lastMultiItem() &&
00739 !noResize ) {
00740 mActionType = RESIZEBOTTOM;
00741 setCursor(sizeVerCursor);
00742 } else {
00743 mActionType = MOVE;
00744 mActionItem->startMove();
00745 setCursor(sizeAllCursor);
00746 }
00747 }
00748 }
00749
00750 void KOAgenda::performItemAction(const QPoint& viewportPos)
00751 {
00752
00753
00754
00755
00756
00757
00758 int x,y;
00759 viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
00760
00761 int gx,gy;
00762 contentsToGrid(x,y,gx,gy);
00763 QPoint clipperPos = clipper()->
00764 mapFromGlobal(viewport()->mapToGlobal(viewportPos));
00765
00766
00767
00768 if ( clipperPos.y() < 0 || clipperPos.y() > visibleHeight() ||
00769 clipperPos.x() < 0 || clipperPos.x() > visibleWidth() ) {
00770 if ( mActionType == MOVE ) {
00771 mScrollUpTimer.stop();
00772 mScrollDownTimer.stop();
00773 mActionItem->resetMove();
00774 placeSubCells( mActionItem );
00775 emit startDragSignal( mActionItem->incidence() );
00776 setCursor( arrowCursor );
00777 mActionItem = 0;
00778 mActionType = NOP;
00779 mItemMoved = 0;
00780 return;
00781 }
00782 } else {
00783 switch ( mActionType ) {
00784 case MOVE:
00785 setCursor( sizeAllCursor );
00786 break;
00787 case RESIZETOP:
00788 case RESIZEBOTTOM:
00789 setCursor( sizeVerCursor );
00790 break;
00791 case RESIZELEFT:
00792 case RESIZERIGHT:
00793 setCursor( sizeHorCursor );
00794 break;
00795 default:
00796 setCursor( arrowCursor );
00797 }
00798 }
00799
00800
00801 if (clipperPos.y() < mScrollBorderWidth) {
00802 mScrollUpTimer.start(mScrollDelay);
00803 } else if (visibleHeight() - clipperPos.y() <
00804 mScrollBorderWidth) {
00805 mScrollDownTimer.start(mScrollDelay);
00806 } else {
00807 mScrollUpTimer.stop();
00808 mScrollDownTimer.stop();
00809 }
00810
00811
00812 if (mCurrentCellX != gx || mCurrentCellY != gy) {
00813 mItemMoved = true;
00814 mActionItem->raise();
00815 if (mActionType == MOVE) {
00816
00817 KOAgendaItem *firstItem = mActionItem->firstMultiItem();
00818 if (!firstItem) firstItem = mActionItem;
00819 KOAgendaItem *lastItem = mActionItem->lastMultiItem();
00820 if (!lastItem) lastItem = mActionItem;
00821 int dy = gy - mCurrentCellY;
00822 int dx = gx - mCurrentCellX;
00823 int x,y;
00824 KOAgendaItem *moveItem = firstItem;
00825 while (moveItem) {
00826 bool changed=false;
00827 if (dx!=0) {
00828 moveItem->moveRelative( dx, 0 );
00829 changed=true;
00830 }
00831
00832 if ( moveItem==firstItem && !mAllDayMode ) {
00833 int newY = dy+moveItem->cellYTop();
00834
00835 if (newY<0) {
00836 moveItem->expandTop( -moveItem->cellYTop() );
00837
00838 KOAgendaItem *newFirst = firstItem->prevMoveItem();
00839
00840 if (newFirst) {
00841 newFirst->setCellXY(moveItem->cellXLeft()-1, rows()+newY, rows()-1);
00842 mItems.append(newFirst);
00843 moveItem->resize( (int)( mGridSpacingX * newFirst->cellWidth() ),
00844 (int)( mGridSpacingY * newFirst->cellHeight() ));
00845 gridToContents(newFirst->cellXLeft(), newFirst->cellYTop(),x,y);
00846 addChild( newFirst, x, y );
00847 } else {
00848 newFirst = insertItem( moveItem->incidence(), moveItem->itemDate(),
00849 moveItem->cellXLeft()-1, rows()+newY, rows()-1 ) ;
00850 }
00851 if (newFirst) newFirst->show();
00852 moveItem->prependMoveItem(newFirst);
00853 firstItem=newFirst;
00854 } else if ( newY>=rows() ) {
00855
00856
00857 firstItem = moveItem->nextMultiItem();
00858 moveItem->hide();
00859 mItems.take( mItems.find( moveItem ) );
00860 removeChild( moveItem );
00861 mActionItem->removeMoveItem(moveItem);
00862 moveItem=firstItem;
00863
00864 if (moveItem) moveItem->expandTop( rows()-newY );
00865 } else {
00866 moveItem->expandTop(dy);
00867 }
00868 changed=true;
00869 }
00870 if ( !moveItem->lastMultiItem() && !mAllDayMode ) {
00871 int newY = dy+moveItem->cellYBottom();
00872 if (newY<0) {
00873
00874 lastItem = moveItem->prevMultiItem();
00875 moveItem->hide();
00876 mItems.take( mItems.find(moveItem) );
00877 removeChild( moveItem );
00878 moveItem->removeMoveItem( moveItem );
00879 moveItem = lastItem;
00880 moveItem->expandBottom(newY+1);
00881 } else if (newY>=rows()) {
00882 moveItem->expandBottom( rows()-moveItem->cellYBottom()-1 );
00883
00884 KOAgendaItem *newLast = lastItem->nextMoveItem();
00885 if (newLast) {
00886 newLast->setCellXY( moveItem->cellXLeft()+1, 0, newY-rows()-1 );
00887 mItems.append(newLast);
00888 moveItem->resize( (int)( mGridSpacingX * newLast->cellWidth() ),
00889 (int)( mGridSpacingY * newLast->cellHeight() ));
00890 gridToContents( newLast->cellXLeft(), newLast->cellYTop(), x, y) ;
00891 addChild( newLast, x, y );
00892 } else {
00893 newLast = insertItem( moveItem->incidence(), moveItem->itemDate(),
00894 moveItem->cellXLeft()+1, 0, newY-rows()-1 ) ;
00895 }
00896 moveItem->appendMoveItem( newLast );
00897 newLast->show();
00898 lastItem = newLast;
00899 } else {
00900 moveItem->expandBottom( dy );
00901 }
00902 changed=true;
00903 }
00904 if (changed) {
00905 moveItem->resize((int)( mGridSpacingX * moveItem->cellWidth() ),
00906 (int)( mGridSpacingY * moveItem->cellHeight() ));
00907 gridToContents( moveItem->cellXLeft(), moveItem->cellYTop(), x, y );
00908 moveChild( moveItem, x, y );
00909 }
00910 moveItem = moveItem->nextMultiItem();
00911 }
00912 } else if (mActionType == RESIZETOP) {
00913 if (mCurrentCellY <= mActionItem->cellYBottom()) {
00914 mActionItem->expandTop(gy - mCurrentCellY);
00915 mActionItem->resize(mActionItem->width(),
00916 (int)( mGridSpacingY * mActionItem->cellHeight() ));
00917 int x,y;
00918 gridToContents(mCurrentCellX,mActionItem->cellYTop(),x,y);
00919 moveChild(mActionItem,childX(mActionItem),y);
00920 }
00921 } else if (mActionType == RESIZEBOTTOM) {
00922 if (mCurrentCellY >= mActionItem->cellYTop()) {
00923 mActionItem->expandBottom(gy - mCurrentCellY);
00924 mActionItem->resize(mActionItem->width(),
00925 (int)( mGridSpacingY * mActionItem->cellHeight() ));
00926 }
00927 } else if (mActionType == RESIZELEFT) {
00928 if (mCurrentCellX <= mActionItem->cellXRight()) {
00929 mActionItem->expandLeft(gx - mCurrentCellX);
00930 mActionItem->resize((int)(mGridSpacingX * mActionItem->cellWidth()),
00931 mActionItem->height());
00932 int x,y;
00933 gridToContents(mActionItem->cellXLeft(),mActionItem->cellYTop(),x,y);
00934 moveChild(mActionItem,x,childY(mActionItem));
00935 }
00936 } else if (mActionType == RESIZERIGHT) {
00937 if (mCurrentCellX >= mActionItem->cellXLeft()) {
00938 mActionItem->expandRight(gx - mCurrentCellX);
00939 mActionItem->resize((int)(mGridSpacingX * mActionItem->cellWidth()),
00940 mActionItem->height());
00941 }
00942 }
00943 mCurrentCellX = gx;
00944 mCurrentCellY = gy;
00945 }
00946 }
00947
00948 void KOAgenda::endItemAction()
00949 {
00950
00951
00952 if ( mItemMoved ) {
00953 if ( mActionType == MOVE ) {
00954 mActionItem->endMove();
00955 }
00956 KOAgendaItem *placeItem = mActionItem->firstMultiItem();
00957 if ( !placeItem ) {
00958 placeItem = mActionItem;
00959 }
00960 emit itemModified( placeItem );
00961 QPtrList<KOAgendaItem> oldconflictItems = placeItem->conflictItems();
00962 KOAgendaItem *item;
00963 for ( item=oldconflictItems.first(); item != 0;
00964 item=oldconflictItems.next() ) {
00965 placeSubCells(item);
00966 }
00967 while ( placeItem ) {
00968 placeSubCells( placeItem );
00969 placeItem = placeItem->nextMultiItem();
00970 }
00971 }
00972
00973 mScrollUpTimer.stop();
00974 mScrollDownTimer.stop();
00975 setCursor( arrowCursor );
00976 mActionItem = 0;
00977 mActionType = NOP;
00978 mItemMoved = 0;
00979
00980
00981 }
00982
00983 void KOAgenda::setNoActionCursor( KOAgendaItem *moveItem, const QPoint& viewportPos )
00984 {
00985
00986
00987
00988
00989
00990
00991 int x,y;
00992 viewportToContents(viewportPos.x(),viewportPos.y(),x,y);
00993
00994 int gx,gy;
00995 contentsToGrid(x,y,gx,gy);
00996 bool noResize = (moveItem && moveItem->incidence() &&
00997 moveItem->incidence()->type() == "Todo");
00998
00999
01000 if (mAllDayMode) {
01001 int gridDistanceX = (int)(x - gx * mGridSpacingX);
01002 if ( !noResize &&
01003 gridDistanceX < mResizeBorderWidth &&
01004 moveItem->cellXLeft() == gx ) {
01005 setCursor(sizeHorCursor);
01006 } else if ( !noResize &&
01007 (mGridSpacingX - gridDistanceX) < mResizeBorderWidth &&
01008 moveItem->cellXRight() == gx ) {
01009 setCursor(sizeHorCursor);
01010 } else {
01011 setCursor(arrowCursor);
01012 }
01013 } else {
01014 int gridDistanceY = (int)(y - gy * mGridSpacingY);
01015 if ( !noResize &&
01016 gridDistanceY < mResizeBorderWidth &&
01017 moveItem->cellYTop() == gy &&
01018 !moveItem->firstMultiItem() ) {
01019 setCursor(sizeVerCursor);
01020 } else if ( !noResize &&
01021 (mGridSpacingY - gridDistanceY) < mResizeBorderWidth &&
01022 moveItem->cellYBottom() == gy &&
01023 !moveItem->lastMultiItem()) {
01024 setCursor(sizeVerCursor);
01025 } else {
01026 setCursor(arrowCursor);
01027 }
01028 }
01029 }
01030
01031
01034 double KOAgenda::calcSubCellWidth( KOAgendaItem *item )
01035 {
01036 int x, y, x1, y1;
01037 gridToContents( item->cellXLeft(), item->cellYTop(), x, y );
01038 gridToContents( item->cellXLeft()+1, item->cellYTop()+1, x1, y1 );
01039 int maxSubCells = item->subCells();
01040 double newSubCellWidth;
01041 if ( mAllDayMode ) {
01042 newSubCellWidth = double( y1 - y ) / maxSubCells;
01043 } else {
01044 newSubCellWidth = double( x1 - x ) / maxSubCells;
01045 }
01046 return newSubCellWidth;
01047 }
01048
01049 void KOAgenda::placeAgendaItem( KOAgendaItem *item, double subCellWidth )
01050 {
01051 int x, y, x1, y1;
01052
01053
01054 gridToContents( item->cellXLeft(), item->cellYTop(), x, y );
01055 gridToContents( item->cellXLeft() + item->cellWidth(),
01056 item->cellYBottom()+1, x1, y1 );
01057
01058 double subCellPos = item->subCell() * subCellWidth;
01059
01060
01061
01062 if (mAllDayMode) {
01063 item->resize( x1-x, int( subCellPos + subCellWidth + 0.01 ) - int( subCellPos ) );
01064 y += int( subCellPos );
01065 } else {
01066 item->resize( int( subCellPos + subCellWidth + 0.01 ) - int( subCellPos ), y1-y );
01067 x += int( subCellPos );
01068 }
01069 moveChild( item, x, y );
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082 void KOAgenda::placeSubCells( KOAgendaItem *placeItem )
01083 {
01084 #if 0
01085 kdDebug(5850) << "KOAgenda::placeSubCells()" << endl;
01086 if ( placeItem ) {
01087 Incidence *event = placeItem->incidence();
01088 if ( !event ) {
01089 kdDebug(5850) << " event is 0" << endl;
01090 } else {
01091 kdDebug(5850) << " event: " << event->summary() << endl;
01092 }
01093 } else {
01094 kdDebug(5850) << " placeItem is 0" << endl;
01095 }
01096 kdDebug(5850) << "KOAgenda::placeSubCells()..." << endl;
01097 #endif
01098
01099 QPtrList<KOrg::CellItem> cells;
01100 KOAgendaItem *item;
01101 for ( item = mItems.first(); item != 0; item = mItems.next() ) {
01102 cells.append( item );
01103 }
01104
01105 QPtrList<KOrg::CellItem> items = KOrg::CellItem::placeItem( cells,
01106 placeItem );
01107
01108 placeItem->setConflictItems( QPtrList<KOAgendaItem>() );
01109 double newSubCellWidth = calcSubCellWidth( placeItem );
01110 KOrg::CellItem *i;
01111 for ( i = items.first(); i; i = items.next() ) {
01112 item = static_cast<KOAgendaItem *>( i );
01113 placeAgendaItem( item, newSubCellWidth );
01114 item->addConflictItem( placeItem );
01115 placeItem->addConflictItem( item );
01116 }
01117 if ( items.isEmpty() )
01118 placeAgendaItem( placeItem, newSubCellWidth );
01119 placeItem->update();
01120 }
01121
01122
01123
01124
01125 void KOAgenda::drawContents(QPainter* p, int cx, int cy, int cw, int ch)
01126 {
01127
01128 QPixmap db(cw, ch);
01129 db.fill(KOPrefs::instance()->mAgendaBgColor);
01130 QPainter dbp(&db);
01131 dbp.translate(-cx,-cy);
01132
01133
01134 double lGridSpacingY = mGridSpacingY*2;
01135
01136
01137 if (mWorkingHoursEnable) {
01138 int x1 = cx;
01139 int y1 = mWorkingHoursYTop;
01140 if (y1 < cy) y1 = cy;
01141 int x2 = cx+cw-1;
01142
01143
01144 int y2 = mWorkingHoursYBottom;
01145 if (y2 > cy+ch-1) y2=cy+ch-1;
01146
01147 if (x2 >= x1 && y2 >= y1) {
01148 int gxStart = (int)(x1/mGridSpacingX);
01149 int gxEnd = (int)(x2/mGridSpacingX);
01150 while(gxStart <= gxEnd) {
01151 if (gxStart < int(mHolidayMask->count()) &&
01152 !mHolidayMask->at(gxStart)) {
01153 int xStart = (int)( KOGlobals::self()->reverseLayout() ?
01154 (mColumns - 1 - gxStart)*mGridSpacingX :
01155 gxStart*mGridSpacingX );
01156 if (xStart < x1) xStart = x1;
01157 int xEnd = (int)( KOGlobals::self()->reverseLayout() ?
01158 (mColumns - gxStart)*mGridSpacingX-1 :
01159 (gxStart+1)*mGridSpacingX-1 );
01160 if (xEnd > x2) xEnd = x2;
01161 dbp.fillRect(xStart,y1,xEnd-xStart+1,y2-y1+1,
01162 KOPrefs::instance()->mWorkingHoursColor);
01163 }
01164 ++gxStart;
01165 }
01166 }
01167 }
01168
01169 int selectionX, selectionX1, selectionY;
01170 gridToContents( mSelectionCellX, 0, selectionX, selectionY );
01171 gridToContents( mSelectionCellX+1, 0, selectionX1, selectionY );
01172
01173
01174 if ( ( cx + cw ) >= selectionX && cx <= ( selectionX1 ) &&
01175 ( cy + ch ) >= mSelectionYTop && cy <= ( mSelectionYTop + mSelectionHeight ) ) {
01176
01177 dbp.fillRect( selectionX, mSelectionYTop, selectionX1-selectionX,
01178 mSelectionHeight, KOPrefs::instance()->mHighlightColor );
01179 }
01180
01181 dbp.setPen( KOPrefs::instance()->mAgendaBgColor.dark(150) );
01182
01183
01184
01185 double x = ((int)(cx/mGridSpacingX))*mGridSpacingX;
01186 while (x < cx + cw) {
01187 dbp.drawLine((int)x,cy,(int)x,cy+ch);
01188 x+=mGridSpacingX;
01189 }
01190
01191
01192 double y = ((int)(cy/lGridSpacingY))*lGridSpacingY;
01193 while (y < cy + ch) {
01194
01195 dbp.drawLine(cx,(int)y,cx+cw,(int)y);
01196 y+=lGridSpacingY;
01197 }
01198 p->drawPixmap(cx,cy, db);
01199 }
01200
01201
01202
01203
01204 void KOAgenda::contentsToGrid (int x, int y, int& gx, int& gy)
01205 {
01206 gx = (int)( KOGlobals::self()->reverseLayout() ?
01207 mColumns - x/mGridSpacingX : x/mGridSpacingX );
01208 gy = (int)( y/mGridSpacingY );
01209 }
01210
01211
01212
01213
01214 void KOAgenda::gridToContents (int gx, int gy, int& x, int& y)
01215 {
01216 x = (int)( KOGlobals::self()->reverseLayout() ?
01217 (mColumns - gx)*mGridSpacingX : gx*mGridSpacingX );
01218 y = (int)( gy*mGridSpacingY );
01219 }
01220
01221
01222
01223
01224
01225
01226 int KOAgenda::timeToY(const QTime &time)
01227 {
01228
01229 int minutesPerCell = 24 * 60 / mRows;
01230
01231 int timeMinutes = time.hour() * 60 + time.minute();
01232
01233 int Y = (timeMinutes + (minutesPerCell / 2)) / minutesPerCell;
01234
01235
01236 return Y;
01237 }
01238
01239
01240
01241
01242
01243
01244 QTime KOAgenda::gyToTime(int gy)
01245 {
01246
01247 int secondsPerCell = 24 * 60 * 60/ mRows;
01248
01249 int timeSeconds = secondsPerCell * gy;
01250
01251 QTime time( 0, 0, 0 );
01252 if ( timeSeconds < 24 * 60 * 60 ) {
01253 time = time.addSecs(timeSeconds);
01254 } else {
01255 time.setHMS( 23, 59, 59 );
01256 }
01257
01258
01259 return time;
01260 }
01261
01262 void KOAgenda::setStartHour(int startHour)
01263 {
01264 int startCell = startHour * mRows / 24;
01265 setContentsPos(0, (int)(startCell * gridSpacingY()));
01266 }
01267
01268
01269
01270
01271
01272 KOAgendaItem *KOAgenda::insertItem (Incidence *event,QDate qd,int X,int YTop,int YBottom)
01273 {
01274
01275
01276 if (mAllDayMode) {
01277 kdDebug(5850) << "KOAgenda: calling insertItem in all-day mode is illegal." << endl;
01278 return 0;
01279 }
01280
01281 KOAgendaItem *agendaItem = new KOAgendaItem (event,qd,viewport());
01282 connect( agendaItem, SIGNAL( removeAgendaItem( KOAgendaItem* ) ),
01283 this, SLOT( removeAgendaItem( KOAgendaItem* ) ) );
01284 connect( agendaItem, SIGNAL( showAgendaItem( KOAgendaItem* ) ),
01285 this, SLOT( showAgendaItem( KOAgendaItem* ) ) );
01286
01287 if ( YBottom<=YTop ) {
01288 kdDebug(5850) << "KOAgenda::insertItem(): Text: " << agendaItem->text() << " YSize<0" << endl;
01289 YBottom = YTop;
01290 }
01291
01292 agendaItem->resize( (int)( (X+1)*mGridSpacingX ) - (int)( X*mGridSpacingX ),
01293 (int)( YTop*mGridSpacingY ) - (int)( (YBottom+1) * mGridSpacingY ) );
01294 agendaItem->setCellXY(X,YTop,YBottom);
01295 agendaItem->setCellXRight(X);
01296
01297 agendaItem->installEventFilter(this);
01298
01299 addChild(agendaItem,(int)( X*mGridSpacingX ), (int)( YTop*mGridSpacingY ));
01300 mItems.append(agendaItem);
01301
01302 placeSubCells(agendaItem);
01303
01304 agendaItem->show();
01305
01306 marcus_bains();
01307
01308 return agendaItem;
01309 }
01310
01311
01312
01313
01314
01315 KOAgendaItem *KOAgenda::insertAllDayItem (Incidence *event,QDate qd,int XBegin,int XEnd)
01316 {
01317 if (!mAllDayMode) {
01318 kdDebug(5850) << "KOAgenda: calling insertAllDayItem in non all-day mode is illegal." << endl;
01319 return 0;
01320 }
01321
01322 KOAgendaItem *agendaItem = new KOAgendaItem (event,qd,viewport());
01323 connect( agendaItem, SIGNAL( removeAgendaItem( KOAgendaItem* ) ),
01324 this, SLOT( removeAgendaItem( KOAgendaItem* ) ) );
01325 connect( agendaItem, SIGNAL( showAgendaItem( KOAgendaItem* ) ),
01326 this, SLOT( showAgendaItem( KOAgendaItem* ) ) );
01327
01328 agendaItem->setCellXY(XBegin,0,0);
01329 agendaItem->setCellXRight(XEnd);
01330
01331 double startIt = mGridSpacingX * (agendaItem->cellXLeft());
01332 double endIt = mGridSpacingX * (agendaItem->cellWidth()+agendaItem->cellXLeft());
01333
01334 agendaItem->resize( int(endIt) - int(startIt), int(mGridSpacingY));
01335
01336 agendaItem->installEventFilter(this);
01337
01338 addChild(agendaItem,(int)( XBegin*mGridSpacingX ), 0);
01339 mItems.append(agendaItem);
01340
01341 placeSubCells(agendaItem);
01342
01343 agendaItem->show();
01344
01345 return agendaItem;
01346 }
01347
01348
01349 void KOAgenda::insertMultiItem (Event *event,QDate qd,int XBegin,int XEnd,
01350 int YTop,int YBottom)
01351 {
01352 if (mAllDayMode) {
01353 kdDebug(5850) << "KOAgenda: calling insertMultiItem in all-day mode is illegal." << endl;
01354 return;
01355 }
01356
01357 int cellX,cellYTop,cellYBottom;
01358 QString newtext;
01359 int width = XEnd - XBegin + 1;
01360 int count = 0;
01361 KOAgendaItem *current = 0;
01362 QPtrList<KOAgendaItem> multiItems;
01363 for ( cellX = XBegin; cellX <= XEnd; ++cellX ) {
01364 if ( cellX == XBegin ) cellYTop = YTop;
01365 else cellYTop = 0;
01366 if ( cellX == XEnd ) cellYBottom = YBottom;
01367 else cellYBottom = rows() - 1;
01368 newtext = QString("(%1/%2): ").arg( ++count ).arg( width );
01369 newtext.append( event->summary() );
01370 current = insertItem( event, qd, cellX, cellYTop, cellYBottom );
01371 current->setText( newtext );
01372 multiItems.append( current );
01373 }
01374
01375 KOAgendaItem *next = 0;
01376 KOAgendaItem *prev = 0;
01377 KOAgendaItem *last = multiItems.last();
01378 KOAgendaItem *first = multiItems.first();
01379 KOAgendaItem *setFirst,*setLast;
01380 current = first;
01381 while (current) {
01382 next = multiItems.next();
01383 if (current == first) setFirst = 0;
01384 else setFirst = first;
01385 if (current == last) setLast = 0;
01386 else setLast = last;
01387
01388 current->setMultiItem(setFirst, prev, next, setLast);
01389 prev=current;
01390 current = next;
01391 }
01392
01393 marcus_bains();
01394 }
01395
01396 void KOAgenda::removeEvent ( Event *event )
01397 {
01398 KOAgendaItem *item = mItems.first();
01399 bool taken = false;
01400
01401
01402
01403 QPtrList<KOAgendaItem> mItemsToRemove;
01404 while ( item ) {
01405 if ( item->incidence() == event ) {
01406 mItemsToRemove.append( item );
01407 }
01408 item = mItems.next();
01409 }
01410 item = mItemsToRemove.first();
01411 while ( item ) {
01412 taken = removeAgendaItem( item );
01413 item = mItemsToRemove.next();
01414 }
01415 }
01416
01417 void KOAgenda::showAgendaItem( KOAgendaItem* agendaItem )
01418 {
01419 if ( !agendaItem ) return;
01420 agendaItem->hide();
01421 addChild( agendaItem );
01422 if ( !mItems.containsRef( agendaItem ) )
01423 mItems.append( agendaItem );
01424 placeSubCells( agendaItem );
01425 agendaItem->show();
01426 }
01427
01428 bool KOAgenda::removeAgendaItem( KOAgendaItem* item )
01429 {
01430
01431 bool taken = false;
01432 KOAgendaItem *thisItem = item;
01433 QPtrList<KOAgendaItem> conflictItems = thisItem->conflictItems();
01434 removeChild( thisItem );
01435 int pos = mItems.find( thisItem );
01436 if ( pos>=0 ) {
01437 mItems.take( pos );
01438 taken = true;
01439 }
01440
01441 KOAgendaItem *confitem;
01442 for ( confitem = conflictItems.first(); confitem != 0;
01443 confitem = conflictItems.next() ) {
01444
01445 if ( confitem != thisItem ) placeSubCells(confitem);
01446
01447 }
01448 mItemsToDelete.append( thisItem );
01449 QTimer::singleShot( 0, this, SLOT( deleteItemsToDelete() ) );
01450 return taken;
01451 }
01452
01453 void KOAgenda::deleteItemsToDelete()
01454 {
01455 mItemsToDelete.clear();
01456 }
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476 void KOAgenda::resizeEvent ( QResizeEvent *ev )
01477 {
01478
01479 double subCellWidth;
01480 KOAgendaItem *item;
01481 if (mAllDayMode) {
01482 mGridSpacingX = double( width() - 2 * frameWidth() ) / (double)mColumns;
01483
01484 mGridSpacingY = height() - 2 * frameWidth();
01485 resizeContents( (int)( mGridSpacingX * mColumns ), (int)(mGridSpacingY ));
01486
01487 for ( item=mItems.first(); item != 0; item=mItems.next() ) {
01488 subCellWidth = calcSubCellWidth( item );
01489 placeAgendaItem( item, subCellWidth );
01490 }
01491 } else {
01492 mGridSpacingX = double(width() - verticalScrollBar()->width() - 2 * frameWidth()) / double(mColumns);
01493
01494 mGridSpacingY = double(height() - 2 * frameWidth()) / double(mRows);
01495 if ( mGridSpacingY < mDesiredGridSpacingY ) mGridSpacingY = mDesiredGridSpacingY;
01496
01497 resizeContents( int( mGridSpacingX * mColumns ), int( mGridSpacingY * mRows ));
01498
01499 for ( item=mItems.first(); item != 0; item=mItems.next() ) {
01500 subCellWidth = calcSubCellWidth( item );
01501 placeAgendaItem( item, subCellWidth );
01502 }
01503 }
01504
01505 checkScrollBoundaries();
01506 calculateWorkingHours();
01507
01508 marcus_bains();
01509
01510 QScrollView::resizeEvent(ev);
01511 viewport()->update();
01512 }
01513
01514
01515 void KOAgenda::scrollUp()
01516 {
01517 scrollBy(0,-mScrollOffset);
01518 }
01519
01520
01521 void KOAgenda::scrollDown()
01522 {
01523 scrollBy(0,mScrollOffset);
01524 }
01525
01526 void KOAgenda::popupAlarm()
01527 {
01528 if (!mClickedItem) {
01529 kdDebug(5850) << "KOAgenda::popupAlarm() called without having a clicked item" << endl;
01530 return;
01531 }
01532
01533 Alarm::List alarms = mClickedItem->incidence()->alarms();
01534 Alarm::List::ConstIterator it;
01535 for( it = alarms.begin(); it != alarms.end(); ++it )
01536 (*it)->toggleAlarm();
01537 if (alarms.isEmpty()) {
01538
01539 Alarm*alm = mClickedItem->incidence()->newAlarm();
01540 alm->setEnabled(true);
01541 }
01542
01543 mClickedItem->updateIcons();
01544 }
01545
01546
01547
01548
01549 int KOAgenda::minimumWidth() const
01550 {
01551
01552 int min = 100;
01553
01554 return min;
01555 }
01556
01557 void KOAgenda::updateConfig()
01558 {
01559 mDesiredGridSpacingY = KOPrefs::instance()->mHourSize;
01560
01561 mGridSpacingY = (double)height()/(double)mRows;
01562 if (mGridSpacingY<mDesiredGridSpacingY) mGridSpacingY=mDesiredGridSpacingY;
01563
01564 calculateWorkingHours();
01565
01566 marcus_bains();
01567 }
01568
01569 void KOAgenda::checkScrollBoundaries()
01570 {
01571
01572 mOldLowerScrollValue = -1;
01573 mOldUpperScrollValue = -1;
01574
01575 checkScrollBoundaries(verticalScrollBar()->value());
01576 }
01577
01578 void KOAgenda::checkScrollBoundaries(int v)
01579 {
01580 int yMin = (int)(v/mGridSpacingY);
01581 int yMax = (int)((v+visibleHeight())/mGridSpacingY);
01582
01583
01584
01585 if (yMin != mOldLowerScrollValue) {
01586 mOldLowerScrollValue = yMin;
01587 emit lowerYChanged(yMin);
01588 }
01589 if (yMax != mOldUpperScrollValue) {
01590 mOldUpperScrollValue = yMax;
01591 emit upperYChanged(yMax);
01592 }
01593 }
01594
01595 void KOAgenda::deselectItem()
01596 {
01597 if (mSelectedItem.isNull()) return;
01598 mSelectedItem->select(false);
01599 mSelectedItem = 0;
01600 }
01601
01602 void KOAgenda::selectItem(KOAgendaItem *item)
01603 {
01604 if ((KOAgendaItem *)mSelectedItem == item) return;
01605 deselectItem();
01606 if (item == 0) {
01607 emit incidenceSelected( 0 );
01608 return;
01609 }
01610 mSelectedItem = item;
01611 mSelectedItem->select();
01612 emit incidenceSelected( mSelectedItem->incidence() );
01613 }
01614
01615
01616 void KOAgenda::keyPressEvent( QKeyEvent *kev )
01617 {
01618 switch(kev->key()) {
01619 case Key_PageDown:
01620 verticalScrollBar()->addPage();
01621 break;
01622 case Key_PageUp:
01623 verticalScrollBar()->subtractPage();
01624 break;
01625 case Key_Down:
01626 verticalScrollBar()->addLine();
01627 break;
01628 case Key_Up:
01629 verticalScrollBar()->subtractLine();
01630 break;
01631 default:
01632 ;
01633 }
01634 }
01635
01636 void KOAgenda::calculateWorkingHours()
01637 {
01638
01639 mWorkingHoursEnable = !mAllDayMode;
01640
01641 mWorkingHoursYTop = (int)(mGridSpacingY *
01642 KOPrefs::instance()->mWorkingHoursStart * 4);
01643 mWorkingHoursYBottom = (int)(mGridSpacingY *
01644 KOPrefs::instance()->mWorkingHoursEnd * 4 - 1);
01645 }
01646
01647
01648 DateList KOAgenda::dateList() const
01649 {
01650 return mSelectedDates;
01651 }
01652
01653 void KOAgenda::setDateList(const DateList &selectedDates)
01654 {
01655 mSelectedDates = selectedDates;
01656 marcus_bains();
01657 }
01658
01659 void KOAgenda::setHolidayMask(QMemArray<bool> *mask)
01660 {
01661 mHolidayMask = mask;
01662
01663
01664
01665
01666
01667
01668
01669
01670 }
01671
01672 void KOAgenda::contentsMousePressEvent ( QMouseEvent *event )
01673 {
01674 kdDebug(5850) << "KOagenda::contentsMousePressEvent(): type: " << event->type() << endl;
01675 QScrollView::contentsMousePressEvent(event);
01676 }
01677
01678 void KOAgenda::setTypeAheadReceiver( QObject *o )
01679 {
01680 mTypeAheadReceiver = o;
01681 }
01682
01683 QObject *KOAgenda::typeAheadReceiver() const
01684 {
01685 return mTypeAheadReceiver;
01686 }