-rw-r--r-- | korganizer/datenavigatorcontainer.cpp | 10 | ||||
-rw-r--r-- | korganizer/koagendaitem.cpp | 4 | ||||
-rw-r--r-- | korganizer/koagendaitem.h | 2 | ||||
-rw-r--r-- | korganizer/kodaymatrix.cpp | 6 | ||||
-rw-r--r-- | korganizer/kodaymatrix.h | 2 | ||||
-rw-r--r-- | korganizer/kotodoview.cpp | 3 | ||||
-rw-r--r-- | korganizer/kotodoview.h | 2 |
7 files changed, 21 insertions, 8 deletions
diff --git a/korganizer/datenavigatorcontainer.cpp b/korganizer/datenavigatorcontainer.cpp index 5cdaa83..5941337 100644 --- a/korganizer/datenavigatorcontainer.cpp +++ b/korganizer/datenavigatorcontainer.cpp @@ -17,241 +17,245 @@ 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. */ #include <kdebug.h> #include <klocale.h> //#include "koglobals.h" #include "navigatorbar.h" #include "kdatenavigator.h" #include <kcalendarsystem.h> #include "datenavigatorcontainer.h" #include "koprefs.h" DateNavigatorContainer::DateNavigatorContainer( QWidget *parent, const char *name ) : QWidget( parent, name ), mCalendar( 0 ), mHorizontalCount( 1 ), mVerticalCount( 1 ) { mExtraViews.setAutoDelete( true ); mNavigatorView = new KDateNavigator( this, name ); connectNavigatorView( mNavigatorView ); } DateNavigatorContainer::~DateNavigatorContainer() { } void DateNavigatorContainer::connectNavigatorView( KDateNavigator *v ) { connect( v, SIGNAL( datesSelected( const KCal::DateList & ) ), SIGNAL( datesSelected( const KCal::DateList & ) ) ); #if 0 connect( v, SIGNAL( incidenceDropped( Incidence *, const QDate & ) ), SIGNAL( incidenceDropped( Incidence *, const QDate & ) ) ); connect( v, SIGNAL( incidenceDroppedMove( Incidence *, const QDate & ) ), SIGNAL( incidenceDroppedMove( Incidence *, const QDate & ) ) ); #endif connect( v, SIGNAL( weekClicked( const QDate & ) ), SIGNAL( weekClicked( const QDate & ) ) ); connect( v, SIGNAL( goPrevious() ), SIGNAL( goPrevious() ) ); connect( v, SIGNAL( goNext() ), SIGNAL( goNext() ) ); connect( v, SIGNAL( goNextMonth() ), SIGNAL( goNextMonth() ) ); connect( v, SIGNAL( goPrevMonth() ), SIGNAL( goPrevMonth() ) ); connect( v, SIGNAL( goNextYear() ), SIGNAL( goNextYear() ) ); connect( v, SIGNAL( goPrevYear() ), SIGNAL( goPrevYear() ) ); connect( v, SIGNAL( monthSelected( int ) ), SIGNAL( monthSelected( int ) ) ); } void DateNavigatorContainer::setCalendar( Calendar *cal ) { mCalendar = cal; mNavigatorView->setCalendar( cal ); KDateNavigator *n; for( n = mExtraViews.first(); n; n = mExtraViews.next() ) { n->setCalendar( cal ); } } void DateNavigatorContainer::updateDayMatrix() { mNavigatorView->updateDayMatrix(); KDateNavigator *n; for( n = mExtraViews.first(); n; n = mExtraViews.next() ) { n->updateDayMatrix(); } } void DateNavigatorContainer::updateToday() { qDebug("DateNavigatorContainer::updateToday() NOT IMPL "); #if 0 mNavigatorView->updateToday(); KDateNavigator *n; for( n = mExtraViews.first(); n; n = mExtraViews.next() ) { n->updateToday(); } #endif } void DateNavigatorContainer::updateView() { mNavigatorView->updateView(); KDateNavigator *n; for( n = mExtraViews.first(); n; n = mExtraViews.next() ) { n->updateView(); } } void DateNavigatorContainer::updateConfig() { mNavigatorView->updateConfig(); KDateNavigator *n; for( n = mExtraViews.first(); n; n = mExtraViews.next() ) { n->updateConfig(); } } void DateNavigatorContainer::selectDates( const DateList &dateList ) { mNavigatorView->selectDates( dateList ); setBaseDates(); if ( mExtraViews.count() ) { KDateNavigator *view = mExtraViews.at( 0 ); view->dayMatrix()->setSelectedDaysFrom(*(dateList.begin()), *(--dateList.end())); view->dayMatrix()->repaint(); } } void DateNavigatorContainer::setBaseDates() { KCal::DateList dateList = mNavigatorView->selectedDates(); if ( dateList.isEmpty() ) { kdError() << "DateNavigatorContainer::selectDates() empty list." << endl; } QDate baseDate = dateList.first(); KDateNavigator *n; bool doRepaint = false; // skip first repaint for( n = mExtraViews.first(); n; n = mExtraViews.next() ) { baseDate = baseDate.addDays( baseDate.daysInMonth () - baseDate.day() +1 ); n->setBaseDate( baseDate, doRepaint ); doRepaint = true; } } void DateNavigatorContainer::resizeEvent( QResizeEvent * e ) { #if 0 kdDebug(5850) << "DateNavigatorContainer::resizeEvent()" << endl; kdDebug(5850) << " CURRENT SIZE: " << size() << endl; kdDebug(5850) << " MINIMUM SIZEHINT: " << minimumSizeHint() << endl; kdDebug(5850) << " SIZEHINT: " << sizeHint() << endl; kdDebug(5850) << " MINIMUM SIZE: " << minimumSize() << endl; #endif QSize minSize = mNavigatorView->sizeHintTwoButtons(); // kdDebug(5850) << " NAVIGATORVIEW minimumSizeHint: " << minSize << endl; int verticalCount = size().height() / minSize.height(); int horizontalCount = size().width() / minSize.width(); //qDebug(" wattdatt %d new %d %d ", size().width() ,e->size().width() , minSize.width() ); //qDebug("COUNT %d %d %d %d ", verticalCount, horizontalCount , mVerticalCount, mHorizontalCount ); bool fontchange = false; QFont fo; if ( horizontalCount != mHorizontalCount || verticalCount != mVerticalCount ) { uint count = horizontalCount * verticalCount; if ( count == 0 ) { bool ok; fo = mNavigatorView->yourFontHint( size() , &ok); //mNavigatorView->resize( size() ); //if ( ! ok ) // return; minSize = mNavigatorView->sizeHintTwoButtons(); verticalCount = size().height() / minSize.height(); horizontalCount = size().width() / minSize.width(); if ( horizontalCount == 0 ) horizontalCount = 1; if ( verticalCount == 0 ) verticalCount = 1; fontchange = true; count = horizontalCount * verticalCount; } else { if ( mNavigatorView->fontChanged() ) { fontchange = true; fo = KOPrefs::instance()->mDateNavigatorFont; mNavigatorView->changeFont( fo ); mNavigatorView->unsetFontChanged(); } } while ( count > ( mExtraViews.count() + 1 ) ) { KDateNavigator *n = new KDateNavigator( this ); n->setMonthSignalOffset ( mExtraViews.count()+1 ); mExtraViews.append( n ); n->setCalendar( mCalendar ); setBaseDates(); connectNavigatorView( n ); n->show(); } - - while ( count < ( mExtraViews.count() + 1 ) ) { - mExtraViews.removeLast(); + int iii = 0; + while ( iii < ( mExtraViews.count() ) ) { + if ( iii < count-1 ) + mExtraViews.at( iii )->show(); + else + mExtraViews.at( iii )->hide(); + ++iii; } if ( fontchange ) { //mNavigatorView->changeFont( fo ); uint i; for( i = 0; i < mExtraViews.count(); ++i ) { KDateNavigator *view = mExtraViews.at( i ); view->changeFont( fo ); } } mHorizontalCount = horizontalCount; mVerticalCount = verticalCount; } int height = size().height() / verticalCount; int width = size().width() / horizontalCount; NavigatorBar *bar = mNavigatorView->navigatorBar(); if ( horizontalCount > 1 ) bar->showButtons( true, false ); else bar->showButtons( true, true ); mNavigatorView->setGeometry(0, 0, width, height ); for( uint i = 0; i < mExtraViews.count(); ++i ) { int x = ( i + 1 ) % horizontalCount; int y = ( i + 1 ) / horizontalCount; KDateNavigator *view = mExtraViews.at( i ); bar = view->navigatorBar(); if ( y > 0 ) bar->showButtons( false, false ); else { if ( x + 1 == horizontalCount ) bar->showButtons( false, true ); else bar->showButtons( false, false ); } view->setGeometry( x * width, y * height, width, height ); } } QSize DateNavigatorContainer::minimumSizeHint() const { return mNavigatorView->minimumSizeHint(); } QSize DateNavigatorContainer::sizeHint() const { return mNavigatorView->sizeHint(); } diff --git a/korganizer/koagendaitem.cpp b/korganizer/koagendaitem.cpp index 0ea2860..19cc0e3 100644 --- a/korganizer/koagendaitem.cpp +++ b/korganizer/koagendaitem.cpp @@ -1,350 +1,350 @@ /* This file is part of KOrganizer. Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> 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. */ #include <qlabel.h> #include <qlayout.h> #include <qhbox.h> #include <qvbox.h> #include <qtooltip.h> #include <qwhatsthis.h> #include <qdragobject.h> #include <qdrawutil.h> #include <qpainter.h> #include <kiconloader.h> #include <kdebug.h> #include <kglobal.h> #include <klocale.h> #ifndef DESKTOP_VERSION #include <qpe/qpeapplication.h> #define AGENDA_ICON_SIZE 5 #else #define AGENDA_ICON_SIZE 7 #endif #include <libkcal/icaldrag.h> #include <libkcal/vcaldrag.h> #include <libkcal/kincidenceformatter.h> extern int globalFlagBlockAgenda; extern int globalFlagBlockAgendaItemPaint; extern int globalFlagBlockAgendaItemUpdate; #include "koprefs.h" #include "koagendaitem.h" //#include "koagendaitem.moc" //-------------------------------------------------------------------------- QToolTipGroup *KOAgendaItem::mToolTipGroup = 0; //-------------------------------------------------------------------------- class KOAgendaItemWhatsThis :public QWhatsThis { public: KOAgendaItemWhatsThis( KOAgendaItem* view ) : QWhatsThis( view ),_view (view) { }; protected: virtual QString text( const QPoint& ) { return _view->getWhatsThisText() ; } private: KOAgendaItem * _view; }; KOAgendaItem::KOAgendaItem(Incidence *incidence, QDate qd, QWidget *parent,bool allday, const char *name,WFlags) : QWidget(parent, name), mIncidence(incidence), mDate(qd) { #ifndef DESKTOP_VERSION //QPEApplication::setStylusOperation( this, QPEApplication::RightOnHold ); #endif - new KOAgendaItemWhatsThis(this); + mKOAgendaItemWhatsThis = new KOAgendaItemWhatsThis(this); int wflags = getWFlags() |WRepaintNoErase;// WResizeNoErase setWFlags ( wflags); mAllDay = allday; init ( incidence, qd ); //setMouseTracking(true); //setAcceptDrops(true); xPaintCoord = -1; yPaintCoord = -1; } QString KOAgendaItem::getWhatsThisText() { if ( mIncidence ) return KIncidenceFormatter::instance()->getFormattedText( mIncidence, KOPrefs::instance()->mWTshowDetails, KOPrefs::instance()->mWTshowCreated, KOPrefs::instance()->mWTshowChanged); return "KOAgendaItem::getWhatsThisText()::internal error"; } void KOAgendaItem::init ( Incidence *incidence, QDate qd ) { mIncidence = incidence; mDate = qd; mFirstMultiItem = 0; mNextMultiItem = 0; mLastMultiItem = 0; computeText(); if ( (incidence->type() == "Todo") && ( !((static_cast<Todo*>(incidence))->isCompleted()) && ((static_cast<Todo*>(incidence))->dtDue().date() <= QDate::currentDate()) ) ) { if ( (static_cast<Todo*>(incidence))->dtDue() < QDateTime::currentDateTime().date()) mBackgroundColor = KOPrefs::instance()->mTodoOverdueColor ; else mBackgroundColor = KOPrefs::instance()->mTodoDueTodayColor; } else { QStringList categories = mIncidence->categories(); QString cat = categories.first(); if (cat.isEmpty()) { if ( (incidence->type() == "Todo") &&((static_cast<Todo*>(incidence))->isCompleted()) ) mBackgroundColor =KOPrefs::instance()->mTodoDoneColor; else mBackgroundColor =KOPrefs::instance()->mEventColor; } else { mBackgroundColor = *KOPrefs::instance()->categoryColor(cat); if ( (incidence->type() == "Todo") &&((static_cast<Todo*>(incidence))->isCompleted()) ) { if ( mBackgroundColor == KOPrefs::instance()->mEventColor ) mBackgroundColor =KOPrefs::instance()->mTodoDoneColor; } } } mColorGroup = QColorGroup( mBackgroundColor.light(), mBackgroundColor.dark(),mBackgroundColor.light(), mBackgroundColor.dark(),mBackgroundColor, black, mBackgroundColor) ; setBackgroundColor( mBackgroundColor ); mConflictItems.clear(); setCellXY(0,0,1); setCellXWidth(0); setSubCell(0); setSubCells(1); setMultiItem(0,0,0); startMove(); mSelected = true; select(false); QFontMetrics fontinf(KOPrefs::instance()->mAgendaViewFont); mFontPixelSize = fontinf.height();; hide(); xPaintCoord = -1; yPaintCoord = -1; } KOAgendaItem::~KOAgendaItem() { // qDebug("deleteKOAgendaItem::~KOAgendaItem( "); - + delete mKOAgendaItemWhatsThis; } void KOAgendaItem::recreateIncidence() { #if 0 Incidence* newInc = mIncidence->clone(); newInc->recreate(); if ( mIncidence->doesRecur() ) { mIncidence->addExDate( mDate ); newInc->recurrence()->unsetRecurs(); int len = mIncidence->dtStart().secsTo( ((Event*)mIncidence)->dtEnd()); QTime tim = mIncidence->dtStart().time(); newInc->setDtStart( QDateTime(mDate, tim) ); ((Event*)newInc)->setDtEnd( newInc->dtStart().addSecs( len ) ); } #endif mIncidence = mIncidence->recreateCloneException( mDate ); } bool KOAgendaItem::updateIcons(QPainter * p, bool horLayout) { int size = AGENDA_ICON_SIZE; int yOff = 0; int xOff = 0; int x = pos().x() +3; int y; if ( mAllDay ) y = pos().y()+3; else y = mCellYTop * ( height() / cellHeight() ) +3; if (mIncidence->cancelled()) { int xpos = xOff*( 1 +AGENDA_ICON_SIZE )+x; int ypos = yOff*( 1 +AGENDA_ICON_SIZE)+y; p->drawLine( xpos, ypos, xpos+AGENDA_ICON_SIZE-1, ypos+AGENDA_ICON_SIZE-1 ); p->drawLine( xpos, ypos+AGENDA_ICON_SIZE-1, xpos+AGENDA_ICON_SIZE-1, ypos ); if ( horLayout ) ++xOff; else ++yOff; } if (mIncidence->isAlarmEnabled()) { p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, red ); if ( horLayout ) ++xOff; else ++yOff; } if (mIncidence->recurrence()->doesRecur()) { p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, blue ); if ( horLayout ) ++xOff; else ++yOff; } if (mIncidence->description().length() > 0) { p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, darkGreen ); if ( horLayout ) ++xOff; else ++yOff; } if (mIncidence->isReadOnly()) { p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, white ); if ( horLayout ) ++xOff; else ++yOff; } if (mIncidence->attendeeCount()>0) { if (mIncidence->organizer() == KOPrefs::instance()->email()) { p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, black ); if ( horLayout ) ++xOff; else ++yOff; } else { Attendee *me = mIncidence->attendeeByMails(KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email()); if (me!=0) { } else { p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, yellow ); if ( horLayout ) ++xOff; else ++yOff; } p->fillRect ( xOff*( 1 +AGENDA_ICON_SIZE )+x, yOff*( 1 +AGENDA_ICON_SIZE)+y, AGENDA_ICON_SIZE, AGENDA_ICON_SIZE, darkYellow ); if ( horLayout ) ++xOff; else ++yOff; } } return ( yOff || xOff ); } void KOAgendaItem::select(bool selected) { //qDebug("select %d %d",firstMultiItem(), nextMultiItem() ); if (mSelected == selected) return; mSelected = selected; if ( ! isVisible() ) return; if ( firstMultiItem() ) firstMultiItem()->select( selected ); if ( !firstMultiItem() && nextMultiItem() ) { KOAgendaItem * placeItem = nextMultiItem(); while ( placeItem ) { placeItem->select( selected ); placeItem = placeItem->nextMultiItem(); } } globalFlagBlockAgendaItemUpdate = 0; paintMe( selected ); globalFlagBlockAgendaItemUpdate = 1; repaint( false ); } /* The eventFilter has to filter the mouse events of the agenda item childs. The events are fed into the event handling method of KOAgendaItem. This allows the KOAgenda to handle the KOAgendaItems by using an eventFilter. */ bool KOAgendaItem::eventFilter ( QObject *object, QEvent *e ) { if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove) { QMouseEvent *me = (QMouseEvent *)e; QPoint itemPos = this->mapFromGlobal(((QWidget *)object)-> mapToGlobal(me->pos())); QMouseEvent returnEvent (e->type(),itemPos,me->button(),me->state()); return event(&returnEvent); } else { return false; } } void KOAgendaItem::repaintMe( ) { paintMe ( mSelected ); } void KOAgendaItem::paintMe( bool selected, QPainter* paint ) { if ( globalFlagBlockAgendaItemUpdate && ! selected) return; QPainter pa; if ( mSelected ) { pa.begin( paintPixSel() ); } else { if ( mAllDay ) pa.begin( paintPixAllday() ); else pa.begin( paintPix() ); } int x, yy, w, h; float nfh = 7.0; x = pos().x(); w = width(); h = height (); if ( mAllDay ) yy = y(); else yy = mCellYTop * ( height() / cellHeight() ); xPaintCoord= x; yPaintCoord = yy; wPaintCoord = width(); hPaintCoord = height(); //qDebug("paintMe %s %d %d %d %d",incidence()->summary().latin1(), x, yy, width(), height()); if ( paint == 0 ) paint = &pa; bool horLayout = ( w < h ); int maxhei = mFontPixelSize+4; if ( horLayout ) maxhei += AGENDA_ICON_SIZE -4; bool small = ( h < maxhei ); if ( ! small ) paint->setFont(KOPrefs::instance()->mAgendaViewFont); else { QFont f = KOPrefs::instance()->mAgendaViewFont; f.setBold( false ); int fh = f.pointSize(); nfh = (((float)height())/(float)(mFontPixelSize+4))*fh; if ( nfh < 6 ) nfh = 6; diff --git a/korganizer/koagendaitem.h b/korganizer/koagendaitem.h index b4dba79..53658c0 100644 --- a/korganizer/koagendaitem.h +++ b/korganizer/koagendaitem.h @@ -1,162 +1,164 @@ /* This file is part of KOrganizer. Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> 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. */ #ifndef KOAGENDAITEM_H #define KOAGENDAITEM_H #include <qframe.h> #include <qlabel.h> #include <qpixmap.h> #include <qdatetime.h> #include <qpalette.h> #include <libkcal/incidence.h> +class KOAgendaItemWhatsThis; class QToolTipGroup; class QDragEnterEvent; class QDropEvent; using namespace KCal; /* The KOAgendaItem has to make sure that it receives all mouse events, which are to be used for dragging and resizing. That means it has to be installed as eventfiler for its children, if it has children, and it has to pass mouse events from the cildren to itself. See eventFilter(). */ class KOAgendaItem : public QWidget { Q_OBJECT public: KOAgendaItem(Incidence *incidence, QDate qd, QWidget *parent, bool allday, const char *name=0, WFlags f=0 ); ~KOAgendaItem(); QString getWhatsThisText(); void init ( Incidence *incidence, QDate qd ); int cellX() { return mCellX; } int cellXWidth() { return mCellXWidth; } int cellYTop() { return mCellYTop; } int cellYBottom() { return mCellYBottom; } int cellHeight(); int cellWidth(); int subCell() { return mSubCell; } int subCells() { return mSubCells; } void setCellXY(int X, int YTop, int YBottom); void setCellY(int YTop, int YBottom); void setCellX(int XLeft, int XRight); void setCellXWidth(int xwidth); void setSubCell(int subCell); void setSubCells(int subCells); /** Start movement */ void startMove(); /** Reset to original values */ void resetMove(); void moveRelative(int dx,int dy); void expandTop(int dy); void expandBottom(int dy); void expandLeft(int dx); void expandRight(int dx); int mLastMoveXPos; void setMultiItem(KOAgendaItem *first,KOAgendaItem *next, KOAgendaItem *last); KOAgendaItem *firstMultiItem() { return mFirstMultiItem; } KOAgendaItem *nextMultiItem() { return mNextMultiItem; } KOAgendaItem *lastMultiItem() { return mLastMultiItem; } Incidence *incidence() const { return mIncidence; } QDate itemDate() { return mDate; } /** Update the date of this item's occurence (not in the event) */ void setItemDate(QDate qd); void setText ( const QString & text ) { mDisplayedText = text; } QString text () { return mDisplayedText; } virtual bool eventFilter ( QObject *, QEvent * ); static QToolTipGroup *toolTipGroup(); QPtrList<KOAgendaItem> conflictItems(); void setConflictItems(QPtrList<KOAgendaItem>); void addConflictItem(KOAgendaItem *ci); void paintMe( bool, QPainter* painter = 0 ); void repaintMe(); static void resizePixmap( int, int ); static QPixmap * paintPix(); static QPixmap * paintPixSel(); static QPixmap * paintPixAllday(); void updateItem(); void computeText(); void recreateIncidence(); bool checkLayout(); public slots: bool updateIcons( QPainter *, bool ); void select(bool=true); protected: void dragEnterEvent(QDragEnterEvent *e); void dropEvent(QDropEvent *e); void paintEvent ( QPaintEvent * ); void resizeEvent ( QResizeEvent *ev ); private: + KOAgendaItemWhatsThis* mKOAgendaItemWhatsThis; bool mAllDay; int mCellX; int mCellXWidth; int mCellYTop,mCellYBottom; int mSubCell; // subcell number of this item int mSubCells; // Total number of subcells in cell of this item int xPaintCoord; int yPaintCoord; int wPaintCoord; int hPaintCoord; // Variables to remember start position int mStartCellX; int mStartCellXWidth; int mStartCellYTop,mStartCellYBottom; int mLastMovePos; // Multi item pointers KOAgendaItem *mFirstMultiItem; KOAgendaItem *mNextMultiItem; KOAgendaItem *mLastMultiItem; int mFontPixelSize; Incidence *mIncidence; // corresponding event or todo QDate mDate; //date this events occurs (for recurrence) //void showIcon( QLabel*, int ); //QLabel *mTodoIconLabel; //QLabel *mItemLabel; //QWidget *mIconBox; //QLabel *mIconAlarm,*mIconRecur,*mIconReadonly; //QLabel *mIconReply,*mIconGroup,*mIconOrganizer; //QLabel *mIconMoreInfo; static QToolTipGroup *mToolTipGroup; QColor mBackgroundColor; QColorGroup mColorGroup; QString mDisplayedText; bool mSelected; QPtrList<KOAgendaItem> mConflictItems; }; #endif // KOAGENDAITEM_H diff --git a/korganizer/kodaymatrix.cpp b/korganizer/kodaymatrix.cpp index ae0a051..5133519 100644 --- a/korganizer/kodaymatrix.cpp +++ b/korganizer/kodaymatrix.cpp @@ -1,416 +1,418 @@ /* This file is part of KOrganizer. Copyright (c) 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at> Parts of the source code have been copied from kdpdatebutton.cpp 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 ode for Qt in the source distribution. */ #include <qevent.h> #include <qpainter.h> #include <qptrlist.h> #include <qtimer.h> #include <qwhatsthis.h> #include <kglobal.h> #include <kdebug.h> #include <klocale.h> #include <libkcal/vcaldrag.h> #include <libkcal/icaldrag.h> #include <libkcal/dndfactory.h> #include <libkcal/calendarresources.h> #include <libkcal/resourcecalendar.h> #include <kresources/resourceselectdialog.h> #include <kcalendarsystem.h> #ifndef KORG_NOPLUGINS #include "kocore.h" #endif #include "koprefs.h" #include "koglobals.h" #include "kodaymatrix.h" // ============================================================================ // D Y N A M I C T I P // ============================================================================ DynamicTip::DynamicTip( QWidget * parent ) : QToolTip( parent ) { matrix = (KODayMatrix*)parent; } class KODaymatrixWhatsThis :public QWhatsThis { public: - KODaymatrixWhatsThis( KODayMatrix* view ) : QWhatsThis( view ),_view (view) { }; + KODaymatrixWhatsThis( KODayMatrix* view ) : QWhatsThis( view ),_view (view) { ;}; + ~KODaymatrixWhatsThis() { ; }; protected: virtual QString text( const QPoint& p ) { return _view->getWhatsThisText( p ) ; } private: KODayMatrix * _view; }; void DynamicTip::maybeTip( const QPoint &pos ) { //calculate which cell of the matrix the mouse is in QRect sz = matrix->frameRect(); int dheight = sz.height()*7 / 42; int dwidth = sz.width() / 7; int row = pos.y()/dheight; int col = pos.x()/dwidth; QRect rct(col*dwidth, row*dheight, dwidth, dheight); // kdDebug() << "DynamicTip::maybeTip matrix cell index [" << // col << "][" << row << "] => " <<(col+row*7) << endl; //show holiday names only QString str = matrix->getHolidayLabel(col+row*7); if (str.isEmpty()) return; tip(rct, str); } // ============================================================================ // K O D A Y M A T R I X // ============================================================================ const int KODayMatrix::NOSELECTION = -1000; const int KODayMatrix::NUMDAYS = 42; KODayMatrix::KODayMatrix( QWidget *parent, const char *name ) : QFrame( parent, name ), mCalendar( 0 ) #if 0 KODayMatrix::KODayMatrix(QWidget *parent, Calendar* calendar, QDate date, const char *name) : QFrame(parent, name) #endif { - new KODaymatrixWhatsThis(this); + mKODaymatrixWhatsThis = new KODaymatrixWhatsThis(this); mPendingUpdateBeforeRepaint = false; mouseDown = false; // initialize dynamic arrays bDays.resize ( NUMDAYS ); days = new QDate[NUMDAYS]; daylbls = new QString[NUMDAYS]; events = new int[NUMDAYS]; mToolTip = new DynamicTip(this); // set default values used for drawing the matrix mDefaultBackColor = palette().active().base(); mDefaultTextColor = palette().active().foreground(); mDefaultTextColorShaded = getShadedColor(mDefaultTextColor); mHolidayColorShaded = getShadedColor(KOPrefs::instance()->mHolidayColor); mSelectedDaysColor = QColor("white"); mTodayMarginWidth = 2; mSelEnd = mSelStart = NOSELECTION; setAcceptDrops(true); //setFont( QFont("Arial", 10) ); mUpdateTimer = new QTimer( this ); connect (mUpdateTimer ,SIGNAL(timeout()), this, SLOT ( updateViewTimed() )); mRepaintTimer = new QTimer( this ); connect (mRepaintTimer ,SIGNAL(timeout()), this, SLOT ( repaintViewTimed() )); mDayChanged = false; updateView(); } QString KODayMatrix::getWhatsThisText( QPoint p ) { int tmp = getDayIndexFrom(p.x(), p.y()); if ( tmp < 0 || tmp > NUMDAYS-1 || !mCalendar ) return QString(); QDate mDate = days[tmp]; QPtrList<Event> eventlist = mCalendar->events(mDate); Event *event; QStringList mToolTip; for(event=eventlist.first();event != 0;event=eventlist.next()) { QString mToolTipText; QString text; int multiday = 0;// 1 = start, 2 = midddle, 3 = end day if (event->isMultiDay()) { QString prefix = "<->";multiday = 2; QString time; if ( event->doesRecur() ) { if ( event->recursOn( mDate) ) { prefix ="->" ;multiday = 1; } else { int days = event->dtStart().date().daysTo ( event->dtEnd().date() ); if ( event->recursOn( mDate.addDays( -days)) ) { prefix ="<-" ;multiday = 3; } } } else { if (mDate == event->dtStart().date()) { prefix ="->" ;multiday = 1; } else if (mDate == event->dtEnd().date()) { prefix ="<-" ;multiday = 3; } } if ( !event->doesFloat() ) { if ( mDate == event->dtStart().date () ) time = KGlobal::locale()->formatTime(event->dtStart().time())+" "; else if ( mDate == event->dtEnd().date () ) time = KGlobal::locale()->formatTime(event->dtEnd().time())+" "; } text = time + event->summary(); mToolTipText += prefix + text; } else { if (event->doesFloat()) { text = event->summary(); mToolTipText += text; } else { text = KGlobal::locale()->formatTime(event->dtStart().time()); text += " " + event->summary(); mToolTipText += KGlobal::locale()->formatTime(event->dtStart().time()) +"-"+KGlobal::locale()->formatTime(event->dtEnd().time())+" " + event->summary(); } } mToolTip.append( mToolTipText ); } mToolTip.sort(); return "<b>"+KGlobal::locale()->formatDate(days[tmp]) + "</b><br>" + mToolTip.join("<br>"); } void KODayMatrix::setCalendar( Calendar *cal ) { mCalendar = cal; setAcceptDrops( mCalendar ); updateEvents(); } QColor KODayMatrix::getShadedColor(QColor color) { QColor shaded; int h=0; int s=0; int v=0; color.hsv(&h,&s,&v); s = s/4; v = 192+v/4; shaded.setHsv(h,s,v); return shaded; } KODayMatrix::~KODayMatrix() { + delete mKODaymatrixWhatsThis; delete [] days; delete [] daylbls; delete [] events; delete mToolTip; } /* void KODayMatrix::setStartDate(QDate start) { updateView(start); } */ void KODayMatrix::addSelectedDaysTo(DateList& selDays) { if (mSelStart == NOSELECTION) { return; } //cope with selection being out of matrix limits at top (< 0) int i0 = mSelStart; if (i0 < 0) { for (int i = i0; i < 0; i++) { selDays.append(days[0].addDays(i)); } i0 = 0; } //cope with selection being out of matrix limits at bottom (> NUMDAYS-1) if (mSelEnd > NUMDAYS-1) { for (int i = i0; i <= NUMDAYS-1; i++) { selDays.append(days[i]); } for (int i = NUMDAYS; i < mSelEnd; i++) { selDays.append(days[0].addDays(i)); } // apply normal routine to selection being entirely within matrix limits } else { for (int i = i0; i <= mSelEnd; i++) { selDays.append(days[i]); } } } void KODayMatrix::setSelectedDaysFrom(const QDate& start, const QDate& end) { mSelStart = startdate.daysTo(start); if ( mSelStart < 0 ) mSelStart = 0; mSelEnd = startdate.daysTo(end); if ( mSelEnd < 0 ) clearSelection(); } void KODayMatrix::clearSelection() { mSelEnd = mSelStart = NOSELECTION; } void KODayMatrix::recalculateToday() { today = -1; for (int i=0; i<NUMDAYS; i++) { events[i] = 0; days[i] = startdate.addDays(i); daylbls[i] = QString::number( KOGlobals::self()->calendarSystem()->day( days[i] )); // if today is in the currently displayed month, hilight today if (days[i].year() == QDate::currentDate().year() && days[i].month() == QDate::currentDate().month() && days[i].day() == QDate::currentDate().day()) { today = i; } } // qDebug(QString("Today is visible at %1.").arg(today)); } void KODayMatrix::updateView() { updateView(startdate); } void KODayMatrix::repaintViewTimed() { mRepaintTimer->stop(); repaint(false); } void KODayMatrix::updateViewTimed() { mUpdateTimer->stop(); if ( !mCalendar ) { qDebug("NOT CAL "); return; } //qDebug("KODayMatrix::updateViewTimed "); for(int i = 0; i < NUMDAYS; i++) { // if events are set for the day then remember to draw it bold QPtrList<Event> eventlist = mCalendar->events(days[i]); Event *event; int numEvents = eventlist.count(); QString holiStr = ""; bDays.clearBit(i); for(event=eventlist.first();event != 0;event=eventlist.next()) { ushort recurType = event->recurrence()->doesRecur(); if ((recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur) || (recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur)) { numEvents--; } if ( event->categories().contains( i18n("Holiday") ) || event->categories().contains( "Holiday" )) { if ( !holiStr.isEmpty() ) holiStr += "\n"; holiStr += event->summary(); } if ( event->categories().contains( i18n("Birthday") ) || event->categories().contains( "Birthday" )) { if ( !holiStr.isEmpty() ) holiStr += "\n"; holiStr += event->summary(); bDays.setBit(i); } } events[i] = numEvents; //if it is a holy day then draw it red. Sundays are consider holidays, too if ( (KOGlobals::self()->calendarSystem()->dayOfWeek(days[i]) == KOGlobals::self()->calendarSystem()->weekDayOfPray()) || !holiStr.isEmpty()) { mHolidays[i] = holiStr; } else { mHolidays[i] = QString::null; } } if ( ! mPendingUpdateBeforeRepaint ) repaint(false); } void KODayMatrix::updateView(QDate actdate) { if ( ! actdate.isValid() ) { //qDebug("date not valid "); return; } mDayChanged = false; //flag to indicate if the starting day of the matrix has changed by this call //mDayChanged = false; // if a new startdate is to be set then apply Cornelius's calculation // of the first day to be shown if (actdate != startdate) { // reset index of selection according to shift of starting date from startdate to actdate if (mSelStart != NOSELECTION) { int tmp = actdate.daysTo(startdate); //kdDebug() << "Shift of Selection1: " << mSelStart << " - " << mSelEnd << " -> " << tmp << "(" << offset << ")" << endl; // shift selection if new one would be visible at least partly ! if (mSelStart+tmp < NUMDAYS && mSelEnd+tmp >= 0) { // nested if is required for next X display pushed from a different month - correction required // otherwise, for month forward and backward, it must be avoided if( mSelStart > NUMDAYS || mSelStart < 0 ) mSelStart = mSelStart + tmp; if( mSelEnd > NUMDAYS || mSelEnd < 0 ) mSelEnd = mSelEnd + tmp; } } startdate = actdate; mDayChanged = true; recalculateToday(); } //qDebug("restart Timer %d vis: %d", mDayChanged, isVisible() ); if ( !isVisible() ) { mPendingUpdateBeforeRepaint = true; } else { #ifdef DESKTOP_VERSION //mRepaintTimer->start( 150 ); mUpdateTimer->start( 150 ); #else mRepaintTimer->start( 350 ); mUpdateTimer->start( 1200 ); #endif } } void KODayMatrix::updateEvents() { if ( !mCalendar ) return; for( int i = 0; i < NUMDAYS; i++ ) { // if events are set for the day then remember to draw it bold QPtrList<Event> eventlist = mCalendar->events( days[ i ] ); int numEvents = eventlist.count(); Event *event; for( event = eventlist.first(); event != 0;event=eventlist.next()) { ushort recurType = event->doesRecur(); if ( ( recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur ) || diff --git a/korganizer/kodaymatrix.h b/korganizer/kodaymatrix.h index f4016b6..10f4b05 100644 --- a/korganizer/kodaymatrix.h +++ b/korganizer/kodaymatrix.h @@ -1,322 +1,324 @@ /* This file is part of KOrganizer. Copyright (c) 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at> 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 _KODAYMAT_H #define _KODAYMAT_H #include <libkcal/calendar.h> #include <qstring.h> #include <qframe.h> #include <qcolor.h> #include <qpen.h> #include <qdatetime.h> #include <qtooltip.h> #include <qpixmap.h> #include <qbitarray.h> #include <qmap.h> class QDragEnterEvent; class QDragMoveEvent; class QDragLeaveEvent; class QDropEvent; class KODayMatrix; +class KODaymatrixWhatsThis; using namespace KCal; /** * small helper class to dynamically show tooltips inside the day matrix. * This class asks the day matrix object for a appropriate label which * is in our special case the name of the holiday or null if this day is no holiday. */ class DynamicTip : public QToolTip { public: /** * Constructor that expects a KODayMatrix object as parent. * * @param parent the parent KODayMatrix control. */ DynamicTip(QWidget* parent ); protected: /** * Qt's callback to ask the object to provide an approrpiate text for the * tooltip to be shown. * * @param pos coordinates of the mouse. */ void maybeTip( const QPoint & pos); private: /** the parent control this tooltip is designed for. */ KODayMatrix* matrix; }; /** * replacement for kdpdatebuton.cpp that used 42 widgets for the day matrix to be displayed. * Cornelius thought this was a waste of memory and a lot of overhead. * In addition the selection was not very intuitive so I decided to rewrite it using a QFrame * that draws the labels and allows for dragging selection while maintaining nearly full * compatibility in behaviour with its predecessor. * * The following functionality has been changed: * * o when shifting events in the agenda view from one day to another the day matrix is updated now * o TODO ET dragging an event to the matrix will MOVE not COPY the event to the new date. * o no support for Ctrl+click to create groups of dates * (This has not really been supported in the predecessor. It was not very intuitive nor was it * user friendly.) * This feature has been replaced with dragging a selection on the matrix. The matrix will * automatically choose the appropriate selection (e.g. you are not any longer able to select * two distinct groups of date selections as in the old class) * o now that you can select more then a week it can happen that not all selected days are * displayed in the matrix. However this is preferred to the alternative which would mean to * adjust the selection and leave some days undisplayed while scrolling through the months * * @short day matrix widget of the KDateNavigator * * @author Eitzenberger Thomas */ class KODayMatrix: public QFrame { Q_OBJECT public: /** constructor to create a day matrix widget. * * @param parent widget that is the parent of the day matrix. Normally this should * be a KDateNavigator * @param calendar instance of a calendar on which all calculations are based * @param date start date of the matrix (is expected to be already fixed). It is * assumed that this date is the first week day to be shown in the matrix. * @param name name of the widget */ KODayMatrix( QWidget *parent, const char *name ); //KODayMatrix(QWidget *parent, Calendar* calendar, QDate date, const char *name ); /** destructor that deallocates all dynamically allocated private members. */ ~KODayMatrix(); /** updates the day matrix to start with the given date. Does all the necessary * checks for holidays or events on a day and stores them for display later on. * Does NOT update the view visually. Call repaint() for this. * * @param actdate recalculates the day matrix to show NUMDAYS starting from this * date. */ void updateView(QDate actdate); void updateEvents(); /** returns the QDate object associated with day indexed by the * supplied offset. */ const QDate& getDate(int offset); void setCalendar( Calendar * ); /** returns the official name of this holy day or 0 if there is no label * for this day. */ QString getHolidayLabel(int offset); /** adds all actual selected days from mSelStart to mSelEnd to the supplied * DateList. */ void addSelectedDaysTo(DateList&); /** sets the actual to be displayed selection in the day matrix starting from * start and ending with end. Theview must be manually updated by calling * repaint. (?) */ void setSelectedDaysFrom(const QDate& start, const QDate& end); void clearSelection(); /** Is today visible in the view? Keep this in sync with * the values today (below) can take. */ bool isTodayVisible() const { return today>=0; } ; /** If today is visible, then we can find out if today is * near the beginning or the end of the month. * This is dependent on today remaining the index * in the array of visible dates and going from * top left (0) to bottom right (41). */ bool isBeginningOfMonth() const { return today<=8; } ; bool isEndOfMonth() const { return today>=27; } ; QString getWhatsThisText( QPoint ) ; QSize sizeHint() const; QRect frameRect () const { int wid = frameWidth(); return QRect(0+wid,0+wid,width()-wid-wid,height()-wid-wid);} public slots: /** Recalculates all the flags of the days in the matrix like holidays or events * on a day (Actually calls above method with the actual startdate). */ void updateView(); void updateViewTimed(); void repaintViewTimed(); /** * Calculate which square in the matrix should be * hilighted to indicate it's today. */ void recalculateToday(); /* void setStartDate(QDate); */ signals: /** emitted if the user selects a block of days with the mouse by dragging a rectangle * inside the matrix * * @param daylist list of days that have been selected by the user */ void selected( const KCal::DateList &daylist ); /** emitted if the user has dropped an event inside the matrix * * @param event the dropped calendar event */ void eventDropped(Event *event); protected: void paintEvent(QPaintEvent *ev); void mousePressEvent (QMouseEvent* e); void mouseReleaseEvent (QMouseEvent* e); void mouseMoveEvent (QMouseEvent* e); void dragEnterEvent(QDragEnterEvent *); void dragMoveEvent(QDragMoveEvent *); void dragLeaveEvent(QDragLeaveEvent *); void dropEvent(QDropEvent *); void resizeEvent(QResizeEvent *); private: + KODaymatrixWhatsThis* mKODaymatrixWhatsThis; bool mouseDown; QBitArray bDays; QPixmap myPix; QTimer* mUpdateTimer; QTimer* mRepaintTimer; bool mDayChanged; bool mPendingUpdateBeforeRepaint; /** returns the index of the day located at the matrix's widget (x,y) position. * * @param x horizontal coordinate * @param y vertical coordinate */ int getDayIndexFrom(int x, int y); /** calculates a "shaded" color from the supplied color object. * (Copied from Cornelius's kdpdatebutton.cpp) * * @param color source based on which a shaded color should be calculated. */ QColor getShadedColor(QColor color); /** number of days to be displayed. For now there is no support for any other number then 42. so change it at your own risk :o) */ static const int NUMDAYS; /** calendar instance to be queried for holidays, events, ... */ Calendar *mCalendar; /** starting date of the matrix */ QDate startdate; /** array of day labels to optimeize drawing performance. */ QString *daylbls; /** array of days displayed to reduce memory consumption by subsequently calling QDate::addDays(). */ QDate *days; /** array of storing the number of events on a given day. * used for drawing a bold font if there is at least one event on that day. */ int *events; /** stores holiday names of the days shown in the matrix. */ QMap<int,QString> mHolidays; /** indey of today or -1 if today is not visible in the matrix. */ int today; /** index of day where dragged selection was initiated. used to detect "negative" timely selections */ int mSelInit; /** if mSelStart has this value it indicates that there is no actual selection in the matrix. */ static const int NOSELECTION; /** index of first selected day. */ int mSelStart; /** index of last selected day. */ int mSelEnd; /** dynamic tooltip to handle mouse dependent tips for each day in the matrix. */ DynamicTip* mToolTip; /** default background colour of the matrix. */ QColor mDefaultBackColor; /** default text color of the matrix. */ QColor mDefaultTextColor; /** default text color for days not in the actual month. */ QColor mDefaultTextColorShaded; /** default text color for holidays not in the actual month. */ QColor mHolidayColorShaded; /** text color for selected days. */ QColor mSelectedDaysColor; /** default width of the frame drawn around today if it is visible in the matrix. */ int mTodayMarginWidth; /** stores actual size of each day in the widget so that I dont need to ask this data * on every repaint. */ QRect daysize; }; #endif diff --git a/korganizer/kotodoview.cpp b/korganizer/kotodoview.cpp index 5e8ea27..2b01c23 100644 --- a/korganizer/kotodoview.cpp +++ b/korganizer/kotodoview.cpp @@ -224,521 +224,522 @@ void KOTodoListView::contentsMousePressEvent(QMouseEvent* e) } } } #endif QListView::contentsMousePressEvent(e); } void KOTodoListView::paintEvent(QPaintEvent* e) { emit paintNeeded(); QListView::paintEvent( e); } void KOTodoListView::contentsMouseMoveEvent(QMouseEvent* e) { #ifndef KORG_NODND //QListView::contentsMouseMoveEvent(e); if (mMousePressed && (mPressPos - e->pos()).manhattanLength() > QApplication::startDragDistance()*3) { mMousePressed = false; QListViewItem *item = itemAt(contentsToViewport(mPressPos)); if (item) { DndFactory factory( mCalendar ); ICalDrag *vd = factory.createDrag( ((KOTodoViewItem *)item)->todo(),viewport()); internalDrop = false; // we cannot do any senseful here, because the DnD is still broken in Qt if (vd->drag()) { if ( !internalDrop ) { //emit deleteTodo( ((KOTodoViewItem *)item)->todo() ); qDebug("Dnd: External move: Delete drag source "); } else qDebug("Dnd: Internal move "); } else { if ( !internalDrop ) { qDebug("Dnd: External Copy"); } else qDebug("DnD: Internal copy: Copy pending"); } } } #endif } void KOTodoListView::keyPressEvent ( QKeyEvent * e ) { QListViewItem* cn; if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter ) { cn = currentItem(); if ( cn ) { KOTodoViewItem* ci = (KOTodoViewItem*)( cn ); if ( ci ){ if ( e->state() == ShiftButton ) ci->setOn( false ); else ci->setOn( true ); cn = cn->itemBelow(); if ( cn ) { setCurrentItem ( cn ); ensureItemVisible ( cn ); } } } return; } // qDebug("KOTodoListView::keyPressEvent "); if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton || mName != "todolistsmall" ) { switch ( e->key() ) { case Qt::Key_Down: case Qt::Key_Up: QListView::keyPressEvent ( e ); break; case Qt::Key_Left: case Qt::Key_Right: QListView::keyPressEvent ( e ); e->accept(); return; break; default: e->ignore(); break; } return; } e->ignore(); } void KOTodoListView::contentsMouseReleaseEvent(QMouseEvent *e) { QListView::contentsMouseReleaseEvent(e); mMousePressed = false; } void KOTodoListView::contentsMouseDoubleClickEvent(QMouseEvent *e) { if (!e) return; QPoint vp = contentsToViewport(e->pos()); QListViewItem *item = itemAt(vp); emit double_Clicked(item); if (!item) return; emit doubleClicked(item,vp,0); } ///////////////////////////////////////////////////////////////////////////// KOQuickTodo::KOQuickTodo(QWidget *parent) : QLineEdit(parent) { setText(i18n("Click to add a new Todo")); } void KOQuickTodo::focusInEvent(QFocusEvent *ev) { if ( text()==i18n("Click to add a new Todo") ) setText(""); QLineEdit::focusInEvent(ev); } void KOQuickTodo::focusOutEvent(QFocusEvent *ev) { setText(i18n("Click to add a new Todo")); QLineEdit::focusOutEvent(ev); } ///////////////////////////////////////////////////////////////////////////// KOTodoView::KOTodoView(Calendar *calendar,QWidget* parent,const char* name) : KOrg::BaseView(calendar,parent,name) { mPendingUpdateBeforeRepaint = false; isFlatDisplay = false; mNavigator = 0; QBoxLayout *topLayout = new QVBoxLayout(this); mName = QString ( name ); mBlockUpdate = false; mQuickAdd = new KOQuickTodo(this); topLayout->addWidget(mQuickAdd); if ( !KOPrefs::instance()->mEnableQuickTodo ) mQuickAdd->hide(); mTodoListView = new KOTodoListView(calendar,this, name ); topLayout->addWidget(mTodoListView); //mTodoListView->header()->setMaximumHeight(30); mTodoListView->setRootIsDecorated(true); mTodoListView->setAllColumnsShowFocus(true); mTodoListView->setShowSortIndicator(true); mTodoListView->addColumn(i18n("Todo")); mTodoListView->addColumn(i18n("Prio")); mTodoListView->setColumnAlignment(1,AlignHCenter); mTodoListView->addColumn(i18n("Complete")); mTodoListView->setColumnAlignment(2,AlignCenter); mTodoListView->addColumn(i18n("Due Date")); mTodoListView->setColumnAlignment(3,AlignLeft); mTodoListView->addColumn(i18n("Due Time")); mTodoListView->setColumnAlignment(4,AlignHCenter); mTodoListView->addColumn(i18n("Start Date")); mTodoListView->setColumnAlignment(5,AlignLeft); mTodoListView->addColumn(i18n("Start Time")); mTodoListView->setColumnAlignment(6,AlignHCenter); mTodoListView->addColumn(i18n("Cancelled")); mTodoListView->addColumn(i18n("Categories")); #if 0 mTodoListView->addColumn(i18n("Sort Id")); mTodoListView->setColumnAlignment(4,AlignHCenter); #endif mTodoListView->setMinimumHeight( 60 ); mTodoListView->setItemsRenameable( true ); mTodoListView->setRenameable( 0 ); mTodoListView->setColumnWidth( 0, 120 ); mTodoListView->setColumnWidthMode(0, QListView::Manual); mTodoListView->setColumnWidthMode(1, QListView::Manual); mTodoListView->setColumnWidthMode(2, QListView::Manual); mTodoListView->setColumnWidthMode(3, QListView::Manual); mTodoListView->setColumnWidthMode(4, QListView::Manual); mTodoListView->setColumnWidthMode(5, QListView::Manual); mTodoListView->setColumnWidthMode(6, QListView::Manual); mTodoListView->setColumnWidthMode(7, QListView::Manual); mTodoListView->setColumnWidthMode(8, QListView::Manual); - new KOTodoViewWhatsThis(mTodoListView->viewport(),this); + mKOTodoViewWhatsThis = new KOTodoViewWhatsThis(mTodoListView->viewport(),this); mPriorityPopupMenu = new QPopupMenu(this); for (int i = 1; i <= 5; i++) { QString label = QString ("%1").arg (i); mPriority[mPriorityPopupMenu->insertItem (label)] = i; } connect (mPriorityPopupMenu, SIGNAL(activated (int)), SLOT (setNewPriority(int))); mPercentageCompletedPopupMenu = new QPopupMenu(this); for (int i = 0; i <= 100; i+=20) { QString label = QString ("%1 %").arg (i); mPercentage[mPercentageCompletedPopupMenu->insertItem (label)] = i; } connect (mPercentageCompletedPopupMenu, SIGNAL (activated (int)), SLOT (setNewPercentage (int))); mItemPopupMenu = new QPopupMenu(this); mItemPopupMenu->insertItem(i18n("Show..."), this, SLOT (showTodo())); mItemPopupMenu->insertItem(i18n("Edit..."), this, SLOT (editTodo())); mItemPopupMenu->insertItem( i18n("Delete"), this, SLOT (deleteTodo())); mItemPopupMenu->insertItem( i18n("Clone..."), this, SLOT (cloneTodo())); mItemPopupMenu->insertItem( i18n("Move..."), this, SLOT (moveTodo())); mItemPopupMenu->insertItem( i18n("Beam..."), this, SLOT (beamTodo())); mItemPopupMenu->insertItem( i18n("Toggle Cancel"), this, SLOT (cancelTodo())); mItemPopupMenu->insertSeparator(); mItemPopupMenu->insertItem( i18n("New Todo..."), this, SLOT (newTodo())); mItemPopupMenu->insertItem(i18n("New Sub-Todo..."), this, SLOT (newSubTodo())); mItemPopupMenu->insertItem(i18n("Unparent Todo"), this, SLOT (unparentTodo()),0,21); mItemPopupMenu->insertItem(i18n("Reparent Todo"), this, SLOT (reparentTodo()),0,22); mItemPopupMenu->insertSeparator(); #if 0 mItemPopupMenu->insertItem(i18n("Delete completed To-Dos","Purge Completed"), this, SLOT( purgeCompleted() ) ); mItemPopupMenu->insertItem(i18n("toggle completed To-Dos","Show Completed"), this, SLOT( toggleCompleted() ),0, 33 ); mItemPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"), this, SLOT( toggleQuickTodo() ),0, 34 ); mItemPopupMenu->insertItem(i18n("toggle running todo","Hide not Running"), this, SLOT( toggleRunning() ),0, 35 ); #endif mPopupMenu = new QPopupMenu(this); mPopupMenu->insertItem(SmallIconSet("todo"), i18n("New Todo..."), this, SLOT (newTodo()),0,1); mPopupMenu->insertItem(i18n("delete completed To-Dos","Purge Completed"), this, SLOT(purgeCompleted()),0,2); mPopupMenu->insertItem(i18n("Show Completed"), this, SLOT( toggleCompleted() ),0,3 ); mPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"), this, SLOT( toggleQuickTodo() ),0,4 ); mPopupMenu->insertItem(i18n("toggle running todo","Hide not Running"), this, SLOT( toggleRunning() ),0,5 ); mPopupMenu->insertItem(i18n(" set all open","Display all opened"), this, SLOT( setAllOpen() ),0,6 ); mPopupMenu->insertItem(i18n(" set all close","Display all closed"), this, SLOT( setAllClose() ),0,7 ); mPopupMenu->insertItem(i18n(" set all flat","Display all flat"), this, SLOT( setAllFlat() ),0,8 ); mDocPrefs = new DocPrefs( name ); mItemPopupMenu->insertItem(i18n("Todo View"),mPopupMenu ); mPopupMenu->setCheckable( true ); mItemPopupMenu->setCheckable( true ); mPopupMenu->setItemChecked( 3,KOPrefs::instance()->mShowCompletedTodo ); mItemPopupMenu->setItemChecked( 33 , KOPrefs::instance()->mShowCompletedTodo ); mPopupMenu->setItemChecked(4,KOPrefs::instance()->mEnableQuickTodo); mItemPopupMenu->setItemChecked( 34 , KOPrefs::instance()->mEnableQuickTodo ); mPopupMenu->setItemChecked(5,KOPrefs::instance()->mHideNonStartedTodos); mItemPopupMenu->setItemChecked( 35 , KOPrefs::instance()->mHideNonStartedTodos ); // Double clicking conflicts with opening/closing the subtree connect( mTodoListView, SIGNAL( doubleClicked( QListViewItem *) ), SLOT( editItem( QListViewItem *) ) ); /* connect( mTodoListView, SIGNAL( rightButtonClicked ( QListViewItem *, const QPoint &,int ) ), SLOT( popupMenu( QListViewItem *, const QPoint & ,int) ) ); */ connect( mTodoListView, SIGNAL( contextRequest ( QListViewItem *, const QPoint &,int ) ), SLOT( popupMenu( QListViewItem *, const QPoint & ,int) ) ); connect( mTodoListView, SIGNAL( clicked( QListViewItem * ) ), SLOT( itemClicked( QListViewItem * ) ) ); connect( mTodoListView, SIGNAL( double_Clicked( QListViewItem * ) ), SLOT( itemDoubleClicked( QListViewItem * ) ) ); connect( mTodoListView, SIGNAL( todoDropped( Todo *, int ) ), SLOT( updateView() ) ); connect( mTodoListView, SIGNAL( todoDropped( Todo *, int ) ), SLOT( todoModified(Todo *, int) ) ); connect( mTodoListView, SIGNAL( expanded( QListViewItem * ) ), SLOT( itemStateChanged( QListViewItem * ) ) ); connect( mTodoListView, SIGNAL( collapsed( QListViewItem * ) ), SLOT( itemStateChanged( QListViewItem * ) ) ); connect( mTodoListView, SIGNAL( paintNeeded() ), SLOT( paintNeeded()) ); #if 0 connect(mTodoListView,SIGNAL(selectionChanged(QListViewItem *)), SLOT(selectionChanged(QListViewItem *))); connect(mTodoListView,SIGNAL(clicked(QListViewItem *)), SLOT(selectionChanged(QListViewItem *))); connect(mTodoListView,SIGNAL(pressed(QListViewItem *)), SLOT(selectionChanged(QListViewItem *))); #endif connect( mTodoListView, SIGNAL(reparentTodoSignal( Todo *,Todo * ) ), SIGNAL(reparentTodoSignal( Todo *,Todo * ) )); connect( mTodoListView, SIGNAL(unparentTodoSignal(Todo *) ), SIGNAL(unparentTodoSignal(Todo *) )); connect( mTodoListView, SIGNAL( deleteTodo(Todo *) ), SIGNAL(deleteTodoSignal(Todo *) )); connect( mTodoListView, SIGNAL(selectionChanged() ), SLOT( processSelectionChange() ) ); connect( mQuickAdd, SIGNAL( returnPressed () ), SLOT( addQuickTodo() ) ); } KOTodoView::~KOTodoView() { + delete mKOTodoViewWhatsThis; delete mDocPrefs; } QString KOTodoView::getWhatsThisText(QPoint p) { KOTodoViewItem* item = ( KOTodoViewItem* ) mTodoListView->itemAt( p ); if ( item ) return KIncidenceFormatter::instance()->getFormattedText( item->todo(), KOPrefs::instance()->mWTshowDetails, KOPrefs::instance()->mWTshowCreated, KOPrefs::instance()->mWTshowChanged); return i18n("That is the todo view" ); } void KOTodoView::jumpToDate () { // if (mActiveItem) { // mActiveItem->todo()); // if ( mActiveItem->todo()->hasDueDate() ) // emit mActiveItem->todo()jumpToTime( mTodo->dtDue().date() ); } void KOTodoView::paintNeeded() { if ( mPendingUpdateBeforeRepaint ) { updateView(); mPendingUpdateBeforeRepaint = false; } } void KOTodoView::paintEvent(QPaintEvent * pevent) { if ( mPendingUpdateBeforeRepaint ) { updateView(); mPendingUpdateBeforeRepaint = false; } KOrg::BaseView::paintEvent( pevent); } void KOTodoView::updateView() { pendingSubtodo = 0; if ( mBlockUpdate ) { return; } if ( !isVisible() ) { mPendingUpdateBeforeRepaint = true; return; } //qDebug("KOTodoView::updateView() %x", this); if ( isFlatDisplay ) { displayAllFlat(); return; } //qDebug("update "); // kdDebug() << "KOTodoView::updateView()" << endl; QFont fo = KOPrefs::instance()->mTodoViewFont; Incidence* oldInc = 0; mActiveItem = (KOTodoViewItem*)mTodoListView->currentItem(); if (mActiveItem) oldInc = mActiveItem->todo(); mTodoListView->clear(); if ( mName == "todolistsmall" ) { if ( KOPrefs::instance()->mTodoViewUsesSmallFont ) { int ps = fo.pointSize() -2; if ( ps > 12 ) ps -= 2; fo.setPointSize( ps ); } } mTodoListView->setFont( fo ); // QFontMetrics fm ( KOPrefs::instance()->mTodoViewFont ); //mTodoListView->header()->setMaximumHeight(fm.height()); QPtrList<Todo> todoList = calendar()->todos(); /* kdDebug() << "KOTodoView::updateView(): Todo List:" << endl; Event *t; for(t = todoList.first(); t; t = todoList.next()) { kdDebug() << " " << t->getSummary() << endl; if (t->getRelatedTo()) { kdDebug() << " (related to " << t->getRelatedTo()->getSummary() << ")" << endl; } QPtrList<Event> l = t->getRelations(); Event *c; for(c=l.first();c;c=l.next()) { kdDebug() << " - relation: " << c->getSummary() << endl; } } */ // Put for each Event a KOTodoViewItem in the list view. Don't rely on a // specific order of events. That means that we have to generate parent items // recursively for proper hierarchical display of Todos. mTodoMap.clear(); Todo *todo; todo = todoList.first();// todo; todo = todoList.next()) { while ( todo ) { bool next = true; // qDebug("todo %s ", todo->summary().latin1()); Incidence *incidence = todo->relatedTo(); while ( incidence ) { if ( incidence->type() == "Todo") { //qDebug("related %s ",incidence->summary().latin1() ); if ( !(todoList.contains ( ((Todo* )incidence ) ) )) { //qDebug("related not found "); todoList.remove( ); todo = todoList.current(); next = false; incidence = 0; } else { //qDebug("related found "); incidence = incidence->relatedTo(); } } else incidence = 0; } if ( next ) todo = todoList.next(); } // qDebug("again .... "); // for(todo = todoList.first(); todo; todo = todoList.next()) { // qDebug("yytodo %s ", todo->summary().latin1()); // } //qDebug("for "); for(todo = todoList.first(); todo; todo = todoList.next()) { if (!mTodoMap.contains(todo) && checkTodo( todo ) ) { insertTodoItem(todo); } } //qDebug("for end "); // Restore opened/closed state mTodoListView->blockSignals( true ); if( mDocPrefs ) restoreItemState( mTodoListView->firstChild() ); mTodoListView->blockSignals( false ); mTodoListView->setFocus(); if ( mTodoListView->firstChild () ) { if ( oldInc ) { KOTodoViewItem* item = (KOTodoViewItem*)mTodoListView->firstChild (); while ( item ) { if ( item->todo() == oldInc ) { mTodoListView->setCurrentItem( item ); mTodoListView->ensureItemVisible( item ); break; } item = (KOTodoViewItem*)item->itemBelow(); } if ( ! item ) mTodoListView->setCurrentItem( mTodoListView->firstChild () ); } else { mTodoListView->setCurrentItem( mTodoListView->firstChild () ); } } processSelectionChange(); } bool KOTodoView::checkTodo( Todo * todo ) { if ( !KOPrefs::instance()->mShowCompletedTodo && todo->isCompleted() ) return false; if ( !todo->isCompleted() ) { if ( todo->hasDueDate() && todo->dtDue().date() <= QDate::currentDate() ) return true; } if ( KOPrefs::instance()->mHideNonStartedTodos && mNavigator ) { if ( todo->hasStartDate() ) if ( mNavigator->selectedDates().last() < todo->dtStart().date() ) return false; if ( todo->hasDueDate() ) if ( mNavigator->selectedDates().first() > todo->dtDue().date() ) return false; } return true; } void KOTodoView::restoreItemState( QListViewItem *item ) { pendingSubtodo = 0; while( item ) { KOTodoViewItem *todoItem = (KOTodoViewItem *)item; todoItem->setOpen( mDocPrefs->readBoolEntry( todoItem->todo()->uid() ) ); if( item->childCount() > 0 ) restoreItemState( item->firstChild() ); item = item->nextSibling(); } } diff --git a/korganizer/kotodoview.h b/korganizer/kotodoview.h index 462f0a6..eab0754 100644 --- a/korganizer/kotodoview.h +++ b/korganizer/kotodoview.h @@ -1,255 +1,257 @@ /* This file is part of KOrganizer. Copyright (c) 2000, 2001 Cornelius Schumacher <schumacher@kde.org> 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 KOTODOVIEW_H #define KOTODOVIEW_H #include <qfont.h> #include <qfontmetrics.h> #include <qlineedit.h> #include <qptrlist.h> #include <qstrlist.h> #include <qlistbox.h> #include <qpopupmenu.h> #include <qlabel.h> #include <qmap.h> #include <qlistview.h> #include <klistview.h> #include <libkcal/calendar.h> #include <libkcal/todo.h> #include <korganizer/baseview.h> #include "kotodoviewitem.h" #include "koprefs.h" #include "koglobals.h" #include "datenavigator.h" class QDragEnterEvent; class QDragMoveEvent; class QDragLeaveEvent; class QDropEvent; +class KOTodoViewWhatsThis; class DocPrefs; class KOTodoListView : public KListView { Q_OBJECT public: KOTodoListView(Calendar *,QWidget *parent=0,const char *name=0); virtual ~KOTodoListView() {} signals: void paintNeeded(); void todoDropped(Todo *, int); void double_Clicked(QListViewItem *item); void reparentTodoSignal( Todo *,Todo * ); void unparentTodoSignal(Todo *); void deleteTodo( Todo * ); protected: void contentsDragEnterEvent(QDragEnterEvent *); void contentsDragMoveEvent(QDragMoveEvent *); void contentsDragLeaveEvent(QDragLeaveEvent *); void contentsDropEvent(QDropEvent *); void contentsMousePressEvent(QMouseEvent *); void contentsMouseMoveEvent(QMouseEvent *); void contentsMouseReleaseEvent(QMouseEvent *); void contentsMouseDoubleClickEvent(QMouseEvent *); private: void paintEvent(QPaintEvent * pevent); bool internalDrop; QString mName; Calendar *mCalendar; QPoint mPressPos; bool mMousePressed; QListViewItem *mOldCurrent; void keyPressEvent ( QKeyEvent * ) ; }; /** This is the line-edit on top of the todoview for fast addition of new todos */ class KOQuickTodo : public QLineEdit { public: KOQuickTodo(QWidget *parent=0); protected: void focusInEvent(QFocusEvent *ev); void focusOutEvent(QFocusEvent *ev); }; /** This class provides a multi-column list view of todo events. @short multi-column list view of todo events. @author Cornelius Schumacher <schumacher@kde.org> */ class KOTodoView : public KOrg::BaseView { Q_OBJECT public: KOTodoView(Calendar *, QWidget* parent=0, const char* name=0 ); ~KOTodoView(); QPtrList<Incidence> selectedIncidences(); QPtrList<Todo> selectedTodos(); DateList selectedDates() {DateList q; return q;} /** Return number of shown dates. TodoView does not show dates, */ int currentDateCount() { return 0; } void printPreview(CalPrinter *calPrinter, const QDate &fd, const QDate &td); void setDocumentId( const QString & ); void saveLayout(KConfig *config, const QString &group) const; void restoreLayout(KConfig *config, const QString &group); /** Create a popup menu to set categories */ QPopupMenu *getCategoryPopupMenu (KOTodoViewItem *todoItem); void setNavigator( DateNavigator* nav ) {mNavigator = nav;} QString getWhatsThisText(QPoint p); public slots: void updateView(); void updateConfig(); void changeEventDisplay(Event *, int); void showDates(const QDate &start, const QDate &end); void showEvents(QPtrList<Event> eventList); void clearSelection(); void jumpToDate (); void editItem(QListViewItem *item); void showItem(QListViewItem *item,const QPoint &,int); void popupMenu(QListViewItem *item,const QPoint &,int); void newTodo(); void newSubTodo(); void unparentTodo(); void reparentTodo(); void showTodo(); void editTodo(); void cloneTodo(); void cancelTodo(); void moveTodo(); void beamTodo(); void deleteTodo(); void setNewPriority(int); void setNewPercentage(int); void changedCategories(int); void setAllOpen(); void setAllClose(); void setAllFlat(); void displayAllFlat(); void purgeCompleted(); void toggleCompleted(); void toggleRunning(); void toggleQuickTodo(); void updateTodo( Todo *, int ); void itemClicked(QListViewItem *); void itemStateChanged(QListViewItem *); void modified(bool); void itemDoubleClicked(QListViewItem *item); signals: void newTodoSignal(); void newSubTodoSignal(Todo *); void unparentTodoSignal(Todo *); void reparentTodoSignal( Todo *,Todo * ); void showTodoSignal(Todo *); void editTodoSignal(Todo *); void deleteTodoSignal(Todo *); void todoModifiedSignal (Todo *, int); void isModified(bool); void cloneTodoSignal( Incidence * ); void cancelTodoSignal( Incidence * ); void moveTodoSignal( Incidence * ); void beamTodoSignal( Incidence * ); void purgeCompletedSignal(); protected slots: void paintNeeded(); void processSelectionChange(); void addQuickTodo(); void setTodoModified( Todo* ); void todoModified(Todo *, int ); private: /* * the TodoEditor approach is rather unscaling in the long * run. * Korganizer keeps it in memory and we need to update * 1. make KOTodoViewItem a QObject again? * 2. add a public method for setting one todo modified? * 3. add a private method for setting a todo modified + friend here? * -- zecke 2002-07-08 */ + KOTodoViewWhatsThis* mKOTodoViewWhatsThis; friend class KOTodoListView; void paintEvent(QPaintEvent * pevent); bool mPendingUpdateBeforeRepaint; friend class KOTodoViewItem; QMap<Todo *,KOTodoViewItem *>::ConstIterator insertTodoItem(Todo *todo); void restoreItemState( QListViewItem * ); bool checkTodo( Todo * ); bool isFlatDisplay; void setOpen( QListViewItem*, bool setOpen); KOTodoListView *mTodoListView; QPopupMenu *mItemPopupMenu; QPopupMenu *mPopupMenu; QPopupMenu *mPriorityPopupMenu; QPopupMenu *mPercentageCompletedPopupMenu; QPopupMenu *mCategoryPopupMenu; QMap<int, int> mPercentage; QMap<int, int> mPriority; QMap<int, QString> mCategory; KOTodoViewItem *mActiveItem; QMap<Todo *,KOTodoViewItem *> mTodoMap; QString mName; DocPrefs *mDocPrefs; QString mCurrentDoc; KOQuickTodo *mQuickAdd; bool mBlockUpdate; void keyPressEvent ( QKeyEvent * ) ; KOTodoViewItem * pendingSubtodo; DateNavigator* mNavigator; }; #endif |