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