-rw-r--r-- | korganizer/koagenda.cpp | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/korganizer/koagenda.cpp b/korganizer/koagenda.cpp index ce73168..f860f7d 100644 --- a/korganizer/koagenda.cpp +++ b/korganizer/koagenda.cpp @@ -1,1179 +1,1188 @@ /* This file is part of KOrganizer. Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> Marcus Bains line. Copyright (c) 2001 Ali Rahimi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef _WIN32_ #define protected public #include <qwidget.h> #undef protected #endif #include <qintdict.h> #include <qdatetime.h> #include <qapplication.h> #include <qpopupmenu.h> #include <qcursor.h> #include <qpainter.h> #include <kdebug.h> #include <klocale.h> #include <kiconloader.h> #include <kglobal.h> #include "koagendaitem.h" #include "koprefs.h" #include "koglobals.h" #include "koagenda.h" #include <libkcal/event.h> #include <libkcal/todo.h> #ifndef DESKTOP_VERSION #include <qpe/qpeapplication.h> #endif //extern bool globalFlagBlockPainting; extern int globalFlagBlockAgenda; extern int globalFlagBlockAgendaItemPaint; extern int globalFlagBlockAgendaItemUpdate; extern int globalFlagBlockStartup; //////////////////////////////////////////////////////////////////////////// MarcusBains::MarcusBains(KOAgenda *_agenda,const char *name) : QFrame(_agenda->viewport(),name), agenda(_agenda) { setLineWidth(0); setMargin(0); setBackgroundColor(Qt::red); minutes = new QTimer(this); connect(minutes, SIGNAL(timeout()), this, SLOT(updateLoc())); minutes->start(0, true); mTimeBox = new QLabel(this); mTimeBox->setAlignment(Qt::AlignRight | Qt::AlignBottom); QPalette pal = mTimeBox->palette(); pal.setColor(QColorGroup::Foreground, Qt::red); mTimeBox->setPalette(pal); //mTimeBox->setAutoMask(true); agenda->addChild(mTimeBox); oldToday = -1; } MarcusBains::~MarcusBains() { delete minutes; } int MarcusBains::todayColumn() { QDate currentDate = QDate::currentDate(); DateList dateList = agenda->dateList(); DateList::ConstIterator it; int col = 0; for(it = dateList.begin(); it != dateList.end(); ++it) { if((*it) == currentDate) return KOGlobals::self()->reverseLayout() ? agenda->columns() - 1 - col : col; ++col; } return -1; } void MarcusBains::updateLoc() { updateLocation(); } void MarcusBains::updateLocation(bool recalculate) { QTime tim = QTime::currentTime(); //qDebug(" MarcusBains::updateLocation %s ", tim.toString().latin1()); if((tim.hour() == 0) && (oldTime.hour()==23)) recalculate = true; int mins = tim.hour()*60 + tim.minute(); int minutesPerCell = 24 * 60 / agenda->rows(); int y = mins*agenda->gridSpacingY()/minutesPerCell; int today = recalculate ? todayColumn() : oldToday; int x = agenda->gridSpacingX()*today; bool disabled = !(KOPrefs::instance()->mMarcusBainsEnabled); oldTime = tim; oldToday = today; if(disabled || (today<0)) { hide(); mTimeBox->hide(); return; } else { show(); mTimeBox->show(); } if(recalculate) setFixedSize(agenda->gridSpacingX(),1); agenda->moveChild(this, x, y); raise(); if(recalculate) //mTimeBox->setFont(QFont("helvetica",10)); mTimeBox->setFont(KOPrefs::instance()->mMarcusBainsFont); mTimeBox->setText(KGlobal::locale()->formatTime(tim, KOPrefs::instance()->mMarcusBainsShowSeconds)); mTimeBox->adjustSize(); // the -2 below is there because there is a bug in this program // somewhere, where the last column of this widget is a few pixels // narrower than the other columns. int offs = (today==agenda->columns()-1) ? -4 : 0; agenda->moveChild(mTimeBox, x+agenda->gridSpacingX()-mTimeBox->width()+offs-1, y-mTimeBox->height()); mTimeBox->raise(); //mTimeBox->setAutoMask(true); minutes->start(5000,true); } //////////////////////////////////////////////////////////////////////////// /* Create an agenda widget with rows rows and columns columns. */ KOAgenda::KOAgenda(int columns,int rows,int rowSize,QWidget *parent, const char *name,WFlags f) : QScrollView(parent,name,f) { mAllAgendaPopup = 0; mColumns = columns; mRows = rows; mGridSpacingY = rowSize; mAllDayMode = false; #ifndef DESKTOP_VERSION //QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold ); #endif mHolidayMask = 0; init(); } /* Create an agenda widget with columns columns and one row. This is used for all-day events. */ KOAgenda::KOAgenda(int columns,QWidget *parent,const char *name,WFlags f) : QScrollView(parent,name,f) { mAllAgendaPopup = 0; blockResize = false; mColumns = columns; mRows = 1; //qDebug("aaaaaaaaaaaaaaaaaaldays %d ", KOPrefs::instance()->mAllDaySize); mGridSpacingY = KOPrefs::instance()->mAllDaySize; mAllDayMode = true; #ifndef DESKTOP_VERSION //QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold ); #endif mHolidayMask = 0; init(); } KOAgenda::~KOAgenda() { if(mMarcusBains) delete mMarcusBains; } Incidence *KOAgenda::selectedIncidence() const { return (mSelectedItem ? mSelectedItem->incidence() : 0); } QDate KOAgenda::selectedIncidenceDate() const { return (mSelectedItem ? mSelectedItem->itemDate() : QDate()); } void KOAgenda::init() { mPopupTimer = new QTimer(this); connect(mPopupTimer , SIGNAL(timeout()), this, SLOT(popupMenu())); mNewItemPopup = new QPopupMenu( this ); connect ( mNewItemPopup, SIGNAL (activated ( int ) ), this, SLOT ( newItem(int)) ); QString pathString = ""; if ( !KOPrefs::instance()->mToolBarMiniIcons ) { if ( QApplication::desktop()->width() < 480 ) pathString += "icons16/"; } else pathString += "iconsmini/"; mNewItemPopup->insertItem ( SmallIcon( pathString +"newevent" ), i18n("New Event..."), 1 ); mNewItemPopup->insertItem ( SmallIcon( pathString +"newtodo" ), i18n("New Todo..."),2 ); mNewItemPopup->insertSeparator ( ); mNewItemPopup->insertItem ( SmallIcon( pathString +"day" ), i18n("Day view"),3 ); mNewItemPopup->insertItem ( SmallIcon( pathString +"xdays" ), i18n("Next days"),8 ); mNewItemPopup->insertItem ( SmallIcon( pathString +"week" ), i18n("Next week"),4 ); mNewItemPopup->insertItem ( SmallIcon( pathString +"week" ), i18n("Next two weeks"),5 ); mNewItemPopup->insertItem ( SmallIcon( pathString +"month" ), i18n("This month"),6 ); mNewItemPopup->insertItem ( SmallIcon( pathString +"journal" ), i18n("Journal view"),7 ); #ifndef _WIN32_ int wflags = viewport()-> getWFlags() |WRepaintNoErase;//WResizeNoErase viewport()->setWFlags ( wflags); #endif mGridSpacingX = 80; mResizeBorderWidth = 8; mScrollBorderWidth = 8; mScrollDelay = 30; mScrollOffset = 10; mPaintPixmap.resize( 20,20); //enableClipper(true); // Grab key strokes for keyboard navigation of agenda. Seems to have no // effect. Has to be fixed. setFocusPolicy(WheelFocus); connect(&mScrollUpTimer,SIGNAL(timeout()),SLOT(scrollUp())); connect(&mScrollDownTimer,SIGNAL(timeout()),SLOT(scrollDown())); connect(&mResizeTimer,SIGNAL(timeout()),SLOT(finishResize())); mStartCellX = 0; mStartCellY = 0; mCurrentCellX = 0; mCurrentCellY = 0; mSelectionCellX = 0; mSelectionYTop = 0; mSelectionHeight = 0; mOldLowerScrollValue = -1; mOldUpperScrollValue = -1; mClickedItem = 0; mActionItem = 0; mActionType = NOP; mItemMoved = false; mSelectedItem = 0; // mItems.setAutoDelete(true); resizeContents( mGridSpacingX * mColumns + 1 , mGridSpacingY * mRows + 1 ); viewport()->update(); setMinimumSize(30, 1); // setMaximumHeight(mGridSpacingY * mRows + 5); // Disable horizontal scrollbar. This is a hack. The geometry should be // controlled in a way that the contents horizontally always fits. Then it is // not necessary to turn off the scrollbar. setHScrollBarMode(AlwaysOff); if ( ! mAllDayMode ) setVScrollBarMode(AlwaysOn); else setVScrollBarMode(AlwaysOff); setStartHour(KOPrefs::instance()->mDayBegins); calculateWorkingHours(); connect(verticalScrollBar(),SIGNAL(valueChanged(int)), SLOT(checkScrollBoundaries(int))); // Create the Marcus Bains line. if(mAllDayMode) mMarcusBains = 0; else { mMarcusBains = new MarcusBains(this); addChild(mMarcusBains); } mPopupKind = 0; mPopupItem = 0; } void KOAgenda::clear() { KOAgendaItem *item; for ( item=mItems.first(); item != 0; item=mItems.next() ) { mUnusedItems.append( item ); //item->hide(); } mItems.clear(); mSelectedItem = 0; clearSelection(); } void KOAgenda::clearSelection() { mSelectionCellX = 0; mSelectionYTop = 0; mSelectionHeight = 0; } void KOAgenda::marcus_bains() { if(mMarcusBains) mMarcusBains->updateLocation(true); } void KOAgenda::changeColumns(int columns) { if (columns == 0) { qDebug("KOAgenda::changeColumns() called with argument 0 "); return; } clear(); mColumns = columns; computeSizes(); } /* This is the eventFilter function, which gets all events from the KOAgendaItems contained in the agenda. It has to handle moving and resizing for all items. */ bool KOAgenda::eventFilter ( QObject *object, QEvent *event ) { // kdDebug() << "KOAgenda::eventFilter" << endl; switch(event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonDblClick: case QEvent::MouseButtonRelease: case QEvent::MouseMove: return eventFilter_mouse(object, static_cast<QMouseEvent *>(event)); case (QEvent::Leave): if (!mActionItem) setCursor(arrowCursor); return true; default: return QScrollView::eventFilter(object,event); } } void KOAgenda::popupMenu() { mPopupTimer->stop(); if ( mPopupKind == 1 || mPopupKind == 3 ) { if (mActionItem ) { endItemAction(); } mLeftMouseDown = false; // no more leftMouse computation if (mPopupItem) { //mClickedItem = mPopupItem; selectItem(mPopupItem); if ( mAllAgendaPopup && KOPrefs::instance()->mBlockPopupMenu && mPopupKind == 1 ) mAllAgendaPopup->installEventFilter( this ); emit showIncidencePopupSignal(mPopupItem->incidence()); } } else if ( mPopupKind == 2 || mPopupKind == 4 ) { if ( mLeftMouseDown ) { // we have a simulated right click - clear left mouse action endSelectAction( false ); // do not emit new event signal mLeftMouseDown = false; // no more leftMouse computation } if ( KOPrefs::instance()->mBlockPopupMenu && mPopupKind == 2 ) mNewItemPopup->installEventFilter( this ); mNewItemPopup->popup( mPopupPos); } mLeftMouseDown = false; mPopupItem = 0; mPopupKind = 0; } - +void KOAgenda::categoryChanged(Incidence * inc) +{ + KOAgendaItem *item; + for ( item=mItems.first(); item != 0; item=mItems.next() ) { + if ( item->incidence() == inc ) { + item->initColor (); + item->updateItem(); + } + } +} bool KOAgenda::eventFilter_mouse(QObject *object, QMouseEvent *me) { static int startX = 0; static int startY = 0; int blockmoveDist = ( QApplication::desktop()->width() < 480 ? 7 : 9 ); static bool blockMoving = true; //qDebug("KOAgenda::eventFilter_mous "); if ( object == mNewItemPopup ) { //qDebug("mNewItemPopup "); if ( me->type() == QEvent::MouseButtonRelease ) { mNewItemPopup->removeEventFilter( this ); int dX = me->globalPos().x() - mPopupPos.x();; if ( dX < 0 ) dX = -dX; int dY = me->globalPos().y() - mPopupPos.y(); if ( dY < 0 ) dY = -dY; if ( dX > blockmoveDist || dY > blockmoveDist ) { mNewItemPopup->hide(); } } return true; } if ( object == mAllAgendaPopup ) { //qDebug(" mAllAgendaPopup "); if ( me->type() == QEvent::MouseButtonRelease ) { mAllAgendaPopup->removeEventFilter( this ); int dX = me->globalPos().x() - mPopupPos.x();; if ( dX < 0 ) dX = -dX; int dY = me->globalPos().y() - mPopupPos.y(); if ( dY < 0 ) dY = -dY; if ( dX > blockmoveDist || dY > blockmoveDist ) { mAllAgendaPopup->hide(); } } return true; } QPoint viewportPos; if (object != viewport()) { blockmoveDist = blockmoveDist*2; viewportPos = ((QWidget *)object)->mapToParent(me->pos()); } else { viewportPos = me->pos(); } bool objIsNotViewport = (object != viewport()); bool leftButt = false; #ifdef DESKTOP_VERSION leftButt = (me->button() == LeftButton); #endif switch (me->type()) { case QEvent::MouseButtonPress: if (me->button() == LeftButton) { mPopupTimer->start( 600 ); mLeftMouseDown = true; } blockMoving = true; startX = viewportPos.x(); startY = viewportPos.y(); mPopupPos = me->globalPos(); if ( objIsNotViewport && !leftButt ) { KOAgendaItem * tempItem = (KOAgendaItem *)object; if (mAllDayMode) { if ( tempItem->height() > 10 ) { int minV = tempItem->height()/4; if ( minV > (blockmoveDist/2)-2 ) { if ( minV > blockmoveDist ) minV = blockmoveDist; else minV = (blockmoveDist/2); } bool border = false; int diff = tempItem->y() - viewportPos.y(); if ( diff < 0 ) diff *= -1; if ( diff < minV ) { border = true; objIsNotViewport = false; } if ( ! border ) { diff = tempItem->y() + tempItem->height()- viewportPos.y(); if ( diff < 0 ) diff *= -1; if ( diff < minV ) { border = true; objIsNotViewport = false; } } } } else { // not allday if ( tempItem->width() > 10 ) { int minH = tempItem->width()/4; if ( minH > (blockmoveDist/2)-2 ) { if ( minH > blockmoveDist ) minH = blockmoveDist; else minH = (blockmoveDist/2); } bool border = false; int diff = tempItem->x() - viewportPos.x(); if ( diff < 0 ) diff *= -1; if ( diff < minH ) { border = true; objIsNotViewport = false; } if ( ! border ) { diff = tempItem->x() + tempItem->width() - viewportPos.x(); if ( diff < 0 ) diff *= -1; if ( diff < minH ) { border = true; objIsNotViewport = false; } } } } } if ( objIsNotViewport ) { mPopupItem = (KOAgendaItem *)object; mPopupKind = 1; if (me->button() == RightButton) { mPopupKind = 3; popupMenu(); } else if (me->button() == LeftButton) { mActionItem = (KOAgendaItem *)object; if (mActionItem) { emit signalClearSelection(); slotClearSelection(); selectItem(mActionItem); Incidence *incidence = mActionItem->incidence(); if ( incidence->isReadOnly() /*|| incidence->recurrence()->doesRecur() */) { mActionItem = 0; } else { startItemAction(viewportPos); } } } } else { // ---------- viewport() mPopupItem = 0; mPopupKind = 2; selectItem(0); mActionItem = 0; if (me->button() == RightButton) { int x,y; viewportToContents(viewportPos.x(),viewportPos.y(),x,y); int gx,gy; contentsToGrid(x,y,gx,gy); mCurrentCellX = gx; mCurrentCellY = gy; mStartCellX = gx; mStartCellY = gy; mPopupKind = 4; popupMenu(); } else if (me->button() == LeftButton) { setCursor(arrowCursor); startSelectAction(viewportPos); } } break; case QEvent::MouseButtonRelease: if (me->button() == LeftButton ) { mPopupTimer->stop(); } if (object != viewport()) { if (me->button() == LeftButton && mLeftMouseDown) { if (mActionItem) { QPoint clipperPos = clipper()->mapFromGlobal(viewport()->mapToGlobal(viewportPos)); //qDebug(" %d %d %d ",clipperPos.y(),visibleHeight() , 9 ); if ( mActionType == MOVE && (clipperPos.y() > visibleHeight()-2 ||clipperPos.y() < 0 ) ) { mScrollUpTimer.stop(); mScrollDownTimer.stop(); mActionItem->resetMove(); placeSubCells( mActionItem ); // emit startDragSignal( mActionItem->incidence() ); setCursor( arrowCursor ); mActionItem = 0; mActionType = NOP; mItemMoved = 0; mLeftMouseDown = false; return true; } endItemAction(); } } } else { // ---------- viewport() if (me->button() == LeftButton && mLeftMouseDown ) { //left click endSelectAction( true ); // emit new event signal } } if (me->button() == LeftButton) mLeftMouseDown = false; break; case QEvent::MouseMove: //qDebug("mm "); if ( !mLeftMouseDown ) return false; if ( blockMoving ) { int dX, dY; dX = startX - viewportPos.x(); if ( dX < 0 ) dX = -dX; dY = viewportPos.y() - startY; if ( dY < 0 ) dY = -dY; //qDebug("%d %d %d ", dX, dY , blockmoveDist ); if ( dX > blockmoveDist || dY > blockmoveDist ) { blockMoving = false; } } if ( ! blockMoving ) mPopupTimer->stop(); if (object != viewport()) { KOAgendaItem *moveItem = (KOAgendaItem *)object; if (!moveItem->incidence()->isReadOnly() ) { if (!mActionItem) setNoActionCursor(moveItem,viewportPos); else { if ( !blockMoving ) performItemAction(viewportPos); } } } else { // ---------- viewport() mPopupPos = viewport()->mapToGlobal( me->pos() ); if ( mActionType == SELECT ) { performSelectAction( viewportPos ); } } break; case QEvent::MouseButtonDblClick: mPopupTimer->stop(); if (object == viewport()) { selectItem(0); int x,y; viewportToContents(viewportPos.x(),viewportPos.y(),x,y); int gx,gy; contentsToGrid(x,y,gx,gy); emit newEventSignal(gx,gy); } else { KOAgendaItem *doubleClickedItem = (KOAgendaItem *)object; selectItem(doubleClickedItem); if ( KOPrefs::instance()->mEditOnDoubleClick ) emit editIncidenceSignal(doubleClickedItem->incidence()); else emit showIncidenceSignal(doubleClickedItem->incidence()); } break; default: break; } return true; } void KOAgenda::newItem( int item ) { if ( item == 1 ) { //new event newEventSignal(mStartCellX ,mStartCellY ); } else if ( item == 2 ) { //new event newTodoSignal(mStartCellX ,mStartCellY ); } else { emit showDateView( item, mStartCellX ); // 3Day view // 4Week view // 5Month view // 6Journal view } } void KOAgenda::slotClearSelection() { if (mSelectionHeight) { int selectionX = mSelectionCellX * mGridSpacingX; int top = mSelectionYTop - 2 *mGridSpacingY; int hei = mSelectionHeight + 4 *mGridSpacingY; clearSelection(); repaintContents( selectionX, top, mGridSpacingX, hei ,false ); } } void KOAgenda::startSelectAction(QPoint viewportPos) { emit signalClearSelection(); slotClearSelection(); mActionType = SELECT; int x,y; viewportToContents(viewportPos.x(),viewportPos.y(),x,y); int gx,gy; contentsToGrid(x,y,gx,gy); mStartCellX = gx; mStartCellY = gy; mCurrentCellX = gx; mCurrentCellY = gy; // Store new selection mSelectionCellX = gx; mSelectionYTop = gy * mGridSpacingY; mSelectionHeight = mGridSpacingY; // Paint new selection repaintContents( mSelectionCellX * mGridSpacingX+1, mSelectionYTop, mGridSpacingX-1, mSelectionHeight ); } void KOAgenda::performSelectAction(QPoint viewportPos) { int x,y; viewportToContents(viewportPos.x(),viewportPos.y(),x,y); int gx,gy; contentsToGrid(x,y,gx,gy); QPoint clipperPos = clipper()-> mapFromGlobal(viewport()->mapToGlobal(viewportPos)); // Scroll if cursor was moved to upper or lower end of agenda. if (clipperPos.y() < mScrollBorderWidth) { mScrollUpTimer.start(mScrollDelay); } else if (visibleHeight() - clipperPos.y() < mScrollBorderWidth) { mScrollDownTimer.start(mScrollDelay); } else { mScrollUpTimer.stop(); mScrollDownTimer.stop(); } if ( gy > mCurrentCellY ) { mSelectionHeight = ( gy + 1 ) * mGridSpacingY - mSelectionYTop; repaintContents( (KOGlobals::self()->reverseLayout() ? mColumns - 1 - mSelectionCellX : mSelectionCellX) * mGridSpacingX, mSelectionYTop, mGridSpacingX, mSelectionHeight , false); mCurrentCellY = gy; } else if ( gy < mCurrentCellY ) { if ( gy >= mStartCellY ) { int selectionHeight = mSelectionHeight; mSelectionHeight = ( gy + 1 ) * mGridSpacingY - mSelectionYTop; repaintContents( (KOGlobals::self()->reverseLayout() ? mColumns - 1 - mSelectionCellX : mSelectionCellX) * mGridSpacingX, mSelectionYTop, mGridSpacingX, selectionHeight,false ); mCurrentCellY = gy; } else { } } } void KOAgenda::endSelectAction( bool emitNewEvent ) { mActionType = NOP; mScrollUpTimer.stop(); mScrollDownTimer.stop(); emit newTimeSpanSignal(mStartCellX,mStartCellY,mCurrentCellX,mCurrentCellY); if ( emitNewEvent && mStartCellY < mCurrentCellY ) { emit newEventSignal(mStartCellX,mStartCellY,mCurrentCellX,mCurrentCellY); } } void KOAgenda::startItemAction(QPoint viewportPos) { int x,y; viewportToContents(viewportPos.x(),viewportPos.y(),x,y); int gx,gy; contentsToGrid(x,y,gx,gy); mStartCellX = gx; mStartCellY = gy; mCurrentCellX = gx; mCurrentCellY = gy; if (mAllDayMode) { int gridDistanceX = (x - gx * mGridSpacingX); if (gridDistanceX < mResizeBorderWidth && mActionItem->cellX() == mCurrentCellX) { mActionType = RESIZELEFT; setCursor(sizeHorCursor); } else if ((mGridSpacingX - gridDistanceX) < mResizeBorderWidth && mActionItem->cellXWidth() == mCurrentCellX) { mActionType = RESIZERIGHT; setCursor(sizeHorCursor); } else { mActionType = MOVE; mActionItem->startMove(); setCursor(sizeAllCursor); } } else { int gridDistanceY = (y - gy * mGridSpacingY); bool allowResize = ( mActionItem->incidence()->typeID() != todoID ); if (allowResize && gridDistanceY < mResizeBorderWidth && mActionItem->cellYTop() == mCurrentCellY && !mActionItem->firstMultiItem()) { mActionType = RESIZETOP; setCursor(sizeVerCursor); } else if (allowResize &&(mGridSpacingY - gridDistanceY) < mResizeBorderWidth && mActionItem->cellYBottom() == mCurrentCellY && !mActionItem->lastMultiItem()) { mActionType = RESIZEBOTTOM; setCursor(sizeVerCursor); } else { mActionType = MOVE; mActionItem->startMove(); setCursor(sizeAllCursor); } } } void KOAgenda::performItemAction(QPoint viewportPos) { // kdDebug() << "viewportPos: " << viewportPos.x() << "," << viewportPos.y() << endl; // QPoint point = viewport()->mapToGlobal(viewportPos); // kdDebug() << "Global: " << point.x() << "," << point.y() << endl; // point = clipper()->mapFromGlobal(point); // kdDebug() << "clipper: " << point.x() << "," << point.y() << endl; // kdDebug() << "visible height: " << visibleHeight() << endl; int x,y; viewportToContents(viewportPos.x(),viewportPos.y(),x,y); // kdDebug() << "contents: " << x << "," << y << "\n" << endl; int gx,gy; contentsToGrid(x,y,gx,gy); QPoint clipperPos = clipper()-> mapFromGlobal(viewport()->mapToGlobal(viewportPos)); // Cursor left active agenda area. // This starts a drag. if ( /*clipperPos.y() < 0 || clipperPos.y() > visibleHeight() ||*/ clipperPos.x() < 0 || clipperPos.x() > visibleWidth() ) { if ( mActionType == MOVE ) { mScrollUpTimer.stop(); mScrollDownTimer.stop(); mActionItem->resetMove(); placeSubCells( mActionItem ); // emit startDragSignal( mActionItem->incidence() ); setCursor( arrowCursor ); mActionItem = 0; mActionType = NOP; mItemMoved = 0; return; } } else { switch ( mActionType ) { case MOVE: setCursor( sizeAllCursor ); break; case RESIZETOP: case RESIZEBOTTOM: setCursor( sizeVerCursor ); break; case RESIZELEFT: case RESIZERIGHT: setCursor( sizeHorCursor ); break; default: setCursor( arrowCursor ); } } // Scroll if item was moved to upper or lower end of agenda. if (clipperPos.y() < mScrollBorderWidth) { mScrollUpTimer.start(mScrollDelay); } else if (visibleHeight() - clipperPos.y() < mScrollBorderWidth) { mScrollDownTimer.start(mScrollDelay); } else { mScrollUpTimer.stop(); mScrollDownTimer.stop(); } // Move or resize item if necessary if (mCurrentCellX != gx || mCurrentCellY != gy) { mItemMoved = true; mActionItem->raise(); if (mActionType == MOVE) { // Move all items belonging to a multi item KOAgendaItem *moveItem = mActionItem->firstMultiItem(); bool isMultiItem = (moveItem || mActionItem->lastMultiItem()); if (!moveItem) moveItem = mActionItem; while (moveItem) { int dy; if (isMultiItem) dy = 0; else dy = gy - mCurrentCellY; moveItem->moveRelative(gx - mCurrentCellX,dy); int x,y; gridToContents(moveItem->cellX(),moveItem->cellYTop(),x,y); moveItem->resize(mGridSpacingX * moveItem->cellWidth(), mGridSpacingY * moveItem->cellHeight()); moveChild(moveItem,x,y); moveItem = moveItem->nextMultiItem(); } } else if (mActionType == RESIZETOP) { if (mCurrentCellY <= mActionItem->cellYBottom()) { mActionItem->expandTop(gy - mCurrentCellY); mActionItem->resize(mActionItem->width(), mGridSpacingY * mActionItem->cellHeight()); int x,y; gridToContents(mCurrentCellX,mActionItem->cellYTop(),x,y); //moveChild(mActionItem,childX(mActionItem),y); QScrollView::moveChild( mActionItem,childX(mActionItem),y ); } } else if (mActionType == RESIZEBOTTOM) { if (mCurrentCellY >= mActionItem->cellYTop()) { mActionItem->expandBottom(gy - mCurrentCellY); mActionItem->resize(mActionItem->width(), mGridSpacingY * mActionItem->cellHeight()); } } else if (mActionType == RESIZELEFT) { if (mCurrentCellX <= mActionItem->cellXWidth()) { mActionItem->expandLeft(gx - mCurrentCellX); mActionItem->resize(mGridSpacingX * mActionItem->cellWidth(), mActionItem->height()); int x,y; gridToContents(mActionItem->cellX(),mActionItem->cellYTop(),x,y); moveChild(mActionItem,x,childY(mActionItem)); } } else if (mActionType == RESIZERIGHT) { if (mCurrentCellX >= mActionItem->cellX()) { mActionItem->expandRight(gx - mCurrentCellX); mActionItem->resize(mGridSpacingX * mActionItem->cellWidth(), mActionItem->height()); } } mCurrentCellX = gx; mCurrentCellY = gy; } } void KOAgenda::endItemAction() { if ( mItemMoved ) { KOAgendaItem *placeItem = mActionItem->firstMultiItem(); if ( !placeItem ) { placeItem = mActionItem; } if ( placeItem->incidence()->recurrence()->doesRecur() ) { Incidence* oldInc = placeItem->incidence(); placeItem->recreateIncidence(); emit addToCalSignal(placeItem->incidence(), oldInc ); } int type = mActionType; if ( mAllDayMode ) type = -1; KOAgendaItem *modifiedItem = placeItem; //emit itemModified( placeItem, mActionType /*KOGlobals::EVENTEDITED */); QPtrList<KOAgendaItem> oldconflictItems ;//= placeItem->conflictItems(); KOAgendaItem *item; if ( placeItem->incidence()->typeID() == todoID ) { mSelectedItem = 0; //qDebug("todo %d %d %d ", mCurrentCellX, modifiedItem->cellX() ,modifiedItem->cellXWidth()); modifiedItem->mLastMoveXPos = mCurrentCellX; emit itemModified( modifiedItem, mActionType ); } else { globalFlagBlockAgendaItemPaint = 1; for ( item=oldconflictItems.first(); item != 0; item=oldconflictItems.next() ) { placeSubCells(item); } while ( placeItem ) { //qDebug("placeItem %s ", placeItem->incidence()->summary().latin1()); oldconflictItems = placeItem->conflictItems(); for ( item=oldconflictItems.first(); item != 0; item=oldconflictItems.next() ) { placeSubCells(item); } placeSubCells( placeItem ); placeItem = placeItem->nextMultiItem(); } globalFlagBlockAgendaItemPaint = 0; for ( item=oldconflictItems.first(); item != 0; item=oldconflictItems.next() ) { globalFlagBlockAgendaItemUpdate = 0; item->repaintMe(); globalFlagBlockAgendaItemUpdate = 1; item->repaint( false ); } placeItem = modifiedItem; while ( placeItem ) { //qDebug("placeItem %s ", placeItem->incidence()->summary().latin1()); globalFlagBlockAgendaItemUpdate = 0; placeItem->repaintMe(); globalFlagBlockAgendaItemUpdate = 1; placeItem->repaint(false); placeItem = placeItem->nextMultiItem(); } emit itemModified( modifiedItem, mActionType ); placeItem = modifiedItem; while ( placeItem ) { oldconflictItems = placeItem->conflictItems(); for ( item=oldconflictItems.first(); item != 0; item=oldconflictItems.next() ) { placeSubCells(item); } placeSubCells( placeItem ); placeItem = placeItem->nextMultiItem(); } placeItem = modifiedItem; while ( placeItem ) { oldconflictItems = placeItem->conflictItems(); for ( item=oldconflictItems.first(); item != 0; item=oldconflictItems.next() ) { globalFlagBlockAgendaItemUpdate = 0; item->repaintMe(); globalFlagBlockAgendaItemUpdate = 1; item->repaint(false); } placeItem = placeItem->nextMultiItem(); } /* oldconflictItems = modifiedItem->conflictItems(); for ( item=oldconflictItems.first(); item != 0; item=oldconflictItems.next() ) { globalFlagBlockAgendaItemUpdate = 0; item->paintMe(false); globalFlagBlockAgendaItemUpdate = 1; item->repaint(false); } */ } } mScrollUpTimer.stop(); mScrollDownTimer.stop(); setCursor( arrowCursor ); mActionItem = 0; mActionType = NOP; mItemMoved = 0; } void KOAgenda::setNoActionCursor(KOAgendaItem *moveItem,QPoint viewportPos) { // kdDebug() << "viewportPos: " << viewportPos.x() << "," << viewportPos.y() << endl; // QPoint point = viewport()->mapToGlobal(viewportPos); // kdDebug() << "Global: " << point.x() << "," << point.y() << endl; // point = clipper()->mapFromGlobal(point); // kdDebug() << "clipper: " << point.x() << "," << point.y() << endl; int x,y; viewportToContents(viewportPos.x(),viewportPos.y(),x,y); // kdDebug() << "contents: " << x << "," << y << "\n" << endl; int gx,gy; contentsToGrid(x,y,gx,gy); // Change cursor to resize cursor if appropriate if (mAllDayMode) { int gridDistanceX = (x - gx * mGridSpacingX); if (gridDistanceX < mResizeBorderWidth && moveItem->cellX() == gx) { setCursor(sizeHorCursor); } else if ((mGridSpacingX - gridDistanceX) < mResizeBorderWidth && moveItem->cellXWidth() == gx) { setCursor(sizeHorCursor); } else { setCursor(arrowCursor); } } else { int gridDistanceY = (y - gy * mGridSpacingY); if (gridDistanceY < mResizeBorderWidth && moveItem->cellYTop() == gy && !moveItem->firstMultiItem()) { setCursor(sizeVerCursor); } else if ((mGridSpacingY - gridDistanceY) < mResizeBorderWidth && moveItem->cellYBottom() == gy && !moveItem->lastMultiItem()) { setCursor(sizeVerCursor); } else { setCursor(arrowCursor); } } } /* Place item in cell and take care that multiple items using the same cell do not overlap. This method is not yet optimal. It doesn´t use the maximum space it can get in all cases. At the moment the method has a bug: When an item is placed only the sub cell widths of the items are changed, which are within the Y region the item to place spans. When the sub cell width change of one of this items affects a cell, where other items are, which do not overlap in Y with the item to place, the display gets corrupted, although the corruption looks quite nice. */ void KOAgenda::placeSubCells(KOAgendaItem *placeItem) { QPtrList<KOAgendaItem> conflictItems; int maxSubCells = 0; QIntDict<KOAgendaItem> subCellDict(5); KOAgendaItem *item; for ( item=mItems.first(); item != 0; item=mItems.next() ) { if (item != placeItem) { if (placeItem->cellX() <= item->cellXWidth() && placeItem->cellXWidth() >= item->cellX()) { if ((placeItem->cellYTop() <= item->cellYBottom()) && (placeItem->cellYBottom() >= item->cellYTop())) { conflictItems.append(item); if (item->subCells() > maxSubCells) maxSubCells = item->subCells(); subCellDict.insert(item->subCell(),item); } } } } if (conflictItems.count() > 0) { // Look for unused sub cell and insert item int i; for(i=0;i<maxSubCells;++i) { if (!subCellDict.find(i)) { placeItem->setSubCell(i); break; } } if (i == maxSubCells) { placeItem->setSubCell(maxSubCells); maxSubCells++; // add new item to number of sub cells } // Prepare for sub cell geometry adjustment int newSubCellWidth; if (mAllDayMode) newSubCellWidth = mGridSpacingY / maxSubCells; else newSubCellWidth = mGridSpacingX / maxSubCells; conflictItems.append(placeItem); // Adjust sub cell geometry of all direct conflict items for ( item=conflictItems.first(); item != 0; item=conflictItems.next() ) { item->setSubCells(maxSubCells); if (mAllDayMode) { item->resize(item->cellWidth() * mGridSpacingX, newSubCellWidth); } else { item->resize(newSubCellWidth, item->cellHeight() * mGridSpacingY); } int x,y; gridToContents(item->cellX(),item->cellYTop(),x,y); if (mAllDayMode) { |