-rw-r--r-- | korganizer/kodaymatrix.cpp | 144 | ||||
-rw-r--r-- | korganizer/kodaymatrix.h | 2 | ||||
-rw-r--r-- | korganizer/komonthview.cpp | 34 | ||||
-rw-r--r-- | korganizer/komonthview.h | 6 |
4 files changed, 173 insertions, 13 deletions
diff --git a/korganizer/kodaymatrix.cpp b/korganizer/kodaymatrix.cpp index c7e1b45..322131f 100644 --- a/korganizer/kodaymatrix.cpp +++ b/korganizer/kodaymatrix.cpp @@ -1,994 +1,1130 @@ /* 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() { ; }; 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 , Qt::WRepaintNoErase ), mCalendar( 0 ) #if 0 KODayMatrix::KODayMatrix(QWidget *parent, Calendar* calendar, QDate date, const char *name) : QFrame(parent, name) #endif { oldW = 0; oldH = 0; myPix.resize( 150, 120 ); mRedrawNeeded = true; mKODaymatrixWhatsThis = new KODaymatrixWhatsThis(this); mPendingUpdateBeforeRepaint = false; mouseDown = false; // initialize dynamic arrays bDays.resize ( NUMDAYS ); + pDays.resize ( NUMDAYS ); hDays.resize ( NUMDAYS ); eDays.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(); } } if ( !event->location().isEmpty() ) mToolTipText += " (" + event->location() + ")"; #if QT_VERSION >= 0x030000 mToolTipText.replace( '<' , "<" ); mToolTipText.replace( '>' , ">" ); #else if ( mToolTipText.find ('<') >= 0 ) { mToolTipText.replace( QRegExp("<") , "<" ); } if ( mToolTipText.find ('>') >= 0 ) { mToolTipText.replace( QRegExp(">") , ">" ); } #endif //qDebug("TTT: %s ", mToolTipText.latin1()); 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]); } } } bool KODayMatrix::setSelectedDaysFrom(const QDate& start, const QDate& end) { mRedrawNeeded = true; bool noSel = (mSelEnd == NOSELECTION && mSelStart == NOSELECTION ); mSelStart = startdate.daysTo(start); if ( mSelStart < 0 ) mSelStart = 0; mSelEnd = startdate.daysTo(end); if ( mSelEnd > NUMDAYS-1 ) mSelEnd = NUMDAYS-1; if ( mSelEnd < 0 || mSelStart > NUMDAYS-1 ) { clearSelection(); if ( noSel ) return false; } return true; } 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() { mRedrawNeeded = true; bDays.fill( false); + pDays.fill( false); hDays.fill( false); eDays.fill( false); mRepaintTimer->stop(); + int startDay = days[0].dayOfWeek(); // 1...7 7 = sunday + int i; + for(i = 0; i < NUMDAYS; i++) { + if ( ( (i+startDay) % 7 == 0 ) ) { + pDays.setBit(i); + } + } repaint(false); } +void KODayMatrix::computeEvent(Event *event, int i ) +{ + QString holiStr = mHolidays[i]; + if ( event->isHoliday()) { + pDays.setBit(i); + hDays.setBit(i); + if ( !holiStr.isEmpty() ) + holiStr += "\n"; + holiStr += event->summary(); + if ( !event->location().isEmpty() ) + holiStr += " (" + event->location() + ")"; + mHolidays[i] =holiStr ; + } + if ( event->isBirthday()) { + pDays.setBit(i); + if ( !holiStr.isEmpty() ) + holiStr += "\n"; + holiStr += i18n("Birthday") + ": "+event->summary(); + if ( !event->location().isEmpty() ) + holiStr += " (" + event->location() + ")"; + bDays.setBit(i); + mHolidays[i] =holiStr ; + } + eDays.setBit(i); +} void KODayMatrix::updateViewTimed() { mUpdateTimer->stop(); if ( !mCalendar ) { qDebug("NOT CAL "); return; } +#if 1 + + int i; + int timeSpan = NUMDAYS-1; + QPtrList<Event> events = mCalendar->events(); + Event *event; + QDateTime dt; + bool ok; + bDays.fill( false); + pDays.fill( false); + hDays.fill( false); + eDays.fill( false); + mHolidays.clear(); + QDate mStartDate = days[0]; + QDate endDate = mStartDate.addDays( timeSpan ); + for( event = events.first(); event; event = events.next() ) { // for event + ushort recurType = event->recurrence()->doesRecur(); + if ((recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur) || + (recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur)) { + continue; + } + if ( event->doesRecur() ) { + bool last; + QDateTime incidenceStart = event->recurrence()->getPreviousDateTime( QDateTime( mStartDate ) , &last ); + QDateTime incidenceEnd; + int eventlen = event->dtStart().date().daysTo ( event->dtEnd().date() ); + bool invalid = false; + while( true ) { + if ( incidenceStart.isValid() ) { + incidenceEnd = incidenceStart.addDays( eventlen ); + int st = incidenceStart.date().daysTo( endDate ); + if ( st >= 0 ) { // start before timeend + int end = mStartDate.daysTo( incidenceEnd.date() ); + if ( end >= 0 ) { // end after timestart --- got one! + //normalize + st = timeSpan - st; + if ( st < 0 ) st = 0; + if ( end > timeSpan ) end = timeSpan; + int iii; + //qDebug("found %s %d %d ",event->summary().latin1(), st, end ); + for ( iii = st;iii<= end;++iii) { + computeEvent( event, iii ); + } + } + } + } else { + if ( invalid ) + break; + invalid = true; + //qDebug("invalid %s", event->summary().latin1()); + incidenceStart = QDateTime( mStartDate ).addSecs( -2 );; + } + if ( last ) + break; + bool ok; + incidenceStart = event->getNextOccurence( incidenceStart.addSecs( 1 ) ,&ok ); + if ( ! ok ) + break; + if ( incidenceStart.date() > endDate ) + break; + } + } else { // no recur + int st = event->dtStart().date().daysTo( endDate ); + if ( st >= 0 ) { // start before timeend + int end = mStartDate.daysTo( event->dtEnd().date() ); + if ( end >= 0 ) { // end after timestart --- got one! + //normalize + st = timeSpan - st; + if ( st < 0 ) st = 0; + if ( end > timeSpan ) end = timeSpan; + int iii; + for ( iii = st;iii<= end;++iii) + computeEvent( event, iii ); + } + } + } + } + int startDay = days[0].dayOfWeek(); // 1...7 7 = sunday + for(i = 0; i < NUMDAYS; i++) { + if ( ( (i+startDay) % 7 == 0 ) ) { + pDays.setBit(i); + } + } + +#if 0 + // insert due todos + QPtrList<Todo> todos = calendar()->todos( ); + Todo *todo; + for(todo = todos.first(); todo; todo = todos.next()) { + //insertTodo( todo ); + if ( todo->hasDueDate() ) { + int day = mStartDate.daysTo( todo->dtDue().date() ); + if ( day >= 0 && day < timeSpan + 1) { + (*cells)[day]->insertTodo( todo ); + } + } + } +#endif + +#else //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); hDays.clearBit(i); eDays.clearBit(i); for(event=eventlist.first();event != 0;event=eventlist.next()) { + qDebug("FFFFFFFFFFFFFFFFFFFFFFFFF "); ushort recurType = event->recurrence()->doesRecur(); if ((recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur) || (recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur)) { numEvents--; } if ( event->isHoliday()) { hDays.setBit(i); if ( !holiStr.isEmpty() ) holiStr += "\n"; holiStr += event->summary(); if ( !event->location().isEmpty() ) holiStr += " (" + event->location() + ")"; } if ( event->isBirthday()) { if ( !holiStr.isEmpty() ) holiStr += "\n"; holiStr += i18n("Birthday") + ": "+event->summary(); if ( !event->location().isEmpty() ) holiStr += " (" + event->location() + ")"; bDays.setBit(i); } } if ( numEvents ) eDays.setBit(i); //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; } } +#endif mRedrawNeeded = true; 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(); mRedrawNeeded = true; } //qDebug("restart Timer %d vis: %d", mDayChanged, isVisible() ); if ( !isVisible() ) { mPendingUpdateBeforeRepaint = true; } else { #ifdef DESKTOP_VERSION //mRepaintTimer->start( 100 ); //updateViewTimed(); mUpdateTimer->start( 50 ); #else mRepaintTimer->start( 350 ); - mUpdateTimer->start( 1200 ); + mUpdateTimer->start( 800 ); #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 ) || ( recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur ) ) { numEvents--; } } if ( numEvents ) eDays.setBit(i); else eDays.clearBit(i); } } const QDate& KODayMatrix::getDate(int offset) { if (offset < 0 || offset > NUMDAYS-1) { qDebug("Wrong offset2 %d", offset); return days[0]; } return days[offset]; } QString KODayMatrix::getHolidayLabel(int offset) { if (offset < 0 || offset > NUMDAYS-1) { qDebug("Wrong offset1 %d", offset); return QString(); } return mHolidays[offset]; } int KODayMatrix::getDayIndexFrom(int x, int y) { int colModulo = (width()-2) % 7; int rowModulo = (height()-2) % 6; #if 0 return 7*(y/daysize.height()) + (KOGlobals::self()->reverseLayout() ? 6 - x/daysize.width() : x/daysize.width()); #endif int xVal = (x-colModulo/2-2)/daysize.width(); int yVal = (y-rowModulo/2-2)/daysize.height(); return 7*(yVal) + xVal; } // ---------------------------------------------------------------------------- // M O U S E E V E N T H A N D L I N G // ---------------------------------------------------------------------------- void KODayMatrix::mousePressEvent (QMouseEvent* e) { if ( e->button() == LeftButton ) mouseDown = true; mSelStart = getDayIndexFrom(e->x(), e->y()); if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1; mSelInit = mSelStart; mSelEnd = mSelStart; mRedrawNeeded = true; repaint(false); } void KODayMatrix::mouseReleaseEvent (QMouseEvent* e) { mRedrawNeeded = true; if ( e->button() == LeftButton ) if ( ! mouseDown ) { return; } else mouseDown = false; int tmp = getDayIndexFrom(e->x(), e->y()); if (tmp > NUMDAYS-1) tmp=NUMDAYS-1; if (mSelInit > tmp) { mSelEnd = mSelInit; if (tmp != mSelStart) { mSelStart = tmp; repaint(false); } } else { mSelStart = mSelInit; //repaint only if selection has changed if (tmp != mSelEnd) { mSelEnd = tmp; repaint(false); } } DateList daylist; if ( mSelStart < 0 ) mSelStart = 0; for (int i = mSelStart; i <= mSelEnd; i++) { daylist.append(days[i]); } emit selected((const DateList)daylist); } void KODayMatrix::mouseMoveEvent (QMouseEvent* e) { if ( ! mouseDown ) { return; } mRedrawNeeded = true; int tmp = getDayIndexFrom(e->x(), e->y()); if (tmp > NUMDAYS-1) tmp=NUMDAYS-1; if (mSelInit > tmp) { mSelEnd = mSelInit; if (tmp != mSelStart) { mSelStart = tmp; repaint(false); } } else { mSelStart = mSelInit; //repaint only if selection has changed if (tmp != mSelEnd) { mSelEnd = tmp; repaint(false); } } } // ---------------------------------------------------------------------------- // D R A G ' N D R O P H A N D L I N G // ---------------------------------------------------------------------------- void KODayMatrix::dragEnterEvent(QDragEnterEvent *e) { #ifndef KORG_NODND if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) { e->ignore(); return; } // some visual feedback // oldPalette = palette(); // setPalette(my_HilitePalette); // update(); #endif } void KODayMatrix::dragMoveEvent(QDragMoveEvent *e) { #ifndef KORG_NODND if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) { e->ignore(); return; } e->accept(); #endif } void KODayMatrix::dragLeaveEvent(QDragLeaveEvent */*dl*/) { #ifndef KORG_NODND // setPalette(oldPalette); // update(); #endif } void KODayMatrix::dropEvent(QDropEvent *e) { #ifndef KORG_NODND // kdDebug() << "KODayMatrix::dropEvent(e) begin" << endl; if (!mCalendar || !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) { e->ignore(); return; } DndFactory factory( mCalendar ); Event *event = factory.createDrop(e); if (event) { e->acceptAction(); Event *existingEvent = mCalendar->event(event->uid()); if(existingEvent) { // uniquify event event->recreate(); /* KMessageBox::sorry(this, i18n("Event already exists in this calendar."), i18n("Drop Event")); delete event; return; */ } // kdDebug() << "Drop new Event" << endl; // Adjust date QDateTime start = event->dtStart(); QDateTime end = event->dtEnd(); int duration = start.daysTo(end); int idx = getDayIndexFrom(e->pos().x(), e->pos().y()); start.setDate(days[idx]); end.setDate(days[idx].addDays(duration)); event->setDtStart(start); event->setDtEnd(end); mCalendar->addEvent(event); emit eventDropped(event); } else { // kdDebug() << "KODayMatrix::dropEvent(): Event from drop not decodable" << endl; e->ignore(); } #endif } // ---------------------------------------------------------------------------- // P A I N T E V E N T H A N D L I N G // ---------------------------------------------------------------------------- void KODayMatrix::paintEvent(QPaintEvent * pevent) { if ( width() <= 0 || height() <= 0 ) return; if ( mPendingUpdateBeforeRepaint ) { updateViewTimed(); mPendingUpdateBeforeRepaint = false; } #if 0 if ( myPix.width() != width() || myPix.height()!=height() ) { myPix.resize(size() ); mRedrawNeeded = true; } #endif if ( oldW != width() || oldH !=height() ) mRedrawNeeded = true; oldH = height() ; oldW = width(); if ( myPix.width() < width() || myPix.height() < height() ) { myPix.resize(size() ); mRedrawNeeded = true; } if ( mRedrawNeeded ) { //qDebug("REDRAW "); QPainter p(&myPix); p.setFont(font()); int dheight = daysize.height(); int dwidth = daysize.width(); int row,col; int selw, selh; int xyOff = frameWidth(); int colModulo = (width()-2) % 7; int rowModulo = (height()-2) % 6; //qDebug("col %d row %d ",colModulo,rowModulo ); bool isRTL = KOGlobals::self()->reverseLayout(); // draw background and topleft frame p.fillRect(0,0,width(),height(), mDefaultBackColor); p.setPen(mDefaultTextColor); p.drawRect(0, 0, width(), height()); int mSelStartT = mSelStart; int mSelEndT = mSelEnd; if ( mSelEndT >= NUMDAYS ) mSelEndT = NUMDAYS-1; // draw selected days with highlighted background color if (mSelStart != NOSELECTION) { bool skip = false; if ( ! mouseDown ) { int mo = days[20].month(); //qDebug("-- %d %d ", mSelStartT, mSelEndT); //qDebug("%d %d %d - d %d", mo, days[mSelStartT].month() , days[mSelEndT].month(), days[mSelEndT].day() ); int startMo = days[mSelStartT].month(); int endMo = days[mSelEndT].month(); if ( startMo == 12 && mo == 1 && endMo <= 2 ) startMo = 1; if ( endMo == 1 && mo == 12 ) endMo = 12; if ( mo == 12 && startMo == 1 ) startMo = 13; if ( (startMo > mo || endMo < mo) ) { skip = true; } else { if ( days[mSelStartT].month() != mo ) { int add = days[mSelStartT].daysInMonth ()-days[mSelStartT].day(); mSelStartT += add +1; } if ( days[mSelEndT].month() != mo ) { int sub = days[mSelEndT].day(); mSelEndT -= sub ; } } } //qDebug("SKIP %d ", skip); if ( ! skip ) { row = mSelStartT/7; col = mSelStartT -row*7; QColor selcol = KOPrefs::instance()->mHighlightColor; int addCol = 0; int addRow = 0; int addRow2 = 0; int addCol2 = 0; if (row == mSelEndT/7) { if ( rowModulo ) { if ( row >= 6 - rowModulo ) addRow = row - 5 + rowModulo; } if ( colModulo ) { int colt1 = mSelEndT%7; //qDebug("colt1 %d ", colt1 ); if ( colt1 >= 7 - colModulo ) addCol = colt1 - 7 + colModulo+1; int colt = mSelStartT%7; if ( colt >= 7 - colModulo ) addCol2 = colt - 7 + colModulo; addCol -= addCol2; //qDebug("COL %d %d %d %d ",col , colt1 ,addCol ,addCol2 ); } // Single row selection //if ( row == 0) // addRow = 1; p.fillRect(isRTL ? (7 - (mSelEndT-mSelStartT+1) - col)*dwidth : col*dwidth+1+addCol2, row*dheight+addRow, (mSelEndT-mSelStartT+1)*dwidth+addCol, dheight+1, selcol); } else { // draw first row to the right if ( colModulo ) { if ( col >= 7 - colModulo ) addCol2 = col - 7 + colModulo; } if ( rowModulo ) { if ( row >= 6 - rowModulo ) addRow = row - 5 + rowModulo; } //if ( row == 0) // addRow = 1; int drawWid = width()-(col*dwidth+1+addCol2)-1; p.fillRect(isRTL ? 0 : col*dwidth+1+addCol2, row*dheight+addRow, drawWid, dheight+1, selcol); // draw full block till last line selh = mSelEndT/7-row; addRow = 0; if ( rowModulo ) { if ( mSelEndT/7 >= 6 - rowModulo ) addRow = mSelEndT/7 - 5 + rowModulo; } //qDebug("%d %d %d ",selh, row, addRow ); int addrow2 = addRow-selh+1; if ( addrow2 < 0 ) addrow2 = 0; if (selh > 1) { p.fillRect(1, (row+1)*dheight+addrow2, 7*dwidth+colModulo, (selh-1)*dheight+addRow,selcol); } // draw last block from left to mSelEndT selw = mSelEndT-7*(mSelEndT/7)+1; //qDebug("esl %d ",selw ); int add = 0; if ( colModulo ) { add = 7 - colModulo; if ( selw > add ) add = selw - add; else add = 0; } //qDebug("add %d ", add); p.fillRect(isRTL ? (7-selw)*dwidth : 1, (row+selh)*dheight+addRow, selw*dwidth+add, dheight+1, selcol); } } } // iterate over all days in the matrix and draw the day label in appropriate colors QColor actcol = mDefaultTextColorShaded; p.setPen(actcol); QPen tmppen; for(int i = 0; i < NUMDAYS; i++) { row = i/7; col = isRTL ? 6-(i-row*7) : i-row*7; // if it is the first day of a month switch color from normal to shaded and vice versa if ( KOGlobals::self()->calendarSystem()->day( days[i] ) == 1) { if (actcol == mDefaultTextColorShaded) { actcol = mDefaultTextColor; } else { actcol = mDefaultTextColorShaded; } p.setPen(actcol); } if (actcol == mDefaultTextColorShaded) { if ( ! mouseDown ) { continue; } } //Reset pen color after selected days block if (i == mSelEndT+1) { p.setPen(actcol); } // if today then draw rectangle around day if (today == i) { tmppen = p.pen(); QPen mTodayPen(p.pen()); if ( daysize.width() < 20 ) mTodayPen.setWidth(1); else mTodayPen.setWidth(mTodayMarginWidth); //draw red rectangle for holidays - if (!mHolidays[i].isNull()) { + if (pDays.testBit(i)) { if (actcol == mDefaultTextColor) { mTodayPen.setColor(KOPrefs::instance()->mHolidayColor); } else { mTodayPen.setColor(mHolidayColorShaded); } } //draw gray rectangle for today if in selection if (i >= mSelStartT && i <= mSelEndT) { QColor grey("grey"); mTodayPen.setColor(grey); } p.setPen(mTodayPen); int addCol = 0; int addRow = 0; if (rowModulo) { if ( row >= 6 - rowModulo ) addRow = row - 5 + rowModulo; } if ( colModulo ) { if ( col >= 7 - colModulo ) addCol = col - 6 + colModulo-1; } addCol += 1; if ( row == 0 ) addRow = 1; p.drawRect(col*dwidth+addCol, row*dheight+addRow, dwidth+1, dheight+1); p.setPen(tmppen); } // if any events are on that day then draw it using a bold font if ( eDays.testBit(i) ) { QFont myFont = font(); myFont.setBold(true); p.setFont(myFont); } // if it is a holiday then use the default holiday color - if ( !mHolidays[i].isNull()) { + if ( pDays.testBit(i)) { if ( bDays.testBit(i) ) { if ( hDays.testBit(i) ) p.setPen(QColor(Qt::green)); else p.setPen(QColor(Qt::green).dark()); } else { if (actcol == mDefaultTextColor ) { p.setPen(KOPrefs::instance()->mHolidayColor); } else { p.setPen(mHolidayColorShaded); } } } // draw selected days with special color // DO NOT specially highlight holidays in selection ! if (i >= mSelStartT && i <= mSelEndT) { ;//p.setPen(mSelectedDaysColor); } int addCol = 0; int addRow = 0; if ( colModulo ) { if ( col >= 7 - colModulo ) addCol = col - 7 + colModulo; } if ( rowModulo ) { if ( row >= 6 - rowModulo ) addRow = row - 5 + rowModulo; } //qDebug("add %d %d -- %d %d ", col, addCol, row, addRow); ++addCol;//++addCol; if ( row == 0) addRow = 1; p.drawText(col*dwidth+addCol, row*dheight+addRow, dwidth, dheight, Qt::AlignHCenter | Qt::AlignVCenter, daylbls[i]); // reset color to actual color - if (!mHolidays[i].isNull()) { + if (pDays.testBit(i)) { p.setPen(actcol); } // reset bold font to plain font if ( eDays.testBit(i)) { QFont myFont = font(); myFont.setBold(false); p.setFont(myFont); } } } else { //qDebug("NO redraw "); } bitBlt (this, pevent->rect().topLeft(), &myPix , pevent->rect() ,CopyROP); mRedrawNeeded = false; } // ---------------------------------------------------------------------------- // R E SI Z E E V E N T H A N D L I N G // ---------------------------------------------------------------------------- void KODayMatrix::resizeEvent(QResizeEvent *) { QRect sz = frameRect(); daysize.setHeight(sz.height()*7 / NUMDAYS); daysize.setWidth(sz.width() / 7); } QSize KODayMatrix::sizeHint() const { QFontMetrics fm ( font() ); int wid = fm.width( "30") *7+3; int hei = fm.height() * 6+3; //qDebug("KODayMatrix::sizeHint()********************* %d %d", wid , hei); return QSize ( wid, hei ); } diff --git a/korganizer/kodaymatrix.h b/korganizer/kodaymatrix.h index d725ead..b686bd7 100644 --- a/korganizer/kodaymatrix.h +++ b/korganizer/kodaymatrix.h @@ -1,328 +1,330 @@ /* 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. (?) */ bool 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: + void computeEvent(Event *even, int dayindex ); int oldW, oldH; bool mRedrawNeeded; KODaymatrixWhatsThis* mKODaymatrixWhatsThis; bool mouseDown; QBitArray bDays; QBitArray hDays; QBitArray eDays; + QBitArray pDays; 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/komonthview.cpp b/korganizer/komonthview.cpp index 1ed288b..425496a 100644 --- a/korganizer/komonthview.cpp +++ b/korganizer/komonthview.cpp @@ -1,1943 +1,1961 @@ /* 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 <qpopupmenu.h> #include <qfont.h> #include <qfontmetrics.h> #include <qkeycode.h> #include <qhbox.h> #include <qvbox.h> #include <qwidgetstack.h> #include <qpushbutton.h> #include <qtooltip.h> #include <qpainter.h> #include <qtimer.h> #include <qwhatsthis.h> #ifndef DESKTOP_VERSION #include <qpe/qpeapplication.h> #else #include <qapplication.h> #endif #include <kdebug.h> #include <klocale.h> #include <kglobal.h> #include <kconfig.h> #include <kiconloader.h> #include <kcalendarsystem.h> #ifndef KORG_NOPRINTER #include "calprinter.h" #endif #include "koprefs.h" #ifndef KORG_NOPLUGINS #include "kocore.h" #endif #include "koglobals.h" #include <libkcal/kincidenceformatter.h> #include "komonthview.h" #define PIXMAP_SIZE 5 #ifdef DESKTOP_VERSION QToolTipGroup *MonthViewCell::mToolTipGroup = 0; #endif class KNOWhatsThis :public QWhatsThis { public: KNOWhatsThis( KNoScrollListBox* sbox ) : QWhatsThis( sbox ), _wid( sbox) { }; //~KNOWhatsThis( ) {qDebug("~KNOWhatsThis( ) "); }; protected: virtual QString text( const QPoint& p) { return _wid->getWhatsThisText(p) ; }; private: KNoScrollListBox* _wid; }; KNoScrollListBox::KNoScrollListBox(QWidget *parent,const char *name) : QListBox(parent, name, WRepaintNoErase) { #ifndef DESKTOP_VERSION QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold ); #endif mWT = new KNOWhatsThis(this); resetOnFocusIn = true; setVScrollBarMode(QScrollView::AlwaysOff); setHScrollBarMode(QScrollView::AlwaysOff); } KNoScrollListBox::~KNoScrollListBox() { } void KNoScrollListBox::focusInEvent ( QFocusEvent * e ) { QListBox::focusInEvent ( e ); QListBoxItem * i = item ( 0 ); if ( i && resetOnFocusIn ) { setCurrentItem( i ); setSelected ( 0, true ); } resetOnFocusIn = true; if ( KOPrefs::instance()->mEnableMonthScroll || KOPrefs::instance()->mMonthViewWeek ) { QListBoxItem *fi = firstItem (); if (fi ) { int ihei = fi->height( this ); int hei = numRows () * ihei; if ( hei < height() - horizontalScrollBar()->height () ) { setVScrollBarMode(QScrollView::AlwaysOff); } else setVScrollBarMode(QScrollView::Auto); if ( ihei *3 > height() ) { setHScrollBarMode(QScrollView::AlwaysOff); } else { setHScrollBarMode(QScrollView::Auto); } } else { setVScrollBarMode(QScrollView::Auto); setHScrollBarMode(QScrollView::Auto); } } } void KNoScrollListBox::focusOutEvent ( QFocusEvent * e ) { int i = currentItem (); if ( i >= 0 ) { setSelected ( i, false ); } QListBox::focusOutEvent ( e ); setVScrollBarMode(QScrollView::AlwaysOff); setHScrollBarMode(QScrollView::AlwaysOff); } QString KNoScrollListBox::getWhatsThisText(QPoint p) { QListBoxItem* item = itemAt ( p ); if ( ! item ) { return i18n("Click in the cell\nto add an event!"); } return KIncidenceFormatter::instance()->getFormattedText(((MonthViewItem*) item)->incidence(), KOPrefs::instance()->mWTshowDetails, KOPrefs::instance()->mWTshowCreated, KOPrefs::instance()->mWTshowChanged); } void KNoScrollListBox::keyPressEvent(QKeyEvent *e) { //qDebug("KNoScrollListBox::keyPressEvent "); switch(e->key()) { case Key_Right: if ( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton ) { e->ignore(); return; } scrollBy(10,0); break; case Key_Left: if (e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton ) { e->ignore(); return; } scrollBy(-10,0); break; case Key_Up: if( e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton) { e->ignore(); break; } if ( count() ) { setCurrentItem((currentItem()+count()-1)%count()); if(!itemVisible(currentItem())) { if((unsigned int) currentItem() == (count()-1)) { setTopItem(currentItem()-numItemsVisible()+1); } else { setTopItem(topItem()-1); } } } break; case Key_Down: if(e->state() == Qt::ControlButton|| e->state() == Qt::ShiftButton) { e->ignore(); break; } if ( count () ) { setCurrentItem((currentItem()+1)%count()); if(!itemVisible(currentItem())) { if(currentItem() == 0) { setTopItem(0); } else { setTopItem(topItem()+1); } } } break; case Key_I: QTimer::singleShot( 1, this, SLOT ( oneDown() ) ); e->ignore(); break; case Key_Return: case Key_Enter: { if ( currentItem() >= 0 ) { emit doubleClicked( item( currentItem() ) ); e->accept(); } else { e->ignore(); } } break; case Key_Shift: emit shiftDown(); break; default: e->ignore(); break; } } void KNoScrollListBox::oneDown() { if ( count () ) { resetOnFocusIn = false; setCurrentItem((currentItem()+1)%count()); if(!itemVisible(currentItem())) { if(currentItem() == 0) { setTopItem(0); } else { setTopItem(topItem()+1); } } } } void KNoScrollListBox::keyReleaseEvent(QKeyEvent *e) { switch(e->key()) { case Key_Shift: emit shiftUp(); break; default: break; } } void KNoScrollListBox::mousePressEvent(QMouseEvent *e) { QListBox::mousePressEvent(e); if(e->button() == RightButton) { emit rightClick(); } } MonthViewItem::MonthViewItem( Incidence *incidence, QDate qd, const QString & s) : QListBoxItem() { mblockRepaint = true; setText( s ); mMultiday = 0; mIncidence = incidence; mDate = qd; mRecur = false; mAlarm = false; mReply = false; mInfo = false; + mdayPos = 0; isWeekItem = KOPrefs::instance()->mMonthViewWeek; //qDebug("NEWWWWWWWWWWWWW "); } void MonthViewItem::recycle( Incidence *incidence, QDate qd, const QString & s) { setText( s ); mMultiday = 0; mIncidence = incidence; mDate = qd; mRecur = false; mAlarm = false; mReply = false; - mInfo = false; + mInfo = false; + mdayPos = 0; //qDebug("recucleeeeeeeeeeeeeeeee "); } void MonthViewItem::paint(QPainter *p) { if ( mblockRepaint ) { //qDebug("block "); return; } //qDebug("NON block "); #if QT_VERSION >= 0x030000 bool sel = isSelected(); #else bool sel = selected(); #endif if (KOPrefs::instance()->mMonthViewUsesCategoryColor) { p->setBackgroundColor( palette().color( QPalette::Normal, \ sel ? QColorGroup::Highlight : QColorGroup::Background ) ); p->eraseRect( 0, 0, listBox()->maxItemWidth(), height( listBox() ) ); } int x = 1; //int y = 3;//(height() - mRecurPixmap.height()) /2; int size = PIXMAP_SIZE; if ( QApplication::desktop()->width() < 300 ) size = 3; int heihei = height( listBox () ); int y = (heihei - size -1 ) /2; if ( KOPrefs::instance()->mMonthShowIcons ) { if ( mInfo ) { p->fillRect ( x, y,size,size, Qt::darkGreen ); x += size + 1; } if ( mRecur ) { p->fillRect ( x, y,size,size, Qt::blue ); x += size + 1; } if ( mAlarm ) { p->fillRect ( x, y,size,size, Qt::red ); x += size + 1; } if ( mReply ) { p->fillRect ( x, y,size,size, Qt::yellow ); x += size + 1; } } if ( mMultiday ) { int yyy = y+(size/2); int sizeM = size+2; p->setBrush( QBrush::SolidPattern ); p->drawLine ( x+1, yyy, x +sizeM +sizeM/2-1, yyy ) ; if ( mMultiday == 2 || mMultiday == 3 ) { QPointArray pa ( 3 ); pa.setPoint (0, x, yyy ); pa.setPoint (1, x+sizeM/2, yyy+sizeM/2 ); pa.setPoint (2, x+sizeM/2, yyy-sizeM/2 ); p->drawPolygon( pa ); } if ( mMultiday == 2 || mMultiday == 1 ) { QPointArray pa ( 3 ); pa.setPoint (0, x+sizeM +sizeM/2, yyy ); pa.setPoint (1, x+sizeM, yyy+sizeM/2 ); pa.setPoint (2, x+sizeM, yyy-sizeM/2 ); p->drawPolygon( pa ); } if ( mMultiday == 1 ) { // p->fillRect ( x, yyy-sizeM/2+1, sizeM/2, size, QBrush ( QBrush::SolidPattern ) ); p->drawLine ( x+1, yyy-sizeM/2, x+1, yyy+sizeM/2 ); } if ( mMultiday == 3 ) { // p->fillRect ( x+sizeM, yyy-sizeM/2+1, sizeM/2, size, QBrush ( QBrush::SolidPattern ) ); p->drawLine ( x+sizeM +sizeM/2-1, yyy-sizeM/2, x+sizeM +sizeM/2-1, yyy+sizeM/2 ); } x += sizeM/2 + 1; x += sizeM + 1; } if ( mIncidence->type() == "Todo" ){ Todo* td = ( Todo* ) mIncidence; if ( td->isCompleted() ) { int half = size/2; p->drawLine ( x, heihei/2, x +half , heihei/2 +half ) ; p->drawLine ( x +half , heihei/2 +half , x +half+half +2 , heihei/2 -2 ) ; x += half+half + 4; } else { int val = td->percentComplete()/20; p->fillRect ( x+1, y-2, val ,size+4,Qt::black ); p->drawRect ( x, y-2,7,size+4); x += size + 3; } } QFontMetrics fm = p->fontMetrics(); int yPos; int pmheight = size; if( pmheight < fm.height() ) yPos = fm.ascent() + fm.leading()/2; else yPos = pmheight/2 - fm.height()/2 + fm.ascent(); p->setPen( palette().color( QPalette::Normal, sel ? \ QColorGroup::HighlightedText : QColorGroup::Foreground ) ); p->drawText( x, yPos, text() ); if ( mIncidence->cancelled() ) { int wid = fm.width( text() ); p->drawLine( x, heihei/2-1 ,x+wid, heihei/2-1 ); } } int MonthViewItem::height(const QListBox *lb) const { int ret = 10; if ( lb ) ret = lb->fontMetrics().lineSpacing()+1; return ret; } int MonthViewItem::width(const QListBox *lb) const { if( KOPrefs::instance()->mEnableMonthScroll || isWeekItem ) { int size = PIXMAP_SIZE; if ( QApplication::desktop()->width() < 300 ) size = 3; int x = 1; if ( KOPrefs::instance()->mMonthShowIcons ) { if ( mInfo ) { x += size + 1; } if( mRecur ) { x += size+1; } if( mAlarm ) { x += size+1; } if( mReply ) { x += size+1; } } if( mMultiday ) { x += size+1+2+size/2; } return( x + lb->fontMetrics().width( text() ) + 1 ); } if ( ! lb ) return 10; //qDebug("ret wid %d ", lb->width()); return lb->width(); } MonthViewCell::MonthViewCell( KOMonthView *parent,QWidget* par ) : KNoScrollListBox( par ), mMonthView( parent ) { //QVBoxLayout *topLayout = new QVBoxLayout( this ); currentPalette = 0; // mLabel = new QLabel( this );QPushButton mLabel = new QPushButton( this ); //mLabel->setFrameStyle( QFrame::Panel | QFrame::Plain ); //mLabel->setLineWidth( 1 ); //mLabel->setAlignment( AlignCenter ); mLabel->setFlat( true ); mLabel->setFocusPolicy(NoFocus); //mItemList = new KNoScrollListBox( this ); setMinimumSize( 10, 10 ); setFrameStyle( QFrame::Panel | QFrame::Plain ); setLineWidth( 1 ); //topLayout->addWidget( mItemList ); mLabel->raise(); // QColor( 0,0,255 ) QColor( 160,1600,255 ) mStandardPalette = palette(); mStandardPalette.setColor(QColorGroup::Base, mStandardPalette.color( QPalette::Normal, QColorGroup::Background ) ); enableScrollBars( false ); updateConfig(); //connect( mLabel, SIGNAL( clicked( )), SLOT( newEvent() )); connect( mLabel, SIGNAL( clicked( )), SLOT( showDay() )); connect( this , SIGNAL( doubleClicked( QListBoxItem *) ), SLOT( defaultAction( QListBoxItem * ) ) ); connect( this, SIGNAL( rightButtonPressed( QListBoxItem *, const QPoint &) ), SLOT( contextMenu( QListBoxItem * ) ) ); connect( this, SIGNAL( highlighted( QListBoxItem *) ), SLOT( selection( QListBoxItem * ) ) ); connect( this, SIGNAL( clicked( QListBoxItem * ) ), SLOT( cellClicked( QListBoxItem * ) ) ); connect( this, SIGNAL( clicked( QListBoxItem * ) ), SLOT( selection( QListBoxItem * ) ) ); } #ifdef DESKTOP_VERSION QToolTipGroup *MonthViewCell::toolTipGroup() { if (!mToolTipGroup) mToolTipGroup = new QToolTipGroup(0); return mToolTipGroup; } #endif void MonthViewCell::setDate( const QDate &date ) { // kdDebug() << "MonthViewCell::setDate(): " << date.toString() << endl; mDate = date; //resizeEvent( 0 ); } QDate MonthViewCell::date() const { return mDate; } void MonthViewCell::setPrimary( bool primary ) { mPrimary = primary; //setMyPalette(); } void MonthViewCell::setMyPalette() { if ( mHoliday) { if ( currentPalette == 1 ) return; mLabel->setPalette( QPalette ( mHolidayPalette.color( QPalette::Normal,QColorGroup::Base),mHolidayPalette.color(QPalette::Normal,QColorGroup::Base ) )); setPalette( mHolidayPalette ); //mLabel->setPalette( mHolidayPalette ); currentPalette = 1; } else { if ( mPrimary ) { if ( currentPalette == 2 ) return; mLabel->setPalette( QPalette ( mPrimaryPalette.color( QPalette::Normal,QColorGroup::Base),mPrimaryPalette.color(QPalette::Normal,QColorGroup::Base ) )); //mLabel->setPalette( mPrimaryPalette ); setPalette( mPrimaryPalette ); currentPalette = 2; } else { if ( currentPalette == 3 ) return; setPalette( mNonPrimaryPalette ); mLabel->setPalette( QPalette ( mNonPrimaryPalette.color( QPalette::Normal,QColorGroup::Base),mNonPrimaryPalette.color(QPalette::Normal,QColorGroup::Base ) )); //mLabel->setPalette( mNonPrimaryPalette );; currentPalette = 3; } } //QPalette pal = palette(); //mLabel->setPalette( QPalette ( pal.color( QPalette::Normal,QColorGroup::Base),pal.color(QPalette::Normal,QColorGroup::Base ) )); } QPalette MonthViewCell::getPalette () { if ( !KOPrefs::instance()->mMonthViewUsesDayColors ) return mStandardPalette; if ( mHoliday) { return mHolidayPalette ; } else { if ( mPrimary ) { return mPrimaryPalette ; } } return mNonPrimaryPalette; } bool MonthViewCell::isPrimary() const { return mPrimary; } void MonthViewCell::setHoliday( bool holiday ) { mHoliday = holiday; //setMyPalette(); } void MonthViewCell::setHoliday( const QString &holiday ) { mHolidayString = holiday; if ( !holiday.isEmpty() ) { setHoliday( true ); } } void MonthViewCell::startUpdateCell() { - + mdayCount = 0; setFocusPolicy(NoFocus); if ( !mMonthView->isUpdatePossible() ) return; MonthViewItem *mitem = (MonthViewItem*) firstItem (); while ( mitem ) { mitem->setBlockRepaint( true ); mitem = (MonthViewItem *)mitem->next(); } if ( mAvailItemList.count() > 20 ) { mAvailItemList.setAutoDelete( true ); mAvailItemList.clear(); mAvailItemList.setAutoDelete( false ); } /* if ( !isVisible() ){ return; } */ // qDebug("MonthViewCell::updateCell() "); setPrimary( mDate.month()%2 ); setHoliday( KOGlobals::self()->calendarSystem()->dayOfWeek(mDate) == KOGlobals::self()->calendarSystem()->weekDayOfPray() || ( mDate.dayOfWeek() == 6 ) && KOPrefs::instance()-> mExcludeSaturdays); if ( mDate == QDate::currentDate() ) { setLineWidth( 3 ); } else { setLineWidth( 1 ); } MonthViewItem* CurrentAvailItem = (MonthViewItem*) firstItem (); //clear(); while ( CurrentAvailItem ) { MonthViewItem *item = CurrentAvailItem; CurrentAvailItem = (MonthViewItem *)item->next(); mAvailItemList.append( item ); takeItem ( item ); } #ifdef DESKTOP_VERSION QToolTip::remove(this); #endif mToolTip.clear(); //qApp->processEvents(); #if 0 if ( !mHolidayString.isEmpty() ) { MonthViewItem *item = new MonthViewItem( 0, mDate, mHolidayString ); item->setPalette( mHolidayPalette ); insertItem( item ); mToolTip.append ( mHolidayString ); } #endif } -void MonthViewCell::insertEvent(Event *event) +int MonthViewCell::insertEvent(Event *event) { QString mToolTipText; setFocusPolicy(WheelFocus); if ( !(event->doesRecur() == Recurrence::rNone) ) { if ( !KOPrefs::instance()->mMonthDailyRecur && event->doesRecur() == Recurrence::rDaily ) - return; + return mdayCount; else if ( !KOPrefs::instance()->mMonthWeeklyRecur && event->doesRecur() == Recurrence::rWeekly ) - return; + return mdayCount; } if ( event->isHoliday()) { setHoliday( true ); if ( mDate.dayOfWeek() == 7 ) setLineWidth( 3 ); } 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(); } } MonthViewItem *item ; if ( mAvailItemList.count() ) { item = mAvailItemList.first(); mAvailItemList.remove( item ); item->recycle( event, mDate, text ); } else { item = new MonthViewItem( event, mDate, text ); } QPalette pal; if (KOPrefs::instance()->mMonthViewUsesCategoryColor) { QStringList categories = event->categories(); QString cat = categories.first(); if ( KOPrefs::instance()->mMonthViewUsesForegroundColor ) { pal = getPalette(); if (cat.isEmpty()) { pal.setColor(QColorGroup::Foreground,KOPrefs::instance()->mEventColor); } else { pal.setColor(QColorGroup::Foreground, *(KOPrefs::instance()->categoryColor(cat))); } } else { if (cat.isEmpty()) { pal = QPalette(KOPrefs::instance()->mEventColor, KOPrefs::instance()->mEventColor); } else { pal = QPalette(*(KOPrefs::instance()->categoryColor(cat)), *(KOPrefs::instance()->categoryColor(cat))); } } } else { pal = mStandardPalette ; } item->setPalette( pal ); item->setRecur( event->recurrence()->doesRecur() ); item->setAlarm( event->isAlarmEnabled() && multiday < 2 ); item->setMoreInfo( event->description().length() > 0 ); #ifdef DESKTOP_VERSION Attendee *me = event->attendeeByMails(KOPrefs::instance()->mAdditionalMails, KOPrefs::instance()->email()); if ( me != 0 ) { if ( me->status() == Attendee::NeedsAction && me->RSVP()) item->setReply(true && multiday < 2); else item->setReply(false); } else item->setReply(false); #endif item->setMultiDay( multiday ); - insertItem( item ); + if ( multiday ) { + insertItem( item ,mdayCount); + ++mdayCount; + } else { + uint i; + int pos = mdayCount; + for ( i = mdayCount; i < count();++i ) { + QListBoxItem* it = this->item ( i ); + if ( text < it->text() ) { + pos = i; + break; + } + ++pos; + } + insertItem( item ,pos); + } mToolTip.append( mToolTipText ); + return mdayCount; } void MonthViewCell::insertTodo(Todo *todo) { setFocusPolicy(WheelFocus); QString text; if (todo->hasDueDate()) { if (!todo->doesFloat()) { text += KGlobal::locale()->formatTime(todo->dtDue().time()); text += " "; } } text += todo->summary(); MonthViewItem *item ; if ( mAvailItemList.count() ) { item = mAvailItemList.first(); mAvailItemList.remove( item ); item->recycle( todo, mDate, text ); } else { item = new MonthViewItem( todo, mDate, text ); } //MonthViewItem *item = new MonthViewItem( todo, mDate, text ); //item->setPalette( mStandardPalette ); QPalette pal; if (KOPrefs::instance()->mMonthViewUsesCategoryColor) { QStringList categories = todo->categories(); QString cat = categories.first(); if ( KOPrefs::instance()->mMonthViewUsesForegroundColor ) { pal = getPalette(); if (cat.isEmpty()) { pal.setColor(QColorGroup::Foreground,KOPrefs::instance()->mEventColor); } else { pal.setColor(QColorGroup::Foreground, *(KOPrefs::instance()->categoryColor(cat))); } } else { if (cat.isEmpty()) { pal = QPalette(KOPrefs::instance()->mEventColor, KOPrefs::instance()->mEventColor); } else { pal = QPalette(*(KOPrefs::instance()->categoryColor(cat)), *(KOPrefs::instance()->categoryColor(cat))); } } } else { pal = mStandardPalette ; } item->setPalette( pal ); item->setRecur( todo->recurrence()->doesRecur() ); item->setAlarm( todo->isAlarmEnabled() ); item->setMoreInfo( todo->description().length() > 0 ); - insertItem( item ); + insertItem( item , count()); mToolTip.append( text ); } void MonthViewCell::repaintfinishUpdateCell() { MonthViewItem *mitem = (MonthViewItem*) firstItem (); while ( mitem ) { mitem->setBlockRepaint( false ); updateItem ( mitem ); mitem = (MonthViewItem *)mitem->next(); } } void MonthViewCell::finishUpdateCell() { #ifdef DESKTOP_VERSION if (mToolTip.count() > 0 ) { mToolTip.sort(); QToolTip::add(this,mToolTip.join("\n"),toolTipGroup(),""); } #endif - sort(); + //sort(); //setMyPalette(); setMyPalette(); resizeEvent( 0 ); } void MonthViewCell::updateCell() { //qDebug("MonthViewCell::updateCell() "); if ( !mMonthView->isUpdatePossible() ) return; startUpdateCell(); //mLabel->setMaximumWidth( width() - mItemList->lineWidth()*2); QPtrList<Event> events = mMonthView->calendar()->events( mDate, true ); Event *event; for( event = events.first(); event; event = events.next() ) { // for event insertEvent(event); } // insert due todos QPtrList<Todo> todos = mMonthView->calendar()->todos( mDate ); Todo *todo; for(todo = todos.first(); todo; todo = todos.next()) { insertTodo( todo ); } finishUpdateCell(); // if ( isVisible()) //qApp->processEvents(); } void MonthViewCell::updateConfig( bool bigFont ) // = false { if ( bigFont ) { QFont fo = KOPrefs::instance()->mMonthViewFont; int ps = fo.pointSize() + 2; if ( ps < 18 ) ps += 2; fo.setPointSize( ps ); setFont( fo ); } else setFont( KOPrefs::instance()->mMonthViewFont ); QFontMetrics fm( font() ); mLabelSize = fm.size( 0, "30" ) + QSize( 4, 2 ); mLabelBigSize = fm.size( 0, "Mag 30" ) + QSize( 2, 2 ); mHolidayPalette = mStandardPalette; mPrimaryPalette = mStandardPalette; mNonPrimaryPalette = mStandardPalette; if ( KOPrefs::instance()->mMonthViewUsesDayColors ) { mHolidayPalette.setColor(QColorGroup::Base, KOPrefs::instance()->mMonthViewHolidayColor ); mHolidayPalette.setColor(QColorGroup::Background, KOPrefs::instance()->mMonthViewHolidayColor ); mHolidayPalette.setColor(QColorGroup::Foreground, KOPrefs::instance()->mMonthViewHolidayColor.dark()); mPrimaryPalette.setColor(QColorGroup::Foreground,KOPrefs::instance()->mMonthViewOddColor.dark()); mPrimaryPalette.setColor(QColorGroup::Base,KOPrefs::instance()->mMonthViewOddColor); mPrimaryPalette.setColor(QColorGroup::Background,KOPrefs::instance()->mMonthViewOddColor); mNonPrimaryPalette.setColor(QColorGroup::Foreground,KOPrefs::instance()->mMonthViewEvenColor.dark()); mNonPrimaryPalette.setColor(QColorGroup::Base,KOPrefs::instance()->mMonthViewEvenColor); mNonPrimaryPalette.setColor(QColorGroup::Background,KOPrefs::instance()->mMonthViewEvenColor); } //updateCell(); } void MonthViewCell::enableScrollBars( bool enabled ) { return; if ( enabled ) { QListBoxItem *fi = firstItem (); if (fi ) { int ihei = fi->height( this ); int hei = numRows () * ihei; if ( hei < height() - horizontalScrollBar()->height () ) { setVScrollBarMode(QScrollView::AlwaysOff); } else setVScrollBarMode(QScrollView::Auto); if ( ihei *3 > height() ) { setHScrollBarMode(QScrollView::AlwaysOff); } else { setHScrollBarMode(QScrollView::Auto); } } else { setVScrollBarMode(QScrollView::Auto); setHScrollBarMode(QScrollView::Auto); } } else { setVScrollBarMode(QScrollView::AlwaysOff); setHScrollBarMode(QScrollView::AlwaysOff); } } Incidence *MonthViewCell::selectedIncidence() { int index = currentItem(); if ( index < 0 ) return 0; MonthViewItem *mitem = static_cast<MonthViewItem *>( item( index ) ); if ( !mitem ) return 0; return mitem->incidence(); } QDate MonthViewCell::selectedIncidenceDate() { QDate qd; int index = currentItem(); if ( index < 0 ) return qd; MonthViewItem *mitem = static_cast<MonthViewItem *>( item( index ) ); if ( !mitem ) return qd; return mitem->incidenceDate(); } void MonthViewCell::deselect() { clearSelection(); enableScrollBars( false ); // updateCell(); } void MonthViewCell::select() { ;// updateCell(); } void MonthViewCell::resizeEvent ( QResizeEvent * e ) { if ( !mMonthView->isUpdatePossible() ) return; //qDebug("++++++++++++++MonthViewCell::resizeEvent %d %d ", width(), height()); deselect(); mLabel->setMaximumHeight( height() - lineWidth()*2 ); QString text; mLabel->setText( text ); bool smallDisplay = QApplication::desktop()->width() < 320 && KOPrefs::instance()->mMonthViewSatSunTog; if ( KOPrefs::instance()->mMonthViewWeek || KOGlobals::self()->calendarSystem()->day( mDate ) == 1 || (mDate.dayOfWeek() == 7 && !smallDisplay ) || KOPrefs::instance()->mMonthShowShort) { text = KOGlobals::self()->calendarSystem()->monthName( mDate, true ) + " "; mLabel->resize( mLabelBigSize ); text += QString::number( KOGlobals::self()->calendarSystem()->day(mDate) ); } else { mLabel->resize( mLabelSize ); text += QString::number( KOGlobals::self()->calendarSystem()->day(mDate) ); } mLabel->setText( text ); int size = height() - mLabel->height() - lineWidth()-1; //qDebug("LW %d ", lineWidth()); if ( size > 0 ) verticalScrollBar()->setMaximumHeight( size ); size = width() - mLabel->width() -lineWidth()-1; if ( size > 0 ) horizontalScrollBar()->setMaximumWidth( size ); mLabel->move( width()-lineWidth() - mLabel->width(), height()-lineWidth() - mLabel->height() ); //mLabel->setMaximumWidth( width() - mItemList->lineWidth()*2); // mItemList->resize ( width(), height () ); if ( e ) KNoScrollListBox::resizeEvent ( e ); } void MonthViewCell::defaultAction( QListBoxItem *item ) { if ( !item ) { QDateTime dt( date(), QTime( KOPrefs::instance()->mStartTime, 0 ) ); emit newEventSignal( dt ); return; } MonthViewItem *eventItem = static_cast<MonthViewItem *>( item ); Incidence *incidence = eventItem->incidence(); if ( incidence ) mMonthView->defaultAction( incidence ); } void MonthViewCell::showDay() { emit showDaySignal( date() ); } void MonthViewCell::newEvent() { QDateTime dt( date(), QTime( KOPrefs::instance()->mStartTime, 0 ) ); emit newEventSignal( dt ); } void MonthViewCell::cellClicked( QListBoxItem *item ) { if ( item == 0 ) { QDateTime dt( date(), QTime( KOPrefs::instance()->mStartTime, 0 ) ); emit newEventSignal( dt ); return; } /* if ( lastClicked ) if ( ! item ) { if ( lastClicked->listBox() != item->listBox() ) lastClicked->listBox()->clearSelection(); } */ mMonthView->setSelectedCell( this ); if( KOPrefs::instance()->mEnableMonthScroll || KOPrefs::instance()->mMonthViewWeek ) enableScrollBars( true ); select(); } void MonthViewCell::contextMenu( QListBoxItem *item ) { if ( !item ) return; MonthViewItem *eventItem = static_cast<MonthViewItem *>( item ); Incidence *incidence = eventItem->incidence(); if ( incidence ) mMonthView->showContextMenu( incidence ); } void MonthViewCell::selection( QListBoxItem *item ) { if ( !item ) return; mMonthView->setSelectedCell( this ); } // ******************************************************************************* // ******************************************************************************* // ******************************************************************************* KOMonthView::KOMonthView(Calendar *calendar, QWidget *parent, const char *name) : KOEventView( calendar, parent, name ), mDaysPerWeek( 7 ), mNumWeeks( 6 ), mNumCells( mDaysPerWeek * mNumWeeks ), mWidthLongDayLabel( 0 ), mSelectedCell( 0 ) { mFlagKeyPressed = false; mShortDayLabelsM = false; mShortDayLabelsW = false; skipResize = false; clPending = true; mNavigatorBar = new NavigatorBar( QDate::currentDate(), this, "useBigPixmaps" ); mWidStack = new QWidgetStack( this ); QVBoxLayout* hb = new QVBoxLayout( this ); mMonthView = new QWidget( mWidStack ); mWeekView = new QWidget( mWidStack ); #if QT_VERSION >= 0x030000 mWidStack->addWidget(mMonthView ); mWidStack->addWidget(mWeekView ); #else mWidStack->addWidget( mMonthView, 1 ); mWidStack->addWidget( mWeekView , 1 ); #endif hb->addWidget( mNavigatorBar ); hb->addWidget( mWidStack ); mShowWeekView = KOPrefs::instance()->mMonthViewWeek; updatePossible = false; //updatePossible = true; mCells.setAutoDelete( true ); mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ; mDayLabels.resize( mDaysPerWeek ); mDayLabelsW.resize( mDaysPerWeek ); QFont bfont = font(); if ( QApplication::desktop()->width() < 650 ) { bfont.setPointSize( bfont.pointSize() - 2 ); } bfont.setBold( true ); int i; for( i = 0; i < mDaysPerWeek; i++ ) { QLabel *label = new QLabel( mMonthView ); label->setFont(bfont); label->setFrameStyle(QFrame::Panel|QFrame::Raised); label->setLineWidth(1); label->setAlignment(AlignCenter); mDayLabels.insert( i, label ); label = new QLabel( mWeekView ); label->setFont(bfont); label->setFrameStyle(QFrame::Panel|QFrame::Raised); label->setLineWidth(1); label->setAlignment(AlignCenter); mDayLabelsW.insert( i, label ); } bfont.setBold( false ); mWeekLabels.resize( mNumWeeks+1 ); mWeekLabelsW.resize( 2 ); for( i = 0; i < mNumWeeks+1; i++ ) { KOWeekButton *label = new KOWeekButton( mMonthView ); label->setFocusPolicy(NoFocus); label->setFont(bfont); connect( label, SIGNAL( selectWeekNum ( int )),this, SLOT( selectInternalWeekNum ( int )) ); label->setFlat(true); QWhatsThis::add(label,i18n("Click on the week number to\nshow week zoomed")); //label->setFrameStyle(QFrame::Panel|QFrame::Raised); //label->setLineWidth(1); //label->setAlignment(AlignCenter); mWeekLabels.insert( i, label ); } mWeekLabels[mNumWeeks]->setText( i18n("W")); mWeekLabels[mNumWeeks]->setFocusPolicy(WheelFocus); QWhatsThis::add(mWeekLabels[mNumWeeks],i18n("Click on this to\nselect week number")); for( i = 0; i < 1+1; i++ ) { KOWeekButton *label = new KOWeekButton( mWeekView ); label->setFocusPolicy(NoFocus); label->setFont(bfont); connect( label, SIGNAL( selectWeekNum ( int )),this, SLOT( selectInternalWeekNum ( int )) ); label->setFlat(true); QWhatsThis::add(label,i18n("Click on the week number to\nshow week zoomed")); //label->setFrameStyle(QFrame::Panel|QFrame::Raised); //label->setLineWidth(1); //label->setAlignment(AlignCenter); mWeekLabelsW.insert( i, label ); } mWeekLabelsW[1]->setText( i18n("W")); mWeekLabelsW[1]->setFocusPolicy(WheelFocus); int row, col; mCells.resize( mNumCells ); for( row = 0; row < mNumWeeks; ++row ) { for( col = 0; col < mDaysPerWeek; ++col ) { MonthViewCell *cell = new MonthViewCell( this, mMonthView ); mCells.insert( row * mDaysPerWeek + col, cell ); connect( cell, SIGNAL( defaultAction( Incidence * ) ), SLOT( defaultAction( Incidence * ) ) ); connect( cell, SIGNAL( newEventSignal( QDateTime ) ), SIGNAL( newEventSignal( QDateTime ) ) ); connect( cell, SIGNAL( showDaySignal( QDate ) ), SIGNAL( showDaySignal( QDate ) ) ); } } mCellsW.resize( mDaysPerWeek ); for( col = 0; col < mDaysPerWeek; ++col ) { MonthViewCell *cell = new MonthViewCell( this, mWeekView ); mCellsW.insert( col, cell ); connect( cell, SIGNAL( defaultAction( Incidence * ) ), SLOT( defaultAction( Incidence * ) ) ); connect( cell, SIGNAL( newEventSignal( QDateTime ) ), SIGNAL( newEventSignal( QDateTime ) ) ); connect( cell, SIGNAL( showDaySignal( QDate ) ), SIGNAL( showDaySignal( QDate ) ) ); cell->updateConfig(KOPrefs::instance()->mMonthViewUsesBigFont ); } //connect( mWeekLabels[mNumWeeks], SIGNAL( clicked() ), SLOT( switchView() ) ); mContextMenu = eventPopup(); // updateConfig(); //useless here... // ... but we need mWidthLongDayLabel computed QFontMetrics fontmetric(mDayLabels[0]->font()); mWidthLongDayLabel = 0; for (int i = 0; i < 7; i++) { int width = fontmetric.width(KOGlobals::self()->calendarSystem()->weekDayName(i+1)); if ( width > mWidthLongDayLabel ) mWidthLongDayLabel = width; } //mWeekLabels[mNumWeeks]->setText( i18n("W")); #if 0 if ( mShowWeekView ) mWidStack->raiseWidget( mWeekView ); else mWidStack->raiseWidget( mMonthView ); #endif emit incidenceSelected( 0 ); mComputeLayoutTimer = new QTimer( this ); connect (mComputeLayoutTimer ,SIGNAL(timeout()), this, SLOT ( slotComputeLayout())); #ifndef DESKTOP_VERSION resize( QApplication::desktop()->size() ); #else resize(640, 480 ); updatePossible = true; #endif computeLayout(); if ( mShowWeekView ) mWidStack->raiseWidget( mWeekView ); else mWidStack->raiseWidget( mMonthView ); } KOMonthView::~KOMonthView() { delete mContextMenu; } void KOMonthView::selectInternalWeekNum ( int n ) { switchView(); if ( !KOPrefs::instance()->mMonthViewWeek ) emit selectMonth (); else emit selectWeekNum ( n ); } int KOMonthView::currentWeek() { if ( mShowWeekView ) return mWeekLabelsW[0]->getWeekNum(); return mWeekLabels[0]->getWeekNum(); } void KOMonthView::switchView() { if ( selectedCell( ) ) selectedCell()->deselect(); mShowWeekView = !mShowWeekView; KOPrefs::instance()->mMonthViewWeek = mShowWeekView; if ( clPending ) { computeLayout(); updateConfig(); } if ( mShowWeekView ) mWidStack->raiseWidget( mWeekView ); else mWidStack->raiseWidget( mMonthView ); clPending = false; } int KOMonthView::maxDatesHint() { return mNumCells; } int KOMonthView::currentDateCount() { return mNumCells; } QPtrList<Incidence> KOMonthView::selectedIncidences() { QPtrList<Incidence> selected; if ( mSelectedCell ) { Incidence *incidence = mSelectedCell->selectedIncidence(); if ( incidence ) selected.append( incidence ); } return selected; } DateList KOMonthView::selectedDates() { DateList selected; if ( mSelectedCell ) { QDate qd = mSelectedCell->selectedIncidenceDate(); if ( qd.isValid() ) selected.append( qd ); } return selected; } void KOMonthView::printPreview(CalPrinter *calPrinter, const QDate &fd, const QDate &td) { #ifndef KORG_NOPRINTER calPrinter->preview(CalPrinter::Month, fd, td); #endif } void KOMonthView::updateConfig() { int mWeekStartsMonday = KGlobal::locale()->weekStartsMonday(); if ( mShowWeekView || KOPrefs::instance()->mMonthViewSatSunTog ) { mWeekStartsMonday = true; } QFontMetrics fontmetric(mDayLabels[0]->font()); mWidthLongDayLabel = 0; for (int i = 0; i < 7; i++) { int width = fontmetric.width(KOGlobals::self()->calendarSystem()->weekDayName(i+1)); if ( width > mWidthLongDayLabel ) mWidthLongDayLabel = width; } bool temp = mShowSatSunComp ; mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ; if ( ! mShowWeekView ) { if ( temp != KOPrefs::instance()->mMonthViewSatSunTog ) computeLayout(); } updateDayLabels(); //qDebug("KOMonthView::updateConfig() %d %d %d ",height(), mDayLabels[0]->sizeHint().height() ,mNumWeeks); //int cellHeight = (height() - mDayLabels[0]->sizeHint().height()) /mNumWeeks; //resizeEvent( 0 ); for (uint i = 0; i < mCells.count(); ++i) { mCells[i]->updateConfig(); } for (uint i = 0; i < mCellsW.count(); ++i) { mCellsW[i]->updateConfig(KOPrefs::instance()->mMonthViewUsesBigFont); } #ifdef DESKTOP_VERSION MonthViewCell::toolTipGroup()->setEnabled(KOPrefs::instance()->mEnableToolTips); #endif updateView(); } void KOMonthView::updateDayLabels() { QPtrVector<QLabel> *mDayLabelsT; mDayLabelsT = &mDayLabelsW; for (int i = 0; i < 7; i++) { { bool show = mShortDayLabelsW; if ( i > 4 && mShowSatSunComp && mWidthLongDayLabel > (*mDayLabelsT)[i]->width() ) show = true; (*mDayLabelsT)[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(i+1,show)); } } mDayLabelsT = &mDayLabels; for (int i = 0; i < 7; i++) { if (KGlobal::locale()->weekStartsMonday() || KOPrefs::instance()->mMonthViewSatSunTog ) { bool show = mShortDayLabelsM; if ( i > 4 && mShowSatSunComp && mWidthLongDayLabel > (*mDayLabelsT)[i]->width() ) show = true; (*mDayLabelsT)[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(i+1,show)); } else { if (i==0) (*mDayLabelsT)[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(7,mShortDayLabelsM)); else (*mDayLabelsT)[i]->setText(KOGlobals::self()->calendarSystem()->weekDayName(i,mShortDayLabelsM)); } } } void KOMonthView::showDates(const QDate &start, const QDate &) { // kdDebug() << "KOMonthView::showDates(): " << start.toString() << endl; QPtrVector<MonthViewCell> *cells; QPtrVector<QLabel> *dayLabels; QPtrVector<KOWeekButton> *weekLabels; int weekNum = 6; mStartDate = start; if ( mShowWeekView ) { weekNum = 1; cells = &mCellsW; dayLabels = &mDayLabelsW; weekLabels = &mWeekLabelsW; if ( !KGlobal::locale()->weekStartsMonday() ) { mStartDate = mStartDate.addDays( 1 ); } } else { cells = &mCells; dayLabels = &mDayLabels; weekLabels = &mWeekLabels; } int mWeekStartsMonday = KGlobal::locale()->weekStartsMonday(); if ( mShowWeekView || KOPrefs::instance()->mMonthViewSatSunTog ) { mWeekStartsMonday = true; } int startWeekDay = mWeekStartsMonday ? 1 : 7; while( KOGlobals::self()->calendarSystem()->dayOfWeek(mStartDate) != startWeekDay ) { mStartDate = mStartDate.addDays( -1 ); } bool primary = false; uint i; for( i = 0; i < (*cells).size(); ++i ) { QDate date = mStartDate.addDays( i ); (*cells)[i]->setDate( date ); #ifndef KORG_NOPLUGINS // add holiday, if present QString hstring(KOCore::self()->holiday(date)); (*cells)[i]->setHoliday( hstring ); #endif } QDate date = mStartDate.addDays( mWeekStartsMonday ? 3 : 4 ); for( i = 0; i < weekNum; ++i ) { int wno; // remember, according to ISO 8601, the first week of the year is the // first week that contains a thursday. Thus we must subtract off 4, // not just 1. int dayOfYear = date.dayOfYear(); if (dayOfYear % 7 != 0) wno = dayOfYear / 7 + 1; else wno =dayOfYear / 7; (*weekLabels)[i]->setWeekNum( wno ); date = date.addDays( 7 ); } updateView(); } void KOMonthView::showEvents(QPtrList<Event>) { qDebug("KOMonthView::selectEvents is not implemented yet. "); } void KOMonthView::changeEventDisplay(Event *, int) { // this should be re-written to be much more efficient, but this // quick-and-dirty-hack gets the job done for right now. //qDebug("KOMonthView::changeEventDisplay "); updateView(); } void KOMonthView::updateView() { if ( !updatePossible ) return; //qDebug("UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU "); //QTime ti; //ti.start(); clearSelection(); QPtrVector<MonthViewCell> *cells; if ( mShowWeekView ) { cells = &mCellsW; } else { cells = &mCells; } #if 1 int i; int timeSpan = (*cells).size()-1; if ( KOPrefs::instance()->mMonthViewWeek ) timeSpan = 6; for( i = 0; i < timeSpan + 1; ++i ) { (*cells)[i]->startUpdateCell(); } QPtrList<Event> events = calendar()->events(); Event *event; QDateTime dt; bool ok; QDate endDate = mStartDate.addDays( timeSpan ); for( event = events.first(); event; event = events.next() ) { // for event if ( event->doesRecur() ) { bool last; QDateTime incidenceStart = event->recurrence()->getPreviousDateTime( QDateTime( mStartDate ) , &last ); QDateTime incidenceEnd; int eventlen = event->dtStart().date().daysTo ( event->dtEnd().date() ); bool invalid = false; while( true ) { if ( incidenceStart.isValid() ) { incidenceEnd = incidenceStart.addDays( eventlen ); int st = incidenceStart.date().daysTo( endDate ); if ( st >= 0 ) { // start before timeend int end = mStartDate.daysTo( incidenceEnd.date() ); if ( end >= 0 ) { // end after timestart --- got one! //normalize st = timeSpan - st; if ( st < 0 ) st = 0; if ( end > timeSpan ) end = timeSpan; int iii; //qDebug("found %s %d %d ",event->summary().latin1(), st, end ); for ( iii = st;iii<= end;++iii) (*cells)[iii]->insertEvent( event ); } } } else { if ( invalid ) break; invalid = true; //qDebug("invalid %s", event->summary().latin1()); incidenceStart = QDateTime( mStartDate ).addSecs( -2 );; } if ( last ) break; bool ok; incidenceStart = event->getNextOccurence( incidenceStart.addSecs( 1 ) ,&ok ); if ( ! ok ) break; if ( incidenceStart.date() > endDate ) break; } } else { // no recur int st = event->dtStart().date().daysTo( endDate ); if ( st >= 0 ) { // start before timeend int end = mStartDate.daysTo( event->dtEnd().date() ); if ( end >= 0 ) { // end after timestart --- got one! //normalize st = timeSpan - st; if ( st < 0 ) st = 0; if ( end > timeSpan ) end = timeSpan; int iii; for ( iii = st;iii<= end;++iii) (*cells)[iii]->insertEvent( event ); } } } } // insert due todos QPtrList<Todo> todos = calendar()->todos( ); Todo *todo; for(todo = todos.first(); todo; todo = todos.next()) { //insertTodo( todo ); if ( todo->hasDueDate() ) { int day = mStartDate.daysTo( todo->dtDue().date() ); if ( day >= 0 && day < timeSpan + 1) { (*cells)[day]->insertTodo( todo ); } } } for( i = 0; i < timeSpan+1; ++i ) { (*cells)[i]->finishUpdateCell(); } processSelectionChange(); //qApp->processEvents(); for( i = 0; i < timeSpan+1; ++i ) { (*cells)[i]->repaintfinishUpdateCell(); } setKeyBFocus(); #else // old code //qDebug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ "); int i; for( i = 0; i < (*cells).count(); ++i ) { (*cells)[i]->updateCell(); } //qDebug("KOMonthView::updateView() "); processSelectionChange(); // qDebug("---------------------------------------------------------------------+ "); (*cells)[0]->setFocus(); #endif //qDebug("update time %d ", ti.elapsed()); } void KOMonthView::setKeyBoardFocus() { //qDebug("KOMonthView::setKeyBoardFocus() "); bool shootAgain = false; if ( mShowWeekView ) { shootAgain = !mWeekLabelsW[1]->hasFocus(); mWeekLabelsW[1]->setFocus(); } else { shootAgain = !mWeekLabels[mNumWeeks]->hasFocus(); mWeekLabels[mNumWeeks]->setFocus(); } if ( shootAgain ) { QTimer::singleShot( 0, this, SLOT ( setKeyBFocus() ) ); } } void KOMonthView::setKeyBFocus() { //qDebug("KOMonthView::setKeyBFocus() "); QTimer::singleShot( 0, this, SLOT ( setKeyBoardFocus() ) ); } void KOMonthView::resizeEvent(QResizeEvent * e) { //qDebug("KOMonthView::resizeEvent %d %d -- %d %d ", e->size().width(), e->size().height(), e->oldSize().width(), e->oldSize().height()); if ( isVisible() ) { //qDebug("KOMonthView::isVisible "); slotComputeLayout(); } else mComputeLayoutTimer->start( 100 ); } void KOMonthView::slotComputeLayout() { mComputeLayoutTimer->stop(); //qDebug("KOMonthView::Post - resizeEvent %d %d ", width(), height() ); computeLayout(); clPending = true; setKeyBFocus(); } void KOMonthView::computeLayoutWeek() { static int lastWid = 0; static int lastHei = 0; int daysToShow; bool combinedSatSun = false; if (mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ) { daysToShow = 6; combinedSatSun = true; } int tWid = topLevelWidget()->size().width(); int tHei = topLevelWidget()->size().height(); int wid = width();//e int hei = height()-1-mNavigatorBar->height(); if ( ((wid *3)/2) < tWid && (( hei *3) /2) < tHei ) return; if ( lastWid == width() && lastHei == height() ) { //qDebug("KOListWeekView::No compute layout needed "); return; } lastWid = width(); lastHei = height(); if ( wid < hei ) daysToShow = 2; else daysToShow = 3; mShowSatSunComp = true; combinedSatSun = true; //qDebug("KOMonthView::computeLayout() WWW ------------------------------------ "); QFontMetrics fm ( mWeekLabels[0]->font() ); int weeklabelwid = fm.width( "888" ); wid -= weeklabelwid; int colWid = wid / daysToShow; int lastCol = wid - ( colWid*6 ); int dayLabelHei = mDayLabelsW[0]->sizeHint().height(); int cellHei = (hei - (5- daysToShow )*dayLabelHei) /(5- daysToShow ); int colModulo = wid % daysToShow; int rowModulo = (hei- (5- daysToShow )*dayLabelHei) % daysToShow-1; //qDebug("rowmod %d ", rowModulo); int i; int x,y,w,h; x= 0; y= 0; w = colWid; h = dayLabelHei ; for ( i = 0; i < 7; i++) { if ( i && !( i % daysToShow) && i < 6) { y += hei/(5-daysToShow); x = 0; w = colWid; } if ( ((i) % daysToShow) >= daysToShow-colModulo ) { ++w; } if ( i >= 5 ) { mDayLabelsW[i]->setGeometry( x+weeklabelwid,y,w/2+w%2,h); x -= (w/2 ); } else mDayLabelsW[i]->setGeometry( x+weeklabelwid,y,w,h); x += w; } x= 0; y= dayLabelHei; w = colWid; h = cellHei; int max = 0; for ( i = 0; i < mCellsW.count(); ++i) { if ( i > 6 ) { mCellsW[i]->hide(); continue; } w = colWid; if ( ((i) % daysToShow) >= daysToShow-colModulo ) { ++w; } if ( i == (daysToShow-1-rowModulo)*7) ++h; if ( i >= 5 ) { if ( i ==5 ) { max = h/2; mCellsW[i]->setGeometry ( x+weeklabelwid,y,w,max ); x -= w ;y += h/2; } else { if ( ((i-1) % daysToShow) >= daysToShow-colModulo ) { ++w; } max = h-h/2; mCellsW[i]->setGeometry ( x+weeklabelwid,y,w,max ); y -= h/2; } } else { max = h; mCellsW[i]->setGeometry ( x+weeklabelwid,y,w,h ); } x += w; if ( x + w/2 > wid ) { x = 0; y += h+dayLabelHei ; } //mCellsW[i]->dateLabel()->setMaximumHeight( max - mCellsW[i]->lineWidth()*2 ); } y= dayLabelHei; h = cellHei ; mWeekLabelsW[0]->setGeometry( 0,y,weeklabelwid,hei-dayLabelHei); mWeekLabelsW[1]->setGeometry( 0,0,weeklabelwid,dayLabelHei); // qDebug("RRRRRRRRRRRRR %d %d old %d %d", e->size().width(),e->size().height() , e->oldSize().width(),e->oldSize().height()); //qDebug("parent %d %d ", topLevelWidget()->size().width(), topLevelWidget()->size().height()); mShortDayLabelsW = mDayLabelsW[0]->width()-2 < mWidthLongDayLabel ; updateDayLabels(); //bool forceUpdate = !updatePossible; updatePossible = true; //mWeekLabels[mNumWeeks]->setText( i18n("M")); //if ( forceUpdate ) // updateView(); } void KOMonthView::computeLayout() { static int lastWid = 0; static int lastHei = 0; if ( mShowWeekView ){ computeLayoutWeek(); return; } int daysToShow = 7; bool combinedSatSun = false; if (mShowSatSunComp = KOPrefs::instance()->mMonthViewSatSunTog ) { daysToShow = 6; combinedSatSun = true; } int tWid = topLevelWidget()->size().width(); int tHei = topLevelWidget()->size().height(); int wid = width();//e int hei = height()-1-mNavigatorBar->height(); if ( ((wid *3)/2) < tWid && (( hei *3) /2) < tHei ) { return; } if ( lastWid == width() && lastHei == height() ){ //qDebug("KOMonthview::No compute layout needed "); return; } lastWid = width(); lastHei = height(); //qDebug("KOMonthView::computeLayout() MMM ------------------- "); QFontMetrics fm ( mWeekLabels[0]->font() ); int weeklabelwid = fm.width( "888" ); wid -= weeklabelwid; int colWid = wid / daysToShow; int lastCol = wid - ( colWid*6 ); int dayLabelHei = mDayLabels[0]->sizeHint().height(); int cellHei = (hei - dayLabelHei) /6; int colModulo = wid % daysToShow; int rowModulo = (hei- dayLabelHei) % 6; //qDebug("rowmod %d ", rowModulo); int i; int x,y,w,h; x= 0; y= 0; w = colWid; h = dayLabelHei ; for ( i = 0; i < 7; i++) { if ( i == daysToShow-colModulo ) ++w; if ( combinedSatSun ) { if ( i >= daysToShow-1 ) { mDayLabels[i]->setGeometry( x+weeklabelwid,y,w/2,h); x -= w/2 ; } else mDayLabels[i]->setGeometry( x+weeklabelwid,y,w,h); } else mDayLabels[i]->setGeometry( x+weeklabelwid,y,w,h); x += w; } x= 0; y= dayLabelHei; w = colWid; h = cellHei ; int max = 0; for ( i = 0; i < mCells.count(); ++i) { //qDebug("iii %d ", i); w = colWid; if ( ((i) % 7) >= 7-colModulo ) { ++w; } if ( i == (6-rowModulo)*7) ++h; if ( combinedSatSun ) { if ( (i)%7 >= daysToShow-1 ) { if ( (i)%7 == daysToShow-1 ) { max = h/2; mCells[i]->setGeometry ( x+weeklabelwid,y,w,max ); x -= w ;y += h/2; } else { max = h-h/2; mCells[i]->setGeometry ( x+weeklabelwid,y,w,max ); y -= h/2; } } else { max = h; mCells[i]->setGeometry ( x+weeklabelwid,y,w,h ); } } else { max = h; mCells[i]->setGeometry ( x+weeklabelwid,y,w,h ); } x += w; if ( x + w/2 > wid ) { x = 0; y += h; } //mCells[i]->dateLabel()->setMaximumHeight( max- mCells[i]->lineWidth()*2 ); } y= dayLabelHei; h = cellHei ; for ( i = 0; i < 6; i++) { if ( i == (6-rowModulo)) ++h; mWeekLabels[i]->setGeometry( 0,y,weeklabelwid,h); y += h; } mWeekLabels[6]->setGeometry( 0,0,weeklabelwid,dayLabelHei); // qDebug("RRRRRRRRRRRRR %d %d old %d %d", e->size().width(),e->size().height() , e->oldSize().width(),e->oldSize().height()); //qDebug("parent %d %d ", topLevelWidget()->size().width(), topLevelWidget()->size().height()); mShortDayLabelsM = mDayLabels[0]->width()-2 < mWidthLongDayLabel ; updateDayLabels(); //bool forceUpdate = !updatePossible; updatePossible = true; //mWeekLabels[mNumWeeks]->setText( i18n("W")); } void KOMonthView::showContextMenu( Incidence *incidence ) { mContextMenu->showIncidencePopup(incidence); /* if( incidence && incidence->type() == "Event" ) { Event *event = static_cast<Event *>(incidence); mContextMenu->showEventPopup(event); } else { kdDebug() << "MonthView::showContextMenu(): cast failed." << endl; } */ } MonthViewCell * KOMonthView::selectedCell( ) { return mSelectedCell; } void KOMonthView::setSelectedCell( MonthViewCell *cell ) { //qDebug("KOMonthView::setSelectedCell "); if ( mSelectedCell && mSelectedCell != cell ) { MonthViewCell * mvc = mSelectedCell; mSelectedCell = cell; mvc->deselect(); } else mSelectedCell = cell; // if ( mSelectedCell ) // mSelectedCell->select(); if ( !mSelectedCell ) emit incidenceSelected( 0 ); else emit incidenceSelected( mSelectedCell->selectedIncidence() ); } void KOMonthView::processSelectionChange() { QPtrList<Incidence> incidences = selectedIncidences(); if (incidences.count() > 0) { emit incidenceSelected( incidences.first() ); } else { emit incidenceSelected( 0 ); clearSelection(); } } void KOMonthView::clearSelection() { if ( mSelectedCell ) { mSelectedCell->deselect(); mSelectedCell = 0; } } void KOMonthView::keyReleaseEvent ( QKeyEvent * e) { if ( !e->isAutoRepeat() ) { mFlagKeyPressed = false; } } void KOMonthView::keyPressEvent ( QKeyEvent * e ) { qApp->processEvents(); if ( e->isAutoRepeat() && !mFlagKeyPressed ) { //e->ignore(); e->accept(); return; } if (! e->isAutoRepeat() ) mFlagKeyPressed = true; switch(e->key()) { case Key_Up: { if ( mShowWeekView ) { emit selectWeekNum ( currentWeek() - 1 ); } else { emit prevMonth(); } } e->accept(); break; case Key_Down: { if ( mShowWeekView ) { emit selectWeekNum ( currentWeek() +1); } else { emit nextMonth(); } } e->accept(); break; case Key_Return: case Key_Enter: { selectInternalWeekNum ( currentWeek() ); } e->accept(); break; case Key_D: if ( mSelectedCell ) { mSelectedCell->showDay(); e->accept(); } else { e->ignore(); } break; default: e->ignore(); break; } } diff --git a/korganizer/komonthview.h b/korganizer/komonthview.h index e962756..e39eeb0 100644 --- a/korganizer/komonthview.h +++ b/korganizer/komonthview.h @@ -1,325 +1,329 @@ /* 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 _KOMONTHVIEW_H #define _KOMONTHVIEW_H #include <qlabel.h> #include <qframe.h> #include <qdatetime.h> #include <qlistbox.h> #include <qpoint.h> #include <qwidgetstack.h> #include <qlayout.h> #include <qtimer.h> #include <qintdict.h> #include <qpushbutton.h> #include <qvaluelist.h> #include <qptrvector.h> #include <libkcal/calendar.h> #include <libkcal/event.h> #include "koeventview.h" #include "navigatorbar.h" #ifdef DESKTOP_VERSION class QToolTipGroup; #endif class KNOWhatsThis; class KOWeekButton : public QPushButton { Q_OBJECT public: KOWeekButton( QWidget *parent=0, const char *name=0 ) : QPushButton( parent, name) { connect( this, SIGNAL( clicked() ), SLOT( bottonClicked() )); mNumber = -1; } void setWeekNum ( int num ) {mNumber = num; setText( QString::number ( num ));} int getWeekNum() { return mNumber;} signals: void selectWeekNum ( int ); private: void focusInEvent ( QFocusEvent * ){;} int mNumber; void keyPressEvent ( QKeyEvent * e ) { e->ignore(); } private slots : void bottonClicked() { if ( mNumber > 0 ) emit selectWeekNum ( mNumber ); } }; class KNoScrollListBox: public QListBox { Q_OBJECT public: KNoScrollListBox(QWidget *parent=0, const char *name=0); ~KNoScrollListBox(); QString getWhatsThisText(QPoint p) ; signals: void shiftDown(); void shiftUp(); void rightClick(); protected slots: void oneDown(); void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); void mousePressEvent(QMouseEvent *); void focusInEvent ( QFocusEvent * ); void focusOutEvent ( QFocusEvent * ); private: bool resetOnFocusIn; KNOWhatsThis * mWT; }; class MonthViewItem: public QListBoxItem { public: MonthViewItem( Incidence *, QDate qd, const QString & title ); void recycle( Incidence *incidence, QDate qd, const QString & s); void setRecur(bool on) { mRecur = on; } void setAlarm(bool on) { mAlarm = on; } void setReply(bool on) { mReply = on; } void setMoreInfo(bool on) { mInfo = on; } void setMultiDay(int type) { mMultiday = type; } + void setMultiDayPos(int type) { mdayPos = type; } + int gettMultiDayPos() { return mdayPos; } void setBlockRepaint(bool on) { mblockRepaint = on; } void setPalette(const QPalette &p) { mPalette = p; } QPalette palette() const { return mPalette; } Incidence *incidence() const { return mIncidence; } QDate incidenceDate() { return mDate; } protected: virtual void paint(QPainter *); virtual int height(const QListBox *) const; virtual int width(const QListBox *) const; private: + int mdayPos; bool isWeekItem; bool mblockRepaint; int mMultiday; bool mRecur; bool mAlarm; bool mReply; bool mInfo; QPalette mPalette; QDate mDate; Incidence *mIncidence; }; class KOMonthView; class MonthViewCell : public KNoScrollListBox { Q_OBJECT public: MonthViewCell(KOMonthView *,QWidget* ); ~MonthViewCell() {mAvailItemList.setAutoDelete( true );} void setDate( const QDate & ); QDate date() const; void setPrimary( bool ); bool isPrimary() const; void setHoliday( bool ); void setHoliday( const QString & ); void updateCell(); void startUpdateCell(); void finishUpdateCell(); void repaintfinishUpdateCell(); - void insertEvent(Event *); + int insertEvent(Event *); void insertTodo(Todo *); void updateConfig( bool bigFont = false ); void enableScrollBars( bool ); Incidence *selectedIncidence(); QDate selectedIncidenceDate(); QPushButton * dateLabel() { return mLabel; } void deselect(); void select(); #ifdef DESKTOP_VERSION static QToolTipGroup *toolTipGroup(); #endif signals: void defaultAction( Incidence * ); void newEventSignal( QDateTime ); void showDaySignal( QDate ); protected: QStringList mToolTip; void resizeEvent( QResizeEvent * ); public slots: void showDay(); protected slots: void defaultAction( QListBoxItem * ); void contextMenu( QListBoxItem * ); void selection( QListBoxItem * ); void cellClicked( QListBoxItem * ); void newEvent(); private: + int mdayCount; QPtrList <MonthViewItem> mAvailItemList; KOMonthView *mMonthView; int currentPalette; QDate mDate; bool mPrimary; bool mHoliday; QString mHolidayString; //QLabel *mLabel; QPushButton *mLabel; //QListBox *mItemList; #ifdef DESKTOP_VERSION static QToolTipGroup *mToolTipGroup; #endif QSize mLabelSize; QSize mLabelBigSize; QPalette mHolidayPalette; QPalette mStandardPalette; QPalette mPrimaryPalette; QPalette mNonPrimaryPalette; void setMyPalette(); QPalette getPalette (); }; class KOMonthView: public KOEventView { Q_OBJECT public: KOMonthView(Calendar *cal, QWidget *parent = 0, const char *name = 0 ); ~KOMonthView(); /** Returns maximum number of days supported by the komonthview */ virtual int maxDatesHint(); /** Returns number of currently shown dates. */ virtual int currentDateCount(); /** returns the currently selected events */ virtual QPtrList<Incidence> selectedIncidences(); /** returns dates of the currently selected events */ virtual DateList selectedDates(); virtual void printPreview(CalPrinter *calPrinter, const QDate &, const QDate &); bool isMonthView() { return !mShowWeekView; } bool isUpdatePossible() { return updatePossible; } MonthViewCell * selectedCell(); bool skipResize; NavigatorBar* navigatorBar() { return mNavigatorBar ;} public slots: virtual void updateView(); virtual void updateConfig(); virtual void showDates(const QDate &start, const QDate &end); virtual void showEvents(QPtrList<Event> eventList); void changeEventDisplay(Event *, int); void clearSelection(); void showContextMenu( Incidence * ); void setSelectedCell( MonthViewCell * ); void switchView(); void setKeyBoardFocus(); void setKeyBFocus(); protected slots: void slotComputeLayout(); void selectInternalWeekNum ( int ); void processSelectionChange(); signals: void nextMonth(); void prevMonth(); void selectWeekNum ( int ); void selectMonth (); void showDaySignal( QDate ); protected: void resizeEvent(QResizeEvent *); void viewChanged(); void updateDayLabels(); private: QTimer* mComputeLayoutTimer; NavigatorBar* mNavigatorBar; int currentWeek(); bool clPending; QWidgetStack * mWidStack; QWidget* mMonthView; QWidget* mWeekView; bool mShowWeekView; bool updatePossible; int mDaysPerWeek; int mNumWeeks; int mNumCells; //bool mWeekStartsMonday; bool mShowSatSunComp; void computeLayout(); void computeLayoutWeek(); QPtrVector<MonthViewCell> mCells; QPtrVector<QLabel> mDayLabels; QPtrVector<KOWeekButton> mWeekLabels; QPtrVector<MonthViewCell> mCellsW; QPtrVector<QLabel> mDayLabelsW; QPtrVector<KOWeekButton> mWeekLabelsW; bool mShortDayLabelsM; bool mShortDayLabelsW; int mWidthLongDayLabel; QDate mStartDate; MonthViewCell *mSelectedCell; bool mFlagKeyPressed; KOEventPopupMenu *mContextMenu; void keyPressEvent ( QKeyEvent * ) ; void keyReleaseEvent ( QKeyEvent * ) ; }; #endif |