-rw-r--r-- | korganizer/koagendaview.cpp | 134 | ||||
-rw-r--r-- | korganizer/koagendaview.h | 2 | ||||
-rw-r--r-- | korganizer/kodaymatrix.cpp | 493 | ||||
-rw-r--r-- | korganizer/kodaymatrix.h | 1 |
4 files changed, 326 insertions, 304 deletions
diff --git a/korganizer/koagendaview.cpp b/korganizer/koagendaview.cpp index 2996acb..218396d 100644 --- a/korganizer/koagendaview.cpp +++ b/korganizer/koagendaview.cpp @@ -36,211 +36,221 @@ #include <qpainter.h> #include <qpushbutton.h> #include <qapplication.h> #include <kapplication.h> #include <KDGanttMinimizeSplitter.h> #include <kdebug.h> #include <kstandarddirs.h> #include <kiconloader.h> #include <klocale.h> #include <kconfig.h> #include <kglobal.h> #include "calendarview.h" #include "koviewmanager.h" #include <libkcal/calendar.h> #include <libkcal/icaldrag.h> #include <libkcal/dndfactory.h> #include <kcalendarsystem.h> #include "koglobals.h" #ifndef KORG_NOPLUGINS #include "kocore.h" #endif #include "koprefs.h" #include "koagenda.h" #include "koagendaitem.h" #ifndef KORG_NOPRINTER #include "calprinter.h" #endif #include "koagendaview.h" //#include "koagendaview.moc" //extern bool globalFlagBlockPainting; extern int globalFlagBlockAgenda; extern int globalFlagBlockStartup; extern int globalFlagBlockAgendaItemPaint; extern int globalFlagBlockAgendaItemUpdate; extern int globalFlagBlockLabel; using namespace KOrg; TimeLabels::TimeLabels(int rows,QWidget *parent,const char *name,WFlags f) : QScrollView(parent,name,f) { + myPix.resize( 1, 1 ); mRows = rows; + mRedrawNeeded = true; setMinimumHeight( 20 ); mCellHeight = KOPrefs::instance()->mHourSize*4; enableClipper(true); setHScrollBarMode(AlwaysOff); setVScrollBarMode(AlwaysOff); resizeContents(50,mRows * mCellHeight); viewport()->setBackgroundMode( PaletteBackground ); } void TimeLabels::setCellHeight(int height) { mCellHeight = height; } /* Optimization so that only the "dirty" portion of the scroll view is redrawn. Unfortunately, this is not called by default paintEvent() method. */ void TimeLabels::drawContents(QPainter *p,int cx, int cy, int cw, int ch) { // if ( globalFlagBlockAgenda ) // return; // bug: the parameters cx, cy, cw, ch are the areas that need to be // redrawn, not the area of the widget. unfortunately, this // code assumes the latter... // now, for a workaround... // these two assignments fix the weird redraw bug - cx = contentsX() + 2; - cw = contentsWidth() - 2; - // end of workaround - - int cell = ((int)(cy/mCellHeight)); - int y = cell * mCellHeight; - QFontMetrics fm = fontMetrics(); - QString hour; - QString suffix; - int tW = fm.width("24:00i"); - int timeHeight = fm.height(); - //timeHeight -= (timeHeight/4-2); - int borderWidth = 0; - QFont nFont = p->font(); + if ( mRedrawNeeded ) { + cx = contentsX() + 2; + cw = contentsWidth() - 2; + // end of workaround + + int cell = ((int)(cy/mCellHeight)); + int y = cell * mCellHeight; + QFontMetrics fm = fontMetrics(); + QString hour; + QString suffix; + int tW = fm.width("24:00i"); + int timeHeight = fm.height(); + //timeHeight -= (timeHeight/4-2); + int borderWidth = 0; + QFont nFont = p->font(); - if (!KGlobal::locale()->use12Clock()) - suffix = "00"; - else - borderWidth = 0; - if ( timeHeight > mCellHeight ) { - timeHeight = mCellHeight-1; - int pointS = nFont.pointSize(); - while ( pointS > 4 ) { - nFont.setPointSize( pointS ); + if (!KGlobal::locale()->use12Clock()) + suffix = "00"; + else + borderWidth = 0; + if ( timeHeight > mCellHeight ) { + timeHeight = mCellHeight-1; + int pointS = nFont.pointSize(); + while ( pointS > 4 ) { + nFont.setPointSize( pointS ); + fm = QFontMetrics( nFont ); + if ( fm.height() < mCellHeight ) + break; + -- pointS; + } fm = QFontMetrics( nFont ); - if ( fm.height() < mCellHeight ) - break; - -- pointS; - } - fm = QFontMetrics( nFont ); - borderWidth = 4; - timeHeight = fm.height(); - } - timeHeight -= (timeHeight/4-2); - QFont sFont = nFont; - sFont.setPointSize( sFont.pointSize()/2+2 ); - QFontMetrics fmS( sFont ); - int sHei = fmS.height(); - sHei -= (sHei/4-2); - int startW = this->width() - frameWidth(); - while (y < cy + ch) { - p->drawLine(cx,y,cx+tW,y); - hour.setNum(cell); - - // handle 24h and am/pm time formats - if (KGlobal::locale()->use12Clock()) { - if (cell > 11) suffix = "pm"; - else - suffix = "am"; - if (cell == 0) hour.setNum(12); - if (cell > 12) hour.setNum(cell - 12); + borderWidth = 4; + timeHeight = fm.height(); } + timeHeight -= (timeHeight/4-2); + QFont sFont = nFont; + sFont.setPointSize( sFont.pointSize()/2+2 ); + QFontMetrics fmS( sFont ); + int sHei = fmS.height(); + sHei -= (sHei/4-2); + int startW = this->width() - frameWidth(); + while (y < cy + ch) { + p->drawLine(cx,y,cx+tW,y); + hour.setNum(cell); + + // handle 24h and am/pm time formats + if (KGlobal::locale()->use12Clock()) { + if (cell > 11) suffix = "pm"; + else + suffix = "am"; + if (cell == 0) hour.setNum(12); + if (cell > 12) hour.setNum(cell - 12); + } - // center and draw the time label - int timeWidth = fm.width(hour+"i"); - int tw2 = fm.width(suffix); - int offset = startW - timeWidth - tw2 ; - p->setFont( nFont ); - p->drawText(cx - borderWidth + offset, y+ timeHeight, hour); - p->setFont( sFont ); - offset = startW - tw2-1; - p->drawText(cx - borderWidth + offset, y+ sHei, suffix); - - // increment indices - y += mCellHeight; - cell++; + // center and draw the time label + int timeWidth = fm.width(hour+"i"); + int tw2 = fm.width(suffix); + int offset = startW - timeWidth - tw2 ; + p->setFont( nFont ); + p->drawText(cx - borderWidth + offset, y+ timeHeight, hour); + p->setFont( sFont ); + offset = startW - tw2-1; + p->drawText(cx - borderWidth + offset, y+ sHei, suffix); + + // increment indices + y += mCellHeight; + cell++; + } + } else { + //qDebug("NO redraw "); } + // double buffer not yet implemented + //bitBlt (this, 0, 0, &myPix, 0 ,0,width(), height() ,CopyROP); + //mRedrawNeeded = false; } /** Calculates the minimum width. */ int TimeLabels::minimumWidth() const { return mMiniWidth; } /** updates widget's internal state */ void TimeLabels::updateConfig() { + mRedrawNeeded = true; // set the font // config->setGroup("Fonts"); // QFont font = config->readFontEntry("TimeBar Font"); setFont(KOPrefs::instance()->mTimeBarFont); QString test = "88:88"; if (KGlobal::locale()->use12Clock()) test += "i"; mMiniWidth = fontMetrics().width(test) + frameWidth()*2 +1 ; // update geometry restrictions based on new settings setFixedWidth(minimumWidth()); // update HourSize mCellHeight = KOPrefs::instance()->mHourSize*4; resizeContents(50,mRows * mCellHeight); } /** update time label positions */ void TimeLabels::positionChanged() { int adjustment = mAgenda->contentsY(); setContentsPos(0, adjustment); } /** */ void TimeLabels::setAgenda(KOAgenda* agenda) { mAgenda = agenda; } void TimeLabels::contentsMousePressEvent ( QMouseEvent * e) { mMouseDownY = e->pos().y(); mOrgCap = topLevelWidget()->caption(); } void TimeLabels::contentsMouseMoveEvent ( QMouseEvent * e ) { int diff = mMouseDownY - e->pos().y(); if ( diff < 10 && diff > -10 ) return; int tSize = KOPrefs::instance()->mHourSize + (diff/10) ; if ( tSize < 4 ) tSize = 4; if ( tSize > 22 ) tSize = 22; tSize = (tSize-2)/2; topLevelWidget()->setCaption(i18n("New Agendasize: %1").arg(tSize)); diff --git a/korganizer/koagendaview.h b/korganizer/koagendaview.h index 6dc81c6..30c9b05 100644 --- a/korganizer/koagendaview.h +++ b/korganizer/koagendaview.h @@ -56,96 +56,98 @@ class KOAgendaButton : public QPushButton mNum = -3; setFlat( true ); setFocusPolicy(NoFocus); setSizePolicy(QSizePolicy( QSizePolicy::Expanding ,QSizePolicy::Expanding )); connect( this, SIGNAL( clicked() ), this, SLOT ( bClicked() ) ); }; QSize sizeHint () const { return QSize( 5,5) ;} void setNum( int n) { mNum = n; } private slots: void bClicked() {emit numClicked( mNum);} signals: void numClicked( int ); private: int mNum; }; class TimeLabels : public QScrollView { Q_OBJECT public: TimeLabels(int rows,QWidget *parent=0,const char *name=0,WFlags f=0); void setCellHeight(int height); /** Calculates the minimum width */ virtual int minimumWidth() const; /** updates widget's internal state */ void updateConfig(); /** */ void setAgenda(KOAgenda* agenda); /** */ virtual void paintEvent(QPaintEvent* e); void contentsMousePressEvent ( QMouseEvent * ) ; void contentsMouseReleaseEvent ( QMouseEvent * ); void contentsMouseMoveEvent ( QMouseEvent * ); public slots: /** update time label positions */ void positionChanged(); signals: void scaleChanged(); protected: void drawContents(QPainter *p,int cx, int cy, int cw, int ch); private: + QPixmap myPix; + bool mRedrawNeeded; int mMiniWidth; int mMouseDownY; QString mOrgCap; int mRows; int mCellHeight; /** */ KOAgenda* mAgenda; }; class EventIndicator : public QFrame { Q_OBJECT public: enum Location { Top, Bottom }; EventIndicator(Location loc=Top,QWidget *parent=0,const char *name=0); virtual ~EventIndicator(); void changeColumns(int columns); void setPaintWidget( KDGanttMinimizeSplitter* ); void setXOffset( int ); void enableColumn(int column, bool enable); protected: void drawContents(QPainter *); private: int mXOffset; KDGanttMinimizeSplitter* mPaintWidget; int mColumns; QHBox *mTopBox; QBoxLayout *mTopLayout; Location mLocation; QPixmap mPixmap; QMemArray<bool> mEnabled; }; /** KOAgendaView is the agenda-like view used to display events in an one or multi-day view. */ class KOAgendaView : public KOEventView { Q_OBJECT public: KOAgendaView(Calendar *cal,QWidget *parent = 0,const char *name = 0 ); virtual ~KOAgendaView(); void setStartHour( int ); void toggleAllDay(); diff --git a/korganizer/kodaymatrix.cpp b/korganizer/kodaymatrix.cpp index d543aaf..dfc6af7 100644 --- a/korganizer/kodaymatrix.cpp +++ b/korganizer/kodaymatrix.cpp @@ -65,96 +65,97 @@ 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 { + mRedrawNeeded = true; mKODaymatrixWhatsThis = new KODaymatrixWhatsThis(this); mPendingUpdateBeforeRepaint = false; mouseDown = false; // initialize dynamic arrays bDays.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; @@ -341,139 +342,141 @@ void KODayMatrix::updateViewTimed() mUpdateTimer->stop(); if ( !mCalendar ) { qDebug("NOT CAL "); return; } //qDebug("KODayMatrix::updateViewTimed "); for(int i = 0; i < NUMDAYS; i++) { // if events are set for the day then remember to draw it bold QPtrList<Event> eventlist = mCalendar->events(days[i]); Event *event; int numEvents = eventlist.count(); QString holiStr = ""; bDays.clearBit(i); hDays.clearBit(i); eDays.clearBit(i); for(event=eventlist.first();event != 0;event=eventlist.next()) { ushort recurType = event->recurrence()->doesRecur(); if ((recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur) || (recurType == Recurrence::rWeekly && !KOPrefs::instance()->mWeeklyRecur)) { numEvents--; } if ( event->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; } } + 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( 20 ); + mUpdateTimer->start( 50 ); #else mRepaintTimer->start( 350 ); mUpdateTimer->start( 1200 ); #endif } } void KODayMatrix::updateEvents() { if ( !mCalendar ) return; for( int i = 0; i < NUMDAYS; i++ ) { // if events are set for the day then remember to draw it bold QPtrList<Event> eventlist = mCalendar->events( days[ i ] ); int numEvents = eventlist.count(); Event *event; for( event = eventlist.first(); event != 0;event=eventlist.next()) { ushort recurType = event->doesRecur(); if ( ( recurType == Recurrence::rDaily && !KOPrefs::instance()->mDailyRecur ) || ( 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]; @@ -633,323 +636,329 @@ void KODayMatrix::dropEvent(QDropEvent *e) 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 ( myPix.width() != width() || myPix.height()!=height() ) { myPix.resize(size() ); + mRedrawNeeded = true; } - QPainter p(&myPix); - p.setFont(font()); + 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 ); + + 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; - } - if (selh > 1) { - p.fillRect(1, (row+1)*dheight, 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); - } - } - } + 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; + } + if (selh > 1) { + p.fillRect(1, (row+1)*dheight, 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); - } + // 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 (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; - } + // 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 (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; - p.drawRect(col*dwidth+addCol, row*dheight+addRow, dwidth, dheight+1); - p.setPen(tmppen); - } + addCol += 1; + p.drawRect(col*dwidth+addCol, row*dheight+addRow, dwidth, 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 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 ( 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); - } - } - } + // if it is a holiday then use the default holiday color + if ( !mHolidays[i].isNull()) { + 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); - } + // 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()) { - p.setPen(actcol); - } - // reset bold font to plain font - if ( eDays.testBit(i)) { - QFont myFont = font(); - myFont.setBold(false); - p.setFont(myFont); - } - } - int off = 0;//xyOff; - bitBlt (this, off, off, &myPix, 0 ,0,width(), height() ,CopyROP); - //qDebug("ffffffffff %d ", off); + 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()) { + 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, 0, 0, &myPix, 0 ,0,width(), height() ,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 38a7f92..731117c 100644 --- a/korganizer/kodaymatrix.h +++ b/korganizer/kodaymatrix.h @@ -182,96 +182,97 @@ public slots: 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: + bool mRedrawNeeded; KODaymatrixWhatsThis* mKODaymatrixWhatsThis; bool mouseDown; QBitArray bDays; QBitArray hDays; QBitArray eDays; 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. */ |